Skip to content

Commit

Permalink
Added support for uint textures
Browse files Browse the repository at this point in the history
  • Loading branch information
Daivuk committed Oct 1, 2022
1 parent 45cdb06 commit eb4220a
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 7 deletions.
8 changes: 8 additions & 0 deletions include/onut/Shader.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ namespace onut
Float2 = 2,
Float3 = 3,
Float4 = 4,
UInt = 5,
Matrix = 16
};

Expand Down Expand Up @@ -89,12 +90,19 @@ namespace onut
};
using ParsedUniforms = std::vector<ParsedUniform>;

enum class ParsedTextureType
{
Float4,
UInt
};

struct ParsedTexture
{
int index;
sample::Filtering filter = sample::Filtering::Trilinear;
sample::AddressMode repeatX = sample::AddressMode::Wrap;
sample::AddressMode repeatY = sample::AddressMode::Wrap;
VarType type = VarType::Float4;
std::string name;
};
using ParsedTextures = std::vector<ParsedTexture>;
Expand Down
4 changes: 3 additions & 1 deletion include/onut/Texture.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ namespace onut
R32, // float
RG32, // float
RGBA32, // float
RGB10A2 // normalized in range [0, 1]
RGB10A2, // normalized in range [0, 1]
I8 // bytes
};

class Texture : public Resource, public std::enable_shared_from_this<Texture>
Expand All @@ -35,6 +36,7 @@ namespace onut
static OTextureRef createFromFile(const std::string& filename, const OContentManagerRef& pContentManager = nullptr, bool generateMipmaps = oGenerateMipmaps);
static OTextureRef createFromFileData(const uint8_t* pData, uint32_t size, bool generateMipmaps = oGenerateMipmaps);
static OTextureRef createFromData(const uint8_t* pData, const Point& size, bool generateMipmaps = oGenerateMipmaps);
static OTextureRef createFromDataWithFormat(const uint8_t* pData, const Point& size, RenderTargetFormat format, bool generateMipmaps = oGenerateMipmaps);
static OTextureRef createRenderTarget(const Point& size, bool willBeUsedInEffects = false, RenderTargetFormat format = onut::RenderTargetFormat::RGBA8);
static OTextureRef createScreenRenderTarget(bool willBeUsedInEffects = false, RenderTargetFormat format = onut::RenderTargetFormat::RGBA8);
static OTextureRef createDynamic(const Point& size);
Expand Down
11 changes: 11 additions & 0 deletions src/Shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,17 @@ namespace onut
return false;
}
}
else if (propName == "type")
{
if (propValue == "float4")
{
texture.type = Shader::VarType::Float4;
}
else if (propValue == "uint")
{
texture.type = Shader::VarType::UInt;
}
}
else
{
shaderError(lexer, "Invalid texture sampler property");
Expand Down
27 changes: 21 additions & 6 deletions src/ShaderD3D11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@ namespace onut
{
const auto& texture = *rit;
source += "SamplerState sampler_" + texture.name + " : register(s" + std::to_string(texture.index) + ");\n";
source += "Texture2D texture_" + texture.name + " : register(t" + std::to_string(texture.index) + ");\n";
source += "Texture2D";
if (texture.type == VarType::UInt) source += "<uint>";
source += " texture_" + texture.name + " : register(t" + std::to_string(texture.index) + ");\n";
source += "float4 " + texture.name + "(float2 uv)\n";
source += "{\n";
source += " return texture_" + texture.name + ".SampleLevel(sampler_" + texture.name + ", uv, 0);\n";
Expand Down Expand Up @@ -348,11 +350,24 @@ namespace onut
{
const auto& texture = *rit;
source += "SamplerState sampler_" + texture.name + " : register(s" + std::to_string(texture.index) + ");\n";
source += "Texture2D texture_" + texture.name + " : register(t" + std::to_string(texture.index) + ");\n";
source += "float4 " + texture.name + "(float2 uv)\n";
source += "{\n";
source += " return texture_" + texture.name + ".Sample(sampler_" + texture.name + ", uv);\n";
source += "}\n\n";
source += "Texture2D";
if (texture.type == VarType::UInt)
{
source += "<uint>";
source += " texture_" + texture.name + " : register(t" + std::to_string(texture.index) + ");\n";
source += "uint " + texture.name + "(int2 uv)\n";
source += "{\n";
source += " return texture_" + texture.name + ".Load(int3(uv, 0));\n";
source += "}\n\n";
}
else if (texture.type == VarType::Float4)
{
source += " texture_" + texture.name + " : register(t" + std::to_string(texture.index) + ");\n";
source += "float4 " + texture.name + "(float2 uv)\n";
source += "{\n";
source += " return texture_" + texture.name + ".Sample(sampler_" + texture.name + ", uv);\n";
source += "}\n\n";
}
}

// Put inputs
Expand Down
63 changes: 63 additions & 0 deletions src/TextureD3D11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,49 @@ namespace onut
return pRet;
}

OTextureRef Texture::createFromDataWithFormat(const uint8_t* pData, const Point& size, RenderTargetFormat format, bool generateMipmaps)
{
auto pRet = std::shared_ptr<TextureD3D11>(new TextureD3D11());

ID3D11Texture2D* pTexture = NULL;
ID3D11ShaderResourceView* pTextureView = NULL;

pRet->m_format = format;

D3D11_TEXTURE2D_DESC desc;
desc.Width = static_cast<UINT>(size.x);
desc.Height = static_cast<UINT>(size.y);
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = pRet->getDXGIFormat();
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_IMMUTABLE;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;

D3D11_SUBRESOURCE_DATA data;
data.pSysMem = pData;
data.SysMemPitch = size.x * pRet->getPitch();
data.SysMemSlicePitch = 0;

auto pRendererD3D11 = std::dynamic_pointer_cast<ORendererD3D11>(oRenderer);
auto pDevice = pRendererD3D11->getDevice();
auto ret = pDevice->CreateTexture2D(&desc, &data, &pTexture);
assert(ret == S_OK);
ret = pDevice->CreateShaderResourceView(pTexture, NULL, &pTextureView);
assert(ret == S_OK);

pTexture->Release();

pRet->m_size = size;
pRet->m_pTextureView = pTextureView;

pRet->m_type = Type::Static;
return pRet;
}

void TextureD3D11::setData(const uint8_t* pData)
{
assert(isDynamic()); // Only dynamic texture can be set data
Expand Down Expand Up @@ -630,6 +673,25 @@ namespace onut
oRenderer->renderStates.textures[0].pop();
}

UINT TextureD3D11::getPitch()
{
switch (m_format)
{
case RenderTargetFormat::R8: return 1;
case RenderTargetFormat::RG8: return 2;
case RenderTargetFormat::RGBA8: return 4;
case RenderTargetFormat::R16: return 2;
case RenderTargetFormat::RG16: return 4;
case RenderTargetFormat::RGBA16: return 8;
case RenderTargetFormat::R32: return 4;
case RenderTargetFormat::RG32: return 8;
case RenderTargetFormat::RGBA32: return 16;
case RenderTargetFormat::RGB10A2: return 4;
case RenderTargetFormat::I8: return 1;
default: return 4;
};
}

DXGI_FORMAT TextureD3D11::getDXGIFormat()
{
switch (m_format)
Expand All @@ -644,6 +706,7 @@ namespace onut
case RenderTargetFormat::RG32: return DXGI_FORMAT_R32G32_FLOAT;
case RenderTargetFormat::RGBA32: return DXGI_FORMAT_R32G32B32A32_FLOAT;
case RenderTargetFormat::RGB10A2: return DXGI_FORMAT_R10G10B10A2_UNORM;
case RenderTargetFormat::I8: return DXGI_FORMAT_R8_UINT;
default: return DXGI_FORMAT_R8G8B8A8_UNORM;
};
}
Expand Down
1 change: 1 addition & 0 deletions src/TextureD3D11.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ namespace onut

void createRenderTargetViews(ID3D11Texture2D*& pTexture, ID3D11ShaderResourceView*& pTextureView, ID3D11RenderTargetView*& pRenderTargetView);
DXGI_FORMAT getDXGIFormat();
UINT getPitch();
void resolve();

ID3D11Texture2D* m_pResolvedTexture = nullptr; // Used for Multisample only
Expand Down

0 comments on commit eb4220a

Please sign in to comment.