diff --git a/Test/baseResults/hlsl.samplecmp.negative.frag.out b/Test/baseResults/hlsl.samplecmp.negative.frag.out new file mode 100644 index 000000000..99cfdbf6a --- /dev/null +++ b/Test/baseResults/hlsl.samplecmp.negative.frag.out @@ -0,0 +1,96 @@ +hlsl.samplecmp.negative.frag +ERROR: 0:9: '' : expected: SamplerComparisonState +ERROR: 1 compilation errors. No code generated. + + +Shader version: 500 +gl_FragCoord origin is upper left +ERROR: node is still EOpNull! +0:7 Function Definition: @main( ( temp 4-component vector of float) +0:7 Function Parameters: +0:? Sequence +0:8 texture ( temp float) +0:8 Construct combined texture-sampler ( temp sampler2DShadow) +0:8 'g_shadowTex' ( uniform texture2D) +0:8 'g_shadowSamplerComp' ( uniform sampler) +0:8 Construct vec3 ( temp 3-component vector of float) +0:? Constant: +0:? 0.000000 +0:? 0.000000 +0:8 Constant: +0:8 0.000000 +0:9 ERROR: Bad aggregation op + ( temp float) +0:9 'g_shadowTex' ( uniform texture2D) +0:9 'g_shadowSampler' ( uniform sampler) +0:? Constant: +0:? 0.000000 +0:? 0.000000 +0:9 Constant: +0:9 0.000000 +0:11 Branch: Return with expression +0:11 Constant: +0:11 0.000000 +0:11 0.000000 +0:11 0.000000 +0:11 0.000000 +0:7 Function Definition: main( ( temp void) +0:7 Function Parameters: +0:? Sequence +0:7 move second child to first child ( temp 4-component vector of float) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) +0:7 Function Call: @main( ( temp 4-component vector of float) +0:? Linker Objects +0:? 'g_shadowTex' ( uniform texture2D) +0:? 'g_shadowSampler' ( uniform sampler) +0:? 'g_shadowSamplerComp' ( uniform sampler) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) + + +Linked fragment stage: + + +Shader version: 500 +gl_FragCoord origin is upper left +ERROR: node is still EOpNull! +0:7 Function Definition: @main( ( temp 4-component vector of float) +0:7 Function Parameters: +0:? Sequence +0:8 texture ( temp float) +0:8 Construct combined texture-sampler ( temp sampler2DShadow) +0:8 'g_shadowTex' ( uniform texture2D) +0:8 'g_shadowSamplerComp' ( uniform sampler) +0:8 Construct vec3 ( temp 3-component vector of float) +0:? Constant: +0:? 0.000000 +0:? 0.000000 +0:8 Constant: +0:8 0.000000 +0:9 ERROR: Bad aggregation op + ( temp float) +0:9 'g_shadowTex' ( uniform texture2D) +0:9 'g_shadowSampler' ( uniform sampler) +0:? Constant: +0:? 0.000000 +0:? 0.000000 +0:9 Constant: +0:9 0.000000 +0:11 Branch: Return with expression +0:11 Constant: +0:11 0.000000 +0:11 0.000000 +0:11 0.000000 +0:11 0.000000 +0:7 Function Definition: main( ( temp void) +0:7 Function Parameters: +0:? Sequence +0:7 move second child to first child ( temp 4-component vector of float) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) +0:7 Function Call: @main( ( temp 4-component vector of float) +0:? Linker Objects +0:? 'g_shadowTex' ( uniform texture2D) +0:? 'g_shadowSampler' ( uniform sampler) +0:? 'g_shadowSamplerComp' ( uniform sampler) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) + +SPIR-V is not generated for failed compile or link diff --git a/Test/baseResults/hlsl.samplecmp.negative2.frag.out b/Test/baseResults/hlsl.samplecmp.negative2.frag.out new file mode 100644 index 000000000..996b3f870 --- /dev/null +++ b/Test/baseResults/hlsl.samplecmp.negative2.frag.out @@ -0,0 +1,80 @@ +hlsl.samplecmp.negative2.frag +ERROR: 0:7: '' : expected: SamplerComparisonState +ERROR: 1 compilation errors. No code generated. + + +Shader version: 500 +gl_FragCoord origin is upper left +ERROR: node is still EOpNull! +0:6 Function Definition: @main( ( temp 4-component vector of float) +0:6 Function Parameters: +0:? Sequence +0:7 ERROR: Bad aggregation op + ( temp 4-component vector of float) +0:7 'g_shadowTex' ( uniform texture2D) +0:7 'g_shadowSampler' ( uniform sampler) +0:? Constant: +0:? 0.000000 +0:? 0.000000 +0:7 Constant: +0:7 0.000000 +0:? Constant: +0:? 0 (const int) +0:? 0 (const int) +0:9 Branch: Return with expression +0:9 Constant: +0:9 0.000000 +0:9 0.000000 +0:9 0.000000 +0:9 0.000000 +0:6 Function Definition: main( ( temp void) +0:6 Function Parameters: +0:? Sequence +0:6 move second child to first child ( temp 4-component vector of float) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) +0:6 Function Call: @main( ( temp 4-component vector of float) +0:? Linker Objects +0:? 'g_shadowTex' ( uniform texture2D) +0:? 'g_shadowSampler' ( uniform sampler) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) + + +Linked fragment stage: + + +Shader version: 500 +gl_FragCoord origin is upper left +ERROR: node is still EOpNull! +0:6 Function Definition: @main( ( temp 4-component vector of float) +0:6 Function Parameters: +0:? Sequence +0:7 ERROR: Bad aggregation op + ( temp 4-component vector of float) +0:7 'g_shadowTex' ( uniform texture2D) +0:7 'g_shadowSampler' ( uniform sampler) +0:? Constant: +0:? 0.000000 +0:? 0.000000 +0:7 Constant: +0:7 0.000000 +0:? Constant: +0:? 0 (const int) +0:? 0 (const int) +0:9 Branch: Return with expression +0:9 Constant: +0:9 0.000000 +0:9 0.000000 +0:9 0.000000 +0:9 0.000000 +0:6 Function Definition: main( ( temp void) +0:6 Function Parameters: +0:? Sequence +0:6 move second child to first child ( temp 4-component vector of float) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) +0:6 Function Call: @main( ( temp 4-component vector of float) +0:? Linker Objects +0:? 'g_shadowTex' ( uniform texture2D) +0:? 'g_shadowSampler' ( uniform sampler) +0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) + +SPIR-V is not generated for failed compile or link diff --git a/Test/hlsl.samplecmp.negative.frag b/Test/hlsl.samplecmp.negative.frag new file mode 100644 index 000000000..cea87bd6d --- /dev/null +++ b/Test/hlsl.samplecmp.negative.frag @@ -0,0 +1,12 @@ + +Texture2D g_shadowTex; +SamplerState g_shadowSampler; +SamplerComparisonState g_shadowSamplerComp; + +float4 main() : SV_Target0 +{ + g_shadowTex.SampleCmp(g_shadowSamplerComp, float2(0,0), 0); // OK + g_shadowTex.SampleCmp(g_shadowSampler, float2(0,0), 0); // ERROR (should be comparison sampler) + + return 0; +} diff --git a/Test/hlsl.samplecmp.negative2.frag b/Test/hlsl.samplecmp.negative2.frag new file mode 100644 index 000000000..33a2133ab --- /dev/null +++ b/Test/hlsl.samplecmp.negative2.frag @@ -0,0 +1,10 @@ + +Texture2D g_shadowTex; +SamplerState g_shadowSampler; + +float4 main() : SV_Target0 +{ + g_shadowTex.GatherCmpRed(g_shadowSampler, float2(0,0), 0, int2(0,0)); // ERROR (should be comparison sampler) + + return 0; +} diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index 2889e1a38..b23674ea6 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -212,6 +212,8 @@ INSTANTIATE_TEST_CASE_P( {"hlsl.samplecmp.basic.dx10.frag", "main"}, {"hlsl.samplecmp.offset.dx10.frag", "main"}, {"hlsl.samplecmp.offsetarray.dx10.frag", "main"}, + {"hlsl.samplecmp.negative.frag", "main"}, + {"hlsl.samplecmp.negative2.frag", "main"}, {"hlsl.samplecmplevelzero.array.dx10.frag", "main"}, {"hlsl.samplecmplevelzero.basic.dx10.frag", "main"}, {"hlsl.samplecmplevelzero.offset.dx10.frag", "main"}, diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index 4ba0d87d9..6a6cb3f16 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -3144,6 +3144,18 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType TIntermTyped* argCmpVal = argAggregate->getSequence()[3]->getAsTyped(); TIntermTyped* argOffset = nullptr; + // Sampler argument should be a sampler. + if (argSamp->getType().getBasicType() != EbtSampler) { + error(loc, "expected: sampler type", "", ""); + return; + } + + // Sampler should be a SamplerComparisonState + if (! argSamp->getType().getSampler().isShadow()) { + error(loc, "expected: SamplerComparisonState", "", ""); + return; + } + // optional offset value if (argAggregate->getSequence().size() > 4) argOffset = argAggregate->getSequence()[4]->getAsTyped(); @@ -3381,6 +3393,18 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType bool hasOffset1 = false; bool hasOffset4 = false; + // Sampler argument should be a sampler. + if (argSamp->getType().getBasicType() != EbtSampler) { + error(loc, "expected: sampler type", "", ""); + return; + } + + // Cmp forms require SamplerComparisonState + if (cmpValues > 0 && ! argSamp->getType().getSampler().isShadow()) { + error(loc, "expected: SamplerComparisonState", "", ""); + return; + } + // Only 2D forms can have offsets. Discover if we have 0, 1 or 4 offsets. if (dim == Esd2D) { hasOffset1 = (argSize == (4+cmpValues) || argSize == (5+cmpValues));