Generate HLSL code for integer sampling.
TRAC #23472
Signed-off-by: Geoff Lang
Signed-off-by: Shannon Woods
Author: Nicolas Capens
diff --git a/src/compiler/OutputHLSL.cpp b/src/compiler/OutputHLSL.cpp
index 172e1bd..4f5a32e 100644
--- a/src/compiler/OutputHLSL.cpp
+++ b/src/compiler/OutputHLSL.cpp
@@ -34,24 +34,15 @@
{
TString name = "gl_texture";
- if (sampler == EbtSampler2D ||
- sampler == EbtISampler2D ||
- sampler == EbtUSampler2D ||
- sampler == EbtSampler2DArray ||
- sampler == EbtISampler2DArray ||
- sampler == EbtUSampler2DArray)
+ if (IsSampler2D(sampler))
{
name += "2D";
}
- else if (sampler == EbtSampler3D ||
- sampler == EbtISampler3D ||
- sampler == EbtUSampler3D)
+ else if (IsSampler3D(sampler))
{
name += "3D";
}
- else if (sampler == EbtSamplerCube ||
- sampler == EbtISamplerCube ||
- sampler == EbtUSamplerCube)
+ else if (IsSamplerCube(sampler))
{
name += "Cube";
}
@@ -972,117 +963,180 @@
}
out << ")\n"
- "{\n"
- " return ";
+ "{\n";
- // HLSL intrinsic
- if (mOutputType == SH_HLSL9_OUTPUT)
+ if (IsIntegerSampler(textureFunction->sampler) && IsSamplerCube(textureFunction->sampler))
{
- switch(textureFunction->sampler)
+ // Currently unsupported because TextureCube does not support Load
+ // This will require emulation using a Texture2DArray with 6 faces
+ if (textureFunction->sampler == EbtISamplerCube)
{
- case EbtSampler2D: out << "tex2D"; break;
- case EbtSamplerCube: out << "texCUBE"; break;
- default: UNREACHABLE();
+ out << " return int4(0, 0, 0, 0);";
}
- }
- else if (mOutputType == SH_HLSL11_OUTPUT)
- {
- out << "x.Sample";
- }
- else UNREACHABLE();
-
- if (mOutputType == SH_HLSL9_OUTPUT)
- {
- switch(textureFunction->mipmap)
+ else if (textureFunction->sampler == EbtUSamplerCube)
{
- case TextureFunction::IMPLICIT: out << "(s, "; break;
- case TextureFunction::BIAS: out << "bias(s, "; break;
- case TextureFunction::LOD: out << "lod(s, "; break;
- case TextureFunction::LOD0: out << "lod(s, "; break;
- default: UNREACHABLE();
+ out << " return uint4(0, 0, 0, 0);";
}
+ else UNREACHABLE();
}
- else if (mOutputType == SH_HLSL11_OUTPUT)
+ else
{
- switch(textureFunction->mipmap)
+ if (IsIntegerSampler(textureFunction->sampler))
{
- case TextureFunction::IMPLICIT: out << "(s, "; break;
- case TextureFunction::BIAS: out << "Bias(s, "; break;
- case TextureFunction::LOD: out << "Level(s, "; break;
- case TextureFunction::LOD0: out << "Level(s, "; break;
- default: UNREACHABLE();
- }
- }
- else UNREACHABLE();
-
- switch(hlslCoords)
- {
- case 2: out << "float2("; break;
- case 3: out << "float3("; break;
- case 4: out << "float4("; break;
- default: UNREACHABLE();
- }
-
- TString proj = "";
-
- if (textureFunction->proj)
- {
- switch(textureFunction->coords)
- {
- case 3: proj = " / t.z"; break;
- case 4: proj = " / t.w"; break;
- default: UNREACHABLE();
- }
- }
-
- out << "t.x" + proj + ", t.y" + proj;
-
- if (mOutputType == SH_HLSL9_OUTPUT)
- {
- if (hlslCoords >= 3)
- {
- if (textureFunction->coords < 3)
+ if (IsSampler2D(textureFunction->sampler))
{
- out << ", 0";
+ out << " uint width; uint height; uint numberOfLevels;\n"
+ " x.GetDimensions(0, width, height, numberOfLevels);\n";
+ }
+ else if (IsSampler3D(textureFunction->sampler))
+ {
+ out << " uint width; uint height; uint depth; uint numberOfLevels;\n"
+ " x.GetDimensions(0, width, height, depth, numberOfLevels);\n";
+ }
+ else UNREACHABLE();
+ }
+
+ out << " return ";
+
+ // HLSL intrinsic
+ if (mOutputType == SH_HLSL9_OUTPUT)
+ {
+ switch(textureFunction->sampler)
+ {
+ case EbtSampler2D: out << "tex2D"; break;
+ case EbtSamplerCube: out << "texCUBE"; break;
+ default: UNREACHABLE();
+ }
+
+ switch(textureFunction->mipmap)
+ {
+ case TextureFunction::IMPLICIT: out << "(s, "; break;
+ case TextureFunction::BIAS: out << "bias(s, "; break;
+ case TextureFunction::LOD: out << "lod(s, "; break;
+ case TextureFunction::LOD0: out << "lod(s, "; break;
+ default: UNREACHABLE();
+ }
+ }
+ else if (mOutputType == SH_HLSL11_OUTPUT)
+ {
+ if (IsIntegerSampler(textureFunction->sampler))
+ {
+ out << "x.Load(";
}
else
{
- out << ", t.z" + proj;
+ switch(textureFunction->mipmap)
+ {
+ case TextureFunction::IMPLICIT: out << "x.Sample(s, "; break;
+ case TextureFunction::BIAS: out << "x.SampleBias(s, "; break;
+ case TextureFunction::LOD: out << "x.SampleLevel(s, "; break;
+ case TextureFunction::LOD0: out << "x.SampleLevel(s, "; break;
+ default: UNREACHABLE();
+ }
}
}
+ else UNREACHABLE();
- if (hlslCoords == 4)
+ // Integer sampling requires integer addresses
+ TString addressx = "";
+ TString addressy = "";
+ TString addressz = "";
+ TString close = "";
+
+ if (IsIntegerSampler(textureFunction->sampler))
{
- switch(textureFunction->mipmap)
+ switch(hlslCoords)
{
- case TextureFunction::BIAS: out << ", bias"; break;
- case TextureFunction::LOD: out << ", lod"; break;
- case TextureFunction::LOD0: out << ", 0"; break;
+ case 2: out << "int3("; break;
+ case 3: out << "int4("; break;
+ default: UNREACHABLE();
+ }
+
+ addressx = "int(floor(float(width) * frac(";
+ addressy = "int(floor(float(height) * frac(";
+ addressz = "int(floor(float(depth) * frac(";
+ close = ")))";
+ }
+ else
+ {
+ switch(hlslCoords)
+ {
+ case 2: out << "float2("; break;
+ case 3: out << "float3("; break;
+ case 4: out << "float4("; break;
default: UNREACHABLE();
}
}
- out << "));\n";
- }
- else if (mOutputType == SH_HLSL11_OUTPUT)
- {
- if (hlslCoords >= 3)
+ TString proj = ""; // Only used for projected textures
+
+ if (textureFunction->proj)
{
- out << ", t.z" + proj;
+ switch(textureFunction->coords)
+ {
+ case 3: proj = " / t.z"; break;
+ case 4: proj = " / t.w"; break;
+ default: UNREACHABLE();
+ }
}
- switch(textureFunction->mipmap)
- {
- case TextureFunction::IMPLICIT: out << "));"; break;
- case TextureFunction::BIAS: out << "), bias);"; break;
- case TextureFunction::LOD: out << "), lod);"; break;
- case TextureFunction::LOD0: out << "), 0);"; break;
- default: UNREACHABLE();
- }
- }
- else UNREACHABLE();
+ out << addressx + ("t.x" + proj) + close + ", " + addressy + ("t.y" + proj) + close;
- out << "}\n"
+ if (mOutputType == SH_HLSL9_OUTPUT)
+ {
+ if (hlslCoords >= 3)
+ {
+ if (textureFunction->coords < 3)
+ {
+ out << ", 0";
+ }
+ else
+ {
+ out << ", t.z" + proj;
+ }
+ }
+
+ if (hlslCoords == 4)
+ {
+ switch(textureFunction->mipmap)
+ {
+ case TextureFunction::BIAS: out << ", bias"; break;
+ case TextureFunction::LOD: out << ", lod"; break;
+ case TextureFunction::LOD0: out << ", 0"; break;
+ default: UNREACHABLE();
+ }
+ }
+
+ out << "));\n";
+ }
+ else if (mOutputType == SH_HLSL11_OUTPUT)
+ {
+ if (hlslCoords >= 3)
+ {
+ out << ", " + addressz + ("t.z" + proj) + close;
+ }
+
+ if (!IsIntegerSampler(textureFunction->sampler))
+ {
+ switch(textureFunction->mipmap)
+ {
+ case TextureFunction::IMPLICIT: out << "));"; break;
+ case TextureFunction::BIAS: out << "), bias);"; break;
+ case TextureFunction::LOD: out << "), lod);"; break;
+ case TextureFunction::LOD0: out << "), 0);"; break;
+ default: UNREACHABLE();
+ }
+ }
+ else
+ {
+ out << ", 0));"; // Sample from the top level
+ }
+ }
+ else UNREACHABLE();
+ }
+
+ out << "\n"
+ "}\n"
"\n";
}
@@ -3014,9 +3068,11 @@
case EbtSampler2DArray: return "Texture2DArray";
case EbtSampler3D: return "Texture3D";
case EbtISampler2D: return "Texture2D<int4>";
+ case EbtISampler3D: return "Texture3D<int4>";
case EbtISamplerCube: return "TextureCube<int4>";
case EbtISampler2DArray: return "Texture2DArray<int4>";
case EbtUSampler2D: return "Texture2D<uint4>";
+ case EbtUSampler3D: return "Texture3D<uint4>";
case EbtUSamplerCube: return "TextureCube<uint4>";
case EbtUSampler2DArray: return "Texture2DArray<uint4>";
default: