Commit 4e6d3eaf by LoopDawg

HLSL: require coverage mask to be arrayed output.

SPIR-V requires the coverage mask to be an array of integers, but HLSL allows scalar integers. This adds the requisite type conversion and wrapped entry point handling. Fixes: #1202
parent cfb05ec7
...@@ -93,13 +93,16 @@ using depth_any ...@@ -93,13 +93,16 @@ using depth_any
0:16 Constant: 0:16 Constant:
0:16 1 (const int) 0:16 1 (const int)
0:16 move second child to first child ( temp int) 0:16 move second child to first child ( temp int)
0:? 'sampleMask' ( out int SampleMaskIn) 0:16 direct index ( out int SampleMaskIn)
0:? 'sampleMask' ( out 1-element array of int SampleMaskIn)
0:16 Constant:
0:16 0 (const int)
0:? 'sampleMask' ( temp int) 0:? 'sampleMask' ( temp int)
0:? Linker Objects 0:? Linker Objects
0:? '@entryPointOutput.Depth' ( out float FragDepth) 0:? '@entryPointOutput.Depth' ( out float FragDepth)
0:? '@entryPointOutput.Color' (layout( location=0) out 4-component vector of float) 0:? '@entryPointOutput.Color' (layout( location=0) out 4-component vector of float)
0:? 'inpos' ( noperspective in 4-component vector of float FragCoord) 0:? 'inpos' ( noperspective in 4-component vector of float FragCoord)
0:? 'sampleMask' ( out int SampleMaskIn) 0:? 'sampleMask' ( out 1-element array of int SampleMaskIn)
Linked fragment stage: Linked fragment stage:
...@@ -199,22 +202,25 @@ using depth_any ...@@ -199,22 +202,25 @@ using depth_any
0:16 Constant: 0:16 Constant:
0:16 1 (const int) 0:16 1 (const int)
0:16 move second child to first child ( temp int) 0:16 move second child to first child ( temp int)
0:? 'sampleMask' ( out int SampleMaskIn) 0:16 direct index ( out int SampleMaskIn)
0:? 'sampleMask' ( out 1-element array of int SampleMaskIn)
0:16 Constant:
0:16 0 (const int)
0:? 'sampleMask' ( temp int) 0:? 'sampleMask' ( temp int)
0:? Linker Objects 0:? Linker Objects
0:? '@entryPointOutput.Depth' ( out float FragDepth) 0:? '@entryPointOutput.Depth' ( out float FragDepth)
0:? '@entryPointOutput.Color' (layout( location=0) out 4-component vector of float) 0:? '@entryPointOutput.Color' (layout( location=0) out 4-component vector of float)
0:? 'inpos' ( noperspective in 4-component vector of float FragCoord) 0:? 'inpos' ( noperspective in 4-component vector of float FragCoord)
0:? 'sampleMask' ( out int SampleMaskIn) 0:? 'sampleMask' ( out 1-element array of int SampleMaskIn)
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80006 // Generated by (magic number): 80006
// Id's are bound by 88 // Id's are bound by 92
Capability Shader Capability Shader
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 68 78 82 86 EntryPoint Fragment 4 "main" 68 78 82 88
ExecutionMode 4 OriginUpperLeft ExecutionMode 4 OriginUpperLeft
ExecutionMode 4 DepthReplacing ExecutionMode 4 DepthReplacing
Source HLSL 500 Source HLSL 500
...@@ -246,12 +252,12 @@ using depth_any ...@@ -246,12 +252,12 @@ using depth_any
Name 74 "param" Name 74 "param"
Name 78 "@entryPointOutput.Color" Name 78 "@entryPointOutput.Color"
Name 82 "@entryPointOutput.Depth" Name 82 "@entryPointOutput.Depth"
Name 86 "sampleMask" Name 88 "sampleMask"
Decorate 68(inpos) NoPerspective Decorate 68(inpos) NoPerspective
Decorate 68(inpos) BuiltIn FragCoord Decorate 68(inpos) BuiltIn FragCoord
Decorate 78(@entryPointOutput.Color) Location 0 Decorate 78(@entryPointOutput.Color) Location 0
Decorate 82(@entryPointOutput.Depth) BuiltIn FragDepth Decorate 82(@entryPointOutput.Depth) BuiltIn FragDepth
Decorate 86(sampleMask) BuiltIn SampleMask Decorate 88(sampleMask) BuiltIn SampleMask
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeFloat 32 6: TypeFloat 32
...@@ -278,8 +284,11 @@ using depth_any ...@@ -278,8 +284,11 @@ using depth_any
78(@entryPointOutput.Color): 77(ptr) Variable Output 78(@entryPointOutput.Color): 77(ptr) Variable Output
81: TypePointer Output 6(float) 81: TypePointer Output 6(float)
82(@entryPointOutput.Depth): 81(ptr) Variable Output 82(@entryPointOutput.Depth): 81(ptr) Variable Output
85: TypePointer Output 17(int) 85: 42(int) Constant 1
86(sampleMask): 85(ptr) Variable Output 86: TypeArray 17(int) 85
87: TypePointer Output 86
88(sampleMask): 87(ptr) Variable Output
90: TypePointer Output 17(int)
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
66(inpos): 16(ptr) Variable Function 66(inpos): 16(ptr) Variable Function
...@@ -301,8 +310,9 @@ using depth_any ...@@ -301,8 +310,9 @@ using depth_any
83: 7(ptr) AccessChain 70(flattenTemp) 59 83: 7(ptr) AccessChain 70(flattenTemp) 59
84: 6(float) Load 83 84: 6(float) Load 83
Store 82(@entryPointOutput.Depth) 84 Store 82(@entryPointOutput.Depth) 84
87: 17(int) Load 71(sampleMask) 89: 17(int) Load 71(sampleMask)
Store 86(sampleMask) 87 91: 90(ptr) AccessChain 88(sampleMask) 53
Store 91 89
Return Return
FunctionEnd FunctionEnd
13(MyFunc(f1;f1;f1;f1;): 2 Function None 8 13(MyFunc(f1;f1;f1;f1;): 2 Function None 8
......
// Verify that coverage mask is an array, as required by SPIR-V.
struct PS_INPUT
{
};
struct PS_OUTPUT
{
float4 vColor : SV_Target0;
uint nCoverageMask : SV_Coverage;
};
PS_OUTPUT main( PS_INPUT i )
{
PS_OUTPUT o;
o.vColor = float4(1.0, 0.0, 0.0, 1.0);
o.nCoverageMask = 0;
return o;
}
...@@ -148,6 +148,7 @@ INSTANTIATE_TEST_CASE_P( ...@@ -148,6 +148,7 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.constructArray.vert", "main"}, {"hlsl.constructArray.vert", "main"},
{"hlsl.constructexpr.frag", "main"}, {"hlsl.constructexpr.frag", "main"},
{"hlsl.constructimat.frag", "main"}, {"hlsl.constructimat.frag", "main"},
{"hlsl.coverage.frag", "main"},
{"hlsl.depthGreater.frag", "PixelShaderFunction"}, {"hlsl.depthGreater.frag", "PixelShaderFunction"},
{"hlsl.depthLess.frag", "PixelShaderFunction"}, {"hlsl.depthLess.frag", "PixelShaderFunction"},
{"hlsl.discard.frag", "PixelShaderFunction"}, {"hlsl.discard.frag", "PixelShaderFunction"},
......
...@@ -1481,6 +1481,14 @@ void HlslParseContext::fixBuiltInIoType(TType& type) ...@@ -1481,6 +1481,14 @@ void HlslParseContext::fixBuiltInIoType(TType& type)
case EbvTessLevelOuter: requiredArraySize = 4; break; case EbvTessLevelOuter: requiredArraySize = 4; break;
case EbvTessLevelInner: requiredArraySize = 2; break; case EbvTessLevelInner: requiredArraySize = 2; break;
case EbvSampleMask:
{
// Promote scalar to array of size 1. Leave existing arrays alone.
if (!type.isArray())
requiredArraySize = 1;
break;
}
case EbvWorkGroupId: requiredVectorSize = 3; break; case EbvWorkGroupId: requiredVectorSize = 3; break;
case EbvGlobalInvocationId: requiredVectorSize = 3; break; case EbvGlobalInvocationId: requiredVectorSize = 3; break;
case EbvLocalInvocationId: requiredVectorSize = 3; break; case EbvLocalInvocationId: requiredVectorSize = 3; break;
...@@ -2700,6 +2708,15 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op ...@@ -2700,6 +2708,15 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
} else if (assignsClipPos(left)) { } else if (assignsClipPos(left)) {
// Position can require special handling: see comment above assignPosition // Position can require special handling: see comment above assignPosition
return assignPosition(loc, op, left, right); return assignPosition(loc, op, left, right);
} else if (left->getQualifier().builtIn == EbvSampleMask) {
// Certain builtins are required to be arrayed outputs in SPIR-V, but may internally be scalars
// in the shader. Copy the scalar RHS into the LHS array element zero, if that happens.
if (left->isArray() && !right->isArray()) {
const TType derefType(left->getType(), 0);
left = intermediate.addIndex(EOpIndexDirect, left, intermediate.addConstantUnion(0, loc), loc);
left->setType(derefType);
// Fall through to add assign.
}
} }
return intermediate.addAssign(op, left, right, loc); return intermediate.addAssign(op, left, right, loc);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment