Commit 84a30c8b by John Kessenich Committed by GitHub

Merge pull request #774 from steve-lunarg/tess-ctrlpt-pcf

HLSL: support per control point patch const fn invocation
parents e70fcf2d e741249b
...@@ -869,14 +869,20 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* gls ...@@ -869,14 +869,20 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* gls
builder.addCapability(spv::CapabilityShader); builder.addCapability(spv::CapabilityShader);
break; break;
case EShLangTessEvaluation:
case EShLangTessControl: case EShLangTessControl:
builder.addCapability(spv::CapabilityTessellation); builder.addCapability(spv::CapabilityTessellation);
builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, glslangIntermediate->getVertices());
break;
case EShLangTessEvaluation: glslang::TLayoutGeometry primitive;
builder.addCapability(spv::CapabilityTessellation);
switch (glslangIntermediate->getInputPrimitive()) { if (glslangIntermediate->getStage() == EShLangTessControl) {
builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, glslangIntermediate->getVertices());
primitive = glslangIntermediate->getOutputPrimitive();
} else {
primitive = glslangIntermediate->getInputPrimitive();
}
switch (primitive) {
case glslang::ElgTriangles: mode = spv::ExecutionModeTriangles; break; case glslang::ElgTriangles: mode = spv::ExecutionModeTriangles; break;
case glslang::ElgQuads: mode = spv::ExecutionModeQuads; break; case glslang::ElgQuads: mode = spv::ExecutionModeQuads; break;
case glslang::ElgIsolines: mode = spv::ExecutionModeIsolines; break; case glslang::ElgIsolines: mode = spv::ExecutionModeIsolines; break;
......
...@@ -60,14 +60,14 @@ output primitive = line_strip ...@@ -60,14 +60,14 @@ output primitive = line_strip
0:? 'VertexID' (layout( location=0) in 3-element array of uint) 0:? 'VertexID' (layout( location=0) in 3-element array of uint)
0:16 move second child to first child ( temp 3-element array of uint) 0:16 move second child to first child ( temp 3-element array of uint)
0:? 'test' ( temp 3-element array of uint) 0:? 'test' ( temp 3-element array of uint)
0:? 'test' (layout( location=3) in 3-element array of uint) 0:? 'test' (layout( location=1) in 3-element array of uint)
0:16 Function Call: @main(u1[3];u1[3];struct-PSInput-f1-i11; ( temp void) 0:16 Function Call: @main(u1[3];u1[3];struct-PSInput-f1-i11; ( temp void)
0:? 'VertexID' ( temp 3-element array of uint) 0:? 'VertexID' ( temp 3-element array of uint)
0:? 'test' ( temp 3-element array of uint) 0:? 'test' ( temp 3-element array of uint)
0:? 'OutputStream' ( temp structure{ temp float myfloat, temp int something}) 0:? 'OutputStream' ( temp structure{ temp float myfloat, temp int something})
0:? Linker Objects 0:? Linker Objects
0:? 'VertexID' (layout( location=0) in 3-element array of uint) 0:? 'VertexID' (layout( location=0) in 3-element array of uint)
0:? 'test' (layout( location=3) in 3-element array of uint) 0:? 'test' (layout( location=1) in 3-element array of uint)
Linked geometry stage: Linked geometry stage:
...@@ -134,14 +134,14 @@ output primitive = line_strip ...@@ -134,14 +134,14 @@ output primitive = line_strip
0:? 'VertexID' (layout( location=0) in 3-element array of uint) 0:? 'VertexID' (layout( location=0) in 3-element array of uint)
0:16 move second child to first child ( temp 3-element array of uint) 0:16 move second child to first child ( temp 3-element array of uint)
0:? 'test' ( temp 3-element array of uint) 0:? 'test' ( temp 3-element array of uint)
0:? 'test' (layout( location=3) in 3-element array of uint) 0:? 'test' (layout( location=1) in 3-element array of uint)
0:16 Function Call: @main(u1[3];u1[3];struct-PSInput-f1-i11; ( temp void) 0:16 Function Call: @main(u1[3];u1[3];struct-PSInput-f1-i11; ( temp void)
0:? 'VertexID' ( temp 3-element array of uint) 0:? 'VertexID' ( temp 3-element array of uint)
0:? 'test' ( temp 3-element array of uint) 0:? 'test' ( temp 3-element array of uint)
0:? 'OutputStream' ( temp structure{ temp float myfloat, temp int something}) 0:? 'OutputStream' ( temp structure{ temp float myfloat, temp int something})
0:? Linker Objects 0:? Linker Objects
0:? 'VertexID' (layout( location=0) in 3-element array of uint) 0:? 'VertexID' (layout( location=0) in 3-element array of uint)
0:? 'test' (layout( location=3) in 3-element array of uint) 0:? 'test' (layout( location=1) in 3-element array of uint)
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
...@@ -173,7 +173,7 @@ output primitive = line_strip ...@@ -173,7 +173,7 @@ output primitive = line_strip
Name 53 "param" Name 53 "param"
Name 55 "param" Name 55 "param"
Decorate 45(VertexID) Location 0 Decorate 45(VertexID) Location 0
Decorate 48(test) Location 3 Decorate 48(test) Location 1
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeInt 32 0 6: TypeInt 32 0
......
hlsl.hull.void.tesc hlsl.hull.void.tesc
Shader version: 450 Shader version: 450
vertices = 3 vertices = 3
vertex spacing = fractional_even_spacing
0:? Sequence 0:? Sequence
0:26 Function Definition: @main(struct-VS_OUT-vf31[3]; ( temp structure{ temp 3-component vector of float cpoint}) 0:26 Function Definition: @main(struct-VS_OUT-vf31[3]; ( temp structure{ temp 3-component vector of float cpoint})
0:26 Function Parameters: 0:26 Function Parameters:
...@@ -27,7 +28,9 @@ vertices = 3 ...@@ -27,7 +28,9 @@ vertices = 3
0:? 'ip' ( temp 3-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' ( temp 3-element array of structure{ temp 3-component vector of float cpoint})
0:? 'ip' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float cpoint})
0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint}) 0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint})
0:? '@entryPointOutput' (layout( location=0) out structure{ temp 3-component vector of float cpoint}) 0:26 indirect index ( temp structure{ temp 3-component vector of float cpoint})
0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float cpoint})
0:? 'InvocationId' ( in uint InvocationID)
0:26 Function Call: @main(struct-VS_OUT-vf31[3]; ( temp structure{ temp 3-component vector of float cpoint}) 0:26 Function Call: @main(struct-VS_OUT-vf31[3]; ( temp structure{ temp 3-component vector of float cpoint})
0:? 'ip' ( temp 3-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' ( temp 3-element array of structure{ temp 3-component vector of float cpoint})
0:? Barrier ( temp void) 0:? Barrier ( temp void)
...@@ -38,11 +41,12 @@ vertices = 3 ...@@ -38,11 +41,12 @@ vertices = 3
0:? Constant: 0:? Constant:
0:? 0 (const int) 0:? 0 (const int)
0:? true case 0:? true case
0:? Function Call: PCF( ( temp void) 0:? Sequence
0:? Function Call: PCF( ( temp void)
0:33 Function Definition: PCF( ( temp void) 0:33 Function Definition: PCF( ( temp void)
0:33 Function Parameters: 0:33 Function Parameters:
0:? Linker Objects 0:? Linker Objects
0:? '@entryPointOutput' (layout( location=0) out structure{ temp 3-component vector of float cpoint}) 0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float cpoint})
0:? 'ip' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float cpoint})
0:? 'InvocationId' ( in uint InvocationID) 0:? 'InvocationId' ( in uint InvocationID)
...@@ -52,6 +56,7 @@ Linked tessellation control stage: ...@@ -52,6 +56,7 @@ Linked tessellation control stage:
Shader version: 450 Shader version: 450
vertices = 3 vertices = 3
vertex spacing = fractional_even_spacing
0:? Sequence 0:? Sequence
0:26 Function Definition: @main(struct-VS_OUT-vf31[3]; ( temp structure{ temp 3-component vector of float cpoint}) 0:26 Function Definition: @main(struct-VS_OUT-vf31[3]; ( temp structure{ temp 3-component vector of float cpoint})
0:26 Function Parameters: 0:26 Function Parameters:
...@@ -78,7 +83,9 @@ vertices = 3 ...@@ -78,7 +83,9 @@ vertices = 3
0:? 'ip' ( temp 3-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' ( temp 3-element array of structure{ temp 3-component vector of float cpoint})
0:? 'ip' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float cpoint})
0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint}) 0:26 move second child to first child ( temp structure{ temp 3-component vector of float cpoint})
0:? '@entryPointOutput' (layout( location=0) out structure{ temp 3-component vector of float cpoint}) 0:26 indirect index ( temp structure{ temp 3-component vector of float cpoint})
0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float cpoint})
0:? 'InvocationId' ( in uint InvocationID)
0:26 Function Call: @main(struct-VS_OUT-vf31[3]; ( temp structure{ temp 3-component vector of float cpoint}) 0:26 Function Call: @main(struct-VS_OUT-vf31[3]; ( temp structure{ temp 3-component vector of float cpoint})
0:? 'ip' ( temp 3-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' ( temp 3-element array of structure{ temp 3-component vector of float cpoint})
0:? Barrier ( temp void) 0:? Barrier ( temp void)
...@@ -89,23 +96,26 @@ vertices = 3 ...@@ -89,23 +96,26 @@ vertices = 3
0:? Constant: 0:? Constant:
0:? 0 (const int) 0:? 0 (const int)
0:? true case 0:? true case
0:? Function Call: PCF( ( temp void) 0:? Sequence
0:? Function Call: PCF( ( temp void)
0:33 Function Definition: PCF( ( temp void) 0:33 Function Definition: PCF( ( temp void)
0:33 Function Parameters: 0:33 Function Parameters:
0:? Linker Objects 0:? Linker Objects
0:? '@entryPointOutput' (layout( location=0) out structure{ temp 3-component vector of float cpoint}) 0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float cpoint})
0:? 'ip' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float cpoint})
0:? 'InvocationId' ( in uint InvocationID) 0:? 'InvocationId' ( in uint InvocationID)
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80001 // Generated by (magic number): 80001
// Id's are bound by 51 // Id's are bound by 55
Capability Tessellation Capability Tessellation
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint TessellationControl 4 "main" 33 36 44 EntryPoint TessellationControl 4 "main" 33 37 39
ExecutionMode 4 OutputVertices 3 ExecutionMode 4 OutputVertices 3
ExecutionMode 4 Triangles
ExecutionMode 4 SpacingFractionalEven
Name 4 "main" Name 4 "main"
Name 8 "VS_OUT" Name 8 "VS_OUT"
MemberName 8(VS_OUT) 0 "cpoint" MemberName 8(VS_OUT) 0 "cpoint"
...@@ -117,12 +127,12 @@ vertices = 3 ...@@ -117,12 +127,12 @@ vertices = 3
Name 21 "output" Name 21 "output"
Name 31 "ip" Name 31 "ip"
Name 33 "ip" Name 33 "ip"
Name 36 "@entryPointOutput" Name 37 "@entryPointOutput"
Name 37 "param" Name 39 "InvocationId"
Name 44 "InvocationId" Name 41 "param"
Decorate 33(ip) Location 0 Decorate 33(ip) Location 0
Decorate 36(@entryPointOutput) Location 0 Decorate 37(@entryPointOutput) Location 0
Decorate 44(InvocationId) BuiltIn InvocationId Decorate 39(InvocationId) BuiltIn InvocationId
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeFloat 32 6: TypeFloat 32
...@@ -140,33 +150,37 @@ vertices = 3 ...@@ -140,33 +150,37 @@ vertices = 3
24: TypePointer Function 7(fvec3) 24: TypePointer Function 7(fvec3)
32: TypePointer Input 11 32: TypePointer Input 11
33(ip): 32(ptr) Variable Input 33(ip): 32(ptr) Variable Input
35: TypePointer Output 13(HS_OUT) 35: TypeArray 13(HS_OUT) 10
36(@entryPointOutput): 35(ptr) Variable Output 36: TypePointer Output 35
40: 9(int) Constant 2 37(@entryPointOutput): 36(ptr) Variable Output
41: 9(int) Constant 1 38: TypePointer Input 9(int)
42: 9(int) Constant 0 39(InvocationId): 38(ptr) Variable Input
43: TypePointer Input 9(int) 44: TypePointer Output 13(HS_OUT)
44(InvocationId): 43(ptr) Variable Input 46: 9(int) Constant 2
46: TypeBool 47: 9(int) Constant 1
48: 9(int) Constant 0
50: TypeBool
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
31(ip): 12(ptr) Variable Function 31(ip): 12(ptr) Variable Function
37(param): 12(ptr) Variable Function 41(param): 12(ptr) Variable Function
34: 11 Load 33(ip) 34: 11 Load 33(ip)
Store 31(ip) 34 Store 31(ip) 34
38: 11 Load 31(ip) 40: 9(int) Load 39(InvocationId)
Store 37(param) 38 42: 11 Load 31(ip)
39: 13(HS_OUT) FunctionCall 16(@main(struct-VS_OUT-vf31[3];) 37(param) Store 41(param) 42
Store 36(@entryPointOutput) 39 43: 13(HS_OUT) FunctionCall 16(@main(struct-VS_OUT-vf31[3];) 41(param)
ControlBarrier 40 41 42 45: 44(ptr) AccessChain 37(@entryPointOutput) 40
45: 9(int) Load 44(InvocationId) Store 45 43
47: 46(bool) IEqual 45 23 ControlBarrier 46 47 48
SelectionMerge 49 None 49: 9(int) Load 39(InvocationId)
BranchConditional 47 48 49 51: 50(bool) IEqual 49 23
48: Label SelectionMerge 53 None
50: 2 FunctionCall 18(PCF() BranchConditional 51 52 53
Branch 49 52: Label
49: Label 54: 2 FunctionCall 18(PCF()
Branch 53
53: Label
Return Return
FunctionEnd FunctionEnd
16(@main(struct-VS_OUT-vf31[3];): 13(HS_OUT) Function None 14 16(@main(struct-VS_OUT-vf31[3];): 13(HS_OUT) Function None 14
......
struct ds_in_t
{
float4 pos : POSITION;
float3 norm : TEXCOORD0;
};
struct pcf_in_t
{
float flTessFactor [3] : SV_TessFactor;
float flInsideTessFactor : SV_InsideTessFactor;
};
struct gs_in_t
{
float4 pos : POSITION;
float3 norm : TEXCOORD0;
};
[domain ( "tri" )]
gs_in_t main (const OutputPatch <ds_in_t, 3> i, float3 tesscoord : SV_DomainLocation, pcf_in_t pcf_data )
{
gs_in_t o;
o.pos = i[0].pos + tesscoord.x;
o.norm = i[0].norm + tesscoord.y;
tesscoord.z;
return o;
}
// ***
// per-control-point invocation of PCF from entry point return value
// ***
struct hs_in_t
{
float3 val : TEXCOORD0;
};
struct hs_pcf_t
{
float tfactor[3] : SV_TessFactor; // must turn into a size 4 array in SPIR-V
float flInFactor : SV_InsideTessFactor; // must turn into a size 2 array in SPIR-V
};
struct hs_out_t
{
float3 val : TEXCOORD0;
};
[ domain ("tri") ]
[ partitioning ("fractional_odd") ]
[ outputtopology ("triangle_cw") ]
[ outputcontrolpoints (3) ]
[ patchconstantfunc ( "PCF" ) ]
hs_out_t main (InputPatch <hs_in_t, 3> i , uint cpid : SV_OutputControlPointID)
{
hs_out_t o;
o.val = cpid;
return o;
}
hs_pcf_t PCF( const OutputPatch <hs_out_t, 3> pcf_out)
{
hs_pcf_t o;
o.tfactor[0] = pcf_out[0].val.x;
o.tfactor[1] = pcf_out[1].val.x;
o.tfactor[2] = pcf_out[2].val.x;
o.flInFactor = 4;
return o;
}
...@@ -884,6 +884,13 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree) ...@@ -884,6 +884,13 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
case EShLangTessControl: case EShLangTessControl:
infoSink.debug << "vertices = " << vertices << "\n"; infoSink.debug << "vertices = " << vertices << "\n";
if (inputPrimitive != ElgNone)
infoSink.debug << "input primitive = " << TQualifier::getGeometryString(inputPrimitive) << "\n";
if (vertexSpacing != EvsNone)
infoSink.debug << "vertex spacing = " << TQualifier::getVertexSpacingString(vertexSpacing) << "\n";
if (vertexOrder != EvoNone)
infoSink.debug << "triangle order = " << TQualifier::getVertexOrderString(vertexOrder) << "\n";
break; break;
case EShLangTessEvaluation: case EShLangTessEvaluation:
......
...@@ -461,10 +461,12 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) ...@@ -461,10 +461,12 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
case EShLangTessEvaluation: case EShLangTessEvaluation:
if (inputPrimitive == ElgNone) if (inputPrimitive == ElgNone)
error(infoSink, "At least one shader must specify an input layout primitive"); error(infoSink, "At least one shader must specify an input layout primitive");
if (vertexSpacing == EvsNone) if (source == EShSourceGlsl) {
vertexSpacing = EvsEqual; if (vertexSpacing == EvsNone)
if (vertexOrder == EvoNone) vertexSpacing = EvsEqual;
vertexOrder = EvoCcw; if (vertexOrder == EvoNone)
vertexOrder = EvoCcw;
}
break; break;
case EShLangGeometry: case EShLangGeometry:
if (inputPrimitive == ElgNone) if (inputPrimitive == ElgNone)
......
...@@ -123,9 +123,11 @@ INSTANTIATE_TEST_CASE_P( ...@@ -123,9 +123,11 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.getdimensions.rw.dx10.frag", "main"}, {"hlsl.getdimensions.rw.dx10.frag", "main"},
{"hlsl.getdimensions.dx10.vert", "main"}, {"hlsl.getdimensions.dx10.vert", "main"},
{"hlsl.getsampleposition.dx10.frag", "main"}, {"hlsl.getsampleposition.dx10.frag", "main"},
{"hlsl.domain.1.tese", "main"},
{"hlsl.hull.1.tesc", "main"}, {"hlsl.hull.1.tesc", "main"},
{"hlsl.hull.2.tesc", "main"}, {"hlsl.hull.2.tesc", "main"},
{"hlsl.hull.void.tesc", "main"}, {"hlsl.hull.void.tesc", "main"},
{"hlsl.hull.ctrlpt-1.tesc", "main"},
{"hlsl.identifier.sample.frag", "main"}, {"hlsl.identifier.sample.frag", "main"},
{"hlsl.if.frag", "PixelShaderFunction"}, {"hlsl.if.frag", "PixelShaderFunction"},
{"hlsl.implicitBool.frag", "main"}, {"hlsl.implicitBool.frag", "main"},
......
...@@ -80,6 +80,7 @@ public: ...@@ -80,6 +80,7 @@ public:
void handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype); void handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&, const TAttributeMap&, TIntermNode*& entryPointTree); TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&, const TAttributeMap&, TIntermNode*& entryPointTree);
TIntermNode* transformEntryPoint(const TSourceLoc&, TFunction&, const TAttributeMap&); TIntermNode* transformEntryPoint(const TSourceLoc&, TFunction&, const TAttributeMap&);
void handleEntryPointAttributes(const TSourceLoc&, const TAttributeMap&);
void handleFunctionBody(const TSourceLoc&, TFunction&, TIntermNode* functionBody, TIntermNode*& node); void handleFunctionBody(const TSourceLoc&, TFunction&, TIntermNode* functionBody, TIntermNode*& node);
void remapEntryPointIO(TFunction& function, TVariable*& returnValue, TVector<TVariable*>& inputs, TVector<TVariable*>& outputs); void remapEntryPointIO(TFunction& function, TVariable*& returnValue, TVector<TVariable*>& inputs, TVector<TVariable*>& outputs);
void remapNonEntryPointIO(TFunction& function); void remapNonEntryPointIO(TFunction& function);
...@@ -247,6 +248,8 @@ protected: ...@@ -247,6 +248,8 @@ protected:
void addInterstageIoToLinkage(); void addInterstageIoToLinkage();
void addPatchConstantInvocation(); void addPatchConstantInvocation();
void fixBuiltInArrayType(TType&);
void flatten(const TSourceLoc& loc, const TVariable& variable); void flatten(const TSourceLoc& loc, const TVariable& variable);
int flatten(const TSourceLoc& loc, const TVariable& variable, const TType&, TFlattenData&, TString name); int flatten(const TSourceLoc& loc, const TVariable& variable, const TType&, TFlattenData&, TString name);
int flattenStruct(const TSourceLoc& loc, const TVariable& variable, const TType&, TFlattenData&, TString name); int flattenStruct(const TSourceLoc& loc, const TVariable& variable, const TType&, TFlattenData&, TString name);
...@@ -280,6 +283,9 @@ protected: ...@@ -280,6 +283,9 @@ protected:
void finish() override; // post-processing void finish() override; // post-processing
// Linkage symbol helpers
TIntermSymbol* findLinkageSymbol(TBuiltInVariable biType) const;
// Current state of parsing // Current state of parsing
struct TPragma contextPragma; struct TPragma contextPragma;
int loopNestingLevel; // 0 if outside all loops int loopNestingLevel; // 0 if outside all loops
......
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