summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2019-03-05 14:53:44 -0500
committerGitHub <noreply@github.com>2019-03-05 14:53:44 -0500
commit3d5546600fb4c585b6f6f6dcdb5e122698d1225e (patch)
treea11fc783760fd6e4b03c05b40fd4ff2f11c582da
parent890403f576a85a7dca90d9d20360cd73c9ec9604 (diff)
Hotfix/texture2d gather (#876)
* First pass test to see if GatherRed works. * Add support for generating R_Float32 textures. * Set default texture format. * * Alter the texture2d-gather to work with a R_Float32 texture * Add support for scalar Texture2d types with GatherXXX in stdlib * Remove some left over commented out test code from texture2d-gather.hlsl
-rw-r--r--source/slang/core.meta.slang19
-rw-r--r--source/slang/core.meta.slang.h21
-rw-r--r--tests/bugs/texture2d-gather.hlsl44
-rw-r--r--tools/render-test/shader-input-layout.cpp70
-rw-r--r--tools/render-test/shader-input-layout.h7
-rw-r--r--tools/render-test/shader-renderer-util.cpp5
6 files changed, 146 insertions, 20 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang
index 0c2b70e10..f3e57b90b 100644
--- a/source/slang/core.meta.slang
+++ b/source/slang/core.meta.slang
@@ -1001,8 +1001,12 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
static const struct {
char const* genericPrefix;
char const* elementType;
+ char const* outputType;
} kGatherExtensionCases[] = {
- { "__generic<T, let N : int>", "vector<T,N>" },
+ { "__generic<T, let N : int>", "vector<T,N>", "vector<T, 4>" },
+ { "", "float", "vector<float, 4>" },
+ { "", "int" , "vector<int, 4>"},
+ { "", "uint", "vector<uint, 4>"},
// TODO: need a case here for scalars `T`, but also
// need to ensure that case doesn't accidentally match
@@ -1022,7 +1026,6 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
sb << "<" << cc.elementType << " >";
sb << "\n{\n";
-
// `Gather`
// (tricky because it returns a 4-vector of the element type
// of the texture components...)
@@ -1046,27 +1049,29 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
auto componentIndex = kk.componentIndex;
auto componentName = kk.componentName;
+ auto outputType = cc.outputType;
+
EMIT_LINE_DIRECTIVE();
sb << "__target_intrinsic(glsl, \"textureGather($p, $2, " << componentIndex << ")\")\n";
- sb << "vector<T, 4> Gather" << componentName << "(SamplerState s, ";
+ sb << outputType << " Gather" << componentName << "(SamplerState s, ";
sb << "float" << kBaseTextureTypes[tt].coordCount << " location);\n";
EMIT_LINE_DIRECTIVE();
sb << "__target_intrinsic(glsl, \"textureGatherOffset($p, $2, $3, " << componentIndex << ")\")\n";
- sb << "vector<T, 4> Gather" << componentName << "(SamplerState s, ";
+ sb << outputType << " Gather" << componentName << "(SamplerState s, ";
sb << "float" << kBaseTextureTypes[tt].coordCount << " location, ";
sb << "constexpr int" << kBaseTextureTypes[tt].coordCount << " offset);\n";
EMIT_LINE_DIRECTIVE();
- sb << "vector<T, 4> Gather" << componentName << "(SamplerState s, ";
+ sb << outputType << " Gather" << componentName << "(SamplerState s, ";
sb << "float" << kBaseTextureTypes[tt].coordCount << " location, ";
sb << "constexpr int" << kBaseTextureTypes[tt].coordCount << " offset, ";
sb << "out uint status);\n";
EMIT_LINE_DIRECTIVE();
sb << "__target_intrinsic(glsl, \"textureGatherOffsets($p, $2, int" << kBaseTextureTypes[tt].coordCount << "[]($3, $4, $5, $6), " << componentIndex << ")\")\n";
- sb << "vector<T, 4> Gather" << componentName << "(SamplerState s, ";
+ sb << outputType << " Gather" << componentName << "(SamplerState s, ";
sb << "float" << kBaseTextureTypes[tt].coordCount << " location, ";
sb << "int" << kBaseTextureTypes[tt].coordCount << " offset1, ";
sb << "int" << kBaseTextureTypes[tt].coordCount << " offset2, ";
@@ -1074,7 +1079,7 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
sb << "int" << kBaseTextureTypes[tt].coordCount << " offset4);\n";
EMIT_LINE_DIRECTIVE();
- sb << "vector<T, 4> Gather" << componentName << "(SamplerState s, ";
+ sb << outputType << " Gather" << componentName << "(SamplerState s, ";
sb << "float" << kBaseTextureTypes[tt].coordCount << " location, ";
sb << "int" << kBaseTextureTypes[tt].coordCount << " offset1, ";
sb << "int" << kBaseTextureTypes[tt].coordCount << " offset2, ";
diff --git a/source/slang/core.meta.slang.h b/source/slang/core.meta.slang.h
index 25feb0005..2ae45a01c 100644
--- a/source/slang/core.meta.slang.h
+++ b/source/slang/core.meta.slang.h
@@ -1019,8 +1019,12 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
static const struct {
char const* genericPrefix;
char const* elementType;
+ char const* outputType;
} kGatherExtensionCases[] = {
- { "__generic<T, let N : int>", "vector<T,N>" },
+ { "__generic<T, let N : int>", "vector<T,N>", "vector<T, 4>" },
+ { "", "float", "vector<float, 4>" },
+ { "", "int" , "vector<int, 4>"},
+ { "", "uint", "vector<uint, 4>"},
// TODO: need a case here for scalars `T`, but also
// need to ensure that case doesn't accidentally match
@@ -1040,7 +1044,6 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
sb << "<" << cc.elementType << " >";
sb << "\n{\n";
-
// `Gather`
// (tricky because it returns a 4-vector of the element type
// of the texture components...)
@@ -1064,27 +1067,29 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
auto componentIndex = kk.componentIndex;
auto componentName = kk.componentName;
+ auto outputType = cc.outputType;
+
EMIT_LINE_DIRECTIVE();
sb << "__target_intrinsic(glsl, \"textureGather($p, $2, " << componentIndex << ")\")\n";
- sb << "vector<T, 4> Gather" << componentName << "(SamplerState s, ";
+ sb << outputType << " Gather" << componentName << "(SamplerState s, ";
sb << "float" << kBaseTextureTypes[tt].coordCount << " location);\n";
EMIT_LINE_DIRECTIVE();
sb << "__target_intrinsic(glsl, \"textureGatherOffset($p, $2, $3, " << componentIndex << ")\")\n";
- sb << "vector<T, 4> Gather" << componentName << "(SamplerState s, ";
+ sb << outputType << " Gather" << componentName << "(SamplerState s, ";
sb << "float" << kBaseTextureTypes[tt].coordCount << " location, ";
sb << "constexpr int" << kBaseTextureTypes[tt].coordCount << " offset);\n";
EMIT_LINE_DIRECTIVE();
- sb << "vector<T, 4> Gather" << componentName << "(SamplerState s, ";
+ sb << outputType << " Gather" << componentName << "(SamplerState s, ";
sb << "float" << kBaseTextureTypes[tt].coordCount << " location, ";
sb << "constexpr int" << kBaseTextureTypes[tt].coordCount << " offset, ";
sb << "out uint status);\n";
EMIT_LINE_DIRECTIVE();
sb << "__target_intrinsic(glsl, \"textureGatherOffsets($p, $2, int" << kBaseTextureTypes[tt].coordCount << "[]($3, $4, $5, $6), " << componentIndex << ")\")\n";
- sb << "vector<T, 4> Gather" << componentName << "(SamplerState s, ";
+ sb << outputType << " Gather" << componentName << "(SamplerState s, ";
sb << "float" << kBaseTextureTypes[tt].coordCount << " location, ";
sb << "int" << kBaseTextureTypes[tt].coordCount << " offset1, ";
sb << "int" << kBaseTextureTypes[tt].coordCount << " offset2, ";
@@ -1092,7 +1097,7 @@ for (int tt = 0; tt < kBaseTextureTypeCount; ++tt)
sb << "int" << kBaseTextureTypes[tt].coordCount << " offset4);\n";
EMIT_LINE_DIRECTIVE();
- sb << "vector<T, 4> Gather" << componentName << "(SamplerState s, ";
+ sb << outputType << " Gather" << componentName << "(SamplerState s, ";
sb << "float" << kBaseTextureTypes[tt].coordCount << " location, ";
sb << "int" << kBaseTextureTypes[tt].coordCount << " offset1, ";
sb << "int" << kBaseTextureTypes[tt].coordCount << " offset2, ";
@@ -1197,7 +1202,7 @@ for (auto op : binaryOps)
sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M> operator" << op.opName << "(" << leftQual << "matrix<" << leftType << ",N,M> left, " << rightType << " right);\n";
}
}
-SLANG_RAW("#line 1182 \"core.meta.slang\"")
+SLANG_RAW("#line 1187 \"core.meta.slang\"")
SLANG_RAW("\n")
SLANG_RAW("\n")
SLANG_RAW("// Operators to apply to `enum` types\n")
diff --git a/tests/bugs/texture2d-gather.hlsl b/tests/bugs/texture2d-gather.hlsl
new file mode 100644
index 000000000..3886472bd
--- /dev/null
+++ b/tests/bugs/texture2d-gather.hlsl
@@ -0,0 +1,44 @@
+//TEST(smoke):COMPARE_HLSL_RENDER:
+//TEST_INPUT: Texture2D(size=16, content=chessboard, format=R_Float32):dxbinding(0),glbinding(0)
+
+Texture2D<float> g_texture : register(t0);
+SamplerState g_sampler : register(s0);
+
+cbuffer Uniforms
+{
+ float4x4 modelViewProjection;
+}
+
+struct AssembledVertex
+{
+ float3 position;
+ float3 color;
+};
+
+// Vertex Shader
+struct VertexStageInput
+{
+ AssembledVertex assembledVertex : A;
+};
+
+struct VertexStageOutput
+{
+ float4 color : COLOR;
+ float4 position : SV_Position;
+};
+
+VertexStageOutput vertexMain(VertexStageInput input)
+{
+ VertexStageOutput output;
+
+ output.position = mul(modelViewProjection, float4(input.assembledVertex.position, 1.0));
+ output.color = float4(input.assembledVertex.color, 1.0f);
+
+ return output;
+}
+
+// Fragment Shader
+float4 fragmentMain(VertexStageOutput input) : SV_Target
+{
+ return g_texture.GatherRed(g_sampler, input.color.xy);
+} \ No newline at end of file
diff --git a/tools/render-test/shader-input-layout.cpp b/tools/render-test/shader-input-layout.cpp
index 5a2021b01..6d51a1980 100644
--- a/tools/render-test/shader-input-layout.cpp
+++ b/tools/render-test/shader-input-layout.cpp
@@ -208,10 +208,25 @@ namespace renderer_test
}
else if(word == "format")
{
+ Format format = Format::Unknown;
+
parser.Read("=");
auto formatWord = parser.ReadWord();
if(formatWord == "R_UInt32")
- entry.bufferDesc.format = Format::R_UInt32;
+ {
+ format = Format::R_UInt32;
+ }
+ else if (formatWord == "R_Float32")
+ {
+ format = Format::R_Float32;
+ }
+ else if (formatWord == "RGBA_Unorm_UInt8")
+ {
+ format = Format::RGBA_Unorm_UInt8;
+ }
+
+ entry.textureDesc.format = format;
+ entry.bufferDesc.format = format;
}
if (parser.LookAhead(","))
parser.Read(",");
@@ -265,15 +280,64 @@ namespace renderer_test
}
}
}
+ }
+
+ void generateTextureData(TextureData& output, const InputTextureDesc& desc)
+ {
+ switch (desc.format)
+ {
+ case Format::RGBA_Unorm_UInt8:
+ {
+ generateTextureDataRGB8(output, desc);
+ break;
+ }
+ case Format::R_Float32:
+ {
+ TextureData work;
+ generateTextureDataRGB8(work, desc);
+ output.textureSize = work.textureSize;
+ output.mipLevels = work.mipLevels;
+ output.arraySize = work.arraySize;
+ List<List<unsigned int>>& dstBuffer = output.dataBuffer;
+
+ int numMips = int(work.dataBuffer.Count());
+ dstBuffer.SetSize(numMips);
+
+ for (int i = 0; i < numMips; ++i)
+ {
+ const int numPixels = int(work.dataBuffer[i].Count());
+ const unsigned int* srcPixels = work.dataBuffer[i].Buffer();
+
+ dstBuffer[i].SetSize(numPixels);
+
+ float* dstPixels = (float*)dstBuffer[i].Buffer();
+
+ for (int j = 0; j < numPixels; ++j)
+ {
+ // Copy out red
+ const unsigned int srcPixel = srcPixels[j];
+ const float value = (srcPixel & 0xff) * 1.0f / 255;
+ dstPixels[j] = value;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ SLANG_ASSERT(!"Unhandled format");
+ break;
+ }
+ }
}
- void generateTextureData(TextureData & output, const InputTextureDesc & inputDesc)
+
+ void generateTextureDataRGB8(TextureData& output, const InputTextureDesc& inputDesc)
{
int arrLen = inputDesc.arrayLength;
if (arrLen == 0)
arrLen = 1;
- List<List<unsigned int>> & dataBuffer = output.dataBuffer;
+ List<List<unsigned int>>& dataBuffer = output.dataBuffer;
int arraySize = arrLen;
if (inputDesc.isCube)
arraySize *= 6;
diff --git a/tools/render-test/shader-input-layout.h b/tools/render-test/shader-input-layout.h
index 1044a6eea..d9188fadd 100644
--- a/tools/render-test/shader-input-layout.h
+++ b/tools/render-test/shader-input-layout.h
@@ -27,6 +27,9 @@ struct InputTextureDesc
bool isDepthTexture = false;
bool isRWTexture = false;
int size = 4;
+
+ Format format = Format::RGBA_Unorm_UInt8;
+
InputTextureContent content = InputTextureContent::One;
};
@@ -80,7 +83,9 @@ public:
void Parse(const char * source);
};
-void generateTextureData(TextureData & output, const InputTextureDesc & desc);
+void generateTextureDataRGB8(TextureData& output, const InputTextureDesc& desc);
+void generateTextureData(TextureData& output, const InputTextureDesc& desc);
+
} // namespace render_test
diff --git a/tools/render-test/shader-renderer-util.cpp b/tools/render-test/shader-renderer-util.cpp
index 0d0f8a3a5..3dc717c5b 100644
--- a/tools/render-test/shader-renderer-util.cpp
+++ b/tools/render-test/shader-renderer-util.cpp
@@ -28,7 +28,10 @@ void BindingStateImpl::apply(Renderer* renderer, PipelineType pipelineType)
TextureResource::Desc textureResourceDesc;
textureResourceDesc.init(Resource::Type::Unknown);
- textureResourceDesc.format = Format::RGBA_Unorm_UInt8;
+ // Default to RGBA_Unorm_UInt8
+ const Format format = (inputDesc.format == Format::Unknown) ? Format::RGBA_Unorm_UInt8 : inputDesc.format;
+
+ textureResourceDesc.format = format;
textureResourceDesc.numMipLevels = texData.mipLevels;
textureResourceDesc.arraySize = inputDesc.arrayLength;
textureResourceDesc.bindFlags = bindFlags;