diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index d2a9085d..1e03909b 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -869,14 +869,20 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* gls builder.addCapability(spv::CapabilityShader); break; + case EShLangTessEvaluation: case EShLangTessControl: builder.addCapability(spv::CapabilityTessellation); - builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, glslangIntermediate->getVertices()); - break; - case EShLangTessEvaluation: - builder.addCapability(spv::CapabilityTessellation); - switch (glslangIntermediate->getInputPrimitive()) { + glslang::TLayoutGeometry primitive; + + 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::ElgQuads: mode = spv::ExecutionModeQuads; break; case glslang::ElgIsolines: mode = spv::ExecutionModeIsolines; break; diff --git a/Test/baseResults/hlsl.basic.geom.out b/Test/baseResults/hlsl.basic.geom.out index 24250b3e..12616d93 100644 --- a/Test/baseResults/hlsl.basic.geom.out +++ b/Test/baseResults/hlsl.basic.geom.out @@ -60,14 +60,14 @@ output primitive = line_strip 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:? '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:? 'VertexID' ( 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:? Linker Objects 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: @@ -134,14 +134,14 @@ output primitive = line_strip 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:? '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:? 'VertexID' ( 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:? Linker Objects 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 // Generated by (magic number): 80001 @@ -173,7 +173,7 @@ output primitive = line_strip Name 53 "param" Name 55 "param" Decorate 45(VertexID) Location 0 - Decorate 48(test) Location 3 + Decorate 48(test) Location 1 2: TypeVoid 3: TypeFunction 2 6: TypeInt 32 0 diff --git a/Test/baseResults/hlsl.domain.1.tese.out b/Test/baseResults/hlsl.domain.1.tese.out new file mode 100644 index 00000000..550ead06 --- /dev/null +++ b/Test/baseResults/hlsl.domain.1.tese.out @@ -0,0 +1,393 @@ +hlsl.domain.1.tese +Shader version: 450 +input primitive = triangles +vertex spacing = none +triangle order = none +0:? Sequence +0:22 Function Definition: @main(struct-ds_in_t-vf4-vf31[3];vf3;struct-pcf_in_t-f1[3]-f11; ( temp structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:22 Function Parameters: +0:22 'i' ( const (read only) 3-element array of structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:22 'tesscoord' ( in 3-component vector of float) +0:22 'pcf_data' ( in structure{ temp 3-element array of float flTessFactor, temp float flInsideTessFactor}) +0:? Sequence +0:25 move second child to first child ( temp 4-component vector of float) +0:25 pos: direct index for structure ( temp 4-component vector of float) +0:25 'o' ( temp structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:25 Constant: +0:25 0 (const int) +0:25 add ( temp 4-component vector of float) +0:25 pos: direct index for structure ( temp 4-component vector of float) +0:25 direct index ( temp structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:25 'i' ( const (read only) 3-element array of structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:25 Constant: +0:25 0 (const int) +0:25 Constant: +0:25 0 (const int) +0:25 direct index ( temp float) +0:25 'tesscoord' ( in 3-component vector of float) +0:25 Constant: +0:25 0 (const int) +0:26 move second child to first child ( temp 3-component vector of float) +0:26 norm: direct index for structure ( temp 3-component vector of float) +0:26 'o' ( temp structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:26 Constant: +0:26 1 (const int) +0:26 add ( temp 3-component vector of float) +0:26 norm: direct index for structure ( temp 3-component vector of float) +0:26 direct index ( temp structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:26 'i' ( const (read only) 3-element array of structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:26 Constant: +0:26 0 (const int) +0:26 Constant: +0:26 1 (const int) +0:26 direct index ( temp float) +0:26 'tesscoord' ( in 3-component vector of float) +0:26 Constant: +0:26 1 (const int) +0:28 direct index ( temp float) +0:28 'tesscoord' ( in 3-component vector of float) +0:28 Constant: +0:28 2 (const int) +0:30 Branch: Return with expression +0:30 'o' ( temp structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:22 Function Definition: main( ( temp void) +0:22 Function Parameters: +0:? Sequence +0:22 move second child to first child ( temp 3-element array of structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:? 'i' ( temp 3-element array of structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:? 'i' (layout( location=0) in 3-element array of structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:22 move second child to first child ( temp 3-component vector of float) +0:? 'tesscoord' ( temp 3-component vector of float) +0:? 'tesscoord' ( patch in 3-component vector of float TessCoord) +0:22 Sequence +0:22 move second child to first child ( temp float) +0:22 direct index ( temp float) +0:22 flTessFactor: direct index for structure ( temp 3-element array of float) +0:? 'pcf_data' ( temp structure{ temp 3-element array of float flTessFactor, temp float flInsideTessFactor}) +0:22 Constant: +0:22 0 (const int) +0:22 Constant: +0:22 0 (const int) +0:22 direct index ( patch in float TessLevelOuter) +0:? 'pcf_data_flTessFactor' ( patch in 4-element array of float TessLevelOuter) +0:22 Constant: +0:22 0 (const int) +0:22 move second child to first child ( temp float) +0:22 direct index ( temp float) +0:22 flTessFactor: direct index for structure ( temp 3-element array of float) +0:? 'pcf_data' ( temp structure{ temp 3-element array of float flTessFactor, temp float flInsideTessFactor}) +0:22 Constant: +0:22 0 (const int) +0:22 Constant: +0:22 1 (const int) +0:22 direct index ( patch in float TessLevelOuter) +0:? 'pcf_data_flTessFactor' ( patch in 4-element array of float TessLevelOuter) +0:22 Constant: +0:22 1 (const int) +0:22 move second child to first child ( temp float) +0:22 direct index ( temp float) +0:22 flTessFactor: direct index for structure ( temp 3-element array of float) +0:? 'pcf_data' ( temp structure{ temp 3-element array of float flTessFactor, temp float flInsideTessFactor}) +0:22 Constant: +0:22 0 (const int) +0:22 Constant: +0:22 2 (const int) +0:22 direct index ( patch in float TessLevelOuter) +0:? 'pcf_data_flTessFactor' ( patch in 4-element array of float TessLevelOuter) +0:22 Constant: +0:22 2 (const int) +0:22 move second child to first child ( temp float) +0:22 flInsideTessFactor: direct index for structure ( temp float) +0:? 'pcf_data' ( temp structure{ temp 3-element array of float flTessFactor, temp float flInsideTessFactor}) +0:22 Constant: +0:22 1 (const int) +0:22 direct index ( patch in float TessLevelInner) +0:? 'pcf_data_flInsideTessFactor' ( patch in 2-element array of float TessLevelInner) +0:22 Constant: +0:22 0 (const int) +0:22 move second child to first child ( temp structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:? '@entryPointOutput' (layout( location=0) out structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:22 Function Call: @main(struct-ds_in_t-vf4-vf31[3];vf3;struct-pcf_in_t-f1[3]-f11; ( temp structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:? 'i' ( temp 3-element array of structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:? 'tesscoord' ( temp 3-component vector of float) +0:? 'pcf_data' ( temp structure{ temp 3-element array of float flTessFactor, temp float flInsideTessFactor}) +0:? Linker Objects +0:? '@entryPointOutput' (layout( location=0) out structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:? 'i' (layout( location=0) in 3-element array of structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:? 'tesscoord' ( patch in 3-component vector of float TessCoord) +0:? 'pcf_data' (layout( location=2) patch in structure{}) +0:? 'pcf_data_flTessFactor' ( patch in 4-element array of float TessLevelOuter) +0:? 'pcf_data_flInsideTessFactor' ( patch in 2-element array of float TessLevelInner) + + +Linked tessellation evaluation stage: + + +Shader version: 450 +input primitive = triangles +vertex spacing = none +triangle order = none +0:? Sequence +0:22 Function Definition: @main(struct-ds_in_t-vf4-vf31[3];vf3;struct-pcf_in_t-f1[3]-f11; ( temp structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:22 Function Parameters: +0:22 'i' ( const (read only) 3-element array of structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:22 'tesscoord' ( in 3-component vector of float) +0:22 'pcf_data' ( in structure{ temp 3-element array of float flTessFactor, temp float flInsideTessFactor}) +0:? Sequence +0:25 move second child to first child ( temp 4-component vector of float) +0:25 pos: direct index for structure ( temp 4-component vector of float) +0:25 'o' ( temp structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:25 Constant: +0:25 0 (const int) +0:25 add ( temp 4-component vector of float) +0:25 pos: direct index for structure ( temp 4-component vector of float) +0:25 direct index ( temp structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:25 'i' ( const (read only) 3-element array of structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:25 Constant: +0:25 0 (const int) +0:25 Constant: +0:25 0 (const int) +0:25 direct index ( temp float) +0:25 'tesscoord' ( in 3-component vector of float) +0:25 Constant: +0:25 0 (const int) +0:26 move second child to first child ( temp 3-component vector of float) +0:26 norm: direct index for structure ( temp 3-component vector of float) +0:26 'o' ( temp structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:26 Constant: +0:26 1 (const int) +0:26 add ( temp 3-component vector of float) +0:26 norm: direct index for structure ( temp 3-component vector of float) +0:26 direct index ( temp structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:26 'i' ( const (read only) 3-element array of structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:26 Constant: +0:26 0 (const int) +0:26 Constant: +0:26 1 (const int) +0:26 direct index ( temp float) +0:26 'tesscoord' ( in 3-component vector of float) +0:26 Constant: +0:26 1 (const int) +0:28 direct index ( temp float) +0:28 'tesscoord' ( in 3-component vector of float) +0:28 Constant: +0:28 2 (const int) +0:30 Branch: Return with expression +0:30 'o' ( temp structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:22 Function Definition: main( ( temp void) +0:22 Function Parameters: +0:? Sequence +0:22 move second child to first child ( temp 3-element array of structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:? 'i' ( temp 3-element array of structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:? 'i' (layout( location=0) in 3-element array of structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:22 move second child to first child ( temp 3-component vector of float) +0:? 'tesscoord' ( temp 3-component vector of float) +0:? 'tesscoord' ( patch in 3-component vector of float TessCoord) +0:22 Sequence +0:22 move second child to first child ( temp float) +0:22 direct index ( temp float) +0:22 flTessFactor: direct index for structure ( temp 3-element array of float) +0:? 'pcf_data' ( temp structure{ temp 3-element array of float flTessFactor, temp float flInsideTessFactor}) +0:22 Constant: +0:22 0 (const int) +0:22 Constant: +0:22 0 (const int) +0:22 direct index ( patch in float TessLevelOuter) +0:? 'pcf_data_flTessFactor' ( patch in 4-element array of float TessLevelOuter) +0:22 Constant: +0:22 0 (const int) +0:22 move second child to first child ( temp float) +0:22 direct index ( temp float) +0:22 flTessFactor: direct index for structure ( temp 3-element array of float) +0:? 'pcf_data' ( temp structure{ temp 3-element array of float flTessFactor, temp float flInsideTessFactor}) +0:22 Constant: +0:22 0 (const int) +0:22 Constant: +0:22 1 (const int) +0:22 direct index ( patch in float TessLevelOuter) +0:? 'pcf_data_flTessFactor' ( patch in 4-element array of float TessLevelOuter) +0:22 Constant: +0:22 1 (const int) +0:22 move second child to first child ( temp float) +0:22 direct index ( temp float) +0:22 flTessFactor: direct index for structure ( temp 3-element array of float) +0:? 'pcf_data' ( temp structure{ temp 3-element array of float flTessFactor, temp float flInsideTessFactor}) +0:22 Constant: +0:22 0 (const int) +0:22 Constant: +0:22 2 (const int) +0:22 direct index ( patch in float TessLevelOuter) +0:? 'pcf_data_flTessFactor' ( patch in 4-element array of float TessLevelOuter) +0:22 Constant: +0:22 2 (const int) +0:22 move second child to first child ( temp float) +0:22 flInsideTessFactor: direct index for structure ( temp float) +0:? 'pcf_data' ( temp structure{ temp 3-element array of float flTessFactor, temp float flInsideTessFactor}) +0:22 Constant: +0:22 1 (const int) +0:22 direct index ( patch in float TessLevelInner) +0:? 'pcf_data_flInsideTessFactor' ( patch in 2-element array of float TessLevelInner) +0:22 Constant: +0:22 0 (const int) +0:22 move second child to first child ( temp structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:? '@entryPointOutput' (layout( location=0) out structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:22 Function Call: @main(struct-ds_in_t-vf4-vf31[3];vf3;struct-pcf_in_t-f1[3]-f11; ( temp structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:? 'i' ( temp 3-element array of structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:? 'tesscoord' ( temp 3-component vector of float) +0:? 'pcf_data' ( temp structure{ temp 3-element array of float flTessFactor, temp float flInsideTessFactor}) +0:? Linker Objects +0:? '@entryPointOutput' (layout( location=0) out structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:? 'i' (layout( location=0) in 3-element array of structure{ temp 4-component vector of float pos, temp 3-component vector of float norm}) +0:? 'tesscoord' ( patch in 3-component vector of float TessCoord) +0:? 'pcf_data' (layout( location=2) patch in structure{}) +0:? 'pcf_data_flTessFactor' ( patch in 4-element array of float TessLevelOuter) +0:? 'pcf_data_flInsideTessFactor' ( patch in 2-element array of float TessLevelInner) + +// Module Version 10000 +// Generated by (magic number): 80001 +// Id's are bound by 91 + + Capability Tessellation + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint TessellationEvaluation 4 "main" 51 55 61 76 81 90 + ExecutionMode 4 Triangles + Name 4 "main" + Name 9 "ds_in_t" + MemberName 9(ds_in_t) 0 "pos" + MemberName 9(ds_in_t) 1 "norm" + Name 15 "pcf_in_t" + MemberName 15(pcf_in_t) 0 "flTessFactor" + MemberName 15(pcf_in_t) 1 "flInsideTessFactor" + Name 17 "gs_in_t" + MemberName 17(gs_in_t) 0 "pos" + MemberName 17(gs_in_t) 1 "norm" + Name 22 "@main(struct-ds_in_t-vf4-vf31[3];vf3;struct-pcf_in_t-f1[3]-f11;" + Name 19 "i" + Name 20 "tesscoord" + Name 21 "pcf_data" + Name 25 "o" + Name 49 "i" + Name 51 "i" + Name 53 "tesscoord" + Name 55 "tesscoord" + Name 57 "pcf_data" + Name 61 "pcf_data_flTessFactor" + Name 76 "pcf_data_flInsideTessFactor" + Name 81 "@entryPointOutput" + Name 83 "param" + Name 85 "param" + Name 88 "pcf_in_t" + Name 90 "pcf_data" + Decorate 51(i) Location 0 + Decorate 55(tesscoord) Patch + Decorate 55(tesscoord) BuiltIn TessCoord + Decorate 61(pcf_data_flTessFactor) Patch + Decorate 61(pcf_data_flTessFactor) BuiltIn TessLevelOuter + Decorate 76(pcf_data_flInsideTessFactor) Patch + Decorate 76(pcf_data_flInsideTessFactor) BuiltIn TessLevelInner + Decorate 81(@entryPointOutput) Location 0 + Decorate 90(pcf_data) Patch + Decorate 90(pcf_data) Location 2 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8: TypeVector 6(float) 3 + 9(ds_in_t): TypeStruct 7(fvec4) 8(fvec3) + 10: TypeInt 32 0 + 11: 10(int) Constant 3 + 12: TypeArray 9(ds_in_t) 11 + 13: TypePointer Function 8(fvec3) + 14: TypeArray 6(float) 11 + 15(pcf_in_t): TypeStruct 14 6(float) + 16: TypePointer Function 15(pcf_in_t) + 17(gs_in_t): TypeStruct 7(fvec4) 8(fvec3) + 18: TypeFunction 17(gs_in_t) 12 13(ptr) 16(ptr) + 24: TypePointer Function 17(gs_in_t) + 26: TypeInt 32 1 + 27: 26(int) Constant 0 + 29: 10(int) Constant 0 + 30: TypePointer Function 6(float) + 35: TypePointer Function 7(fvec4) + 37: 26(int) Constant 1 + 39: 10(int) Constant 1 + 48: TypePointer Function 12 + 50: TypePointer Input 12 + 51(i): 50(ptr) Variable Input + 54: TypePointer Input 8(fvec3) + 55(tesscoord): 54(ptr) Variable Input + 58: 10(int) Constant 4 + 59: TypeArray 6(float) 58 + 60: TypePointer Input 59 +61(pcf_data_flTessFactor): 60(ptr) Variable Input + 62: TypePointer Input 6(float) + 69: 26(int) Constant 2 + 73: 10(int) Constant 2 + 74: TypeArray 6(float) 73 + 75: TypePointer Input 74 +76(pcf_data_flInsideTessFactor): 75(ptr) Variable Input + 80: TypePointer Output 17(gs_in_t) +81(@entryPointOutput): 80(ptr) Variable Output + 88(pcf_in_t): TypeStruct + 89: TypePointer Input 88(pcf_in_t) + 90(pcf_data): 89(ptr) Variable Input + 4(main): 2 Function None 3 + 5: Label + 49(i): 48(ptr) Variable Function + 53(tesscoord): 13(ptr) Variable Function + 57(pcf_data): 16(ptr) Variable Function + 83(param): 13(ptr) Variable Function + 85(param): 16(ptr) Variable Function + 52: 12 Load 51(i) + Store 49(i) 52 + 56: 8(fvec3) Load 55(tesscoord) + Store 53(tesscoord) 56 + 63: 62(ptr) AccessChain 61(pcf_data_flTessFactor) 27 + 64: 6(float) Load 63 + 65: 30(ptr) AccessChain 57(pcf_data) 27 27 + Store 65 64 + 66: 62(ptr) AccessChain 61(pcf_data_flTessFactor) 37 + 67: 6(float) Load 66 + 68: 30(ptr) AccessChain 57(pcf_data) 27 37 + Store 68 67 + 70: 62(ptr) AccessChain 61(pcf_data_flTessFactor) 69 + 71: 6(float) Load 70 + 72: 30(ptr) AccessChain 57(pcf_data) 27 69 + Store 72 71 + 77: 62(ptr) AccessChain 76(pcf_data_flInsideTessFactor) 27 + 78: 6(float) Load 77 + 79: 30(ptr) AccessChain 57(pcf_data) 37 + Store 79 78 + 82: 12 Load 49(i) + 84: 8(fvec3) Load 53(tesscoord) + Store 83(param) 84 + 86:15(pcf_in_t) Load 57(pcf_data) + Store 85(param) 86 + 87: 17(gs_in_t) FunctionCall 22(@main(struct-ds_in_t-vf4-vf31[3];vf3;struct-pcf_in_t-f1[3]-f11;) 82 83(param) 85(param) + Store 81(@entryPointOutput) 87 + Return + FunctionEnd +22(@main(struct-ds_in_t-vf4-vf31[3];vf3;struct-pcf_in_t-f1[3]-f11;): 17(gs_in_t) Function None 18 + 19(i): 12 FunctionParameter + 20(tesscoord): 13(ptr) FunctionParameter + 21(pcf_data): 16(ptr) FunctionParameter + 23: Label + 25(o): 24(ptr) Variable Function + 28: 7(fvec4) CompositeExtract 19(i) 0 0 + 31: 30(ptr) AccessChain 20(tesscoord) 29 + 32: 6(float) Load 31 + 33: 7(fvec4) CompositeConstruct 32 32 32 32 + 34: 7(fvec4) FAdd 28 33 + 36: 35(ptr) AccessChain 25(o) 27 + Store 36 34 + 38: 8(fvec3) CompositeExtract 19(i) 0 1 + 40: 30(ptr) AccessChain 20(tesscoord) 39 + 41: 6(float) Load 40 + 42: 8(fvec3) CompositeConstruct 41 41 41 + 43: 8(fvec3) FAdd 38 42 + 44: 13(ptr) AccessChain 25(o) 37 + Store 44 43 + 45: 17(gs_in_t) Load 25(o) + ReturnValue 45 + FunctionEnd diff --git a/Test/baseResults/hlsl.hull.1.tesc.out b/Test/baseResults/hlsl.hull.1.tesc.out index 89ab4e63..a60c1226 100644 --- a/Test/baseResults/hlsl.hull.1.tesc.out +++ b/Test/baseResults/hlsl.hull.1.tesc.out @@ -1,6 +1,7 @@ hlsl.hull.1.tesc Shader version: 450 vertices = 4 +vertex spacing = equal_spacing 0:? Sequence 0:26 Function Definition: @main(struct-VS_OUT-vf31[4];u1; ( temp structure{ temp 3-component vector of float cpoint}) 0:26 Function Parameters: @@ -31,7 +32,9 @@ vertices = 4 0:? 'm_cpid' ( temp uint) 0:? 'm_cpid' ( in uint InvocationID) 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 4-element array of structure{ temp 3-component vector of float cpoint}) +0:? 'm_cpid' ( in uint InvocationID) 0:26 Function Call: @main(struct-VS_OUT-vf31[4];u1; ( temp structure{ temp 3-component vector of float cpoint}) 0:? 'ip' ( temp 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'm_cpid' ( temp uint) @@ -50,8 +53,8 @@ vertices = 4 0:? 'pid' ( in uint PrimitiveID) 0:? Sequence 0:? move second child to first child ( temp float) -0:? direct index ( out float TessLevelOuter) -0:? '@patchConstantOutput_edges' ( out 2-element array of float TessLevelOuter) +0:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_edges' ( patch out 4-element array of float TessLevelOuter) 0:? Constant: 0:? 0 (const int) 0:? direct index ( temp float) @@ -62,8 +65,8 @@ vertices = 4 0:? Constant: 0:? 0 (const int) 0:? move second child to first child ( temp float) -0:? direct index ( out float TessLevelOuter) -0:? '@patchConstantOutput_edges' ( out 2-element array of float TessLevelOuter) +0:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_edges' ( patch out 4-element array of float TessLevelOuter) 0:? Constant: 0:? 1 (const int) 0:? direct index ( temp float) @@ -100,11 +103,12 @@ vertices = 4 0:38 Branch: Return with expression 0:38 'output' ( temp structure{ temp 2-element array of float edges}) 0:? Linker Objects -0:? '@entryPointOutput' (layout( location=0) out structure{ temp 3-component vector of float cpoint}) +0:? '@entryPointOutput' (layout( location=0) out 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' (layout( location=0) in 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'm_cpid' ( in uint InvocationID) 0:? 'pid' ( in uint PrimitiveID) -0:? '@patchConstantOutput_edges' ( out 2-element array of float TessLevelOuter) +0:? '@patchConstantOutput' (layout( location=1) patch out structure{}) +0:? '@patchConstantOutput_edges' ( patch out 4-element array of float TessLevelOuter) Linked tessellation control stage: @@ -112,6 +116,7 @@ Linked tessellation control stage: Shader version: 450 vertices = 4 +vertex spacing = equal_spacing 0:? Sequence 0:26 Function Definition: @main(struct-VS_OUT-vf31[4];u1; ( temp structure{ temp 3-component vector of float cpoint}) 0:26 Function Parameters: @@ -142,7 +147,9 @@ vertices = 4 0:? 'm_cpid' ( temp uint) 0:? 'm_cpid' ( in uint InvocationID) 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 4-element array of structure{ temp 3-component vector of float cpoint}) +0:? 'm_cpid' ( in uint InvocationID) 0:26 Function Call: @main(struct-VS_OUT-vf31[4];u1; ( temp structure{ temp 3-component vector of float cpoint}) 0:? 'ip' ( temp 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'm_cpid' ( temp uint) @@ -161,8 +168,8 @@ vertices = 4 0:? 'pid' ( in uint PrimitiveID) 0:? Sequence 0:? move second child to first child ( temp float) -0:? direct index ( out float TessLevelOuter) -0:? '@patchConstantOutput_edges' ( out 2-element array of float TessLevelOuter) +0:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_edges' ( patch out 4-element array of float TessLevelOuter) 0:? Constant: 0:? 0 (const int) 0:? direct index ( temp float) @@ -173,8 +180,8 @@ vertices = 4 0:? Constant: 0:? 0 (const int) 0:? move second child to first child ( temp float) -0:? direct index ( out float TessLevelOuter) -0:? '@patchConstantOutput_edges' ( out 2-element array of float TessLevelOuter) +0:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_edges' ( patch out 4-element array of float TessLevelOuter) 0:? Constant: 0:? 1 (const int) 0:? direct index ( temp float) @@ -211,21 +218,24 @@ vertices = 4 0:38 Branch: Return with expression 0:38 'output' ( temp structure{ temp 2-element array of float edges}) 0:? Linker Objects -0:? '@entryPointOutput' (layout( location=0) out structure{ temp 3-component vector of float cpoint}) +0:? '@entryPointOutput' (layout( location=0) out 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' (layout( location=0) in 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'm_cpid' ( in uint InvocationID) 0:? 'pid' ( in uint PrimitiveID) -0:? '@patchConstantOutput_edges' ( out 2-element array of float TessLevelOuter) +0:? '@patchConstantOutput' (layout( location=1) patch out structure{}) +0:? '@patchConstantOutput_edges' ( patch out 4-element array of float TessLevelOuter) // Module Version 10000 // Generated by (magic number): 80001 -// Id's are bound by 85 +// Id's are bound by 93 Capability Tessellation 1: ExtInstImport "GLSL.std.450" MemoryModel Logical GLSL450 - EntryPoint TessellationControl 4 "main" 40 44 47 62 67 + EntryPoint TessellationControl 4 "main" 40 44 48 66 72 92 ExecutionMode 4 OutputVertices 4 + ExecutionMode 4 Isolines + ExecutionMode 4 SpacingEqual Name 4 "main" Name 8 "VS_OUT" MemberName 8(VS_OUT) 0 "cpoint" @@ -243,19 +253,24 @@ vertices = 4 Name 40 "ip" Name 42 "m_cpid" Name 44 "m_cpid" - Name 47 "@entryPointOutput" - Name 48 "param" + Name 48 "@entryPointOutput" Name 50 "param" - Name 61 "@patchConstantResult" - Name 62 "pid" - Name 63 "param" - Name 67 "@patchConstantOutput_edges" - Name 77 "output" + Name 52 "param" + Name 65 "@patchConstantResult" + Name 66 "pid" + Name 67 "param" + Name 72 "@patchConstantOutput_edges" + Name 82 "output" + Name 90 "HS_CONSTANT_OUT" + Name 92 "@patchConstantOutput" Decorate 40(ip) Location 0 Decorate 44(m_cpid) BuiltIn InvocationId - Decorate 47(@entryPointOutput) Location 0 - Decorate 62(pid) BuiltIn PrimitiveId - Decorate 67(@patchConstantOutput_edges) BuiltIn TessLevelOuter + Decorate 48(@entryPointOutput) Location 0 + Decorate 66(pid) BuiltIn PrimitiveId + Decorate 72(@patchConstantOutput_edges) Patch + Decorate 72(@patchConstantOutput_edges) BuiltIn TessLevelOuter + Decorate 92(@patchConstantOutput) Patch + Decorate 92(@patchConstantOutput) Location 1 2: TypeVoid 3: TypeFunction 2 6: TypeFloat 32 @@ -280,58 +295,66 @@ vertices = 4 40(ip): 39(ptr) Variable Input 43: TypePointer Input 9(int) 44(m_cpid): 43(ptr) Variable Input - 46: TypePointer Output 14(HS_OUT) -47(@entryPointOutput): 46(ptr) Variable Output - 53: 9(int) Constant 1 - 54: 9(int) Constant 0 - 56: TypeBool - 60: TypePointer Function 22(HS_CONSTANT_OUT) - 62(pid): 43(ptr) Variable Input - 66: TypePointer Output 21 -67(@patchConstantOutput_edges): 66(ptr) Variable Output - 68: TypePointer Function 6(float) - 71: TypePointer Output 6(float) - 73: 29(int) Constant 1 - 78: 6(float) Constant 1073741824 - 80: 6(float) Constant 1090519040 + 46: TypeArray 14(HS_OUT) 10 + 47: TypePointer Output 46 +48(@entryPointOutput): 47(ptr) Variable Output + 55: TypePointer Output 14(HS_OUT) + 57: 9(int) Constant 1 + 58: 9(int) Constant 0 + 60: TypeBool + 64: TypePointer Function 22(HS_CONSTANT_OUT) + 66(pid): 43(ptr) Variable Input + 70: TypeArray 6(float) 10 + 71: TypePointer Output 70 +72(@patchConstantOutput_edges): 71(ptr) Variable Output + 73: TypePointer Function 6(float) + 76: TypePointer Output 6(float) + 78: 29(int) Constant 1 + 83: 6(float) Constant 1073741824 + 85: 6(float) Constant 1090519040 +90(HS_CONSTANT_OUT): TypeStruct + 91: TypePointer Output 90(HS_CONSTANT_OUT) +92(@patchConstantOutput): 91(ptr) Variable Output 4(main): 2 Function None 3 5: Label 38(ip): 12(ptr) Variable Function 42(m_cpid): 13(ptr) Variable Function - 48(param): 12(ptr) Variable Function - 50(param): 13(ptr) Variable Function -61(@patchConstantResult): 60(ptr) Variable Function - 63(param): 13(ptr) Variable Function + 50(param): 12(ptr) Variable Function + 52(param): 13(ptr) Variable Function +65(@patchConstantResult): 64(ptr) Variable Function + 67(param): 13(ptr) Variable Function 41: 11 Load 40(ip) Store 38(ip) 41 45: 9(int) Load 44(m_cpid) Store 42(m_cpid) 45 - 49: 11 Load 38(ip) - Store 48(param) 49 - 51: 9(int) Load 42(m_cpid) + 49: 9(int) Load 44(m_cpid) + 51: 11 Load 38(ip) Store 50(param) 51 - 52: 14(HS_OUT) FunctionCall 18(@main(struct-VS_OUT-vf31[4];u1;) 48(param) 50(param) - Store 47(@entryPointOutput) 52 - ControlBarrier 20 53 54 - 55: 9(int) Load 44(m_cpid) - 57: 56(bool) IEqual 55 30 - SelectionMerge 59 None - BranchConditional 57 58 59 - 58: Label - 64: 9(int) Load 62(pid) - Store 63(param) 64 - 65:22(HS_CONSTANT_OUT) FunctionCall 25(PCF(u1;) 63(param) - Store 61(@patchConstantResult) 65 - 69: 68(ptr) AccessChain 61(@patchConstantResult) 30 30 - 70: 6(float) Load 69 - 72: 71(ptr) AccessChain 67(@patchConstantOutput_edges) 30 - Store 72 70 - 74: 68(ptr) AccessChain 61(@patchConstantResult) 30 73 + 53: 9(int) Load 42(m_cpid) + Store 52(param) 53 + 54: 14(HS_OUT) FunctionCall 18(@main(struct-VS_OUT-vf31[4];u1;) 50(param) 52(param) + 56: 55(ptr) AccessChain 48(@entryPointOutput) 49 + Store 56 54 + ControlBarrier 20 57 58 + 59: 9(int) Load 44(m_cpid) + 61: 60(bool) IEqual 59 30 + SelectionMerge 63 None + BranchConditional 61 62 63 + 62: Label + 68: 9(int) Load 66(pid) + Store 67(param) 68 + 69:22(HS_CONSTANT_OUT) FunctionCall 25(PCF(u1;) 67(param) + Store 65(@patchConstantResult) 69 + 74: 73(ptr) AccessChain 65(@patchConstantResult) 30 30 75: 6(float) Load 74 - 76: 71(ptr) AccessChain 67(@patchConstantOutput_edges) 73 - Store 76 75 - Branch 59 - 59: Label + 77: 76(ptr) AccessChain 72(@patchConstantOutput_edges) 30 + Store 77 75 + 79: 73(ptr) AccessChain 65(@patchConstantResult) 30 78 + 80: 6(float) Load 79 + 81: 76(ptr) AccessChain 72(@patchConstantOutput_edges) 78 + Store 81 80 + Branch 63 + 63: Label Return FunctionEnd 18(@main(struct-VS_OUT-vf31[4];u1;): 14(HS_OUT) Function None 15 @@ -349,11 +372,11 @@ vertices = 4 25(PCF(u1;):22(HS_CONSTANT_OUT) Function None 23 24(pid): 13(ptr) FunctionParameter 26: Label - 77(output): 60(ptr) Variable Function - 79: 68(ptr) AccessChain 77(output) 30 30 - Store 79 78 - 81: 68(ptr) AccessChain 77(output) 30 73 - Store 81 80 - 82:22(HS_CONSTANT_OUT) Load 77(output) - ReturnValue 82 + 82(output): 64(ptr) Variable Function + 84: 73(ptr) AccessChain 82(output) 30 30 + Store 84 83 + 86: 73(ptr) AccessChain 82(output) 30 78 + Store 86 85 + 87:22(HS_CONSTANT_OUT) Load 82(output) + ReturnValue 87 FunctionEnd diff --git a/Test/baseResults/hlsl.hull.2.tesc.out b/Test/baseResults/hlsl.hull.2.tesc.out index 9d848c61..f7c7389e 100644 --- a/Test/baseResults/hlsl.hull.2.tesc.out +++ b/Test/baseResults/hlsl.hull.2.tesc.out @@ -1,6 +1,7 @@ hlsl.hull.2.tesc Shader version: 450 vertices = 4 +vertex spacing = equal_spacing 0:? Sequence 0:26 Function Definition: @main(struct-VS_OUT-vf31[4]; ( temp structure{ temp 3-component vector of float cpoint}) 0:26 Function Parameters: @@ -27,7 +28,9 @@ vertices = 4 0:? 'ip' ( temp 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' (layout( location=0) in 4-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:? '@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 4-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[4]; ( temp structure{ temp 3-component vector of float cpoint}) 0:? 'ip' ( temp 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? Barrier ( temp void) @@ -46,8 +49,8 @@ vertices = 4 0:? 'pos' ( in 4-component vector of float Position) 0:? Sequence 0:? move second child to first child ( temp float) -0:? direct index ( out float TessLevelOuter) -0:? '@patchConstantOutput_edges' ( out 2-element array of float TessLevelOuter) +0:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_edges' ( patch out 4-element array of float TessLevelOuter) 0:? Constant: 0:? 0 (const int) 0:? direct index ( temp float) @@ -58,8 +61,8 @@ vertices = 4 0:? Constant: 0:? 0 (const int) 0:? move second child to first child ( temp float) -0:? direct index ( out float TessLevelOuter) -0:? '@patchConstantOutput_edges' ( out 2-element array of float TessLevelOuter) +0:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_edges' ( patch out 4-element array of float TessLevelOuter) 0:? Constant: 0:? 1 (const int) 0:? direct index ( temp float) @@ -97,12 +100,13 @@ vertices = 4 0:38 Branch: Return with expression 0:38 'output' ( temp structure{ temp 2-element array of float edges}) 0:? Linker Objects -0:? '@entryPointOutput' (layout( location=0) out structure{ temp 3-component vector of float cpoint}) +0:? '@entryPointOutput' (layout( location=0) out 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' (layout( location=0) in 4-element array of structure{ temp 3-component vector of float cpoint}) +0:? 'InvocationId' ( in uint InvocationID) 0:? 'pid' ( in uint PrimitiveID) 0:? 'pos' ( in 4-component vector of float Position) -0:? 'InvocationId' ( in uint InvocationID) -0:? '@patchConstantOutput_edges' ( out 2-element array of float TessLevelOuter) +0:? '@patchConstantOutput' (layout( location=1) patch out structure{}) +0:? '@patchConstantOutput_edges' ( patch out 4-element array of float TessLevelOuter) Linked tessellation control stage: @@ -110,6 +114,7 @@ Linked tessellation control stage: Shader version: 450 vertices = 4 +vertex spacing = equal_spacing 0:? Sequence 0:26 Function Definition: @main(struct-VS_OUT-vf31[4]; ( temp structure{ temp 3-component vector of float cpoint}) 0:26 Function Parameters: @@ -136,7 +141,9 @@ vertices = 4 0:? 'ip' ( temp 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' (layout( location=0) in 4-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:? '@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 4-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[4]; ( temp structure{ temp 3-component vector of float cpoint}) 0:? 'ip' ( temp 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? Barrier ( temp void) @@ -155,8 +162,8 @@ vertices = 4 0:? 'pos' ( in 4-component vector of float Position) 0:? Sequence 0:? move second child to first child ( temp float) -0:? direct index ( out float TessLevelOuter) -0:? '@patchConstantOutput_edges' ( out 2-element array of float TessLevelOuter) +0:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_edges' ( patch out 4-element array of float TessLevelOuter) 0:? Constant: 0:? 0 (const int) 0:? direct index ( temp float) @@ -167,8 +174,8 @@ vertices = 4 0:? Constant: 0:? 0 (const int) 0:? move second child to first child ( temp float) -0:? direct index ( out float TessLevelOuter) -0:? '@patchConstantOutput_edges' ( out 2-element array of float TessLevelOuter) +0:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_edges' ( patch out 4-element array of float TessLevelOuter) 0:? Constant: 0:? 1 (const int) 0:? direct index ( temp float) @@ -206,22 +213,25 @@ vertices = 4 0:38 Branch: Return with expression 0:38 'output' ( temp structure{ temp 2-element array of float edges}) 0:? Linker Objects -0:? '@entryPointOutput' (layout( location=0) out structure{ temp 3-component vector of float cpoint}) +0:? '@entryPointOutput' (layout( location=0) out 4-element array of structure{ temp 3-component vector of float cpoint}) 0:? 'ip' (layout( location=0) in 4-element array of structure{ temp 3-component vector of float cpoint}) +0:? 'InvocationId' ( in uint InvocationID) 0:? 'pid' ( in uint PrimitiveID) 0:? 'pos' ( in 4-component vector of float Position) -0:? 'InvocationId' ( in uint InvocationID) -0:? '@patchConstantOutput_edges' ( out 2-element array of float TessLevelOuter) +0:? '@patchConstantOutput' (layout( location=1) patch out structure{}) +0:? '@patchConstantOutput_edges' ( patch out 4-element array of float TessLevelOuter) // Module Version 10000 // Generated by (magic number): 80001 -// Id's are bound by 87 +// Id's are bound by 95 Capability Tessellation 1: ExtInstImport "GLSL.std.450" MemoryModel Logical GLSL450 - EntryPoint TessellationControl 4 "main" 42 45 52 60 62 69 + EntryPoint TessellationControl 4 "main" 42 46 48 64 66 74 94 ExecutionMode 4 OutputVertices 4 + ExecutionMode 4 Isolines + ExecutionMode 4 SpacingEqual Name 4 "main" Name 8 "VS_OUT" MemberName 8(VS_OUT) 0 "cpoint" @@ -237,22 +247,27 @@ vertices = 4 Name 30 "output" Name 40 "ip" Name 42 "ip" - Name 45 "@entryPointOutput" - Name 46 "param" - Name 52 "InvocationId" - Name 59 "@patchConstantResult" - Name 60 "pid" - Name 62 "pos" - Name 63 "param" - Name 65 "param" - Name 69 "@patchConstantOutput_edges" - Name 79 "output" + Name 46 "@entryPointOutput" + Name 48 "InvocationId" + Name 50 "param" + Name 63 "@patchConstantResult" + Name 64 "pid" + Name 66 "pos" + Name 67 "param" + Name 69 "param" + Name 74 "@patchConstantOutput_edges" + Name 84 "output" + Name 92 "HS_CONSTANT_OUT" + Name 94 "@patchConstantOutput" Decorate 42(ip) Location 0 - Decorate 45(@entryPointOutput) Location 0 - Decorate 52(InvocationId) BuiltIn InvocationId - Decorate 60(pid) BuiltIn PrimitiveId - Decorate 62(pos) BuiltIn Position - Decorate 69(@patchConstantOutput_edges) BuiltIn TessLevelOuter + Decorate 46(@entryPointOutput) Location 0 + Decorate 48(InvocationId) BuiltIn InvocationId + Decorate 64(pid) BuiltIn PrimitiveId + Decorate 66(pos) BuiltIn Position + Decorate 74(@patchConstantOutput_edges) Patch + Decorate 74(@patchConstantOutput_edges) BuiltIn TessLevelOuter + Decorate 94(@patchConstantOutput) Patch + Decorate 94(@patchConstantOutput) Location 1 2: TypeVoid 3: TypeFunction 2 6: TypeFloat 32 @@ -277,59 +292,67 @@ vertices = 4 33: TypePointer Function 7(fvec3) 41: TypePointer Input 11 42(ip): 41(ptr) Variable Input - 44: TypePointer Output 13(HS_OUT) -45(@entryPointOutput): 44(ptr) Variable Output - 49: 9(int) Constant 1 - 50: 9(int) Constant 0 - 51: TypePointer Input 9(int) -52(InvocationId): 51(ptr) Variable Input - 54: TypeBool - 58: TypePointer Function 23(HS_CONSTANT_OUT) - 60(pid): 51(ptr) Variable Input - 61: TypePointer Input 19(fvec4) - 62(pos): 61(ptr) Variable Input - 68: TypePointer Output 22 -69(@patchConstantOutput_edges): 68(ptr) Variable Output - 70: TypePointer Function 6(float) - 73: TypePointer Output 6(float) - 75: 31(int) Constant 1 - 80: 6(float) Constant 1073741824 - 82: 6(float) Constant 1090519040 + 44: TypeArray 13(HS_OUT) 10 + 45: TypePointer Output 44 +46(@entryPointOutput): 45(ptr) Variable Output + 47: TypePointer Input 9(int) +48(InvocationId): 47(ptr) Variable Input + 53: TypePointer Output 13(HS_OUT) + 55: 9(int) Constant 1 + 56: 9(int) Constant 0 + 58: TypeBool + 62: TypePointer Function 23(HS_CONSTANT_OUT) + 64(pid): 47(ptr) Variable Input + 65: TypePointer Input 19(fvec4) + 66(pos): 65(ptr) Variable Input + 72: TypeArray 6(float) 10 + 73: TypePointer Output 72 +74(@patchConstantOutput_edges): 73(ptr) Variable Output + 75: TypePointer Function 6(float) + 78: TypePointer Output 6(float) + 80: 31(int) Constant 1 + 85: 6(float) Constant 1073741824 + 87: 6(float) Constant 1090519040 +92(HS_CONSTANT_OUT): TypeStruct + 93: TypePointer Output 92(HS_CONSTANT_OUT) +94(@patchConstantOutput): 93(ptr) Variable Output 4(main): 2 Function None 3 5: Label 40(ip): 12(ptr) Variable Function - 46(param): 12(ptr) Variable Function -59(@patchConstantResult): 58(ptr) Variable Function - 63(param): 18(ptr) Variable Function - 65(param): 20(ptr) Variable Function + 50(param): 12(ptr) Variable Function +63(@patchConstantResult): 62(ptr) Variable Function + 67(param): 18(ptr) Variable Function + 69(param): 20(ptr) Variable Function 43: 11 Load 42(ip) Store 40(ip) 43 - 47: 11 Load 40(ip) - Store 46(param) 47 - 48: 13(HS_OUT) FunctionCall 16(@main(struct-VS_OUT-vf31[4];) 46(param) - Store 45(@entryPointOutput) 48 - ControlBarrier 21 49 50 - 53: 9(int) Load 52(InvocationId) - 55: 54(bool) IEqual 53 32 - SelectionMerge 57 None - BranchConditional 55 56 57 - 56: Label - 64: 9(int) Load 60(pid) - Store 63(param) 64 - 66: 19(fvec4) Load 62(pos) - Store 65(param) 66 - 67:23(HS_CONSTANT_OUT) FunctionCall 27(PCF(u1;vf4;) 63(param) 65(param) - Store 59(@patchConstantResult) 67 - 71: 70(ptr) AccessChain 59(@patchConstantResult) 32 32 - 72: 6(float) Load 71 - 74: 73(ptr) AccessChain 69(@patchConstantOutput_edges) 32 - Store 74 72 - 76: 70(ptr) AccessChain 59(@patchConstantResult) 32 75 + 49: 9(int) Load 48(InvocationId) + 51: 11 Load 40(ip) + Store 50(param) 51 + 52: 13(HS_OUT) FunctionCall 16(@main(struct-VS_OUT-vf31[4];) 50(param) + 54: 53(ptr) AccessChain 46(@entryPointOutput) 49 + Store 54 52 + ControlBarrier 21 55 56 + 57: 9(int) Load 48(InvocationId) + 59: 58(bool) IEqual 57 32 + SelectionMerge 61 None + BranchConditional 59 60 61 + 60: Label + 68: 9(int) Load 64(pid) + Store 67(param) 68 + 70: 19(fvec4) Load 66(pos) + Store 69(param) 70 + 71:23(HS_CONSTANT_OUT) FunctionCall 27(PCF(u1;vf4;) 67(param) 69(param) + Store 63(@patchConstantResult) 71 + 76: 75(ptr) AccessChain 63(@patchConstantResult) 32 32 77: 6(float) Load 76 - 78: 73(ptr) AccessChain 69(@patchConstantOutput_edges) 75 - Store 78 77 - Branch 57 - 57: Label + 79: 78(ptr) AccessChain 74(@patchConstantOutput_edges) 32 + Store 79 77 + 81: 75(ptr) AccessChain 63(@patchConstantResult) 32 80 + 82: 6(float) Load 81 + 83: 78(ptr) AccessChain 74(@patchConstantOutput_edges) 80 + Store 83 82 + Branch 61 + 61: Label Return FunctionEnd 16(@main(struct-VS_OUT-vf31[4];): 13(HS_OUT) Function None 14 @@ -347,11 +370,11 @@ vertices = 4 25(pid): 18(ptr) FunctionParameter 26(pos): 20(ptr) FunctionParameter 28: Label - 79(output): 58(ptr) Variable Function - 81: 70(ptr) AccessChain 79(output) 32 32 - Store 81 80 - 83: 70(ptr) AccessChain 79(output) 32 75 - Store 83 82 - 84:23(HS_CONSTANT_OUT) Load 79(output) - ReturnValue 84 + 84(output): 62(ptr) Variable Function + 86: 75(ptr) AccessChain 84(output) 32 32 + Store 86 85 + 88: 75(ptr) AccessChain 84(output) 32 80 + Store 88 87 + 89:23(HS_CONSTANT_OUT) Load 84(output) + ReturnValue 89 FunctionEnd diff --git a/Test/baseResults/hlsl.hull.ctrlpt-1.tesc.out b/Test/baseResults/hlsl.hull.ctrlpt-1.tesc.out new file mode 100644 index 00000000..e6deae4f --- /dev/null +++ b/Test/baseResults/hlsl.hull.ctrlpt-1.tesc.out @@ -0,0 +1,612 @@ +hlsl.hull.ctrlpt-1.tesc +Shader version: 450 +vertices = 3 +vertex spacing = fractional_odd_spacing +triangle order = cw +0:? Sequence +0:27 Function Definition: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) +0:27 Function Parameters: +0:27 'i' ( in 3-element array of structure{ temp 3-component vector of float val}) +0:27 'cpid' ( in uint) +0:? Sequence +0:29 move second child to first child ( temp 3-component vector of float) +0:29 val: direct index for structure ( temp 3-component vector of float) +0:29 'o' ( temp structure{ temp 3-component vector of float val}) +0:29 Constant: +0:29 0 (const int) +0:29 Construct vec3 ( temp 3-component vector of float) +0:29 Convert uint to float ( temp float) +0:29 'cpid' ( in uint) +0:30 Branch: Return with expression +0:30 'o' ( temp structure{ temp 3-component vector of float val}) +0:27 Function Definition: main( ( temp void) +0:27 Function Parameters: +0:? Sequence +0:27 move second child to first child ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? 'i' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? 'i' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float val}) +0:27 move second child to first child ( temp uint) +0:? 'cpid' ( temp uint) +0:? 'cpid' ( in uint InvocationID) +0:27 move second child to first child ( temp structure{ temp 3-component vector of float val}) +0:27 indirect index ( temp structure{ temp 3-component vector of float val}) +0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float val}) +0:? 'cpid' ( in uint InvocationID) +0:27 Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) +0:? 'i' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? 'cpid' ( temp uint) +0:? Barrier ( temp void) +0:? Test condition and select ( temp void) +0:? Condition +0:? Compare Equal ( temp bool) +0:? 'cpid' ( in uint InvocationID) +0:? Constant: +0:? 0 (const int) +0:? true case +0:? Sequence +0:? move second child to first child ( temp structure{ temp 3-component vector of float val}) +0:? direct index ( temp structure{ temp 3-component vector of float val}) +0:? 'pcf_out' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Constant: +0:? 0 (const int) +0:? Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) +0:? 'i' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Constant: +0:? 0 (const uint) +0:? move second child to first child ( temp structure{ temp 3-component vector of float val}) +0:? direct index ( temp structure{ temp 3-component vector of float val}) +0:? 'pcf_out' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Constant: +0:? 1 (const int) +0:? Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) +0:? 'i' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Constant: +0:? 1 (const uint) +0:? move second child to first child ( temp structure{ temp 3-component vector of float val}) +0:? direct index ( temp structure{ temp 3-component vector of float val}) +0:? 'pcf_out' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Constant: +0:? 2 (const int) +0:? Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) +0:? 'i' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Constant: +0:? 2 (const uint) +0:? move second child to first child ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? '@patchConstantResult' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Function Call: PCF(struct-hs_out_t-vf31[3]; ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? 'pcf_out' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Sequence +0:? move second child to first child ( temp float) +0:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_tfactor' ( patch out 4-element array of float TessLevelOuter) +0:? Constant: +0:? 0 (const int) +0:? direct index ( temp float) +0:? tfactor: direct index for structure ( temp 3-element array of float) +0:? '@patchConstantResult' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Constant: +0:? 0 (const int) +0:? Constant: +0:? 0 (const int) +0:? move second child to first child ( temp float) +0:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_tfactor' ( patch out 4-element array of float TessLevelOuter) +0:? Constant: +0:? 1 (const int) +0:? direct index ( temp float) +0:? tfactor: direct index for structure ( temp 3-element array of float) +0:? '@patchConstantResult' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Constant: +0:? 0 (const int) +0:? Constant: +0:? 1 (const int) +0:? move second child to first child ( temp float) +0:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_tfactor' ( patch out 4-element array of float TessLevelOuter) +0:? Constant: +0:? 2 (const int) +0:? direct index ( temp float) +0:? tfactor: direct index for structure ( temp 3-element array of float) +0:? '@patchConstantResult' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Constant: +0:? 0 (const int) +0:? Constant: +0:? 2 (const int) +0:? move second child to first child ( temp float) +0:? direct index ( patch out float TessLevelInner) +0:? '@patchConstantOutput_flInFactor' ( patch out 2-element array of float TessLevelInner) +0:? Constant: +0:? 0 (const int) +0:? flInFactor: direct index for structure ( temp float) +0:? '@patchConstantResult' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Constant: +0:? 1 (const int) +0:34 Function Definition: PCF(struct-hs_out_t-vf31[3]; ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:34 Function Parameters: +0:34 'pcf_out' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:? Sequence +0:37 move second child to first child ( temp float) +0:37 direct index ( temp float) +0:37 tfactor: direct index for structure ( temp 3-element array of float) +0:37 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:37 Constant: +0:37 0 (const int) +0:37 Constant: +0:37 0 (const int) +0:37 direct index ( temp float) +0:37 val: direct index for structure ( temp 3-component vector of float) +0:37 direct index ( temp structure{ temp 3-component vector of float val}) +0:37 'pcf_out' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:37 Constant: +0:37 0 (const int) +0:37 Constant: +0:37 0 (const int) +0:37 Constant: +0:37 0 (const int) +0:38 move second child to first child ( temp float) +0:38 direct index ( temp float) +0:38 tfactor: direct index for structure ( temp 3-element array of float) +0:38 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:38 Constant: +0:38 0 (const int) +0:38 Constant: +0:38 1 (const int) +0:38 direct index ( temp float) +0:38 val: direct index for structure ( temp 3-component vector of float) +0:38 direct index ( temp structure{ temp 3-component vector of float val}) +0:38 'pcf_out' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:38 Constant: +0:38 1 (const int) +0:38 Constant: +0:38 0 (const int) +0:38 Constant: +0:38 0 (const int) +0:39 move second child to first child ( temp float) +0:39 direct index ( temp float) +0:39 tfactor: direct index for structure ( temp 3-element array of float) +0:39 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:39 Constant: +0:39 0 (const int) +0:39 Constant: +0:39 2 (const int) +0:39 direct index ( temp float) +0:39 val: direct index for structure ( temp 3-component vector of float) +0:39 direct index ( temp structure{ temp 3-component vector of float val}) +0:39 'pcf_out' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:39 Constant: +0:39 2 (const int) +0:39 Constant: +0:39 0 (const int) +0:39 Constant: +0:39 0 (const int) +0:40 move second child to first child ( temp float) +0:40 flInFactor: direct index for structure ( temp float) +0:40 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:40 Constant: +0:40 1 (const int) +0:40 Constant: +0:40 4.000000 +0:42 Branch: Return with expression +0:42 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Linker Objects +0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float val}) +0:? 'i' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float val}) +0:? 'cpid' ( in uint InvocationID) +0:? '@patchConstantOutput' (layout( location=1) patch out structure{}) +0:? '@patchConstantOutput_tfactor' ( patch out 4-element array of float TessLevelOuter) +0:? '@patchConstantOutput_flInFactor' ( patch out 2-element array of float TessLevelInner) + + +Linked tessellation control stage: + + +Shader version: 450 +vertices = 3 +vertex spacing = fractional_odd_spacing +triangle order = cw +0:? Sequence +0:27 Function Definition: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) +0:27 Function Parameters: +0:27 'i' ( in 3-element array of structure{ temp 3-component vector of float val}) +0:27 'cpid' ( in uint) +0:? Sequence +0:29 move second child to first child ( temp 3-component vector of float) +0:29 val: direct index for structure ( temp 3-component vector of float) +0:29 'o' ( temp structure{ temp 3-component vector of float val}) +0:29 Constant: +0:29 0 (const int) +0:29 Construct vec3 ( temp 3-component vector of float) +0:29 Convert uint to float ( temp float) +0:29 'cpid' ( in uint) +0:30 Branch: Return with expression +0:30 'o' ( temp structure{ temp 3-component vector of float val}) +0:27 Function Definition: main( ( temp void) +0:27 Function Parameters: +0:? Sequence +0:27 move second child to first child ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? 'i' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? 'i' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float val}) +0:27 move second child to first child ( temp uint) +0:? 'cpid' ( temp uint) +0:? 'cpid' ( in uint InvocationID) +0:27 move second child to first child ( temp structure{ temp 3-component vector of float val}) +0:27 indirect index ( temp structure{ temp 3-component vector of float val}) +0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float val}) +0:? 'cpid' ( in uint InvocationID) +0:27 Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) +0:? 'i' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? 'cpid' ( temp uint) +0:? Barrier ( temp void) +0:? Test condition and select ( temp void) +0:? Condition +0:? Compare Equal ( temp bool) +0:? 'cpid' ( in uint InvocationID) +0:? Constant: +0:? 0 (const int) +0:? true case +0:? Sequence +0:? move second child to first child ( temp structure{ temp 3-component vector of float val}) +0:? direct index ( temp structure{ temp 3-component vector of float val}) +0:? 'pcf_out' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Constant: +0:? 0 (const int) +0:? Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) +0:? 'i' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Constant: +0:? 0 (const uint) +0:? move second child to first child ( temp structure{ temp 3-component vector of float val}) +0:? direct index ( temp structure{ temp 3-component vector of float val}) +0:? 'pcf_out' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Constant: +0:? 1 (const int) +0:? Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) +0:? 'i' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Constant: +0:? 1 (const uint) +0:? move second child to first child ( temp structure{ temp 3-component vector of float val}) +0:? direct index ( temp structure{ temp 3-component vector of float val}) +0:? 'pcf_out' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Constant: +0:? 2 (const int) +0:? Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) +0:? 'i' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Constant: +0:? 2 (const uint) +0:? move second child to first child ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? '@patchConstantResult' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Function Call: PCF(struct-hs_out_t-vf31[3]; ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? 'pcf_out' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Sequence +0:? move second child to first child ( temp float) +0:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_tfactor' ( patch out 4-element array of float TessLevelOuter) +0:? Constant: +0:? 0 (const int) +0:? direct index ( temp float) +0:? tfactor: direct index for structure ( temp 3-element array of float) +0:? '@patchConstantResult' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Constant: +0:? 0 (const int) +0:? Constant: +0:? 0 (const int) +0:? move second child to first child ( temp float) +0:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_tfactor' ( patch out 4-element array of float TessLevelOuter) +0:? Constant: +0:? 1 (const int) +0:? direct index ( temp float) +0:? tfactor: direct index for structure ( temp 3-element array of float) +0:? '@patchConstantResult' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Constant: +0:? 0 (const int) +0:? Constant: +0:? 1 (const int) +0:? move second child to first child ( temp float) +0:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_tfactor' ( patch out 4-element array of float TessLevelOuter) +0:? Constant: +0:? 2 (const int) +0:? direct index ( temp float) +0:? tfactor: direct index for structure ( temp 3-element array of float) +0:? '@patchConstantResult' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Constant: +0:? 0 (const int) +0:? Constant: +0:? 2 (const int) +0:? move second child to first child ( temp float) +0:? direct index ( patch out float TessLevelInner) +0:? '@patchConstantOutput_flInFactor' ( patch out 2-element array of float TessLevelInner) +0:? Constant: +0:? 0 (const int) +0:? flInFactor: direct index for structure ( temp float) +0:? '@patchConstantResult' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Constant: +0:? 1 (const int) +0:34 Function Definition: PCF(struct-hs_out_t-vf31[3]; ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:34 Function Parameters: +0:34 'pcf_out' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:? Sequence +0:37 move second child to first child ( temp float) +0:37 direct index ( temp float) +0:37 tfactor: direct index for structure ( temp 3-element array of float) +0:37 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:37 Constant: +0:37 0 (const int) +0:37 Constant: +0:37 0 (const int) +0:37 direct index ( temp float) +0:37 val: direct index for structure ( temp 3-component vector of float) +0:37 direct index ( temp structure{ temp 3-component vector of float val}) +0:37 'pcf_out' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:37 Constant: +0:37 0 (const int) +0:37 Constant: +0:37 0 (const int) +0:37 Constant: +0:37 0 (const int) +0:38 move second child to first child ( temp float) +0:38 direct index ( temp float) +0:38 tfactor: direct index for structure ( temp 3-element array of float) +0:38 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:38 Constant: +0:38 0 (const int) +0:38 Constant: +0:38 1 (const int) +0:38 direct index ( temp float) +0:38 val: direct index for structure ( temp 3-component vector of float) +0:38 direct index ( temp structure{ temp 3-component vector of float val}) +0:38 'pcf_out' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:38 Constant: +0:38 1 (const int) +0:38 Constant: +0:38 0 (const int) +0:38 Constant: +0:38 0 (const int) +0:39 move second child to first child ( temp float) +0:39 direct index ( temp float) +0:39 tfactor: direct index for structure ( temp 3-element array of float) +0:39 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:39 Constant: +0:39 0 (const int) +0:39 Constant: +0:39 2 (const int) +0:39 direct index ( temp float) +0:39 val: direct index for structure ( temp 3-component vector of float) +0:39 direct index ( temp structure{ temp 3-component vector of float val}) +0:39 'pcf_out' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:39 Constant: +0:39 2 (const int) +0:39 Constant: +0:39 0 (const int) +0:39 Constant: +0:39 0 (const int) +0:40 move second child to first child ( temp float) +0:40 flInFactor: direct index for structure ( temp float) +0:40 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:40 Constant: +0:40 1 (const int) +0:40 Constant: +0:40 4.000000 +0:42 Branch: Return with expression +0:42 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Linker Objects +0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float val}) +0:? 'i' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float val}) +0:? 'cpid' ( in uint InvocationID) +0:? '@patchConstantOutput' (layout( location=1) patch out structure{}) +0:? '@patchConstantOutput_tfactor' ( patch out 4-element array of float TessLevelOuter) +0:? '@patchConstantOutput_flInFactor' ( patch out 2-element array of float TessLevelInner) + +// Module Version 10000 +// Generated by (magic number): 80001 +// Id's are bound by 127 + + Capability Tessellation + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint TessellationControl 4 "main" 41 45 48 94 108 126 + ExecutionMode 4 OutputVertices 3 + ExecutionMode 4 Triangles + ExecutionMode 4 SpacingFractionalOdd + ExecutionMode 4 VertexOrderCw + Name 4 "main" + Name 8 "hs_in_t" + MemberName 8(hs_in_t) 0 "val" + Name 14 "hs_out_t" + MemberName 14(hs_out_t) 0 "val" + Name 18 "@main(struct-hs_in_t-vf31[3];u1;" + Name 16 "i" + Name 17 "cpid" + Name 22 "hs_pcf_t" + MemberName 22(hs_pcf_t) 0 "tfactor" + MemberName 22(hs_pcf_t) 1 "flInFactor" + Name 25 "PCF(struct-hs_out_t-vf31[3];" + Name 24 "pcf_out" + Name 28 "o" + Name 39 "i" + Name 41 "i" + Name 43 "cpid" + Name 45 "cpid" + Name 48 "@entryPointOutput" + Name 50 "param" + Name 52 "param" + Name 66 "pcf_out" + Name 67 "i" + Name 68 "param" + Name 70 "param" + Name 74 "i" + Name 75 "param" + Name 77 "param" + Name 81 "i" + Name 82 "param" + Name 84 "param" + Name 88 "@patchConstantResult" + Name 94 "@patchConstantOutput_tfactor" + Name 108 "@patchConstantOutput_flInFactor" + Name 112 "o" + Name 124 "hs_pcf_t" + Name 126 "@patchConstantOutput" + Decorate 41(i) Location 0 + Decorate 45(cpid) BuiltIn InvocationId + Decorate 48(@entryPointOutput) Location 0 + Decorate 94(@patchConstantOutput_tfactor) Patch + Decorate 94(@patchConstantOutput_tfactor) BuiltIn TessLevelOuter + Decorate 108(@patchConstantOutput_flInFactor) Patch + Decorate 108(@patchConstantOutput_flInFactor) BuiltIn TessLevelInner + Decorate 126(@patchConstantOutput) Patch + Decorate 126(@patchConstantOutput) Location 1 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 3 + 8(hs_in_t): TypeStruct 7(fvec3) + 9: TypeInt 32 0 + 10: 9(int) Constant 3 + 11: TypeArray 8(hs_in_t) 10 + 12: TypePointer Function 11 + 13: TypePointer Function 9(int) + 14(hs_out_t): TypeStruct 7(fvec3) + 15: TypeFunction 14(hs_out_t) 12(ptr) 13(ptr) + 20: TypeArray 14(hs_out_t) 10 + 21: TypeArray 6(float) 10 + 22(hs_pcf_t): TypeStruct 21 6(float) + 23: TypeFunction 22(hs_pcf_t) 20 + 27: TypePointer Function 14(hs_out_t) + 29: TypeInt 32 1 + 30: 29(int) Constant 0 + 34: TypePointer Function 7(fvec3) + 40: TypePointer Input 11 + 41(i): 40(ptr) Variable Input + 44: TypePointer Input 9(int) + 45(cpid): 44(ptr) Variable Input + 47: TypePointer Output 20 +48(@entryPointOutput): 47(ptr) Variable Output + 55: TypePointer Output 14(hs_out_t) + 57: 9(int) Constant 2 + 58: 9(int) Constant 1 + 59: 9(int) Constant 0 + 61: TypeBool + 65: TypePointer Function 20 + 73: 29(int) Constant 1 + 80: 29(int) Constant 2 + 87: TypePointer Function 22(hs_pcf_t) + 91: 9(int) Constant 4 + 92: TypeArray 6(float) 91 + 93: TypePointer Output 92 +94(@patchConstantOutput_tfactor): 93(ptr) Variable Output + 95: TypePointer Function 6(float) + 98: TypePointer Output 6(float) + 106: TypeArray 6(float) 57 + 107: TypePointer Output 106 +108(@patchConstantOutput_flInFactor): 107(ptr) Variable Output + 119: 6(float) Constant 1082130432 + 124(hs_pcf_t): TypeStruct + 125: TypePointer Output 124(hs_pcf_t) +126(@patchConstantOutput): 125(ptr) Variable Output + 4(main): 2 Function None 3 + 5: Label + 39(i): 12(ptr) Variable Function + 43(cpid): 13(ptr) Variable Function + 50(param): 12(ptr) Variable Function + 52(param): 13(ptr) Variable Function + 66(pcf_out): 65(ptr) Variable Function + 67(i): 12(ptr) Variable Function + 68(param): 12(ptr) Variable Function + 70(param): 13(ptr) Variable Function + 74(i): 12(ptr) Variable Function + 75(param): 12(ptr) Variable Function + 77(param): 13(ptr) Variable Function + 81(i): 12(ptr) Variable Function + 82(param): 12(ptr) Variable Function + 84(param): 13(ptr) Variable Function +88(@patchConstantResult): 87(ptr) Variable Function + 42: 11 Load 41(i) + Store 39(i) 42 + 46: 9(int) Load 45(cpid) + Store 43(cpid) 46 + 49: 9(int) Load 45(cpid) + 51: 11 Load 39(i) + Store 50(param) 51 + 53: 9(int) Load 43(cpid) + Store 52(param) 53 + 54:14(hs_out_t) FunctionCall 18(@main(struct-hs_in_t-vf31[3];u1;) 50(param) 52(param) + 56: 55(ptr) AccessChain 48(@entryPointOutput) 49 + Store 56 54 + ControlBarrier 57 58 59 + 60: 9(int) Load 45(cpid) + 62: 61(bool) IEqual 60 30 + SelectionMerge 64 None + BranchConditional 62 63 64 + 63: Label + 69: 11 Load 67(i) + Store 68(param) 69 + Store 70(param) 59 + 71:14(hs_out_t) FunctionCall 18(@main(struct-hs_in_t-vf31[3];u1;) 68(param) 70(param) + 72: 27(ptr) AccessChain 66(pcf_out) 30 + Store 72 71 + 76: 11 Load 74(i) + Store 75(param) 76 + Store 77(param) 58 + 78:14(hs_out_t) FunctionCall 18(@main(struct-hs_in_t-vf31[3];u1;) 75(param) 77(param) + 79: 27(ptr) AccessChain 66(pcf_out) 73 + Store 79 78 + 83: 11 Load 81(i) + Store 82(param) 83 + Store 84(param) 57 + 85:14(hs_out_t) FunctionCall 18(@main(struct-hs_in_t-vf31[3];u1;) 82(param) 84(param) + 86: 27(ptr) AccessChain 66(pcf_out) 80 + Store 86 85 + 89: 20 Load 66(pcf_out) + 90:22(hs_pcf_t) FunctionCall 25(PCF(struct-hs_out_t-vf31[3];) 89 + Store 88(@patchConstantResult) 90 + 96: 95(ptr) AccessChain 88(@patchConstantResult) 30 30 + 97: 6(float) Load 96 + 99: 98(ptr) AccessChain 94(@patchConstantOutput_tfactor) 30 + Store 99 97 + 100: 95(ptr) AccessChain 88(@patchConstantResult) 30 73 + 101: 6(float) Load 100 + 102: 98(ptr) AccessChain 94(@patchConstantOutput_tfactor) 73 + Store 102 101 + 103: 95(ptr) AccessChain 88(@patchConstantResult) 30 80 + 104: 6(float) Load 103 + 105: 98(ptr) AccessChain 94(@patchConstantOutput_tfactor) 80 + Store 105 104 + 109: 95(ptr) AccessChain 88(@patchConstantResult) 73 + 110: 6(float) Load 109 + 111: 98(ptr) AccessChain 108(@patchConstantOutput_flInFactor) 30 + Store 111 110 + Branch 64 + 64: Label + Return + FunctionEnd +18(@main(struct-hs_in_t-vf31[3];u1;):14(hs_out_t) Function None 15 + 16(i): 12(ptr) FunctionParameter + 17(cpid): 13(ptr) FunctionParameter + 19: Label + 28(o): 27(ptr) Variable Function + 31: 9(int) Load 17(cpid) + 32: 6(float) ConvertUToF 31 + 33: 7(fvec3) CompositeConstruct 32 32 32 + 35: 34(ptr) AccessChain 28(o) 30 + Store 35 33 + 36:14(hs_out_t) Load 28(o) + ReturnValue 36 + FunctionEnd +25(PCF(struct-hs_out_t-vf31[3];):22(hs_pcf_t) Function None 23 + 24(pcf_out): 20 FunctionParameter + 26: Label + 112(o): 87(ptr) Variable Function + 113: 6(float) CompositeExtract 24(pcf_out) 0 0 0 + 114: 95(ptr) AccessChain 112(o) 30 30 + Store 114 113 + 115: 6(float) CompositeExtract 24(pcf_out) 1 0 0 + 116: 95(ptr) AccessChain 112(o) 30 73 + Store 116 115 + 117: 6(float) CompositeExtract 24(pcf_out) 2 0 0 + 118: 95(ptr) AccessChain 112(o) 30 80 + Store 118 117 + 120: 95(ptr) AccessChain 112(o) 73 + Store 120 119 + 121:22(hs_pcf_t) Load 112(o) + ReturnValue 121 + FunctionEnd diff --git a/Test/baseResults/hlsl.hull.void.tesc.out b/Test/baseResults/hlsl.hull.void.tesc.out index a2d0a1c7..20b8dd32 100644 --- a/Test/baseResults/hlsl.hull.void.tesc.out +++ b/Test/baseResults/hlsl.hull.void.tesc.out @@ -1,6 +1,7 @@ hlsl.hull.void.tesc Shader version: 450 vertices = 3 +vertex spacing = fractional_even_spacing 0:? Sequence 0:26 Function Definition: @main(struct-VS_OUT-vf31[3]; ( temp structure{ temp 3-component vector of float cpoint}) 0:26 Function Parameters: @@ -27,7 +28,9 @@ vertices = 3 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: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:? 'ip' ( temp 3-element array of structure{ temp 3-component vector of float cpoint}) 0:? Barrier ( temp void) @@ -38,11 +41,12 @@ vertices = 3 0:? Constant: 0:? 0 (const int) 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 Parameters: 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:? 'InvocationId' ( in uint InvocationID) @@ -52,6 +56,7 @@ Linked tessellation control stage: Shader version: 450 vertices = 3 +vertex spacing = fractional_even_spacing 0:? Sequence 0:26 Function Definition: @main(struct-VS_OUT-vf31[3]; ( temp structure{ temp 3-component vector of float cpoint}) 0:26 Function Parameters: @@ -78,7 +83,9 @@ vertices = 3 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: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:? 'ip' ( temp 3-element array of structure{ temp 3-component vector of float cpoint}) 0:? Barrier ( temp void) @@ -89,23 +96,26 @@ vertices = 3 0:? Constant: 0:? 0 (const int) 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 Parameters: 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:? 'InvocationId' ( in uint InvocationID) // Module Version 10000 // Generated by (magic number): 80001 -// Id's are bound by 51 +// Id's are bound by 55 Capability Tessellation 1: ExtInstImport "GLSL.std.450" MemoryModel Logical GLSL450 - EntryPoint TessellationControl 4 "main" 33 36 44 + EntryPoint TessellationControl 4 "main" 33 37 39 ExecutionMode 4 OutputVertices 3 + ExecutionMode 4 Triangles + ExecutionMode 4 SpacingFractionalEven Name 4 "main" Name 8 "VS_OUT" MemberName 8(VS_OUT) 0 "cpoint" @@ -117,12 +127,12 @@ vertices = 3 Name 21 "output" Name 31 "ip" Name 33 "ip" - Name 36 "@entryPointOutput" - Name 37 "param" - Name 44 "InvocationId" + Name 37 "@entryPointOutput" + Name 39 "InvocationId" + Name 41 "param" Decorate 33(ip) Location 0 - Decorate 36(@entryPointOutput) Location 0 - Decorate 44(InvocationId) BuiltIn InvocationId + Decorate 37(@entryPointOutput) Location 0 + Decorate 39(InvocationId) BuiltIn InvocationId 2: TypeVoid 3: TypeFunction 2 6: TypeFloat 32 @@ -140,33 +150,37 @@ vertices = 3 24: TypePointer Function 7(fvec3) 32: TypePointer Input 11 33(ip): 32(ptr) Variable Input - 35: TypePointer Output 13(HS_OUT) -36(@entryPointOutput): 35(ptr) Variable Output - 40: 9(int) Constant 2 - 41: 9(int) Constant 1 - 42: 9(int) Constant 0 - 43: TypePointer Input 9(int) -44(InvocationId): 43(ptr) Variable Input - 46: TypeBool + 35: TypeArray 13(HS_OUT) 10 + 36: TypePointer Output 35 +37(@entryPointOutput): 36(ptr) Variable Output + 38: TypePointer Input 9(int) +39(InvocationId): 38(ptr) Variable Input + 44: TypePointer Output 13(HS_OUT) + 46: 9(int) Constant 2 + 47: 9(int) Constant 1 + 48: 9(int) Constant 0 + 50: TypeBool 4(main): 2 Function None 3 5: Label 31(ip): 12(ptr) Variable Function - 37(param): 12(ptr) Variable Function + 41(param): 12(ptr) Variable Function 34: 11 Load 33(ip) Store 31(ip) 34 - 38: 11 Load 31(ip) - Store 37(param) 38 - 39: 13(HS_OUT) FunctionCall 16(@main(struct-VS_OUT-vf31[3];) 37(param) - Store 36(@entryPointOutput) 39 - ControlBarrier 40 41 42 - 45: 9(int) Load 44(InvocationId) - 47: 46(bool) IEqual 45 23 - SelectionMerge 49 None - BranchConditional 47 48 49 - 48: Label - 50: 2 FunctionCall 18(PCF() - Branch 49 - 49: Label + 40: 9(int) Load 39(InvocationId) + 42: 11 Load 31(ip) + Store 41(param) 42 + 43: 13(HS_OUT) FunctionCall 16(@main(struct-VS_OUT-vf31[3];) 41(param) + 45: 44(ptr) AccessChain 37(@entryPointOutput) 40 + Store 45 43 + ControlBarrier 46 47 48 + 49: 9(int) Load 39(InvocationId) + 51: 50(bool) IEqual 49 23 + SelectionMerge 53 None + BranchConditional 51 52 53 + 52: Label + 54: 2 FunctionCall 18(PCF() + Branch 53 + 53: Label Return FunctionEnd 16(@main(struct-VS_OUT-vf31[3];): 13(HS_OUT) Function None 14 diff --git a/Test/hlsl.domain.1.tese b/Test/hlsl.domain.1.tese new file mode 100644 index 00000000..50394104 --- /dev/null +++ b/Test/hlsl.domain.1.tese @@ -0,0 +1,32 @@ + +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 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; +} + diff --git a/Test/hlsl.hull.ctrlpt-1.tesc b/Test/hlsl.hull.ctrlpt-1.tesc new file mode 100644 index 00000000..3e329f25 --- /dev/null +++ b/Test/hlsl.hull.ctrlpt-1.tesc @@ -0,0 +1,43 @@ +// *** +// 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 i , uint cpid : SV_OutputControlPointID) +{ + hs_out_t o; + o.val = cpid; + return o; +} + +hs_pcf_t PCF( const OutputPatch 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; +} diff --git a/glslang/MachineIndependent/intermOut.cpp b/glslang/MachineIndependent/intermOut.cpp index b8a6969d..c0c60c57 100644 --- a/glslang/MachineIndependent/intermOut.cpp +++ b/glslang/MachineIndependent/intermOut.cpp @@ -884,6 +884,13 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree) case EShLangTessControl: 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; case EShLangTessEvaluation: diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp index 761cb416..0328009d 100644 --- a/glslang/MachineIndependent/linkValidate.cpp +++ b/glslang/MachineIndependent/linkValidate.cpp @@ -461,10 +461,12 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) case EShLangTessEvaluation: if (inputPrimitive == ElgNone) error(infoSink, "At least one shader must specify an input layout primitive"); - if (vertexSpacing == EvsNone) - vertexSpacing = EvsEqual; - if (vertexOrder == EvoNone) - vertexOrder = EvoCcw; + if (source == EShSourceGlsl) { + if (vertexSpacing == EvsNone) + vertexSpacing = EvsEqual; + if (vertexOrder == EvoNone) + vertexOrder = EvoCcw; + } break; case EShLangGeometry: if (inputPrimitive == ElgNone) diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index fe471829..efbc970e 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -123,9 +123,11 @@ INSTANTIATE_TEST_CASE_P( {"hlsl.getdimensions.rw.dx10.frag", "main"}, {"hlsl.getdimensions.dx10.vert", "main"}, {"hlsl.getsampleposition.dx10.frag", "main"}, + {"hlsl.domain.1.tese", "main"}, {"hlsl.hull.1.tesc", "main"}, {"hlsl.hull.2.tesc", "main"}, {"hlsl.hull.void.tesc", "main"}, + {"hlsl.hull.ctrlpt-1.tesc", "main"}, {"hlsl.identifier.sample.frag", "main"}, {"hlsl.if.frag", "PixelShaderFunction"}, {"hlsl.implicitBool.frag", "main"}, diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index 60ce1158..c5c0a1d6 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -1047,6 +1047,8 @@ TType& HlslParseContext::split(TType& type, TString name, const TType* outerStru if (arraySizes) ioVar->getWritableType().newArraySizes(*arraySizes); + fixBuiltInArrayType(ioVar->getWritableType()); + interstageBuiltInIo[tInterstageIoData(memberType, *outerStructType)] = ioVar; // Merge qualifier from the user structure @@ -1381,6 +1383,34 @@ void HlslParseContext::trackLinkage(TSymbol& symbol) } +// Some types require fixed array sizes in SPIR-V, but can be scalars or +// arrays of sizes SPIR-V doesn't allow. For example, tessellation factors. +// This creates the right size. A conversion is performed when the internal +// type is copied to or from the external type. +void HlslParseContext::fixBuiltInArrayType(TType& type) +{ + int requiredSize = 0; + + switch (type.getQualifier().builtIn) { + case EbvTessLevelOuter: requiredSize = 4; break; + case EbvTessLevelInner: requiredSize = 2; break; + case EbvClipDistance: // TODO: ... + case EbvCullDistance: // TODO: ... + default: + return; + } + + if (type.isArray()) { + // Already an array. Fix the size. + type.changeOuterArraySize(requiredSize); + } else { + // it wasn't an array, but needs to be. + TArraySizes arraySizes; + arraySizes.addInnerSize(requiredSize); + type.newArraySizes(arraySizes); + } +} + // Variables that correspond to the user-interface in and out of a stage // (not the built-in interface) are assigned locations and // registered as a linkage node (part of the stage's external interface). @@ -1389,15 +1419,24 @@ void HlslParseContext::trackLinkage(TSymbol& symbol) void HlslParseContext::assignLocations(TVariable& variable) { const auto assignLocation = [&](TVariable& variable) { - const TQualifier& qualifier = variable.getType().getQualifier(); + const TType& type = variable.getType(); + const TQualifier& qualifier = type.getQualifier(); if (qualifier.storage == EvqVaryingIn || qualifier.storage == EvqVaryingOut) { if (qualifier.builtIn == EbvNone) { + // Strip off the outer array dimension for those having an extra one. + int size; + if (type.isArray() && qualifier.isArrayedIo(language)) { + TType elementType(type, 0); + size = intermediate.computeTypeLocationSize(elementType); + } else + size = intermediate.computeTypeLocationSize(type); + if (qualifier.storage == EvqVaryingIn) { variable.getWritableType().getQualifier().layoutLocation = nextInLocation; - nextInLocation += intermediate.computeTypeLocationSize(variable.getType()); + nextInLocation += size; } else { variable.getWritableType().getQualifier().layoutLocation = nextOutLocation; - nextOutLocation += intermediate.computeTypeLocationSize(variable.getType()); + nextOutLocation += size; } } @@ -1559,48 +1598,10 @@ TIntermAggregate* HlslParseContext::handleFunctionDefinition(const TSourceLoc& l return paramNodes; } -// -// Do all special handling for the entry point, including wrapping -// the shader's entry point with the official entry point that will call it. -// -// The following: -// -// retType shaderEntryPoint(args...) // shader declared entry point -// { body } -// -// Becomes -// -// out retType ret; -// in iargs...; -// out oargs ...; -// -// void shaderEntryPoint() // synthesized, but official, entry point -// { -// args = iargs...; -// ret = @shaderEntryPoint(args...); -// oargs = args...; -// } -// -// The symbol table will still map the original entry point name to the -// the modified function and it's new name: -// -// symbol table: shaderEntryPoint -> @shaderEntryPoint -// -// Returns nullptr if no entry-point tree was built, otherwise, returns -// a subtree that creates the entry point. -// -TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunction& userFunction, const TAttributeMap& attributes) + +// Handle all [attrib] attribute for the shader entry point +void HlslParseContext::handleEntryPointAttributes(const TSourceLoc& loc, const TAttributeMap& attributes) { - // if we aren't in the entry point, fix the IO as such and exit - if (userFunction.getName().compare(intermediate.getEntryPointName().c_str()) != 0) { - remapNonEntryPointIO(userFunction); - return nullptr; - } - - entryPointFunction = &userFunction; // needed in finish() - - // entry point logic... - // Handle entry-point function attributes const TIntermAggregate* numThreads = attributes[EatNumThreads]; if (numThreads != nullptr) { @@ -1652,8 +1653,12 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct error(loc, "unsupported domain type", domainStr.c_str(), ""); } - if (! intermediate.setInputPrimitive(domain)) { - error(loc, "cannot change previously set domain", TQualifier::getGeometryString(domain), ""); + if (language == EShLangTessEvaluation) { + if (! intermediate.setInputPrimitive(domain)) + error(loc, "cannot change previously set domain", TQualifier::getGeometryString(domain), ""); + } else { + if (! intermediate.setOutputPrimitive(domain)) + error(loc, "cannot change previously set domain", TQualifier::getGeometryString(domain), ""); } } } @@ -1731,6 +1736,52 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct } } } +} + +// +// Do all special handling for the entry point, including wrapping +// the shader's entry point with the official entry point that will call it. +// +// The following: +// +// retType shaderEntryPoint(args...) // shader declared entry point +// { body } +// +// Becomes +// +// out retType ret; +// in iargs...; +// out oargs ...; +// +// void shaderEntryPoint() // synthesized, but official, entry point +// { +// args = iargs...; +// ret = @shaderEntryPoint(args...); +// oargs = args...; +// } +// +// The symbol table will still map the original entry point name to the +// the modified function and it's new name: +// +// symbol table: shaderEntryPoint -> @shaderEntryPoint +// +// Returns nullptr if no entry-point tree was built, otherwise, returns +// a subtree that creates the entry point. +// +TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunction& userFunction, const TAttributeMap& attributes) +{ + // if we aren't in the entry point, fix the IO as such and exit + if (userFunction.getName().compare(intermediate.getEntryPointName().c_str()) != 0) { + remapNonEntryPointIO(userFunction); + return nullptr; + } + + entryPointFunction = &userFunction; // needed in finish() + + // Handle entry point attributes + handleEntryPointAttributes(loc, attributes); + + // entry point logic... // Move parameters and return value to shader in/out TVariable* entryPointOutput; // gets created in remapEntryPointIO @@ -1799,10 +1850,40 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct currentCaller = userFunction.getMangledName(); // Return value - if (entryPointOutput) - intermediate.growAggregate(synthBody, handleAssign(loc, EOpAssign, - intermediate.addSymbol(*entryPointOutput), callReturn)); - else + if (entryPointOutput) { + TIntermTyped* returnAssign; + + // For hull shaders, the wrapped entry point return value is written to + // an array element as indexed by invocation ID, which we might have to make up. + // This is required to match SPIR-V semantics. + if (language == EShLangTessControl) { + TIntermSymbol* invocationIdSym = findLinkageSymbol(EbvInvocationId); + + // If there is no user declared invocation ID, we must make one. + if (invocationIdSym == nullptr) { + TType invocationIdType(EbtUint, EvqIn, 1); + TString* invocationIdName = NewPoolTString("InvocationId"); + invocationIdType.getQualifier().builtIn = EbvInvocationId; + + TVariable* variable = makeInternalVariable(*invocationIdName, invocationIdType); + + globalQualifierFix(loc, variable->getWritableType().getQualifier()); + trackLinkage(*variable); + + invocationIdSym = intermediate.addSymbol(*variable); + } + + TIntermTyped* element = intermediate.addIndex(EOpIndexIndirect, intermediate.addSymbol(*entryPointOutput), + invocationIdSym, loc); + element->setType(callReturn->getType()); + + returnAssign = handleAssign(loc, EOpAssign, element, callReturn); + } else { + returnAssign = handleAssign(loc, EOpAssign, intermediate.addSymbol(*entryPointOutput), callReturn); + } + + intermediate.growAggregate(synthBody, returnAssign); + } else intermediate.growAggregate(synthBody, callReturn); // Output copies @@ -1862,19 +1943,42 @@ void HlslParseContext::remapEntryPointIO(TFunction& function, TVariable*& return ioVariable->getWritableType().setStruct(newLists->second.output); } } - if (storage == EvqVaryingIn) + if (storage == EvqVaryingIn) { correctInput(ioVariable->getWritableType().getQualifier()); - else + if (language == EShLangTessEvaluation) + if (!ioVariable->getType().isArray()) + ioVariable->getWritableType().getQualifier().patch = true; + } else { correctOutput(ioVariable->getWritableType().getQualifier()); + } ioVariable->getWritableType().getQualifier().storage = storage; return ioVariable; }; // return value is actually a shader-scoped output (out) - if (function.getType().getBasicType() == EbtVoid) + if (function.getType().getBasicType() == EbtVoid) { returnValue = nullptr; - else - returnValue = makeIoVariable("@entryPointOutput", function.getWritableType(), EvqVaryingOut); + } else { + if (language == EShLangTessControl) { + // tessellation evaluation in HLSL writes a per-ctrl-pt value, but it needs to be an + // array in SPIR-V semantics. We'll write to it indexed by invocation ID. + + returnValue = makeIoVariable("@entryPointOutput", function.getWritableType(), EvqVaryingOut); + + TType outputType; + outputType.shallowCopy(function.getType()); + + // vertices has necessarily already been set when handling entry point attributes. + TArraySizes arraySizes; + arraySizes.addInnerSize(intermediate.getVertices()); + outputType.newArraySizes(arraySizes); + + clearUniformInputOutput(function.getWritableType().getQualifier()); + returnValue = makeIoVariable("@entryPointOutput", outputType, EvqVaryingOut); + } else { + returnValue = makeIoVariable("@entryPointOutput", function.getWritableType(), EvqVaryingOut); + } + } // parameters are actually shader-scoped inputs and outputs (in or out) for (int i = 0; i < function.getParamCount(); i++) { @@ -2031,7 +2135,11 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op const bool split = isLeft ? isSplitLeft : isSplitRight; const TIntermTyped* outer = isLeft ? outerLeft : outerRight; const TVector& flatVariables = isLeft ? *leftVariables : *rightVariables; - const TOperator op = node->getType().isArray() ? EOpIndexDirect : EOpIndexDirectStruct; + + // Index operator if it's an aggregate, else EOpNull + const TOperator op = node->getType().isArray() ? EOpIndexDirect : + node->getType().isStruct() ? EOpIndexDirectStruct : EOpNull; + const TType derefType(node->getType(), member); if (split && derefType.isBuiltInInterstageIO(language)) { @@ -2047,10 +2155,14 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op } else if (flattened && isFinalFlattening(derefType)) { subTree = intermediate.addSymbol(*flatVariables[memberIdx++]); } else { - const TType splitDerefType(splitNode->getType(), splitMember); + if (op == EOpNull) { + subTree = splitNode; + } else { + const TType splitDerefType(splitNode->getType(), splitMember); - subTree = intermediate.addIndex(op, splitNode, intermediate.addConstantUnion(splitMember, loc), loc); - subTree->setType(splitDerefType); + subTree = intermediate.addIndex(op, splitNode, intermediate.addConstantUnion(splitMember, loc), loc); + subTree->setType(splitDerefType); + } } return subTree; @@ -2069,11 +2181,15 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op // If we get here, we are assigning to or from a whole array or struct that must be // flattened, so have to do member-by-member assignment: - if (left->getType().isArray()) { - const TType dereferencedType(left->getType(), 0); + if (left->getType().isArray() || right->getType().isArray()) { + const int elementsL = left->getType().isArray() ? left->getType().getOuterArraySize() : 1; + const int elementsR = right->getType().isArray() ? right->getType().getOuterArraySize() : 1; + + // The arrays may not be the same size, e.g, if the size has been forced for EbvTessLevelInner or Outer. + const int elementsToCopy = std::min(elementsL, elementsR); // array case - for (int element=0; element < left->getType().getOuterArraySize(); ++element) { + for (int element=0; element < elementsToCopy; ++element) { arrayElement.push_back(element); // Add a new AST symbol node if we have a temp variable holding a complex RHS. @@ -2083,10 +2199,7 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op TIntermTyped* subSplitLeft = isSplitLeft ? getMember(true, left, element, splitLeft, element) : subLeft; TIntermTyped* subSplitRight = isSplitRight ? getMember(false, right, element, splitRight, element) : subRight; - if (isFinalFlattening(dereferencedType)) - assignList = intermediate.growAggregate(assignList, intermediate.addAssign(op, subLeft, subRight, loc), loc); - else - traverse(subLeft, subRight, subSplitLeft, subSplitRight); + traverse(subLeft, subRight, subSplitLeft, subSplitRight); arrayElement.pop_back(); } @@ -2120,8 +2233,8 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op // subtree here IFF it does not itself contain any interstage built-in IO variables, so we only have to // recurse into it if there's something for splitting to do. That can save a lot of AST verbosity for // a bunch of memberwise copies. - if (isFinalFlattening(typeL) || (!isFlattenLeft && !isFlattenRight && - !typeL.containsBuiltInInterstageIO(language) && !typeR.containsBuiltInInterstageIO(language))) { + if ((!isFlattenLeft && !isFlattenRight && + !typeL.containsBuiltInInterstageIO(language) && !typeR.containsBuiltInInterstageIO(language))) { assignList = intermediate.growAggregate(assignList, intermediate.addAssign(op, subSplitLeft, subSplitRight, loc), loc); } else { traverse(subLeft, subRight, subSplitLeft, subSplitRight); @@ -2131,8 +2244,8 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op memberR += (typeR.isBuiltInInterstageIO(language) ? 0 : 1); } } else { - assert(0); // we should never be called on a non-flattenable thing, because - // that case bails out above to a simple copy. + // Member copy + assignList = intermediate.growAggregate(assignList, intermediate.addAssign(op, left, right, loc), loc); } }; @@ -4178,6 +4291,10 @@ void HlslParseContext::handleSemantic(TSourceLoc loc, TQualifier& qualifier, TBu case EbvStencilRef: error(loc, "unimplemented; need ARB_shader_stencil_export", "SV_STENCILREF", ""); break; + case EbvTessLevelInner: + case EbvTessLevelOuter: + qualifier.patch = true; + break; default: break; } @@ -7225,6 +7342,8 @@ bool HlslParseContext::isInputBuiltIn(const TQualifier& qualifier) const case EbvTessLevelInner: case EbvTessLevelOuter: return language == EShLangTessEvaluation; + case EbvTessCoord: + return language == EShLangTessEvaluation; default: return false; } @@ -7362,6 +7481,17 @@ void HlslParseContext::clearUniformInputOutput(TQualifier& qualifier) correctUniform(qualifier); } + +// Return a symbol for the linkage variable of the given TBuiltInVariable type +TIntermSymbol* HlslParseContext::findLinkageSymbol(TBuiltInVariable biType) const +{ + const auto it = builtInLinkageSymbols.find(biType); + if (it == builtInLinkageSymbols.end()) // if it wasn't declared by the user, return nullptr + return nullptr; + + return intermediate.addSymbol(*it->second->getAsVariable()); +} + // Add patch constant function invocation void HlslParseContext::addPatchConstantInvocation() { @@ -7433,13 +7563,9 @@ void HlslParseContext::addPatchConstantInvocation() } }; - // Return a symbol for the linkage variable of the given TBuiltInVariable type - const auto findLinkageSymbol = [this](TBuiltInVariable biType) -> TIntermSymbol* { - const auto it = builtInLinkageSymbols.find(biType); - if (it == builtInLinkageSymbols.end()) // if it wasn't declared by the user, return nullptr - return nullptr; - - return intermediate.addSymbol(*it->second->getAsVariable()); + const auto isPerCtrlPt = [this](const TType& type) { + // TODO: this is not sufficient to reject all such cases in malformed shaders. + return type.isArray() && !type.isRuntimeSizedArray(); }; // We will perform these steps. Each is in a scoped block for separation: they could @@ -7451,21 +7577,25 @@ void HlslParseContext::addPatchConstantInvocation() // 2. Synthesizes a call to the patchconstfunction using builtin variables from either main, // or the ones we created. Matching is based on builtin type. We may use synthesized // variables from (1) above. + // + // 2B: Synthesize per control point invocations of wrapped entry point if the PCF requires them. // // 3. Create a return sequence: copy the return value (if any) from the PCF to a // (non-sanitized) output variable. In case this may involve multiple copies, such as for // an arrayed variable, a temporary copy of the PCF output is created to avoid multiple // indirections into a complex R-value coming from the call to the PCF. - // - // 4. Add a barrier to the end of the entry point body - // - // 5. Call the PCF inside an if test for (invocation id == 0). + // + // 4. Create a barrier. + // + // 5/5B. Call the PCF inside an if test for (invocation id == 0). TFunction& patchConstantFunction = const_cast(*candidateList[0]); const int pcfParamCount = patchConstantFunction.getParamCount(); TIntermSymbol* invocationIdSym = findLinkageSymbol(EbvInvocationId); TIntermSequence& epBodySeq = entryPointFunctionBody->getAsAggregate()->getSequence(); + int perCtrlPtParam = -1; // -1 means there isn't one. + // ================ Step 1A: Union Interfaces ================ // Our patch constant function. { @@ -7478,16 +7608,6 @@ void HlslParseContext::addPatchConstantInvocation() findBuiltIns(patchConstantFunction, pcfBuiltIns); findBuiltIns(*entryPointFunction, epfBuiltIns); - // Patchconstantfunction can contain only builtin qualified variables. (Technically, only HS inputs, - // but this test is less assertive than that). - - for (auto bi = pcfBuiltIns.begin(); bi != pcfBuiltIns.end(); ++bi) { - if (bi->builtIn == EbvNone) { - error(loc, "patch constant function invalid parameter", "", ""); - return; - } - } - // Find the set of builtins in the PCF that are not present in the entry point. std::set notInEntryPoint; @@ -7499,15 +7619,27 @@ void HlslParseContext::addPatchConstantInvocation() // Now we'll add those to the entry and to the linkage. for (int p=0; pclone(); const TBuiltInVariable biType = patchConstantFunction[p].declaredBuiltIn; const TStorageQualifier storage = patchConstantFunction[p].type->getQualifier().storage; - // Use the original declaration type for the linkage - paramType->getQualifier().builtIn = biType; + // Track whether there is any per control point input + if (isPerCtrlPt(*patchConstantFunction[p].type)) { + if (perCtrlPtParam >= 0) { + // Presently we only support one per ctrl pt input. TODO: does HLSL even allow multiple? + error(loc, "unimplemented: multiple per control point inputs to patch constant function", "", ""); + return; + } + perCtrlPtParam = p; + } - if (notInEntryPoint.count(tInterstageIoData(biType, storage)) == 1) - addToLinkage(*paramType, patchConstantFunction[p].name, nullptr); + if (biType != EbvNone) { + TType* paramType = patchConstantFunction[p].type->clone(); + // Use the original declaration type for the linkage + paramType->getQualifier().builtIn = biType; + + if (notInEntryPoint.count(tInterstageIoData(biType, storage)) == 1) + addToLinkage(*paramType, patchConstantFunction[p].name, nullptr); + } } // If we didn't find it because the shader made one, add our own. @@ -7522,36 +7654,50 @@ void HlslParseContext::addPatchConstantInvocation() } TIntermTyped* pcfArguments = nullptr; + TVariable* perCtrlPtVar = nullptr; // ================ Step 1B: Argument synthesis ================ // Create pcfArguments for synthesis of patchconstantfunction invocation // TODO: handle struct or array inputs { for (int p=0; pisArray() || - patchConstantFunction[p].type->isStruct()) { + if ((patchConstantFunction[p].type->isArray() && !isPerCtrlPt(*patchConstantFunction[p].type)) || + (!patchConstantFunction[p].type->isArray() && patchConstantFunction[p].type->isStruct())) { error(loc, "unimplemented array or variable in patch constant function signature", "", ""); return; } - // find which builtin it is - const TBuiltInVariable biType = patchConstantFunction[p].declaredBuiltIn; + TIntermSymbol* inputArg = nullptr; - TIntermSymbol* builtIn = findLinkageSymbol(biType); + if (p == perCtrlPtParam) { + if (perCtrlPtVar == nullptr) { + perCtrlPtVar = makeInternalVariable(*patchConstantFunction[perCtrlPtParam].name, + *patchConstantFunction[perCtrlPtParam].type); + + perCtrlPtVar->getWritableType().getQualifier().makeTemporary(); + } + inputArg = intermediate.addSymbol(*perCtrlPtVar, loc); + } else { + // find which builtin it is + const TBuiltInVariable biType = patchConstantFunction[p].declaredBuiltIn; + + inputArg = findLinkageSymbol(biType); - if (builtIn == nullptr) { - error(loc, "unable to find patch constant function builtin variable", "", ""); - return; + if (inputArg == nullptr) { + error(loc, "unable to find patch constant function builtin variable", "", ""); + return; + } } if (pcfParamCount == 1) - pcfArguments = builtIn; + pcfArguments = inputArg; else - pcfArguments = intermediate.growAggregate(pcfArguments, builtIn); + pcfArguments = intermediate.growAggregate(pcfArguments, inputArg); } } // ================ Step 2: Synthesize call to PCF ================ + TIntermAggregate* pcfCallSequence = nullptr; TIntermTyped* pcfCall = nullptr; { @@ -7563,7 +7709,8 @@ void HlslParseContext::addPatchConstantInvocation() pcfCall = intermediate.setAggregateOperator(pcfArguments, EOpFunctionCall, patchConstantFunction.getType(), loc); pcfCall->getAsAggregate()->setUserDefined(); pcfCall->getAsAggregate()->setName(patchConstantFunction.getMangledName()); - intermediate.addToCallGraph(infoSink, entryPointFunction->getMangledName(), patchConstantFunction.getMangledName()); + intermediate.addToCallGraph(infoSink, intermediate.getEntryPointMangledName().c_str(), + patchConstantFunction.getMangledName()); if (pcfCall->getAsAggregate()) { TQualifierList& qualifierList = pcfCall->getAsAggregate()->getQualifierList(); @@ -7575,6 +7722,71 @@ void HlslParseContext::addPatchConstantInvocation() } } + // ================ Step 2B: Per Control Point synthesis ================ + // If there is per control point data, we must either emulate that with multiple + // invocations of the entry point to build up an array, or (TODO:) use a yet + // unavailable extension to look across the SIMD lanes. This is the former + // as a placeholder for the latter. + if (perCtrlPtParam >= 0) { + // We must introduce a local temp variable of the type wanted by the PCF input. + const int arraySize = patchConstantFunction[perCtrlPtParam].type->getOuterArraySize(); + + if (entryPointFunction->getType().getBasicType() == EbtVoid) { + error(loc, "entry point must return a value for use with patch constant function", "", ""); + return; + } + + // Create calls to wrapped main to fill in the array. We will substitute fixed values + // of invocation ID when calling the wrapped main. + + // This is the type of the each member of the per ctrl point array. + const TType derefType(perCtrlPtVar->getType(), 0); + + for (int cpt = 0; cpt < arraySize; ++cpt) { + // TODO: improve. substr(1) here is to avoid the '@' that was grafted on but isn't in the symtab + // for this function. + const TString origName = entryPointFunction->getName().substr(1); + TFunction callee(&origName, TType(EbtVoid)); + TIntermTyped* callingArgs = nullptr; + + for (int i = 0; i < entryPointFunction->getParamCount(); i++) { + TParameter& param = (*entryPointFunction)[i]; + TType& paramType = *param.type; + + if (paramType.getQualifier().isParamOutput()) { + error(loc, "unimplemented: entry point outputs in patch constant function invocation", "", ""); + return; + } + + if (paramType.getQualifier().isParamInput()) { + TIntermTyped* arg = nullptr; + if ((*entryPointFunction)[i].declaredBuiltIn == EbvInvocationId) { + // substitute invocation ID with the array element ID + arg = intermediate.addConstantUnion(cpt, loc); + } else { + TVariable* argVar = makeInternalVariable(*param.name, *param.type); + argVar->getWritableType().getQualifier().makeTemporary(); + arg = intermediate.addSymbol(*argVar); + } + + handleFunctionArgument(&callee, callingArgs, arg); + } + } + + // Call and assign to per ctrl point variable + currentCaller = intermediate.getEntryPointMangledName().c_str(); + TIntermTyped* callReturn = handleFunctionCall(loc, &callee, callingArgs); + TIntermTyped* index = intermediate.addConstantUnion(cpt, loc); + TIntermSymbol* perCtrlPtSym = intermediate.addSymbol(*perCtrlPtVar, loc); + TIntermTyped* element = intermediate.addIndex(EOpIndexDirect, perCtrlPtSym, index, loc); + element->setType(derefType); + element->setLoc(loc); + + pcfCallSequence = intermediate.growAggregate(pcfCallSequence, + handleAssign(loc, EOpAssign, element, callReturn)); + } + } + // ================ Step 3: Create return Sequence ================ // Return sequence: copy PCF result to a temporary, then to shader output variable. if (pcfCall->getBasicType() != EbtVoid) { @@ -7591,30 +7803,31 @@ void HlslParseContext::addPatchConstantInvocation() if (patchConstantFunction.getDeclaredBuiltInType() != EbvNone) outType.getQualifier().builtIn = patchConstantFunction.getDeclaredBuiltInType(); + outType.getQualifier().patch = true; // make it a per-patch variable + TVariable* pcfOutput = makeInternalVariable("@patchConstantOutput", outType); pcfOutput->getWritableType().getQualifier().storage = EvqVaryingOut; if (pcfOutput->getType().containsBuiltInInterstageIO(language)) split(*pcfOutput); + assignLocations(*pcfOutput); + TIntermSymbol* pcfOutputSym = intermediate.addSymbol(*pcfOutput, loc); // The call to the PCF is a complex R-value: we want to store it in a temp to avoid // repeated calls to the PCF: TVariable* pcfCallResult = makeInternalVariable("@patchConstantResult", *retType); pcfCallResult->getWritableType().getQualifier().makeTemporary(); - TIntermSymbol* pcfResultVar = intermediate.addSymbol(*pcfCallResult, loc); - // sanitizeType(&pcfCall->getWritableType()); - TIntermNode* pcfResultAssign = intermediate.addAssign(EOpAssign, pcfResultVar, pcfCall, loc); + TIntermSymbol* pcfResultVar = intermediate.addSymbol(*pcfCallResult, loc); + TIntermNode* pcfResultAssign = handleAssign(loc, EOpAssign, pcfResultVar, pcfCall); TIntermNode* pcfResultToOut = handleAssign(loc, EOpAssign, pcfOutputSym, intermediate.addSymbol(*pcfCallResult, loc)); - TIntermTyped* pcfAggregate = nullptr; - pcfAggregate = intermediate.growAggregate(pcfAggregate, pcfResultAssign); - pcfAggregate = intermediate.growAggregate(pcfAggregate, pcfResultToOut); - pcfAggregate = intermediate.setAggregateOperator(pcfAggregate, EOpSequence, *retType, loc); - - pcfCall = pcfAggregate; + pcfCallSequence = intermediate.growAggregate(pcfCallSequence, pcfResultAssign); + pcfCallSequence = intermediate.growAggregate(pcfCallSequence, pcfResultToOut); + } else { + pcfCallSequence = intermediate.growAggregate(pcfCallSequence, pcfCall); } // ================ Step 4: Barrier ================ @@ -7623,12 +7836,14 @@ void HlslParseContext::addPatchConstantInvocation() barrier->setType(TType(EbtVoid)); epBodySeq.insert(epBodySeq.end(), barrier); - // ================ Step 5: Test on invocation ID ================ + // ================ Step 5: Test on invocation ID ================ TIntermTyped* zero = intermediate.addConstantUnion(0, loc, true); TIntermTyped* cmp = intermediate.addBinaryNode(EOpEqual, invocationIdSym, zero, loc, TType(EbtBool)); - // Create if statement - TIntermTyped* invocationIdTest = new TIntermSelection(cmp, pcfCall, nullptr); + + // ================ Step 5B: Create if statement on Invocation ID == 0 ================ + intermediate.setAggregateOperator(pcfCallSequence, EOpSequence, TType(EbtVoid), loc); + TIntermTyped* invocationIdTest = new TIntermSelection(cmp, pcfCallSequence, nullptr); invocationIdTest->setLoc(loc); // add our test sequence before the return. diff --git a/hlsl/hlslParseHelper.h b/hlsl/hlslParseHelper.h index 67f8f7ee..b46a5809 100755 --- a/hlsl/hlslParseHelper.h +++ b/hlsl/hlslParseHelper.h @@ -80,6 +80,7 @@ public: void handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype); TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&, const TAttributeMap&, TIntermNode*& entryPointTree); TIntermNode* transformEntryPoint(const TSourceLoc&, TFunction&, const TAttributeMap&); + void handleEntryPointAttributes(const TSourceLoc&, const TAttributeMap&); void handleFunctionBody(const TSourceLoc&, TFunction&, TIntermNode* functionBody, TIntermNode*& node); void remapEntryPointIO(TFunction& function, TVariable*& returnValue, TVector& inputs, TVector& outputs); void remapNonEntryPointIO(TFunction& function); @@ -247,6 +248,8 @@ protected: void addInterstageIoToLinkage(); void addPatchConstantInvocation(); + void fixBuiltInArrayType(TType&); + void flatten(const TSourceLoc& loc, const TVariable& variable); 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); @@ -280,6 +283,9 @@ protected: void finish() override; // post-processing + // Linkage symbol helpers + TIntermSymbol* findLinkageSymbol(TBuiltInVariable biType) const; + // Current state of parsing struct TPragma contextPragma; int loopNestingLevel; // 0 if outside all loops