diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index 72f55227..bda4ee78 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -178,6 +178,7 @@ const char* variableName = nullptr; bool HlslEnable16BitTypes = false; bool HlslDX9compatible = false; bool HlslDxPositionW = false; +bool EnhancedMsgs = false; bool DumpBuiltinSymbols = false; std::vector IncludeDirectoryList; @@ -665,6 +666,8 @@ void ProcessArguments(std::vector>& workItem HlslDX9compatible = true; } else if (lowerword == "hlsl-dx-position-w") { HlslDxPositionW = true; + } else if (lowerword == "enhanced-msgs") { + EnhancedMsgs = true; } else if (lowerword == "auto-sampled-textures") { autoSampledTextures = true; } else if (lowerword == "invert-y" || // synonyms @@ -1073,6 +1076,8 @@ void SetMessageOptions(EShMessages& messages) messages = (EShMessages)(messages | EShMsgHlslDX9Compatible); if (DumpBuiltinSymbols) messages = (EShMessages)(messages | EShMsgBuiltinSymbolTable); + if (EnhancedMsgs) + messages = (EShMessages)(messages | EShMsgEnhanced); } // @@ -1301,6 +1306,9 @@ void CompileAndLinkShaderUnits(std::vector compUnits) if (HlslDxPositionW) shader->setDxPositionW(true); + if (EnhancedMsgs) + shader->setEnhancedMsgs(); + // Set up the environment, some subsettings take precedence over earlier // ways of setting things. if (Options & EOptionSpv) { @@ -1867,6 +1875,7 @@ void usage() " --hlsl-dx-position-w W component of SV_Position in HLSL fragment\n" " shaders compatible with DirectX\n" " --invert-y | --iy invert position.Y output in vertex shader\n" + " --enhanced-msgs print more readable error messages (GLSL only)\n" " --keep-uncalled | --ku don't eliminate uncalled functions\n" " --nan-clamp favor non-NaN operand in min, max, and clamp\n" " --no-storage-format | --nsf use Unknown image format\n" diff --git a/Test/baseResults/150.tesc.out b/Test/baseResults/150.tesc.out index 535a8a62..78b32da2 100644 --- a/Test/baseResults/150.tesc.out +++ b/Test/baseResults/150.tesc.out @@ -627,7 +627,7 @@ ERROR: node is still EOpNull! ERROR: 0:7: 'vertices' : inconsistent output number of vertices for array size of gl_out ERROR: 0:11: 'vertices' : inconsistent output number of vertices for array size of a ERROR: 0:12: 'vertices' : inconsistent output number of vertices for array size of outb -ERROR: 0:26: 'gl_PointSize' : no such field in structure +ERROR: 0:26: 'gl_PointSize' : no such field in structure 'gl_out' ERROR: 0:26: 'assign' : cannot convert from ' temp float' to ' temp block{ out 4-component vector of float Position gl_Position}' ERROR: 0:29: 'out' : type must be an array: outf ERROR: 0:43: 'vertices' : must be greater than 0 @@ -940,8 +940,9 @@ ERROR: Linking tessellation control stage: Multiple function bodies in multiple main( ERROR: Linking tessellation control stage: Multiple function bodies in multiple compilation units for the same signature in the same stage: main( -ERROR: Linking tessellation control stage: Types must match: - outa: " global 4-element array of int" versus " global 1-element array of int" +ERROR: Linking tessellation control and tessellation control stages: Array sizes must be compatible: + tessellation control stage: " int outa[4]" + tessellation control stage: " int outa[1]" ERROR: Linking tessellation control stage: can't handle multiple entry points per stage ERROR: Linking tessellation control stage: Multiple function bodies in multiple compilation units for the same signature in the same stage: main( @@ -951,8 +952,9 @@ ERROR: Linking tessellation control stage: Multiple function bodies in multiple foo( ERROR: Linking tessellation control stage: Multiple function bodies in multiple compilation units for the same signature in the same stage: main( -ERROR: Linking tessellation control stage: Types must match: - gl_out: " out 4-element array of block{ out 4-component vector of float Position gl_Position, out float PointSize gl_PointSize, out unsized 2-element array of float ClipDistance gl_ClipDistance}" versus " out 3-element array of block{ out 4-component vector of float Position gl_Position}" +ERROR: Linking tessellation control and tessellation control stages: tessellation control block member has no corresponding member in tessellation control block: + tessellation control stage: Block: gl_PerVertex, Member: gl_PointSize + tessellation control stage: Block: gl_PerVertex, Member: n/a Linked tessellation evaluation stage: diff --git a/Test/baseResults/310.geom.out b/Test/baseResults/310.geom.out index b0dabc3b..2fa5d111 100644 --- a/Test/baseResults/310.geom.out +++ b/Test/baseResults/310.geom.out @@ -6,7 +6,7 @@ ERROR: 0:43: 'EmitStreamVertex' : no matching overloaded function found ERROR: 0:44: 'EndStreamPrimitive' : no matching overloaded function found ERROR: 0:47: 'gl_ClipDistance' : undeclared identifier ERROR: 0:47: 'gl_ClipDistance' : left of '[' is not of type array, matrix, or vector -ERROR: 0:48: 'gl_ClipDistance' : no such field in structure +ERROR: 0:48: 'gl_ClipDistance' : no such field in structure 'gl_in' ERROR: 0:48: 'expression' : left of '[' is not of type array, matrix, or vector ERROR: 0:47: 'assign' : l-value required (can't modify a const) ERROR: 0:55: 'selecting output stream' : not supported with this profile: es diff --git a/Test/baseResults/310.tesc.out b/Test/baseResults/310.tesc.out index 25ce6ee9..bd4c1bdc 100644 --- a/Test/baseResults/310.tesc.out +++ b/Test/baseResults/310.tesc.out @@ -6,12 +6,12 @@ ERROR: 0:12: 'patch' : can only use on output in tessellation-control shader ERROR: 0:26: 'gl_PointSize' : required extension not requested: Possible extensions include: GL_EXT_tessellation_point_size GL_OES_tessellation_point_size -ERROR: 0:27: 'gl_ClipDistance' : no such field in structure +ERROR: 0:27: 'gl_ClipDistance' : no such field in structure 'gl_in' ERROR: 0:27: 'expression' : left of '[' is not of type array, matrix, or vector ERROR: 0:34: 'gl_PointSize' : required extension not requested: Possible extensions include: GL_EXT_tessellation_point_size GL_OES_tessellation_point_size -ERROR: 0:35: 'gl_ClipDistance' : no such field in structure +ERROR: 0:35: 'gl_ClipDistance' : no such field in structure 'gl_out' ERROR: 0:35: 'expression' : left of '[' is not of type array, matrix, or vector ERROR: 0:35: 'assign' : l-value required (can't modify a const) ERROR: 0:41: '' : tessellation control barrier() cannot be placed within flow control diff --git a/Test/baseResults/310.tese.out b/Test/baseResults/310.tese.out index 2f23d9ba..5eecaffa 100644 --- a/Test/baseResults/310.tese.out +++ b/Test/baseResults/310.tese.out @@ -10,7 +10,7 @@ ERROR: 0:26: 'barrier' : no matching overloaded function found ERROR: 0:37: 'gl_PointSize' : required extension not requested: Possible extensions include: GL_EXT_tessellation_point_size GL_OES_tessellation_point_size -ERROR: 0:38: 'gl_ClipDistance' : no such field in structure +ERROR: 0:38: 'gl_ClipDistance' : no such field in structure 'gl_in' ERROR: 0:38: 'expression' : left of '[' is not of type array, matrix, or vector ERROR: 0:47: 'gl_PointSize' : required extension not requested: Possible extensions include: GL_EXT_tessellation_point_size @@ -43,7 +43,7 @@ ERROR: 0:100: 'location' : overlapping use of location 24 ERROR: 0:103: 'location' : overlapping use of location 24 ERROR: 0:105: 'gl_TessLevelOuter' : identifiers starting with "gl_" are reserved ERROR: 0:113: 'sample' : Reserved word. -ERROR: 0:119: 'gl_PointSize' : no such field in structure +ERROR: 0:119: 'gl_PointSize' : no such field in structure 'gl_in' ERROR: 0:119: '=' : cannot convert from ' temp block{ in highp 4-component vector of float Position gl_Position}' to ' temp highp float' ERROR: 0:127: 'gl_BoundingBoxOES' : undeclared identifier ERROR: 43 compilation errors. No code generated. diff --git a/Test/baseResults/320.geom.out b/Test/baseResults/320.geom.out index f3337660..cdaacb91 100644 --- a/Test/baseResults/320.geom.out +++ b/Test/baseResults/320.geom.out @@ -6,7 +6,7 @@ ERROR: 0:33: 'EmitStreamVertex' : no matching overloaded function found ERROR: 0:34: 'EndStreamPrimitive' : no matching overloaded function found ERROR: 0:37: 'gl_ClipDistance' : undeclared identifier ERROR: 0:37: 'gl_ClipDistance' : left of '[' is not of type array, matrix, or vector -ERROR: 0:38: 'gl_ClipDistance' : no such field in structure +ERROR: 0:38: 'gl_ClipDistance' : no such field in structure 'gl_in' ERROR: 0:38: 'expression' : left of '[' is not of type array, matrix, or vector ERROR: 0:37: 'assign' : l-value required (can't modify a const) ERROR: 0:45: 'selecting output stream' : not supported with this profile: es diff --git a/Test/baseResults/320.tesc.out b/Test/baseResults/320.tesc.out index 6bb52b30..67848d9b 100644 --- a/Test/baseResults/320.tesc.out +++ b/Test/baseResults/320.tesc.out @@ -6,12 +6,12 @@ ERROR: 0:10: 'patch' : can only use on output in tessellation-control shader ERROR: 0:24: 'gl_PointSize' : required extension not requested: Possible extensions include: GL_EXT_tessellation_point_size GL_OES_tessellation_point_size -ERROR: 0:25: 'gl_ClipDistance' : no such field in structure +ERROR: 0:25: 'gl_ClipDistance' : no such field in structure 'gl_in' ERROR: 0:25: 'expression' : left of '[' is not of type array, matrix, or vector ERROR: 0:32: 'gl_PointSize' : required extension not requested: Possible extensions include: GL_EXT_tessellation_point_size GL_OES_tessellation_point_size -ERROR: 0:33: 'gl_ClipDistance' : no such field in structure +ERROR: 0:33: 'gl_ClipDistance' : no such field in structure 'gl_out' ERROR: 0:33: 'expression' : left of '[' is not of type array, matrix, or vector ERROR: 0:33: 'assign' : l-value required (can't modify a const) ERROR: 0:39: '' : tessellation control barrier() cannot be placed within flow control diff --git a/Test/baseResults/320.tese.out b/Test/baseResults/320.tese.out index 014eeb0a..ba51b9c8 100644 --- a/Test/baseResults/320.tese.out +++ b/Test/baseResults/320.tese.out @@ -10,7 +10,7 @@ ERROR: 0:22: 'barrier' : no matching overloaded function found ERROR: 0:33: 'gl_PointSize' : required extension not requested: Possible extensions include: GL_EXT_tessellation_point_size GL_OES_tessellation_point_size -ERROR: 0:34: 'gl_ClipDistance' : no such field in structure +ERROR: 0:34: 'gl_ClipDistance' : no such field in structure 'gl_in' ERROR: 0:34: 'expression' : left of '[' is not of type array, matrix, or vector ERROR: 0:43: 'gl_PointSize' : required extension not requested: Possible extensions include: GL_EXT_tessellation_point_size diff --git a/Test/baseResults/410.geom.out b/Test/baseResults/410.geom.out index 498da5ac..3cc7900c 100644 --- a/Test/baseResults/410.geom.out +++ b/Test/baseResults/410.geom.out @@ -2,7 +2,7 @@ ERROR: 0:8: 'myIn' : cannot redeclare a built-in block with a user name ERROR: 0:12: 'gl_myIn' : no declaration found for redeclaration ERROR: 0:20: 'gl_PerVertex' : can only redeclare a built-in block once, and before any use -ERROR: 0:32: 'gl_Position' : no such field in structure +ERROR: 0:32: 'gl_Position' : no such field in structure 'gl_in' ERROR: 0:32: '=' : cannot convert from ' temp block{ in float PointSize gl_PointSize}' to ' temp 4-component vector of float' ERROR: 0:33: 'gl_Position' : member of nameless block was not redeclared ERROR: 0:33: 'assign' : l-value required "gl_PerVertex" (can't modify void) diff --git a/Test/baseResults/420.tesc.out b/Test/baseResults/420.tesc.out index a1f881cb..4410c846 100644 --- a/Test/baseResults/420.tesc.out +++ b/Test/baseResults/420.tesc.out @@ -2,7 +2,7 @@ ERROR: 0:7: 'vertices' : inconsistent output number of vertices for array size of gl_out ERROR: 0:11: 'vertices' : inconsistent output number of vertices for array size of a ERROR: 0:12: 'vertices' : inconsistent output number of vertices for array size of outb -ERROR: 0:26: 'gl_PointSize' : no such field in structure +ERROR: 0:26: 'gl_PointSize' : no such field in structure 'gl_out' ERROR: 0:26: 'assign' : cannot convert from ' temp float' to ' temp block{ out 4-component vector of float Position gl_Position}' ERROR: 0:29: 'out' : type must be an array: outf ERROR: 0:43: 'vertices' : must be greater than 0 diff --git a/Test/baseResults/450.geom.out b/Test/baseResults/450.geom.out index e75bf939..b51a674f 100644 --- a/Test/baseResults/450.geom.out +++ b/Test/baseResults/450.geom.out @@ -1,6 +1,6 @@ 450.geom ERROR: 0:15: '[' : array index out of range '3' -ERROR: 0:15: 'gl_Position' : no such field in structure +ERROR: 0:15: 'gl_Position' : no such field in structure 'gl_in' ERROR: 0:19: 'points' : can only apply to a standalone qualifier ERROR: 3 compilation errors. No code generated. diff --git a/Test/baseResults/enhanced.0.frag.out b/Test/baseResults/enhanced.0.frag.out new file mode 100644 index 00000000..1171bfaf --- /dev/null +++ b/Test/baseResults/enhanced.0.frag.out @@ -0,0 +1,6 @@ +enhanced.0.frag +ERROR: enhanced.0.frag:7: ' vec4 constructor' : not enough data provided for construction +ERROR: 1 compilation errors. No code generated. + + +SPIR-V is not generated for failed compile or link diff --git a/Test/baseResults/enhanced.1.frag.out b/Test/baseResults/enhanced.1.frag.out new file mode 100644 index 00000000..42f5b72d --- /dev/null +++ b/Test/baseResults/enhanced.1.frag.out @@ -0,0 +1,6 @@ +enhanced.1.frag +ERROR: enhanced.1.frag:9: 'v2' : no such field in structure 'vVert' +ERROR: 1 compilation errors. No code generated. + + +SPIR-V is not generated for failed compile or link diff --git a/Test/baseResults/enhanced.2.frag.out b/Test/baseResults/enhanced.2.frag.out new file mode 100644 index 00000000..a7e48de4 --- /dev/null +++ b/Test/baseResults/enhanced.2.frag.out @@ -0,0 +1,6 @@ +enhanced.2.frag +ERROR: enhanced.2.frag:5: ' vec3 constructor' : too many arguments +ERROR: 1 compilation errors. No code generated. + + +SPIR-V is not generated for failed compile or link diff --git a/Test/baseResults/enhanced.3.link.out b/Test/baseResults/enhanced.3.link.out new file mode 100644 index 00000000..c0e6a202 --- /dev/null +++ b/Test/baseResults/enhanced.3.link.out @@ -0,0 +1,8 @@ +enhanced.3.vert +enhanced.3.frag +ERROR: Linking vertex and fragment stages: Member names and types must match: + Block: VS_OUT + vertex stage: " vec2 TexCoords" + fragment stage: " vec2 foobar" + +SPIR-V is not generated for failed compile or link diff --git a/Test/baseResults/enhanced.4.link.out b/Test/baseResults/enhanced.4.link.out new file mode 100644 index 00000000..2c0acf41 --- /dev/null +++ b/Test/baseResults/enhanced.4.link.out @@ -0,0 +1,7 @@ +enhanced.4.vert +enhanced.4.frag +ERROR: Linking vertex and fragment stages: Layout location qualifier must match: + vertex stage: Block: VS_OUT Instance: vs_out: "layout( location=0) out" + fragment stage: Block: VS_OUT Instance: fs_in: "layout( location=1) in" + +SPIR-V is not generated for failed compile or link diff --git a/Test/baseResults/enhanced.5.link.out b/Test/baseResults/enhanced.5.link.out new file mode 100644 index 00000000..929cfcef --- /dev/null +++ b/Test/baseResults/enhanced.5.link.out @@ -0,0 +1,8 @@ +enhanced.5.vert +enhanced.5.frag +ERROR: Linking vertex and fragment stages: Member names and types must match: + Block: VS_OUT + vertex stage: " vec2 TexCoords" + fragment stage: " vec3 TexCoords" + +SPIR-V is not generated for failed compile or link diff --git a/Test/baseResults/enhanced.6.link.out b/Test/baseResults/enhanced.6.link.out new file mode 100644 index 00000000..99626282 --- /dev/null +++ b/Test/baseResults/enhanced.6.link.out @@ -0,0 +1,7 @@ +enhanced.6.vert +enhanced.6.frag +ERROR: Linking vertex and fragment stages: Array sizes must be compatible: + vertex stage: " VS_OUT{ vec2 TexCoords} vs_out[2]" + fragment stage: " VS_OUT{ vec2 TexCoords} fs_in[1]" + +SPIR-V is not generated for failed compile or link diff --git a/Test/baseResults/enhanced.7.link.out b/Test/baseResults/enhanced.7.link.out new file mode 100644 index 00000000..a6333be9 --- /dev/null +++ b/Test/baseResults/enhanced.7.link.out @@ -0,0 +1,7 @@ +enhanced.7.vert +enhanced.7.frag +ERROR: Linking vertex and fragment stages: vertex block member has no corresponding member in fragment block: + vertex stage: Block: Vertex, Member: ii + fragment stage: Block: Vertex, Member: n/a + +SPIR-V is not generated for failed compile or link diff --git a/Test/baseResults/iomap.crossStage.2.vert.out b/Test/baseResults/iomap.crossStage.2.vert.out index 325c1b46..85139cc7 100644 --- a/Test/baseResults/iomap.crossStage.2.vert.out +++ b/Test/baseResults/iomap.crossStage.2.vert.out @@ -207,8 +207,9 @@ Linked geometry stage: Linked fragment stage: -WARNING: Linking unknown stage stage: Matched shader interfaces are using different instance names. - blockName1: "layout( column_major std140) uniform 2-element array of block{layout( column_major std140) uniform 4-component vector of float a, layout( column_major std140) uniform 2-component vector of float b}" versus blockName2: "layout( column_major std140) uniform 2-element array of block{layout( column_major std140) uniform 4-component vector of float a, layout( column_major std140) uniform 2-component vector of float b}" +WARNING: Linking unknown stage and fragment stages: Matched shader interfaces are using different instance names. + unknown stage stage: Block: crossStageBlock2 Instance: blockName1: "" + fragment stage: Block: crossStageBlock2 Instance: blockName2: "" Shader version: 460 0:? Sequence diff --git a/Test/baseResults/iomap.crossStage.vert.out b/Test/baseResults/iomap.crossStage.vert.out index 5338b807..13ff58c9 100644 --- a/Test/baseResults/iomap.crossStage.vert.out +++ b/Test/baseResults/iomap.crossStage.vert.out @@ -133,8 +133,9 @@ Linked vertex stage: Linked fragment stage: -WARNING: Linking unknown stage stage: Matched shader interfaces are using different instance names. - blockName1: "layout( column_major std140) uniform 2-element array of block{layout( column_major std140) uniform 4-component vector of float a, layout( column_major std140) uniform 2-component vector of float b}" versus blockName2: "layout( column_major std140) uniform 2-element array of block{layout( column_major std140) uniform 4-component vector of float a, layout( column_major std140) uniform 2-component vector of float b}" +WARNING: Linking unknown stage and fragment stages: Matched shader interfaces are using different instance names. + unknown stage stage: Block: crossStageBlock2 Instance: blockName1: "" + fragment stage: Block: crossStageBlock2 Instance: blockName2: "" Shader version: 460 0:? Sequence diff --git a/Test/baseResults/iomap.crossStage.vk.vert.out b/Test/baseResults/iomap.crossStage.vk.vert.out index e137bdfc..0a2eae84 100644 --- a/Test/baseResults/iomap.crossStage.vk.vert.out +++ b/Test/baseResults/iomap.crossStage.vk.vert.out @@ -194,8 +194,9 @@ Linked geometry stage: Linked fragment stage: -WARNING: Linking unknown stage stage: Matched shader interfaces are using different instance names. - blockName1: "layout( column_major std140) uniform 2-element array of block{layout( column_major std140) uniform highp 4-component vector of float a, layout( column_major std140) uniform highp 2-component vector of float b}" versus blockName2: "layout( column_major std140) uniform 2-element array of block{layout( column_major std140) uniform highp 4-component vector of float a, layout( column_major std140) uniform highp 2-component vector of float b}" +WARNING: Linking unknown stage and fragment stages: Matched shader interfaces are using different instance names. + unknown stage stage: Block: crossStageBlock2 Instance: blockName1: "" + fragment stage: Block: crossStageBlock2 Instance: blockName2: "" Shader version: 460 0:? Sequence diff --git a/Test/baseResults/link.multiAnonBlocksInvalid.0.0.vert.out b/Test/baseResults/link.multiAnonBlocksInvalid.0.0.vert.out index 404ae849..c34401cb 100644 --- a/Test/baseResults/link.multiAnonBlocksInvalid.0.0.vert.out +++ b/Test/baseResults/link.multiAnonBlocksInvalid.0.0.vert.out @@ -92,15 +92,20 @@ Shader version: 430 Linked vertex stage: -ERROR: Linking vertex stage: Types must match: - anon@0: "layout( column_major std140) uniform block{layout( column_major std140 offset=0) uniform 4X4 matrix of float uProj}" versus anon@1: "layout( column_major std140) uniform block{layout( column_major std140 offset=0) uniform 4X4 matrix of float uProj, layout( column_major std140 offset=64) uniform 4X4 matrix of float uWorld}" -ERROR: Linking vertex stage: Types must match: - anon@2: " out block{ out 4-component vector of float v1}" versus " out block{ out 4-component vector of float v1, out 4-component vector of float v2}" -ERROR: Linking vertex stage: Types must match: - anon@1: "layout( column_major shared) buffer block{layout( column_major shared) buffer 4-component vector of float b}" versus anon@3: "layout( column_major shared) buffer block{layout( column_major shared) buffer 4-component vector of float a}" -ERROR: Linking vertex stage: Matched Uniform or Storage blocks must all be anonymous, or all be named: -WARNING: Linking vertex stage: Matched shader interfaces are using different instance names. - myName: "layout( column_major std140) uniform block{layout( column_major std140 offset=0) uniform 4X4 matrix of float m}" versus anon@4: "layout( column_major std140) uniform block{layout( column_major std140 offset=0) uniform 4X4 matrix of float m}" +ERROR: Linking vertex and vertex stages: vertex block member has no corresponding member in vertex block: + vertex stage: Block: Block, Member: uWorld + vertex stage: Block: Block, Member: n/a +ERROR: Linking vertex and vertex stages: vertex block member has no corresponding member in vertex block: + vertex stage: Block: Vertex, Member: v2 + vertex stage: Block: Vertex, Member: n/a +ERROR: Linking vertex and vertex stages: Member names and types must match: + Block: BufferBlock + vertex stage: " vec4 b" + vertex stage: " vec4 a" +ERROR: Linking vertex and vertex stages: Matched Uniform or Storage blocks must all be anonymous, or all be named: +WARNING: Linking vertex and vertex stages: Matched shader interfaces are using different instance names. + vertex stage: Block: NamedBlock Instance: myName: "" + vertex stage: Block: NamedBlock Instance: anon@4: "" Shader version: 430 ERROR: node is still EOpNull! diff --git a/Test/baseResults/link.multiBlocksInvalid.0.0.vert.out b/Test/baseResults/link.multiBlocksInvalid.0.0.vert.out index ad609e86..d94debbf 100644 --- a/Test/baseResults/link.multiBlocksInvalid.0.0.vert.out +++ b/Test/baseResults/link.multiBlocksInvalid.0.0.vert.out @@ -89,19 +89,35 @@ Shader version: 430 Linked vertex stage: -ERROR: Linking vertex stage: Types must match: -WARNING: Linking vertex stage: Matched shader interfaces are using different instance names. - uC: "layout( column_major std140) uniform block{layout( column_major std140 offset=0) uniform 4-component vector of float color1}" versus uColorB: "layout( column_major std140) uniform block{layout( column_major std140 offset=0) uniform 4-component vector of float color2}" -ERROR: Linking vertex stage: Types must match: -ERROR: Linking vertex stage: Storage qualifiers must match: -ERROR: Linking vertex stage: Layout qualification must match: - uBufC: "layout( column_major std430) buffer block{layout( column_major std430 offset=0) buffer 4-component vector of float color1}" versus uColorB: "layout( column_major std140) uniform block{layout( column_major std140 offset=0) uniform 4-component vector of float color2}" -ERROR: Linking vertex stage: Types must match: -WARNING: Linking vertex stage: Matched shader interfaces are using different instance names. - uD: "layout( column_major std140) uniform block{layout( column_major std140 offset=0) uniform 4X4 matrix of float uProj}" versus uDefaultB: "layout( column_major std140) uniform block{layout( column_major std140 offset=0) uniform 4X4 matrix of float uWorld}" -ERROR: Linking vertex stage: Types must match: -WARNING: Linking vertex stage: Matched shader interfaces are using different instance names. - oV: " out block{ out 4-component vector of float v1}" versus oVert: " out block{ out 4-component vector of float v2}" +ERROR: Linking vertex and vertex stages: Member names and types must match: + Block: ColorBlock + vertex stage: " vec4 color1" + vertex stage: " vec4 color2" +WARNING: Linking vertex and vertex stages: Matched shader interfaces are using different instance names. + vertex stage: Block: ColorBlock Instance: uC: "" + vertex stage: Block: ColorBlock Instance: uColorB: "" +ERROR: Linking vertex and vertex stages: Member names and types must match: + Block: ColorBlock + vertex stage: " vec4 color1" + vertex stage: " vec4 color2" +ERROR: Linking vertex and vertex stages: Storage qualifiers must match: +ERROR: Linking vertex and vertex stages: Layout packing qualifier must match: + vertex stage: Block: ColorBlock Instance: uBufC: "layout( column_major std430) buffer" + vertex stage: Block: ColorBlock Instance: uColorB: "layout( column_major std140) uniform" +ERROR: Linking vertex and vertex stages: Member names and types must match: + Block: Block + vertex stage: " mat4x4 uProj" + vertex stage: " mat4x4 uWorld" +WARNING: Linking vertex and vertex stages: Matched shader interfaces are using different instance names. + vertex stage: Block: Block Instance: uD: "" + vertex stage: Block: Block Instance: uDefaultB: "" +ERROR: Linking vertex and vertex stages: Member names and types must match: + Block: Vertex + vertex stage: " vec4 v1" + vertex stage: " vec4 v2" +WARNING: Linking vertex and vertex stages: Matched shader interfaces are using different instance names. + vertex stage: Block: Vertex Instance: oV: "" + vertex stage: Block: Vertex Instance: oVert: "" Shader version: 430 0:? Sequence diff --git a/Test/baseResults/link.multiBlocksValid.1.0.vert.out b/Test/baseResults/link.multiBlocksValid.1.0.vert.out index 0015cab4..69513f05 100644 --- a/Test/baseResults/link.multiBlocksValid.1.0.vert.out +++ b/Test/baseResults/link.multiBlocksValid.1.0.vert.out @@ -83,12 +83,15 @@ Shader version: 430 Linked vertex stage: -WARNING: Linking vertex stage: Matched shader interfaces are using different instance names. - c: "layout( column_major std140) uniform block{layout( column_major std140 offset=0) uniform 4-component vector of float color1, layout( column_major std140 offset=16) uniform 4-component vector of float color2}" versus a: "layout( column_major std140) uniform block{layout( column_major std140 offset=0) uniform 4-component vector of float color1, layout( column_major std140 offset=16) uniform 4-component vector of float color2}" -WARNING: Linking vertex stage: Matched shader interfaces are using different instance names. - a: "layout( column_major std140) uniform block{layout( column_major std140 offset=0) uniform 4X4 matrix of float uProj, layout( column_major std140 offset=64) uniform 4X4 matrix of float uWorld}" versus b: "layout( column_major std140) uniform block{layout( column_major std140 offset=0) uniform 4X4 matrix of float uProj, layout( column_major std140 offset=64) uniform 4X4 matrix of float uWorld}" -WARNING: Linking vertex stage: Matched shader interfaces are using different instance names. - b: " out block{ out 4-component vector of float v1, out 4-component vector of float v2}" versus c: " out block{ out 4-component vector of float v1, out 4-component vector of float v2}" +WARNING: Linking vertex and vertex stages: Matched shader interfaces are using different instance names. + vertex stage: Block: ColorBlock Instance: c: "" + vertex stage: Block: ColorBlock Instance: a: "" +WARNING: Linking vertex and vertex stages: Matched shader interfaces are using different instance names. + vertex stage: Block: Block Instance: a: "" + vertex stage: Block: Block Instance: b: "" +WARNING: Linking vertex and vertex stages: Matched shader interfaces are using different instance names. + vertex stage: Block: Vertex Instance: b: "" + vertex stage: Block: Vertex Instance: c: "" Shader version: 430 0:? Sequence diff --git a/Test/baseResults/link.vk.differentPC.0.0.frag.out b/Test/baseResults/link.vk.differentPC.0.0.frag.out index d7cfd220..d78ba54a 100644 --- a/Test/baseResults/link.vk.differentPC.0.0.frag.out +++ b/Test/baseResults/link.vk.differentPC.0.0.frag.out @@ -52,8 +52,10 @@ gl_FragCoord origin is upper left Linked fragment stage: -ERROR: Linking fragment stage: Types must match: - uPC: "layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale}" versus "layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale2}" +ERROR: Linking fragment and fragment stages: Member names and types must match: + Block: PushConstantBlock + fragment stage: " float scale" + fragment stage: " float scale2" Shader version: 450 gl_FragCoord origin is upper left diff --git a/Test/baseResults/link.vk.differentPC.1.0.frag.out b/Test/baseResults/link.vk.differentPC.1.0.frag.out index 632f18b1..07ed124a 100644 --- a/Test/baseResults/link.vk.differentPC.1.0.frag.out +++ b/Test/baseResults/link.vk.differentPC.1.0.frag.out @@ -52,10 +52,12 @@ gl_FragCoord origin is upper left Linked fragment stage: -ERROR: Linking fragment stage: Types must match: - uPC: "layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale, layout( column_major std430 offset=36) uniform highp float scale2}" versus "layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale}" -ERROR: Linking fragment stage: Types must match: - uPC: "layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale, layout( column_major std430 offset=36) uniform highp float scale2}" versus "layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale}" +ERROR: Linking fragment and fragment stages: fragment block member has no corresponding member in fragment block: + fragment stage: Block: PushConstantBlock, Member: scale2 + fragment stage: Block: PushConstantBlock, Member: n/a +ERROR: Linking fragment and fragment stages: fragment block member has no corresponding member in fragment block: + fragment stage: Block: PushConstantBlock, Member: scale2 + fragment stage: Block: PushConstantBlock, Member: n/a Shader version: 450 gl_FragCoord origin is upper left diff --git a/Test/baseResults/link.vk.multiBlocksValid.0.0.vert.out b/Test/baseResults/link.vk.multiBlocksValid.0.0.vert.out index bdabab18..29a4df04 100644 --- a/Test/baseResults/link.vk.multiBlocksValid.0.0.vert.out +++ b/Test/baseResults/link.vk.multiBlocksValid.0.0.vert.out @@ -87,14 +87,18 @@ Shader version: 430 Linked vertex stage: -WARNING: Linking vertex stage: Matched shader interfaces are using different instance names. - uC: "layout( binding=1 column_major std140) uniform block{layout( column_major std140 offset=0) uniform highp 4-component vector of float color1, layout( column_major std140 offset=16) uniform bool b, layout( column_major std140 offset=32) uniform highp 4-component vector of float color2, layout( column_major std140 offset=48) uniform highp 4-component vector of float color3}" versus uColor: "layout( binding=1 column_major std140) uniform block{layout( column_major std140 offset=0) uniform highp 4-component vector of float color1, layout( column_major std140 offset=16) uniform bool b, layout( column_major std140 offset=32) uniform highp 4-component vector of float color2, layout( column_major std140 offset=48) uniform highp 4-component vector of float color3}" -WARNING: Linking vertex stage: Matched shader interfaces are using different instance names. - uBuf: "layout( binding=1 column_major std430) buffer block{layout( column_major std430 offset=0) buffer highp 4X4 matrix of float p}" versus uBuffer: "layout( binding=1 column_major std430) buffer block{layout( column_major std430 offset=0) buffer highp 4X4 matrix of float p}" -WARNING: Linking vertex stage: Matched shader interfaces are using different instance names. - uM: "layout( binding=0 column_major std140) uniform block{layout( column_major std140 offset=0) uniform highp 4X4 matrix of float uProj, layout( column_major std140 offset=64) uniform highp 4X4 matrix of float uWorld}" versus uMatrix: "layout( binding=0 column_major std140) uniform block{layout( column_major std140 offset=0) uniform highp 4X4 matrix of float uProj, layout( column_major std140 offset=64) uniform highp 4X4 matrix of float uWorld}" -WARNING: Linking vertex stage: Matched shader interfaces are using different instance names. - oV: " out block{ out highp 4-component vector of float v1, out highp 4-component vector of float v2}" versus anon@0: " out block{ out highp 4-component vector of float v1, out highp 4-component vector of float v2}" +WARNING: Linking vertex and vertex stages: Matched shader interfaces are using different instance names. + vertex stage: Block: ColorBlock Instance: uC: "" + vertex stage: Block: ColorBlock Instance: uColor: "" +WARNING: Linking vertex and vertex stages: Matched shader interfaces are using different instance names. + vertex stage: Block: BufferBlock Instance: uBuf: "" + vertex stage: Block: BufferBlock Instance: uBuffer: "" +WARNING: Linking vertex and vertex stages: Matched shader interfaces are using different instance names. + vertex stage: Block: MatrixBlock Instance: uM: "" + vertex stage: Block: MatrixBlock Instance: uMatrix: "" +WARNING: Linking vertex and vertex stages: Matched shader interfaces are using different instance names. + vertex stage: Block: Vertex Instance: oV: "" + vertex stage: Block: Vertex Instance: anon@0: "" Shader version: 430 0:? Sequence diff --git a/Test/baseResults/link.vk.multiBlocksValid.1.0.geom.out b/Test/baseResults/link.vk.multiBlocksValid.1.0.geom.out index b0456a08..4005f601 100644 --- a/Test/baseResults/link.vk.multiBlocksValid.1.0.geom.out +++ b/Test/baseResults/link.vk.multiBlocksValid.1.0.geom.out @@ -131,16 +131,21 @@ output primitive = triangle_strip Linked geometry stage: -WARNING: Linking geometry stage: Matched shader interfaces are using different instance names. - uC: "layout( binding=1 column_major std140) uniform block{layout( column_major std140 offset=0) uniform highp 4-component vector of float color1, layout( column_major std140 offset=16) uniform bool b, layout( column_major std140 offset=32) uniform highp 4-component vector of float color2, layout( column_major std140 offset=48) uniform highp 4-component vector of float color3}" versus uColor: "layout( binding=1 column_major std140) uniform block{layout( column_major std140 offset=0) uniform highp 4-component vector of float color1, layout( column_major std140 offset=16) uniform bool b, layout( column_major std140 offset=32) uniform highp 4-component vector of float color2, layout( column_major std140 offset=48) uniform highp 4-component vector of float color3}" -WARNING: Linking geometry stage: Matched shader interfaces are using different instance names. - uBuf: "layout( binding=1 column_major std430) buffer block{layout( column_major std430 offset=0) buffer highp 4X4 matrix of float p}" versus uBuffer: "layout( binding=1 column_major std430) buffer block{layout( column_major std430 offset=0) buffer highp 4X4 matrix of float p}" -WARNING: Linking geometry stage: Matched shader interfaces are using different instance names. - uM: "layout( binding=0 column_major std140) uniform block{layout( column_major std140 offset=0) uniform highp 4X4 matrix of float uProj, layout( column_major std140 offset=64) uniform highp 4X4 matrix of float uWorld}" versus uMatrix: "layout( binding=0 column_major std140) uniform block{layout( column_major std140 offset=0) uniform highp 4X4 matrix of float uProj, layout( column_major std140 offset=64) uniform highp 4X4 matrix of float uWorld}" -WARNING: Linking geometry stage: Matched shader interfaces are using different instance names. - oV: "layout( stream=0) out block{layout( stream=0) out highp 4-component vector of float val1}" versus anon@0: "layout( stream=0) out block{layout( stream=0) out highp 4-component vector of float val1}" -WARNING: Linking geometry stage: Matched shader interfaces are using different instance names. - iV: " in 3-element array of block{ in highp 4-component vector of float v1, in highp 4-component vector of float v2}" versus iVV: " in 3-element array of block{ in highp 4-component vector of float v1, in highp 4-component vector of float v2}" +WARNING: Linking geometry and geometry stages: Matched shader interfaces are using different instance names. + geometry stage: Block: ColorBlock Instance: uC: "" + geometry stage: Block: ColorBlock Instance: uColor: "" +WARNING: Linking geometry and geometry stages: Matched shader interfaces are using different instance names. + geometry stage: Block: BufferBlock Instance: uBuf: "" + geometry stage: Block: BufferBlock Instance: uBuffer: "" +WARNING: Linking geometry and geometry stages: Matched shader interfaces are using different instance names. + geometry stage: Block: MatrixBlock Instance: uM: "" + geometry stage: Block: MatrixBlock Instance: uMatrix: "" +WARNING: Linking geometry and geometry stages: Matched shader interfaces are using different instance names. + geometry stage: Block: Vertex Instance: oV: "" + geometry stage: Block: Vertex Instance: anon@0: "" +WARNING: Linking geometry and geometry stages: Matched shader interfaces are using different instance names. + geometry stage: Block: Vertex Instance: iV: "" + geometry stage: Block: Vertex Instance: iVV: "" Shader version: 430 invocations = 1 diff --git a/Test/baseResults/link.vk.pcNamingValid.0.0.vert.out b/Test/baseResults/link.vk.pcNamingValid.0.0.vert.out index e1d5c888..f84877e0 100644 --- a/Test/baseResults/link.vk.pcNamingValid.0.0.vert.out +++ b/Test/baseResults/link.vk.pcNamingValid.0.0.vert.out @@ -56,8 +56,9 @@ Shader version: 450 Linked vertex stage: -WARNING: Linking vertex stage: Matched shader interfaces are using different instance names. - a: "layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4X4 matrix of float uWorld, layout( column_major std430 offset=64) uniform highp 4X4 matrix of float uProj, layout( column_major std430 offset=128) uniform highp 4-component vector of float color1, layout( column_major std430 offset=144) uniform highp 4-component vector of float color2}" versus b: "layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4X4 matrix of float uWorld, layout( column_major std430 offset=64) uniform highp 4X4 matrix of float uProj, layout( column_major std430 offset=128) uniform highp 4-component vector of float color1, layout( column_major std430 offset=144) uniform highp 4-component vector of float color2}" +WARNING: Linking vertex and vertex stages: Matched shader interfaces are using different instance names. + vertex stage: Block: PCBlock Instance: a: "" + vertex stage: Block: PCBlock Instance: b: "" Shader version: 450 0:? Sequence diff --git a/Test/enhanced.0.frag b/Test/enhanced.0.frag new file mode 100644 index 00000000..7a42c053 --- /dev/null +++ b/Test/enhanced.0.frag @@ -0,0 +1,9 @@ +#version 450 + +in vec3 v; + +void main() +{ + vec4 color = vec4(v); +} + diff --git a/Test/enhanced.1.frag b/Test/enhanced.1.frag new file mode 100644 index 00000000..9aab34d7 --- /dev/null +++ b/Test/enhanced.1.frag @@ -0,0 +1,11 @@ +#version 450 + +in Vertex { + vec4 v; +} vVert; + +void main() +{ + vec4 color = vec4(vVert.v2.rgb, 1.0); +} + diff --git a/Test/enhanced.2.frag b/Test/enhanced.2.frag new file mode 100644 index 00000000..c3c194ce --- /dev/null +++ b/Test/enhanced.2.frag @@ -0,0 +1,7 @@ +#version 450 + +void main() +{ + vec3 color = vec3(0.0,0.0,0.0,1.0); +} + diff --git a/Test/enhanced.3.frag b/Test/enhanced.3.frag new file mode 100644 index 00000000..1de9f4b2 --- /dev/null +++ b/Test/enhanced.3.frag @@ -0,0 +1,16 @@ +#version 450 core + +layout (location = 0) out vec4 FragColor; + +layout (location = 0) in VS_OUT +{ + vec2 foobar; +} fs_in; + +layout (binding = 1) uniform sampler2D t0; + +void main() +{ + FragColor = texture(t0, fs_in.foobar); +} + diff --git a/Test/enhanced.3.vert b/Test/enhanced.3.vert new file mode 100644 index 00000000..043ee246 --- /dev/null +++ b/Test/enhanced.3.vert @@ -0,0 +1,22 @@ +#version 450 core + +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec2 aTexCoords; + +layout (binding = 0) uniform anonblock { + mat4 model; + mat4 view; + mat4 projection; +} ; + +layout (location = 0) out VS_OUT +{ + vec2 TexCoords; +} vs_out; + +void main() +{ + gl_Position = projection * view * model * vec4(aPos, 1.0); + vs_out.TexCoords = aTexCoords; +} + diff --git a/Test/enhanced.4.frag b/Test/enhanced.4.frag new file mode 100644 index 00000000..9c16606d --- /dev/null +++ b/Test/enhanced.4.frag @@ -0,0 +1,16 @@ +#version 450 core + +layout (location = 0) out vec4 FragColor; + +layout (location = 1) in VS_OUT +{ + vec2 TexCoords; +} fs_in; + +layout (binding = 1) uniform sampler2D t0; + +void main() +{ + FragColor = texture(t0, fs_in.TexCoords); +} + diff --git a/Test/enhanced.4.vert b/Test/enhanced.4.vert new file mode 100644 index 00000000..043ee246 --- /dev/null +++ b/Test/enhanced.4.vert @@ -0,0 +1,22 @@ +#version 450 core + +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec2 aTexCoords; + +layout (binding = 0) uniform anonblock { + mat4 model; + mat4 view; + mat4 projection; +} ; + +layout (location = 0) out VS_OUT +{ + vec2 TexCoords; +} vs_out; + +void main() +{ + gl_Position = projection * view * model * vec4(aPos, 1.0); + vs_out.TexCoords = aTexCoords; +} + diff --git a/Test/enhanced.5.frag b/Test/enhanced.5.frag new file mode 100644 index 00000000..b2a51e26 --- /dev/null +++ b/Test/enhanced.5.frag @@ -0,0 +1,16 @@ +#version 450 core + +layout (location = 0) out vec4 FragColor; + +layout (location = 0) in VS_OUT +{ + vec3 TexCoords; +} fs_in; + +layout (binding = 1) uniform sampler2D t0; + +void main() +{ + FragColor = texture(t0, fs_in.TexCoords.xy); +} + diff --git a/Test/enhanced.5.vert b/Test/enhanced.5.vert new file mode 100644 index 00000000..043ee246 --- /dev/null +++ b/Test/enhanced.5.vert @@ -0,0 +1,22 @@ +#version 450 core + +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec2 aTexCoords; + +layout (binding = 0) uniform anonblock { + mat4 model; + mat4 view; + mat4 projection; +} ; + +layout (location = 0) out VS_OUT +{ + vec2 TexCoords; +} vs_out; + +void main() +{ + gl_Position = projection * view * model * vec4(aPos, 1.0); + vs_out.TexCoords = aTexCoords; +} + diff --git a/Test/enhanced.6.frag b/Test/enhanced.6.frag new file mode 100644 index 00000000..e1cf6857 --- /dev/null +++ b/Test/enhanced.6.frag @@ -0,0 +1,16 @@ +#version 450 core + +layout (location = 0) out vec4 FragColor; + +layout (location = 0) in VS_OUT +{ + vec2 TexCoords; +} fs_in[1]; + +layout (binding = 1) uniform sampler2D t0; + +void main() +{ + FragColor = texture(t0, fs_in[0].TexCoords); +} + diff --git a/Test/enhanced.6.vert b/Test/enhanced.6.vert new file mode 100644 index 00000000..876a903e --- /dev/null +++ b/Test/enhanced.6.vert @@ -0,0 +1,22 @@ +#version 450 core + +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec2 aTexCoords; + +layout (binding = 0) uniform anonblock { + mat4 model; + mat4 view; + mat4 projection; +} ; + +layout (location = 0) out VS_OUT +{ + vec2 TexCoords; +} vs_out[2]; + +void main() +{ + gl_Position = projection * view * model * vec4(aPos, 1.0); + vs_out[0].TexCoords = aTexCoords; +} + diff --git a/Test/enhanced.7.frag b/Test/enhanced.7.frag new file mode 100644 index 00000000..f6e5279d --- /dev/null +++ b/Test/enhanced.7.frag @@ -0,0 +1,20 @@ +#version 450 core + +layout (location = 0) out vec4 FragColor; + +layout (location = 0) in Vertex +{ + vec4 color; + vec3 worldSpacePos; + vec3 worldSpaceNorm; + vec2 texCoord1; + flat int cameraIndex; +} fs_in; + +layout (binding = 1) uniform sampler2D t0; + +void main() +{ + FragColor = texture(t0, fs_in.texCoord1); +} + diff --git a/Test/enhanced.7.vert b/Test/enhanced.7.vert new file mode 100644 index 00000000..4e70a617 --- /dev/null +++ b/Test/enhanced.7.vert @@ -0,0 +1,27 @@ +#version 450 core + +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec2 aTexCoords; + +layout (binding = 0) uniform anonblock { + mat4 model; + mat4 view; + mat4 projection; +} ; + +layout (location = 0) out Vertex +{ + vec4 color; + vec3 worldSpacePos; + vec3 worldSpaceNorm; + vec2 texCoord1; + flat int cameraIndex; + float ii; +} vs_out; + +void main() +{ + gl_Position = projection * view * model * vec4(aPos, 1.0); + vs_out.texCoord1 = aTexCoords; +} + diff --git a/Test/runtests b/Test/runtests index 63c3a03b..9f588e28 100755 --- a/Test/runtests +++ b/Test/runtests @@ -298,6 +298,28 @@ diff -b $BASEDIR/hlsl.autosampledtextures.frag.out $TARGETDIR/hlsl.autosampledte run --auto-sampled-textures -H -Od -S frag glsl.autosampledtextures.frag > $TARGETDIR/glsl.autosampledtextures.frag.out diff -b $BASEDIR/glsl.autosampledtextures.frag.out $TARGETDIR/glsl.autosampledtextures.frag.out || HASERROR=1 +# +# Test --enhanced-msgs +# + +echo "Testing enhanced-msgs" +run --enhanced-msgs -V --target-env vulkan1.2 --amb --aml enhanced.0.frag > $TARGETDIR/enhanced.0.frag.out +diff -b $BASEDIR/enhanced.0.frag.out $TARGETDIR/enhanced.0.frag.out || HASERROR=1 +run --enhanced-msgs -V --target-env vulkan1.2 --amb --aml enhanced.1.frag > $TARGETDIR/enhanced.1.frag.out +diff -b $BASEDIR/enhanced.1.frag.out $TARGETDIR/enhanced.1.frag.out || HASERROR=1 +run --enhanced-msgs -V --target-env vulkan1.2 --amb --aml enhanced.2.frag > $TARGETDIR/enhanced.2.frag.out +diff -b $BASEDIR/enhanced.2.frag.out $TARGETDIR/enhanced.2.frag.out || HASERROR=1 +run --enhanced-msgs -V --target-env vulkan1.2 --amb --aml enhanced.3.vert enhanced.3.frag > $TARGETDIR/enhanced.3.link.out +diff -b $BASEDIR/enhanced.3.link.out $TARGETDIR/enhanced.3.link.out || HASERROR=1 +run --enhanced-msgs -V --target-env vulkan1.2 --amb --aml enhanced.4.vert enhanced.4.frag > $TARGETDIR/enhanced.4.link.out +diff -b $BASEDIR/enhanced.4.link.out $TARGETDIR/enhanced.4.link.out || HASERROR=1 +run --enhanced-msgs -V --target-env vulkan1.2 --amb --aml enhanced.5.vert enhanced.5.frag > $TARGETDIR/enhanced.5.link.out +diff -b $BASEDIR/enhanced.5.link.out $TARGETDIR/enhanced.5.link.out || HASERROR=1 +run --enhanced-msgs -V --target-env vulkan1.2 --amb --aml enhanced.6.vert enhanced.6.frag > $TARGETDIR/enhanced.6.link.out +diff -b $BASEDIR/enhanced.6.link.out $TARGETDIR/enhanced.6.link.out || HASERROR=1 +run --enhanced-msgs -V --target-env vulkan1.2 --amb --aml enhanced.7.vert enhanced.7.frag > $TARGETDIR/enhanced.7.link.out +diff -b $BASEDIR/enhanced.7.link.out $TARGETDIR/enhanced.7.link.out || HASERROR=1 + # # Final checking # diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index 6a7e61df..54150fbe 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -2142,7 +2142,8 @@ public: const char* getPrecisionQualifierString() const { return ""; } TString getBasicTypeString() const { return ""; } #else - TString getCompleteString() const + TString getCompleteString(bool syntactic = false, bool getQualifiers = true, bool getPrecision = true, + bool getType = true, TString name = "", TString structName = "") const { TString typeString; @@ -2150,232 +2151,335 @@ public: const auto appendUint = [&](unsigned int u) { typeString.append(std::to_string(u).c_str()); }; const auto appendInt = [&](int i) { typeString.append(std::to_string(i).c_str()); }; - if (qualifier.hasSprivDecorate()) + if (getQualifiers) { + if (qualifier.hasSprivDecorate()) appendStr(qualifier.getSpirvDecorateQualifierString().c_str()); - if (qualifier.hasLayout()) { + if (qualifier.hasLayout()) { // To reduce noise, skip this if the only layout is an xfb_buffer // with no triggering xfb_offset. TQualifier noXfbBuffer = qualifier; noXfbBuffer.layoutXfbBuffer = TQualifier::layoutXfbBufferEnd; if (noXfbBuffer.hasLayout()) { - appendStr("layout("); - if (qualifier.hasAnyLocation()) { - appendStr(" location="); - appendUint(qualifier.layoutLocation); - if (qualifier.hasComponent()) { - appendStr(" component="); - appendUint(qualifier.layoutComponent); - } - if (qualifier.hasIndex()) { - appendStr(" index="); - appendUint(qualifier.layoutIndex); - } + appendStr("layout("); + if (qualifier.hasAnyLocation()) { + appendStr(" location="); + appendUint(qualifier.layoutLocation); + if (qualifier.hasComponent()) { + appendStr(" component="); + appendUint(qualifier.layoutComponent); } - if (qualifier.hasSet()) { - appendStr(" set="); - appendUint(qualifier.layoutSet); - } - if (qualifier.hasBinding()) { - appendStr(" binding="); - appendUint(qualifier.layoutBinding); - } - if (qualifier.hasStream()) { - appendStr(" stream="); - appendUint(qualifier.layoutStream); - } - if (qualifier.hasMatrix()) { - appendStr(" "); - appendStr(TQualifier::getLayoutMatrixString(qualifier.layoutMatrix)); - } - if (qualifier.hasPacking()) { - appendStr(" "); - appendStr(TQualifier::getLayoutPackingString(qualifier.layoutPacking)); - } - if (qualifier.hasOffset()) { - appendStr(" offset="); - appendInt(qualifier.layoutOffset); - } - if (qualifier.hasAlign()) { - appendStr(" align="); - appendInt(qualifier.layoutAlign); - } - if (qualifier.hasFormat()) { - appendStr(" "); - appendStr(TQualifier::getLayoutFormatString(qualifier.layoutFormat)); - } - if (qualifier.hasXfbBuffer() && qualifier.hasXfbOffset()) { - appendStr(" xfb_buffer="); - appendUint(qualifier.layoutXfbBuffer); - } - if (qualifier.hasXfbOffset()) { - appendStr(" xfb_offset="); - appendUint(qualifier.layoutXfbOffset); - } - if (qualifier.hasXfbStride()) { - appendStr(" xfb_stride="); - appendUint(qualifier.layoutXfbStride); - } - if (qualifier.hasAttachment()) { - appendStr(" input_attachment_index="); - appendUint(qualifier.layoutAttachment); - } - if (qualifier.hasSpecConstantId()) { - appendStr(" constant_id="); - appendUint(qualifier.layoutSpecConstantId); - } - if (qualifier.layoutPushConstant) - appendStr(" push_constant"); - if (qualifier.layoutBufferReference) - appendStr(" buffer_reference"); - if (qualifier.hasBufferReferenceAlign()) { - appendStr(" buffer_reference_align="); - appendUint(1u << qualifier.layoutBufferReferenceAlign); + if (qualifier.hasIndex()) { + appendStr(" index="); + appendUint(qualifier.layoutIndex); } + } + if (qualifier.hasSet()) { + appendStr(" set="); + appendUint(qualifier.layoutSet); + } + if (qualifier.hasBinding()) { + appendStr(" binding="); + appendUint(qualifier.layoutBinding); + } + if (qualifier.hasStream()) { + appendStr(" stream="); + appendUint(qualifier.layoutStream); + } + if (qualifier.hasMatrix()) { + appendStr(" "); + appendStr(TQualifier::getLayoutMatrixString(qualifier.layoutMatrix)); + } + if (qualifier.hasPacking()) { + appendStr(" "); + appendStr(TQualifier::getLayoutPackingString(qualifier.layoutPacking)); + } + if (qualifier.hasOffset()) { + appendStr(" offset="); + appendInt(qualifier.layoutOffset); + } + if (qualifier.hasAlign()) { + appendStr(" align="); + appendInt(qualifier.layoutAlign); + } + if (qualifier.hasFormat()) { + appendStr(" "); + appendStr(TQualifier::getLayoutFormatString(qualifier.layoutFormat)); + } + if (qualifier.hasXfbBuffer() && qualifier.hasXfbOffset()) { + appendStr(" xfb_buffer="); + appendUint(qualifier.layoutXfbBuffer); + } + if (qualifier.hasXfbOffset()) { + appendStr(" xfb_offset="); + appendUint(qualifier.layoutXfbOffset); + } + if (qualifier.hasXfbStride()) { + appendStr(" xfb_stride="); + appendUint(qualifier.layoutXfbStride); + } + if (qualifier.hasAttachment()) { + appendStr(" input_attachment_index="); + appendUint(qualifier.layoutAttachment); + } + if (qualifier.hasSpecConstantId()) { + appendStr(" constant_id="); + appendUint(qualifier.layoutSpecConstantId); + } + if (qualifier.layoutPushConstant) + appendStr(" push_constant"); + if (qualifier.layoutBufferReference) + appendStr(" buffer_reference"); + if (qualifier.hasBufferReferenceAlign()) { + appendStr(" buffer_reference_align="); + appendUint(1u << qualifier.layoutBufferReferenceAlign); + } - if (qualifier.layoutPassthrough) - appendStr(" passthrough"); - if (qualifier.layoutViewportRelative) - appendStr(" layoutViewportRelative"); - if (qualifier.layoutSecondaryViewportRelativeOffset != -2048) { - appendStr(" layoutSecondaryViewportRelativeOffset="); - appendInt(qualifier.layoutSecondaryViewportRelativeOffset); - } - if (qualifier.layoutShaderRecord) - appendStr(" shaderRecordNV"); + if (qualifier.layoutPassthrough) + appendStr(" passthrough"); + if (qualifier.layoutViewportRelative) + appendStr(" layoutViewportRelative"); + if (qualifier.layoutSecondaryViewportRelativeOffset != -2048) { + appendStr(" layoutSecondaryViewportRelativeOffset="); + appendInt(qualifier.layoutSecondaryViewportRelativeOffset); + } + if (qualifier.layoutShaderRecord) + appendStr(" shaderRecordNV"); - appendStr(")"); + appendStr(")"); } - } + } - if (qualifier.invariant) + if (qualifier.invariant) appendStr(" invariant"); - if (qualifier.noContraction) + if (qualifier.noContraction) appendStr(" noContraction"); - if (qualifier.centroid) + if (qualifier.centroid) appendStr(" centroid"); - if (qualifier.smooth) + if (qualifier.smooth) appendStr(" smooth"); - if (qualifier.flat) + if (qualifier.flat) appendStr(" flat"); - if (qualifier.nopersp) + if (qualifier.nopersp) appendStr(" noperspective"); - if (qualifier.explicitInterp) + if (qualifier.explicitInterp) appendStr(" __explicitInterpAMD"); - if (qualifier.pervertexNV) + if (qualifier.pervertexNV) appendStr(" pervertexNV"); - if (qualifier.perPrimitiveNV) + if (qualifier.perPrimitiveNV) appendStr(" perprimitiveNV"); - if (qualifier.perViewNV) + if (qualifier.perViewNV) appendStr(" perviewNV"); - if (qualifier.perTaskNV) + if (qualifier.perTaskNV) appendStr(" taskNV"); - if (qualifier.patch) + if (qualifier.patch) appendStr(" patch"); - if (qualifier.sample) + if (qualifier.sample) appendStr(" sample"); - if (qualifier.coherent) + if (qualifier.coherent) appendStr(" coherent"); - if (qualifier.devicecoherent) + if (qualifier.devicecoherent) appendStr(" devicecoherent"); - if (qualifier.queuefamilycoherent) + if (qualifier.queuefamilycoherent) appendStr(" queuefamilycoherent"); - if (qualifier.workgroupcoherent) + if (qualifier.workgroupcoherent) appendStr(" workgroupcoherent"); - if (qualifier.subgroupcoherent) + if (qualifier.subgroupcoherent) appendStr(" subgroupcoherent"); - if (qualifier.shadercallcoherent) + if (qualifier.shadercallcoherent) appendStr(" shadercallcoherent"); - if (qualifier.nonprivate) + if (qualifier.nonprivate) appendStr(" nonprivate"); - if (qualifier.volatil) + if (qualifier.volatil) appendStr(" volatile"); - if (qualifier.restrict) + if (qualifier.restrict) appendStr(" restrict"); - if (qualifier.readonly) + if (qualifier.readonly) appendStr(" readonly"); - if (qualifier.writeonly) + if (qualifier.writeonly) appendStr(" writeonly"); - if (qualifier.specConstant) + if (qualifier.specConstant) appendStr(" specialization-constant"); - if (qualifier.nonUniform) + if (qualifier.nonUniform) appendStr(" nonuniform"); - if (qualifier.isNullInit()) + if (qualifier.isNullInit()) appendStr(" null-init"); - if (qualifier.isSpirvByReference()) + if (qualifier.isSpirvByReference()) appendStr(" spirv_by_reference"); - if (qualifier.isSpirvLiteral()) + if (qualifier.isSpirvLiteral()) appendStr(" spirv_literal"); - appendStr(" "); - appendStr(getStorageQualifierString()); - if (isArray()) { - for(int i = 0; i < (int)arraySizes->getNumDims(); ++i) { + appendStr(" "); + appendStr(getStorageQualifierString()); + } + if (getType) { + if (syntactic) { + if (getPrecision && qualifier.precision != EpqNone) { + appendStr(" "); + appendStr(getPrecisionQualifierString()); + } + if (isVector() || isMatrix()) { + appendStr(" "); + switch (basicType) { + case EbtDouble: + appendStr("d"); + break; + case EbtInt: + appendStr("i"); + break; + case EbtUint: + appendStr("u"); + break; + case EbtBool: + appendStr("b"); + break; + case EbtFloat: + default: + break; + } + if (isVector()) { + appendStr("vec"); + appendInt(vectorSize); + } else { + appendStr("mat"); + appendInt(matrixCols); + appendStr("x"); + appendInt(matrixRows); + } + } else if (isStruct() && structure) { + appendStr(" "); + appendStr(structName.c_str()); + appendStr("{"); + bool hasHiddenMember = true; + for (size_t i = 0; i < structure->size(); ++i) { + if (!(*structure)[i].type->hiddenMember()) { + if (!hasHiddenMember) + appendStr(", "); + typeString.append((*structure)[i].type->getCompleteString(syntactic, getQualifiers, getPrecision, getType, (*structure)[i].type->getFieldName())); + hasHiddenMember = false; + } + } + appendStr("}"); + } else { + appendStr(" "); + switch (basicType) { + case EbtDouble: + appendStr("double"); + break; + case EbtInt: + appendStr("int"); + break; + case EbtUint: + appendStr("uint"); + break; + case EbtBool: + appendStr("bool"); + break; + case EbtFloat: + appendStr("float"); + break; + default: + appendStr("unexpected"); + break; + } + } + if (name.length() > 0) { + appendStr(" "); + appendStr(name.c_str()); + } + if (isArray()) { + for (int i = 0; i < (int)arraySizes->getNumDims(); ++i) { int size = arraySizes->getDimSize(i); if (size == UnsizedArraySize && i == 0 && arraySizes->isVariablyIndexed()) - appendStr(" runtime-sized array of"); + appendStr("[]"); else { - if (size == UnsizedArraySize) { - appendStr(" unsized"); - if (i == 0) { - appendStr(" "); - appendInt(arraySizes->getImplicitSize()); - } - } else { - appendStr(" "); - appendInt(arraySizes->getDimSize(i)); - } - appendStr("-element array of"); + if (size == UnsizedArraySize) { + appendStr("["); + if (i == 0) + appendInt(arraySizes->getImplicitSize()); + appendStr("]"); + } + else { + appendStr("["); + appendInt(arraySizes->getDimSize(i)); + appendStr("]"); + } } + } } - } - if (isParameterized()) { - appendStr("<"); - for(int i = 0; i < (int)typeParameters->getNumDims(); ++i) { + } + else { + if (isArray()) { + for (int i = 0; i < (int)arraySizes->getNumDims(); ++i) { + int size = arraySizes->getDimSize(i); + if (size == UnsizedArraySize && i == 0 && arraySizes->isVariablyIndexed()) + appendStr(" runtime-sized array of"); + else { + if (size == UnsizedArraySize) { + appendStr(" unsized"); + if (i == 0) { + appendStr(" "); + appendInt(arraySizes->getImplicitSize()); + } + } + else { + appendStr(" "); + appendInt(arraySizes->getDimSize(i)); + } + appendStr("-element array of"); + } + } + } + if (isParameterized()) { + appendStr("<"); + for (int i = 0; i < (int)typeParameters->getNumDims(); ++i) { appendInt(typeParameters->getDimSize(i)); if (i != (int)typeParameters->getNumDims() - 1) + appendStr(", "); + } + appendStr(">"); + } + if (getPrecision && qualifier.precision != EpqNone) { + appendStr(" "); + appendStr(getPrecisionQualifierString()); + } + if (isMatrix()) { + appendStr(" "); + appendInt(matrixCols); + appendStr("X"); + appendInt(matrixRows); + appendStr(" matrix of"); + } + else if (isVector()) { + appendStr(" "); + appendInt(vectorSize); + appendStr("-component vector of"); + } + + appendStr(" "); + typeString.append(getBasicTypeString()); + + if (qualifier.builtIn != EbvNone) { + appendStr(" "); + appendStr(getBuiltInVariableString()); + } + + // Add struct/block members + if (isStruct() && structure) { + appendStr("{"); + bool hasHiddenMember = true; + for (size_t i = 0; i < structure->size(); ++i) { + if (!(*structure)[i].type->hiddenMember()) { + if (!hasHiddenMember) appendStr(", "); - } - appendStr(">"); - } - if (qualifier.precision != EpqNone) { - appendStr(" "); - appendStr(getPrecisionQualifierString()); - } - if (isMatrix()) { - appendStr(" "); - appendInt(matrixCols); - appendStr("X"); - appendInt(matrixRows); - appendStr(" matrix of"); - } else if (isVector()) { - appendStr(" "); - appendInt(vectorSize); - appendStr("-component vector of"); - } - - appendStr(" "); - typeString.append(getBasicTypeString()); - - if (qualifier.builtIn != EbvNone) { - appendStr(" "); - appendStr(getBuiltInVariableString()); - } - - // Add struct/block members - if (isStruct() && structure) { - appendStr("{"); - bool hasHiddenMember = true; - for (size_t i = 0; i < structure->size(); ++i) { - if (! (*structure)[i].type->hiddenMember()) { - if (!hasHiddenMember) - appendStr(", "); - typeString.append((*structure)[i].type->getCompleteString()); - typeString.append(" "); - typeString.append((*structure)[i].type->getFieldName()); - hasHiddenMember = false; + typeString.append((*structure)[i].type->getCompleteString()); + typeString.append(" "); + typeString.append((*structure)[i].type->getFieldName()); + hasHiddenMember = false; } + } + appendStr("}"); } - appendStr("}"); + } } return typeString; @@ -2444,10 +2548,20 @@ public: // type definitions, and member names to be considered the same type. // This rule applies recursively for nested or embedded types." // - bool sameStructType(const TType& right) const + // If type mismatch in structure, return member indices through lpidx and rpidx. + // If matching members for either block are exhausted, return -1 for exhausted + // block and the index of the unmatched member. Otherwise return {-1,-1}. + // + bool sameStructType(const TType& right, int* lpidx = nullptr, int* rpidx = nullptr) const { - // TODO: Why return true when neither types are structures? + // Initialize error to general type mismatch. + if (lpidx != nullptr) { + *lpidx = -1; + *rpidx = -1; + } + // Most commonly, they are both nullptr, or the same pointer to the same actual structure + // TODO: Why return true when neither types are structures? if ((!isStruct() && !right.isStruct()) || (isStruct() && right.isStruct() && structure == right.structure)) return true; @@ -2464,11 +2578,17 @@ public: bool isGLPerVertex = *typeName == "gl_PerVertex"; // Both being nullptr was caught above, now they both have to be structures of the same number of elements - if (structure->size() != right.structure->size() && !isGLPerVertex) + if (lpidx == nullptr && + (structure->size() != right.structure->size() && !isGLPerVertex)) { return false; + } // Compare the names and types of all the members, which have to match for (size_t li = 0, ri = 0; li < structure->size() || ri < right.structure->size(); ++li, ++ri) { + if (lpidx != nullptr) { + *lpidx = static_cast(li); + *rpidx = static_cast(ri); + } if (li < structure->size() && ri < right.structure->size()) { if ((*structure)[li].type->getFieldName() == (*right.structure)[ri].type->getFieldName()) { if (*(*structure)[li].type != *(*right.structure)[ri].type) @@ -2498,11 +2618,19 @@ public: } // If we get here, then there should only be inconsistently declared members left } else if (li < structure->size()) { - if (!(*structure)[li].type->hiddenMember() && !isInconsistentGLPerVertexMember((*structure)[li].type->getFieldName())) + if (!(*structure)[li].type->hiddenMember() && !isInconsistentGLPerVertexMember((*structure)[li].type->getFieldName())) { + if (lpidx != nullptr) { + *rpidx = -1; + } return false; + } } else { - if (!(*right.structure)[ri].type->hiddenMember() && !isInconsistentGLPerVertexMember((*right.structure)[ri].type->getFieldName())) + if (!(*right.structure)[ri].type->hiddenMember() && !isInconsistentGLPerVertexMember((*right.structure)[ri].type->getFieldName())) { + if (lpidx != nullptr) { + *lpidx = -1; + } return false; + } } } @@ -2526,10 +2654,15 @@ public: return *referentType == *right.referentType; } - // See if two types match, in all aspects except arrayness - bool sameElementType(const TType& right) const + // See if two types match, in all aspects except arrayness + // If mismatch in structure members, return member indices in lpidx and rpidx. + bool sameElementType(const TType& right, int* lpidx = nullptr, int* rpidx = nullptr) const { - return basicType == right.basicType && sameElementShape(right); + if (lpidx != nullptr) { + *lpidx = -1; + *rpidx = -1; + } + return basicType == right.basicType && sameElementShape(right, lpidx, rpidx); } // See if two type's arrayness match @@ -2563,15 +2696,20 @@ public: #endif // See if two type's elements match in all ways except basic type - bool sameElementShape(const TType& right) const + // If mismatch in structure members, return member indices in lpidx and rpidx. + bool sameElementShape(const TType& right, int* lpidx = nullptr, int* rpidx = nullptr) const { + if (lpidx != nullptr) { + *lpidx = -1; + *rpidx = -1; + } return sampler == right.sampler && vectorSize == right.vectorSize && matrixCols == right.matrixCols && matrixRows == right.matrixRows && vector1 == right.vector1 && isCoopMat() == right.isCoopMat() && - sameStructType(right) && + sameStructType(right, lpidx, rpidx) && sameReferenceType(right); } diff --git a/glslang/Include/glslang_c_shader_types.h b/glslang/Include/glslang_c_shader_types.h index df19777b..f11443f3 100644 --- a/glslang/Include/glslang_c_shader_types.h +++ b/glslang/Include/glslang_c_shader_types.h @@ -155,6 +155,7 @@ typedef enum { GLSLANG_MSG_HLSL_LEGALIZATION_BIT = (1 << 12), GLSLANG_MSG_HLSL_DX9_COMPATIBLE_BIT = (1 << 13), GLSLANG_MSG_BUILTIN_SYMBOL_TABLE_BIT = (1 << 14), + GLSLANG_MSG_ENHANCED = (1 << 15), LAST_ELEMENT_MARKER(GLSLANG_MSG_COUNT), } glslang_messages_t; diff --git a/glslang/Include/intermediate.h b/glslang/Include/intermediate.h index 595bd623..a64ed683 100644 --- a/glslang/Include/intermediate.h +++ b/glslang/Include/intermediate.h @@ -1155,7 +1155,7 @@ public: virtual bool isIntegerDomain() const { return type.isIntegerDomain(); } bool isAtomic() const { return type.isAtomic(); } bool isReference() const { return type.isReference(); } - TString getCompleteString() const { return type.getCompleteString(); } + TString getCompleteString(bool enhanced = false) const { return type.getCompleteString(enhanced); } protected: TIntermTyped& operator=(const TIntermTyped&); diff --git a/glslang/MachineIndependent/ParseContextBase.cpp b/glslang/MachineIndependent/ParseContextBase.cpp index 1da50d62..616580f9 100644 --- a/glslang/MachineIndependent/ParseContextBase.cpp +++ b/glslang/MachineIndependent/ParseContextBase.cpp @@ -74,6 +74,9 @@ void C_DECL TParseContextBase::error(const TSourceLoc& loc, const char* szReason { if (messages & EShMsgOnlyPreprocessor) return; + // If enhanced msg readability, only print one error + if (messages & EShMsgEnhanced && numErrors > 0) + return; va_list args; va_start(args, szExtraInfoFormat); outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixError, args); diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index fa291160..64e352f3 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -902,8 +902,10 @@ TIntermTyped* TParseContext::handleBinaryMath(const TSourceLoc& loc, const char* result = intermediate.addBinaryMath(op, left, right, loc); } - if (result == nullptr) - binaryOpError(loc, str, left->getCompleteString(), right->getCompleteString()); + if (result == nullptr) { + bool enhanced = intermediate.getEnhancedMsgs(); + binaryOpError(loc, str, left->getCompleteString(enhanced), right->getCompleteString(enhanced)); + } return result; } @@ -926,8 +928,10 @@ TIntermTyped* TParseContext::handleUnaryMath(const TSourceLoc& loc, const char* if (result) return result; - else - unaryOpError(loc, str, childNode->getCompleteString()); + else { + bool enhanced = intermediate.getEnhancedMsgs(); + unaryOpError(loc, str, childNode->getCompleteString(enhanced)); + } return childNode; } @@ -953,8 +957,8 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm requireProfile(loc, ~EEsProfile, feature); profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, feature); } else if (!base->getType().isCoopMat()) { - error(loc, "does not operate on this type:", field.c_str(), base->getType().getCompleteString().c_str()); - + bool enhanced = intermediate.getEnhancedMsgs(); + error(loc, "does not operate on this type:", field.c_str(), base->getType().getCompleteString(enhanced).c_str()); return base; } @@ -1005,10 +1009,16 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm intermediate.addIoAccessed(field); } inheritMemoryQualifiers(base->getQualifier(), result->getWritableType().getQualifier()); - } else - error(loc, "no such field in structure", field.c_str(), ""); + } else { + auto baseSymbol = base; + while (baseSymbol->getAsSymbolNode() == nullptr) + baseSymbol = baseSymbol->getAsBinaryNode()->getLeft(); + TString structName; + structName.append("\'").append(baseSymbol->getAsSymbolNode()->getName().c_str()).append( "\'"); + error(loc, "no such field in structure", field.c_str(), structName.c_str()); + } } else - error(loc, "does not apply to this type:", field.c_str(), base->getType().getCompleteString().c_str()); + error(loc, "does not apply to this type:", field.c_str(), base->getType().getCompleteString(intermediate.getEnhancedMsgs()).c_str()); // Propagate noContraction up the dereference chain if (base->getQualifier().isNoContraction()) @@ -1314,7 +1324,7 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction // result = addConstructor(loc, arguments, type); if (result == nullptr) - error(loc, "cannot construct with these arguments", type.getCompleteString().c_str(), ""); + error(loc, "cannot construct with these arguments", type.getCompleteString(intermediate.getEnhancedMsgs()).c_str(), ""); } } else { // @@ -1494,7 +1504,7 @@ TIntermTyped* TParseContext::handleBuiltInFunctionCall(TSourceLoc loc, TIntermNo else error(arguments->getLoc(), " wrong operand type", "Internal Error", "built in unary operator function. Type: %s", - static_cast(arguments)->getCompleteString().c_str()); + static_cast(arguments)->getCompleteString(intermediate.getEnhancedMsgs()).c_str()); } else if (result->getAsOperator()) builtInOpCheck(loc, function, *result->getAsOperator()); @@ -2599,23 +2609,24 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan // Check that if extended types are being used that the correct extensions are enabled. if (arg0 != nullptr) { const TType& type = arg0->getType(); + bool enhanced = intermediate.getEnhancedMsgs(); switch (type.getBasicType()) { default: break; case EbtInt8: case EbtUint8: - requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int8, type.getCompleteString().c_str()); + requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int8, type.getCompleteString(enhanced).c_str()); break; case EbtInt16: case EbtUint16: - requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int16, type.getCompleteString().c_str()); + requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int16, type.getCompleteString(enhanced).c_str()); break; case EbtInt64: case EbtUint64: - requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int64, type.getCompleteString().c_str()); + requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int64, type.getCompleteString(enhanced).c_str()); break; case EbtFloat16: - requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_float16, type.getCompleteString().c_str()); + requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_float16, type.getCompleteString(enhanced).c_str()); break; } } @@ -3198,6 +3209,12 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T break; } + TString constructorString; + if (intermediate.getEnhancedMsgs()) + constructorString.append(type.getCompleteString(true, false, false, true)).append(" constructor"); + else + constructorString.append("constructor"); + // See if it's a matrix bool constructingMatrix = false; switch (op) { @@ -3255,7 +3272,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T if (function[arg].type->isArray()) { if (function[arg].type->isUnsizedArray()) { // Can't construct from an unsized array. - error(loc, "array argument must be sized", "constructor", ""); + error(loc, "array argument must be sized", constructorString.c_str(), ""); return true; } arrayArg = true; @@ -3285,13 +3302,13 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T intArgument = true; if (type.isStruct()) { if (function[arg].type->contains16BitFloat()) { - requireFloat16Arithmetic(loc, "constructor", "can't construct structure containing 16-bit type"); + requireFloat16Arithmetic(loc, constructorString.c_str(), "can't construct structure containing 16-bit type"); } if (function[arg].type->contains16BitInt()) { - requireInt16Arithmetic(loc, "constructor", "can't construct structure containing 16-bit type"); + requireInt16Arithmetic(loc, constructorString.c_str(), "can't construct structure containing 16-bit type"); } if (function[arg].type->contains8BitInt()) { - requireInt8Arithmetic(loc, "constructor", "can't construct structure containing 8-bit type"); + requireInt8Arithmetic(loc, constructorString.c_str(), "can't construct structure containing 8-bit type"); } } } @@ -3305,9 +3322,9 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T case EOpConstructF16Vec3: case EOpConstructF16Vec4: if (type.isArray()) - requireFloat16Arithmetic(loc, "constructor", "16-bit arrays not supported"); + requireFloat16Arithmetic(loc, constructorString.c_str(), "16-bit arrays not supported"); if (type.isVector() && function.getParamCount() != 1) - requireFloat16Arithmetic(loc, "constructor", "16-bit vectors only take vector types"); + requireFloat16Arithmetic(loc, constructorString.c_str(), "16-bit vectors only take vector types"); break; case EOpConstructUint16: case EOpConstructU16Vec2: @@ -3318,9 +3335,9 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T case EOpConstructI16Vec3: case EOpConstructI16Vec4: if (type.isArray()) - requireInt16Arithmetic(loc, "constructor", "16-bit arrays not supported"); + requireInt16Arithmetic(loc, constructorString.c_str(), "16-bit arrays not supported"); if (type.isVector() && function.getParamCount() != 1) - requireInt16Arithmetic(loc, "constructor", "16-bit vectors only take vector types"); + requireInt16Arithmetic(loc, constructorString.c_str(), "16-bit vectors only take vector types"); break; case EOpConstructUint8: case EOpConstructU8Vec2: @@ -3331,9 +3348,9 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T case EOpConstructI8Vec3: case EOpConstructI8Vec4: if (type.isArray()) - requireInt8Arithmetic(loc, "constructor", "8-bit arrays not supported"); + requireInt8Arithmetic(loc, constructorString.c_str(), "8-bit arrays not supported"); if (type.isVector() && function.getParamCount() != 1) - requireInt8Arithmetic(loc, "constructor", "8-bit vectors only take vector types"); + requireInt8Arithmetic(loc, constructorString.c_str(), "8-bit vectors only take vector types"); break; default: break; @@ -3415,7 +3432,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T if (type.isArray()) { if (function.getParamCount() == 0) { - error(loc, "array constructor must have at least one argument", "constructor", ""); + error(loc, "array constructor must have at least one argument", constructorString.c_str(), ""); return true; } @@ -3423,7 +3440,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T // auto adapt the constructor type to the number of arguments type.changeOuterArraySize(function.getParamCount()); } else if (type.getOuterArraySize() != function.getParamCount()) { - error(loc, "array constructor needs one argument per array element", "constructor", ""); + error(loc, "array constructor needs one argument per array element", constructorString.c_str(), ""); return true; } @@ -3436,7 +3453,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T // At least the dimensionalities have to match. if (! function[0].type->isArray() || arraySizes.getNumDims() != function[0].type->getArraySizes()->getNumDims() + 1) { - error(loc, "array constructor argument not correct type to construct array element", "constructor", ""); + error(loc, "array constructor argument not correct type to construct array element", constructorString.c_str(), ""); return true; } @@ -3453,7 +3470,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T } if (arrayArg && op != EOpConstructStruct && ! type.isArrayOfArrays()) { - error(loc, "constructing non-array constituent from array argument", "constructor", ""); + error(loc, "constructing non-array constituent from array argument", constructorString.c_str(), ""); return true; } @@ -3463,51 +3480,51 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T // "If a matrix argument is given to a matrix constructor, // it is a compile-time error to have any other arguments." if (function.getParamCount() != 1) - error(loc, "matrix constructed from matrix can only have one argument", "constructor", ""); + error(loc, "matrix constructed from matrix can only have one argument", constructorString.c_str(), ""); return false; } if (overFull) { - error(loc, "too many arguments", "constructor", ""); + error(loc, "too many arguments", constructorString.c_str(), ""); return true; } if (op == EOpConstructStruct && ! type.isArray() && (int)type.getStruct()->size() != function.getParamCount()) { - error(loc, "Number of constructor parameters does not match the number of structure fields", "constructor", ""); + error(loc, "Number of constructor parameters does not match the number of structure fields", constructorString.c_str(), ""); return true; } if ((op != EOpConstructStruct && size != 1 && size < type.computeNumComponents()) || (op == EOpConstructStruct && size < type.computeNumComponents())) { - error(loc, "not enough data provided for construction", "constructor", ""); + error(loc, "not enough data provided for construction", constructorString.c_str(), ""); return true; } if (type.isCoopMat() && function.getParamCount() != 1) { - error(loc, "wrong number of arguments", "constructor", ""); + error(loc, "wrong number of arguments", constructorString.c_str(), ""); return true; } if (type.isCoopMat() && !(function[0].type->isScalar() || function[0].type->isCoopMat())) { - error(loc, "Cooperative matrix constructor argument must be scalar or cooperative matrix", "constructor", ""); + error(loc, "Cooperative matrix constructor argument must be scalar or cooperative matrix", constructorString.c_str(), ""); return true; } TIntermTyped* typed = node->getAsTyped(); if (typed == nullptr) { - error(loc, "constructor argument does not have a type", "constructor", ""); + error(loc, "constructor argument does not have a type", constructorString.c_str(), ""); return true; } if (op != EOpConstructStruct && op != EOpConstructNonuniform && typed->getBasicType() == EbtSampler) { - error(loc, "cannot convert a sampler", "constructor", ""); + error(loc, "cannot convert a sampler", constructorString.c_str(), ""); return true; } if (op != EOpConstructStruct && typed->isAtomic()) { - error(loc, "cannot convert an atomic_uint", "constructor", ""); + error(loc, "cannot convert an atomic_uint", constructorString.c_str(), ""); return true; } if (typed->getBasicType() == EbtVoid) { - error(loc, "cannot convert a void", "constructor", ""); + error(loc, "cannot convert a void", constructorString.c_str(), ""); return true; } @@ -7430,14 +7447,14 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp // Uniforms require a compile-time constant initializer if (qualifier == EvqUniform && ! initializer->getType().getQualifier().isFrontEndConstant()) { error(loc, "uniform initializers must be constant", "=", "'%s'", - variable->getType().getCompleteString().c_str()); + variable->getType().getCompleteString(intermediate.getEnhancedMsgs()).c_str()); variable->getWritableType().getQualifier().makeTemporary(); return nullptr; } // Global consts require a constant initializer (specialization constant is okay) if (qualifier == EvqConst && symbolTable.atGlobalLevel() && ! initializer->getType().getQualifier().isConstant()) { error(loc, "global const initializers must be constant", "=", "'%s'", - variable->getType().getCompleteString().c_str()); + variable->getType().getCompleteString(intermediate.getEnhancedMsgs()).c_str()); variable->getWritableType().getQualifier().makeTemporary(); return nullptr; } @@ -7500,7 +7517,7 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp TIntermSymbol* intermSymbol = intermediate.addSymbol(*variable, loc); TIntermTyped* initNode = intermediate.addAssign(EOpAssign, intermSymbol, initializer, loc); if (! initNode) - assignError(loc, "=", intermSymbol->getCompleteString(), initializer->getCompleteString()); + assignError(loc, "=", intermSymbol->getCompleteString(intermediate.getEnhancedMsgs()), initializer->getCompleteString(intermediate.getEnhancedMsgs())); return initNode; } @@ -7571,7 +7588,7 @@ TIntermTyped* TParseContext::convertInitializerList(const TSourceLoc& loc, const } } else if (type.isMatrix()) { if (type.getMatrixCols() != (int)initList->getSequence().size()) { - error(loc, "wrong number of matrix columns:", "initializer list", type.getCompleteString().c_str()); + error(loc, "wrong number of matrix columns:", "initializer list", type.getCompleteString(intermediate.getEnhancedMsgs()).c_str()); return nullptr; } TType vectorType(type, 0); // dereferenced type @@ -7582,20 +7599,20 @@ TIntermTyped* TParseContext::convertInitializerList(const TSourceLoc& loc, const } } else if (type.isVector()) { if (type.getVectorSize() != (int)initList->getSequence().size()) { - error(loc, "wrong vector size (or rows in a matrix column):", "initializer list", type.getCompleteString().c_str()); + error(loc, "wrong vector size (or rows in a matrix column):", "initializer list", type.getCompleteString(intermediate.getEnhancedMsgs()).c_str()); return nullptr; } TBasicType destType = type.getBasicType(); for (int i = 0; i < type.getVectorSize(); ++i) { TBasicType initType = initList->getSequence()[i]->getAsTyped()->getBasicType(); if (destType != initType && !intermediate.canImplicitlyPromote(initType, destType)) { - error(loc, "type mismatch in initializer list", "initializer list", type.getCompleteString().c_str()); + error(loc, "type mismatch in initializer list", "initializer list", type.getCompleteString(intermediate.getEnhancedMsgs()).c_str()); return nullptr; } } } else { - error(loc, "unexpected initializer-list type:", "initializer list", type.getCompleteString().c_str()); + error(loc, "unexpected initializer-list type:", "initializer list", type.getCompleteString(intermediate.getEnhancedMsgs()).c_str()); return nullptr; } @@ -8103,8 +8120,9 @@ TIntermTyped* TParseContext::constructAggregate(TIntermNode* node, const TType& { TIntermTyped* converted = intermediate.addConversion(EOpConstructStruct, type, node->getAsTyped()); if (! converted || converted->getType() != type) { + bool enhanced = intermediate.getEnhancedMsgs(); error(loc, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount, - node->getAsTyped()->getType().getCompleteString().c_str(), type.getCompleteString().c_str()); + node->getAsTyped()->getType().getCompleteString(enhanced).c_str(), type.getCompleteString(enhanced).c_str()); return nullptr; } diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp index bcf2c33f..871b9598 100644 --- a/glslang/MachineIndependent/ShaderLang.cpp +++ b/glslang/MachineIndependent/ShaderLang.cpp @@ -1830,6 +1830,7 @@ void TShader::setUniqueId(unsigned long long id) void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); } void TShader::setDxPositionW(bool invert) { intermediate->setDxPositionW(invert); } +void TShader::setEnhancedMsgs() { intermediate->setEnhancedMsgs(); } void TShader::setNanMinMaxClamp(bool useNonNan) { intermediate->setNanMinMaxClamp(useNonNan); } #ifndef GLSLANG_WEB @@ -2049,6 +2050,8 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages) firstIntermediate->getVersion(), firstIntermediate->getProfile()); intermediate[stage]->setLimits(firstIntermediate->getLimits()); + if (firstIntermediate->getEnhancedMsgs()) + intermediate[stage]->setEnhancedMsgs(); // The new TIntermediate must use the same origin as the original TIntermediates. // Otherwise linking will fail due to different coordinate systems. diff --git a/glslang/MachineIndependent/glslang.m4 b/glslang/MachineIndependent/glslang.m4 index d4cc5bc9..624add5a 100644 --- a/glslang/MachineIndependent/glslang.m4 +++ b/glslang/MachineIndependent/glslang.m4 @@ -798,7 +798,7 @@ conditional_expression parseContext.rValueErrorCheck($5.loc, ":", $6); $$ = parseContext.intermediate.addSelection($1, $4, $6, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.loc, ":", $4->getCompleteString(), $6->getCompleteString()); + parseContext.binaryOpError($2.loc, ":", $4->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), $6->getCompleteString(parseContext.intermediate.getEnhancedMsgs())); $$ = $6; } } @@ -815,7 +815,7 @@ assignment_expression parseContext.rValueErrorCheck($2.loc, "assign", $3); $$ = parseContext.addAssign($2.loc, $2.op, $1, $3); if ($$ == 0) { - parseContext.assignError($2.loc, "assign", $1->getCompleteString(), $3->getCompleteString()); + parseContext.assignError($2.loc, "assign", $1->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), $3->getCompleteString(parseContext.intermediate.getEnhancedMsgs())); $$ = $1; } } @@ -877,7 +877,7 @@ expression parseContext.samplerConstructorLocationCheck($2.loc, ",", $3); $$ = parseContext.intermediate.addComma($1, $3, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.loc, ",", $1->getCompleteString(), $3->getCompleteString()); + parseContext.binaryOpError($2.loc, ",", $1->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), $3->getCompleteString(parseContext.intermediate.getEnhancedMsgs())); $$ = $3; } } diff --git a/glslang/MachineIndependent/glslang.y b/glslang/MachineIndependent/glslang.y index df53eb5b..93c98995 100644 --- a/glslang/MachineIndependent/glslang.y +++ b/glslang/MachineIndependent/glslang.y @@ -798,7 +798,7 @@ conditional_expression parseContext.rValueErrorCheck($5.loc, ":", $6); $$ = parseContext.intermediate.addSelection($1, $4, $6, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.loc, ":", $4->getCompleteString(), $6->getCompleteString()); + parseContext.binaryOpError($2.loc, ":", $4->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), $6->getCompleteString(parseContext.intermediate.getEnhancedMsgs())); $$ = $6; } } @@ -815,7 +815,7 @@ assignment_expression parseContext.rValueErrorCheck($2.loc, "assign", $3); $$ = parseContext.addAssign($2.loc, $2.op, $1, $3); if ($$ == 0) { - parseContext.assignError($2.loc, "assign", $1->getCompleteString(), $3->getCompleteString()); + parseContext.assignError($2.loc, "assign", $1->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), $3->getCompleteString(parseContext.intermediate.getEnhancedMsgs())); $$ = $1; } } @@ -877,7 +877,7 @@ expression parseContext.samplerConstructorLocationCheck($2.loc, ",", $3); $$ = parseContext.intermediate.addComma($1, $3, $2.loc); if ($$ == 0) { - parseContext.binaryOpError($2.loc, ",", $1->getCompleteString(), $3->getCompleteString()); + parseContext.binaryOpError($2.loc, ",", $1->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), $3->getCompleteString(parseContext.intermediate.getEnhancedMsgs())); $$ = $3; } } diff --git a/glslang/MachineIndependent/glslang_tab.cpp b/glslang/MachineIndependent/glslang_tab.cpp index 5ba6a6d4..0b216b62 100644 --- a/glslang/MachineIndependent/glslang_tab.cpp +++ b/glslang/MachineIndependent/glslang_tab.cpp @@ -5878,7 +5878,7 @@ yyreduce: parseContext.rValueErrorCheck((yyvsp[-1].lex).loc, ":", (yyvsp[0].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = parseContext.intermediate.addSelection((yyvsp[-5].interm.intermTypedNode), (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yyvsp[-4].lex).loc); if ((yyval.interm.intermTypedNode) == 0) { - parseContext.binaryOpError((yyvsp[-4].lex).loc, ":", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(), (yyvsp[0].interm.intermTypedNode)->getCompleteString()); + parseContext.binaryOpError((yyvsp[-4].lex).loc, ":", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), (yyvsp[0].interm.intermTypedNode)->getCompleteString(parseContext.intermediate.getEnhancedMsgs())); (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } } @@ -5902,7 +5902,7 @@ yyreduce: parseContext.rValueErrorCheck((yyvsp[-1].interm).loc, "assign", (yyvsp[0].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = parseContext.addAssign((yyvsp[-1].interm).loc, (yyvsp[-1].interm).op, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) { - parseContext.assignError((yyvsp[-1].interm).loc, "assign", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(), (yyvsp[0].interm.intermTypedNode)->getCompleteString()); + parseContext.assignError((yyvsp[-1].interm).loc, "assign", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), (yyvsp[0].interm.intermTypedNode)->getCompleteString(parseContext.intermediate.getEnhancedMsgs())); (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } } @@ -6023,7 +6023,7 @@ yyreduce: parseContext.samplerConstructorLocationCheck((yyvsp[-1].lex).loc, ",", (yyvsp[0].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = parseContext.intermediate.addComma((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yyvsp[-1].lex).loc); if ((yyval.interm.intermTypedNode) == 0) { - parseContext.binaryOpError((yyvsp[-1].lex).loc, ",", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(), (yyvsp[0].interm.intermTypedNode)->getCompleteString()); + parseContext.binaryOpError((yyvsp[-1].lex).loc, ",", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), (yyvsp[0].interm.intermTypedNode)->getCompleteString(parseContext.intermediate.getEnhancedMsgs())); (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } } diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp index 620be97c..f5dc9b27 100644 --- a/glslang/MachineIndependent/linkValidate.cpp +++ b/glslang/MachineIndependent/linkValidate.cpp @@ -55,22 +55,28 @@ namespace glslang { // // Link-time error emitter. // -void TIntermediate::error(TInfoSink& infoSink, const char* message) +void TIntermediate::error(TInfoSink& infoSink, const char* message, EShLanguage unitStage) { #ifndef GLSLANG_WEB infoSink.info.prefix(EPrefixError); - infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n"; + if (unitStage < EShLangCount) + infoSink.info << "Linking " << StageName(getStage()) << " and " << StageName(unitStage) << " stages: " << message << "\n"; + else + infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n"; #endif ++numErrors; } // Link-time warning. -void TIntermediate::warn(TInfoSink& infoSink, const char* message) +void TIntermediate::warn(TInfoSink& infoSink, const char* message, EShLanguage unitStage) { #ifndef GLSLANG_WEB infoSink.info.prefix(EPrefixWarning); - infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n"; + if (unitStage < EShLangCount) + infoSink.info << "Linking " << StageName(language) << " and " << StageName(unitStage) << " stages: " << message << "\n"; + else + infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n"; #endif } @@ -819,6 +825,10 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy #if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) bool crossStage = getStage() != unitStage; bool writeTypeComparison = false; + bool errorReported = false; + bool printQualifiers = false; + bool printPrecision = false; + bool printType = false; // Types have to match { @@ -850,11 +860,48 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy (symbol.getType().isUnsizedArray() || unitSymbol.getType().isUnsizedArray())); } - if (!symbol.getType().sameElementType(unitSymbol.getType()) || - !symbol.getType().sameTypeParameters(unitSymbol.getType()) || - !arraysMatch ) { + int lpidx = -1; + int rpidx = -1; + if (!symbol.getType().sameElementType(unitSymbol.getType(), &lpidx, &rpidx)) { + if (lpidx >= 0 && rpidx >= 0) { + error(infoSink, "Member names and types must match:", unitStage); + infoSink.info << " Block: " << symbol.getType().getTypeName() << "\n"; + infoSink.info << " " << StageName(getStage()) << " stage: \"" + << (*symbol.getType().getStruct())[lpidx].type->getCompleteString(true, false, false, true, + (*symbol.getType().getStruct())[lpidx].type->getFieldName()) << "\"\n"; + infoSink.info << " " << StageName(unitStage) << " stage: \"" + << (*unitSymbol.getType().getStruct())[rpidx].type->getCompleteString(true, false, false, true, + (*unitSymbol.getType().getStruct())[rpidx].type->getFieldName()) << "\"\n"; + errorReported = true; + } else if (lpidx >= 0 && rpidx == -1) { + TString errmsg = StageName(getStage()); + errmsg.append(" block member has no corresponding member in ").append(StageName(unitStage)).append(" block:"); + error(infoSink, errmsg.c_str(), unitStage); + infoSink.info << " " << StageName(getStage()) << " stage: Block: " << symbol.getType().getTypeName() << ", Member: " + << (*symbol.getType().getStruct())[lpidx].type->getFieldName() << "\n"; + infoSink.info << " " << StageName(unitStage) << " stage: Block: " << unitSymbol.getType().getTypeName() << ", Member: n/a \n"; + errorReported = true; + } else if (lpidx == -1 && rpidx >= 0) { + TString errmsg = StageName(unitStage); + errmsg.append(" block member has no corresponding member in ").append(StageName(getStage())).append(" block:"); + error(infoSink, errmsg.c_str(), unitStage); + infoSink.info << " " << StageName(unitStage) << " stage: Block: " << unitSymbol.getType().getTypeName() << ", Member: " + << (*unitSymbol.getType().getStruct())[rpidx].type->getFieldName() << "\n"; + infoSink.info << " " << StageName(getStage()) << " stage: Block: " << symbol.getType().getTypeName() << ", Member: n/a \n"; + errorReported = true; + } else { + error(infoSink, "Types must match:", unitStage); + writeTypeComparison = true; + printType = true; + } + } else if (!arraysMatch) { + error(infoSink, "Array sizes must be compatible:", unitStage); writeTypeComparison = true; - error(infoSink, "Types must match:"); + printType = true; + } else if (!symbol.getType().sameTypeParameters(unitSymbol.getType())) { + error(infoSink, "Type parameters must match:", unitStage); + writeTypeComparison = true; + printType = true; } } @@ -875,13 +922,35 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy } const TQualifier& qualifier = (*symbol.getType().getStruct())[li].type->getQualifier(); const TQualifier & unitQualifier = (*unitSymbol.getType().getStruct())[ri].type->getQualifier(); - if (qualifier.layoutMatrix != unitQualifier.layoutMatrix || - qualifier.layoutOffset != unitQualifier.layoutOffset || - qualifier.layoutAlign != unitQualifier.layoutAlign || - qualifier.layoutLocation != unitQualifier.layoutLocation || - qualifier.layoutComponent != unitQualifier.layoutComponent) { - error(infoSink, "Interface block member layout qualifiers must match:"); - writeTypeComparison = true; + bool layoutQualifierError = false; + if (qualifier.layoutMatrix != unitQualifier.layoutMatrix) { + error(infoSink, "Interface block member layout matrix qualifier must match:", unitStage); + layoutQualifierError = true; + } + if (qualifier.layoutOffset != unitQualifier.layoutOffset) { + error(infoSink, "Interface block member layout offset qualifier must match:", unitStage); + layoutQualifierError = true; + } + if (qualifier.layoutAlign != unitQualifier.layoutAlign) { + error(infoSink, "Interface block member layout align qualifier must match:", unitStage); + layoutQualifierError = true; + } + if (qualifier.layoutLocation != unitQualifier.layoutLocation) { + error(infoSink, "Interface block member layout location qualifier must match:", unitStage); + layoutQualifierError = true; + } + if (qualifier.layoutComponent != unitQualifier.layoutComponent) { + error(infoSink, "Interface block member layout component qualifier must match:", unitStage); + layoutQualifierError = true; + } + if (layoutQualifierError) { + infoSink.info << " " << StageName(getStage()) << " stage: Block: " << symbol.getType().getTypeName() << ", Member: " + << (*symbol.getType().getStruct())[li].type->getFieldName() << " \"" + << (*symbol.getType().getStruct())[li].type->getCompleteString(true, true, false, false) << "\"\n"; + infoSink.info << " " << StageName(unitStage) << " stage: Block: " << unitSymbol.getType().getTypeName() << ", Member: " + << (*unitSymbol.getType().getStruct())[ri].type->getFieldName() << " \"" + << (*unitSymbol.getType().getStruct())[ri].type->getCompleteString(true, true, false, false) << "\"\n"; + errorReported = true; } ++li; ++ri; @@ -895,8 +964,9 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy // Qualifiers have to (almost) match // Storage... if (!isInOut && symbol.getQualifier().storage != unitSymbol.getQualifier().storage) { - error(infoSink, "Storage qualifiers must match:"); + error(infoSink, "Storage qualifiers must match:", unitStage); writeTypeComparison = true; + printQualifiers = true; } // Uniform and buffer blocks must either both have an instance name, or @@ -904,33 +974,36 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy if (symbol.getQualifier().isUniformOrBuffer() && (IsAnonymous(symbol.getName()) != IsAnonymous(unitSymbol.getName()))) { error(infoSink, "Matched Uniform or Storage blocks must all be anonymous," - " or all be named:"); + " or all be named:", unitStage); writeTypeComparison = true; } if (symbol.getQualifier().storage == unitSymbol.getQualifier().storage && (IsAnonymous(symbol.getName()) != IsAnonymous(unitSymbol.getName()) || (!IsAnonymous(symbol.getName()) && symbol.getName() != unitSymbol.getName()))) { - warn(infoSink, "Matched shader interfaces are using different instance names."); + warn(infoSink, "Matched shader interfaces are using different instance names.", unitStage); writeTypeComparison = true; } // Precision... if (!isInOut && symbol.getQualifier().precision != unitSymbol.getQualifier().precision) { - error(infoSink, "Precision qualifiers must match:"); + error(infoSink, "Precision qualifiers must match:", unitStage); writeTypeComparison = true; + printPrecision = true; } // Invariance... if (! crossStage && symbol.getQualifier().invariant != unitSymbol.getQualifier().invariant) { - error(infoSink, "Presence of invariant qualifier must match:"); + error(infoSink, "Presence of invariant qualifier must match:", unitStage); writeTypeComparison = true; + printQualifiers = true; } // Precise... if (! crossStage && symbol.getQualifier().isNoContraction() != unitSymbol.getQualifier().isNoContraction()) { - error(infoSink, "Presence of precise qualifier must match:"); + error(infoSink, "Presence of precise qualifier must match:", unitStage); writeTypeComparison = true; + printPrecision = true; } // Auxiliary and interpolation... @@ -944,57 +1017,137 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy symbol.getQualifier().isSample()!= unitSymbol.getQualifier().isSample() || symbol.getQualifier().isPatch() != unitSymbol.getQualifier().isPatch() || symbol.getQualifier().isNonPerspective() != unitSymbol.getQualifier().isNonPerspective())) { - error(infoSink, "Interpolation and auxiliary storage qualifiers must match:"); + error(infoSink, "Interpolation and auxiliary storage qualifiers must match:", unitStage); writeTypeComparison = true; + printQualifiers = true; } // Memory... - if (symbol.getQualifier().coherent != unitSymbol.getQualifier().coherent || - symbol.getQualifier().devicecoherent != unitSymbol.getQualifier().devicecoherent || - symbol.getQualifier().queuefamilycoherent != unitSymbol.getQualifier().queuefamilycoherent || - symbol.getQualifier().workgroupcoherent != unitSymbol.getQualifier().workgroupcoherent || - symbol.getQualifier().subgroupcoherent != unitSymbol.getQualifier().subgroupcoherent || - symbol.getQualifier().shadercallcoherent!= unitSymbol.getQualifier().shadercallcoherent || - symbol.getQualifier().nonprivate != unitSymbol.getQualifier().nonprivate || - symbol.getQualifier().volatil != unitSymbol.getQualifier().volatil || - symbol.getQualifier().restrict != unitSymbol.getQualifier().restrict || - symbol.getQualifier().readonly != unitSymbol.getQualifier().readonly || - symbol.getQualifier().writeonly != unitSymbol.getQualifier().writeonly) { - error(infoSink, "Memory qualifiers must match:"); - writeTypeComparison = true; + bool memoryQualifierError = false; + if (symbol.getQualifier().coherent != unitSymbol.getQualifier().coherent) { + error(infoSink, "Memory coherent qualifier must match:", unitStage); + memoryQualifierError = true; + } + if (symbol.getQualifier().devicecoherent != unitSymbol.getQualifier().devicecoherent) { + error(infoSink, "Memory devicecoherent qualifier must match:", unitStage); + memoryQualifierError = true; + } + if (symbol.getQualifier().queuefamilycoherent != unitSymbol.getQualifier().queuefamilycoherent) { + error(infoSink, "Memory queuefamilycoherent qualifier must match:", unitStage); + memoryQualifierError = true; + } + if (symbol.getQualifier().workgroupcoherent != unitSymbol.getQualifier().workgroupcoherent) { + error(infoSink, "Memory workgroupcoherent qualifier must match:", unitStage); + memoryQualifierError = true; + } + if (symbol.getQualifier().subgroupcoherent != unitSymbol.getQualifier().subgroupcoherent) { + error(infoSink, "Memory subgroupcoherent qualifier must match:", unitStage); + memoryQualifierError = true; + } + if (symbol.getQualifier().shadercallcoherent != unitSymbol.getQualifier().shadercallcoherent) { + error(infoSink, "Memory shadercallcoherent qualifier must match:", unitStage); + memoryQualifierError = true; + } + if (symbol.getQualifier().nonprivate != unitSymbol.getQualifier().nonprivate) { + error(infoSink, "Memory nonprivate qualifier must match:", unitStage); + memoryQualifierError = true; + } + if (symbol.getQualifier().volatil != unitSymbol.getQualifier().volatil) { + error(infoSink, "Memory volatil qualifier must match:", unitStage); + memoryQualifierError = true; + } + if (symbol.getQualifier().restrict != unitSymbol.getQualifier().restrict) { + error(infoSink, "Memory restrict qualifier must match:", unitStage); + memoryQualifierError = true; + } + if (symbol.getQualifier().readonly != unitSymbol.getQualifier().readonly) { + error(infoSink, "Memory readonly qualifier must match:", unitStage); + memoryQualifierError = true; + } + if (symbol.getQualifier().writeonly != unitSymbol.getQualifier().writeonly) { + error(infoSink, "Memory writeonly qualifier must match:", unitStage); + memoryQualifierError = true; + } + if (memoryQualifierError) { + writeTypeComparison = true; + printQualifiers = true; } // Layouts... // TODO: 4.4 enhanced layouts: Generalize to include offset/align: current spec // requires separate user-supplied offset from actual computed offset, but // current implementation only has one offset. - if (symbol.getQualifier().layoutMatrix != unitSymbol.getQualifier().layoutMatrix || - symbol.getQualifier().layoutPacking != unitSymbol.getQualifier().layoutPacking || - (symbol.getQualifier().hasLocation() && unitSymbol.getQualifier().hasLocation() && symbol.getQualifier().layoutLocation != unitSymbol.getQualifier().layoutLocation) || - symbol.getQualifier().layoutComponent != unitSymbol.getQualifier().layoutComponent || - symbol.getQualifier().layoutIndex != unitSymbol.getQualifier().layoutIndex || - (symbol.getQualifier().hasBinding() && unitSymbol.getQualifier().hasBinding() && symbol.getQualifier().layoutBinding != unitSymbol.getQualifier().layoutBinding) || - (symbol.getQualifier().hasBinding() && (symbol.getQualifier().layoutOffset != unitSymbol.getQualifier().layoutOffset))) { - error(infoSink, "Layout qualification must match:"); + bool layoutQualifierError = false; + if (symbol.getQualifier().layoutMatrix != unitSymbol.getQualifier().layoutMatrix) { + error(infoSink, "Layout matrix qualifier must match:", unitStage); + layoutQualifierError = true; + } + if (symbol.getQualifier().layoutPacking != unitSymbol.getQualifier().layoutPacking) { + error(infoSink, "Layout packing qualifier must match:", unitStage); + layoutQualifierError = true; + } + if (symbol.getQualifier().hasLocation() && unitSymbol.getQualifier().hasLocation() && symbol.getQualifier().layoutLocation != unitSymbol.getQualifier().layoutLocation) { + error(infoSink, "Layout location qualifier must match:", unitStage); + layoutQualifierError = true; + } + if (symbol.getQualifier().layoutComponent != unitSymbol.getQualifier().layoutComponent) { + error(infoSink, "Layout component qualifier must match:", unitStage); + layoutQualifierError = true; + } + if (symbol.getQualifier().layoutIndex != unitSymbol.getQualifier().layoutIndex) { + error(infoSink, "Layout index qualifier must match:", unitStage); + layoutQualifierError = true; + } + if (symbol.getQualifier().hasBinding() && unitSymbol.getQualifier().hasBinding() && symbol.getQualifier().layoutBinding != unitSymbol.getQualifier().layoutBinding) { + error(infoSink, "Layout binding qualifier must match:", unitStage); + layoutQualifierError = true; + } + if (symbol.getQualifier().hasBinding() && (symbol.getQualifier().layoutOffset != unitSymbol.getQualifier().layoutOffset)) { + error(infoSink, "Layout offset qualifier must match:", unitStage); + layoutQualifierError = true; + } + if (layoutQualifierError) { writeTypeComparison = true; + printQualifiers = true; } // Initializers have to match, if both are present, and if we don't already know the types don't match - if (! writeTypeComparison) { + if (! writeTypeComparison && ! errorReported) { if (! symbol.getConstArray().empty() && ! unitSymbol.getConstArray().empty()) { if (symbol.getConstArray() != unitSymbol.getConstArray()) { - error(infoSink, "Initializers must match:"); + error(infoSink, "Initializers must match:", unitStage); infoSink.info << " " << symbol.getName() << "\n"; } } } if (writeTypeComparison) { - infoSink.info << " " << symbol.getName() << ": \"" << symbol.getType().getCompleteString() << "\" versus "; - if (symbol.getName() != unitSymbol.getName()) - infoSink.info << unitSymbol.getName() << ": "; - - infoSink.info << "\"" << unitSymbol.getType().getCompleteString() << "\"\n"; + if (symbol.getType().getBasicType() == EbtBlock && unitSymbol.getType().getBasicType() == EbtBlock && + symbol.getType().getStruct() && unitSymbol.getType().getStruct()) { + if (printType) { + infoSink.info << " " << StageName(getStage()) << " stage: \"" << symbol.getType().getCompleteString(true, printQualifiers, printPrecision, + printType, symbol.getName(), symbol.getType().getTypeName()) << "\"\n"; + infoSink.info << " " << StageName(unitStage) << " stage: \"" << unitSymbol.getType().getCompleteString(true, printQualifiers, printPrecision, + printType, unitSymbol.getName(), unitSymbol.getType().getTypeName()) << "\"\n"; + } else { + infoSink.info << " " << StageName(getStage()) << " stage: Block: " << symbol.getType().getTypeName() << " Instance: " << symbol.getName() + << ": \"" << symbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType) << "\"\n"; + infoSink.info << " " << StageName(unitStage) << " stage: Block: " << unitSymbol.getType().getTypeName() << " Instance: " << unitSymbol.getName() + << ": \"" << unitSymbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType) << "\"\n"; + } + } else { + if (printType) { + infoSink.info << " " << StageName(getStage()) << " stage: \"" + << symbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType, symbol.getName()) << "\"\n"; + infoSink.info << " " << StageName(unitStage) << " stage: \"" + << unitSymbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType, unitSymbol.getName()) << "\"\n"; + } else { + infoSink.info << " " << StageName(getStage()) << " stage: " << symbol.getName() << " \"" + << symbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType) << "\"\n"; + infoSink.info << " " << StageName(unitStage) << " stage: " << unitSymbol.getName() << " \"" + << unitSymbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType) << "\"\n"; + } + } } #endif } diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index a658c09c..c4d80159 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -291,6 +291,7 @@ public: numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false), invertY(false), dxPositionW(false), + enhancedMsgs(false), useStorageBuffer(false), invariantAll(false), nanMinMaxClamp(false), @@ -469,12 +470,18 @@ public: void setDxPositionW(bool dxPosW) { - dxPositionW = dxPosW; - if (dxPositionW) - processes.addProcess("dx-position-w"); + dxPositionW = dxPosW; + if (dxPositionW) + processes.addProcess("dx-position-w"); } bool getDxPositionW() const { return dxPositionW; } + void setEnhancedMsgs() + { + enhancedMsgs = true; + } + bool getEnhancedMsgs() const { return enhancedMsgs && source == EShSourceGlsl; } + #ifdef ENABLE_HLSL void setSource(EShSource s) { source = s; } EShSource getSource() const { return source; } @@ -1031,8 +1038,8 @@ public: protected: TIntermSymbol* addSymbol(long long Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&); - void error(TInfoSink& infoSink, const char*); - void warn(TInfoSink& infoSink, const char*); + void error(TInfoSink& infoSink, const char*, EShLanguage unitStage = EShLangCount); + void warn(TInfoSink& infoSink, const char*, EShLanguage unitStage = EShLangCount); void mergeCallGraphs(TInfoSink&, TIntermediate&); void mergeModes(TInfoSink&, TIntermediate&); void mergeTrees(TInfoSink&, TIntermediate&); @@ -1086,6 +1093,7 @@ protected: bool recursive; bool invertY; bool dxPositionW; + bool enhancedMsgs; bool useStorageBuffer; bool invariantAll; bool nanMinMaxClamp; // true if desiring min/max/clamp to favor non-NaN over NaN diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h index 3c0e2910..2e240255 100644 --- a/glslang/Public/ShaderLang.h +++ b/glslang/Public/ShaderLang.h @@ -264,6 +264,7 @@ enum EShMessages : unsigned { EShMsgHlslLegalization = (1 << 12), // enable HLSL Legalization messages EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (for samplers and semantics) EShMsgBuiltinSymbolTable = (1 << 14), // print the builtin symbol table + EShMsgEnhanced = (1 << 15), // enhanced message readability LAST_ELEMENT_MARKER(EShMsgCount), }; @@ -488,6 +489,7 @@ public: GLSLANG_EXPORT void setUniformLocationBase(int base); GLSLANG_EXPORT void setInvertY(bool invert); GLSLANG_EXPORT void setDxPositionW(bool dxPosW); + GLSLANG_EXPORT void setEnhancedMsgs(); #ifdef ENABLE_HLSL GLSLANG_EXPORT void setHlslIoMapping(bool hlslIoMap); GLSLANG_EXPORT void setFlattenUniformArrays(bool flatten);