diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2019-03-05 14:53:44 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-03-05 14:53:44 -0500 |
| commit | 3d5546600fb4c585b6f6f6dcdb5e122698d1225e (patch) | |
| tree | a11fc783760fd6e4b03c05b40fd4ff2f11c582da | |
| parent | 890403f576a85a7dca90d9d20360cd73c9ec9604 (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.slang | 19 | ||||
| -rw-r--r-- | source/slang/core.meta.slang.h | 21 | ||||
| -rw-r--r-- | tests/bugs/texture2d-gather.hlsl | 44 | ||||
| -rw-r--r-- | tools/render-test/shader-input-layout.cpp | 70 | ||||
| -rw-r--r-- | tools/render-test/shader-input-layout.h | 7 | ||||
| -rw-r--r-- | tools/render-test/shader-renderer-util.cpp | 5 |
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; |
