From 4e064eef4619b0b1e17aca78c52fcfca83ad937d Mon Sep 17 00:00:00 2001 From: greg-lunarg Date: Mon, 15 Mar 2021 11:26:11 -0600 Subject: Revert "Revert "GL_ext_vulkan_glsl_relaxed extension support, and cross stage aware IO mapper"" --- SPIRV/GlslangToSpv.cpp | 3 + StandAlone/StandAlone.cpp | 174 +++++ Test/baseResults/iomap.crossStage.2.vert.out | 787 ++++++++++++++++++++++ Test/baseResults/iomap.crossStage.vert.out | 515 +++++++++++++++ Test/baseResults/iomap.crossStage.vk.vert.out | 720 +++++++++++++++++++++ Test/baseResults/vk.relaxed.errorcheck.vert.out | 124 ++++ Test/baseResults/vk.relaxed.frag.out | 826 ++++++++++++++++++++++++ Test/baseResults/vk.relaxed.link1.frag.out | 515 +++++++++++++++ Test/baseResults/vk.relaxed.stagelink.vert.out | 717 ++++++++++++++++++++ Test/iomap.crossStage.2.frag | 42 ++ Test/iomap.crossStage.2.geom | 39 ++ Test/iomap.crossStage.2.vert | 38 ++ Test/iomap.crossStage.frag | 41 ++ Test/iomap.crossStage.vert | 38 ++ Test/iomap.crossStage.vk.frag | 50 ++ Test/iomap.crossStage.vk.geom | 35 + Test/iomap.crossStage.vk.vert | 32 + Test/vk.relaxed.errorcheck.frag | 16 + Test/vk.relaxed.errorcheck.vert | 15 + Test/vk.relaxed.frag | 74 +++ Test/vk.relaxed.link1.frag | 28 + Test/vk.relaxed.link2.frag | 19 + Test/vk.relaxed.stagelink.frag | 28 + Test/vk.relaxed.stagelink.vert | 31 + glslang/Include/Types.h | 44 ++ glslang/Include/intermediate.h | 3 + glslang/MachineIndependent/Initialize.cpp | 86 ++- glslang/MachineIndependent/ParseContextBase.cpp | 63 +- glslang/MachineIndependent/ParseHelper.cpp | 300 ++++++++- glslang/MachineIndependent/ParseHelper.h | 43 +- glslang/MachineIndependent/ShaderLang.cpp | 83 ++- glslang/MachineIndependent/Versions.cpp | 2 +- glslang/MachineIndependent/Versions.h | 3 +- glslang/MachineIndependent/intermOut.cpp | 1 + glslang/MachineIndependent/iomapper.cpp | 184 ++++-- glslang/MachineIndependent/iomapper.h | 41 +- glslang/MachineIndependent/linkValidate.cpp | 364 ++++++++++- glslang/MachineIndependent/localintermediate.h | 53 +- glslang/Public/ShaderLang.h | 23 +- gtests/CMakeLists.txt | 4 +- gtests/GlslMapIO.FromFile.cpp | 306 +++++++++ gtests/Link.FromFile.Vk.cpp | 12 +- gtests/VkRelaxed.FromFile.cpp | 296 +++++++++ 43 files changed, 6707 insertions(+), 111 deletions(-) create mode 100644 Test/baseResults/iomap.crossStage.2.vert.out create mode 100644 Test/baseResults/iomap.crossStage.vert.out create mode 100644 Test/baseResults/iomap.crossStage.vk.vert.out create mode 100644 Test/baseResults/vk.relaxed.errorcheck.vert.out create mode 100644 Test/baseResults/vk.relaxed.frag.out create mode 100644 Test/baseResults/vk.relaxed.link1.frag.out create mode 100644 Test/baseResults/vk.relaxed.stagelink.vert.out create mode 100644 Test/iomap.crossStage.2.frag create mode 100644 Test/iomap.crossStage.2.geom create mode 100644 Test/iomap.crossStage.2.vert create mode 100644 Test/iomap.crossStage.frag create mode 100644 Test/iomap.crossStage.vert create mode 100644 Test/iomap.crossStage.vk.frag create mode 100644 Test/iomap.crossStage.vk.geom create mode 100644 Test/iomap.crossStage.vk.vert create mode 100644 Test/vk.relaxed.errorcheck.frag create mode 100644 Test/vk.relaxed.errorcheck.vert create mode 100644 Test/vk.relaxed.frag create mode 100644 Test/vk.relaxed.link1.frag create mode 100644 Test/vk.relaxed.link2.frag create mode 100644 Test/vk.relaxed.stagelink.frag create mode 100644 Test/vk.relaxed.stagelink.vert create mode 100644 gtests/GlslMapIO.FromFile.cpp create mode 100644 gtests/VkRelaxed.FromFile.cpp diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 8eb06b7c..6d9c7cfe 100644 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -2784,6 +2784,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt break; case glslang::EOpAtomicAdd: + case glslang::EOpAtomicSubtract: case glslang::EOpAtomicMin: case glslang::EOpAtomicMax: case glslang::EOpAtomicAnd: @@ -2955,6 +2956,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt break; case glslang::EOpAtomicAdd: + case glslang::EOpAtomicSubtract: case glslang::EOpAtomicMin: case glslang::EOpAtomicMax: case glslang::EOpAtomicAnd: @@ -6894,6 +6896,7 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv builder.addCapability(spv::CapabilityAtomicFloat64AddEXT); } break; + case glslang::EOpAtomicSubtract: case glslang::EOpAtomicCounterSubtract: opCode = spv::OpAtomicISub; break; diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index fdbf0279..923ded30 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -110,6 +110,7 @@ bool SpvToolsValidate = false; bool NaNClamp = false; bool stripDebugInfo = false; bool beQuiet = false; +bool VulkanRulesRelaxed = false; // // Return codes from main/exit(). @@ -195,6 +196,17 @@ std::array, glslang::EResCount> baseBindi std::array, glslang::EResCount> baseBindingForSet; std::array, EShLangCount> baseResourceSetBinding; +std::vector> blockStorageOverrides; + +bool setGlobalUniformBlock = false; +std::string globalUniformName; +unsigned int globalUniformBinding; +unsigned int globalUniformSet; + +bool setGlobalBufferBlock = false; +std::string atomicCounterBlockName; +unsigned int atomicCounterBlockSet; + // Add things like "#define ..." to a preamble to use in the beginning of the shader. class TPreamble { public: @@ -396,6 +408,115 @@ void ProcessResourceSetBindingBase(int& argc, char**& argv, std::array>& storage) +{ + if (argc < 3) + usage(); + + glslang::TBlockStorageClass blockStorage = glslang::EbsNone; + + std::string strBacking(argv[2]); + if (strBacking == "uniform") + blockStorage = glslang::EbsUniform; + else if (strBacking == "buffer") + blockStorage = glslang::EbsStorageBuffer; + else if (strBacking == "push_constant") + blockStorage = glslang::EbsPushConstant; + else { + printf("%s: invalid block storage\n", strBacking.c_str()); + usage(); + } + + storage.push_back(std::make_pair(std::string(argv[1]), blockStorage)); + + argc -= 2; + argv += 2; +} + +inline bool isNonDigit(char c) { + // a non-digit character valid in a glsl identifier + return (c == '_') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); +} + +// whether string isa valid identifier to be used in glsl +bool isValidIdentifier(const char* str) { + std::string idn(str); + + if (idn.length() == 0) { + return false; + } + + if (idn.length() >= 3 && idn.substr(0, 3) == "gl_") { + // identifiers startin with "gl_" are reserved + return false; + } + + if (!isNonDigit(idn[0])) { + return false; + } + + for (unsigned int i = 1; i < idn.length(); ++i) { + if (!(isdigit(idn[i]) || isNonDigit(idn[i]))) { + return false; + } + } + + return true; +} + +// Process settings for either the global buffer block or global unfirom block +// of the form: +// --argname name set binding +void ProcessGlobalBlockSettings(int& argc, char**& argv, std::string* name, unsigned int* set, unsigned int* binding) +{ + if (argc < 4) + usage(); + + unsigned int curArg = 1; + + assert(name || set || binding); + + if (name) { + if (!isValidIdentifier(argv[curArg])) { + printf("%s: invalid identifier\n", argv[curArg]); + usage(); + } + *name = argv[curArg]; + + curArg++; + } + + if (set) { + errno = 0; + int setVal = ::strtol(argv[curArg], NULL, 10); + if (errno || setVal < 0) { + printf("%s: invalid set\n", argv[curArg]); + usage(); + } + *set = setVal; + + curArg++; + } + + if (binding) { + errno = 0; + int bindingVal = ::strtol(argv[curArg], NULL, 10); + if (errno || bindingVal < 0) { + printf("%s: invalid binding\n", argv[curArg]); + usage(); + } + *binding = bindingVal; + + curArg++; + } + + argc -= (curArg - 1); + argv += (curArg - 1); +} + // // Do all command-line argument parsing. This includes building up the work-items // to be processed later, and saving all the command-line options. @@ -569,6 +690,17 @@ void ProcessArguments(std::vector>& workItem lowerword == "resource-set-binding" || lowerword == "rsb") { ProcessResourceSetBindingBase(argc, argv, baseResourceSetBinding); + } else if (lowerword == "set-block-storage" || + lowerword == "sbs") { + ProcessBlockStorage(argc, argv, blockStorageOverrides); + } else if (lowerword == "set-atomic-counter-block" || + lowerword == "sacb") { + ProcessGlobalBlockSettings(argc, argv, &atomicCounterBlockName, &atomicCounterBlockSet, nullptr); + setGlobalBufferBlock = true; + } else if (lowerword == "set-default-uniform-block" || + lowerword == "sdub") { + ProcessGlobalBlockSettings(argc, argv, &globalUniformName, &globalUniformSet, &globalUniformBinding); + setGlobalUniformBlock = true; } else if (lowerword == "shift-image-bindings" || // synonyms lowerword == "shift-image-binding" || lowerword == "sib") { @@ -721,6 +853,9 @@ void ProcessArguments(std::vector>& workItem else Error("unknown -O option"); break; + case 'R': + VulkanRulesRelaxed = true; + break; case 'S': if (argc <= 1) Error("no specified for -S"); @@ -1068,6 +1203,24 @@ void CompileAndLinkShaderUnits(std::vector compUnits) shader->setUniformLocationBase(uniformBase); #endif + if (VulkanRulesRelaxed) { + for (auto& storageOverride : blockStorageOverrides) { + shader->addBlockStorageOverride(storageOverride.first.c_str(), + storageOverride.second); + } + + if (setGlobalBufferBlock) { + shader->setAtomicCounterBlockName(atomicCounterBlockName.c_str()); + shader->setAtomicCounterBlockSet(atomicCounterBlockSet); + } + + if (setGlobalUniformBlock) { + shader->setGlobalUniformBlockName(globalUniformName.c_str()); + shader->setGlobalUniformSet(globalUniformSet); + shader->setGlobalUniformBinding(globalUniformBinding); + } + } + shader->setNanMinMaxClamp(NaNClamp); #ifdef ENABLE_HLSL @@ -1091,6 +1244,8 @@ void CompileAndLinkShaderUnits(std::vector compUnits) if (targetHlslFunctionality1) shader->setEnvTargetHlslFunctionality1(); #endif + if (VulkanRulesRelaxed) + shader->setEnvInputVulkanRulesRelaxed(); } shaders.push_back(shader); @@ -1572,6 +1727,9 @@ void usage() " is searched first, followed by left-to-right order of -I\n" " -Od disables optimization; may cause illegal SPIR-V for HLSL\n" " -Os optimizes SPIR-V to minimize size\n" + " -R use relaxed verification rules for generating Vulkan SPIR-V,\n" + " allowing the use of default uniforms, atomic_uints, and\n" + " gl_VertexID and gl_InstanceID keywords.\n" " -S uses specified stage rather than parsing the file extension\n" " choices for are vert, tesc, tese, geom, frag, or comp\n" " -U | --undef-macro | --U \n" @@ -1649,6 +1807,22 @@ void usage() " --resource-set-binding [stage] set\n" " set descriptor set for all resources\n" " --rsb synonym for --resource-set-binding\n" + " --set-block-backing name {uniform|buffer|push_constant}\n" + " changes the backing type of a uniform, buffer,\n" + " or push_constant block declared in\n" + " in the program, when using -R option.\n" + " This can be used to change the backing\n" + " for existing blocks as well as implicit ones\n" + " such as 'gl_DefaultUniformBlock'.\n" + " --sbs synonym for set-block-storage\n" + " --set-atomic-counter-block name set\n" + " set name, and descriptor set for\n" + " atomic counter blocks, with -R opt\n" + " --sacb synonym for set-atomic-counter-block\n" + " --set-default-uniform-block name set binding\n" + " set name, descriptor set, and binding for\n" + " global default-uniform-block, with -R opt\n" + " --sdub synonym for set-default-uniform-block\n" " --shift-image-binding [stage] num\n" " base binding number for images (uav)\n" " --shift-image-binding [stage] [num set]...\n" diff --git a/Test/baseResults/iomap.crossStage.2.vert.out b/Test/baseResults/iomap.crossStage.2.vert.out new file mode 100644 index 00000000..325c1b46 --- /dev/null +++ b/Test/baseResults/iomap.crossStage.2.vert.out @@ -0,0 +1,787 @@ +iomap.crossStage.2.vert +Shader version: 460 +0:? Sequence +0:32 Function Definition: main( ( global void) +0:32 Function Parameters: +0:34 Sequence +0:34 move second child to first child ( temp 4-component vector of float) +0:34 'vgo1' ( smooth out 4-component vector of float) +0:34 Constant: +0:34 0.000000 +0:34 0.000000 +0:34 0.000000 +0:34 0.000000 +0:35 move second child to first child ( temp 2-component vector of float) +0:35 'vgo2' ( smooth out 2-component vector of float) +0:35 Constant: +0:35 0.000000 +0:35 0.000000 +0:36 move second child to first child ( temp 4-component vector of float) +0:36 o3: direct index for structure ( out 4-component vector of float) +0:36 'anon@0' (layout( location=5) out block{ out 4-component vector of float o3}) +0:36 Constant: +0:36 0 (const uint) +0:36 Constant: +0:36 0.000000 +0:36 0.000000 +0:36 0.000000 +0:36 0.000000 +0:? Linker Objects +0:? 'vgo1' ( smooth out 4-component vector of float) +0:? 'vgo2' ( smooth out 2-component vector of float) +0:? 'anon@0' (layout( location=5) out block{ out 4-component vector of float o3}) +0:? 'u1' ( uniform 2-component vector of float) +0:? 'u2' ( uniform 3-component vector of float) +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 'u3' ( uniform 4-component vector of float) +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 'um2' ( uniform 2X2 matrix of float) +0:? 4.000000 +0:? 0.000000 +0:? 0.000000 +0:? 4.000000 +0:? 'glass' (layout( location=0 binding=0) uniform sampler2D) +0:? 'anon@1' (layout( column_major std140) uniform block{layout( column_major std140) uniform 4-component vector of float a, layout( column_major std140) uniform 4-component vector of float b}) +0:? 'anon@2' (layout( column_major std430) buffer block{layout( column_major std430) buffer 2-component vector of float vb1}) +0:? '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}) +0:? 'gl_VertexID' ( gl_VertexId int VertexId) +0:? 'gl_InstanceID' ( gl_InstanceId int InstanceId) + +iomap.crossStage.2.geom +Shader version: 460 +invocations = -1 +max_vertices = 3 +input primitive = points +output primitive = triangle_strip +0:? Sequence +0:29 Function Definition: main( ( global void) +0:29 Function Parameters: +0:31 Sequence +0:31 Sequence +0:31 Sequence +0:31 move second child to first child ( temp int) +0:31 'i' ( temp int) +0:31 Constant: +0:31 0 (const int) +0:31 Loop with condition tested first +0:31 Loop Condition +0:31 Compare Less Than ( temp bool) +0:31 'i' ( temp int) +0:31 Constant: +0:31 3 (const int) +0:31 Loop Body +0:32 Sequence +0:32 move second child to first child ( temp 4-component vector of float) +0:32 'gfo1' (layout( stream=0) out 4-component vector of float) +0:32 Constant: +0:32 0.000000 +0:32 0.000000 +0:32 0.000000 +0:32 0.000000 +0:33 move second child to first child ( temp 2-component vector of float) +0:33 'gfo2' (layout( stream=0) out 2-component vector of float) +0:33 Constant: +0:33 0.000000 +0:33 0.000000 +0:34 move second child to first child ( temp 4-component vector of float) +0:34 o3: direct index for structure (layout( stream=0) out 4-component vector of float) +0:34 'gf_out' (layout( location=5 stream=0) out block{layout( stream=0) out 4-component vector of float o3}) +0:34 Constant: +0:34 0 (const int) +0:34 o3: direct index for structure ( in 4-component vector of float) +0:34 indirect index (layout( location=5) temp block{ in 4-component vector of float o3}) +0:34 'inBlock' (layout( location=5) in 1-element array of block{ in 4-component vector of float o3}) +0:34 'i' ( temp int) +0:34 Constant: +0:34 0 (const int) +0:35 EmitVertex ( global void) +0:31 Loop Terminal Expression +0:31 Post-Increment ( temp int) +0:31 'i' ( temp int) +0:37 EndPrimitive ( global void) +0:? Linker Objects +0:? 'vgo1' ( in 1-element array of 4-component vector of float) +0:? 'vgo2' ( in 1-element array of 2-component vector of float) +0:? 'inBlock' (layout( location=5) in 1-element array of block{ in 4-component vector of float o3}) +0:? 'gfo1' (layout( stream=0) out 4-component vector of float) +0:? 'gfo2' (layout( stream=0) out 2-component vector of float) +0:? 'gf_out' (layout( location=5 stream=0) out block{layout( stream=0) out 4-component vector of float o3}) +0:? 'u1' ( uniform 2-component vector of float) +0:? 'u2' ( uniform 3-component vector of float) +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 'u3' ( uniform 4-component vector of float) +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? '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}) + +iomap.crossStage.2.frag +Shader version: 460 +0:? Sequence +0:37 Function Definition: main( ( global void) +0:37 Function Parameters: +0:39 Sequence +0:39 Sequence +0:39 move second child to first child ( temp 4-component vector of float) +0:39 'color' ( temp 4-component vector of float) +0:39 component-wise multiply ( temp 4-component vector of float) +0:39 component-wise multiply ( temp 4-component vector of float) +0:39 component-wise multiply ( temp 4-component vector of float) +0:39 'gfo1' ( smooth in 4-component vector of float) +0:39 vector swizzle ( temp 4-component vector of float) +0:39 'u1' ( uniform 2-component vector of float) +0:39 Sequence +0:39 Constant: +0:39 0 (const int) +0:39 Constant: +0:39 1 (const int) +0:39 Constant: +0:39 0 (const int) +0:39 Constant: +0:39 1 (const int) +0:39 vector swizzle ( temp 4-component vector of float) +0:39 'u2' ( uniform 3-component vector of float) +0:39 Sequence +0:39 Constant: +0:39 0 (const int) +0:39 Constant: +0:39 1 (const int) +0:39 Constant: +0:39 2 (const int) +0:39 Constant: +0:39 0 (const int) +0:39 vector swizzle ( temp 4-component vector of float) +0:39 'u3' ( uniform 4-component vector of float) +0:39 0.000000 +0:39 0.000000 +0:39 0.000000 +0:39 0.000000 +0:39 Sequence +0:39 Constant: +0:39 0 (const int) +0:39 Constant: +0:39 1 (const int) +0:39 Constant: +0:39 2 (const int) +0:39 Constant: +0:39 3 (const int) +0:40 move second child to first child ( temp 4-component vector of float) +0:40 'outColor' ( out 4-component vector of float) +0:40 'color' ( temp 4-component vector of float) +0:? Linker Objects +0:? 'anon@0' (layout( location=5) in block{ in 4-component vector of float o3}) +0:? 'gfo1' ( smooth in 4-component vector of float) +0:? 'gfo2' ( smooth in 2-component vector of float) +0:? 'outColor' ( out 4-component vector of float) +0:? 'u1' ( uniform 2-component vector of float) +0:? 'u2' ( uniform 3-component vector of float) +0:? 'u3' ( uniform 4-component vector of float) +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 'um2' ( uniform 2X2 matrix of float) +0:? 4.000000 +0:? 0.000000 +0:? 0.000000 +0:? 4.000000 +0:? 'glass' (layout( location=0 binding=0) uniform sampler2D) +0:? 'anon@1' (layout( column_major std140) uniform block{layout( column_major std140) uniform 4-component vector of float a, layout( column_major std140) uniform 4-component vector of float b}) +0:? 'anon@2' (layout( column_major std430) buffer block{layout( column_major std430) buffer 2-component vector of float fb1}) +0:? '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}) + + +Linked vertex stage: + + +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}" + +Shader version: 460 +0:? Sequence +0:32 Function Definition: main( ( global void) +0:32 Function Parameters: +0:34 Sequence +0:34 move second child to first child ( temp 4-component vector of float) +0:34 'vgo1' ( smooth out 4-component vector of float) +0:34 Constant: +0:34 0.000000 +0:34 0.000000 +0:34 0.000000 +0:34 0.000000 +0:35 move second child to first child ( temp 2-component vector of float) +0:35 'vgo2' ( smooth out 2-component vector of float) +0:35 Constant: +0:35 0.000000 +0:35 0.000000 +0:36 move second child to first child ( temp 4-component vector of float) +0:36 o3: direct index for structure ( out 4-component vector of float) +0:36 'anon@0' (layout( location=5) out block{ out 4-component vector of float o3}) +0:36 Constant: +0:36 0 (const uint) +0:36 Constant: +0:36 0.000000 +0:36 0.000000 +0:36 0.000000 +0:36 0.000000 +0:? Linker Objects +0:? 'vgo1' ( smooth out 4-component vector of float) +0:? 'vgo2' ( smooth out 2-component vector of float) +0:? 'anon@0' (layout( location=5) out block{ out 4-component vector of float o3}) +0:? 'u1' ( uniform 2-component vector of float) +0:? 'u2' ( uniform 3-component vector of float) +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 'u3' ( uniform 4-component vector of float) +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 'um2' ( uniform 2X2 matrix of float) +0:? 4.000000 +0:? 0.000000 +0:? 0.000000 +0:? 4.000000 +0:? 'glass' (layout( location=0 binding=0) uniform sampler2D) +0:? 'anon@1' (layout( column_major std140) uniform block{layout( column_major std140) uniform 4-component vector of float a, layout( column_major std140) uniform 4-component vector of float b}) +0:? 'anon@2' (layout( column_major std430) buffer block{layout( column_major std430) buffer 2-component vector of float vb1}) +0:? '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}) +0:? 'gl_VertexID' ( gl_VertexId int VertexId) +0:? 'gl_InstanceID' ( gl_InstanceId int InstanceId) +Shader version: 460 +invocations = 1 +max_vertices = 3 +input primitive = points +output primitive = triangle_strip +0:? Sequence +0:29 Function Definition: main( ( global void) +0:29 Function Parameters: +0:31 Sequence +0:31 Sequence +0:31 Sequence +0:31 move second child to first child ( temp int) +0:31 'i' ( temp int) +0:31 Constant: +0:31 0 (const int) +0:31 Loop with condition tested first +0:31 Loop Condition +0:31 Compare Less Than ( temp bool) +0:31 'i' ( temp int) +0:31 Constant: +0:31 3 (const int) +0:31 Loop Body +0:32 Sequence +0:32 move second child to first child ( temp 4-component vector of float) +0:32 'gfo1' (layout( stream=0) out 4-component vector of float) +0:32 Constant: +0:32 0.000000 +0:32 0.000000 +0:32 0.000000 +0:32 0.000000 +0:33 move second child to first child ( temp 2-component vector of float) +0:33 'gfo2' (layout( stream=0) out 2-component vector of float) +0:33 Constant: +0:33 0.000000 +0:33 0.000000 +0:34 move second child to first child ( temp 4-component vector of float) +0:34 o3: direct index for structure (layout( stream=0) out 4-component vector of float) +0:34 'gf_out' (layout( location=5 stream=0) out block{layout( stream=0) out 4-component vector of float o3}) +0:34 Constant: +0:34 0 (const int) +0:34 o3: direct index for structure ( in 4-component vector of float) +0:34 indirect index (layout( location=5) temp block{ in 4-component vector of float o3}) +0:34 'inBlock' (layout( location=5) in 1-element array of block{ in 4-component vector of float o3}) +0:34 'i' ( temp int) +0:34 Constant: +0:34 0 (const int) +0:35 EmitVertex ( global void) +0:31 Loop Terminal Expression +0:31 Post-Increment ( temp int) +0:31 'i' ( temp int) +0:37 EndPrimitive ( global void) +0:? Linker Objects +0:? 'vgo1' ( in 1-element array of 4-component vector of float) +0:? 'vgo2' ( in 1-element array of 2-component vector of float) +0:? 'inBlock' (layout( location=5) in 1-element array of block{ in 4-component vector of float o3}) +0:? 'gfo1' (layout( stream=0) out 4-component vector of float) +0:? 'gfo2' (layout( stream=0) out 2-component vector of float) +0:? 'gf_out' (layout( location=5 stream=0) out block{layout( stream=0) out 4-component vector of float o3}) +0:? 'u1' ( uniform 2-component vector of float) +0:? 'u2' ( uniform 3-component vector of float) +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 'u3' ( uniform 4-component vector of float) +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? '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}) +Shader version: 460 +0:? Sequence +0:37 Function Definition: main( ( global void) +0:37 Function Parameters: +0:39 Sequence +0:39 Sequence +0:39 move second child to first child ( temp 4-component vector of float) +0:39 'color' ( temp 4-component vector of float) +0:39 component-wise multiply ( temp 4-component vector of float) +0:39 component-wise multiply ( temp 4-component vector of float) +0:39 component-wise multiply ( temp 4-component vector of float) +0:39 'gfo1' ( smooth in 4-component vector of float) +0:39 vector swizzle ( temp 4-component vector of float) +0:39 'u1' ( uniform 2-component vector of float) +0:39 Sequence +0:39 Constant: +0:39 0 (const int) +0:39 Constant: +0:39 1 (const int) +0:39 Constant: +0:39 0 (const int) +0:39 Constant: +0:39 1 (const int) +0:39 vector swizzle ( temp 4-component vector of float) +0:39 'u2' ( uniform 3-component vector of float) +0:39 Sequence +0:39 Constant: +0:39 0 (const int) +0:39 Constant: +0:39 1 (const int) +0:39 Constant: +0:39 2 (const int) +0:39 Constant: +0:39 0 (const int) +0:39 vector swizzle ( temp 4-component vector of float) +0:39 'u3' ( uniform 4-component vector of float) +0:39 0.000000 +0:39 0.000000 +0:39 0.000000 +0:39 0.000000 +0:39 Sequence +0:39 Constant: +0:39 0 (const int) +0:39 Constant: +0:39 1 (const int) +0:39 Constant: +0:39 2 (const int) +0:39 Constant: +0:39 3 (const int) +0:40 move second child to first child ( temp 4-component vector of float) +0:40 'outColor' ( out 4-component vector of float) +0:40 'color' ( temp 4-component vector of float) +0:? Linker Objects +0:? 'anon@0' (layout( location=5) in block{ in 4-component vector of float o3}) +0:? 'gfo1' ( smooth in 4-component vector of float) +0:? 'gfo2' ( smooth in 2-component vector of float) +0:? 'outColor' ( out 4-component vector of float) +0:? 'u1' ( uniform 2-component vector of float) +0:? 'u2' ( uniform 3-component vector of float) +0:? 'u3' ( uniform 4-component vector of float) +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 'um2' ( uniform 2X2 matrix of float) +0:? 4.000000 +0:? 0.000000 +0:? 0.000000 +0:? 4.000000 +0:? 'glass' (layout( location=0 binding=0) uniform sampler2D) +0:? 'anon@1' (layout( column_major std140) uniform block{layout( column_major std140) uniform 4-component vector of float a, layout( column_major std140) uniform 4-component vector of float b}) +0:? 'anon@2' (layout( column_major std430) buffer block{layout( column_major std430) buffer 2-component vector of float fb1}) +0:? '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}) + +// Module Version 10000 +// Generated by (magic number): 8000a +// Id's are bound by 56 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Vertex 4 "main" 9 14 18 54 55 + Source GLSL 460 + Name 4 "main" + Name 9 "vgo1" + Name 14 "vgo2" + Name 16 "outBlock" + MemberName 16(outBlock) 0 "o3" + Name 18 "" + Name 23 "u1" + Name 27 "u2" + Name 29 "u3" + Name 36 "um2" + Name 40 "glass" + Name 41 "crossStageBlock1" + MemberName 41(crossStageBlock1) 0 "a" + MemberName 41(crossStageBlock1) 1 "b" + Name 43 "" + Name 44 "vertOnlyBlock" + MemberName 44(vertOnlyBlock) 0 "vb1" + Name 46 "" + Name 47 "crossStageBlock2" + MemberName 47(crossStageBlock2) 0 "a" + MemberName 47(crossStageBlock2) 1 "b" + Name 52 "blockName1" + Name 54 "gl_VertexID" + Name 55 "gl_InstanceID" + Decorate 9(vgo1) Location 0 + Decorate 14(vgo2) Location 1 + Decorate 16(outBlock) Block + Decorate 18 Location 5 + Decorate 23(u1) Location 1 + Decorate 23(u1) DescriptorSet 0 + Decorate 27(u2) Location 2 + Decorate 27(u2) DescriptorSet 0 + Decorate 29(u3) Location 3 + Decorate 29(u3) DescriptorSet 0 + Decorate 36(um2) Location 4 + Decorate 36(um2) DescriptorSet 0 + Decorate 40(glass) Location 0 + Decorate 40(glass) DescriptorSet 0 + Decorate 40(glass) Binding 0 + MemberDecorate 41(crossStageBlock1) 0 Offset 0 + MemberDecorate 41(crossStageBlock1) 1 Offset 16 + Decorate 41(crossStageBlock1) Block + Decorate 43 DescriptorSet 0 + Decorate 43 Binding 0 + MemberDecorate 44(vertOnlyBlock) 0 Offset 0 + Decorate 44(vertOnlyBlock) BufferBlock + Decorate 46 DescriptorSet 0 + Decorate 46 Binding 0 + MemberDecorate 47(crossStageBlock2) 0 Offset 0 + MemberDecorate 47(crossStageBlock2) 1 Offset 16 + Decorate 47(crossStageBlock2) Block + Decorate 52(blockName1) DescriptorSet 0 + Decorate 52(blockName1) Binding 0 + Decorate 54(gl_VertexID) BuiltIn VertexId + Decorate 55(gl_InstanceID) BuiltIn InstanceId + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8: TypePointer Output 7(fvec4) + 9(vgo1): 8(ptr) Variable Output + 10: 6(float) Constant 0 + 11: 7(fvec4) ConstantComposite 10 10 10 10 + 12: TypeVector 6(float) 2 + 13: TypePointer Output 12(fvec2) + 14(vgo2): 13(ptr) Variable Output + 15: 12(fvec2) ConstantComposite 10 10 + 16(outBlock): TypeStruct 7(fvec4) + 17: TypePointer Output 16(outBlock) + 18: 17(ptr) Variable Output + 19: TypeInt 32 1 + 20: 19(int) Constant 0 + 22: TypePointer UniformConstant 12(fvec2) + 23(u1): 22(ptr) Variable UniformConstant + 24: TypeVector 6(float) 3 + 25: 24(fvec3) ConstantComposite 10 10 10 + 26: TypePointer UniformConstant 24(fvec3) + 27(u2): 26(ptr) Variable UniformConstant 25 + 28: TypePointer UniformConstant 7(fvec4) + 29(u3): 28(ptr) Variable UniformConstant 11 + 30: TypeMatrix 12(fvec2) 2 + 31: 6(float) Constant 1082130432 + 32: 12(fvec2) ConstantComposite 31 10 + 33: 12(fvec2) ConstantComposite 10 31 + 34: 30 ConstantComposite 32 33 + 35: TypePointer UniformConstant 30 + 36(um2): 35(ptr) Variable UniformConstant 34 + 37: TypeImage 6(float) 2D sampled format:Unknown + 38: TypeSampledImage 37 + 39: TypePointer UniformConstant 38 + 40(glass): 39(ptr) Variable UniformConstant +41(crossStageBlock1): TypeStruct 7(fvec4) 7(fvec4) + 42: TypePointer Uniform 41(crossStageBlock1) + 43: 42(ptr) Variable Uniform +44(vertOnlyBlock): TypeStruct 12(fvec2) + 45: TypePointer Uniform 44(vertOnlyBlock) + 46: 45(ptr) Variable Uniform +47(crossStageBlock2): TypeStruct 7(fvec4) 12(fvec2) + 48: TypeInt 32 0 + 49: 48(int) Constant 2 + 50: TypeArray 47(crossStageBlock2) 49 + 51: TypePointer Uniform 50 + 52(blockName1): 51(ptr) Variable Uniform + 53: TypePointer Input 19(int) + 54(gl_VertexID): 53(ptr) Variable Input +55(gl_InstanceID): 53(ptr) Variable Input + 4(main): 2 Function None 3 + 5: Label + Store 9(vgo1) 11 + Store 14(vgo2) 15 + 21: 8(ptr) AccessChain 18 20 + Store 21 11 + Return + FunctionEnd +// Module Version 10000 +// Generated by (magic number): 8000a +// Id's are bound by 65 + + Capability Geometry + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Geometry 4 "main" 22 27 31 37 48 51 + ExecutionMode 4 InputPoints + ExecutionMode 4 Invocations 1 + ExecutionMode 4 OutputTriangleStrip + ExecutionMode 4 OutputVertices 3 + Source GLSL 460 + Name 4 "main" + Name 8 "i" + Name 22 "gfo1" + Name 27 "gfo2" + Name 29 "outBlock" + MemberName 29(outBlock) 0 "o3" + Name 31 "gf_out" + Name 32 "outBlock" + MemberName 32(outBlock) 0 "o3" + Name 37 "inBlock" + Name 48 "vgo1" + Name 51 "vgo2" + Name 53 "u1" + Name 57 "u2" + Name 59 "u3" + Name 60 "crossStageBlock2" + MemberName 60(crossStageBlock2) 0 "a" + MemberName 60(crossStageBlock2) 1 "b" + Name 64 "blockName1" + Decorate 22(gfo1) Location 0 + Decorate 27(gfo2) Location 1 + Decorate 29(outBlock) Block + Decorate 31(gf_out) Location 5 + Decorate 32(outBlock) Block + Decorate 37(inBlock) Location 5 + Decorate 48(vgo1) Location 0 + Decorate 51(vgo2) Location 1 + Decorate 53(u1) Location 1 + Decorate 53(u1) DescriptorSet 0 + Decorate 57(u2) Location 2 + Decorate 57(u2) DescriptorSet 0 + Decorate 59(u3) Location 3 + Decorate 59(u3) DescriptorSet 0 + MemberDecorate 60(crossStageBlock2) 0 Offset 0 + MemberDecorate 60(crossStageBlock2) 1 Offset 16 + Decorate 60(crossStageBlock2) Block + Decorate 64(blockName1) DescriptorSet 0 + Decorate 64(blockName1) Binding 0 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeInt 32 1 + 7: TypePointer Function 6(int) + 9: 6(int) Constant 0 + 16: 6(int) Constant 3 + 17: TypeBool + 19: TypeFloat 32 + 20: TypeVector 19(float) 4 + 21: TypePointer Output 20(fvec4) + 22(gfo1): 21(ptr) Variable Output + 23: 19(float) Constant 0 + 24: 20(fvec4) ConstantComposite 23 23 23 23 + 25: TypeVector 19(float) 2 + 26: TypePointer Output 25(fvec2) + 27(gfo2): 26(ptr) Variable Output + 28: 25(fvec2) ConstantComposite 23 23 + 29(outBlock): TypeStruct 20(fvec4) + 30: TypePointer Output 29(outBlock) + 31(gf_out): 30(ptr) Variable Output + 32(outBlock): TypeStruct 20(fvec4) + 33: TypeInt 32 0 + 34: 33(int) Constant 1 + 35: TypeArray 32(outBlock) 34 + 36: TypePointer Input 35 + 37(inBlock): 36(ptr) Variable Input + 39: TypePointer Input 20(fvec4) + 44: 6(int) Constant 1 + 46: TypeArray 20(fvec4) 34 + 47: TypePointer Input 46 + 48(vgo1): 47(ptr) Variable Input + 49: TypeArray 25(fvec2) 34 + 50: TypePointer Input 49 + 51(vgo2): 50(ptr) Variable Input + 52: TypePointer UniformConstant 25(fvec2) + 53(u1): 52(ptr) Variable UniformConstant + 54: TypeVector 19(float) 3 + 55: 54(fvec3) ConstantComposite 23 23 23 + 56: TypePointer UniformConstant 54(fvec3) + 57(u2): 56(ptr) Variable UniformConstant 55 + 58: TypePointer UniformConstant 20(fvec4) + 59(u3): 58(ptr) Variable UniformConstant 24 +60(crossStageBlock2): TypeStruct 20(fvec4) 25(fvec2) + 61: 33(int) Constant 2 + 62: TypeArray 60(crossStageBlock2) 61 + 63: TypePointer Uniform 62 + 64(blockName1): 63(ptr) Variable Uniform + 4(main): 2 Function None 3 + 5: Label + 8(i): 7(ptr) Variable Function + Store 8(i) 9 + Branch 10 + 10: Label + LoopMerge 12 13 None + Branch 14 + 14: Label + 15: 6(int) Load 8(i) + 18: 17(bool) SLessThan 15 16 + BranchConditional 18 11 12 + 11: Label + Store 22(gfo1) 24 + Store 27(gfo2) 28 + 38: 6(int) Load 8(i) + 40: 39(ptr) AccessChain 37(inBlock) 38 9 + 41: 20(fvec4) Load 40 + 42: 21(ptr) AccessChain 31(gf_out) 9 + Store 42 41 + EmitVertex + Branch 13 + 13: Label + 43: 6(int) Load 8(i) + 45: 6(int) IAdd 43 44 + Store 8(i) 45 + Branch 10 + 12: Label + EndPrimitive + Return + FunctionEnd +// Module Version 10000 +// Generated by (magic number): 8000a +// Id's are bound by 62 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "main" 11 32 36 38 + ExecutionMode 4 OriginLowerLeft + Source GLSL 460 + Name 4 "main" + Name 9 "color" + Name 11 "gfo1" + Name 15 "u1" + Name 21 "u2" + Name 28 "u3" + Name 32 "outColor" + Name 34 "outBlock" + MemberName 34(outBlock) 0 "o3" + Name 36 "" + Name 38 "gfo2" + Name 45 "um2" + Name 49 "glass" + Name 50 "crossStageBlock1" + MemberName 50(crossStageBlock1) 0 "a" + MemberName 50(crossStageBlock1) 1 "b" + Name 52 "" + Name 53 "fragOnlyBlock" + MemberName 53(fragOnlyBlock) 0 "fb1" + Name 55 "" + Name 56 "crossStageBlock2" + MemberName 56(crossStageBlock2) 0 "a" + MemberName 56(crossStageBlock2) 1 "b" + Name 61 "blockName2" + Decorate 11(gfo1) Location 0 + Decorate 15(u1) Location 1 + Decorate 15(u1) DescriptorSet 0 + Decorate 21(u2) Location 2 + Decorate 21(u2) DescriptorSet 0 + Decorate 28(u3) Location 3 + Decorate 28(u3) DescriptorSet 0 + Decorate 32(outColor) Location 0 + Decorate 34(outBlock) Block + Decorate 36 Location 5 + Decorate 38(gfo2) Location 1 + Decorate 45(um2) Location 4 + Decorate 45(um2) DescriptorSet 0 + Decorate 49(glass) Location 0 + Decorate 49(glass) DescriptorSet 0 + Decorate 49(glass) Binding 0 + MemberDecorate 50(crossStageBlock1) 0 Offset 0 + MemberDecorate 50(crossStageBlock1) 1 Offset 16 + Decorate 50(crossStageBlock1) Block + Decorate 52 DescriptorSet 0 + Decorate 52 Binding 0 + MemberDecorate 53(fragOnlyBlock) 0 Offset 0 + Decorate 53(fragOnlyBlock) BufferBlock + Decorate 55 DescriptorSet 0 + Decorate 55 Binding 0 + MemberDecorate 56(crossStageBlock2) 0 Offset 0 + MemberDecorate 56(crossStageBlock2) 1 Offset 16 + Decorate 56(crossStageBlock2) Block + Decorate 61(blockName2) DescriptorSet 0 + Decorate 61(blockName2) Binding 0 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8: TypePointer Function 7(fvec4) + 10: TypePointer Input 7(fvec4) + 11(gfo1): 10(ptr) Variable Input + 13: TypeVector 6(float) 2 + 14: TypePointer UniformConstant 13(fvec2) + 15(u1): 14(ptr) Variable UniformConstant + 19: TypeVector 6(float) 3 + 20: TypePointer UniformConstant 19(fvec3) + 21(u2): 20(ptr) Variable UniformConstant + 25: 6(float) Constant 0 + 26: 7(fvec4) ConstantComposite 25 25 25 25 + 27: TypePointer UniformConstant 7(fvec4) + 28(u3): 27(ptr) Variable UniformConstant 26 + 31: TypePointer Output 7(fvec4) + 32(outColor): 31(ptr) Variable Output + 34(outBlock): TypeStruct 7(fvec4) + 35: TypePointer Input 34(outBlock) + 36: 35(ptr) Variable Input + 37: TypePointer Input 13(fvec2) + 38(gfo2): 37(ptr) Variable Input + 39: TypeMatrix 13(fvec2) 2 + 40: 6(float) Constant 1082130432 + 41: 13(fvec2) ConstantComposite 40 25 + 42: 13(fvec2) ConstantComposite 25 40 + 43: 39 ConstantComposite 41 42 + 44: TypePointer UniformConstant 39 + 45(um2): 44(ptr) Variable UniformConstant 43 + 46: TypeImage 6(float) 2D sampled format:Unknown + 47: TypeSampledImage 46 + 48: TypePointer UniformConstant 47 + 49(glass): 48(ptr) Variable UniformConstant +50(crossStageBlock1): TypeStruct 7(fvec4) 7(fvec4) + 51: TypePointer Uniform 50(crossStageBlock1) + 52: 51(ptr) Variable Uniform +53(fragOnlyBlock): TypeStruct 13(fvec2) + 54: TypePointer Uniform 53(fragOnlyBlock) + 55: 54(ptr) Variable Uniform +56(crossStageBlock2): TypeStruct 7(fvec4) 13(fvec2) + 57: TypeInt 32 0 + 58: 57(int) Constant 2 + 59: TypeArray 56(crossStageBlock2) 58 + 60: TypePointer Uniform 59 + 61(blockName2): 60(ptr) Variable Uniform + 4(main): 2 Function None 3 + 5: Label + 9(color): 8(ptr) Variable Function + 12: 7(fvec4) Load 11(gfo1) + 16: 13(fvec2) Load 15(u1) + 17: 7(fvec4) VectorShuffle 16 16 0 1 0 1 + 18: 7(fvec4) FMul 12 17 + 22: 19(fvec3) Load 21(u2) + 23: 7(fvec4) VectorShuffle 22 22 0 1 2 0 + 24: 7(fvec4) FMul 18 23 + 29: 7(fvec4) Load 28(u3) + 30: 7(fvec4) FMul 24 29 + Store 9(color) 30 + 33: 7(fvec4) Load 9(color) + Store 32(outColor) 33 + Return + FunctionEnd diff --git a/Test/baseResults/iomap.crossStage.vert.out b/Test/baseResults/iomap.crossStage.vert.out new file mode 100644 index 00000000..5338b807 --- /dev/null +++ b/Test/baseResults/iomap.crossStage.vert.out @@ -0,0 +1,515 @@ +iomap.crossStage.vert +Shader version: 460 +0:? Sequence +0:32 Function Definition: main( ( global void) +0:32 Function Parameters: +0:34 Sequence +0:34 move second child to first child ( temp 4-component vector of float) +0:34 'o1' ( smooth out 4-component vector of float) +0:34 Constant: +0:34 0.000000 +0:34 0.000000 +0:34 0.000000 +0:34 0.000000 +0:35 move second child to first child ( temp 2-component vector of float) +0:35 'o2' ( smooth out 2-component vector of float) +0:35 Constant: +0:35 0.000000 +0:35 0.000000 +0:36 move second child to first child ( temp 4-component vector of float) +0:36 o3: direct index for structure ( out 4-component vector of float) +0:36 'anon@0' (layout( location=5) out block{ out 4-component vector of float o3}) +0:36 Constant: +0:36 0 (const uint) +0:36 Constant: +0:36 0.000000 +0:36 0.000000 +0:36 0.000000 +0:36 0.000000 +0:? Linker Objects +0:? 'o1' ( smooth out 4-component vector of float) +0:? 'o2' ( smooth out 2-component vector of float) +0:? 'anon@0' (layout( location=5) out block{ out 4-component vector of float o3}) +0:? 'u1' ( uniform 2-component vector of float) +0:? 'u2' ( uniform 3-component vector of float) +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 'u3' ( uniform 4-component vector of float) +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 'um2' ( uniform 2X2 matrix of float) +0:? 4.000000 +0:? 0.000000 +0:? 0.000000 +0:? 4.000000 +0:? 'glass' (layout( location=0 binding=0) uniform sampler2D) +0:? 'anon@1' (layout( column_major std140) uniform block{layout( column_major std140) uniform 4-component vector of float a, layout( column_major std140) uniform 4-component vector of float b}) +0:? 'anon@2' (layout( column_major std430) buffer block{layout( column_major std430) buffer 2-component vector of float vb1}) +0:? '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}) +0:? 'gl_VertexID' ( gl_VertexId int VertexId) +0:? 'gl_InstanceID' ( gl_InstanceId int InstanceId) + +iomap.crossStage.frag +Shader version: 460 +0:? Sequence +0:36 Function Definition: main( ( global void) +0:36 Function Parameters: +0:38 Sequence +0:38 Sequence +0:38 move second child to first child ( temp 4-component vector of float) +0:38 'color' ( temp 4-component vector of float) +0:38 component-wise multiply ( temp 4-component vector of float) +0:38 component-wise multiply ( temp 4-component vector of float) +0:38 component-wise multiply ( temp 4-component vector of float) +0:38 'o1' ( smooth in 4-component vector of float) +0:38 vector swizzle ( temp 4-component vector of float) +0:38 'u1' ( uniform 2-component vector of float) +0:38 Sequence +0:38 Constant: +0:38 0 (const int) +0:38 Constant: +0:38 1 (const int) +0:38 Constant: +0:38 0 (const int) +0:38 Constant: +0:38 1 (const int) +0:38 vector swizzle ( temp 4-component vector of float) +0:38 'u2' ( uniform 3-component vector of float) +0:38 Sequence +0:38 Constant: +0:38 0 (const int) +0:38 Constant: +0:38 1 (const int) +0:38 Constant: +0:38 2 (const int) +0:38 Constant: +0:38 0 (const int) +0:38 vector swizzle ( temp 4-component vector of float) +0:38 'u3' ( uniform 4-component vector of float) +0:38 0.000000 +0:38 0.000000 +0:38 0.000000 +0:38 0.000000 +0:38 Sequence +0:38 Constant: +0:38 0 (const int) +0:38 Constant: +0:38 1 (const int) +0:38 Constant: +0:38 2 (const int) +0:38 Constant: +0:38 3 (const int) +0:39 move second child to first child ( temp 4-component vector of float) +0:39 'outColor' ( out 4-component vector of float) +0:39 'color' ( temp 4-component vector of float) +0:? Linker Objects +0:? 'anon@0' (layout( location=5) in block{ in 4-component vector of float o3}) +0:? 'o2' ( smooth in 2-component vector of float) +0:? 'o1' ( smooth in 4-component vector of float) +0:? 'outColor' ( out 4-component vector of float) +0:? 'u1' ( uniform 2-component vector of float) +0:? 'u2' ( uniform 3-component vector of float) +0:? 'u3' ( uniform 4-component vector of float) +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 'um2' ( uniform 2X2 matrix of float) +0:? 4.000000 +0:? 0.000000 +0:? 0.000000 +0:? 4.000000 +0:? 'glass' (layout( location=0 binding=0) uniform sampler2D) +0:? 'anon@1' (layout( column_major std140) uniform block{layout( column_major std140) uniform 4-component vector of float a, layout( column_major std140) uniform 4-component vector of float b}) +0:? 'anon@2' (layout( column_major std430) buffer block{layout( column_major std430) buffer 2-component vector of float fb1}) +0:? '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}) + + +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}" + +Shader version: 460 +0:? Sequence +0:32 Function Definition: main( ( global void) +0:32 Function Parameters: +0:34 Sequence +0:34 move second child to first child ( temp 4-component vector of float) +0:34 'o1' ( smooth out 4-component vector of float) +0:34 Constant: +0:34 0.000000 +0:34 0.000000 +0:34 0.000000 +0:34 0.000000 +0:35 move second child to first child ( temp 2-component vector of float) +0:35 'o2' ( smooth out 2-component vector of float) +0:35 Constant: +0:35 0.000000 +0:35 0.000000 +0:36 move second child to first child ( temp 4-component vector of float) +0:36 o3: direct index for structure ( out 4-component vector of float) +0:36 'anon@0' (layout( location=5) out block{ out 4-component vector of float o3}) +0:36 Constant: +0:36 0 (const uint) +0:36 Constant: +0:36 0.000000 +0:36 0.000000 +0:36 0.000000 +0:36 0.000000 +0:? Linker Objects +0:? 'o1' ( smooth out 4-component vector of float) +0:? 'o2' ( smooth out 2-component vector of float) +0:? 'anon@0' (layout( location=5) out block{ out 4-component vector of float o3}) +0:? 'u1' ( uniform 2-component vector of float) +0:? 'u2' ( uniform 3-component vector of float) +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 'u3' ( uniform 4-component vector of float) +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 'um2' ( uniform 2X2 matrix of float) +0:? 4.000000 +0:? 0.000000 +0:? 0.000000 +0:? 4.000000 +0:? 'glass' (layout( location=0 binding=0) uniform sampler2D) +0:? 'anon@1' (layout( column_major std140) uniform block{layout( column_major std140) uniform 4-component vector of float a, layout( column_major std140) uniform 4-component vector of float b}) +0:? 'anon@2' (layout( column_major std430) buffer block{layout( column_major std430) buffer 2-component vector of float vb1}) +0:? '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}) +0:? 'gl_VertexID' ( gl_VertexId int VertexId) +0:? 'gl_InstanceID' ( gl_InstanceId int InstanceId) +Shader version: 460 +0:? Sequence +0:36 Function Definition: main( ( global void) +0:36 Function Parameters: +0:38 Sequence +0:38 Sequence +0:38 move second child to first child ( temp 4-component vector of float) +0:38 'color' ( temp 4-component vector of float) +0:38 component-wise multiply ( temp 4-component vector of float) +0:38 component-wise multiply ( temp 4-component vector of float) +0:38 component-wise multiply ( temp 4-component vector of float) +0:38 'o1' ( smooth in 4-component vector of float) +0:38 vector swizzle ( temp 4-component vector of float) +0:38 'u1' ( uniform 2-component vector of float) +0:38 Sequence +0:38 Constant: +0:38 0 (const int) +0:38 Constant: +0:38 1 (const int) +0:38 Constant: +0:38 0 (const int) +0:38 Constant: +0:38 1 (const int) +0:38 vector swizzle ( temp 4-component vector of float) +0:38 'u2' ( uniform 3-component vector of float) +0:38 Sequence +0:38 Constant: +0:38 0 (const int) +0:38 Constant: +0:38 1 (const int) +0:38 Constant: +0:38 2 (const int) +0:38 Constant: +0:38 0 (const int) +0:38 vector swizzle ( temp 4-component vector of float) +0:38 'u3' ( uniform 4-component vector of float) +0:38 0.000000 +0:38 0.000000 +0:38 0.000000 +0:38 0.000000 +0:38 Sequence +0:38 Constant: +0:38 0 (const int) +0:38 Constant: +0:38 1 (const int) +0:38 Constant: +0:38 2 (const int) +0:38 Constant: +0:38 3 (const int) +0:39 move second child to first child ( temp 4-component vector of float) +0:39 'outColor' ( out 4-component vector of float) +0:39 'color' ( temp 4-component vector of float) +0:? Linker Objects +0:? 'anon@0' (layout( location=5) in block{ in 4-component vector of float o3}) +0:? 'o2' ( smooth in 2-component vector of float) +0:? 'o1' ( smooth in 4-component vector of float) +0:? 'outColor' ( out 4-component vector of float) +0:? 'u1' ( uniform 2-component vector of float) +0:? 'u2' ( uniform 3-component vector of float) +0:? 'u3' ( uniform 4-component vector of float) +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 0.000000 +0:? 'um2' ( uniform 2X2 matrix of float) +0:? 4.000000 +0:? 0.000000 +0:? 0.000000 +0:? 4.000000 +0:? 'glass' (layout( location=0 binding=0) uniform sampler2D) +0:? 'anon@1' (layout( column_major std140) uniform block{layout( column_major std140) uniform 4-component vector of float a, layout( column_major std140) uniform 4-component vector of float b}) +0:? 'anon@2' (layout( column_major std430) buffer block{layout( column_major std430) buffer 2-component vector of float fb1}) +0:? '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}) + +// Module Version 10000 +// Generated by (magic number): 8000a +// Id's are bound by 56 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Vertex 4 "main" 9 14 18 54 55 + Source GLSL 460 + Name 4 "main" + Name 9 "o1" + Name 14 "o2" + Name 16 "outBlock" + MemberName 16(outBlock) 0 "o3" + Name 18 "" + Name 23 "u1" + Name 27 "u2" + Name 29 "u3" + Name 36 "um2" + Name 40 "glass" + Name 41 "crossStageBlock1" + MemberName 41(crossStageBlock1) 0 "a" + MemberName 41(crossStageBlock1) 1 "b" + Name 43 "" + Name 44 "vertOnlyBlock" + MemberName 44(vertOnlyBlock) 0 "vb1" + Name 46 "" + Name 47 "crossStageBlock2" + MemberName 47(crossStageBlock2) 0 "a" + MemberName 47(crossStageBlock2) 1 "b" + Name 52 "blockName1" + Name 54 "gl_VertexID" + Name 55 "gl_InstanceID" + Decorate 9(o1) Location 0 + Decorate 14(o2) Location 1 + Decorate 16(outBlock) Block + Decorate 18 Location 5 + Decorate 23(u1) Location 1 + Decorate 23(u1) DescriptorSet 0 + Decorate 27(u2) Location 2 + Decorate 27(u2) DescriptorSet 0 + Decorate 29(u3) Location 3 + Decorate 29(u3) DescriptorSet 0 + Decorate 36(um2) Location 4 + Decorate 36(um2) DescriptorSet 0 + Decorate 40(glass) Location 0 + Decorate 40(glass) DescriptorSet 0 + Decorate 40(glass) Binding 0 + MemberDecorate 41(crossStageBlock1) 0 Offset 0 + MemberDecorate 41(crossStageBlock1) 1 Offset 16 + Decorate 41(crossStageBlock1) Block + Decorate 43 DescriptorSet 0 + Decorate 43 Binding 0 + MemberDecorate 44(vertOnlyBlock) 0 Offset 0 + Decorate 44(vertOnlyBlock) BufferBlock + Decorate 46 DescriptorSet 0 + Decorate 46 Binding 0 + MemberDecorate 47(crossStageBlock2) 0 Offset 0 + MemberDecorate 47(crossStageBlock2) 1 Offset 16 + Decorate 47(crossStageBlock2) Block + Decorate 52(blockName1) DescriptorSet 0 + Decorate 52(blockName1) Binding 0 + Decorate 54(gl_VertexID) BuiltIn VertexId + Decorate 55(gl_InstanceID) BuiltIn InstanceId + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8: TypePointer Output 7(fvec4) + 9(o1): 8(ptr) Variable Output + 10: 6(float) Constant 0 + 11: 7(fvec4) ConstantComposite 10 10 10 10 + 12: TypeVector 6(float) 2 + 13: TypePointer Output 12(fvec2) + 14(o2): 13(ptr) Variable Output + 15: 12(fvec2) ConstantComposite 10 10 + 16(outBlock): TypeStruct 7(fvec4) + 17: TypePointer Output 16(outBlock) + 18: 17(ptr) Variable Output + 19: TypeInt 32 1 + 20: 19(int) Constant 0 + 22: TypePointer UniformConstant 12(fvec2) + 23(u1): 22(ptr) Variable UniformConstant + 24: TypeVector 6(float) 3 + 25: 24(fvec3) ConstantComposite 10 10 10 + 26: TypePointer UniformConstant 24(fvec3) + 27(u2): 26(ptr) Variable UniformConstant 25 + 28: TypePointer UniformConstant 7(fvec4) + 29(u3): 28(ptr) Variable UniformConstant 11 + 30: TypeMatrix 12(fvec2) 2 + 31: 6(float) Constant 1082130432 + 32: 12(fvec2) ConstantComposite 31 10 + 33: 12(fvec2) ConstantComposite 10 31 + 34: 30 ConstantComposite 32 33 + 35: TypePointer UniformConstant 30 + 36(um2): 35(ptr) Variable UniformConstant 34 + 37: TypeImage 6(float) 2D sampled format:Unknown + 38: TypeSampledImage 37 + 39: TypePointer UniformConstant 38 + 40(glass): 39(ptr) Variable UniformConstant +41(crossStageBlock1): TypeStruct 7(fvec4) 7(fvec4) + 42: TypePointer Uniform 41(crossStageBlock1) + 43: 42(ptr) Variable Uniform +44(vertOnlyBlock): TypeStruct 12(fvec2) + 45: TypePointer Uniform 44(vertOnlyBlock) + 46: 45(ptr) Variable Uniform +47(crossStageBlock2): TypeStruct 7(fvec4) 12(fvec2) + 48: TypeInt 32 0 + 49: 48(int) Constant 2 + 50: TypeArray 47(crossStageBlock2) 49 + 51: TypePointer Uniform 50 + 52(blockName1): 51(ptr) Variable Uniform + 53: TypePointer Input 19(int) + 54(gl_VertexID): 53(ptr) Variable Input +55(gl_InstanceID): 53(ptr) Variable Input + 4(main): 2 Function None 3 + 5: Label + Store 9(o1) 11 + Store 14(o2) 15 + 21: 8(ptr) AccessChain 18 20 + Store 21 11 + Return + FunctionEnd +// Module Version 10000 +// Generated by (magic number): 8000a +// Id's are bound by 62 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "main" 11 32 36 38 + ExecutionMode 4 OriginLowerLeft + Source GLSL 460 + Name 4 "main" + Name 9 "color" + Name 11 "o1" + Name 15 "u1" + Name 21 "u2" + Name 28 "u3" + Name 32 "outColor" + Name 34 "outBlock" + MemberName 34(outBlock) 0 "o3" + Name 36 "" + Name 38 "o2" + Name 45 "um2" + Name 49 "glass" + Name 50 "crossStageBlock1" + MemberName 50(crossStageBlock1) 0 "a" + MemberName 50(crossStageBlock1) 1 "b" + Name 52 "" + Name 53 "fragOnlyBlock" + MemberName 53(fragOnlyBlock) 0 "fb1" + Name 55 "" + Name 56 "crossStageBlock2" + MemberName 56(crossStageBlock2) 0 "a" + MemberName 56(crossStageBlock2) 1 "b" + Name 61 "blockName2" + Decorate 11(o1) Location 0 + Decorate 15(u1) Location 1 + Decorate 15(u1) DescriptorSet 0 + Decorate 21(u2) Location 2 + Decorate 21(u2) DescriptorSet 0 + Decorate 28(u3) Location 3 + Decorate 28(u3) DescriptorSet 0 + Decorate 32(outColor) Location 0 + Decorate 34(outBlock) Block + Decorate 36 Location 5 + Decorate 38(o2) Location 1 + Decorate 45(um2) Location 4 + Decorate 45(um2) DescriptorSet 0 + Decorate 49(glass) Location 0 + Decorate 49(glass) DescriptorSet 0 + Decorate 49(glass) Binding 0 + MemberDecorate 50(crossStageBlock1) 0 Offset 0 + MemberDecorate 50(crossStageBlock1) 1 Offset 16 + Decorate 50(crossStageBlock1) Block + Decorate 52 DescriptorSet 0 + Decorate 52 Binding 0 + MemberDecorate 53(fragOnlyBlock) 0 Offset 0 + Decorate 53(fragOnlyBlock) BufferBlock + Decorate 55 DescriptorSet 0 + Decorate 55 Binding 0 + MemberDecorate 56(crossStageBlock2) 0 Offset 0 + MemberDecorate 56(crossStageBlock2) 1 Offset 16 + Decorate 56(crossStageBlock2) Block + Decorate 61(blockName2) DescriptorSet 0 + Decorate 61(blockName2) Binding 0 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8: TypePointer Function 7(fvec4) + 10: TypePointer Input 7(fvec4) + 11(o1): 10(ptr) Variable Input + 13: TypeVector 6(float) 2 + 14: TypePointer UniformConstant 13(fvec2) + 15(u1): 14(ptr) Variable UniformConstant + 19: TypeVector 6(float) 3 + 20: TypePointer UniformConstant 19(fvec3) + 21(u2): 20(ptr) Variable UniformConstant + 25: 6(float) Constant 0 + 26: 7(fvec4) ConstantComposite 25 25 25 25 + 27: TypePointer UniformConstant 7(fvec4) + 28(u3): 27(ptr) Variable UniformConstant 26 + 31: TypePointer Output 7(fvec4) + 32(outColor): 31(ptr) Variable Output + 34(outBlock): TypeStruct 7(fvec4) + 35: TypePointer Input 34(outBlock) + 36: 35(ptr) Variable Input + 37: TypePointer Input 13(fvec2) + 38(o2): 37(ptr) Variable Input + 39: TypeMatrix 13(fvec2) 2 + 40: 6(float) Constant 1082130432 + 41: 13(fvec2) ConstantComposite 40 25 + 42: 13(fvec2) ConstantComposite 25 40 + 43: 39 ConstantComposite 41 42 + 44: TypePointer UniformConstant 39 + 45(um2): 44(ptr) Variable UniformConstant 43 + 46: TypeImage 6(float) 2D sampled format:Unknown + 47: TypeSampledImage 46 + 48: TypePointer UniformConstant 47 + 49(glass): 48(ptr) Variable UniformConstant +50(crossStageBlock1): TypeStruct 7(fvec4) 7(fvec4) + 51: TypePointer Uniform 50(crossStageBlock1) + 52: 51(ptr) Variable Uniform +53(fragOnlyBlock): TypeStruct 13(fvec2) + 54: TypePointer Uniform 53(fragOnlyBlock) + 55: 54(ptr) Variable Uniform +56(crossStageBlock2): TypeStruct 7(fvec4) 13(fvec2) + 57: TypeInt 32 0 + 58: 57(int) Constant 2 + 59: TypeArray 56(crossStageBlock2) 58 + 60: TypePointer Uniform 59 + 61(blockName2): 60(ptr) Variable Uniform + 4(main): 2 Function None 3 + 5: Label + 9(color): 8(ptr) Variable Function + 12: 7(fvec4) Load 11(o1) + 16: 13(fvec2) Load 15(u1) + 17: 7(fvec4) VectorShuffle 16 16 0 1 0 1 + 18: 7(fvec4) FMul 12 17 + 22: 19(fvec3) Load 21(u2) + 23: 7(fvec4) VectorShuffle 22 22 0 1 2 0 + 24: 7(fvec4) FMul 18 23 + 29: 7(fvec4) Load 28(u3) + 30: 7(fvec4) FMul 24 29 + Store 9(color) 30 + 33: 7(fvec4) Load 9(color) + Store 32(outColor) 33 + Return + FunctionEnd diff --git a/Test/baseResults/iomap.crossStage.vk.vert.out b/Test/baseResults/iomap.crossStage.vk.vert.out new file mode 100644 index 00000000..e137bdfc --- /dev/null +++ b/Test/baseResults/iomap.crossStage.vk.vert.out @@ -0,0 +1,720 @@ +iomap.crossStage.vk.vert +Shader version: 460 +0:? Sequence +0:26 Function Definition: main( ( global void) +0:26 Function Parameters: +0:28 Sequence +0:28 move second child to first child ( temp highp 4-component vector of float) +0:28 'vgo1' ( smooth out highp 4-component vector of float) +0:28 Constant: +0:28 0.000000 +0:28 0.000000 +0:28 0.000000 +0:28 0.000000 +0:29 move second child to first child ( temp highp 2-component vector of float) +0:29 'vgo2' ( smooth out highp 2-component vector of float) +0:29 Constant: +0:29 0.000000 +0:29 0.000000 +0:30 move second child to first child ( temp highp 4-component vector of float) +0:30 o3: direct index for structure ( out highp 4-component vector of float) +0:30 'anon@0' (layout( location=5) out block{ out highp 4-component vector of float o3}) +0:30 Constant: +0:30 0 (const uint) +0:30 Constant: +0:30 0.000000 +0:30 0.000000 +0:30 0.000000 +0:30 0.000000 +0:? Linker Objects +0:? 'vgo1' ( smooth out highp 4-component vector of float) +0:? 'vgo2' ( smooth out highp 2-component vector of float) +0:? 'anon@0' (layout( location=5) out block{ out highp 4-component vector of float o3}) +0:? 'glass' (layout( binding=0) uniform highp sampler2D) +0:? 'anon@1' (layout( column_major std140) uniform block{layout( column_major std140) uniform highp 4-component vector of float a, layout( column_major std140) uniform highp 4-component vector of float b}) +0:? 'anon@2' (layout( column_major std430) readonly buffer block{layout( column_major std430) readonly buffer highp 2-component vector of float vb1}) +0:? '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}) + +iomap.crossStage.vk.geom +Shader version: 460 +invocations = -1 +max_vertices = 3 +input primitive = points +output primitive = triangle_strip +0:? Sequence +0:25 Function Definition: main( ( global void) +0:25 Function Parameters: +0:27 Sequence +0:27 Sequence +0:27 Sequence +0:27 move second child to first child ( temp highp int) +0:27 'i' ( temp highp int) +0:27 Constant: +0:27 0 (const int) +0:27 Loop with condition tested first +0:27 Loop Condition +0:27 Compare Less Than ( temp bool) +0:27 'i' ( temp highp int) +0:27 Constant: +0:27 3 (const int) +0:27 Loop Body +0:28 Sequence +0:28 move second child to first child ( temp highp 4-component vector of float) +0:28 'gfo1' (layout( stream=0) out highp 4-component vector of float) +0:28 Constant: +0:28 0.000000 +0:28 0.000000 +0:28 0.000000 +0:28 0.000000 +0:29 move second child to first child ( temp highp 2-component vector of float) +0:29 'gfo2' (layout( stream=0) out highp 2-component vector of float) +0:29 Constant: +0:29 0.000000 +0:29 0.000000 +0:30 move second child to first child ( temp highp 4-component vector of float) +0:30 o3: direct index for structure (layout( stream=0) out highp 4-component vector of float) +0:30 'gf_out' (layout( location=5 stream=0) out block{layout( stream=0) out highp 4-component vector of float o3}) +0:30 Constant: +0:30 0 (const int) +0:30 o3: direct index for structure ( in highp 4-component vector of float) +0:30 indirect index (layout( location=5) temp block{ in highp 4-component vector of float o3}) +0:30 'inBlock' (layout( location=5) in 1-element array of block{ in highp 4-component vector of float o3}) +0:30 'i' ( temp highp int) +0:30 Constant: +0:30 0 (const int) +0:31 EmitVertex ( global void) +0:27 Loop Terminal Expression +0:27 Post-Increment ( temp highp int) +0:27 'i' ( temp highp int) +0:33 EndPrimitive ( global void) +0:? Linker Objects +0:? 'vgo1' ( in 1-element array of highp 4-component vector of float) +0:? 'vgo2' ( in 1-element array of highp 2-component vector of float) +0:? 'inBlock' (layout( location=5) in 1-element array of block{ in highp 4-component vector of float o3}) +0:? 'gfo1' (layout( stream=0) out highp 4-component vector of float) +0:? 'gfo2' (layout( stream=0) out highp 2-component vector of float) +0:? 'gf_out' (layout( location=5 stream=0) out block{layout( stream=0) out highp 4-component vector of float o3}) +0:? '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}) + +iomap.crossStage.vk.frag +Shader version: 460 +gl_FragCoord origin is upper left +0:? Sequence +0:30 Function Definition: Bar( ( global highp 2-component vector of float) +0:30 Function Parameters: +0:31 Sequence +0:31 Branch: Return with expression +0:32 add ( temp highp 2-component vector of float) +0:31 add ( temp highp 2-component vector of float) +0:31 fb1: direct index for structure (layout( column_major std430) readonly buffer highp 2-component vector of float) +0:31 'anon@2' (layout( column_major std430) readonly buffer block{layout( column_major std430) readonly buffer highp 2-component vector of float fb1}) +0:31 Constant: +0:31 0 (const uint) +0:32 b: direct index for structure (layout( column_major std140) uniform highp 2-component vector of float) +0:32 direct index (layout( column_major std140) temp 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}) +0:32 '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}) +0:32 Constant: +0:32 0 (const int) +0:32 Constant: +0:32 1 (const int) +0:33 b: direct index for structure (layout( column_major std140) uniform highp 2-component vector of float) +0:33 direct index (layout( column_major std140) temp 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}) +0:33 '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}) +0:33 Constant: +0:33 1 (const int) +0:33 Constant: +0:33 1 (const int) +0:36 Function Definition: Foo( ( global highp 4-component vector of float) +0:36 Function Parameters: +0:37 Sequence +0:37 Branch: Return with expression +0:40 add ( temp highp 4-component vector of float) +0:39 add ( temp highp 4-component vector of float) +0:38 add ( temp highp 4-component vector of float) +0:37 add ( temp highp 4-component vector of float) +0:37 a: direct index for structure (layout( column_major std140) uniform highp 4-component vector of float) +0:37 'anon@1' (layout( column_major std140) uniform block{layout( column_major std140) uniform highp 4-component vector of float a, layout( column_major std140) uniform highp 4-component vector of float b}) +0:37 Constant: +0:37 0 (const uint) +0:38 b: direct index for structure (layout( column_major std140) uniform highp 4-component vector of float) +0:38 'anon@1' (layout( column_major std140) uniform block{layout( column_major std140) uniform highp 4-component vector of float a, layout( column_major std140) uniform highp 4-component vector of float b}) +0:38 Constant: +0:38 1 (const uint) +0:39 a: direct index for structure (layout( column_major std140) uniform highp 4-component vector of float) +0:39 direct index (layout( column_major std140) temp 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}) +0:39 '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}) +0:39 Constant: +0:39 0 (const int) +0:39 Constant: +0:39 0 (const int) +0:40 a: direct index for structure (layout( column_major std140) uniform highp 4-component vector of float) +0:40 direct index (layout( column_major std140) temp 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}) +0:40 '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}) +0:40 Constant: +0:40 1 (const int) +0:40 Constant: +0:40 0 (const int) +0:41 Construct vec4 ( temp highp 4-component vector of float) +0:41 Function Call: Bar( ( global highp 2-component vector of float) +0:41 Constant: +0:41 0.000000 +0:41 Constant: +0:41 0.000000 +0:44 Function Definition: main( ( global void) +0:44 Function Parameters: +0:46 Sequence +0:46 Sequence +0:46 move second child to first child ( temp highp 4-component vector of float) +0:46 'color' ( temp highp 4-component vector of float) +0:46 'gfo1' ( smooth in highp 4-component vector of float) +0:47 move second child to first child ( temp highp 4-component vector of float) +0:47 'color' ( temp highp 4-component vector of float) +0:47 add ( temp highp 4-component vector of float) +0:47 'color' ( temp highp 4-component vector of float) +0:47 Function Call: Foo( ( global highp 4-component vector of float) +0:48 move second child to first child ( temp highp 4-component vector of float) +0:48 'outColor' ( out highp 4-component vector of float) +0:48 'color' ( temp highp 4-component vector of float) +0:? Linker Objects +0:? 'anon@0' (layout( location=5) in block{ in highp 4-component vector of float o3}) +0:? 'gfo1' ( smooth in highp 4-component vector of float) +0:? 'gfo2' ( smooth in highp 2-component vector of float) +0:? 'outColor' ( out highp 4-component vector of float) +0:? 'glass' (layout( binding=0) uniform highp sampler2D) +0:? 'anon@1' (layout( column_major std140) uniform block{layout( column_major std140) uniform highp 4-component vector of float a, layout( column_major std140) uniform highp 4-component vector of float b}) +0:? 'anon@2' (layout( column_major std430) readonly buffer block{layout( column_major std430) readonly buffer highp 2-component vector of float fb1}) +0:? '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}) + + +Linked vertex stage: + + +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}" + +Shader version: 460 +0:? Sequence +0:26 Function Definition: main( ( global void) +0:26 Function Parameters: +0:28 Sequence +0:28 move second child to first child ( temp highp 4-component vector of float) +0:28 'vgo1' ( smooth out highp 4-component vector of float) +0:28 Constant: +0:28 0.000000 +0:28 0.000000 +0:28 0.000000 +0:28 0.000000 +0:29 move second child to first child ( temp highp 2-component vector of float) +0:29 'vgo2' ( smooth out highp 2-component vector of float) +0:29 Constant: +0:29 0.000000 +0:29 0.000000 +0:30 move second child to first child ( temp highp 4-component vector of float) +0:30 o3: direct index for structure ( out highp 4-component vector of float) +0:30 'anon@0' (layout( location=5) out block{ out highp 4-component vector of float o3}) +0:30 Constant: +0:30 0 (const uint) +0:30 Constant: +0:30 0.000000 +0:30 0.000000 +0:30 0.000000 +0:30 0.000000 +0:? Linker Objects +0:? 'vgo1' ( smooth out highp 4-component vector of float) +0:? 'vgo2' ( smooth out highp 2-component vector of float) +0:? 'anon@0' (layout( location=5) out block{ out highp 4-component vector of float o3}) +0:? 'glass' (layout( binding=0) uniform highp sampler2D) +0:? 'anon@1' (layout( column_major std140) uniform block{layout( column_major std140) uniform highp 4-component vector of float a, layout( column_major std140) uniform highp 4-component vector of float b}) +0:? 'anon@2' (layout( column_major std430) readonly buffer block{layout( column_major std430) readonly buffer highp 2-component vector of float vb1}) +0:? '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}) +Shader version: 460 +invocations = 1 +max_vertices = 3 +input primitive = points +output primitive = triangle_strip +0:? Sequence +0:25 Function Definition: main( ( global void) +0:25 Function Parameters: +0:27 Sequence +0:27 Sequence +0:27 Sequence +0:27 move second child to first child ( temp highp int) +0:27 'i' ( temp highp int) +0:27 Constant: +0:27 0 (const int) +0:27 Loop with condition tested first +0:27 Loop Condition +0:27 Compare Less Than ( temp bool) +0:27 'i' ( temp highp int) +0:27 Constant: +0:27 3 (const int) +0:27 Loop Body +0:28 Sequence +0:28 move second child to first child ( temp highp 4-component vector of float) +0:28 'gfo1' (layout( stream=0) out highp 4-component vector of float) +0:28 Constant: +0:28 0.000000 +0:28 0.000000 +0:28 0.000000 +0:28 0.000000 +0:29 move second child to first child ( temp highp 2-component vector of float) +0:29 'gfo2' (layout( stream=0) out highp 2-component vector of float) +0:29 Constant: +0:29 0.000000 +0:29 0.000000 +0:30 move second child to first child ( temp highp 4-component vector of float) +0:30 o3: direct index for structure (layout( stream=0) out highp 4-component vector of float) +0:30 'gf_out' (layout( location=5 stream=0) out block{layout( stream=0) out highp 4-component vector of float o3}) +0:30 Constant: +0:30 0 (const int) +0:30 o3: direct index for structure ( in highp 4-component vector of float) +0:30 indirect index (layout( location=5) temp block{ in highp 4-component vector of float o3}) +0:30 'inBlock' (layout( location=5) in 1-element array of block{ in highp 4-component vector of float o3}) +0:30 'i' ( temp highp int) +0:30 Constant: +0:30 0 (const int) +0:31 EmitVertex ( global void) +0:27 Loop Terminal Expression +0:27 Post-Increment ( temp highp int) +0:27 'i' ( temp highp int) +0:33 EndPrimitive ( global void) +0:? Linker Objects +0:? 'vgo1' ( in 1-element array of highp 4-component vector of float) +0:? 'vgo2' ( in 1-element array of highp 2-component vector of float) +0:? 'inBlock' (layout( location=5) in 1-element array of block{ in highp 4-component vector of float o3}) +0:? 'gfo1' (layout( stream=0) out highp 4-component vector of float) +0:? 'gfo2' (layout( stream=0) out highp 2-component vector of float) +0:? 'gf_out' (layout( location=5 stream=0) out block{layout( stream=0) out highp 4-component vector of float o3}) +0:? '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}) +Shader version: 460 +gl_FragCoord origin is upper left +0:? Sequence +0:30 Function Definition: Bar( ( global highp 2-component vector of float) +0:30 Function Parameters: +0:31 Sequence +0:31 Branch: Return with expression +0:32 add ( temp highp 2-component vector of float) +0:31 add ( temp highp 2-component vector of float) +0:31 fb1: direct index for structure (layout( column_major std430) readonly buffer highp 2-component vector of float) +0:31 'anon@2' (layout( column_major std430) readonly buffer block{layout( column_major std430) readonly buffer highp 2-component vector of float fb1}) +0:31 Constant: +0:31 0 (const uint) +0:32 b: direct index for structure (layout( column_major std140) uniform highp 2-component vector of float) +0:32 direct index (layout( column_major std140) temp 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}) +0:32 '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}) +0:32 Constant: +0:32 0 (const int) +0:32 Constant: +0:32 1 (const int) +0:33 b: direct index for structure (layout( column_major std140) uniform highp 2-component vector of float) +0:33 direct index (layout( column_major std140) temp 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}) +0:33 '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}) +0:33 Constant: +0:33 1 (const int) +0:33 Constant: +0:33 1 (const int) +0:36 Function Definition: Foo( ( global highp 4-component vector of float) +0:36 Function Parameters: +0:37 Sequence +0:37 Branch: Return with expression +0:40 add ( temp highp 4-component vector of float) +0:39 add ( temp highp 4-component vector of float) +0:38 add ( temp highp 4-component vector of float) +0:37 add ( temp highp 4-component vector of float) +0:37 a: direct index for structure (layout( column_major std140) uniform highp 4-component vector of float) +0:37 'anon@1' (layout( column_major std140) uniform block{layout( column_major std140) uniform highp 4-component vector of float a, layout( column_major std140) uniform highp 4-component vector of float b}) +0:37 Constant: +0:37 0 (const uint) +0:38 b: direct index for structure (layout( column_major std140) uniform highp 4-component vector of float) +0:38 'anon@1' (layout( column_major std140) uniform block{layout( column_major std140) uniform highp 4-component vector of float a, layout( column_major std140) uniform highp 4-component vector of float b}) +0:38 Constant: +0:38 1 (const uint) +0:39 a: direct index for structure (layout( column_major std140) uniform highp 4-component vector of float) +0:39 direct index (layout( column_major std140) temp 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}) +0:39 '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}) +0:39 Constant: +0:39 0 (const int) +0:39 Constant: +0:39 0 (const int) +0:40 a: direct index for structure (layout( column_major std140) uniform highp 4-component vector of float) +0:40 direct index (layout( column_major std140) temp 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}) +0:40 '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}) +0:40 Constant: +0:40 1 (const int) +0:40 Constant: +0:40 0 (const int) +0:41 Construct vec4 ( temp highp 4-component vector of float) +0:41 Function Call: Bar( ( global highp 2-component vector of float) +0:41 Constant: +0:41 0.000000 +0:41 Constant: +0:41 0.000000 +0:44 Function Definition: main( ( global void) +0:44 Function Parameters: +0:46 Sequence +0:46 Sequence +0:46 move second child to first child ( temp highp 4-component vector of float) +0:46 'color' ( temp highp 4-component vector of float) +0:46 'gfo1' ( smooth in highp 4-component vector of float) +0:47 move second child to first child ( temp highp 4-component vector of float) +0:47 'color' ( temp highp 4-component vector of float) +0:47 add ( temp highp 4-component vector of float) +0:47 'color' ( temp highp 4-component vector of float) +0:47 Function Call: Foo( ( global highp 4-component vector of float) +0:48 move second child to first child ( temp highp 4-component vector of float) +0:48 'outColor' ( out highp 4-component vector of float) +0:48 'color' ( temp highp 4-component vector of float) +0:? Linker Objects +0:? 'anon@0' (layout( location=5) in block{ in highp 4-component vector of float o3}) +0:? 'gfo1' ( smooth in highp 4-component vector of float) +0:? 'gfo2' ( smooth in highp 2-component vector of float) +0:? 'outColor' ( out highp 4-component vector of float) +0:? 'glass' (layout( binding=0) uniform highp sampler2D) +0:? 'anon@1' (layout( column_major std140) uniform block{layout( column_major std140) uniform highp 4-component vector of float a, layout( column_major std140) uniform highp 4-component vector of float b}) +0:? 'anon@2' (layout( column_major std430) readonly buffer block{layout( column_major std430) readonly buffer highp 2-component vector of float fb1}) +0:? '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}) + +// Module Version 10000 +// Generated by (magic number): 8000a +// Id's are bound by 38 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Vertex 4 "main" 9 14 18 + Source GLSL 460 + Name 4 "main" + Name 9 "vgo1" + Name 14 "vgo2" + Name 16 "outBlock" + MemberName 16(outBlock) 0 "o3" + Name 18 "" + Name 25 "glass" + Name 26 "crossStageBlock1" + MemberName 26(crossStageBlock1) 0 "a" + MemberName 26(crossStageBlock1) 1 "b" + Name 28 "" + Name 29 "vertOnlyBlock" + MemberName 29(vertOnlyBlock) 0 "vb1" + Name 31 "" + Name 32 "crossStageBlock2" + MemberName 32(crossStageBlock2) 0 "a" + MemberName 32(crossStageBlock2) 1 "b" + Name 37 "blockName1" + Decorate 9(vgo1) Location 0 + Decorate 14(vgo2) Location 1 + Decorate 16(outBlock) Block + Decorate 18 Location 5 + Decorate 25(glass) DescriptorSet 0 + Decorate 25(glass) Binding 0 + MemberDecorate 26(crossStageBlock1) 0 Offset 0 + MemberDecorate 26(crossStageBlock1) 1 Offset 16 + Decorate 26(crossStageBlock1) Block + Decorate 28 DescriptorSet 0 + Decorate 28 Binding 1 + MemberDecorate 29(vertOnlyBlock) 0 NonWritable + MemberDecorate 29(vertOnlyBlock) 0 Offset 0 + Decorate 29(vertOnlyBlock) BufferBlock + Decorate 31 DescriptorSet 0 + Decorate 31 Binding 0 + MemberDecorate 32(crossStageBlock2) 0 Offset 0 + MemberDecorate 32(crossStageBlock2) 1 Offset 16 + Decorate 32(crossStageBlock2) Block + Decorate 37(blockName1) DescriptorSet 0 + Decorate 37(blockName1) Binding 3 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8: TypePointer Output 7(fvec4) + 9(vgo1): 8(ptr) Variable Output + 10: 6(float) Constant 0 + 11: 7(fvec4) ConstantComposite 10 10 10 10 + 12: TypeVector 6(float) 2 + 13: TypePointer Output 12(fvec2) + 14(vgo2): 13(ptr) Variable Output + 15: 12(fvec2) ConstantComposite 10 10 + 16(outBlock): TypeStruct 7(fvec4) + 17: TypePointer Output 16(outBlock) + 18: 17(ptr) Variable Output + 19: TypeInt 32 1 + 20: 19(int) Constant 0 + 22: TypeImage 6(float) 2D sampled format:Unknown + 23: TypeSampledImage 22 + 24: TypePointer UniformConstant 23 + 25(glass): 24(ptr) Variable UniformConstant +26(crossStageBlock1): TypeStruct 7(fvec4) 7(fvec4) + 27: TypePointer Uniform 26(crossStageBlock1) + 28: 27(ptr) Variable Uniform +29(vertOnlyBlock): TypeStruct 12(fvec2) + 30: TypePointer Uniform 29(vertOnlyBlock) + 31: 30(ptr) Variable Uniform +32(crossStageBlock2): TypeStruct 7(fvec4) 12(fvec2) + 33: TypeInt 32 0 + 34: 33(int) Constant 2 + 35: TypeArray 32(crossStageBlock2) 34 + 36: TypePointer Uniform 35 + 37(blockName1): 36(ptr) Variable Uniform + 4(main): 2 Function None 3 + 5: Label + Store 9(vgo1) 11 + Store 14(vgo2) 15 + 21: 8(ptr) AccessChain 18 20 + Store 21 11 + Return + FunctionEnd +// Module Version 10000 +// Generated by (magic number): 8000a +// Id's are bound by 57 + + Capability Geometry + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Geometry 4 "main" 22 27 31 37 48 51 + ExecutionMode 4 InputPoints + ExecutionMode 4 Invocations 1 + ExecutionMode 4 OutputTriangleStrip + ExecutionMode 4 OutputVertices 3 + Source GLSL 460 + Name 4 "main" + Name 8 "i" + Name 22 "gfo1" + Name 27 "gfo2" + Name 29 "outBlock" + MemberName 29(outBlock) 0 "o3" + Name 31 "gf_out" + Name 32 "outBlock" + MemberName 32(outBlock) 0 "o3" + Name 37 "inBlock" + Name 48 "vgo1" + Name 51 "vgo2" + Name 52 "crossStageBlock2" + MemberName 52(crossStageBlock2) 0 "a" + MemberName 52(crossStageBlock2) 1 "b" + Name 56 "blockName1" + Decorate 22(gfo1) Location 0 + Decorate 27(gfo2) Location 1 + Decorate 29(outBlock) Block + Decorate 31(gf_out) Location 5 + Decorate 32(outBlock) Block + Decorate 37(inBlock) Location 5 + Decorate 48(vgo1) Location 0 + Decorate 51(vgo2) Location 1 + MemberDecorate 52(crossStageBlock2) 0 Offset 0 + MemberDecorate 52(crossStageBlock2) 1 Offset 16 + Decorate 52(crossStageBlock2) Block + Decorate 56(blockName1) DescriptorSet 0 + Decorate 56(blockName1) Binding 3 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeInt 32 1 + 7: TypePointer Function 6(int) + 9: 6(int) Constant 0 + 16: 6(int) Constant 3 + 17: TypeBool + 19: TypeFloat 32 + 20: TypeVector 19(float) 4 + 21: TypePointer Output 20(fvec4) + 22(gfo1): 21(ptr) Variable Output + 23: 19(float) Constant 0 + 24: 20(fvec4) ConstantComposite 23 23 23 23 + 25: TypeVector 19(float) 2 + 26: TypePointer Output 25(fvec2) + 27(gfo2): 26(ptr) Variable Output + 28: 25(fvec2) ConstantComposite 23 23 + 29(outBlock): TypeStruct 20(fvec4) + 30: TypePointer Output 29(outBlock) + 31(gf_out): 30(ptr) Variable Output + 32(outBlock): TypeStruct 20(fvec4) + 33: TypeInt 32 0 + 34: 33(int) Constant 1 + 35: TypeArray 32(outBlock) 34 + 36: TypePointer Input 35 + 37(inBlock): 36(ptr) Variable Input + 39: TypePointer Input 20(fvec4) + 44: 6(int) Constant 1 + 46: TypeArray 20(fvec4) 34 + 47: TypePointer Input 46 + 48(vgo1): 47(ptr) Variable Input + 49: TypeArray 25(fvec2) 34 + 50: TypePointer Input 49 + 51(vgo2): 50(ptr) Variable Input +52(crossStageBlock2): TypeStruct 20(fvec4) 25(fvec2) + 53: 33(int) Constant 2 + 54: TypeArray 52(crossStageBlock2) 53 + 55: TypePointer Uniform 54 + 56(blockName1): 55(ptr) Variable Uniform + 4(main): 2 Function None 3 + 5: Label + 8(i): 7(ptr) Variable Function + Store 8(i) 9 + Branch 10 + 10: Label + LoopMerge 12 13 None + Branch 14 + 14: Label + 15: 6(int) Load 8(i) + 18: 17(bool) SLessThan 15 16 + BranchConditional 18 11 12 + 11: Label + Store 22(gfo1) 24 + Store 27(gfo2) 28 + 38: 6(int) Load 8(i) + 40: 39(ptr) AccessChain 37(inBlock) 38 9 + 41: 20(fvec4) Load 40 + 42: 21(ptr) AccessChain 31(gf_out) 9 + Store 42 41 + EmitVertex + Branch 13 + 13: Label + 43: 6(int) Load 8(i) + 45: 6(int) IAdd 43 44 + Store 8(i) 45 + Branch 10 + 12: Label + EndPrimitive + Return + FunctionEnd +// Module Version 10000 +// Generated by (magic number): 8000a +// Id's are bound by 81 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "main" 64 70 74 76 + ExecutionMode 4 OriginUpperLeft + Source GLSL 460 + Name 4 "main" + Name 9 "Bar(" + Name 13 "Foo(" + Name 15 "fragOnlyBlock" + MemberName 15(fragOnlyBlock) 0 "fb1" + Name 17 "" + Name 23 "crossStageBlock2" + MemberName 23(crossStageBlock2) 0 "a" + MemberName 23(crossStageBlock2) 1 "b" + Name 28 "blockName2" + Name 38 "crossStageBlock1" + MemberName 38(crossStageBlock1) 0 "a" + MemberName 38(crossStageBlock1) 1 "b" + Name 40 "" + Name 62 "color" + Name 64 "gfo1" + Name 70 "outColor" + Name 72 "outBlock" + MemberName 72(outBlock) 0 "o3" + Name 74 "" + Name 76 "gfo2" + Name 80 "glass" + MemberDecorate 15(fragOnlyBlock) 0 NonWritable + MemberDecorate 15(fragOnlyBlock) 0 Offset 0 + Decorate 15(fragOnlyBlock) BufferBlock + Decorate 17 DescriptorSet 0 + Decorate 17 Binding 2 + MemberDecorate 23(crossStageBlock2) 0 Offset 0 + MemberDecorate 23(crossStageBlock2) 1 Offset 16 + Decorate 23(crossStageBlock2) Block + Decorate 28(blockName2) DescriptorSet 0 + Decorate 28(blockName2) Binding 3 + MemberDecorate 38(crossStageBlock1) 0 Offset 0 + MemberDecorate 38(crossStageBlock1) 1 Offset 16 + Decorate 38(crossStageBlock1) Block + Decorate 40 DescriptorSet 0 + Decorate 40 Binding 1 + Decorate 64(gfo1) Location 0 + Decorate 70(outColor) Location 0 + Decorate 72(outBlock) Block + Decorate 74 Location 5 + Decorate 76(gfo2) Location 1 + Decorate 80(glass) DescriptorSet 0 + Decorate 80(glass) Binding 0 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 2 + 8: TypeFunction 7(fvec2) + 11: TypeVector 6(float) 4 + 12: TypeFunction 11(fvec4) +15(fragOnlyBlock): TypeStruct 7(fvec2) + 16: TypePointer Uniform 15(fragOnlyBlock) + 17: 16(ptr) Variable Uniform + 18: TypeInt 32 1 + 19: 18(int) Constant 0 + 20: TypePointer Uniform 7(fvec2) +23(crossStageBlock2): TypeStruct 11(fvec4) 7(fvec2) + 24: TypeInt 32 0 + 25: 24(int) Constant 2 + 26: TypeArray 23(crossStageBlock2) 25 + 27: TypePointer Uniform 26 + 28(blockName2): 27(ptr) Variable Uniform + 29: 18(int) Constant 1 +38(crossStageBlock1): TypeStruct 11(fvec4) 11(fvec4) + 39: TypePointer Uniform 38(crossStageBlock1) + 40: 39(ptr) Variable Uniform + 41: TypePointer Uniform 11(fvec4) + 54: 6(float) Constant 0 + 61: TypePointer Function 11(fvec4) + 63: TypePointer Input 11(fvec4) + 64(gfo1): 63(ptr) Variable Input + 69: TypePointer Output 11(fvec4) + 70(outColor): 69(ptr) Variable Output + 72(outBlock): TypeStruct 11(fvec4) + 73: TypePointer Input 72(outBlock) + 74: 73(ptr) Variable Input + 75: TypePointer Input 7(fvec2) + 76(gfo2): 75(ptr) Variable Input + 77: TypeImage 6(float) 2D sampled format:Unknown + 78: TypeSampledImage 77 + 79: TypePointer UniformConstant 78 + 80(glass): 79(ptr) Variable UniformConstant + 4(main): 2 Function None 3 + 5: Label + 62(color): 61(ptr) Variable Function + 65: 11(fvec4) Load 64(gfo1) + Store 62(color) 65 + 66: 11(fvec4) Load 62(color) + 67: 11(fvec4) FunctionCall 13(Foo() + 68: 11(fvec4) FAdd 66 67 + Store 62(color) 68 + 71: 11(fvec4) Load 62(color) + Store 70(outColor) 71 + Return + FunctionEnd + 9(Bar(): 7(fvec2) Function None 8 + 10: Label + 21: 20(ptr) AccessChain 17 19 + 22: 7(fvec2) Load 21 + 30: 20(ptr) AccessChain 28(blockName2) 19 29 + 31: 7(fvec2) Load 30 + 32: 7(fvec2) FAdd 22 31 + 33: 20(ptr) AccessChain 28(blockName2) 29 29 + 34: 7(fvec2) Load 33 + 35: 7(fvec2) FAdd 32 34 + ReturnValue 35 + FunctionEnd + 13(Foo(): 11(fvec4) Function None 12 + 14: Label + 42: 41(ptr) AccessChain 40 19 + 43: 11(fvec4) Load 42 + 44: 41(ptr) AccessChain 40 29 + 45: 11(fvec4) Load 44 + 46: 11(fvec4) FAdd 43 45 + 47: 41(ptr) AccessChain 28(blockName2) 19 19 + 48: 11(fvec4) Load 47 + 49: 11(fvec4) FAdd 46 48 + 50: 41(ptr) AccessChain 28(blockName2) 29 19 + 51: 11(fvec4) Load 50 + 52: 11(fvec4) FAdd 49 51 + 53: 7(fvec2) FunctionCall 9(Bar() + 55: 6(float) CompositeExtract 53 0 + 56: 6(float) CompositeExtract 53 1 + 57: 11(fvec4) CompositeConstruct 55 56 54 54 + 58: 11(fvec4) FAdd 52 57 + ReturnValue 58 + FunctionEnd diff --git a/Test/baseResults/vk.relaxed.errorcheck.vert.out b/Test/baseResults/vk.relaxed.errorcheck.vert.out new file mode 100644 index 00000000..f19eae64 --- /dev/null +++ b/Test/baseResults/vk.relaxed.errorcheck.vert.out @@ -0,0 +1,124 @@ +vk.relaxed.errorcheck.vert +Shader version: 460 +0:? Sequence +0:9 Function Definition: foo( ( global highp 4-component vector of float) +0:9 Function Parameters: +0:10 Sequence +0:10 Branch: Return with expression +0:10 vector swizzle ( temp highp 4-component vector of float) +0:10 a: direct index for structure ( uniform highp 2-component vector of float) +0:10 'anon@0' (layout( column_major std140) uniform block{ uniform highp 2-component vector of float a}) +0:10 Constant: +0:10 0 (const uint) +0:10 Sequence +0:10 Constant: +0:10 0 (const int) +0:10 Constant: +0:10 1 (const int) +0:10 Constant: +0:10 0 (const int) +0:10 Constant: +0:10 1 (const int) +0:13 Function Definition: main( ( global void) +0:13 Function Parameters: +0:14 Sequence +0:14 move second child to first child ( temp highp 4-component vector of float) +0:14 'io' (layout( location=0) smooth out highp 4-component vector of float) +0:14 Function Call: foo( ( global highp 4-component vector of float) +0:? Linker Objects +0:? 'io' (layout( location=0) smooth out highp 4-component vector of float) +0:? 'anon@0' (layout( column_major std140) uniform block{ uniform highp 2-component vector of float a}) +0:? 'gl_VertexID' ( in int VertexIndex) +0:? 'gl_InstanceID' ( in int InstanceIndex) + +vk.relaxed.errorcheck.frag +Shader version: 460 +gl_FragCoord origin is upper left +0:? Sequence +0:10 Function Definition: foo( ( global highp 4-component vector of float) +0:10 Function Parameters: +0:11 Sequence +0:11 Branch: Return with expression +0:11 a: direct index for structure ( uniform highp 4-component vector of float) +0:11 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a}) +0:11 Constant: +0:11 0 (const uint) +0:14 Function Definition: main( ( global void) +0:14 Function Parameters: +0:15 Sequence +0:15 move second child to first child ( temp highp 4-component vector of float) +0:15 'o' ( out highp 4-component vector of float) +0:15 add ( temp highp 4-component vector of float) +0:15 'io' (layout( location=0) smooth in highp 4-component vector of float) +0:15 Function Call: foo( ( global highp 4-component vector of float) +0:? Linker Objects +0:? 'io' (layout( location=0) smooth in highp 4-component vector of float) +0:? 'o' ( out highp 4-component vector of float) +0:? 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a}) + + +Linked vertex stage: + + +Linked fragment stage: + +ERROR: Linking unknown stage stage: Types must match: + a: " uniform highp 2-component vector of float" versus " uniform highp 4-component vector of float" + +Shader version: 460 +0:? Sequence +0:9 Function Definition: foo( ( global highp 4-component vector of float) +0:9 Function Parameters: +0:10 Sequence +0:10 Branch: Return with expression +0:10 vector swizzle ( temp highp 4-component vector of float) +0:10 a: direct index for structure ( uniform highp 2-component vector of float) +0:10 'anon@0' (layout( column_major std140) uniform block{ uniform highp 2-component vector of float a}) +0:10 Constant: +0:10 0 (const uint) +0:10 Sequence +0:10 Constant: +0:10 0 (const int) +0:10 Constant: +0:10 1 (const int) +0:10 Constant: +0:10 0 (const int) +0:10 Constant: +0:10 1 (const int) +0:13 Function Definition: main( ( global void) +0:13 Function Parameters: +0:14 Sequence +0:14 move second child to first child ( temp highp 4-component vector of float) +0:14 'io' (layout( location=0) smooth out highp 4-component vector of float) +0:14 Function Call: foo( ( global highp 4-component vector of float) +0:? Linker Objects +0:? 'io' (layout( location=0) smooth out highp 4-component vector of float) +0:? 'anon@0' (layout( column_major std140) uniform block{ uniform highp 2-component vector of float a}) +0:? 'gl_VertexID' ( in int VertexIndex) +0:? 'gl_InstanceID' ( in int InstanceIndex) +Shader version: 460 +gl_FragCoord origin is upper left +0:? Sequence +0:10 Function Definition: foo( ( global highp 4-component vector of float) +0:10 Function Parameters: +0:11 Sequence +0:11 Branch: Return with expression +0:11 a: direct index for structure ( uniform highp 4-component vector of float) +0:11 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a}) +0:11 Constant: +0:11 0 (const uint) +0:14 Function Definition: main( ( global void) +0:14 Function Parameters: +0:15 Sequence +0:15 move second child to first child ( temp highp 4-component vector of float) +0:15 'o' ( out highp 4-component vector of float) +0:15 add ( temp highp 4-component vector of float) +0:15 'io' (layout( location=0) smooth in highp 4-component vector of float) +0:15 Function Call: foo( ( global highp 4-component vector of float) +0:? Linker Objects +0:? 'io' (layout( location=0) smooth in highp 4-component vector of float) +0:? 'o' ( out highp 4-component vector of float) +0:? 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a}) + +Validation failed +SPIR-V is not generated for failed compile or link diff --git a/Test/baseResults/vk.relaxed.frag.out b/Test/baseResults/vk.relaxed.frag.out new file mode 100644 index 00000000..d98910e6 --- /dev/null +++ b/Test/baseResults/vk.relaxed.frag.out @@ -0,0 +1,826 @@ +vk.relaxed.frag +WARNING: 0:7: 'b' : Ignoring initializer for uniform +WARNING: 0:8: 'c' : ignoring layout qualifier for uniform location + +Shader version: 460 +gl_FragCoord origin is upper left +0:? Sequence +0:36 Function Definition: bar( ( global highp uint) +0:36 Function Parameters: +0:37 Sequence +0:37 Sequence +0:37 move second child to first child ( temp highp uint) +0:37 'j' ( temp highp uint) +0:37 Constant: +0:37 0 (const uint) +0:38 move second child to first child ( temp highp uint) +0:38 'j' ( temp highp uint) +0:38 AtomicAdd ( global highp uint) +0:38 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:38 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:38 Constant: +0:38 0 (const uint) +0:38 Constant: +0:38 1 (const uint) +0:39 move second child to first child ( temp highp uint) +0:39 'j' ( temp highp uint) +0:39 subtract ( temp highp uint) +0:39 AtomicAdd ( global highp uint) +0:39 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:39 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:39 Constant: +0:39 0 (const uint) +0:39 Constant: +0:39 4294967295 (const uint) +0:39 Constant: +0:39 1 (const uint) +0:40 move second child to first child ( temp highp uint) +0:40 'j' ( temp highp uint) +0:40 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:40 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:40 Constant: +0:40 0 (const uint) +0:42 move second child to first child ( temp highp uint) +0:42 'j' ( temp highp uint) +0:42 AtomicAdd ( global highp uint) +0:42 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:42 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:42 Constant: +0:42 0 (const uint) +0:42 Constant: +0:42 1 (const uint) +0:43 move second child to first child ( temp highp uint) +0:43 'j' ( temp highp uint) +0:43 AtomicAdd ( global highp uint) +0:43 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:43 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:43 Constant: +0:43 0 (const uint) +0:43 Constant: +0:43 4294967295 (const uint) +0:44 move second child to first child ( temp highp uint) +0:44 'j' ( temp highp uint) +0:44 AtomicSubtract ( global highp uint) +0:44 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:44 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:44 Constant: +0:44 0 (const uint) +0:44 Constant: +0:44 1 (const uint) +0:46 move second child to first child ( temp highp uint) +0:46 'j' ( temp highp uint) +0:46 AtomicMin ( global highp uint) +0:46 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:46 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:46 Constant: +0:46 0 (const uint) +0:46 'j' ( temp highp uint) +0:47 move second child to first child ( temp highp uint) +0:47 'j' ( temp highp uint) +0:47 AtomicMax ( global highp uint) +0:47 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:47 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:47 Constant: +0:47 0 (const uint) +0:47 'j' ( temp highp uint) +0:48 move second child to first child ( temp highp uint) +0:48 'j' ( temp highp uint) +0:48 AtomicAnd ( global highp uint) +0:48 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:48 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:48 Constant: +0:48 0 (const uint) +0:48 'j' ( temp highp uint) +0:50 move second child to first child ( temp highp uint) +0:50 'j' ( temp highp uint) +0:50 AtomicOr ( global highp uint) +0:50 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:50 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:50 Constant: +0:50 0 (const uint) +0:50 'j' ( temp highp uint) +0:51 move second child to first child ( temp highp uint) +0:51 'j' ( temp highp uint) +0:51 AtomicXor ( global highp uint) +0:51 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:51 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:51 Constant: +0:51 0 (const uint) +0:51 'j' ( temp highp uint) +0:53 move second child to first child ( temp highp uint) +0:53 'j' ( temp highp uint) +0:53 AtomicExchange ( global highp uint) +0:53 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:53 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:53 Constant: +0:53 0 (const uint) +0:53 'j' ( temp highp uint) +0:54 move second child to first child ( temp highp uint) +0:54 'j' ( temp highp uint) +0:54 AtomicCompSwap ( global highp uint) +0:54 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:54 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:54 Constant: +0:54 0 (const uint) +0:54 Constant: +0:54 0 (const uint) +0:54 'j' ( temp highp uint) +0:56 AtomicAdd ( global highp uint) +0:56 counter2: direct index for structure ( coherent volatile buffer highp uint) +0:56 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:56 Constant: +0:56 1 (const uint) +0:56 Constant: +0:56 1 (const uint) +0:57 AtomicAdd ( global highp uint) +0:57 counter3: direct index for structure ( coherent volatile buffer highp uint) +0:57 'anon@3' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter3}) +0:57 Constant: +0:57 0 (const uint) +0:57 Constant: +0:57 1 (const uint) +0:59 MemoryBarrierBuffer ( global void) +0:61 Branch: Return with expression +0:61 'j' ( temp highp uint) +0:64 Function Definition: foo( ( global highp 4-component vector of float) +0:64 Function Parameters: +0:65 Sequence +0:65 Sequence +0:65 move second child to first child ( temp highp float) +0:65 'f' ( temp highp float) +0:65 add ( temp highp float) +0:65 add ( temp highp float) +0:65 add ( temp highp float) +0:65 j: direct index for structure (layout( column_major std140) uniform highp float) +0:65 'anon@1' (layout( column_major std140) uniform block{layout( column_major std140) uniform highp float j, layout( column_major std140) uniform highp 4-component vector of float k}) +0:65 Constant: +0:65 0 (const uint) +0:65 j: direct index for structure (layout( column_major std430) buffer highp float) +0:65 'bufferInstance' (layout( column_major std430) buffer block{layout( column_major std430) buffer highp float j, layout( column_major std430) buffer highp 4-component vector of float k}) +0:65 Constant: +0:65 0 (const int) +0:65 y: direct index for structure ( global highp float) +0:65 structUniform: direct index for structure ( uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z}) +0:65 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b, uniform highp 2-component vector of float c, uniform 10-element array of highp 4-component vector of float d, uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z} structUniform}) +0:65 Constant: +0:65 4 (const uint) +0:65 Constant: +0:65 1 (const int) +0:65 Convert uint to float ( temp highp float) +0:65 z: direct index for structure ( global highp uint) +0:65 structUniform: direct index for structure ( uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z}) +0:65 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b, uniform highp 2-component vector of float c, uniform 10-element array of highp 4-component vector of float d, uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z} structUniform}) +0:65 Constant: +0:65 4 (const uint) +0:65 Constant: +0:65 2 (const int) +0:66 Sequence +0:66 move second child to first child ( temp highp 2-component vector of float) +0:66 'v2' ( temp highp 2-component vector of float) +0:66 add ( temp highp 2-component vector of float) +0:66 add ( temp highp 2-component vector of float) +0:66 b: direct index for structure ( uniform highp 2-component vector of float) +0:66 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b, uniform highp 2-component vector of float c, uniform 10-element array of highp 4-component vector of float d, uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z} structUniform}) +0:66 Constant: +0:66 1 (const uint) +0:66 c: direct index for structure ( uniform highp 2-component vector of float) +0:66 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b, uniform highp 2-component vector of float c, uniform 10-element array of highp 4-component vector of float d, uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z} structUniform}) +0:66 Constant: +0:66 2 (const uint) +0:66 x: direct index for structure ( global highp 2-component vector of float) +0:66 structUniform: direct index for structure ( uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z}) +0:66 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b, uniform highp 2-component vector of float c, uniform 10-element array of highp 4-component vector of float d, uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z} structUniform}) +0:66 Constant: +0:66 4 (const uint) +0:66 Constant: +0:66 0 (const int) +0:67 Sequence +0:67 move second child to first child ( temp highp 4-component vector of float) +0:67 'v4' ( temp highp 4-component vector of float) +0:67 add ( temp highp 4-component vector of float) +0:67 add ( temp highp 4-component vector of float) +0:67 add ( temp highp 4-component vector of float) +0:67 add ( temp highp 4-component vector of float) +0:67 add ( temp highp 4-component vector of float) +0:67 add ( temp highp 4-component vector of float) +0:67 a: direct index for structure ( uniform highp 4-component vector of float) +0:67 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b, uniform highp 2-component vector of float c, uniform 10-element array of highp 4-component vector of float d, uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z} structUniform}) +0:67 Constant: +0:67 0 (const uint) +0:67 direct index ( temp highp 4-component vector of float) +0:67 d: direct index for structure ( uniform 10-element array of highp 4-component vector of float) +0:67 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b, uniform highp 2-component vector of float c, uniform 10-element array of highp 4-component vector of float d, uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z} structUniform}) +0:67 Constant: +0:67 3 (const uint) +0:67 Constant: +0:67 0 (const int) +0:67 direct index ( temp highp 4-component vector of float) +0:67 d: direct index for structure ( uniform 10-element array of highp 4-component vector of float) +0:67 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b, uniform highp 2-component vector of float c, uniform 10-element array of highp 4-component vector of float d, uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z} structUniform}) +0:67 Constant: +0:67 3 (const uint) +0:67 Constant: +0:67 1 (const int) +0:67 direct index ( temp highp 4-component vector of float) +0:67 d: direct index for structure ( uniform 10-element array of highp 4-component vector of float) +0:67 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b, uniform highp 2-component vector of float c, uniform 10-element array of highp 4-component vector of float d, uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z} structUniform}) +0:67 Constant: +0:67 3 (const uint) +0:67 Constant: +0:67 2 (const int) +0:67 k: direct index for structure (layout( column_major std140) uniform highp 4-component vector of float) +0:67 'anon@1' (layout( column_major std140) uniform block{layout( column_major std140) uniform highp float j, layout( column_major std140) uniform highp 4-component vector of float k}) +0:67 Constant: +0:67 1 (const uint) +0:67 k: direct index for structure (layout( column_major std430) buffer highp 4-component vector of float) +0:67 'bufferInstance' (layout( column_major std430) buffer block{layout( column_major std430) buffer highp float j, layout( column_major std430) buffer highp 4-component vector of float k}) +0:67 Constant: +0:67 1 (const int) +0:67 texture ( global highp 4-component vector of float) +0:67 't1' ( uniform highp sampler2D) +0:67 Constant: +0:67 0.000000 +0:67 0.000000 +0:68 Branch: Return with expression +0:68 component-wise multiply ( temp highp 4-component vector of float) +0:68 component-wise multiply ( temp highp 4-component vector of float) +0:68 Construct vec4 ( temp highp 4-component vector of float) +0:68 'f' ( temp highp float) +0:68 Construct vec4 ( temp highp 4-component vector of float) +0:68 'v2' ( temp highp 2-component vector of float) +0:68 Constant: +0:68 1.000000 +0:68 Constant: +0:68 1.000000 +0:68 'v4' ( temp highp 4-component vector of float) +0:71 Function Definition: main( ( global void) +0:71 Function Parameters: +0:72 Sequence +0:72 Sequence +0:72 move second child to first child ( temp highp float) +0:72 'j' ( temp highp float) +0:72 Convert uint to float ( temp highp float) +0:72 Function Call: bar( ( global highp uint) +0:73 move second child to first child ( temp highp 4-component vector of float) +0:73 'o' ( out highp 4-component vector of float) +0:73 vector-scale ( temp highp 4-component vector of float) +0:73 'j' ( temp highp float) +0:73 Function Call: foo( ( global highp 4-component vector of float) +0:? Linker Objects +0:? 'o' ( out highp 4-component vector of float) +0:? 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b, uniform highp 2-component vector of float c, uniform 10-element array of highp 4-component vector of float d, uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z} structUniform}) +0:? 't1' ( uniform highp sampler2D) +0:? 'anon@1' (layout( column_major std140) uniform block{layout( column_major std140) uniform highp float j, layout( column_major std140) uniform highp 4-component vector of float k}) +0:? 'bufferInstance' (layout( column_major std430) buffer block{layout( column_major std430) buffer highp float j, layout( column_major std430) buffer highp 4-component vector of float k}) +0:? 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:? 'anon@3' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter3}) + + +Linked fragment stage: + + +Shader version: 460 +gl_FragCoord origin is upper left +0:? Sequence +0:36 Function Definition: bar( ( global highp uint) +0:36 Function Parameters: +0:37 Sequence +0:37 Sequence +0:37 move second child to first child ( temp highp uint) +0:37 'j' ( temp highp uint) +0:37 Constant: +0:37 0 (const uint) +0:38 move second child to first child ( temp highp uint) +0:38 'j' ( temp highp uint) +0:38 AtomicAdd ( global highp uint) +0:38 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:38 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:38 Constant: +0:38 0 (const uint) +0:38 Constant: +0:38 1 (const uint) +0:39 move second child to first child ( temp highp uint) +0:39 'j' ( temp highp uint) +0:39 subtract ( temp highp uint) +0:39 AtomicAdd ( global highp uint) +0:39 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:39 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:39 Constant: +0:39 0 (const uint) +0:39 Constant: +0:39 4294967295 (const uint) +0:39 Constant: +0:39 1 (const uint) +0:40 move second child to first child ( temp highp uint) +0:40 'j' ( temp highp uint) +0:40 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:40 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:40 Constant: +0:40 0 (const uint) +0:42 move second child to first child ( temp highp uint) +0:42 'j' ( temp highp uint) +0:42 AtomicAdd ( global highp uint) +0:42 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:42 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:42 Constant: +0:42 0 (const uint) +0:42 Constant: +0:42 1 (const uint) +0:43 move second child to first child ( temp highp uint) +0:43 'j' ( temp highp uint) +0:43 AtomicAdd ( global highp uint) +0:43 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:43 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:43 Constant: +0:43 0 (const uint) +0:43 Constant: +0:43 4294967295 (const uint) +0:44 move second child to first child ( temp highp uint) +0:44 'j' ( temp highp uint) +0:44 AtomicSubtract ( global highp uint) +0:44 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:44 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:44 Constant: +0:44 0 (const uint) +0:44 Constant: +0:44 1 (const uint) +0:46 move second child to first child ( temp highp uint) +0:46 'j' ( temp highp uint) +0:46 AtomicMin ( global highp uint) +0:46 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:46 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:46 Constant: +0:46 0 (const uint) +0:46 'j' ( temp highp uint) +0:47 move second child to first child ( temp highp uint) +0:47 'j' ( temp highp uint) +0:47 AtomicMax ( global highp uint) +0:47 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:47 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:47 Constant: +0:47 0 (const uint) +0:47 'j' ( temp highp uint) +0:48 move second child to first child ( temp highp uint) +0:48 'j' ( temp highp uint) +0:48 AtomicAnd ( global highp uint) +0:48 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:48 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:48 Constant: +0:48 0 (const uint) +0:48 'j' ( temp highp uint) +0:50 move second child to first child ( temp highp uint) +0:50 'j' ( temp highp uint) +0:50 AtomicOr ( global highp uint) +0:50 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:50 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:50 Constant: +0:50 0 (const uint) +0:50 'j' ( temp highp uint) +0:51 move second child to first child ( temp highp uint) +0:51 'j' ( temp highp uint) +0:51 AtomicXor ( global highp uint) +0:51 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:51 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:51 Constant: +0:51 0 (const uint) +0:51 'j' ( temp highp uint) +0:53 move second child to first child ( temp highp uint) +0:53 'j' ( temp highp uint) +0:53 AtomicExchange ( global highp uint) +0:53 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:53 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:53 Constant: +0:53 0 (const uint) +0:53 'j' ( temp highp uint) +0:54 move second child to first child ( temp highp uint) +0:54 'j' ( temp highp uint) +0:54 AtomicCompSwap ( global highp uint) +0:54 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:54 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:54 Constant: +0:54 0 (const uint) +0:54 Constant: +0:54 0 (const uint) +0:54 'j' ( temp highp uint) +0:56 AtomicAdd ( global highp uint) +0:56 counter2: direct index for structure ( coherent volatile buffer highp uint) +0:56 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:56 Constant: +0:56 1 (const uint) +0:56 Constant: +0:56 1 (const uint) +0:57 AtomicAdd ( global highp uint) +0:57 counter3: direct index for structure ( coherent volatile buffer highp uint) +0:57 'anon@3' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter3}) +0:57 Constant: +0:57 0 (const uint) +0:57 Constant: +0:57 1 (const uint) +0:59 MemoryBarrierBuffer ( global void) +0:61 Branch: Return with expression +0:61 'j' ( temp highp uint) +0:64 Function Definition: foo( ( global highp 4-component vector of float) +0:64 Function Parameters: +0:65 Sequence +0:65 Sequence +0:65 move second child to first child ( temp highp float) +0:65 'f' ( temp highp float) +0:65 add ( temp highp float) +0:65 add ( temp highp float) +0:65 add ( temp highp float) +0:65 j: direct index for structure (layout( column_major std140) uniform highp float) +0:65 'anon@1' (layout( column_major std140) uniform block{layout( column_major std140) uniform highp float j, layout( column_major std140) uniform highp 4-component vector of float k}) +0:65 Constant: +0:65 0 (const uint) +0:65 j: direct index for structure (layout( column_major std430) buffer highp float) +0:65 'bufferInstance' (layout( column_major std430) buffer block{layout( column_major std430) buffer highp float j, layout( column_major std430) buffer highp 4-component vector of float k}) +0:65 Constant: +0:65 0 (const int) +0:65 y: direct index for structure ( global highp float) +0:65 structUniform: direct index for structure ( uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z}) +0:65 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b, uniform highp 2-component vector of float c, uniform 10-element array of highp 4-component vector of float d, uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z} structUniform}) +0:65 Constant: +0:65 4 (const uint) +0:65 Constant: +0:65 1 (const int) +0:65 Convert uint to float ( temp highp float) +0:65 z: direct index for structure ( global highp uint) +0:65 structUniform: direct index for structure ( uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z}) +0:65 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b, uniform highp 2-component vector of float c, uniform 10-element array of highp 4-component vector of float d, uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z} structUniform}) +0:65 Constant: +0:65 4 (const uint) +0:65 Constant: +0:65 2 (const int) +0:66 Sequence +0:66 move second child to first child ( temp highp 2-component vector of float) +0:66 'v2' ( temp highp 2-component vector of float) +0:66 add ( temp highp 2-component vector of float) +0:66 add ( temp highp 2-component vector of float) +0:66 b: direct index for structure ( uniform highp 2-component vector of float) +0:66 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b, uniform highp 2-component vector of float c, uniform 10-element array of highp 4-component vector of float d, uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z} structUniform}) +0:66 Constant: +0:66 1 (const uint) +0:66 c: direct index for structure ( uniform highp 2-component vector of float) +0:66 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b, uniform highp 2-component vector of float c, uniform 10-element array of highp 4-component vector of float d, uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z} structUniform}) +0:66 Constant: +0:66 2 (const uint) +0:66 x: direct index for structure ( global highp 2-component vector of float) +0:66 structUniform: direct index for structure ( uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z}) +0:66 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b, uniform highp 2-component vector of float c, uniform 10-element array of highp 4-component vector of float d, uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z} structUniform}) +0:66 Constant: +0:66 4 (const uint) +0:66 Constant: +0:66 0 (const int) +0:67 Sequence +0:67 move second child to first child ( temp highp 4-component vector of float) +0:67 'v4' ( temp highp 4-component vector of float) +0:67 add ( temp highp 4-component vector of float) +0:67 add ( temp highp 4-component vector of float) +0:67 add ( temp highp 4-component vector of float) +0:67 add ( temp highp 4-component vector of float) +0:67 add ( temp highp 4-component vector of float) +0:67 add ( temp highp 4-component vector of float) +0:67 a: direct index for structure ( uniform highp 4-component vector of float) +0:67 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b, uniform highp 2-component vector of float c, uniform 10-element array of highp 4-component vector of float d, uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z} structUniform}) +0:67 Constant: +0:67 0 (const uint) +0:67 direct index ( temp highp 4-component vector of float) +0:67 d: direct index for structure ( uniform 10-element array of highp 4-component vector of float) +0:67 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b, uniform highp 2-component vector of float c, uniform 10-element array of highp 4-component vector of float d, uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z} structUniform}) +0:67 Constant: +0:67 3 (const uint) +0:67 Constant: +0:67 0 (const int) +0:67 direct index ( temp highp 4-component vector of float) +0:67 d: direct index for structure ( uniform 10-element array of highp 4-component vector of float) +0:67 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b, uniform highp 2-component vector of float c, uniform 10-element array of highp 4-component vector of float d, uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z} structUniform}) +0:67 Constant: +0:67 3 (const uint) +0:67 Constant: +0:67 1 (const int) +0:67 direct index ( temp highp 4-component vector of float) +0:67 d: direct index for structure ( uniform 10-element array of highp 4-component vector of float) +0:67 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b, uniform highp 2-component vector of float c, uniform 10-element array of highp 4-component vector of float d, uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z} structUniform}) +0:67 Constant: +0:67 3 (const uint) +0:67 Constant: +0:67 2 (const int) +0:67 k: direct index for structure (layout( column_major std140) uniform highp 4-component vector of float) +0:67 'anon@1' (layout( column_major std140) uniform block{layout( column_major std140) uniform highp float j, layout( column_major std140) uniform highp 4-component vector of float k}) +0:67 Constant: +0:67 1 (const uint) +0:67 k: direct index for structure (layout( column_major std430) buffer highp 4-component vector of float) +0:67 'bufferInstance' (layout( column_major std430) buffer block{layout( column_major std430) buffer highp float j, layout( column_major std430) buffer highp 4-component vector of float k}) +0:67 Constant: +0:67 1 (const int) +0:67 texture ( global highp 4-component vector of float) +0:67 't1' ( uniform highp sampler2D) +0:67 Constant: +0:67 0.000000 +0:67 0.000000 +0:68 Branch: Return with expression +0:68 component-wise multiply ( temp highp 4-component vector of float) +0:68 component-wise multiply ( temp highp 4-component vector of float) +0:68 Construct vec4 ( temp highp 4-component vector of float) +0:68 'f' ( temp highp float) +0:68 Construct vec4 ( temp highp 4-component vector of float) +0:68 'v2' ( temp highp 2-component vector of float) +0:68 Constant: +0:68 1.000000 +0:68 Constant: +0:68 1.000000 +0:68 'v4' ( temp highp 4-component vector of float) +0:71 Function Definition: main( ( global void) +0:71 Function Parameters: +0:72 Sequence +0:72 Sequence +0:72 move second child to first child ( temp highp float) +0:72 'j' ( temp highp float) +0:72 Convert uint to float ( temp highp float) +0:72 Function Call: bar( ( global highp uint) +0:73 move second child to first child ( temp highp 4-component vector of float) +0:73 'o' ( out highp 4-component vector of float) +0:73 vector-scale ( temp highp 4-component vector of float) +0:73 'j' ( temp highp float) +0:73 Function Call: foo( ( global highp 4-component vector of float) +0:? Linker Objects +0:? 'o' ( out highp 4-component vector of float) +0:? 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b, uniform highp 2-component vector of float c, uniform 10-element array of highp 4-component vector of float d, uniform structure{ global highp 2-component vector of float x, global highp float y, global highp uint z} structUniform}) +0:? 't1' ( uniform highp sampler2D) +0:? 'anon@1' (layout( column_major std140) uniform block{layout( column_major std140) uniform highp float j, layout( column_major std140) uniform highp 4-component vector of float k}) +0:? 'bufferInstance' (layout( column_major std430) buffer block{layout( column_major std430) buffer highp float j, layout( column_major std430) buffer highp 4-component vector of float k}) +0:? 'anon@2' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:? 'anon@3' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter3}) + +// Module Version 10000 +// Generated by (magic number): 8000a +// Id's are bound by 163 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "main" 159 + ExecutionMode 4 OriginUpperLeft + Source GLSL 460 + Name 4 "main" + Name 8 "bar(" + Name 13 "foo(" + Name 16 "j" + Name 18 "gl_AtomicCounterBlock_0" + MemberName 18(gl_AtomicCounterBlock_0) 0 "counter1" + MemberName 18(gl_AtomicCounterBlock_0) 1 "counter2" + Name 20 "" + Name 63 "gl_AtomicCounterBlock_1" + MemberName 63(gl_AtomicCounterBlock_1) 0 "counter3" + Name 65 "" + Name 73 "f" + Name 74 "UniformBlock" + MemberName 74(UniformBlock) 0 "j" + MemberName 74(UniformBlock) 1 "k" + Name 76 "" + Name 80 "BufferBlock" + MemberName 80(BufferBlock) 0 "j" + MemberName 80(BufferBlock) 1 "k" + Name 82 "bufferInstance" + Name 89 "e" + MemberName 89(e) 0 "x" + MemberName 89(e) 1 "y" + MemberName 89(e) 2 "z" + Name 90 "gl_DefaultUniformBlock" + MemberName 90(gl_DefaultUniformBlock) 0 "a" + MemberName 90(gl_DefaultUniformBlock) 1 "b" + MemberName 90(gl_DefaultUniformBlock) 2 "c" + MemberName 90(gl_DefaultUniformBlock) 3 "d" + MemberName 90(gl_DefaultUniformBlock) 4 "structUniform" + Name 92 "" + Name 103 "v2" + Name 114 "v4" + Name 137 "t1" + Name 155 "j" + Name 159 "o" + MemberDecorate 18(gl_AtomicCounterBlock_0) 0 Coherent + MemberDecorate 18(gl_AtomicCounterBlock_0) 0 Volatile + MemberDecorate 18(gl_AtomicCounterBlock_0) 0 Coherent + MemberDecorate 18(gl_AtomicCounterBlock_0) 0 Offset 0 + MemberDecorate 18(gl_AtomicCounterBlock_0) 1 Coherent + MemberDecorate 18(gl_AtomicCounterBlock_0) 1 Volatile + MemberDecorate 18(gl_AtomicCounterBlock_0) 1 Coherent + MemberDecorate 18(gl_AtomicCounterBlock_0) 1 Offset 4 + Decorate 18(gl_AtomicCounterBlock_0) BufferBlock + Decorate 20 DescriptorSet 0 + Decorate 20 Binding 4 + MemberDecorate 63(gl_AtomicCounterBlock_1) 0 Coherent + MemberDecorate 63(gl_AtomicCounterBlock_1) 0 Volatile + MemberDecorate 63(gl_AtomicCounterBlock_1) 0 Coherent + MemberDecorate 63(gl_AtomicCounterBlock_1) 0 Offset 0 + Decorate 63(gl_AtomicCounterBlock_1) BufferBlock + Decorate 65 DescriptorSet 0 + Decorate 65 Binding 5 + MemberDecorate 74(UniformBlock) 0 Offset 0 + MemberDecorate 74(UniformBlock) 1 Offset 16 + Decorate 74(UniformBlock) Block + Decorate 76 DescriptorSet 0 + Decorate 76 Binding 2 + MemberDecorate 80(BufferBlock) 0 Offset 0 + MemberDecorate 80(BufferBlock) 1 Offset 16 + Decorate 80(BufferBlock) BufferBlock + Decorate 82(bufferInstance) DescriptorSet 0 + Decorate 82(bufferInstance) Binding 3 + Decorate 88 ArrayStride 16 + MemberDecorate 89(e) 0 Offset 0 + MemberDecorate 89(e) 1 Offset 8 + MemberDecorate 89(e) 2 Offset 12 + MemberDecorate 90(gl_DefaultUniformBlock) 0 Offset 0 + MemberDecorate 90(gl_DefaultUniformBlock) 1 Offset 16 + MemberDecorate 90(gl_DefaultUniformBlock) 2 Offset 24 + MemberDecorate 90(gl_DefaultUniformBlock) 3 Offset 32 + MemberDecorate 90(gl_DefaultUniformBlock) 4 Offset 192 + Decorate 90(gl_DefaultUniformBlock) Block + Decorate 92 DescriptorSet 0 + Decorate 92 Binding 0 + Decorate 137(t1) DescriptorSet 0 + Decorate 137(t1) Binding 1 + Decorate 159(o) Location 0 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeInt 32 0 + 7: TypeFunction 6(int) + 10: TypeFloat 32 + 11: TypeVector 10(float) 4 + 12: TypeFunction 11(fvec4) + 15: TypePointer Function 6(int) + 17: 6(int) Constant 0 +18(gl_AtomicCounterBlock_0): TypeStruct 6(int) 6(int) + 19: TypePointer Uniform 18(gl_AtomicCounterBlock_0) + 20: 19(ptr) Variable Uniform + 21: TypeInt 32 1 + 22: 21(int) Constant 0 + 23: TypePointer Uniform 6(int) + 25: 6(int) Constant 1 + 28: 6(int) Constant 4294967295 + 60: 21(int) Constant 1 +63(gl_AtomicCounterBlock_1): TypeStruct 6(int) + 64: TypePointer Uniform 63(gl_AtomicCounterBlock_1) + 65: 64(ptr) Variable Uniform + 68: 6(int) Constant 72 + 72: TypePointer Function 10(float) +74(UniformBlock): TypeStruct 10(float) 11(fvec4) + 75: TypePointer Uniform 74(UniformBlock) + 76: 75(ptr) Variable Uniform + 77: TypePointer Uniform 10(float) + 80(BufferBlock): TypeStruct 10(float) 11(fvec4) + 81: TypePointer Uniform 80(BufferBlock) +82(bufferInstance): 81(ptr) Variable Uniform + 86: TypeVector 10(float) 2 + 87: 6(int) Constant 10 + 88: TypeArray 11(fvec4) 87 + 89(e): TypeStruct 86(fvec2) 10(float) 6(int) +90(gl_DefaultUniformBlock): TypeStruct 11(fvec4) 86(fvec2) 86(fvec2) 88 89(e) + 91: TypePointer Uniform 90(gl_DefaultUniformBlock) + 92: 91(ptr) Variable Uniform + 93: 21(int) Constant 4 + 97: 21(int) Constant 2 + 102: TypePointer Function 86(fvec2) + 104: TypePointer Uniform 86(fvec2) + 113: TypePointer Function 11(fvec4) + 115: TypePointer Uniform 11(fvec4) + 118: 21(int) Constant 3 + 134: TypeImage 10(float) 2D sampled format:Unknown + 135: TypeSampledImage 134 + 136: TypePointer UniformConstant 135 + 137(t1): 136(ptr) Variable UniformConstant + 139: 10(float) Constant 0 + 140: 86(fvec2) ConstantComposite 139 139 + 146: 10(float) Constant 1065353216 + 158: TypePointer Output 11(fvec4) + 159(o): 158(ptr) Variable Output + 4(main): 2 Function None 3 + 5: Label + 155(j): 72(ptr) Variable Function + 156: 6(int) FunctionCall 8(bar() + 157: 10(float) ConvertUToF 156 + Store 155(j) 157 + 160: 10(float) Load 155(j) + 161: 11(fvec4) FunctionCall 13(foo() + 162: 11(fvec4) VectorTimesScalar 161 160 + Store 159(o) 162 + Return + FunctionEnd + 8(bar(): 6(int) Function None 7 + 9: Label + 16(j): 15(ptr) Variable Function + Store 16(j) 17 + 24: 23(ptr) AccessChain 20 22 + 26: 6(int) AtomicIAdd 24 25 17 25 + Store 16(j) 26 + 27: 23(ptr) AccessChain 20 22 + 29: 6(int) AtomicIAdd 27 25 17 28 + 30: 6(int) ISub 29 25 + Store 16(j) 30 + 31: 23(ptr) AccessChain 20 22 + 32: 6(int) Load 31 + Store 16(j) 32 + 33: 23(ptr) AccessChain 20 22 + 34: 6(int) AtomicIAdd 33 25 17 25 + Store 16(j) 34 + 35: 23(ptr) AccessChain 20 22 + 36: 6(int) AtomicIAdd 35 25 17 28 + Store 16(j) 36 + 37: 23(ptr) AccessChain 20 22 + 38: 6(int) AtomicISub 37 25 17 25 + Store 16(j) 38 + 39: 23(ptr) AccessChain 20 22 + 40: 6(int) Load 16(j) + 41: 6(int) AtomicUMin 39 25 17 40 + Store 16(j) 41 + 42: 23(ptr) AccessChain 20 22 + 43: 6(int) Load 16(j) + 44: 6(int) AtomicUMax 42 25 17 43 + Store 16(j) 44 + 45: 23(ptr) AccessChain 20 22 + 46: 6(int) Load 16(j) + 47: 6(int) AtomicAnd 45 25 17 46 + Store 16(j) 47 + 48: 23(ptr) AccessChain 20 22 + 49: 6(int) Load 16(j) + 50: 6(int) AtomicOr 48 25 17 49 + Store 16(j) 50 + 51: 23(ptr) AccessChain 20 22 + 52: 6(int) Load 16(j) + 53: 6(int) AtomicXor 51 25 17 52 + Store 16(j) 53 + 54: 23(ptr) AccessChain 20 22 + 55: 6(int) Load 16(j) + 56: 6(int) AtomicExchange 54 25 17 55 + Store 16(j) 56 + 57: 23(ptr) AccessChain 20 22 + 58: 6(int) Load 16(j) + 59: 6(int) AtomicCompareExchange 57 25 17 17 58 17 + Store 16(j) 59 + 61: 23(ptr) AccessChain 20 60 + 62: 6(int) AtomicIAdd 61 25 17 25 + 66: 23(ptr) AccessChain 65 22 + 67: 6(int) AtomicIAdd 66 25 17 25 + MemoryBarrier 25 68 + 69: 6(int) Load 16(j) + ReturnValue 69 + FunctionEnd + 13(foo(): 11(fvec4) Function None 12 + 14: Label + 73(f): 72(ptr) Variable Function + 103(v2): 102(ptr) Variable Function + 114(v4): 113(ptr) Variable Function + 78: 77(ptr) AccessChain 76 22 + 79: 10(float) Load 78 + 83: 77(ptr) AccessChain 82(bufferInstance) 22 + 84: 10(float) Load 83 + 85: 10(float) FAdd 79 84 + 94: 77(ptr) AccessChain 92 93 60 + 95: 10(float) Load 94 + 96: 10(float) FAdd 85 95 + 98: 23(ptr) AccessChain 92 93 97 + 99: 6(int) Load 98 + 100: 10(float) ConvertUToF 99 + 101: 10(float) FAdd 96 100 + Store 73(f) 101 + 105: 104(ptr) AccessChain 92 60 + 106: 86(fvec2) Load 105 + 107: 104(ptr) AccessChain 92 97 + 108: 86(fvec2) Load 107 + 109: 86(fvec2) FAdd 106 108 + 110: 104(ptr) AccessChain 92 93 22 + 111: 86(fvec2) Load 110 + 112: 86(fvec2) FAdd 109 111 + Store 103(v2) 112 + 116: 115(ptr) AccessChain 92 22 + 117: 11(fvec4) Load 116 + 119: 115(ptr) AccessChain 92 118 22 + 120: 11(fvec4) Load 119 + 121: 11(fvec4) FAdd 117 120 + 122: 115(ptr) AccessChain 92 118 60 + 123: 11(fvec4) Load 122 + 124: 11(fvec4) FAdd 121 123 + 125: 115(ptr) AccessChain 92 118 97 + 126: 11(fvec4) Load 125 + 127: 11(fvec4) FAdd 124 126 + 128: 115(ptr) AccessChain 76 60 + 129: 11(fvec4) Load 128 + 130: 11(fvec4) FAdd 127 129 + 131: 115(ptr) AccessChain 82(bufferInstance) 60 + 132: 11(fvec4) Load 131 + 133: 11(fvec4) FAdd 130 132 + 138: 135 Load 137(t1) + 141: 11(fvec4) ImageSampleImplicitLod 138 140 + 142: 11(fvec4) FAdd 133 141 + Store 114(v4) 142 + 143: 10(float) Load 73(f) + 144: 11(fvec4) CompositeConstruct 143 143 143 143 + 145: 86(fvec2) Load 103(v2) + 147: 10(float) CompositeExtract 145 0 + 148: 10(float) CompositeExtract 145 1 + 149: 11(fvec4) CompositeConstruct 147 148 146 146 + 150: 11(fvec4) FMul 144 149 + 151: 11(fvec4) Load 114(v4) + 152: 11(fvec4) FMul 150 151 + ReturnValue 152 + FunctionEnd diff --git a/Test/baseResults/vk.relaxed.link1.frag.out b/Test/baseResults/vk.relaxed.link1.frag.out new file mode 100644 index 00000000..9dac4c64 --- /dev/null +++ b/Test/baseResults/vk.relaxed.link1.frag.out @@ -0,0 +1,515 @@ +vk.relaxed.link1.frag +Shader version: 460 +gl_FragCoord origin is upper left +0:? Sequence +0:19 Function Definition: bar( ( global highp 4-component vector of float) +0:19 Function Parameters: +0:20 Sequence +0:20 Sequence +0:20 move second child to first child ( temp highp uint) +0:20 'j' ( temp highp uint) +0:20 add ( temp highp uint) +0:20 AtomicAdd ( global highp uint) +0:20 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:20 'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:20 Constant: +0:20 0 (const uint) +0:20 Constant: +0:20 1 (const uint) +0:20 subtract ( temp highp uint) +0:20 AtomicAdd ( global highp uint) +0:20 counter2: direct index for structure ( coherent volatile buffer highp uint) +0:20 'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:20 Constant: +0:20 1 (const uint) +0:20 Constant: +0:20 4294967295 (const uint) +0:20 Constant: +0:20 1 (const uint) +0:21 Sequence +0:21 move second child to first child ( temp highp 4-component vector of float) +0:21 'v' ( temp highp 4-component vector of float) +0:21 add ( temp highp 4-component vector of float) +0:21 add ( temp highp 4-component vector of float) +0:21 add ( temp highp 4-component vector of float) +0:21 a: direct index for structure ( uniform highp 4-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d}) +0:21 Constant: +0:21 0 (const uint) +0:21 Construct vec4 ( temp highp 4-component vector of float) +0:21 direct index ( temp highp float) +0:21 b1: direct index for structure ( uniform highp 2-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d}) +0:21 Constant: +0:21 1 (const uint) +0:21 Constant: +0:21 0 (const int) +0:21 direct index ( temp highp float) +0:21 b1: direct index for structure ( uniform highp 2-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d}) +0:21 Constant: +0:21 1 (const uint) +0:21 Constant: +0:21 1 (const int) +0:21 direct index ( temp highp float) +0:21 b2: direct index for structure ( uniform highp 2-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d}) +0:21 Constant: +0:21 2 (const uint) +0:21 Constant: +0:21 0 (const int) +0:21 direct index ( temp highp float) +0:21 b2: direct index for structure ( uniform highp 2-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d}) +0:21 Constant: +0:21 2 (const uint) +0:21 Constant: +0:21 1 (const int) +0:21 c1: direct index for structure ( uniform highp 4-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d}) +0:21 Constant: +0:21 3 (const uint) +0:21 d: direct index for structure ( uniform highp 4-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d}) +0:21 Constant: +0:21 4 (const uint) +0:23 Branch: Return with expression +0:23 vector-scale ( temp highp 4-component vector of float) +0:23 Convert uint to float ( temp highp float) +0:23 'j' ( temp highp uint) +0:23 'v' ( temp highp 4-component vector of float) +0:26 Function Definition: main( ( global void) +0:26 Function Parameters: +0:27 Sequence +0:27 move second child to first child ( temp highp 4-component vector of float) +0:27 'o' ( out highp 4-component vector of float) +0:27 add ( temp highp 4-component vector of float) +0:27 Function Call: foo( ( global highp 4-component vector of float) +0:27 Function Call: bar( ( global highp 4-component vector of float) +0:? Linker Objects +0:? 'o' ( out highp 4-component vector of float) +0:? 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d}) +0:? 'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) + +vk.relaxed.link2.frag +Shader version: 460 +gl_FragCoord origin is upper left +0:? Sequence +0:14 Function Definition: foo( ( global highp 4-component vector of float) +0:14 Function Parameters: +0:15 Sequence +0:15 Sequence +0:15 move second child to first child ( temp highp uint) +0:15 'j' ( temp highp uint) +0:15 add ( temp highp uint) +0:15 AtomicAdd ( global highp uint) +0:15 counter2: direct index for structure ( coherent volatile buffer highp uint) +0:15 'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter3, coherent volatile buffer highp uint counter2}) +0:15 Constant: +0:15 1 (const uint) +0:15 Constant: +0:15 1 (const uint) +0:15 subtract ( temp highp uint) +0:15 AtomicAdd ( global highp uint) +0:15 counter3: direct index for structure ( coherent volatile buffer highp uint) +0:15 'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter3, coherent volatile buffer highp uint counter2}) +0:15 Constant: +0:15 0 (const uint) +0:15 Constant: +0:15 4294967295 (const uint) +0:15 Constant: +0:15 1 (const uint) +0:16 Sequence +0:16 move second child to first child ( temp highp 4-component vector of float) +0:16 'v' ( temp highp 4-component vector of float) +0:16 add ( temp highp 4-component vector of float) +0:16 add ( temp highp 4-component vector of float) +0:16 add ( temp highp 4-component vector of float) +0:16 a: direct index for structure ( uniform highp 4-component vector of float) +0:16 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d}) +0:16 Constant: +0:16 0 (const uint) +0:16 Construct vec4 ( temp highp 4-component vector of float) +0:16 direct index ( temp highp float) +0:16 b1: direct index for structure ( uniform highp 2-component vector of float) +0:16 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d}) +0:16 Constant: +0:16 2 (const uint) +0:16 Constant: +0:16 0 (const int) +0:16 direct index ( temp highp float) +0:16 b1: direct index for structure ( uniform highp 2-component vector of float) +0:16 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d}) +0:16 Constant: +0:16 2 (const uint) +0:16 Constant: +0:16 1 (const int) +0:16 direct index ( temp highp float) +0:16 b2: direct index for structure ( uniform highp 2-component vector of float) +0:16 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d}) +0:16 Constant: +0:16 1 (const uint) +0:16 Constant: +0:16 0 (const int) +0:16 direct index ( temp highp float) +0:16 b2: direct index for structure ( uniform highp 2-component vector of float) +0:16 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d}) +0:16 Constant: +0:16 1 (const uint) +0:16 Constant: +0:16 1 (const int) +0:16 c2: direct index for structure ( uniform highp 4-component vector of float) +0:16 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d}) +0:16 Constant: +0:16 3 (const uint) +0:16 d: direct index for structure ( uniform highp 4-component vector of float) +0:16 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d}) +0:16 Constant: +0:16 4 (const uint) +0:18 Branch: Return with expression +0:18 vector-scale ( temp highp 4-component vector of float) +0:18 Convert uint to float ( temp highp float) +0:18 'j' ( temp highp uint) +0:18 'v' ( temp highp 4-component vector of float) +0:? Linker Objects +0:? 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d}) +0:? 'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter3, coherent volatile buffer highp uint counter2}) + + +Linked fragment stage: + + +Shader version: 460 +gl_FragCoord origin is upper left +0:? Sequence +0:19 Function Definition: bar( ( global highp 4-component vector of float) +0:19 Function Parameters: +0:20 Sequence +0:20 Sequence +0:20 move second child to first child ( temp highp uint) +0:20 'j' ( temp highp uint) +0:20 add ( temp highp uint) +0:20 AtomicAdd ( global highp uint) +0:20 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:20 'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2, coherent volatile buffer highp uint counter3}) +0:20 Constant: +0:20 0 (const uint) +0:20 Constant: +0:20 1 (const uint) +0:20 subtract ( temp highp uint) +0:20 AtomicAdd ( global highp uint) +0:20 counter2: direct index for structure ( coherent volatile buffer highp uint) +0:20 'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2, coherent volatile buffer highp uint counter3}) +0:20 Constant: +0:20 1 (const uint) +0:20 Constant: +0:20 4294967295 (const uint) +0:20 Constant: +0:20 1 (const uint) +0:21 Sequence +0:21 move second child to first child ( temp highp 4-component vector of float) +0:21 'v' ( temp highp 4-component vector of float) +0:21 add ( temp highp 4-component vector of float) +0:21 add ( temp highp 4-component vector of float) +0:21 add ( temp highp 4-component vector of float) +0:21 a: direct index for structure ( uniform highp 4-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d, uniform highp 4-component vector of float c2}) +0:21 Constant: +0:21 0 (const uint) +0:21 Construct vec4 ( temp highp 4-component vector of float) +0:21 direct index ( temp highp float) +0:21 b1: direct index for structure ( uniform highp 2-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d, uniform highp 4-component vector of float c2}) +0:21 Constant: +0:21 1 (const uint) +0:21 Constant: +0:21 0 (const int) +0:21 direct index ( temp highp float) +0:21 b1: direct index for structure ( uniform highp 2-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d, uniform highp 4-component vector of float c2}) +0:21 Constant: +0:21 1 (const uint) +0:21 Constant: +0:21 1 (const int) +0:21 direct index ( temp highp float) +0:21 b2: direct index for structure ( uniform highp 2-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d, uniform highp 4-component vector of float c2}) +0:21 Constant: +0:21 2 (const uint) +0:21 Constant: +0:21 0 (const int) +0:21 direct index ( temp highp float) +0:21 b2: direct index for structure ( uniform highp 2-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d, uniform highp 4-component vector of float c2}) +0:21 Constant: +0:21 2 (const uint) +0:21 Constant: +0:21 1 (const int) +0:21 c1: direct index for structure ( uniform highp 4-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d, uniform highp 4-component vector of float c2}) +0:21 Constant: +0:21 3 (const uint) +0:21 d: direct index for structure ( uniform highp 4-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d, uniform highp 4-component vector of float c2}) +0:21 Constant: +0:21 4 (const uint) +0:23 Branch: Return with expression +0:23 vector-scale ( temp highp 4-component vector of float) +0:23 Convert uint to float ( temp highp float) +0:23 'j' ( temp highp uint) +0:23 'v' ( temp highp 4-component vector of float) +0:26 Function Definition: main( ( global void) +0:26 Function Parameters: +0:27 Sequence +0:27 move second child to first child ( temp highp 4-component vector of float) +0:27 'o' ( out highp 4-component vector of float) +0:27 add ( temp highp 4-component vector of float) +0:27 Function Call: foo( ( global highp 4-component vector of float) +0:27 Function Call: bar( ( global highp 4-component vector of float) +0:14 Function Definition: foo( ( global highp 4-component vector of float) +0:14 Function Parameters: +0:15 Sequence +0:15 Sequence +0:15 move second child to first child ( temp highp uint) +0:15 'j' ( temp highp uint) +0:15 add ( temp highp uint) +0:15 AtomicAdd ( global highp uint) +0:15 counter2: direct index for structure ( coherent volatile buffer highp uint) +0:15 'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2, coherent volatile buffer highp uint counter3}) +0:15 Constant: +0:15 1 (const uint) +0:15 Constant: +0:15 1 (const uint) +0:15 subtract ( temp highp uint) +0:15 AtomicAdd ( global highp uint) +0:15 counter3: direct index for structure ( coherent volatile buffer highp uint) +0:15 'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2, coherent volatile buffer highp uint counter3}) +0:15 Constant: +0:15 2 (const uint) +0:15 Constant: +0:15 4294967295 (const uint) +0:15 Constant: +0:15 1 (const uint) +0:16 Sequence +0:16 move second child to first child ( temp highp 4-component vector of float) +0:16 'v' ( temp highp 4-component vector of float) +0:16 add ( temp highp 4-component vector of float) +0:16 add ( temp highp 4-component vector of float) +0:16 add ( temp highp 4-component vector of float) +0:16 a: direct index for structure ( uniform highp 4-component vector of float) +0:16 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d, uniform highp 4-component vector of float c2}) +0:16 Constant: +0:16 0 (const uint) +0:16 Construct vec4 ( temp highp 4-component vector of float) +0:16 direct index ( temp highp float) +0:16 b1: direct index for structure ( uniform highp 2-component vector of float) +0:16 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d, uniform highp 4-component vector of float c2}) +0:16 Constant: +0:16 1 (const uint) +0:16 Constant: +0:16 0 (const int) +0:16 direct index ( temp highp float) +0:16 b1: direct index for structure ( uniform highp 2-component vector of float) +0:16 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d, uniform highp 4-component vector of float c2}) +0:16 Constant: +0:16 1 (const uint) +0:16 Constant: +0:16 1 (const int) +0:16 direct index ( temp highp float) +0:16 b2: direct index for structure ( uniform highp 2-component vector of float) +0:16 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d, uniform highp 4-component vector of float c2}) +0:16 Constant: +0:16 2 (const uint) +0:16 Constant: +0:16 0 (const int) +0:16 direct index ( temp highp float) +0:16 b2: direct index for structure ( uniform highp 2-component vector of float) +0:16 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d, uniform highp 4-component vector of float c2}) +0:16 Constant: +0:16 2 (const uint) +0:16 Constant: +0:16 1 (const int) +0:16 c2: direct index for structure ( uniform highp 4-component vector of float) +0:16 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d, uniform highp 4-component vector of float c2}) +0:16 Constant: +0:16 5 (const uint) +0:16 d: direct index for structure ( uniform highp 4-component vector of float) +0:16 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d, uniform highp 4-component vector of float c2}) +0:16 Constant: +0:16 4 (const uint) +0:18 Branch: Return with expression +0:18 vector-scale ( temp highp 4-component vector of float) +0:18 Convert uint to float ( temp highp float) +0:18 'j' ( temp highp uint) +0:18 'v' ( temp highp 4-component vector of float) +0:? Linker Objects +0:? 'o' ( out highp 4-component vector of float) +0:? 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d, uniform highp 4-component vector of float c2}) +0:? 'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2, coherent volatile buffer highp uint counter3}) + +// Module Version 10000 +// Generated by (magic number): 8000a +// Id's are bound by 105 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "main" 68 + ExecutionMode 4 OriginUpperLeft + Source GLSL 460 + Name 4 "main" + Name 9 "bar(" + Name 11 "foo(" + Name 15 "j" + Name 16 "gl_AtomicCounterBlock_0" + MemberName 16(gl_AtomicCounterBlock_0) 0 "counter1" + MemberName 16(gl_AtomicCounterBlock_0) 1 "counter2" + MemberName 16(gl_AtomicCounterBlock_0) 2 "counter3" + Name 18 "" + Name 33 "v" + Name 35 "gl_DefaultUniformBlock" + MemberName 35(gl_DefaultUniformBlock) 0 "a" + MemberName 35(gl_DefaultUniformBlock) 1 "b1" + MemberName 35(gl_DefaultUniformBlock) 2 "b2" + MemberName 35(gl_DefaultUniformBlock) 3 "c1" + MemberName 35(gl_DefaultUniformBlock) 4 "d" + MemberName 35(gl_DefaultUniformBlock) 5 "c2" + Name 37 "" + Name 68 "o" + Name 72 "j" + Name 79 "v" + MemberDecorate 16(gl_AtomicCounterBlock_0) 0 Coherent + MemberDecorate 16(gl_AtomicCounterBlock_0) 0 Volatile + MemberDecorate 16(gl_AtomicCounterBlock_0) 0 Coherent + MemberDecorate 16(gl_AtomicCounterBlock_0) 0 Offset 0 + MemberDecorate 16(gl_AtomicCounterBlock_0) 1 Coherent + MemberDecorate 16(gl_AtomicCounterBlock_0) 1 Volatile + MemberDecorate 16(gl_AtomicCounterBlock_0) 1 Coherent + MemberDecorate 16(gl_AtomicCounterBlock_0) 1 Offset 4 + MemberDecorate 16(gl_AtomicCounterBlock_0) 2 Coherent + MemberDecorate 16(gl_AtomicCounterBlock_0) 2 Volatile + MemberDecorate 16(gl_AtomicCounterBlock_0) 2 Coherent + MemberDecorate 16(gl_AtomicCounterBlock_0) 2 Offset 8 + Decorate 16(gl_AtomicCounterBlock_0) BufferBlock + Decorate 18 DescriptorSet 0 + Decorate 18 Binding 1 + MemberDecorate 35(gl_DefaultUniformBlock) 0 Offset 0 + MemberDecorate 35(gl_DefaultUniformBlock) 1 Offset 16 + MemberDecorate 35(gl_DefaultUniformBlock) 2 Offset 24 + MemberDecorate 35(gl_DefaultUniformBlock) 3 Offset 32 + MemberDecorate 35(gl_DefaultUniformBlock) 4 Offset 48 + MemberDecorate 35(gl_DefaultUniformBlock) 5 Offset 64 + Decorate 35(gl_DefaultUniformBlock) Block + Decorate 37 DescriptorSet 0 + Decorate 37 Binding 0 + Decorate 68(o) Location 0 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8: TypeFunction 7(fvec4) + 13: TypeInt 32 0 + 14: TypePointer Function 13(int) +16(gl_AtomicCounterBlock_0): TypeStruct 13(int) 13(int) 13(int) + 17: TypePointer Uniform 16(gl_AtomicCounterBlock_0) + 18: 17(ptr) Variable Uniform + 19: TypeInt 32 1 + 20: 19(int) Constant 0 + 21: TypePointer Uniform 13(int) + 23: 13(int) Constant 1 + 24: 13(int) Constant 0 + 26: 19(int) Constant 1 + 28: 13(int) Constant 4294967295 + 32: TypePointer Function 7(fvec4) + 34: TypeVector 6(float) 2 +35(gl_DefaultUniformBlock): TypeStruct 7(fvec4) 34(fvec2) 34(fvec2) 7(fvec4) 7(fvec4) 7(fvec4) + 36: TypePointer Uniform 35(gl_DefaultUniformBlock) + 37: 36(ptr) Variable Uniform + 38: TypePointer Uniform 7(fvec4) + 41: TypePointer Uniform 6(float) + 46: 19(int) Constant 2 + 53: 19(int) Constant 3 + 57: 19(int) Constant 4 + 67: TypePointer Output 7(fvec4) + 68(o): 67(ptr) Variable Output + 92: 19(int) Constant 5 + 4(main): 2 Function None 3 + 5: Label + 69: 7(fvec4) FunctionCall 11(foo() + 70: 7(fvec4) FunctionCall 9(bar() + 71: 7(fvec4) FAdd 69 70 + Store 68(o) 71 + Return + FunctionEnd + 9(bar(): 7(fvec4) Function None 8 + 10: Label + 15(j): 14(ptr) Variable Function + 33(v): 32(ptr) Variable Function + 22: 21(ptr) AccessChain 18 20 + 25: 13(int) AtomicIAdd 22 23 24 23 + 27: 21(ptr) AccessChain 18 26 + 29: 13(int) AtomicIAdd 27 23 24 28 + 30: 13(int) ISub 29 23 + 31: 13(int) IAdd 25 30 + Store 15(j) 31 + 39: 38(ptr) AccessChain 37 20 + 40: 7(fvec4) Load 39 + 42: 41(ptr) AccessChain 37 26 24 + 43: 6(float) Load 42 + 44: 41(ptr) AccessChain 37 26 23 + 45: 6(float) Load 44 + 47: 41(ptr) AccessChain 37 46 24 + 48: 6(float) Load 47 + 49: 41(ptr) AccessChain 37 46 23 + 50: 6(float) Load 49 + 51: 7(fvec4) CompositeConstruct 43 45 48 50 + 52: 7(fvec4) FAdd 40 51 + 54: 38(ptr) AccessChain 37 53 + 55: 7(fvec4) Load 54 + 56: 7(fvec4) FAdd 52 55 + 58: 38(ptr) AccessChain 37 57 + 59: 7(fvec4) Load 58 + 60: 7(fvec4) FAdd 56 59 + Store 33(v) 60 + 61: 13(int) Load 15(j) + 62: 6(float) ConvertUToF 61 + 63: 7(fvec4) Load 33(v) + 64: 7(fvec4) VectorTimesScalar 63 62 + ReturnValue 64 + FunctionEnd + 11(foo(): 7(fvec4) Function None 8 + 12: Label + 72(j): 14(ptr) Variable Function + 79(v): 32(ptr) Variable Function + 73: 21(ptr) AccessChain 18 26 + 74: 13(int) AtomicIAdd 73 23 24 23 + 75: 21(ptr) AccessChain 18 46 + 76: 13(int) AtomicIAdd 75 23 24 28 + 77: 13(int) ISub 76 23 + 78: 13(int) IAdd 74 77 + Store 72(j) 78 + 80: 38(ptr) AccessChain 37 20 + 81: 7(fvec4) Load 80 + 82: 41(ptr) AccessChain 37 26 24 + 83: 6(float) Load 82 + 84: 41(ptr) AccessChain 37 26 23 + 85: 6(float) Load 84 + 86: 41(ptr) AccessChain 37 46 24 + 87: 6(float) Load 86 + 88: 41(ptr) AccessChain 37 46 23 + 89: 6(float) Load 88 + 90: 7(fvec4) CompositeConstruct 83 85 87 89 + 91: 7(fvec4) FAdd 81 90 + 93: 38(ptr) AccessChain 37 92 + 94: 7(fvec4) Load 93 + 95: 7(fvec4) FAdd 91 94 + 96: 38(ptr) AccessChain 37 57 + 97: 7(fvec4) Load 96 + 98: 7(fvec4) FAdd 95 97 + Store 79(v) 98 + 99: 13(int) Load 72(j) + 100: 6(float) ConvertUToF 99 + 101: 7(fvec4) Load 79(v) + 102: 7(fvec4) VectorTimesScalar 101 100 + ReturnValue 102 + FunctionEnd diff --git a/Test/baseResults/vk.relaxed.stagelink.vert.out b/Test/baseResults/vk.relaxed.stagelink.vert.out new file mode 100644 index 00000000..a63f10c3 --- /dev/null +++ b/Test/baseResults/vk.relaxed.stagelink.vert.out @@ -0,0 +1,717 @@ +vk.relaxed.stagelink.vert +Shader version: 460 +0:? Sequence +0:18 Function Definition: foo( ( global highp 4-component vector of float) +0:18 Function Parameters: +0:19 Sequence +0:19 Sequence +0:19 move second child to first child ( temp highp uint) +0:19 'j' ( temp highp uint) +0:19 add ( temp highp uint) +0:19 AtomicAdd ( global highp uint) +0:19 counter2: direct index for structure ( coherent volatile buffer highp uint) +0:19 'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter3, coherent volatile buffer highp uint counter2}) +0:19 Constant: +0:19 1 (const uint) +0:19 Constant: +0:19 1 (const uint) +0:19 subtract ( temp highp uint) +0:19 AtomicAdd ( global highp uint) +0:19 counter3: direct index for structure ( coherent volatile buffer highp uint) +0:19 'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter3, coherent volatile buffer highp uint counter2}) +0:19 Constant: +0:19 0 (const uint) +0:19 Constant: +0:19 4294967295 (const uint) +0:19 Constant: +0:19 1 (const uint) +0:20 Sequence +0:20 move second child to first child ( temp highp 4-component vector of float) +0:20 'v' ( temp highp 4-component vector of float) +0:20 add ( temp highp 4-component vector of float) +0:20 add ( temp highp 4-component vector of float) +0:20 add ( temp highp 4-component vector of float) +0:20 a: direct index for structure ( uniform highp 4-component vector of float) +0:20 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d, uniform 4-element array of highp 4-component vector of float s}) +0:20 Constant: +0:20 0 (const uint) +0:20 Construct vec4 ( temp highp 4-component vector of float) +0:20 direct index ( temp highp float) +0:20 b1: direct index for structure ( uniform highp 2-component vector of float) +0:20 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d, uniform 4-element array of highp 4-component vector of float s}) +0:20 Constant: +0:20 2 (const uint) +0:20 Constant: +0:20 0 (const int) +0:20 direct index ( temp highp float) +0:20 b1: direct index for structure ( uniform highp 2-component vector of float) +0:20 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d, uniform 4-element array of highp 4-component vector of float s}) +0:20 Constant: +0:20 2 (const uint) +0:20 Constant: +0:20 1 (const int) +0:20 direct index ( temp highp float) +0:20 b2: direct index for structure ( uniform highp 2-component vector of float) +0:20 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d, uniform 4-element array of highp 4-component vector of float s}) +0:20 Constant: +0:20 1 (const uint) +0:20 Constant: +0:20 0 (const int) +0:20 direct index ( temp highp float) +0:20 b2: direct index for structure ( uniform highp 2-component vector of float) +0:20 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d, uniform 4-element array of highp 4-component vector of float s}) +0:20 Constant: +0:20 1 (const uint) +0:20 Constant: +0:20 1 (const int) +0:20 c2: direct index for structure ( uniform highp 4-component vector of float) +0:20 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d, uniform 4-element array of highp 4-component vector of float s}) +0:20 Constant: +0:20 3 (const uint) +0:20 d: direct index for structure ( uniform highp 4-component vector of float) +0:20 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d, uniform 4-element array of highp 4-component vector of float s}) +0:20 Constant: +0:20 4 (const uint) +0:22 Branch: Return with expression +0:22 vector-scale ( temp highp 4-component vector of float) +0:22 Convert uint to float ( temp highp float) +0:22 'j' ( temp highp uint) +0:22 'v' ( temp highp 4-component vector of float) +0:25 Function Definition: main( ( global void) +0:25 Function Parameters: +0:27 Sequence +0:27 Sequence +0:27 move second child to first child ( temp highp 4-component vector of float) +0:27 'v' ( temp highp 4-component vector of float) +0:27 Function Call: foo( ( global highp 4-component vector of float) +0:28 move second child to first child ( temp highp 4-component vector of float) +0:28 'v' ( temp highp 4-component vector of float) +0:28 add ( temp highp 4-component vector of float) +0:28 'v' ( temp highp 4-component vector of float) +0:28 indirect index ( temp highp 4-component vector of float) +0:28 s: direct index for structure ( uniform 4-element array of highp 4-component vector of float) +0:28 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d, uniform 4-element array of highp 4-component vector of float s}) +0:28 Constant: +0:28 5 (const uint) +0:28 'gl_VertexID' ( in int VertexIndex) +0:29 move second child to first child ( temp highp float) +0:29 direct index ( temp highp float) +0:29 'v' ( temp highp 4-component vector of float) +0:29 Constant: +0:29 0 (const int) +0:29 subtract ( temp highp float) +0:29 direct index ( temp highp float) +0:29 'v' ( temp highp 4-component vector of float) +0:29 Constant: +0:29 0 (const int) +0:29 Convert int to float ( temp highp float) +0:29 'gl_InstanceID' ( in highp int InstanceIndex) +0:30 move second child to first child ( temp highp 4-component vector of float) +0:30 'io' (layout( location=0) smooth out highp 4-component vector of float) +0:30 'v' ( temp highp 4-component vector of float) +0:? Linker Objects +0:? 'io' (layout( location=0) smooth out highp 4-component vector of float) +0:? 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d, uniform 4-element array of highp 4-component vector of float s}) +0:? 'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter3, coherent volatile buffer highp uint counter2}) +0:? 'gl_VertexID' ( in int VertexIndex) +0:? 'gl_InstanceID' ( in int InstanceIndex) + +vk.relaxed.stagelink.frag +Shader version: 460 +gl_FragCoord origin is upper left +0:? Sequence +0:19 Function Definition: foo( ( global highp 4-component vector of float) +0:19 Function Parameters: +0:20 Sequence +0:20 Sequence +0:20 move second child to first child ( temp highp uint) +0:20 'j' ( temp highp uint) +0:20 add ( temp highp uint) +0:20 AtomicAdd ( global highp uint) +0:20 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:20 'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:20 Constant: +0:20 0 (const uint) +0:20 Constant: +0:20 1 (const uint) +0:20 subtract ( temp highp uint) +0:20 AtomicAdd ( global highp uint) +0:20 counter2: direct index for structure ( coherent volatile buffer highp uint) +0:20 'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:20 Constant: +0:20 1 (const uint) +0:20 Constant: +0:20 4294967295 (const uint) +0:20 Constant: +0:20 1 (const uint) +0:21 Sequence +0:21 move second child to first child ( temp highp 4-component vector of float) +0:21 'v' ( temp highp 4-component vector of float) +0:21 add ( temp highp 4-component vector of float) +0:21 add ( temp highp 4-component vector of float) +0:21 add ( temp highp 4-component vector of float) +0:21 a: direct index for structure ( uniform highp 4-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d}) +0:21 Constant: +0:21 0 (const uint) +0:21 Construct vec4 ( temp highp 4-component vector of float) +0:21 direct index ( temp highp float) +0:21 b1: direct index for structure ( uniform highp 2-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d}) +0:21 Constant: +0:21 1 (const uint) +0:21 Constant: +0:21 0 (const int) +0:21 direct index ( temp highp float) +0:21 b1: direct index for structure ( uniform highp 2-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d}) +0:21 Constant: +0:21 1 (const uint) +0:21 Constant: +0:21 1 (const int) +0:21 direct index ( temp highp float) +0:21 b2: direct index for structure ( uniform highp 2-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d}) +0:21 Constant: +0:21 2 (const uint) +0:21 Constant: +0:21 0 (const int) +0:21 direct index ( temp highp float) +0:21 b2: direct index for structure ( uniform highp 2-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d}) +0:21 Constant: +0:21 2 (const uint) +0:21 Constant: +0:21 1 (const int) +0:21 c1: direct index for structure ( uniform highp 4-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d}) +0:21 Constant: +0:21 3 (const uint) +0:21 d: direct index for structure ( uniform highp 4-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d}) +0:21 Constant: +0:21 4 (const uint) +0:23 Branch: Return with expression +0:23 vector-scale ( temp highp 4-component vector of float) +0:23 Convert uint to float ( temp highp float) +0:23 'j' ( temp highp uint) +0:23 'v' ( temp highp 4-component vector of float) +0:26 Function Definition: main( ( global void) +0:26 Function Parameters: +0:27 Sequence +0:27 move second child to first child ( temp highp 4-component vector of float) +0:27 'o' ( out highp 4-component vector of float) +0:27 add ( temp highp 4-component vector of float) +0:27 'io' (layout( location=0) smooth in highp 4-component vector of float) +0:27 Function Call: foo( ( global highp 4-component vector of float) +0:? Linker Objects +0:? 'io' (layout( location=0) smooth in highp 4-component vector of float) +0:? 'o' ( out highp 4-component vector of float) +0:? 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d}) +0:? 'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) + + +Linked vertex stage: + + +Linked fragment stage: + + +Shader version: 460 +0:? Sequence +0:18 Function Definition: foo( ( global highp 4-component vector of float) +0:18 Function Parameters: +0:19 Sequence +0:19 Sequence +0:19 move second child to first child ( temp highp uint) +0:19 'j' ( temp highp uint) +0:19 add ( temp highp uint) +0:19 AtomicAdd ( global highp uint) +0:19 counter2: direct index for structure ( coherent volatile buffer highp uint) +0:19 'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter3, coherent volatile buffer highp uint counter2}) +0:19 Constant: +0:19 1 (const uint) +0:19 Constant: +0:19 1 (const uint) +0:19 subtract ( temp highp uint) +0:19 AtomicAdd ( global highp uint) +0:19 counter3: direct index for structure ( coherent volatile buffer highp uint) +0:19 'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter3, coherent volatile buffer highp uint counter2}) +0:19 Constant: +0:19 0 (const uint) +0:19 Constant: +0:19 4294967295 (const uint) +0:19 Constant: +0:19 1 (const uint) +0:20 Sequence +0:20 move second child to first child ( temp highp 4-component vector of float) +0:20 'v' ( temp highp 4-component vector of float) +0:20 add ( temp highp 4-component vector of float) +0:20 add ( temp highp 4-component vector of float) +0:20 add ( temp highp 4-component vector of float) +0:20 a: direct index for structure ( uniform highp 4-component vector of float) +0:20 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d, uniform 4-element array of highp 4-component vector of float s}) +0:20 Constant: +0:20 0 (const uint) +0:20 Construct vec4 ( temp highp 4-component vector of float) +0:20 direct index ( temp highp float) +0:20 b1: direct index for structure ( uniform highp 2-component vector of float) +0:20 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d, uniform 4-element array of highp 4-component vector of float s}) +0:20 Constant: +0:20 2 (const uint) +0:20 Constant: +0:20 0 (const int) +0:20 direct index ( temp highp float) +0:20 b1: direct index for structure ( uniform highp 2-component vector of float) +0:20 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d, uniform 4-element array of highp 4-component vector of float s}) +0:20 Constant: +0:20 2 (const uint) +0:20 Constant: +0:20 1 (const int) +0:20 direct index ( temp highp float) +0:20 b2: direct index for structure ( uniform highp 2-component vector of float) +0:20 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d, uniform 4-element array of highp 4-component vector of float s}) +0:20 Constant: +0:20 1 (const uint) +0:20 Constant: +0:20 0 (const int) +0:20 direct index ( temp highp float) +0:20 b2: direct index for structure ( uniform highp 2-component vector of float) +0:20 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d, uniform 4-element array of highp 4-component vector of float s}) +0:20 Constant: +0:20 1 (const uint) +0:20 Constant: +0:20 1 (const int) +0:20 c2: direct index for structure ( uniform highp 4-component vector of float) +0:20 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d, uniform 4-element array of highp 4-component vector of float s}) +0:20 Constant: +0:20 3 (const uint) +0:20 d: direct index for structure ( uniform highp 4-component vector of float) +0:20 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d, uniform 4-element array of highp 4-component vector of float s}) +0:20 Constant: +0:20 4 (const uint) +0:22 Branch: Return with expression +0:22 vector-scale ( temp highp 4-component vector of float) +0:22 Convert uint to float ( temp highp float) +0:22 'j' ( temp highp uint) +0:22 'v' ( temp highp 4-component vector of float) +0:25 Function Definition: main( ( global void) +0:25 Function Parameters: +0:27 Sequence +0:27 Sequence +0:27 move second child to first child ( temp highp 4-component vector of float) +0:27 'v' ( temp highp 4-component vector of float) +0:27 Function Call: foo( ( global highp 4-component vector of float) +0:28 move second child to first child ( temp highp 4-component vector of float) +0:28 'v' ( temp highp 4-component vector of float) +0:28 add ( temp highp 4-component vector of float) +0:28 'v' ( temp highp 4-component vector of float) +0:28 indirect index ( temp highp 4-component vector of float) +0:28 s: direct index for structure ( uniform 4-element array of highp 4-component vector of float) +0:28 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d, uniform 4-element array of highp 4-component vector of float s}) +0:28 Constant: +0:28 5 (const uint) +0:28 'gl_VertexID' ( in int VertexIndex) +0:29 move second child to first child ( temp highp float) +0:29 direct index ( temp highp float) +0:29 'v' ( temp highp 4-component vector of float) +0:29 Constant: +0:29 0 (const int) +0:29 subtract ( temp highp float) +0:29 direct index ( temp highp float) +0:29 'v' ( temp highp 4-component vector of float) +0:29 Constant: +0:29 0 (const int) +0:29 Convert int to float ( temp highp float) +0:29 'gl_InstanceID' ( in highp int InstanceIndex) +0:30 move second child to first child ( temp highp 4-component vector of float) +0:30 'io' (layout( location=0) smooth out highp 4-component vector of float) +0:30 'v' ( temp highp 4-component vector of float) +0:? Linker Objects +0:? 'io' (layout( location=0) smooth out highp 4-component vector of float) +0:? 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b2, uniform highp 2-component vector of float b1, uniform highp 4-component vector of float c2, uniform highp 4-component vector of float d, uniform 4-element array of highp 4-component vector of float s}) +0:? 'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter3, coherent volatile buffer highp uint counter2}) +0:? 'gl_VertexID' ( in int VertexIndex) +0:? 'gl_InstanceID' ( in int InstanceIndex) +Shader version: 460 +gl_FragCoord origin is upper left +0:? Sequence +0:19 Function Definition: foo( ( global highp 4-component vector of float) +0:19 Function Parameters: +0:20 Sequence +0:20 Sequence +0:20 move second child to first child ( temp highp uint) +0:20 'j' ( temp highp uint) +0:20 add ( temp highp uint) +0:20 AtomicAdd ( global highp uint) +0:20 counter1: direct index for structure ( coherent volatile buffer highp uint) +0:20 'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:20 Constant: +0:20 0 (const uint) +0:20 Constant: +0:20 1 (const uint) +0:20 subtract ( temp highp uint) +0:20 AtomicAdd ( global highp uint) +0:20 counter2: direct index for structure ( coherent volatile buffer highp uint) +0:20 'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) +0:20 Constant: +0:20 1 (const uint) +0:20 Constant: +0:20 4294967295 (const uint) +0:20 Constant: +0:20 1 (const uint) +0:21 Sequence +0:21 move second child to first child ( temp highp 4-component vector of float) +0:21 'v' ( temp highp 4-component vector of float) +0:21 add ( temp highp 4-component vector of float) +0:21 add ( temp highp 4-component vector of float) +0:21 add ( temp highp 4-component vector of float) +0:21 a: direct index for structure ( uniform highp 4-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d}) +0:21 Constant: +0:21 0 (const uint) +0:21 Construct vec4 ( temp highp 4-component vector of float) +0:21 direct index ( temp highp float) +0:21 b1: direct index for structure ( uniform highp 2-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d}) +0:21 Constant: +0:21 1 (const uint) +0:21 Constant: +0:21 0 (const int) +0:21 direct index ( temp highp float) +0:21 b1: direct index for structure ( uniform highp 2-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d}) +0:21 Constant: +0:21 1 (const uint) +0:21 Constant: +0:21 1 (const int) +0:21 direct index ( temp highp float) +0:21 b2: direct index for structure ( uniform highp 2-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d}) +0:21 Constant: +0:21 2 (const uint) +0:21 Constant: +0:21 0 (const int) +0:21 direct index ( temp highp float) +0:21 b2: direct index for structure ( uniform highp 2-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d}) +0:21 Constant: +0:21 2 (const uint) +0:21 Constant: +0:21 1 (const int) +0:21 c1: direct index for structure ( uniform highp 4-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d}) +0:21 Constant: +0:21 3 (const uint) +0:21 d: direct index for structure ( uniform highp 4-component vector of float) +0:21 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d}) +0:21 Constant: +0:21 4 (const uint) +0:23 Branch: Return with expression +0:23 vector-scale ( temp highp 4-component vector of float) +0:23 Convert uint to float ( temp highp float) +0:23 'j' ( temp highp uint) +0:23 'v' ( temp highp 4-component vector of float) +0:26 Function Definition: main( ( global void) +0:26 Function Parameters: +0:27 Sequence +0:27 move second child to first child ( temp highp 4-component vector of float) +0:27 'o' ( out highp 4-component vector of float) +0:27 add ( temp highp 4-component vector of float) +0:27 'io' (layout( location=0) smooth in highp 4-component vector of float) +0:27 Function Call: foo( ( global highp 4-component vector of float) +0:? Linker Objects +0:? 'io' (layout( location=0) smooth in highp 4-component vector of float) +0:? 'o' ( out highp 4-component vector of float) +0:? 'anon@0' (layout( column_major std140) uniform block{ uniform highp 4-component vector of float a, uniform highp 2-component vector of float b1, uniform highp 2-component vector of float b2, uniform highp 4-component vector of float c1, uniform highp 4-component vector of float d}) +0:? 'anon@1' (layout( column_major std430) buffer block{ coherent volatile buffer highp uint counter1, coherent volatile buffer highp uint counter2}) + +// Module Version 10000 +// Generated by (magic number): 8000a +// Id's are bound by 88 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Vertex 4 "main" 72 80 86 + Source GLSL 460 + Name 4 "main" + Name 9 "foo(" + Name 13 "j" + Name 14 "gl_AtomicCounterBlock_0" + MemberName 14(gl_AtomicCounterBlock_0) 0 "counter3" + MemberName 14(gl_AtomicCounterBlock_0) 1 "counter2" + MemberName 14(gl_AtomicCounterBlock_0) 2 "counter1" + Name 16 "" + Name 31 "v" + Name 35 "gl_DefaultUniformBlock" + MemberName 35(gl_DefaultUniformBlock) 0 "a" + MemberName 35(gl_DefaultUniformBlock) 1 "b2" + MemberName 35(gl_DefaultUniformBlock) 2 "b1" + MemberName 35(gl_DefaultUniformBlock) 3 "c2" + MemberName 35(gl_DefaultUniformBlock) 4 "d" + MemberName 35(gl_DefaultUniformBlock) 5 "s" + MemberName 35(gl_DefaultUniformBlock) 6 "c1" + Name 37 "" + Name 67 "v" + Name 72 "gl_VertexID" + Name 80 "gl_InstanceID" + Name 86 "io" + MemberDecorate 14(gl_AtomicCounterBlock_0) 0 Coherent + MemberDecorate 14(gl_AtomicCounterBlock_0) 0 Volatile + MemberDecorate 14(gl_AtomicCounterBlock_0) 0 Coherent + MemberDecorate 14(gl_AtomicCounterBlock_0) 0 Offset 0 + MemberDecorate 14(gl_AtomicCounterBlock_0) 1 Coherent + MemberDecorate 14(gl_AtomicCounterBlock_0) 1 Volatile + MemberDecorate 14(gl_AtomicCounterBlock_0) 1 Coherent + MemberDecorate 14(gl_AtomicCounterBlock_0) 1 Offset 4 + MemberDecorate 14(gl_AtomicCounterBlock_0) 2 Coherent + MemberDecorate 14(gl_AtomicCounterBlock_0) 2 Volatile + MemberDecorate 14(gl_AtomicCounterBlock_0) 2 Coherent + MemberDecorate 14(gl_AtomicCounterBlock_0) 2 Offset 8 + Decorate 14(gl_AtomicCounterBlock_0) BufferBlock + Decorate 16 DescriptorSet 0 + Decorate 16 Binding 1 + Decorate 34 ArrayStride 16 + MemberDecorate 35(gl_DefaultUniformBlock) 0 Offset 0 + MemberDecorate 35(gl_DefaultUniformBlock) 1 Offset 16 + MemberDecorate 35(gl_DefaultUniformBlock) 2 Offset 24 + MemberDecorate 35(gl_DefaultUniformBlock) 3 Offset 32 + MemberDecorate 35(gl_DefaultUniformBlock) 4 Offset 48 + MemberDecorate 35(gl_DefaultUniformBlock) 5 Offset 64 + MemberDecorate 35(gl_DefaultUniformBlock) 6 Offset 128 + Decorate 35(gl_DefaultUniformBlock) Block + Decorate 37 DescriptorSet 0 + Decorate 37 Binding 0 + Decorate 72(gl_VertexID) BuiltIn VertexIndex + Decorate 80(gl_InstanceID) BuiltIn InstanceIndex + Decorate 86(io) Location 0 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8: TypeFunction 7(fvec4) + 11: TypeInt 32 0 + 12: TypePointer Function 11(int) +14(gl_AtomicCounterBlock_0): TypeStruct 11(int) 11(int) 11(int) + 15: TypePointer Uniform 14(gl_AtomicCounterBlock_0) + 16: 15(ptr) Variable Uniform + 17: TypeInt 32 1 + 18: 17(int) Constant 1 + 19: TypePointer Uniform 11(int) + 21: 11(int) Constant 1 + 22: 11(int) Constant 0 + 24: 17(int) Constant 0 + 26: 11(int) Constant 4294967295 + 30: TypePointer Function 7(fvec4) + 32: TypeVector 6(float) 2 + 33: 11(int) Constant 4 + 34: TypeArray 7(fvec4) 33 +35(gl_DefaultUniformBlock): TypeStruct 7(fvec4) 32(fvec2) 32(fvec2) 7(fvec4) 7(fvec4) 34 7(fvec4) + 36: TypePointer Uniform 35(gl_DefaultUniformBlock) + 37: 36(ptr) Variable Uniform + 38: TypePointer Uniform 7(fvec4) + 41: 17(int) Constant 2 + 42: TypePointer Uniform 6(float) + 53: 17(int) Constant 3 + 57: 17(int) Constant 4 + 70: 17(int) Constant 5 + 71: TypePointer Input 17(int) + 72(gl_VertexID): 71(ptr) Variable Input + 77: TypePointer Function 6(float) +80(gl_InstanceID): 71(ptr) Variable Input + 85: TypePointer Output 7(fvec4) + 86(io): 85(ptr) Variable Output + 4(main): 2 Function None 3 + 5: Label + 67(v): 30(ptr) Variable Function + 68: 7(fvec4) FunctionCall 9(foo() + Store 67(v) 68 + 69: 7(fvec4) Load 67(v) + 73: 17(int) Load 72(gl_VertexID) + 74: 38(ptr) AccessChain 37 70 73 + 75: 7(fvec4) Load 74 + 76: 7(fvec4) FAdd 69 75 + Store 67(v) 76 + 78: 77(ptr) AccessChain 67(v) 22 + 79: 6(float) Load 78 + 81: 17(int) Load 80(gl_InstanceID) + 82: 6(float) ConvertSToF 81 + 83: 6(float) FSub 79 82 + 84: 77(ptr) AccessChain 67(v) 22 + Store 84 83 + 87: 7(fvec4) Load 67(v) + Store 86(io) 87 + Return + FunctionEnd + 9(foo(): 7(fvec4) Function None 8 + 10: Label + 13(j): 12(ptr) Variable Function + 31(v): 30(ptr) Variable Function + 20: 19(ptr) AccessChain 16 18 + 23: 11(int) AtomicIAdd 20 21 22 21 + 25: 19(ptr) AccessChain 16 24 + 27: 11(int) AtomicIAdd 25 21 22 26 + 28: 11(int) ISub 27 21 + 29: 11(int) IAdd 23 28 + Store 13(j) 29 + 39: 38(ptr) AccessChain 37 24 + 40: 7(fvec4) Load 39 + 43: 42(ptr) AccessChain 37 41 22 + 44: 6(float) Load 43 + 45: 42(ptr) AccessChain 37 41 21 + 46: 6(float) Load 45 + 47: 42(ptr) AccessChain 37 18 22 + 48: 6(float) Load 47 + 49: 42(ptr) AccessChain 37 18 21 + 50: 6(float) Load 49 + 51: 7(fvec4) CompositeConstruct 44 46 48 50 + 52: 7(fvec4) FAdd 40 51 + 54: 38(ptr) AccessChain 37 53 + 55: 7(fvec4) Load 54 + 56: 7(fvec4) FAdd 52 55 + 58: 38(ptr) AccessChain 37 57 + 59: 7(fvec4) Load 58 + 60: 7(fvec4) FAdd 56 59 + Store 31(v) 60 + 61: 11(int) Load 13(j) + 62: 6(float) ConvertUToF 61 + 63: 7(fvec4) Load 31(v) + 64: 7(fvec4) VectorTimesScalar 63 62 + ReturnValue 64 + FunctionEnd +// Module Version 10000 +// Generated by (magic number): 8000a +// Id's are bound by 74 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "main" 68 70 + ExecutionMode 4 OriginUpperLeft + Source GLSL 460 + Name 4 "main" + Name 9 "foo(" + Name 13 "j" + Name 14 "gl_AtomicCounterBlock_0" + MemberName 14(gl_AtomicCounterBlock_0) 0 "counter3" + MemberName 14(gl_AtomicCounterBlock_0) 1 "counter2" + MemberName 14(gl_AtomicCounterBlock_0) 2 "counter1" + Name 16 "" + Name 31 "v" + Name 35 "gl_DefaultUniformBlock" + MemberName 35(gl_DefaultUniformBlock) 0 "a" + MemberName 35(gl_DefaultUniformBlock) 1 "b2" + MemberName 35(gl_DefaultUniformBlock) 2 "b1" + MemberName 35(gl_DefaultUniformBlock) 3 "c2" + MemberName 35(gl_DefaultUniformBlock) 4 "d" + MemberName 35(gl_DefaultUniformBlock) 5 "s" + MemberName 35(gl_DefaultUniformBlock) 6 "c1" + Name 37 "" + Name 68 "o" + Name 70 "io" + MemberDecorate 14(gl_AtomicCounterBlock_0) 0 Coherent + MemberDecorate 14(gl_AtomicCounterBlock_0) 0 Volatile + MemberDecorate 14(gl_AtomicCounterBlock_0) 0 Coherent + MemberDecorate 14(gl_AtomicCounterBlock_0) 0 Offset 0 + MemberDecorate 14(gl_AtomicCounterBlock_0) 1 Coherent + MemberDecorate 14(gl_AtomicCounterBlock_0) 1 Volatile + MemberDecorate 14(gl_AtomicCounterBlock_0) 1 Coherent + MemberDecorate 14(gl_AtomicCounterBlock_0) 1 Offset 4 + MemberDecorate 14(gl_AtomicCounterBlock_0) 2 Coherent + MemberDecorate 14(gl_AtomicCounterBlock_0) 2 Volatile + MemberDecorate 14(gl_AtomicCounterBlock_0) 2 Coherent + MemberDecorate 14(gl_AtomicCounterBlock_0) 2 Offset 8 + Decorate 14(gl_AtomicCounterBlock_0) BufferBlock + Decorate 16 DescriptorSet 0 + Decorate 16 Binding 1 + Decorate 34 ArrayStride 16 + MemberDecorate 35(gl_DefaultUniformBlock) 0 Offset 0 + MemberDecorate 35(gl_DefaultUniformBlock) 1 Offset 16 + MemberDecorate 35(gl_DefaultUniformBlock) 2 Offset 24 + MemberDecorate 35(gl_DefaultUniformBlock) 3 Offset 32 + MemberDecorate 35(gl_DefaultUniformBlock) 4 Offset 48 + MemberDecorate 35(gl_DefaultUniformBlock) 5 Offset 64 + MemberDecorate 35(gl_DefaultUniformBlock) 6 Offset 128 + Decorate 35(gl_DefaultUniformBlock) Block + Decorate 37 DescriptorSet 0 + Decorate 37 Binding 0 + Decorate 68(o) Location 0 + Decorate 70(io) Location 0 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8: TypeFunction 7(fvec4) + 11: TypeInt 32 0 + 12: TypePointer Function 11(int) +14(gl_AtomicCounterBlock_0): TypeStruct 11(int) 11(int) 11(int) + 15: TypePointer Uniform 14(gl_AtomicCounterBlock_0) + 16: 15(ptr) Variable Uniform + 17: TypeInt 32 1 + 18: 17(int) Constant 2 + 19: TypePointer Uniform 11(int) + 21: 11(int) Constant 1 + 22: 11(int) Constant 0 + 24: 17(int) Constant 1 + 26: 11(int) Constant 4294967295 + 30: TypePointer Function 7(fvec4) + 32: TypeVector 6(float) 2 + 33: 11(int) Constant 4 + 34: TypeArray 7(fvec4) 33 +35(gl_DefaultUniformBlock): TypeStruct 7(fvec4) 32(fvec2) 32(fvec2) 7(fvec4) 7(fvec4) 34 7(fvec4) + 36: TypePointer Uniform 35(gl_DefaultUniformBlock) + 37: 36(ptr) Variable Uniform + 38: 17(int) Constant 0 + 39: TypePointer Uniform 7(fvec4) + 42: TypePointer Uniform 6(float) + 53: 17(int) Constant 6 + 57: 17(int) Constant 4 + 67: TypePointer Output 7(fvec4) + 68(o): 67(ptr) Variable Output + 69: TypePointer Input 7(fvec4) + 70(io): 69(ptr) Variable Input + 4(main): 2 Function None 3 + 5: Label + 71: 7(fvec4) Load 70(io) + 72: 7(fvec4) FunctionCall 9(foo() + 73: 7(fvec4) FAdd 71 72 + Store 68(o) 73 + Return + FunctionEnd + 9(foo(): 7(fvec4) Function None 8 + 10: Label + 13(j): 12(ptr) Variable Function + 31(v): 30(ptr) Variable Function + 20: 19(ptr) AccessChain 16 18 + 23: 11(int) AtomicIAdd 20 21 22 21 + 25: 19(ptr) AccessChain 16 24 + 27: 11(int) AtomicIAdd 25 21 22 26 + 28: 11(int) ISub 27 21 + 29: 11(int) IAdd 23 28 + Store 13(j) 29 + 40: 39(ptr) AccessChain 37 38 + 41: 7(fvec4) Load 40 + 43: 42(ptr) AccessChain 37 18 22 + 44: 6(float) Load 43 + 45: 42(ptr) AccessChain 37 18 21 + 46: 6(float) Load 45 + 47: 42(ptr) AccessChain 37 24 22 + 48: 6(float) Load 47 + 49: 42(ptr) AccessChain 37 24 21 + 50: 6(float) Load 49 + 51: 7(fvec4) CompositeConstruct 44 46 48 50 + 52: 7(fvec4) FAdd 41 51 + 54: 39(ptr) AccessChain 37 53 + 55: 7(fvec4) Load 54 + 56: 7(fvec4) FAdd 52 55 + 58: 39(ptr) AccessChain 37 57 + 59: 7(fvec4) Load 58 + 60: 7(fvec4) FAdd 56 59 + Store 31(v) 60 + 61: 11(int) Load 13(j) + 62: 6(float) ConvertUToF 61 + 63: 7(fvec4) Load 31(v) + 64: 7(fvec4) VectorTimesScalar 63 62 + ReturnValue 64 + FunctionEnd diff --git a/Test/iomap.crossStage.2.frag b/Test/iomap.crossStage.2.frag new file mode 100644 index 00000000..25756a6d --- /dev/null +++ b/Test/iomap.crossStage.2.frag @@ -0,0 +1,42 @@ +#version 460 + + +layout(location = 5) in outBlock { + vec4 o3; +}; + + +in vec4 gfo1; +in vec2 gfo2; + +out vec4 outColor; + +uniform vec2 u1; +uniform vec3 u2; // initializer present in vertex stage +uniform vec4 u3 = vec4(0); // initializer matches initializer in vertex stage + +uniform mat2 um2 = mat2(4.0); + +layout (location = 0, binding = 0) uniform sampler2D glass; + +uniform crossStageBlock1 { + uniform vec4 a; + vec4 b; +}; + +buffer fragOnlyBlock { + vec2 fb1; +}; + +uniform crossStageBlock2 { + uniform vec4 a; + vec2 b; +} blockName2 [2]; // instance name different from vert + + +void main() +{ + vec4 color = gfo1 * u1.rgrg * u2.rgbr * u3.rgba; // o1 is statically used + outColor = color; +} + diff --git a/Test/iomap.crossStage.2.geom b/Test/iomap.crossStage.2.geom new file mode 100644 index 00000000..91508ab5 --- /dev/null +++ b/Test/iomap.crossStage.2.geom @@ -0,0 +1,39 @@ +#version 460 + +layout(points) in; +layout(triangle_strip, max_vertices=3) out; + +in vec4 vgo1[]; +in vec2 vgo2[]; + +layout(location = 5) in outBlock { + vec4 o3; +} inBlock[]; + +out vec4 gfo1; +out vec2 gfo2; + +layout(location = 5) out outBlock { + vec4 o3; +} gf_out; + +uniform vec2 u1; +uniform vec3 u2 = vec3(0); // initializer not present in fragment stage +uniform vec4 u3 = vec4(0); // initializer matches initializer in fragment stage + +uniform crossStageBlock2 { + uniform vec4 a; + vec2 b; +} blockName1 [2]; // instance name different from frag + +void main() +{ + for (int i = 0; i < 3; i++) { + gfo1 = vec4(0); + gfo2 = vec2(0); + gf_out.o3 = inBlock[i].o3; + EmitVertex(); + } + EndPrimitive(); +} + diff --git a/Test/iomap.crossStage.2.vert b/Test/iomap.crossStage.2.vert new file mode 100644 index 00000000..ebb0d9d1 --- /dev/null +++ b/Test/iomap.crossStage.2.vert @@ -0,0 +1,38 @@ +#version 460 + +out vec4 vgo1; // declaration order different than fragment shader +out vec2 vgo2; // declaration order different than fragment shader + +layout(location = 5) out outBlock { + vec4 o3; +}; + +uniform vec2 u1; +uniform vec3 u2 = vec3(0); // initializer not present in fragment stage +uniform vec4 u3 = vec4(0); // initializer matches initializer in fragment stage + +uniform mat2 um2 = mat2(4.0); + +layout (location = 0, binding = 0) uniform sampler2D glass; + +uniform crossStageBlock1 { + uniform vec4 a; + vec4 b; +}; + +buffer vertOnlyBlock { + vec2 vb1; +}; + +uniform crossStageBlock2 { + uniform vec4 a; + vec2 b; +} blockName1 [2]; // instance name different from frag + +void main() +{ + vgo1 = vec4(0); + vgo2 = vec2(0); + o3 = vec4(0); +} + diff --git a/Test/iomap.crossStage.frag b/Test/iomap.crossStage.frag new file mode 100644 index 00000000..16247032 --- /dev/null +++ b/Test/iomap.crossStage.frag @@ -0,0 +1,41 @@ +#version 460 + + +layout(location = 5) in outBlock { + vec4 o3; +}; + +in vec2 o2; // declaration order different than vertex shader +in vec4 o1; // declaration order different than vertex shader + +out vec4 outColor; + +uniform vec2 u1; +uniform vec3 u2; // initializer present in vertex stage +uniform vec4 u3 = vec4(0); // initializer matches initializer in vertex stage + +uniform mat2 um2 = mat2(4.0); + +layout (location = 0, binding = 0) uniform sampler2D glass; + +uniform crossStageBlock1 { + uniform vec4 a; + vec4 b; +}; + +buffer fragOnlyBlock { + vec2 fb1; +}; + +uniform crossStageBlock2 { + uniform vec4 a; + vec2 b; +} blockName2 [2]; // instance name different from vert + + +void main() +{ + vec4 color = o1 * u1.rgrg * u2.rgbr * u3.rgba; // o1 is statically used + outColor = color; +} + diff --git a/Test/iomap.crossStage.vert b/Test/iomap.crossStage.vert new file mode 100644 index 00000000..d05874ff --- /dev/null +++ b/Test/iomap.crossStage.vert @@ -0,0 +1,38 @@ +#version 460 + +out vec4 o1; // declaration order different than fragment shader +out vec2 o2; // declaration order different than fragment shader + +layout(location = 5) out outBlock { + vec4 o3; +}; + +uniform vec2 u1; +uniform vec3 u2 = vec3(0); // initializer not present in fragment stage +uniform vec4 u3 = vec4(0); // initializer matches initializer in fragment stage + +uniform mat2 um2 = mat2(4.0); + +layout (location = 0, binding = 0) uniform sampler2D glass; + +uniform crossStageBlock1 { + uniform vec4 a; + vec4 b; +}; + +buffer vertOnlyBlock { + vec2 vb1; +}; + +uniform crossStageBlock2 { + uniform vec4 a; + vec2 b; +} blockName1 [2]; // instance name different from frag + +void main() +{ + o1 = vec4(0); + o2 = vec2(0); + o3 = vec4(0); +} + diff --git a/Test/iomap.crossStage.vk.frag b/Test/iomap.crossStage.vk.frag new file mode 100644 index 00000000..d09e6874 --- /dev/null +++ b/Test/iomap.crossStage.vk.frag @@ -0,0 +1,50 @@ +#version 460 + + +layout(location = 5) in outBlock { + vec4 o3; +}; + + +in vec4 gfo1; +in vec2 gfo2; + +out vec4 outColor; + +layout (binding = 0) uniform sampler2D glass; + +uniform crossStageBlock1 { + uniform vec4 a; + vec4 b; +}; + +readonly buffer fragOnlyBlock { + vec2 fb1; +}; + +uniform crossStageBlock2 { + uniform vec4 a; + vec2 b; +} blockName2 [2]; // instance name different from vert + +vec2 Bar() { + return fb1 + + blockName2[0].b + + blockName2[1].b; +} + +vec4 Foo() { + return a + + b + + blockName2[0].a + + blockName2[1].a + + vec4(Bar(), 0.0, 0.0); +} + +void main() +{ + vec4 color = gfo1; // o1 is statically used + color = color + Foo(); + outColor = color; +} + diff --git a/Test/iomap.crossStage.vk.geom b/Test/iomap.crossStage.vk.geom new file mode 100644 index 00000000..b9517373 --- /dev/null +++ b/Test/iomap.crossStage.vk.geom @@ -0,0 +1,35 @@ +#version 460 + +layout(points) in; +layout(triangle_strip, max_vertices=3) out; + +in vec4 vgo1[]; +in vec2 vgo2[]; + +layout(location = 5) in outBlock { + vec4 o3; +} inBlock[]; + +out vec4 gfo1; +out vec2 gfo2; + +layout(location = 5) out outBlock { + vec4 o3; +} gf_out; + +uniform crossStageBlock2 { + uniform vec4 a; + vec2 b; +} blockName1 [2]; // instance name different from frag + +void main() +{ + for (int i = 0; i < 3; i++) { + gfo1 = vec4(0); + gfo2 = vec2(0); + gf_out.o3 = inBlock[i].o3; + EmitVertex(); + } + EndPrimitive(); +} + diff --git a/Test/iomap.crossStage.vk.vert b/Test/iomap.crossStage.vk.vert new file mode 100644 index 00000000..e422131f --- /dev/null +++ b/Test/iomap.crossStage.vk.vert @@ -0,0 +1,32 @@ +#version 460 + +out vec4 vgo1; // declaration order different than fragment shader +out vec2 vgo2; // declaration order different than fragment shader + +layout(location = 5) out outBlock { + vec4 o3; +}; + +layout (binding = 0) uniform sampler2D glass; + +uniform crossStageBlock1 { + uniform vec4 a; + vec4 b; +}; + +readonly buffer vertOnlyBlock { + vec2 vb1; +}; + +uniform crossStageBlock2 { + uniform vec4 a; + vec2 b; +} blockName1 [2]; // instance name different from frag + +void main() +{ + vgo1 = vec4(0); + vgo2 = vec2(0); + o3 = vec4(0); +} + diff --git a/Test/vk.relaxed.errorcheck.frag b/Test/vk.relaxed.errorcheck.frag new file mode 100644 index 00000000..b75b50b7 --- /dev/null +++ b/Test/vk.relaxed.errorcheck.frag @@ -0,0 +1,16 @@ +#version 460 + +layout (location = 0) in vec4 io; + +out vec4 o; + +// default uniforms will be gathered into a uniform block +uniform vec4 a; // declared in both stages with different types + +vec4 foo() { + return a; +} + +void main() { + o = io + foo(); +} \ No newline at end of file diff --git a/Test/vk.relaxed.errorcheck.vert b/Test/vk.relaxed.errorcheck.vert new file mode 100644 index 00000000..b1bdbbec --- /dev/null +++ b/Test/vk.relaxed.errorcheck.vert @@ -0,0 +1,15 @@ +#version 460 + +layout (location = 0) out vec4 io; + +// default uniforms will be gathered into a uniform block +// final global block will merge uniforms from all linked files +uniform vec2 a; // declared in both stages with different type + +vec4 foo() { + return a.xyxy; +} + +void main() { + io = foo(); +} \ No newline at end of file diff --git a/Test/vk.relaxed.frag b/Test/vk.relaxed.frag new file mode 100644 index 00000000..d43416e0 --- /dev/null +++ b/Test/vk.relaxed.frag @@ -0,0 +1,74 @@ +#version 460 + +out vec4 o; + +// default uniforms will be gathered into a uniform block +uniform vec4 a; +uniform vec2 b = vec2(0, 0); // initializer will be ignored +layout(location = 0) uniform vec2 c; // location qualifier will be ignored +uniform vec4 d[10]; +uniform struct e { + vec2 x; + float y; + uint z; +} structUniform; + +// opaque types will not be grouped into uniform block +uniform sampler2D t1; + +// shared and packed layout qualifier are silently ignored +layout(shared) uniform UniformBlock { + float j; + vec4 k; +}; + +layout(packed) buffer BufferBlock { + float j; + vec4 k; +} bufferInstance; + +// atomic_uint will be converted to uint and gathered in a buffer block +layout(binding = 0) uniform atomic_uint counter1; // offset not used +layout(binding = 0) uniform atomic_uint counter2; // offset not used +layout(binding = 1) uniform atomic_uint counter3; // offset not used + +// atomic counter functions will be converted to equivalent integer atomic operations +uint bar() { + uint j = 0; + j = atomicCounterIncrement(counter1); + j = atomicCounterDecrement(counter1); + j = atomicCounter(counter1); + + j = atomicCounterAdd(counter1, 1); + j = atomicCounterAdd(counter1, -1); + j = atomicCounterSubtract(counter1, 1); + + j = atomicCounterMin(counter1, j); + j = atomicCounterMax(counter1, j); + j = atomicCounterAnd(counter1, j); + + j = atomicCounterOr(counter1, j); + j = atomicCounterXor(counter1, j); + + j = atomicCounterExchange(counter1, j); + j = atomicCounterCompSwap(counter1, 0, j); + + atomicCounterIncrement(counter2); + atomicCounterIncrement(counter3); + + memoryBarrierAtomicCounter(); + + return j; +} + +vec4 foo() { + float f = j + bufferInstance.j + structUniform.y + structUniform.z; + vec2 v2 = b + c + structUniform.x; + vec4 v4 = a + d[0] + d[1] + d[2] + k + bufferInstance.k + texture(t1, vec2(0, 0)); + return vec4(f) * vec4(v2, 1, 1) * v4; +} + +void main() { + float j = float(bar()); + o = j * foo(); +} \ No newline at end of file diff --git a/Test/vk.relaxed.link1.frag b/Test/vk.relaxed.link1.frag new file mode 100644 index 00000000..95b609f2 --- /dev/null +++ b/Test/vk.relaxed.link1.frag @@ -0,0 +1,28 @@ +#version 460 + +out vec4 o; + +// default uniforms will be gathered into a uniform block +// final global block will merge uniforms from all linked files +uniform vec4 a; // declared in both stages +uniform vec2 b1; // declaration order swapped in other stage +uniform vec2 b2; +uniform vec4 c1; // not delcared in other file +uniform vec4 d; + +// final global buffer will berge buffers from all linked files +layout (binding = 0) uniform atomic_uint counter1; +layout (binding = 0) uniform atomic_uint counter2; + +vec4 foo(); + +vec4 bar() { + uint j = atomicCounterIncrement(counter1) + atomicCounterDecrement(counter2); + vec4 v = a + vec4(b1.x, b1.y, b2.x, b2.y) + c1 + d; + + return float(j) * v; +} + +void main() { + o = foo() + bar(); +} \ No newline at end of file diff --git a/Test/vk.relaxed.link2.frag b/Test/vk.relaxed.link2.frag new file mode 100644 index 00000000..a4f468a4 --- /dev/null +++ b/Test/vk.relaxed.link2.frag @@ -0,0 +1,19 @@ +#version 460 + +// default uniforms will be gathered into a uniform block +// final global block will merge uniforms from all linked files +uniform vec4 a; // declared in both stages +uniform vec2 b2; // declaration order swapped in other stage +uniform vec2 b1; +uniform vec4 c2; // not delcared in other file +uniform vec4 d; + +layout (binding = 0) uniform atomic_uint counter3; +layout (binding = 0) uniform atomic_uint counter2; + +vec4 foo() { + uint j = atomicCounterIncrement(counter2) + atomicCounterDecrement(counter3); + vec4 v = a + vec4(b1.x, b1.y, b2.x, b2.y) + c2 + d; + + return float(j) * v; +} \ No newline at end of file diff --git a/Test/vk.relaxed.stagelink.frag b/Test/vk.relaxed.stagelink.frag new file mode 100644 index 00000000..d1eebba0 --- /dev/null +++ b/Test/vk.relaxed.stagelink.frag @@ -0,0 +1,28 @@ +#version 460 + +layout (location = 0) in vec4 io; + +out vec4 o; + +// default uniforms will be gathered into a uniform block +// final global block will merge uniforms from all linked files +uniform vec4 a; // declared in both stages +uniform vec2 b1; // declaration order swapped in other stage +uniform vec2 b2; +uniform vec4 c1; // not delcared in other file +uniform vec4 d; + +// final global buffer will berge buffers from all linked files +layout (binding = 0) uniform atomic_uint counter1; +layout (binding = 0) uniform atomic_uint counter2; + +vec4 foo() { + uint j = atomicCounterIncrement(counter1) + atomicCounterDecrement(counter2); + vec4 v = a + vec4(b1.x, b1.y, b2.x, b2.y) + c1 + d; + + return float(j) * v; +} + +void main() { + o = io + foo(); +} \ No newline at end of file diff --git a/Test/vk.relaxed.stagelink.vert b/Test/vk.relaxed.stagelink.vert new file mode 100644 index 00000000..52396ac5 --- /dev/null +++ b/Test/vk.relaxed.stagelink.vert @@ -0,0 +1,31 @@ +#version 460 + +layout (location = 0) out vec4 io; + +// default uniforms will be gathered into a uniform block +// final global block will merge uniforms from all linked files +uniform vec4 a; // declared in both stages +uniform vec2 b2; // declaration order swapped in other stage +uniform vec2 b1; +uniform vec4 c2; // not delcared in other file +uniform vec4 d; + +uniform vec4 s[4]; + +layout (binding = 0) uniform atomic_uint counter3; +layout (binding = 0) uniform atomic_uint counter2; + +vec4 foo() { + uint j = atomicCounterIncrement(counter2) + atomicCounterDecrement(counter3); + vec4 v = a + vec4(b1.x, b1.y, b2.x, b2.y) + c2 + d; + + return float(j) * v; +} + +void main() { + + vec4 v = foo(); + v = v + s[gl_VertexID]; + v.x = v.x - float(gl_InstanceID); + io = v; +} \ No newline at end of file diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index 603203db..bb6d0bd8 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -501,6 +501,7 @@ public: noContraction = false; nullInit = false; #endif + defaultBlock = false; } // drop qualifiers that don't belong in a temporary variable @@ -514,6 +515,7 @@ public: specConstant = false; nonUniform = false; nullInit = false; + defaultBlock = false; clearLayout(); } @@ -572,6 +574,7 @@ public: bool specConstant : 1; bool nonUniform : 1; bool explicitOffset : 1; + bool defaultBlock : 1; // default blocks with matching names have structures merged when linking #ifdef GLSLANG_WEB bool isWriteOnly() const { return false; } @@ -756,6 +759,46 @@ public: } } + TBlockStorageClass getBlockStorage() const { + if (storage == EvqUniform && !isPushConstant()) { + return EbsUniform; + } + else if (storage == EvqUniform) { + return EbsPushConstant; + } + else if (storage == EvqBuffer) { + return EbsStorageBuffer; + } + return EbsNone; + } + + void setBlockStorage(TBlockStorageClass newBacking) { +#ifndef GLSLANG_WEB + layoutPushConstant = (newBacking == EbsPushConstant); +#endif + switch (newBacking) { + case EbsUniform : + if (layoutPacking == ElpStd430) { + // std430 would not be valid + layoutPacking = ElpStd140; + } + storage = EvqUniform; + break; + case EbsStorageBuffer : + storage = EvqBuffer; + break; +#ifndef GLSLANG_WEB + case EbsPushConstant : + storage = EvqUniform; + layoutSet = TQualifier::layoutSetEnd; + layoutBinding = TQualifier::layoutBindingEnd; + break; +#endif + default: + break; + } + } + #ifdef GLSLANG_WEB bool isPerView() const { return false; } bool isTaskMemory() const { return false; } @@ -852,6 +895,7 @@ public: return hasNonXfbLayout() || hasXfb(); } + TLayoutMatrix layoutMatrix : 3; TLayoutPacking layoutPacking : 4; int layoutOffset; diff --git a/glslang/Include/intermediate.h b/glslang/Include/intermediate.h index 85edd635..1440c205 100644 --- a/glslang/Include/intermediate.h +++ b/glslang/Include/intermediate.h @@ -593,6 +593,7 @@ enum TOperator { EOpTime, EOpAtomicAdd, + EOpAtomicSubtract, EOpAtomicMin, EOpAtomicMax, EOpAtomicAnd, @@ -1135,6 +1136,8 @@ public: virtual TBasicType getBasicType() const { return type.getBasicType(); } virtual TQualifier& getQualifier() { return type.getQualifier(); } virtual const TQualifier& getQualifier() const { return type.getQualifier(); } + virtual TArraySizes* getArraySizes() { return type.getArraySizes(); } + virtual const TArraySizes* getArraySizes() const { return type.getArraySizes(); } virtual void propagatePrecision(TPrecisionQualifier); virtual int getVectorSize() const { return type.getVectorSize(); } virtual int getMatrixCols() const { return type.getMatrixCols(); } diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp index c94a8a4b..a9e5af45 100644 --- a/glslang/MachineIndependent/Initialize.cpp +++ b/glslang/MachineIndependent/Initialize.cpp @@ -1627,6 +1627,36 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "uint atomicCounterExchange(atomic_uint, uint);" "uint atomicCounterCompSwap(atomic_uint, uint, uint);" + "\n"); + } + } + else if (spvVersion.vulkanRelaxed) { + // + // Atomic counter functions act as aliases to normal atomic functions. + // replace definitions to take 'volatile coherent uint' instead of 'atomic_uint' + // and map to equivalent non-counter atomic op + // + if ((profile != EEsProfile && version >= 300) || + (profile == EEsProfile && version >= 310)) { + commonBuiltins.append( + "uint atomicCounterIncrement(volatile coherent uint);" + "uint atomicCounterDecrement(volatile coherent uint);" + "uint atomicCounter(volatile coherent uint);" + + "\n"); + } + if (profile != EEsProfile && version >= 460) { + commonBuiltins.append( + "uint atomicCounterAdd(volatile coherent uint, uint);" + "uint atomicCounterSubtract(volatile coherent uint, uint);" + "uint atomicCounterMin(volatile coherent uint, uint);" + "uint atomicCounterMax(volatile coherent uint, uint);" + "uint atomicCounterAnd(volatile coherent uint, uint);" + "uint atomicCounterOr(volatile coherent uint, uint);" + "uint atomicCounterXor(volatile coherent uint, uint);" + "uint atomicCounterExchange(volatile coherent uint, uint);" + "uint atomicCounterCompSwap(volatile coherent uint, uint, uint);" + "\n"); } } @@ -4124,7 +4154,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV } #ifndef GLSLANG_WEB if ((profile != EEsProfile && version >= 420) || esBarrier) { - if (spvVersion.vulkan == 0) { + if (spvVersion.vulkan == 0 || spvVersion.vulkanRelaxed) { commonBuiltins.append("void memoryBarrierAtomicCounter();"); } commonBuiltins.append("void memoryBarrierImage();"); @@ -4848,6 +4878,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "in int gl_VertexIndex;" "in int gl_InstanceIndex;" ); + + if (spvVersion.vulkan > 0 && version >= 140 && spvVersion.vulkanRelaxed) + stageBuiltins[EShLangVertex].append( + "in int gl_VertexID;" // declare with 'in' qualifier + "in int gl_InstanceID;" + ); + if (version >= 440) { stageBuiltins[EShLangVertex].append( "in int gl_BaseVertexARB;" @@ -4885,7 +4922,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "mediump float gl_PointSize;" // needs qualifier fixed later ); } else { - if (spvVersion.vulkan == 0) + if (spvVersion.vulkan == 0 || spvVersion.vulkanRelaxed) stageBuiltins[EShLangVertex].append( "in highp int gl_VertexID;" // needs qualifier fixed later "in highp int gl_InstanceID;" // needs qualifier fixed later @@ -7436,6 +7473,12 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion SpecialQualifier("gl_InstanceID", EvqInstanceId, EbvInstanceId, symbolTable); } + if (spvVersion.vulkan > 0 && spvVersion.vulkanRelaxed) { + // treat these built-ins as aliases of VertexIndex and InstanceIndex + BuiltInVariable("gl_VertexID", EbvVertexIndex, symbolTable); + BuiltInVariable("gl_InstanceID", EbvInstanceIndex, symbolTable); + } + if (profile != EEsProfile) { if (version >= 440) { symbolTable.setVariableExtensions("gl_BaseVertexARB", 1, &E_GL_ARB_shader_draw_parameters); @@ -8912,6 +8955,14 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("memoryBarrierAtomicCounter", EOpMemoryBarrierAtomicCounter); symbolTable.relateToOperator("memoryBarrierImage", EOpMemoryBarrierImage); + if (spvVersion.vulkanRelaxed) { + // + // functions signature have been replaced to take uint operations on buffer variables + // remap atomic counter functions to atomic operations + // + symbolTable.relateToOperator("memoryBarrierAtomicCounter", EOpMemoryBarrierBuffer); + } + symbolTable.relateToOperator("atomicLoad", EOpAtomicLoad); symbolTable.relateToOperator("atomicStore", EOpAtomicStore); @@ -8919,6 +8970,20 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("atomicCounterDecrement", EOpAtomicCounterDecrement); symbolTable.relateToOperator("atomicCounter", EOpAtomicCounter); + if (spvVersion.vulkanRelaxed) { + // + // functions signature have been replaced to take uint operations + // remap atomic counter functions to atomic operations + // + // these atomic counter functions do not match signatures of glsl + // atomic functions, so they will be remapped to semantically + // equivalent functions in the parser + // + symbolTable.relateToOperator("atomicCounterIncrement", EOpNull); + symbolTable.relateToOperator("atomicCounterDecrement", EOpNull); + symbolTable.relateToOperator("atomicCounter", EOpNull); + } + symbolTable.relateToOperator("clockARB", EOpReadClockSubgroupKHR); symbolTable.relateToOperator("clock2x32ARB", EOpReadClockSubgroupKHR); @@ -8937,6 +9002,23 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("atomicCounterCompSwap", EOpAtomicCounterCompSwap); } + if (spvVersion.vulkanRelaxed) { + // + // functions signature have been replaced to take 'uint' instead of 'atomic_uint' + // remap atomic counter functions to non-counter atomic ops so + // functions act as aliases to non-counter atomic ops + // + symbolTable.relateToOperator("atomicCounterAdd", EOpAtomicAdd); + symbolTable.relateToOperator("atomicCounterSubtract", EOpAtomicSubtract); + symbolTable.relateToOperator("atomicCounterMin", EOpAtomicMin); + symbolTable.relateToOperator("atomicCounterMax", EOpAtomicMax); + symbolTable.relateToOperator("atomicCounterAnd", EOpAtomicAnd); + symbolTable.relateToOperator("atomicCounterOr", EOpAtomicOr); + symbolTable.relateToOperator("atomicCounterXor", EOpAtomicXor); + symbolTable.relateToOperator("atomicCounterExchange", EOpAtomicExchange); + symbolTable.relateToOperator("atomicCounterCompSwap", EOpAtomicCompSwap); + } + symbolTable.relateToOperator("fma", EOpFma); symbolTable.relateToOperator("frexp", EOpFrexp); symbolTable.relateToOperator("ldexp", EOpLdexp); diff --git a/glslang/MachineIndependent/ParseContextBase.cpp b/glslang/MachineIndependent/ParseContextBase.cpp index 3efa27ac..02cca409 100644 --- a/glslang/MachineIndependent/ParseContextBase.cpp +++ b/glslang/MachineIndependent/ParseContextBase.cpp @@ -601,7 +601,6 @@ void TParseContextBase::parseSwizzleSelector(const TSourceLoc& loc, const TStrin selector.push_back(0); } -#ifdef ENABLE_HLSL // // Make the passed-in variable information become a member of the // global uniform block. If this doesn't exist yet, make it. @@ -646,7 +645,67 @@ void TParseContextBase::growGlobalUniformBlock(const TSourceLoc& loc, TType& mem ++firstNewMember; } -#endif + +void TParseContextBase::growAtomicCounterBlock(int binding, const TSourceLoc& loc, TType& memberType, const TString& memberName, TTypeList* typeList) { + // Make the atomic counter block, if not yet made. + const auto &at = atomicCounterBuffers.find(binding); + if (at == atomicCounterBuffers.end()) { + atomicCounterBuffers.insert({binding, (TVariable*)nullptr }); + atomicCounterBlockFirstNewMember.insert({binding, 0}); + } + + TVariable*& atomicCounterBuffer = atomicCounterBuffers[binding]; + int& bufferNewMember = atomicCounterBlockFirstNewMember[binding]; + + if (atomicCounterBuffer == nullptr) { + TQualifier blockQualifier; + blockQualifier.clear(); + blockQualifier.storage = EvqBuffer; + + char charBuffer[512]; + if (binding != TQualifier::layoutBindingEnd) { + snprintf(charBuffer, 512, "%s_%d", getAtomicCounterBlockName(), binding); + } else { + snprintf(charBuffer, 512, "%s_0", getAtomicCounterBlockName()); + } + + TType blockType(new TTypeList, *NewPoolTString(charBuffer), blockQualifier); + setUniformBlockDefaults(blockType); + blockType.getQualifier().layoutPacking = ElpStd430; + atomicCounterBuffer = new TVariable(NewPoolTString(""), blockType, true); + // If we arn't auto mapping bindings then set the block to use the same + // binding as what the atomic was set to use + if (!intermediate.getAutoMapBindings()) { + atomicCounterBuffer->getWritableType().getQualifier().layoutBinding = binding; + } + bufferNewMember = 0; + + atomicCounterBuffer->getWritableType().getQualifier().layoutSet = atomicCounterBlockSet; + } + + // Add the requested member as a member to the global block. + TType* type = new TType; + type->shallowCopy(memberType); + type->setFieldName(memberName); + if (typeList) + type->setStruct(typeList); + TTypeLoc typeLoc = {type, loc}; + atomicCounterBuffer->getType().getWritableStruct()->push_back(typeLoc); + + // Insert into the symbol table. + if (bufferNewMember == 0) { + // This is the first request; we need a normal symbol table insert + if (symbolTable.insert(*atomicCounterBuffer)) + trackLinkage(*atomicCounterBuffer); + else + error(loc, "failed to insert the global constant buffer", "buffer", ""); + } else { + // This is a follow-on request; we need to amend the first insert + symbolTable.amend(*atomicCounterBuffer, bufferNewMember); + } + + ++bufferNewMember; +} void TParseContextBase::finish() { diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 12d68a3e..550fce67 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -225,6 +225,108 @@ void TParseContext::parserError(const char* s) error(getCurrentLoc(), "compilation terminated", "", ""); } +void TParseContext::growGlobalUniformBlock(const TSourceLoc& loc, TType& memberType, const TString& memberName, TTypeList* typeList) +{ + bool createBlock = globalUniformBlock == nullptr; + + if (createBlock) { + globalUniformBinding = intermediate.getGlobalUniformBinding(); + globalUniformSet = intermediate.getGlobalUniformSet(); + } + + // use base class function to create/expand block + TParseContextBase::growGlobalUniformBlock(loc, memberType, memberName, typeList); + + if (spvVersion.vulkan > 0 && spvVersion.vulkanRelaxed) { + // check for a block storage override + TBlockStorageClass storageOverride = intermediate.getBlockStorageOverride(getGlobalUniformBlockName()); + TQualifier& qualifier = globalUniformBlock->getWritableType().getQualifier(); + qualifier.defaultBlock = true; + + if (storageOverride != EbsNone) { + if (createBlock) { + // Remap block storage + qualifier.setBlockStorage(storageOverride); + + // check that the change didn't create errors + blockQualifierCheck(loc, qualifier, false); + } + + // remap meber storage as well + memberType.getQualifier().setBlockStorage(storageOverride); + } + } +} + +void TParseContext::growAtomicCounterBlock(int binding, const TSourceLoc& loc, TType& memberType, const TString& memberName, TTypeList* typeList) +{ + bool createBlock = atomicCounterBuffers.find(binding) == atomicCounterBuffers.end(); + + if (createBlock) { + atomicCounterBlockSet = intermediate.getAtomicCounterBlockSet(); + } + + // use base class function to create/expand block + TParseContextBase::growAtomicCounterBlock(binding, loc, memberType, memberName, typeList); + TQualifier& qualifier = atomicCounterBuffers[binding]->getWritableType().getQualifier(); + qualifier.defaultBlock = true; + + if (spvVersion.vulkan > 0 && spvVersion.vulkanRelaxed) { + // check for a Block storage override + TBlockStorageClass storageOverride = intermediate.getBlockStorageOverride(getAtomicCounterBlockName()); + + if (storageOverride != EbsNone) { + if (createBlock) { + // Remap block storage + + qualifier.setBlockStorage(storageOverride); + + // check that the change didn't create errors + blockQualifierCheck(loc, qualifier, false); + } + + // remap meber storage as well + memberType.getQualifier().setBlockStorage(storageOverride); + } + } +} + +const char* TParseContext::getGlobalUniformBlockName() const +{ + const char* name = intermediate.getGlobalUniformBlockName(); + if (std::string(name) == "") + return "gl_DefaultUniformBlock"; + else + return name; +} +void TParseContext::finalizeGlobalUniformBlockLayout(TVariable&) +{ +} +void TParseContext::setUniformBlockDefaults(TType& block) const +{ + block.getQualifier().layoutPacking = ElpStd140; + block.getQualifier().layoutMatrix = ElmColumnMajor; +} + + +const char* TParseContext::getAtomicCounterBlockName() const +{ + const char* name = intermediate.getAtomicCounterBlockName(); + if (std::string(name) == "") + return "gl_AtomicCounterBlock"; + else + return name; +} +void TParseContext::finalizeAtomicCounterBlockLayout(TVariable&) +{ +} + +void TParseContext::setAtomicCounterBlockDefaults(TType& block) const +{ + block.getQualifier().layoutPacking = ElpStd430; + block.getQualifier().layoutMatrix = ElmRowMajor; +} + void TParseContext::handlePragma(const TSourceLoc& loc, const TVector& tokens) { #ifndef GLSLANG_WEB @@ -1135,6 +1237,14 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction { TIntermTyped* result = nullptr; + if (spvVersion.vulkan != 0 && spvVersion.vulkanRelaxed) { + // allow calls that are invalid in Vulkan Semantics to be invisibily + // remapped to equivalent valid functions + result = vkRelaxedRemapFunctionCall(loc, function, arguments); + if (result) + return result; + } + if (function->getBuiltInOp() == EOpArrayLength) result = handleLengthMethod(loc, function, arguments); else if (function->getBuiltInOp() != EOpNull) { @@ -1727,6 +1837,7 @@ void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction& // Grab the semantics and storage class semantics from the operands, based on opcode switch (callNode.getOp()) { case EOpAtomicAdd: + case EOpAtomicSubtract: case EOpAtomicMin: case EOpAtomicMax: case EOpAtomicAnd: @@ -2176,6 +2287,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan } case EOpAtomicAdd: + case EOpAtomicSubtract: case EOpAtomicMin: case EOpAtomicMax: case EOpAtomicAnd: @@ -3388,7 +3500,7 @@ void TParseContext::transparentOpaqueCheck(const TSourceLoc& loc, const TType& t if (type.containsNonOpaque()) { // Vulkan doesn't allow transparent uniforms outside of blocks - if (spvVersion.vulkan > 0) + if (spvVersion.vulkan > 0 && !spvVersion.vulkanRelaxed) vulkanRemoved(loc, "non-opaque uniforms outside a block"); // OpenGL wants locations on these (unless they are getting automapped) if (spvVersion.openGl > 0 && !type.getQualifier().hasLocation() && !intermediate.getAutoMapLocations()) @@ -5019,14 +5131,22 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi return; } if (id == TQualifier::getLayoutPackingString(ElpPacked)) { - if (spvVersion.spv != 0) - spvRemoved(loc, "packed"); + if (spvVersion.spv != 0) { + if (spvVersion.vulkanRelaxed) + return; // silently ignore qualifier + else + spvRemoved(loc, "packed"); + } publicType.qualifier.layoutPacking = ElpPacked; return; } if (id == TQualifier::getLayoutPackingString(ElpShared)) { - if (spvVersion.spv != 0) - spvRemoved(loc, "shared"); + if (spvVersion.spv != 0) { + if (spvVersion.vulkanRelaxed) + return; // silently ignore qualifier + else + spvRemoved(loc, "shared"); + } publicType.qualifier.layoutPacking = ElpShared; return; } @@ -5928,7 +6048,7 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) error(loc, "sampler binding not less than gl_MaxCombinedTextureImageUnits", "binding", type.isArray() ? "(using array)" : ""); #endif } - if (type.isAtomic()) { + if (type.isAtomic() && !spvVersion.vulkanRelaxed) { if (qualifier.layoutBinding >= (unsigned int)resources.maxAtomicCounterBindings) { error(loc, "atomic_uint binding is too large; see gl_MaxAtomicCounterBindings", "binding", ""); return; @@ -6598,6 +6718,68 @@ const TFunction* TParseContext::findFunctionExplicitTypes(const TSourceLoc& loc, return bestMatch; } +// +// Adjust function calls that aren't declared in Vulkan to a +// calls with equivalent effects +// +TIntermTyped* TParseContext::vkRelaxedRemapFunctionCall(const TSourceLoc& loc, TFunction* function, TIntermNode* arguments) +{ + TIntermTyped* result = nullptr; + +#ifndef GLSLANG_WEB + if (function->getBuiltInOp() != EOpNull) { + return nullptr; + } + + if (function->getName() == "atomicCounterIncrement") { + // change atomicCounterIncrement into an atomicAdd of 1 + TString name("atomicAdd"); + TType uintType(EbtUint); + + TFunction realFunc(&name, function->getType()); + + for (int i = 0; i < function->getParamCount(); ++i) { + realFunc.addParameter((*function)[i]); + } + + TParameter tmpP = { 0, &uintType }; + realFunc.addParameter(tmpP); + arguments = intermediate.growAggregate(arguments, intermediate.addConstantUnion(1, loc, true)); + + result = handleFunctionCall(loc, &realFunc, arguments); + } else if (function->getName() == "atomicCounterDecrement") { + // change atomicCounterDecrement into an atomicAdd with -1 + // and subtract 1 from result, to return post-decrement value + TString name("atomicAdd"); + TType uintType(EbtUint); + + TFunction realFunc(&name, function->getType()); + + for (int i = 0; i < function->getParamCount(); ++i) { + realFunc.addParameter((*function)[i]); + } + + TParameter tmpP = { 0, &uintType }; + realFunc.addParameter(tmpP); + arguments = intermediate.growAggregate(arguments, intermediate.addConstantUnion(-1, loc, true)); + + result = handleFunctionCall(loc, &realFunc, arguments); + + // post decrement, so that it matches AtomicCounterDecrement semantics + if (result) { + result = handleBinaryMath(loc, "-", EOpSub, result, intermediate.addConstantUnion(1, loc, true)); + } + } else if (function->getName() == "atomicCounter") { + // change atomicCounter into a direct read of the variable + if (arguments->getAsTyped()) { + result = arguments->getAsTyped(); + } + } +#endif + + return result; +} + // When a declaration includes a type, but not a variable name, it can be used // to establish defaults. void TParseContext::declareTypeDefaults(const TSourceLoc& loc, const TPublicType& publicType) @@ -6622,6 +6804,91 @@ void TParseContext::declareTypeDefaults(const TSourceLoc& loc, const TPublicType #endif } +bool TParseContext::vkRelaxedRemapUniformVariable(const TSourceLoc& loc, TString& identifier, const TPublicType&, + TArraySizes*, TIntermTyped* initializer, TType& type) +{ + if (parsingBuiltins || symbolTable.atBuiltInLevel() || !symbolTable.atGlobalLevel() || + type.getQualifier().storage != EvqUniform || + !(type.containsNonOpaque() +#ifndef GLSLANG_WEB + || type.getBasicType() == EbtAtomicUint +#endif + )) { + return false; + } + + if (type.getQualifier().hasLocation()) { + warn(loc, "ignoring layout qualifier for uniform", identifier.c_str(), "location"); + type.getQualifier().layoutLocation = TQualifier::layoutLocationEnd; + } + + if (initializer) { + warn(loc, "Ignoring initializer for uniform", identifier.c_str(), ""); + initializer = nullptr; + } + + if (type.isArray()) { + // do array size checks here + arraySizesCheck(loc, type.getQualifier(), type.getArraySizes(), initializer, false); + + if (arrayQualifierError(loc, type.getQualifier()) || arrayError(loc, type)) { + error(loc, "array param error", identifier.c_str(), ""); + } + } + + // do some checking on the type as it was declared + layoutTypeCheck(loc, type); + + int bufferBinding = TQualifier::layoutBindingEnd; + TVariable* updatedBlock = nullptr; + +#ifndef GLSLANG_WEB + // Convert atomic_uint into members of a buffer block + if (type.isAtomic()) { + type.setBasicType(EbtUint); + type.getQualifier().storage = EvqBuffer; + + type.getQualifier().volatil = true; + type.getQualifier().coherent = true; + + // xxTODO: use logic from fixOffset() to apply explicit member offset + bufferBinding = type.getQualifier().layoutBinding; + type.getQualifier().layoutBinding = TQualifier::layoutBindingEnd; + type.getQualifier().explicitOffset = false; + growAtomicCounterBlock(bufferBinding, loc, type, identifier, nullptr); + updatedBlock = atomicCounterBuffers[bufferBinding]; + } +#endif + + if (!updatedBlock) { + growGlobalUniformBlock(loc, type, identifier, nullptr); + updatedBlock = globalUniformBlock; + } + + // + // don't assign explicit member offsets here + // if any are assigned, need to be updated here and in the merge/link step + // fixBlockUniformOffsets(updatedBlock->getWritableType().getQualifier(), *updatedBlock->getWritableType().getWritableStruct()); + + // checks on update buffer object + layoutObjectCheck(loc, *updatedBlock); + + TSymbol* symbol = symbolTable.find(identifier); + + if (!symbol) { + if (updatedBlock == globalUniformBlock) + error(loc, "error adding uniform to default uniform block", identifier.c_str(), ""); + else + error(loc, "error adding atomic counter to atomic counter block", identifier.c_str(), ""); + return false; + } + + // merge qualifiers + mergeObjectLayoutQualifiers(updatedBlock->getWritableType().getQualifier(), type.getQualifier(), true); + + return true; +} + // // Do everything necessary to handle a variable (non-block) declaration. // Either redeclaring a variable, or making a new one, updating the symbol @@ -6733,6 +7000,14 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden if (symbol == nullptr) reservedErrorCheck(loc, identifier); + if (symbol == nullptr && spvVersion.vulkan > 0 && spvVersion.vulkanRelaxed) { + bool remapped = vkRelaxedRemapUniformVariable(loc, identifier, publicType, arraySizes, initializer, type); + + if (remapped) { + return nullptr; + } + } + inheritGlobalDefaults(type.getQualifier()); // Declare the variable @@ -7625,6 +7900,8 @@ void TParseContext::inheritMemoryQualifiers(const TQualifier& from, TQualifier& void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, const TString* instanceName, TArraySizes* arraySizes) { + if (spvVersion.vulkan > 0 && spvVersion.vulkanRelaxed) + blockStorageRemap(loc, blockName, currentBlockQualifier); blockStageIoCheck(loc, currentBlockQualifier); blockQualifierCheck(loc, currentBlockQualifier, instanceName != nullptr); if (arraySizes != nullptr) { @@ -7914,6 +8191,17 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con trackLinkage(variable); } +// +// allow storage type of block to be remapped at compile time +// +void TParseContext::blockStorageRemap(const TSourceLoc&, const TString* instanceName, TQualifier& qualifier) +{ + TBlockStorageClass type = intermediate.getBlockStorageOverride(instanceName->c_str()); + if (type != EbsNone) { + qualifier.setBlockStorage(type); + } +} + // Do all block-declaration checking regarding the combination of in/out/uniform/buffer // with a particular stage. void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& qualifier) diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index ad9b8d6a..6f00621a 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -92,7 +92,8 @@ public: limits(resources.limits), globalUniformBlock(nullptr), globalUniformBinding(TQualifier::layoutBindingEnd), - globalUniformSet(TQualifier::layoutSetEnd) + globalUniformSet(TQualifier::layoutSetEnd), + atomicCounterBlockSet(TQualifier::layoutSetEnd) { if (entryPoint != nullptr) sourceEntryPointName = *entryPoint; @@ -154,10 +155,11 @@ public: extensionCallback(line, extension, behavior); } -#ifdef ENABLE_HLSL // Manage the global uniform block (default uniforms in GLSL, $Global in HLSL) virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr); -#endif + + // Manage global buffer (used for backing atomic counters in GLSL when using relaxed Vulkan semantics) + virtual void growAtomicCounterBlock(int binding, const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr); // Potentially rename shader entry point function void renameShaderFunction(TString*& name) const @@ -230,7 +232,24 @@ protected: // override this to set the language-specific name virtual const char* getGlobalUniformBlockName() const { return ""; } virtual void setUniformBlockDefaults(TType&) const { } - virtual void finalizeGlobalUniformBlockLayout(TVariable&) { } + virtual void finalizeGlobalUniformBlockLayout(TVariable&) {} + + // Manage the atomic counter block (used for atomic_uints with Vulkan-Relaxed) + TMap atomicCounterBuffers; + unsigned int atomicCounterBlockSet; + TMap atomicCounterBlockFirstNewMember; + // override this to set the language-specific name + virtual const char* getAtomicCounterBlockName() const { return ""; } + virtual void setAtomicCounterBlockDefaults(TType&) const {} + virtual void finalizeAtomicCounterBlockLayout(TVariable&) {} + bool isAtomicCounterBlock(const TSymbol& symbol) { + const TVariable* var = symbol.getAsVariable(); + if (!var) + return false; + const auto& at = atomicCounterBuffers.find(var->getType().getQualifier().layoutBinding); + return (at != atomicCounterBuffers.end() && (*at).second->getType() == var->getType()); + } + virtual void outputMessage(const TSourceLoc&, const char* szReason, const char* szToken, const char* szExtraInfoFormat, TPrefixType prefix, va_list args); @@ -293,6 +312,9 @@ public: bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false) override; void parserError(const char* s); // for bison's yyerror + virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr) override; + virtual void growAtomicCounterBlock(int binding, const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr) override; + void reservedErrorCheck(const TSourceLoc&, const TString&); void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op) override; bool lineContinuationCheck(const TSourceLoc&, bool endOfComment) override; @@ -340,6 +362,10 @@ public: void checkPrecisionQualifier(const TSourceLoc&, TPrecisionQualifier); void memorySemanticsCheck(const TSourceLoc&, const TFunction&, const TIntermOperator& callNode); + TIntermTyped* vkRelaxedRemapFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*); + // returns true if the variable was remapped to something else + bool vkRelaxedRemapUniformVariable(const TSourceLoc&, TString&, const TPublicType&, TArraySizes*, TIntermTyped*, TType&); + void assignError(const TSourceLoc&, const char* op, TString left, TString right); void unaryOpError(const TSourceLoc&, const char* op, TString operand); void binaryOpError(const TSourceLoc&, const char* op, TString left, TString right); @@ -417,6 +443,7 @@ public: TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset); void inheritMemoryQualifiers(const TQualifier& from, TQualifier& to); void declareBlock(const TSourceLoc&, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0); + void blockStorageRemap(const TSourceLoc&, const TString*, TQualifier&); void blockStageIoCheck(const TSourceLoc&, const TQualifier&); void blockQualifierCheck(const TSourceLoc&, const TQualifier&, bool instanceName); void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation); @@ -461,6 +488,14 @@ protected: void finish() override; #endif + virtual const char* getGlobalUniformBlockName() const override; + virtual void finalizeGlobalUniformBlockLayout(TVariable&) override; + virtual void setUniformBlockDefaults(TType& block) const override; + + virtual const char* getAtomicCounterBlockName() const override; + virtual void finalizeAtomicCounterBlockLayout(TVariable&) override; + virtual void setAtomicCounterBlockDefaults(TType& block) const override; + public: // // Generally, bison productions, the scanner, and the PP need read/write access to these; just give them direct access diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp index 3f793a74..4b340eaa 100644 --- a/glslang/MachineIndependent/ShaderLang.cpp +++ b/glslang/MachineIndependent/ShaderLang.cpp @@ -159,7 +159,7 @@ int MapVersionToIndex(int version) return index; } -const int SpvVersionCount = 3; // index range in MapSpvVersionToIndex +const int SpvVersionCount = 4; // index range in MapSpvVersionToIndex int MapSpvVersionToIndex(const SpvVersion& spvVersion) { @@ -167,8 +167,12 @@ int MapSpvVersionToIndex(const SpvVersion& spvVersion) if (spvVersion.openGl > 0) index = 1; - else if (spvVersion.vulkan > 0) - index = 2; + else if (spvVersion.vulkan > 0) { + if (!spvVersion.vulkanRelaxed) + index = 2; + else + index = 3; + } assert(index < SpvVersionCount); @@ -723,6 +727,7 @@ void TranslateEnvironment(const TEnvironment* environment, EShMessages& messages break; case EShClientVulkan: spvVersion.vulkanGlsl = environment->input.dialectVersion; + spvVersion.vulkanRelaxed = environment->input.VulkanRulesRelaxed; break; case EShClientOpenGL: spvVersion.openGl = environment->input.dialectVersion; @@ -1868,6 +1873,15 @@ void TShader::setResourceSetBinding(const std::vector& base) { in void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { intermediate->setTextureSamplerTransformMode(mode); } #endif +void TShader::addBlockStorageOverride(const char* nameStr, TBlockStorageClass backing) { intermediate->addBlockStorageOverride(nameStr, backing); } + +void TShader::setGlobalUniformBlockName(const char* name) { intermediate->setGlobalUniformBlockName(name); } +void TShader::setGlobalUniformSet(unsigned int set) { intermediate->setGlobalUniformSet(set); } +void TShader::setGlobalUniformBinding(unsigned int binding) { intermediate->setGlobalUniformBinding(binding); } + +void TShader::setAtomicCounterBlockName(const char* name) { intermediate->setAtomicCounterBlockName(name); } +void TShader::setAtomicCounterBlockSet(unsigned int set) { intermediate->setAtomicCounterBlockSet(set); } + #ifdef ENABLE_HLSL // See comment above TDefaultHlslIoMapper in iomapper.cpp: void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); } @@ -1983,7 +1997,10 @@ bool TProgram::link(EShMessages messages) error = true; } - // TODO: Link: cross-stage error checking + if (!error) { + if (! crossStageCheck(messages)) + error = true; + } return ! error; } @@ -2060,6 +2077,64 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages) return intermediate[stage]->getNumErrors() == 0; } +// +// Check that there are no errors in linker objects accross stages +// +// Return true if no errors. +// +bool TProgram::crossStageCheck(EShMessages) { + + // make temporary intermediates to hold the linkage symbols for each linking interface + // while we do the checks + // Independent interfaces are: + // all uniform variables and blocks + // all buffer blocks + // all in/out on a stage boundary + + TVector activeStages; + for (int s = 0; s < EShLangCount; ++s) { + if (intermediate[s]) + activeStages.push_back(intermediate[s]); + } + + // no extra linking if there is only one stage + if (! (activeStages.size() > 1)) + return true; + + // setup temporary tree to hold unfirom objects from different stages + TIntermediate* firstIntermediate = activeStages.front(); + TIntermediate uniforms(EShLangCount, + firstIntermediate->getVersion(), + firstIntermediate->getProfile()); + uniforms.setSpv(firstIntermediate->getSpv()); + + TIntermAggregate uniformObjects(EOpLinkerObjects); + TIntermAggregate root(EOpSequence); + root.getSequence().push_back(&uniformObjects); + uniforms.setTreeRoot(&root); + + bool error = false; + + // merge uniforms from all stages into a single intermediate + for (unsigned int i = 0; i < activeStages.size(); ++i) { + uniforms.mergeUniformObjects(*infoSink, *activeStages[i]); + } + error |= uniforms.getNumErrors() != 0; + + // copy final definition of global block back into each stage + for (unsigned int i = 0; i < activeStages.size(); ++i) { + activeStages[i]->mergeGlobalUniformBlocks(*infoSink, uniforms); + } + + // compare cross stage symbols for each stage boundary + for (unsigned int i = 1; i < activeStages.size(); ++i) { + activeStages[i - 1]->checkStageIO(*infoSink, *activeStages[i]); + error |= (activeStages[i - 1]->getNumErrors() != 0); + } + + return !error; +} + const char* TProgram::getInfoLog() { return infoSink->info.c_str(); diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp index 488c98c5..7554bfd7 100644 --- a/glslang/MachineIndependent/Versions.cpp +++ b/glslang/MachineIndependent/Versions.cpp @@ -1273,7 +1273,7 @@ void TParseVersions::spvRemoved(const TSourceLoc& loc, const char* op) // Call for any operation removed because Vulkan SPIR-V is being generated. void TParseVersions::vulkanRemoved(const TSourceLoc& loc, const char* op) { - if (spvVersion.vulkan > 0) + if (spvVersion.vulkan > 0 && !spvVersion.vulkanRelaxed) error(loc, "not allowed when using GLSL for Vulkan", op, ""); } diff --git a/glslang/MachineIndependent/Versions.h b/glslang/MachineIndependent/Versions.h index f377973a..25feb0b7 100644 --- a/glslang/MachineIndependent/Versions.h +++ b/glslang/MachineIndependent/Versions.h @@ -87,11 +87,12 @@ inline const char* ProfileName(EProfile profile) // The union of all requested rule sets will be applied. // struct SpvVersion { - SpvVersion() : spv(0), vulkanGlsl(0), vulkan(0), openGl(0) {} + SpvVersion() : spv(0), vulkanGlsl(0), vulkan(0), openGl(0), vulkanRelaxed(false) {} unsigned int spv; // the version of SPIR-V to target, as defined by "word 1" of the SPIR-V binary header int vulkanGlsl; // the version of GLSL semantics for Vulkan, from GL_KHR_vulkan_glsl, for "#define VULKAN XXX" int vulkan; // the version of Vulkan, for which SPIR-V execution environment rules to use int openGl; // the version of GLSL semantics for OpenGL, from GL_ARB_gl_spirv, for "#define GL_SPIRV XXX" + bool vulkanRelaxed; // relax changes to GLSL for Vulkan, allowing some GL-specific to be compiled to Vulkan SPIR-V target }; // diff --git a/glslang/MachineIndependent/intermOut.cpp b/glslang/MachineIndependent/intermOut.cpp index 5ce3e472..c718f949 100644 --- a/glslang/MachineIndependent/intermOut.cpp +++ b/glslang/MachineIndependent/intermOut.cpp @@ -886,6 +886,7 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node case EOpTime: out.debug << "time"; break; case EOpAtomicAdd: out.debug << "AtomicAdd"; break; + case EOpAtomicSubtract: out.debug << "AtomicSubtract"; break; case EOpAtomicMin: out.debug << "AtomicMin"; break; case EOpAtomicMax: out.debug << "AtomicMax"; break; case EOpAtomicAnd: out.debug << "AtomicAnd"; break; diff --git a/glslang/MachineIndependent/iomapper.cpp b/glslang/MachineIndependent/iomapper.cpp index c42e74fa..7e12864f 100644 --- a/glslang/MachineIndependent/iomapper.cpp +++ b/glslang/MachineIndependent/iomapper.cpp @@ -210,8 +210,8 @@ struct TResolverUniformAdaptor { ent.newIndex = -1; const bool isValid = resolver.validateBinding(stage, ent); if (isValid) { - resolver.resolveBinding(ent.stage, ent); resolver.resolveSet(ent.stage, ent); + resolver.resolveBinding(ent.stage, ent); resolver.resolveUniformLocation(ent.stage, ent); if (ent.newBinding != -1) { @@ -317,15 +317,13 @@ private: }; // The class is used for reserving explicit uniform locations and ubo/ssbo/opaque bindings +// xxTODO: maybe this logic should be moved into the resolver's "validateInOut" and "validateUniform" struct TSymbolValidater { TSymbolValidater(TIoMapResolver& r, TInfoSink& i, TVarLiveMap* in[EShLangCount], TVarLiveMap* out[EShLangCount], TVarLiveMap* uniform[EShLangCount], bool& hadError, EProfile profile, int version) - : preStage(EShLangCount) - , currentStage(EShLangCount) - , nextStage(EShLangCount) - , resolver(r) + : resolver(r) , infoSink(i) , hadError(hadError) , profile(profile) @@ -438,17 +436,23 @@ struct TSymbolValidater TIntermSymbol* base = ent1.symbol; const TType& type = ent1.symbol->getType(); const TString& name = entKey.first; - EShLanguage stage = ent1.stage; TString mangleName1, mangleName2; - if (currentStage != stage) { - preStage = currentStage; - currentStage = stage; - nextStage = EShLangCount; - for (int i = currentStage + 1; i < EShLangCount; i++) { - if (inVarMaps[i] != nullptr) { - nextStage = static_cast(i); - break; - } + EShLanguage stage = ent1.stage; + EShLanguage preStage, currentStage, nextStage; + + preStage = EShLangCount; + for (int i = stage - 1; i >= 0; i--) { + if (inVarMaps[i] != nullptr) { + preStage = static_cast(i); + break; + } + } + currentStage = stage; + nextStage = EShLangCount; + for (int i = stage + 1; i < EShLangCount; i++) { + if (inVarMaps[i] != nullptr) { + nextStage = static_cast(i); + break; } } @@ -459,6 +463,9 @@ struct TSymbolValidater type.appendMangledName(mangleName1); } + + // basic checking that symbols match + // more extensive checking in the link stage if (base->getQualifier().storage == EvqVaryingIn) { // validate stage in; if (preStage == EShLangCount) @@ -484,8 +491,7 @@ struct TSymbolValidater if (ent2->second.symbol->getType().getQualifier().isArrayedIo(preStage)) { TType subType(ent2->second.symbol->getType(), 0); subType.appendMangledName(mangleName2); - } - else { + } else { ent2->second.symbol->getType().appendMangledName(mangleName2); } @@ -536,8 +542,7 @@ struct TSymbolValidater if (ent2->second.symbol->getType().getQualifier().isArrayedIo(nextStage)) { TType subType(ent2->second.symbol->getType(), 0); subType.appendMangledName(mangleName2); - } - else { + } else { ent2->second.symbol->getType().appendMangledName(mangleName2); } if (mangleName1 == mangleName2) @@ -550,7 +555,7 @@ struct TSymbolValidater } return; } - } else if (base->getQualifier().isUniformOrBuffer() && ! base->getQualifier().isPushConstant()) { + } else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().isPushConstant()) { // validate uniform type; for (int i = 0; i < EShLangCount; i++) { if (i != currentStage && outVarMaps[i] != nullptr) { @@ -558,6 +563,7 @@ struct TSymbolValidater if (ent2 != uniformVarMap[i]->end()) { ent2->second.symbol->getType().appendMangledName(mangleName2); if (mangleName1 != mangleName2) { + ent2->second.symbol->getType().sameElementType(type); TString err = "Invalid Uniform variable type : " + entKey.first; infoSink.info.message(EPrefixInternalError, err.c_str()); hadError = true; @@ -608,8 +614,7 @@ struct TSymbolValidater } TVarLiveMap *inVarMaps[EShLangCount], *outVarMaps[EShLangCount], *uniformVarMap[EShLangCount]; - // Use for mark pre stage, to get more interface symbol information. - EShLanguage preStage, currentStage, nextStage; + // Use for mark current shader stage for resolver TIoMapResolver& resolver; TInfoSink& infoSink; @@ -749,14 +754,18 @@ TDefaultIoResolverBase::TDefaultIoResolverBase(const TIntermediate& intermediate , nextOutputLocation(0) { memset(stageMask, false, sizeof(bool) * (EShLangCount + 1)); + memset(stageIntermediates, 0, sizeof(TIntermediate*) * (EShLangCount)); + stageIntermediates[intermediate.getStage()] = &intermediate; } -int TDefaultIoResolverBase::getBaseBinding(TResourceType res, unsigned int set) const { - return selectBaseBinding(intermediate.getShiftBinding(res), intermediate.getShiftBindingForSet(res, set)); +int TDefaultIoResolverBase::getBaseBinding(EShLanguage stage, TResourceType res, unsigned int set) const { + return stageIntermediates[stage] ? selectBaseBinding(stageIntermediates[stage]->getShiftBinding(res), stageIntermediates[stage]->getShiftBindingForSet(res, set)) + : selectBaseBinding(intermediate.getShiftBinding(res), intermediate.getShiftBindingForSet(res, set)); } -const std::vector& TDefaultIoResolverBase::getResourceSetBinding() const { - return intermediate.getResourceSetBinding(); +const std::vector& TDefaultIoResolverBase::getResourceSetBinding(EShLanguage stage) const { + return stageIntermediates[stage] ? stageIntermediates[stage]->getResourceSetBinding() + : intermediate.getResourceSetBinding(); } bool TDefaultIoResolverBase::doAutoBindingMapping() const { return intermediate.getAutoMapBindings(); } @@ -797,14 +806,14 @@ int TDefaultIoResolverBase::getFreeSlot(int set, int base, int size) { return reserveSlot(set, base, size); } -int TDefaultIoResolverBase::resolveSet(EShLanguage /*stage*/, TVarEntryInfo& ent) { +int TDefaultIoResolverBase::resolveSet(EShLanguage stage, TVarEntryInfo& ent) { const TType& type = ent.symbol->getType(); if (type.getQualifier().hasSet()) { return ent.newSet = type.getQualifier().layoutSet; } // If a command line or API option requested a single descriptor set, use that (if not overrided by spaceN) - if (getResourceSetBinding().size() == 1) { - return ent.newSet = atoi(getResourceSetBinding()[0].c_str()); + if (getResourceSetBinding(stage).size() == 1) { + return ent.newSet = atoi(getResourceSetBinding(stage)[0].c_str()); } return ent.newSet = 0; } @@ -925,7 +934,7 @@ int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInf preStage = currentStage; currentStage = stage; } - // kick out of not doing this + // kick out if not doing this if (! doAutoLocationMapping()) { return ent.newLocation = -1; } @@ -1073,7 +1082,7 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn return ent.newLocation = location; } -int TDefaultGlslIoResolver::resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent) { +int TDefaultGlslIoResolver::resolveBinding(EShLanguage stage, TVarEntryInfo& ent) { const TType& type = ent.symbol->getType(); const TString& name = ent.symbol->getAccessName(); // On OpenGL arrays of opaque types take a separate binding for each element @@ -1086,30 +1095,32 @@ int TDefaultGlslIoResolver::resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& // There is no 'set' qualifier in OpenGL shading language, each resource has its own // binding name space, so remap the 'set' to resource type which make each resource // binding is valid from 0 to MAX_XXRESOURCE_BINDINGS - int set = resource; + int set = intermediate.getSpv().openGl != 0 ? resource : ent.newSet; + int resourceKey = set; if (resource < EResCount) { if (type.getQualifier().hasBinding()) { - ent.newBinding = reserveSlot(set, getBaseBinding(resource, set) + type.getQualifier().layoutBinding, numBindings); - return ent.newBinding; - } else if (ent.live && doAutoBindingMapping()) { + int newBinding = reserveSlot(resourceKey, getBaseBinding(stage, resource, set) + type.getQualifier().layoutBinding, numBindings); + return ent.newBinding = newBinding; + + } else { // The resource in current stage is not declared with binding, but it is possible declared // with explicit binding in other stages, find the resourceSlotMap firstly to check whether // the resource has binding, don't need to allocate if it already has a binding bool hasBinding = false; - if (! resourceSlotMap[resource].empty()) { - TVarSlotMap::iterator iter = resourceSlotMap[resource].find(name); - if (iter != resourceSlotMap[resource].end()) { + ent.newBinding = -1; // leave as -1 if it isn't set below + + if (! resourceSlotMap[resourceKey].empty()) { + TVarSlotMap::iterator iter = resourceSlotMap[resourceKey].find(name); + if (iter != resourceSlotMap[resourceKey].end()) { hasBinding = true; ent.newBinding = iter->second; } } - if (! hasBinding) { - TVarSlotMap varSlotMap; + if (!hasBinding && (ent.live && doAutoBindingMapping())) { // find free slot, the caller did make sure it passes all vars with binding // first and now all are passed that do not have a binding and needs one - int binding = getFreeSlot(resource, getBaseBinding(resource, set), numBindings); - varSlotMap[name] = binding; - resourceSlotMap[resource] = varSlotMap; + int binding = getFreeSlot(resourceKey, getBaseBinding(stage, resource, set), numBindings); + resourceSlotMap[resourceKey][name] = binding; ent.newBinding = binding; } return ent.newBinding; @@ -1211,16 +1222,20 @@ void TDefaultGlslIoResolver::reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& void TDefaultGlslIoResolver::reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) { const TType& type = ent.symbol->getType(); const TString& name = ent.symbol->getAccessName(); - int resource = getResourceType(type); + TResourceType resource = getResourceType(type); + int set = intermediate.getSpv().openGl != 0 ? resource : resolveSet(ent.stage, ent); + int resourceKey = set; + if (type.getQualifier().hasBinding()) { - TVarSlotMap& varSlotMap = resourceSlotMap[resource]; + TVarSlotMap& varSlotMap = resourceSlotMap[resourceKey]; TVarSlotMap::iterator iter = varSlotMap.find(name); - int binding = type.getQualifier().layoutBinding; + int binding = type.getQualifier().layoutBinding + getBaseBinding(ent.stage, resource, set); + if (iter == varSlotMap.end()) { // Reserve the slots for the ubo, ssbo and opaques who has explicit binding - int numBindings = type.isSizedArray() ? type.getCumulativeArraySize() : 1; + int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1; varSlotMap[name] = binding; - reserveSlot(resource, binding, numBindings); + reserveSlot(resourceKey, binding, numBindings); } else { // Allocate binding by name for OpenGL driver, so the resource in different // stages should be declared with the same binding @@ -1269,7 +1284,7 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase { return EResCount; } - int resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent) override { + int resolveBinding(EShLanguage stage, TVarEntryInfo& ent) override { const TType& type = ent.symbol->getType(); const int set = getLayoutSet(type); // On OpenGL arrays of opaque types take a seperate binding for each element @@ -1278,11 +1293,11 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase { if (resource < EResCount) { if (type.getQualifier().hasBinding()) { return ent.newBinding = reserveSlot( - set, getBaseBinding(resource, set) + type.getQualifier().layoutBinding, numBindings); + set, getBaseBinding(stage, resource, set) + type.getQualifier().layoutBinding, numBindings); } else if (ent.live && doAutoBindingMapping()) { // find free slot, the caller did make sure it passes all vars with binding // first and now all are passed that do not have a binding and needs one - return ent.newBinding = getFreeSlot(set, getBaseBinding(resource, set), numBindings); + return ent.newBinding = getFreeSlot(set, getBaseBinding(stage, resource, set), numBindings); } } return ent.newBinding = -1; @@ -1354,17 +1369,17 @@ struct TDefaultHlslIoResolver : public TDefaultIoResolverBase { return EResCount; } - int resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent) override { + int resolveBinding(EShLanguage stage, TVarEntryInfo& ent) override { const TType& type = ent.symbol->getType(); const int set = getLayoutSet(type); TResourceType resource = getResourceType(type); if (resource < EResCount) { if (type.getQualifier().hasBinding()) { - return ent.newBinding = reserveSlot(set, getBaseBinding(resource, set) + type.getQualifier().layoutBinding); + return ent.newBinding = reserveSlot(set, getBaseBinding(stage, resource, set) + type.getQualifier().layoutBinding); } else if (ent.live && doAutoBindingMapping()) { // find free slot, the caller did make sure it passes all vars with binding // first and now all are passed that do not have a binding and needs one - return ent.newBinding = getFreeSlot(set, getBaseBinding(resource, set)); + return ent.newBinding = getFreeSlot(set, getBaseBinding(stage, resource, set)); } } return ent.newBinding = -1; @@ -1403,10 +1418,10 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TInfoSi else resolver = &defaultResolver; } - resolver->addStage(stage); #else resolver = &defaultResolver; #endif + resolver->addStage(stage, intermediate); TVarLiveMap inVarMap, outVarMap, uniformVarMap; TVarLiveVector inVector, outVector, uniformVector; @@ -1502,10 +1517,21 @@ bool TGlslIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TIn } // if no resolver is provided, use the default resolver with the given shifts and auto map settings TDefaultGlslIoResolver defaultResolver(intermediate); +#ifdef ENABLE_HLSL + TDefaultHlslIoResolver defaultHlslResolver(intermediate); + if (resolver == nullptr) { + // TODO: use a passed in IO mapper for this + if (intermediate.usingHlslIoMapping()) + resolver = &defaultHlslResolver; + else + resolver = &defaultResolver; + } +#else if (resolver == nullptr) { resolver = &defaultResolver; } - resolver->addStage(stage); +#endif + resolver->addStage(stage, intermediate); inVarMaps[stage] = new TVarLiveMap(); outVarMaps[stage] = new TVarLiveMap(); uniformVarMap[stage] = new TVarLiveMap(); TVarGatherTraverser iter_binding_all(intermediate, true, *inVarMaps[stage], *outVarMaps[stage], *uniformVarMap[stage]); @@ -1547,15 +1573,51 @@ bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) { TResolverInOutAdaptor inOutResolve(EShLangCount, *resolver, infoSink, hadError); TSymbolValidater symbolValidater(*resolver, infoSink, inVarMaps, outVarMaps, uniformVarMap, hadError, profile, version); + + TVarLiveVector inVectors[EShLangCount]; + TVarLiveVector outVectors[EShLangCount]; TVarLiveVector uniformVector; + resolver->beginResolve(EShLangCount); for (int stage = EShLangVertex; stage < EShLangCount; stage++) { if (inVarMaps[stage] != nullptr) { inOutResolve.setStage(EShLanguage(stage)); - for (auto& var : *(inVarMaps[stage])) { symbolValidater(var); } - for (auto& var : *(inVarMaps[stage])) { inOutResolve(var); } - for (auto& var : *(outVarMaps[stage])) { symbolValidater(var); } - for (auto& var : *(outVarMaps[stage])) { inOutResolve(var); } + + // copy vars into a sorted list + std::for_each(inVarMaps[stage]->begin(), inVarMaps[stage]->end(), + [&inVectors, stage](TVarLivePair p) { inVectors[stage].push_back(p); }); + std::sort(inVectors[stage].begin(), inVectors[stage].end(), + [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool { + return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second); + }); + + std::for_each(outVarMaps[stage]->begin(), outVarMaps[stage]->end(), + [&outVectors, stage](TVarLivePair p) { outVectors[stage].push_back(p); }); + std::sort(outVectors[stage].begin(), outVectors[stage].end(), + [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool { + return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second); + }); + + for (auto& var : inVectors[stage]) { symbolValidater(var); } + for (auto& var : inVectors[stage]) { inOutResolve(var); } + for (auto& var : outVectors[stage]) { symbolValidater(var); } + for (auto& var : outVectors[stage]) { inOutResolve(var); } + + // copy results back into maps + std::for_each(inVectors[stage].begin(), inVectors[stage].end(), + [this, stage](TVarLivePair p) { + auto at = inVarMaps[stage]->find(p.first); + if (at != inVarMaps[stage]->end()) + at->second = p.second; + }); + + std::for_each(outVectors[stage].begin(), outVectors[stage].end(), + [this, stage](TVarLivePair p) { + auto at = outVarMaps[stage]->find(p.first); + if (at != outVarMaps[stage]->end()) + at->second = p.second; + }); + } if (uniformVarMap[stage] != nullptr) { uniformResolve.setStage(EShLanguage(stage)); @@ -1563,7 +1625,7 @@ bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) { } } std::sort(uniformVector.begin(), uniformVector.end(), [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool { - return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second); + return TVarEntryInfo::TOrderByPriorityAndLive()(p1.second, p2.second); }); for (auto& var : uniformVector) { symbolValidater(var); } for (auto& var : uniformVector) { uniformResolve(var); } diff --git a/glslang/MachineIndependent/iomapper.h b/glslang/MachineIndependent/iomapper.h index 1dce8ff5..07357c2e 100644 --- a/glslang/MachineIndependent/iomapper.h +++ b/glslang/MachineIndependent/iomapper.h @@ -87,6 +87,35 @@ struct TVarEntryInfo { return lPoints > rPoints; } }; + + struct TOrderByPriorityAndLive { + // ordering: + // 1) do live variables first + // 2) has both binding and set + // 3) has binding but no set + // 4) has no binding but set + // 5) has no binding and no set + inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { + + const TQualifier& lq = l.symbol->getQualifier(); + const TQualifier& rq = r.symbol->getQualifier(); + + // simple rules: + // has binding gives 2 points + // has set gives 1 point + // who has the most points is more important. + int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0); + int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0); + + if (l.live != r.live) + return l.live > r.live; + + if (lPoints != rPoints) + return lPoints > rPoints; + + return l.id < r.id; + } + }; }; // Base class for shared TIoMapResolver services, used by several derivations. @@ -107,8 +136,8 @@ public: void endCollect(EShLanguage) override {} void reserverResourceSlot(TVarEntryInfo& /*ent*/, TInfoSink& /*infoSink*/) override {} void reserverStorageSlot(TVarEntryInfo& /*ent*/, TInfoSink& /*infoSink*/) override {} - int getBaseBinding(TResourceType res, unsigned int set) const; - const std::vector& getResourceSetBinding() const; + int getBaseBinding(EShLanguage stage, TResourceType res, unsigned int set) const; + const std::vector& getResourceSetBinding(EShLanguage stage) const; virtual TResourceType getResourceType(const glslang::TType& type) = 0; bool doAutoBindingMapping() const; bool doAutoLocationMapping() const; @@ -122,9 +151,11 @@ public: int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) override; int resolveInOutComponent(EShLanguage /*stage*/, TVarEntryInfo& ent) override; int resolveInOutIndex(EShLanguage /*stage*/, TVarEntryInfo& ent) override; - void addStage(EShLanguage stage) override { - if (stage < EShLangCount) + void addStage(EShLanguage stage, TIntermediate& stageIntermediate) override { + if (stage < EShLangCount) { stageMask[stage] = true; + stageIntermediates[stage] = &stageIntermediate; + } } uint32_t computeTypeLocationSize(const TType& type, EShLanguage stage); @@ -139,6 +170,8 @@ protected: int nextInputLocation; int nextOutputLocation; bool stageMask[EShLangCount + 1]; + const TIntermediate* stageIntermediates[EShLangCount]; + // Return descriptor set specific base if there is one, and the generic base otherwise. int selectBaseBinding(int base, int descriptorSetBase) const { return descriptorSetBase != -1 ? descriptorSetBase : base; diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp index 3f3a3127..789dc3c3 100644 --- a/glslang/MachineIndependent/linkValidate.cpp +++ b/glslang/MachineIndependent/linkValidate.cpp @@ -90,6 +90,55 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit) #endif } +// +// check that link objects between stages +// +void TIntermediate::mergeUniformObjects(TInfoSink& infoSink, TIntermediate& unit) { + if (unit.treeRoot == nullptr || treeRoot == nullptr) + return; + + // Get the linker-object lists + TIntermSequence& linkerObjects = findLinkerObjects()->getSequence(); + TIntermSequence unitLinkerObjects = unit.findLinkerObjects()->getSequence(); + + // filter unitLinkerObjects to only contain uniforms + auto end = std::remove_if(unitLinkerObjects.begin(), unitLinkerObjects.end(), + [](TIntermNode* node) {return node->getAsSymbolNode()->getQualifier().storage != EvqUniform && + node->getAsSymbolNode()->getQualifier().storage != EvqBuffer; }); + unitLinkerObjects.resize(end - unitLinkerObjects.begin()); + + // merge uniforms and do error checking + mergeGlobalUniformBlocks(infoSink, unit); + mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects, unit.getStage()); +} + +// +// do error checking on the shader boundary in / out vars +// +void TIntermediate::checkStageIO(TInfoSink& infoSink, TIntermediate& unit) { + if (unit.treeRoot == nullptr || treeRoot == nullptr) + return; + + // Get copies of the linker-object lists + TIntermSequence linkerObjects = findLinkerObjects()->getSequence(); + TIntermSequence unitLinkerObjects = unit.findLinkerObjects()->getSequence(); + + // filter linkerObjects to only contain out variables + auto end = std::remove_if(linkerObjects.begin(), linkerObjects.end(), + [](TIntermNode* node) {return node->getAsSymbolNode()->getQualifier().storage != EvqVaryingOut; }); + linkerObjects.resize(end - linkerObjects.begin()); + + // filter unitLinkerObjects to only contain in variables + auto unitEnd = std::remove_if(unitLinkerObjects.begin(), unitLinkerObjects.end(), + [](TIntermNode* node) {return node->getAsSymbolNode()->getQualifier().storage != EvqVaryingIn; }); + unitLinkerObjects.resize(unitEnd - unitLinkerObjects.begin()); + + // do matching and error checking + mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects, unit.getStage()); + + // TODO: final check; make sure that any statically used `in` have matching `out` written to +} + void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit) { if (unit.getNumEntryPoints() > 0) { @@ -137,6 +186,7 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit) MERGE_MAX(spvVersion.vulkanGlsl); MERGE_MAX(spvVersion.vulkan); MERGE_MAX(spvVersion.openGl); + MERGE_TRUE(spvVersion.vulkanRelaxed); numErrors += unit.getNumErrors(); // Only one push_constant is allowed, mergeLinkerObjects() will ensure the push_constant @@ -312,7 +362,8 @@ void TIntermediate::mergeTrees(TInfoSink& infoSink, TIntermediate& unit) remapIds(idMaps, idShift + 1, unit); mergeBodies(infoSink, globals, unitGlobals); - mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects); + mergeGlobalUniformBlocks(infoSink, unit); + mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects, unit.getStage()); ioAccessed.insert(unit.ioAccessed.begin(), unit.ioAccessed.end()); } @@ -456,11 +507,193 @@ void TIntermediate::mergeBodies(TInfoSink& infoSink, TIntermSequence& globals, c globals.insert(globals.end() - 1, unitGlobals.begin(), unitGlobals.end() - 1); } +static inline bool isSameInterface(TIntermSymbol* symbol, EShLanguage stage, TIntermSymbol* unitSymbol, EShLanguage unitStage) { + return // 1) same stage and same shader interface + (stage == unitStage && symbol->getType().getShaderInterface() == unitSymbol->getType().getShaderInterface()) || + // 2) accross stages and both are uniform or buffer + (symbol->getQualifier().storage == EvqUniform && unitSymbol->getQualifier().storage == EvqUniform) || + (symbol->getQualifier().storage == EvqBuffer && unitSymbol->getQualifier().storage == EvqBuffer) || + // 3) in/out matched across stage boundary + (stage < unitStage && symbol->getQualifier().storage == EvqVaryingOut && unitSymbol->getQualifier().storage == EvqVaryingIn) || + (unitStage < stage && symbol->getQualifier().storage == EvqVaryingIn && unitSymbol->getQualifier().storage == EvqVaryingOut); +} + +// +// Global Unfiform block stores any default uniforms (i.e. uniforms without a block) +// If two linked stages declare the same member, they are meant to be the same uniform +// and need to be in the same block +// merge the members of different stages to allow them to be linked properly +// as a single block +// +void TIntermediate::mergeGlobalUniformBlocks(TInfoSink& infoSink, TIntermediate& unit) +{ + TIntermSequence& linkerObjects = findLinkerObjects()->getSequence(); + TIntermSequence& unitLinkerObjects = unit.findLinkerObjects()->getSequence(); + + // build lists of default blocks from the intermediates + TIntermSequence defaultBlocks; + TIntermSequence unitDefaultBlocks; + + auto filter = [](TIntermSequence& list, TIntermNode* node) { + if (node->getAsSymbolNode()->getQualifier().defaultBlock) { + list.push_back(node); + } + }; + + std::for_each(linkerObjects.begin(), linkerObjects.end(), + [&defaultBlocks, &filter](TIntermNode* node) { + filter(defaultBlocks, node); + }); + std::for_each(unitLinkerObjects.begin(), unitLinkerObjects.end(), + [&unitDefaultBlocks, &filter](TIntermNode* node) { + filter(unitDefaultBlocks, node); + }); + + auto itUnitBlock = unitDefaultBlocks.begin(); + for (; itUnitBlock != unitDefaultBlocks.end(); itUnitBlock++) { + + bool add = true; + auto itBlock = defaultBlocks.begin(); + + for (; itBlock != defaultBlocks.end(); itBlock++) { + TIntermSymbol* block = (*itBlock)->getAsSymbolNode(); + TIntermSymbol* unitBlock = (*itUnitBlock)->getAsSymbolNode(); + + assert(block && unitBlock); + + // if the two default blocks match, then merge their definitions + if (block->getType().getTypeName() == unitBlock->getType().getTypeName() && + block->getQualifier().storage == unitBlock->getQualifier().storage) { + add = false; + mergeBlockDefinitions(infoSink, block, unitBlock, &unit); + } + } + if (add) { + // push back on original list; won't change the size of the list we're iterating over + linkerObjects.push_back(*itUnitBlock); + } + } +} + +void TIntermediate::mergeBlockDefinitions(TInfoSink& infoSink, TIntermSymbol* block, TIntermSymbol* unitBlock, TIntermediate* unit) { + if (block->getType() == unitBlock->getType()) { + return; + } + + if (block->getType().getTypeName() != unitBlock->getType().getTypeName() || + block->getType().getBasicType() != unitBlock->getType().getBasicType() || + block->getQualifier().storage != unitBlock->getQualifier().storage || + block->getQualifier().layoutSet != unitBlock->getQualifier().layoutSet) { + // different block names likely means different blocks + return; + } + + // merge the struct + // order of declarations doesn't matter and they matched based on member name + TTypeList* memberList = block->getType().getWritableStruct(); + TTypeList* unitMemberList = unitBlock->getType().getWritableStruct(); + + // keep track of which members have changed position + // so we don't have to search the array again + std::map memberIndexUpdates; + + size_t memberListStartSize = memberList->size(); + for (unsigned int i = 0; i < unitMemberList->size(); ++i) { + bool merge = true; + for (unsigned int j = 0; j < memberListStartSize; ++j) { + if ((*memberList)[j].type->getFieldName() == (*unitMemberList)[i].type->getFieldName()) { + merge = false; + const TType* memberType = (*memberList)[j].type; + const TType* unitMemberType = (*unitMemberList)[i].type; + + // compare types + // don't need as many checks as when merging symbols, since + // initializers and most qualifiers are stripped when the member is moved into the block + if ((*memberType) != (*unitMemberType)) { + error(infoSink, "Types must match:"); + infoSink.info << " " << memberType->getFieldName() << ": "; + infoSink.info << "\"" << memberType->getCompleteString() << "\" versus "; + infoSink.info << "\"" << unitMemberType->getCompleteString() << "\"\n"; + } + + memberIndexUpdates[i] = j; + } + } + if (merge) { + memberList->push_back((*unitMemberList)[i]); + memberIndexUpdates[i] = (unsigned int)memberList->size() - 1; + } + } + + TType unitType; + unitType.shallowCopy(unitBlock->getType()); + + // update symbol node in unit tree, + // and other nodes that may reference it + class TMergeBlockTraverser : public TIntermTraverser { + public: + TMergeBlockTraverser(const glslang::TType &type, const glslang::TType& unitType, + glslang::TIntermediate& unit, + const std::map& memberIdxUpdates) : + newType(type), unitType(unitType), unit(unit), memberIndexUpdates(memberIdxUpdates) + { } + virtual ~TMergeBlockTraverser() { } + + const glslang::TType& newType; // type with modifications + const glslang::TType& unitType; // copy of original type + glslang::TIntermediate& unit; // intermediate that is being updated + const std::map& memberIndexUpdates; + + virtual void visitSymbol(TIntermSymbol* symbol) + { + glslang::TType& symType = symbol->getWritableType(); + + if (symType == unitType) { + // each symbol node has a local copy of the unitType + // if merging involves changing properties that aren't shared objects + // they should be updated in all instances + + // e.g. the struct list is a ptr to an object, so it can be updated + // once, outside the traverser + //*symType.getWritableStruct() = *newType.getStruct(); + } + + } + + virtual bool visitBinary(TVisit, glslang::TIntermBinary* node) + { + if (node->getOp() == EOpIndexDirectStruct && node->getLeft()->getType() == unitType) { + // this is a dereference to a member of the block since the + // member list changed, need to update this to point to the + // right index + assert(node->getRight()->getAsConstantUnion()); + + glslang::TIntermConstantUnion* constNode = node->getRight()->getAsConstantUnion(); + unsigned int memberIdx = constNode->getConstArray()[0].getUConst(); + unsigned int newIdx = memberIndexUpdates.at(memberIdx); + TIntermTyped* newConstNode = unit.addConstantUnion(newIdx, node->getRight()->getLoc()); + + node->setRight(newConstNode); + delete constNode; + + return true; + } + return true; + } + } finalLinkTraverser(block->getType(), unitType, *unit, memberIndexUpdates); + + // update the tree to use the new type + unit->getTreeRoot()->traverse(&finalLinkTraverser); + + // update the member list + (*unitMemberList) = (*memberList); +} + // // Merge the linker objects from unitLinkerObjects into linkerObjects. // Duplication is expected and filtered out, but contradictions are an error. // -void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects) +void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects, EShLanguage unitStage) { // Error check and merge the linker objects (duplicates should not be created) std::size_t initialNumLinkerObjects = linkerObjects.size(); @@ -475,7 +708,7 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin // If they are both blocks in the same shader interface, // match by the block-name, not the identifier name. if (symbol->getType().getBasicType() == EbtBlock && unitSymbol->getType().getBasicType() == EbtBlock) { - if (symbol->getType().getShaderInterface() == unitSymbol->getType().getShaderInterface()) { + if (isSameInterface(symbol, getStage(), unitSymbol, unitStage)) { isSameSymbol = symbol->getType().getTypeName() == unitSymbol->getType().getTypeName(); } } @@ -495,18 +728,54 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin if (! symbol->getQualifier().hasBinding() && unitSymbol->getQualifier().hasBinding()) symbol->getQualifier().layoutBinding = unitSymbol->getQualifier().layoutBinding; + // Similarly for location + if (!symbol->getQualifier().hasLocation() && unitSymbol->getQualifier().hasLocation()) { + symbol->getQualifier().layoutLocation = unitSymbol->getQualifier().layoutLocation; + } + // Update implicit array sizes mergeImplicitArraySizes(symbol->getWritableType(), unitSymbol->getType()); // Check for consistent types/qualification/initializers etc. - mergeErrorCheck(infoSink, *symbol, *unitSymbol, false); + mergeErrorCheck(infoSink, *symbol, *unitSymbol, unitStage); } // If different symbols, verify they arn't push_constant since there can only be one per stage - else if (symbol->getQualifier().isPushConstant() && unitSymbol->getQualifier().isPushConstant()) + else if (symbol->getQualifier().isPushConstant() && unitSymbol->getQualifier().isPushConstant() && getStage() == unitStage) error(infoSink, "Only one push_constant block is allowed per stage"); } - if (merge) + if (merge) { linkerObjects.push_back(unitLinkerObjects[unitLinkObj]); + + // for anonymous blocks, check that their members don't conflict with other names + if (unitLinkerObjects[unitLinkObj]->getAsSymbolNode()->getBasicType() == EbtBlock && + IsAnonymous(unitLinkerObjects[unitLinkObj]->getAsSymbolNode()->getName())) { + for (std::size_t linkObj = 0; linkObj < initialNumLinkerObjects; ++linkObj) { + TIntermSymbol* symbol = linkerObjects[linkObj]->getAsSymbolNode(); + TIntermSymbol* unitSymbol = unitLinkerObjects[unitLinkObj]->getAsSymbolNode(); + assert(symbol && unitSymbol); + + auto checkName = [this, unitSymbol, &infoSink](const TString& name) { + for (unsigned int i = 0; i < unitSymbol->getType().getStruct()->size(); ++i) { + if (name == (*unitSymbol->getType().getStruct())[i].type->getFieldName()) { + error(infoSink, "Anonymous member name used for global variable or other anonymous member: "); + infoSink.info << (*unitSymbol->getType().getStruct())[i].type->getCompleteString() << "\n"; + } + } + }; + + if (isSameInterface(symbol, getStage(), unitSymbol, unitStage)) { + checkName(symbol->getName()); + + // check members of other anonymous blocks + if (symbol->getBasicType() == EbtBlock && IsAnonymous(symbol->getName())) { + for (unsigned int i = 0; i < symbol->getType().getStruct()->size(); ++i) { + checkName((*symbol->getType().getStruct())[i].type->getFieldName()); + } + } + } + } + } + } } } @@ -538,26 +807,74 @@ void TIntermediate::mergeImplicitArraySizes(TType& type, const TType& unitType) // // This function only does one of intra- or cross-stage matching per call. // -void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol, bool crossStage) +void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol, EShLanguage unitStage) { #if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + bool crossStage = getStage() != unitStage; bool writeTypeComparison = false; // Types have to match - if (symbol.getType() != unitSymbol.getType()) { + { // but, we make an exception if one is an implicit array and the other is sized - if (! (symbol.getType().isArray() && unitSymbol.getType().isArray() && - symbol.getType().sameElementType(unitSymbol.getType()) && - (symbol.getType().isUnsizedArray() || unitSymbol.getType().isUnsizedArray()))) { - error(infoSink, "Types must match:"); + // or if the array sizes differ because of the extra array dimension on some in/out boundaries + bool arraysMatch = false; + if (isIoResizeArray(symbol.getType(), getStage()) || isIoResizeArray(unitSymbol.getType(), unitStage)) { + // if the arrays have an extra dimension because of the stage. + // compare dimensions while ignoring the outer dimension + unsigned int firstDim = isIoResizeArray(symbol.getType(), getStage()) ? 1 : 0; + unsigned int numDim = symbol.getArraySizes() + ? symbol.getArraySizes()->getNumDims() : 0; + unsigned int unitFirstDim = isIoResizeArray(unitSymbol.getType(), unitStage) ? 1 : 0; + unsigned int unitNumDim = unitSymbol.getArraySizes() + ? unitSymbol.getArraySizes()->getNumDims() : 0; + arraysMatch = (numDim - firstDim) == (unitNumDim - unitFirstDim); + // check that array sizes match as well + for (unsigned int i = 0; i < (numDim - firstDim) && arraysMatch; i++) { + if (symbol.getArraySizes()->getDimSize(firstDim + i) != + unitSymbol.getArraySizes()->getDimSize(unitFirstDim + i)) { + arraysMatch = false; + break; + } + } + } + else { + arraysMatch = symbol.getType().sameArrayness(unitSymbol.getType()) || + (symbol.getType().isArray() && unitSymbol.getType().isArray() && + (symbol.getType().isUnsizedArray() || unitSymbol.getType().isUnsizedArray())); + } + + if (!symbol.getType().sameElementType(unitSymbol.getType()) || + !symbol.getType().sameTypeParameters(unitSymbol.getType()) || + !arraysMatch ) { writeTypeComparison = true; + error(infoSink, "Types must match:"); + } + } + + // Interface block member-wise layout qualifiers have to match + if (symbol.getType().getBasicType() == EbtBlock && unitSymbol.getType().getBasicType() == EbtBlock && + symbol.getType().getStruct() && unitSymbol.getType().getStruct() && + symbol.getType().sameStructType(unitSymbol.getType())) { + for (unsigned int i = 0; i < symbol.getType().getStruct()->size(); ++i) { + const TQualifier& qualifier = (*symbol.getType().getStruct())[i].type->getQualifier(); + const TQualifier& unitQualifier = (*unitSymbol.getType().getStruct())[i].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; + } } } // Qualifiers have to (almost) match // Storage... - if (symbol.getQualifier().storage != unitSymbol.getQualifier().storage) { + if (symbol.getQualifier().storage != unitSymbol.getQualifier().storage && + !((crossStage && symbol.getQualifier().storage == EvqVaryingIn && unitSymbol.getQualifier().storage == EvqVaryingOut) || + (crossStage && symbol.getQualifier().storage == EvqVaryingOut && unitSymbol.getQualifier().storage == EvqVaryingIn))) { error(infoSink, "Storage qualifiers must match:"); writeTypeComparison = true; } @@ -597,12 +914,16 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy } // Auxiliary and interpolation... - if (symbol.getQualifier().centroid != unitSymbol.getQualifier().centroid || + // "interpolation qualification (e.g., flat) and auxiliary qualification (e.g. centroid) may differ. + // These mismatches are allowed between any pair of stages ... + // those provided in the fragment shader supersede those provided in previous stages." + if (!crossStage && + (symbol.getQualifier().centroid != unitSymbol.getQualifier().centroid || symbol.getQualifier().smooth != unitSymbol.getQualifier().smooth || symbol.getQualifier().flat != unitSymbol.getQualifier().flat || symbol.getQualifier().isSample()!= unitSymbol.getQualifier().isSample() || symbol.getQualifier().isPatch() != unitSymbol.getQualifier().isPatch() || - symbol.getQualifier().isNonPerspective() != unitSymbol.getQualifier().isNonPerspective()) { + symbol.getQualifier().isNonPerspective() != unitSymbol.getQualifier().isNonPerspective())) { error(infoSink, "Interpolation and auxiliary storage qualifiers must match:"); writeTypeComparison = true; } @@ -1830,4 +2151,17 @@ int TIntermediate::computeBufferReferenceTypeSize(const TType& type) return size; } +#ifndef GLSLANG_WEB +bool TIntermediate::isIoResizeArray(const TType& type, EShLanguage language) { + return type.isArray() && + ((language == EShLangGeometry && type.getQualifier().storage == EvqVaryingIn) || + (language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut && + ! type.getQualifier().patch) || + (language == EShLangFragment && type.getQualifier().storage == EvqVaryingIn && + type.getQualifier().pervertexNV) || + (language == EShLangMeshNV && type.getQualifier().storage == EvqVaryingOut && + !type.getQualifier().perTaskNV)); +} +#endif // not GLSLANG_WEB + } // end namespace glslang diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index 9fe684a3..9bfa35cc 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -293,7 +293,12 @@ public: useStorageBuffer(false), nanMinMaxClamp(false), depthReplacing(false), - uniqueId(0) + uniqueId(0), + globalUniformBlockName(""), + atomicCounterBlockName(""), + globalUniformBlockSet(TQualifier::layoutSetEnd), + globalUniformBlockBinding(TQualifier::layoutBindingEnd), + atomicCounterBlockSet(TQualifier::layoutSetEnd) #ifndef GLSLANG_WEB , implicitThisName("@this"), implicitCounterName("@count"), @@ -537,6 +542,19 @@ public: void addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol&); TIntermAggregate* findLinkerObjects() const; + void setGlobalUniformBlockName(const char* name) { globalUniformBlockName = std::string(name); } + const char* getGlobalUniformBlockName() const { return globalUniformBlockName.c_str(); } + void setGlobalUniformSet(unsigned int set) { globalUniformBlockSet = set; } + unsigned int getGlobalUniformSet() const { return globalUniformBlockSet; } + void setGlobalUniformBinding(unsigned int binding) { globalUniformBlockBinding = binding; } + unsigned int getGlobalUniformBinding() const { return globalUniformBlockBinding; } + + void setAtomicCounterBlockName(const char* name) { atomicCounterBlockName = std::string(name); } + const char* getAtomicCounterBlockName() const { return atomicCounterBlockName.c_str(); } + void setAtomicCounterBlockSet(unsigned int set) { atomicCounterBlockSet = set; } + unsigned int getAtomicCounterBlockSet() const { return atomicCounterBlockSet; } + + void setUseStorageBuffer() { useStorageBuffer = true; } bool usingStorageBuffer() const { return useStorageBuffer; } void setDepthReplacing() { depthReplacing = true; } @@ -848,6 +866,20 @@ public: bool getBinaryDoubleOutput() { return binaryDoubleOutput; } #endif // GLSLANG_WEB + void addBlockStorageOverride(const char* nameStr, TBlockStorageClass backing) + { + std::string name(nameStr); + blockBackingOverrides[name] = backing; + } + TBlockStorageClass getBlockStorageOverride(const char* nameStr) const + { + std::string name = nameStr; + auto pos = blockBackingOverrides.find(name); + if (pos == blockBackingOverrides.end()) + return EbsNone; + else + return pos->second; + } #ifdef ENABLE_HLSL void setHlslFunctionality1() { hlslFunctionality1 = true; } bool getHlslFunctionality1() const { return hlslFunctionality1; } @@ -883,6 +915,10 @@ public: void merge(TInfoSink&, TIntermediate&); void finalCheck(TInfoSink&, bool keepUncalled); + void mergeGlobalUniformBlocks(TInfoSink& infoSink, TIntermediate& unit); + void mergeUniformObjects(TInfoSink& infoSink, TIntermediate& unit); + void checkStageIO(TInfoSink&, TIntermediate&); + bool buildConvertOp(TBasicType dst, TBasicType src, TOperator& convertOp) const; TIntermTyped* createConversion(TBasicType convertTo, TIntermTyped* node) const; @@ -906,6 +942,8 @@ public: static int getOffset(const TType& type, int index); static int getBlockSize(const TType& blockType); static int computeBufferReferenceTypeSize(const TType&); + static bool isIoResizeArray(const TType& type, EShLanguage language); + bool promote(TIntermOperator*); void setNanMinMaxClamp(bool setting) { nanMinMaxClamp = setting; } bool getNanMinMaxClamp() const { return nanMinMaxClamp; } @@ -963,9 +1001,10 @@ protected: void seedIdMap(TIdMaps& idMaps, long long& IdShift); void remapIds(const TIdMaps& idMaps, long long idShift, TIntermediate&); void mergeBodies(TInfoSink&, TIntermSequence& globals, const TIntermSequence& unitGlobals); - void mergeLinkerObjects(TInfoSink&, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects); + void mergeLinkerObjects(TInfoSink&, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects, EShLanguage); + void mergeBlockDefinitions(TInfoSink&, TIntermSymbol* block, TIntermSymbol* unitBlock, TIntermediate* unitRoot); void mergeImplicitArraySizes(TType&, const TType&); - void mergeErrorCheck(TInfoSink&, const TIntermSymbol&, const TIntermSymbol&, bool crossStage); + void mergeErrorCheck(TInfoSink&, const TIntermSymbol&, const TIntermSymbol&, EShLanguage); void checkCallGraphCycles(TInfoSink&); void checkCallGraphBodies(TInfoSink&, bool keepUncalled); void inOutLocationCheck(TInfoSink&); @@ -1015,6 +1054,13 @@ protected: bool localSizeNotDefault[3]; int localSizeSpecId[3]; unsigned long long uniqueId; + + std::string globalUniformBlockName; + std::string atomicCounterBlockName; + unsigned int globalUniformBlockSet; + unsigned int globalUniformBlockBinding; + unsigned int atomicCounterBlockSet; + #ifndef GLSLANG_WEB public: const char* const implicitThisName; @@ -1075,6 +1121,7 @@ protected: int uniformLocationBase; TNumericFeatures numericFeatures; #endif + std::unordered_map blockBackingOverrides; std::unordered_set usedConstantId; // specialization constant ids used std::vector usedAtomics; // sets of bindings used by atomic counters diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h index e147b0dc..74b9f3ee 100644 --- a/glslang/Public/ShaderLang.h +++ b/glslang/Public/ShaderLang.h @@ -187,6 +187,7 @@ struct TInputLanguage { EShLanguage stage; // redundant information with other input, this one overrides when not EShSourceNone EShClient dialect; int dialectVersion; // version of client's language definition, not the client (when not EShClientNone) + bool VulkanRulesRelaxed = false; }; struct TClient { @@ -427,6 +428,14 @@ enum TResourceType { EResCount }; +enum TBlockStorageClass +{ + EbsUniform = 0, + EbsStorageBuffer, + EbsPushConstant, + EbsNone, // not a uniform or buffer variable + EbsCount, +}; // Make one TShader per shader that you will link into a program. Then // - provide the shader through setStrings() or setStringsWithLengths() @@ -483,6 +492,14 @@ public: GLSLANG_EXPORT void setNoStorageFormat(bool useUnknownFormat); GLSLANG_EXPORT void setNanMinMaxClamp(bool nanMinMaxClamp); GLSLANG_EXPORT void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode); + GLSLANG_EXPORT void addBlockStorageOverride(const char* nameStr, glslang::TBlockStorageClass backing); + + GLSLANG_EXPORT void setGlobalUniformBlockName(const char* name); + GLSLANG_EXPORT void setAtomicCounterBlockName(const char* name); + GLSLANG_EXPORT void setGlobalUniformSet(unsigned int set); + GLSLANG_EXPORT void setGlobalUniformBinding(unsigned int binding); + GLSLANG_EXPORT void setAtomicCounterBlockSet(unsigned int set); + GLSLANG_EXPORT void setAtomicCounterBlockBinding(unsigned int binding); // For setting up the environment (cleared to nothingness in the constructor). // These must be called so that parsing is done for the right source language and @@ -539,6 +556,9 @@ public: bool getEnvTargetHlslFunctionality1() const { return false; } #endif + void setEnvInputVulkanRulesRelaxed() { environment.input.VulkanRulesRelaxed = true; } + bool getEnvInputVulkanRulesRelaxed() const { return environment.input.VulkanRulesRelaxed; } + // Interface to #include handlers. // // To support #include, a client of Glslang does the following: @@ -806,7 +826,7 @@ public: // Called by TSlotCollector to resolve resource locations or bindings virtual void reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) = 0; // Called by mapIO.addStage to set shader stage mask to mark a stage be added to this pipeline - virtual void addStage(EShLanguage stage) = 0; + virtual void addStage(EShLanguage stage, TIntermediate& stageIntermediate) = 0; }; #endif // !GLSLANG_WEB && !GLSLANG_ANGLE @@ -928,6 +948,7 @@ public: protected: GLSLANG_EXPORT bool linkStage(EShLanguage, EShMessages); + GLSLANG_EXPORT bool crossStageCheck(EShMessages); TPoolAllocator* pool; std::list stages[EShLangCount]; diff --git a/gtests/CMakeLists.txt b/gtests/CMakeLists.txt index 0617ff85..74c9809a 100644 --- a/gtests/CMakeLists.txt +++ b/gtests/CMakeLists.txt @@ -53,7 +53,9 @@ if(BUILD_TESTING) ${CMAKE_CURRENT_SOURCE_DIR}/Link.FromFile.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Link.FromFile.Vk.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Pp.FromFile.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Spv.FromFile.cpp) + ${CMAKE_CURRENT_SOURCE_DIR}/Spv.FromFile.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/VkRelaxed.FromFile.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/GlslMapIO.FromFile.cpp) if(ENABLE_SPVREMAPPER) set(TEST_SOURCES ${TEST_SOURCES} diff --git a/gtests/GlslMapIO.FromFile.cpp b/gtests/GlslMapIO.FromFile.cpp new file mode 100644 index 00000000..574e905f --- /dev/null +++ b/gtests/GlslMapIO.FromFile.cpp @@ -0,0 +1,306 @@ +// +// Copyright (C) 2016-2017 Google, Inc. +// Copyright (C) 2020 The Khronos Group Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +#include + +#include + +#include "TestFixture.h" + +#include "glslang/MachineIndependent/iomapper.h" +#include "glslang/MachineIndependent/reflection.h" + +#ifndef GLSLANG_WEB +namespace glslangtest { +namespace { + +struct IoMapData { + std::vector fileNames; + Semantics semantics; +}; + +using GlslMapIOTest = GlslangTest <::testing::TestWithParam>; + +template +std::string interfaceName(T symbol) { + return symbol.getType()->getBasicType() == glslang::EbtBlock ? std::string(symbol.getType()->getTypeName().c_str()) : symbol.name; +} + +bool verifyIOMapping(std::string& linkingError, glslang::TProgram& program) { + bool success = true; + + // Verify IO Mapping by generating reflection for each stage individually + // and comparing layout qualifiers on the results + + + int reflectionOptions = EShReflectionDefault; + //reflectionOptions |= EShReflectionStrictArraySuffix; + //reflectionOptions |= EShReflectionBasicArraySuffix; + reflectionOptions |= EShReflectionIntermediateIO; + reflectionOptions |= EShReflectionSeparateBuffers; + reflectionOptions |= EShReflectionAllBlockVariables; + //reflectionOptions |= EShReflectionUnwrapIOBlocks; + + success &= program.buildReflection(reflectionOptions); + + // check that the reflection output from the individual stages all makes sense.. + std::vector stageReflections; + for (int s = 0; s < EShLangCount; ++s) { + if (program.getIntermediate((EShLanguage)s)) { + stageReflections.emplace_back((EShReflectionOptions)reflectionOptions, (EShLanguage)s, (EShLanguage)s); + success &= stageReflections.back().addStage((EShLanguage)s, *program.getIntermediate((EShLanguage)s)); + } + } + + // check that input/output locations match between stages + auto it = stageReflections.begin(); + auto nextIt = it + 1; + for (; nextIt != stageReflections.end(); it++, nextIt++) { + int numOut = it->getNumPipeOutputs(); + std::map pipeOut; + + for (int i = 0; i < numOut; i++) { + const glslang::TObjectReflection& out = it->getPipeOutput(i); + std::string name = interfaceName(out); + pipeOut[name] = &out; + } + + int numIn = nextIt->getNumPipeInputs(); + for (int i = 0; i < numIn; i++) { + auto in = nextIt->getPipeInput(i); + std::string name = interfaceName(in); + auto out = pipeOut.find(name); + + if (out != pipeOut.end()) { + auto inQualifier = in.getType()->getQualifier(); + auto outQualifier = out->second->getType()->getQualifier(); + success &= outQualifier.layoutLocation == inQualifier.layoutLocation; + } + else { + success &= false; + } + } + } + + // compare uniforms in each stage to the program + { + int totalUniforms = program.getNumUniformVariables(); + std::map programUniforms; + for (int i = 0; i < totalUniforms; i++) { + const glslang::TObjectReflection& uniform = program.getUniform(i); + std::string name = interfaceName(uniform); + programUniforms[name] = &uniform; + } + it = stageReflections.begin(); + for (; it != stageReflections.end(); it++) { + int numUniform = it->getNumUniforms(); + std::map uniforms; + + for (int i = 0; i < numUniform; i++) { + glslang::TObjectReflection uniform = it->getUniform(i); + std::string name = interfaceName(uniform); + auto programUniform = programUniforms.find(name); + + if (programUniform != programUniforms.end()) { + auto stageQualifier = uniform.getType()->getQualifier(); + auto programQualifier = programUniform->second->getType()->getQualifier(); + + success &= stageQualifier.layoutLocation == programQualifier.layoutLocation; + success &= stageQualifier.layoutBinding == programQualifier.layoutBinding; + success &= stageQualifier.layoutSet == programQualifier.layoutSet; + } + else { + success &= false; + } + } + } + } + + // compare uniform blocks in each stage to the program table + { + int totalUniforms = program.getNumUniformBlocks(); + std::map programUniforms; + for (int i = 0; i < totalUniforms; i++) { + const glslang::TObjectReflection& uniform = program.getUniformBlock(i); + std::string name = interfaceName(uniform); + programUniforms[name] = &uniform; + } + it = stageReflections.begin(); + for (; it != stageReflections.end(); it++) { + int numUniform = it->getNumUniformBlocks(); + std::map uniforms; + + for (int i = 0; i < numUniform; i++) { + glslang::TObjectReflection uniform = it->getUniformBlock(i); + std::string name = interfaceName(uniform); + auto programUniform = programUniforms.find(name); + + if (programUniform != programUniforms.end()) { + auto stageQualifier = uniform.getType()->getQualifier(); + auto programQualifier = programUniform->second->getType()->getQualifier(); + + success &= stageQualifier.layoutLocation == programQualifier.layoutLocation; + success &= stageQualifier.layoutBinding == programQualifier.layoutBinding; + success &= stageQualifier.layoutSet == programQualifier.layoutSet; + } + else { + success &= false; + } + } + } + } + + if (!success) { + linkingError += "Mismatched cross-stage IO\n"; + } + + return success; +} + +TEST_P(GlslMapIOTest, FromFile) +{ + const auto& fileNames = GetParam().fileNames; + Semantics semantics = GetParam().semantics; + const size_t fileCount = fileNames.size(); + const EShMessages controls = DeriveOptions(Source::GLSL, semantics, Target::BothASTAndSpv); + GlslangResult result; + + // Compile each input shader file. + bool success = true; + std::vector> shaders; + for (size_t i = 0; i < fileCount; ++i) { + std::string contents; + tryLoadFile(GlobalTestSettings.testRoot + "/" + fileNames[i], + "input", &contents); + shaders.emplace_back( + new glslang::TShader(GetShaderStage(GetSuffix(fileNames[i])))); + auto* shader = shaders.back().get(); + + shader->setAutoMapLocations(true); + shader->setAutoMapBindings(true); + + if (controls & EShMsgSpvRules) { + if (controls & EShMsgVulkanRules) { + shader->setEnvInput((controls & EShMsgReadHlsl) ? glslang::EShSourceHlsl + : glslang::EShSourceGlsl, + shader->getStage(), glslang::EShClientVulkan, 100); + shader->setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_1); + shader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_0); + } else { + shader->setEnvInput((controls & EShMsgReadHlsl) ? glslang::EShSourceHlsl + : glslang::EShSourceGlsl, + shader->getStage(), glslang::EShClientOpenGL, 100); + shader->setEnvClient(glslang::EShClientOpenGL, glslang::EShTargetOpenGL_450); + shader->setEnvTarget(glslang::EshTargetSpv, glslang::EShTargetSpv_1_0); + } + } + + success &= compile(shader, contents, "", controls); + + result.shaderResults.push_back( + { fileNames[i], shader->getInfoLog(), shader->getInfoDebugLog() }); + } + + // Link all of them. + glslang::TProgram program; + for (const auto& shader : shaders) program.addShader(shader.get()); + success &= program.link(controls); + result.linkingOutput = program.getInfoLog(); + result.linkingError = program.getInfoDebugLog(); + + unsigned int stage = 0; + glslang::TIntermediate* firstIntermediate = nullptr; + while (!program.getIntermediate((EShLanguage)stage) && stage < EShLangCount) { stage++; } + firstIntermediate = program.getIntermediate((EShLanguage)stage); + + glslang::TDefaultGlslIoResolver resolver(*firstIntermediate); + glslang::TGlslIoMapper ioMapper; + + if (success) { + success &= program.mapIO(&resolver, &ioMapper); + result.linkingOutput = program.getInfoLog(); + result.linkingError = program.getInfoDebugLog(); + } + + success &= verifyIOMapping(result.linkingError, program); + result.validationResult = success; + + if (success && (controls & EShMsgSpvRules)) { + for (int stage = 0; stage < EShLangCount; ++stage) { + if (program.getIntermediate((EShLanguage)stage)) { + spv::SpvBuildLogger logger; + std::vector spirv_binary; + options().disableOptimizer = false; + glslang::GlslangToSpv(*program.getIntermediate((EShLanguage)stage), + spirv_binary, &logger, &options()); + + std::ostringstream disassembly_stream; + spv::Parameterize(); + spv::Disassemble(disassembly_stream, spirv_binary); + result.spirvWarningsErrors += logger.getAllMessages(); + result.spirv += disassembly_stream.str(); + result.validationResult &= !options().validate || logger.getAllMessages().empty(); + } + } + } + + std::ostringstream stream; + outputResultToStream(&stream, result, controls); + + // Check with expected results. + const std::string expectedOutputFname = + GlobalTestSettings.testRoot + "/baseResults/" + fileNames.front() + ".out"; + std::string expectedOutput; + tryLoadFile(expectedOutputFname, "expected output", &expectedOutput); + + checkEqAndUpdateIfRequested(expectedOutput, stream.str(), expectedOutputFname, + result.spirvWarningsErrors); +} + +// clang-format off +INSTANTIATE_TEST_SUITE_P( + Glsl, GlslMapIOTest, + ::testing::ValuesIn(std::vector({ + {{"iomap.crossStage.vert", "iomap.crossStage.frag" }, Semantics::OpenGL}, + {{"iomap.crossStage.2.vert", "iomap.crossStage.2.geom", "iomap.crossStage.2.frag" }, Semantics::OpenGL}, + // vulkan semantics + {{"iomap.crossStage.vk.vert", "iomap.crossStage.vk.geom", "iomap.crossStage.vk.frag" }, Semantics::Vulkan}, + })) +); +// clang-format on + +} // anonymous namespace +} // namespace glslangtest +#endif \ No newline at end of file diff --git a/gtests/Link.FromFile.Vk.cpp b/gtests/Link.FromFile.Vk.cpp index 2909a9c1..5e005a46 100644 --- a/gtests/Link.FromFile.Vk.cpp +++ b/gtests/Link.FromFile.Vk.cpp @@ -114,12 +114,12 @@ INSTANTIATE_TEST_SUITE_P( ::testing::ValuesIn(std::vector>({ {"link1.vk.frag", "link2.vk.frag"}, {"spv.unit1.frag", "spv.unit2.frag", "spv.unit3.frag"}, - {"link.vk.matchingPC.0.0.frag", "link.vk.matchingPC.0.1.frag", - "link.vk.matchingPC.0.2.frag"}, - {"link.vk.differentPC.0.0.frag", "link.vk.differentPC.0.1.frag", - "link.vk.differentPC.0.2.frag"}, - {"link.vk.differentPC.1.0.frag", "link.vk.differentPC.1.1.frag", - "link.vk.differentPC.1.2.frag"}, + {"link.vk.matchingPC.0.0.frag", "link.vk.matchingPC.0.1.frag", + "link.vk.matchingPC.0.2.frag"}, + {"link.vk.differentPC.0.0.frag", "link.vk.differentPC.0.1.frag", + "link.vk.differentPC.0.2.frag"}, + {"link.vk.differentPC.1.0.frag", "link.vk.differentPC.1.1.frag", + "link.vk.differentPC.1.2.frag"}, {"link.vk.pcNamingValid.0.0.vert", "link.vk.pcNamingValid.0.1.vert"}, {"link.vk.pcNamingInvalid.0.0.vert", "link.vk.pcNamingInvalid.0.1.vert"}, {"link.vk.multiBlocksValid.0.0.vert", "link.vk.multiBlocksValid.0.1.vert"}, diff --git a/gtests/VkRelaxed.FromFile.cpp b/gtests/VkRelaxed.FromFile.cpp new file mode 100644 index 00000000..d791d6cc --- /dev/null +++ b/gtests/VkRelaxed.FromFile.cpp @@ -0,0 +1,296 @@ +// +// Copyright (C) 2016-2017 Google, Inc. +// Copyright (C) 2020 The Khronos Group Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +#include + +#include + +#include "TestFixture.h" + +#include "glslang/MachineIndependent/iomapper.h" +#include "glslang/MachineIndependent/reflection.h" + +#ifndef GLSLANG_WEB +namespace glslangtest { +namespace { + +struct vkRelaxedData { + std::vector fileNames; +}; + +using VulkanRelaxedTest = GlslangTest <::testing::TestWithParam>; + +template +std::string interfaceName(T symbol) { + return symbol.getType()->getBasicType() == glslang::EbtBlock ? std::string(symbol.getType()->getTypeName().c_str()) : symbol.name; +} + +bool verifyIOMapping(std::string& linkingError, glslang::TProgram& program) { + bool success = true; + + // Verify IO Mapping by generating reflection for each stage individually + // and comparing layout qualifiers on the results + + + int reflectionOptions = EShReflectionDefault; + //reflectionOptions |= EShReflectionStrictArraySuffix; + //reflectionOptions |= EShReflectionBasicArraySuffix; + reflectionOptions |= EShReflectionIntermediateIO; + reflectionOptions |= EShReflectionSeparateBuffers; + reflectionOptions |= EShReflectionAllBlockVariables; + //reflectionOptions |= EShReflectionUnwrapIOBlocks; + + success &= program.buildReflection(reflectionOptions); + + // check that the reflection output from the individual stages all makes sense.. + std::vector stageReflections; + for (int s = 0; s < EShLangCount; ++s) { + if (program.getIntermediate((EShLanguage)s)) { + stageReflections.emplace_back((EShReflectionOptions)reflectionOptions, (EShLanguage)s, (EShLanguage)s); + success &= stageReflections.back().addStage((EShLanguage)s, *program.getIntermediate((EShLanguage)s)); + } + } + + // check that input/output locations match between stages + auto it = stageReflections.begin(); + auto nextIt = it + 1; + for (; nextIt != stageReflections.end(); it++, nextIt++) { + int numOut = it->getNumPipeOutputs(); + std::map pipeOut; + + for (int i = 0; i < numOut; i++) { + const glslang::TObjectReflection& out = it->getPipeOutput(i); + std::string name = interfaceName(out); + pipeOut[name] = &out; + } + + int numIn = nextIt->getNumPipeInputs(); + for (int i = 0; i < numIn; i++) { + auto in = nextIt->getPipeInput(i); + std::string name = interfaceName(in); + auto out = pipeOut.find(name); + + if (out != pipeOut.end()) { + auto inQualifier = in.getType()->getQualifier(); + auto outQualifier = out->second->getType()->getQualifier(); + success &= outQualifier.layoutLocation == inQualifier.layoutLocation; + } + else { + success &= false; + } + } + } + + // compare uniforms in each stage to the program + { + int totalUniforms = program.getNumUniformVariables(); + std::map programUniforms; + for (int i = 0; i < totalUniforms; i++) { + const glslang::TObjectReflection& uniform = program.getUniform(i); + std::string name = interfaceName(uniform); + programUniforms[name] = &uniform; + } + it = stageReflections.begin(); + for (; it != stageReflections.end(); it++) { + int numUniform = it->getNumUniforms(); + std::map uniforms; + + for (int i = 0; i < numUniform; i++) { + glslang::TObjectReflection uniform = it->getUniform(i); + std::string name = interfaceName(uniform); + auto programUniform = programUniforms.find(name); + + if (programUniform != programUniforms.end()) { + auto stageQualifier = uniform.getType()->getQualifier(); + auto programQualifier = programUniform->second->getType()->getQualifier(); + + success &= stageQualifier.layoutLocation == programQualifier.layoutLocation; + success &= stageQualifier.layoutBinding == programQualifier.layoutBinding; + success &= stageQualifier.layoutSet == programQualifier.layoutSet; + } + else { + success &= false; + } + } + } + } + + // compare uniform blocks in each stage to the program table + { + int totalUniforms = program.getNumUniformBlocks(); + std::map programUniforms; + for (int i = 0; i < totalUniforms; i++) { + const glslang::TObjectReflection& uniform = program.getUniformBlock(i); + std::string name = interfaceName(uniform); + programUniforms[name] = &uniform; + } + it = stageReflections.begin(); + for (; it != stageReflections.end(); it++) { + int numUniform = it->getNumUniformBlocks(); + std::map uniforms; + + for (int i = 0; i < numUniform; i++) { + glslang::TObjectReflection uniform = it->getUniformBlock(i); + std::string name = interfaceName(uniform); + auto programUniform = programUniforms.find(name); + + if (programUniform != programUniforms.end()) { + auto stageQualifier = uniform.getType()->getQualifier(); + auto programQualifier = programUniform->second->getType()->getQualifier(); + + success &= stageQualifier.layoutLocation == programQualifier.layoutLocation; + success &= stageQualifier.layoutBinding == programQualifier.layoutBinding; + success &= stageQualifier.layoutSet == programQualifier.layoutSet; + } + else { + success &= false; + } + } + } + } + + if (!success) { + linkingError += "Mismatched cross-stage IO\n"; + } + + return success; +} + +TEST_P(VulkanRelaxedTest, FromFile) +{ + const auto& fileNames = GetParam().fileNames; + Semantics semantics = Semantics::Vulkan; + const size_t fileCount = fileNames.size(); + const EShMessages controls = DeriveOptions(Source::GLSL, semantics, Target::BothASTAndSpv); + GlslangResult result; + + // Compile each input shader file. + bool success = true; + std::vector> shaders; + for (size_t i = 0; i < fileCount; ++i) { + std::string contents; + tryLoadFile(GlobalTestSettings.testRoot + "/" + fileNames[i], + "input", &contents); + shaders.emplace_back( + new glslang::TShader(GetShaderStage(GetSuffix(fileNames[i])))); + auto* shader = shaders.back().get(); + + shader->setAutoMapLocations(true); + shader->setAutoMapBindings(true); + + shader->setEnvInput(glslang::EShSourceGlsl, shader->getStage(), glslang::EShClientVulkan, 100); + shader->setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_1); + shader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_0); + + // Use vulkan relaxed option + shader->setEnvInputVulkanRulesRelaxed(); + + success &= compile(shader, contents, "", controls); + + result.shaderResults.push_back( + { fileNames[i], shader->getInfoLog(), shader->getInfoDebugLog() }); + } + + // Link all of them. + glslang::TProgram program; + for (const auto& shader : shaders) program.addShader(shader.get()); + success &= program.link(controls); + result.linkingOutput = program.getInfoLog(); + result.linkingError = program.getInfoDebugLog(); + + unsigned int stage = 0; + glslang::TIntermediate* firstIntermediate = nullptr; + while (!program.getIntermediate((EShLanguage)stage) && stage < EShLangCount) { stage++; } + firstIntermediate = program.getIntermediate((EShLanguage)stage); + + glslang::TDefaultGlslIoResolver resolver(*firstIntermediate); + glslang::TGlslIoMapper ioMapper; + + if (success) { + success &= program.mapIO(&resolver, &ioMapper); + result.linkingOutput = program.getInfoLog(); + result.linkingError = program.getInfoDebugLog(); + } + + success &= verifyIOMapping(result.linkingError, program); + result.validationResult = success; + + if (success && (controls & EShMsgSpvRules)) { + for (int stage = 0; stage < EShLangCount; ++stage) { + if (program.getIntermediate((EShLanguage)stage)) { + spv::SpvBuildLogger logger; + std::vector spirv_binary; + options().disableOptimizer = false; + glslang::GlslangToSpv(*program.getIntermediate((EShLanguage)stage), + spirv_binary, &logger, &options()); + + std::ostringstream disassembly_stream; + spv::Parameterize(); + spv::Disassemble(disassembly_stream, spirv_binary); + result.spirvWarningsErrors += logger.getAllMessages(); + result.spirv += disassembly_stream.str(); + result.validationResult &= !options().validate || logger.getAllMessages().empty(); + } + } + } + + std::ostringstream stream; + outputResultToStream(&stream, result, controls); + + // Check with expected results. + const std::string expectedOutputFname = + GlobalTestSettings.testRoot + "/baseResults/" + fileNames.front() + ".out"; + std::string expectedOutput; + tryLoadFile(expectedOutputFname, "expected output", &expectedOutput); + + checkEqAndUpdateIfRequested(expectedOutput, stream.str(), expectedOutputFname, + result.spirvWarningsErrors); +} + +// clang-format off +INSTANTIATE_TEST_SUITE_P( + Glsl, VulkanRelaxedTest, + ::testing::ValuesIn(std::vector({ + {{"vk.relaxed.frag"}}, + {{"vk.relaxed.link1.frag", "vk.relaxed.link2.frag"}}, + {{"vk.relaxed.stagelink.vert", "vk.relaxed.stagelink.frag"}}, + {{"vk.relaxed.errorcheck.vert", "vk.relaxed.errorcheck.frag"}}, + })) +); +// clang-format on + +} // anonymous namespace +} // namespace glslangtest +#endif \ No newline at end of file -- cgit v1.2.3