diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index e08bff65..c7febc4a 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -227,13 +227,15 @@ spv::StorageClass TranslateStorageClass(const glslang::TType& type) return spv::StorageClassInput; else if (type.getQualifier().isPipeOutput()) return spv::StorageClassOutput; + else if (type.getBasicType() == glslang::EbtSampler) + return spv::StorageClassUniformConstant; + else if (type.getBasicType() == glslang::EbtAtomicUint) + return spv::StorageClassAtomicCounter; else if (type.getQualifier().isUniformOrBuffer()) { if (type.getQualifier().layoutPushConstant) return spv::StorageClassPushConstant; if (type.getBasicType() == glslang::EbtBlock) return spv::StorageClassUniform; - else if (type.getBasicType() == glslang::EbtAtomicUint) - return spv::StorageClassAtomicCounter; else return spv::StorageClassUniformConstant; // TODO: how are we distuingishing between default and non-default non-writable uniforms? Do default uniforms even exist? @@ -2270,7 +2272,9 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF for (int p = 0; p < (int)parameters.size(); ++p) { const glslang::TType& paramType = parameters[p]->getAsTyped()->getType(); spv::Id typeId = convertGlslangToSpvType(paramType); - if (paramType.getQualifier().storage != glslang::EvqConstReadOnly) + if (paramType.isOpaque()) + typeId = builder.makePointer(TranslateStorageClass(paramType), typeId); + else if (paramType.getQualifier().storage != glslang::EvqConstReadOnly) typeId = builder.makePointer(spv::StorageClassFunction, typeId); else constReadOnlyParameters.insert(parameters[p]->getAsSymbolNode()->getId()); @@ -2686,8 +2690,8 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg builder.clearAccessChain(); glslangArgs[a]->traverse(this); argTypes.push_back(¶mType); - // keep outputs as and samplers l-values, evaluate input-only as r-values - if (qualifiers[a] != glslang::EvqConstReadOnly || paramType.getBasicType() == glslang::EbtSampler) { + // keep outputs as and opaque objects l-values, evaluate input-only as r-values + if (qualifiers[a] != glslang::EvqConstReadOnly || paramType.isOpaque()) { // save l-value lValues.push_back(builder.getAccessChain()); } else { @@ -2706,7 +2710,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg for (int a = 0; a < (int)glslangArgs.size(); ++a) { const glslang::TType& paramType = glslangArgs[a]->getAsTyped()->getType(); spv::Id arg; - if (paramType.getBasicType() == glslang::EbtSampler) { + if (paramType.isOpaque()) { builder.setAccessChain(lValues[lValueCount]); arg = builder.accessChainGetLValue(); ++lValueCount; diff --git a/Test/baseResults/spv.subpass.frag.out b/Test/baseResults/spv.subpass.frag.out index 4b972aca..93d680c7 100644 --- a/Test/baseResults/spv.subpass.frag.out +++ b/Test/baseResults/spv.subpass.frag.out @@ -7,13 +7,13 @@ Linked fragment stage: // Module Version 10000 // Generated by (magic number): 80001 -// Id's are bound by 68 +// Id's are bound by 67 Capability Shader Capability InputAttachment 1: ExtInstImport "GLSL.std.450" MemoryModel Logical GLSL450 - EntryPoint Fragment 4 "main" 15 27 54 + EntryPoint Fragment 4 "main" 15 27 53 ExecutionMode 4 OriginUpperLeft Source GLSL 400 Name 4 "main" @@ -24,27 +24,27 @@ Linked fragment stage: Name 30 "sub" Name 35 "subMS" Name 42 "isub" - Name 46 "isubMS" - Name 54 "ucolor" - Name 57 "usub" - Name 62 "usubMS" + Name 45 "isubMS" + Name 53 "ucolor" + Name 56 "usub" + Name 61 "usubMS" Decorate 30(sub) DescriptorSet 0 Decorate 30(sub) InputAttachmentIndex 1 Decorate 35(subMS) DescriptorSet 0 Decorate 35(subMS) InputAttachmentIndex 2 Decorate 42(isub) DescriptorSet 0 Decorate 42(isub) InputAttachmentIndex 3 - Decorate 46(isubMS) DescriptorSet 0 - Decorate 46(isubMS) InputAttachmentIndex 4 - Decorate 57(usub) DescriptorSet 0 - Decorate 57(usub) InputAttachmentIndex 5 - Decorate 62(usubMS) DescriptorSet 0 - Decorate 62(usubMS) InputAttachmentIndex 6 + Decorate 45(isubMS) DescriptorSet 0 + Decorate 45(isubMS) InputAttachmentIndex 4 + Decorate 56(usub) DescriptorSet 0 + Decorate 56(usub) InputAttachmentIndex 5 + Decorate 61(usubMS) DescriptorSet 0 + Decorate 61(usubMS) InputAttachmentIndex 6 2: TypeVoid 3: TypeFunction 2 6: TypeInt 32 1 7: TypeImage 6(int) SubpassData multi-sampled nonsampled format:Unknown - 8: TypePointer Function 7 + 8: TypePointer UniformConstant 7 9: TypeFunction 2 8(ptr) 13: TypeVector 6(int) 4 14: TypePointer Output 13(ivec4) @@ -66,18 +66,17 @@ Linked fragment stage: 40: TypeImage 6(int) SubpassData nonsampled format:Unknown 41: TypePointer UniformConstant 40 42(isub): 41(ptr) Variable UniformConstant - 45: TypePointer UniformConstant 7 - 46(isubMS): 45(ptr) Variable UniformConstant - 51: TypeInt 32 0 - 52: TypeVector 51(int) 4 - 53: TypePointer Output 52(ivec4) - 54(ucolor): 53(ptr) Variable Output - 55: TypeImage 51(int) SubpassData nonsampled format:Unknown - 56: TypePointer UniformConstant 55 - 57(usub): 56(ptr) Variable UniformConstant - 60: TypeImage 51(int) SubpassData multi-sampled nonsampled format:Unknown - 61: TypePointer UniformConstant 60 - 62(usubMS): 61(ptr) Variable UniformConstant + 45(isubMS): 8(ptr) Variable UniformConstant + 50: TypeInt 32 0 + 51: TypeVector 50(int) 4 + 52: TypePointer Output 51(ivec4) + 53(ucolor): 52(ptr) Variable Output + 54: TypeImage 50(int) SubpassData nonsampled format:Unknown + 55: TypePointer UniformConstant 54 + 56(usub): 55(ptr) Variable UniformConstant + 59: TypeImage 50(int) SubpassData multi-sampled nonsampled format:Unknown + 60: TypePointer UniformConstant 59 + 61(usubMS): 60(ptr) Variable UniformConstant 4(main): 2 Function None 3 5: Label 31: 28 Load 30(sub) @@ -91,20 +90,20 @@ Linked fragment stage: 43: 40 Load 42(isub) 44: 13(ivec4) ImageRead 43 20 Store 15(icolor) 44 - 47: 7 Load 46(isubMS) - 48: 13(ivec4) ImageRead 47 20 Sample 17 - 49: 13(ivec4) Load 15(icolor) - 50: 13(ivec4) IAdd 49 48 - Store 15(icolor) 50 - 58: 55 Load 57(usub) - 59: 52(ivec4) ImageRead 58 20 - Store 54(ucolor) 59 - 63: 60 Load 62(usubMS) - 64: 52(ivec4) ImageRead 63 20 Sample 17 - 65: 52(ivec4) Load 54(ucolor) - 66: 52(ivec4) IAdd 65 64 - Store 54(ucolor) 66 - 67: 2 FunctionCall 11(foo(iIPM1;) 46(isubMS) + 46: 7 Load 45(isubMS) + 47: 13(ivec4) ImageRead 46 20 Sample 17 + 48: 13(ivec4) Load 15(icolor) + 49: 13(ivec4) IAdd 48 47 + Store 15(icolor) 49 + 57: 54 Load 56(usub) + 58: 51(ivec4) ImageRead 57 20 + Store 53(ucolor) 58 + 62: 59 Load 61(usubMS) + 63: 51(ivec4) ImageRead 62 20 Sample 17 + 64: 51(ivec4) Load 53(ucolor) + 65: 51(ivec4) IAdd 64 63 + Store 53(ucolor) 65 + 66: 2 FunctionCall 11(foo(iIPM1;) 45(isubMS) Return FunctionEnd 11(foo(iIPM1;): 2 Function None 9 diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index c4933e07..aa368340 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -1255,6 +1255,8 @@ public: virtual bool isStruct() const { return structure != nullptr; } virtual bool isFloatingDomain() const { return basicType == EbtFloat || basicType == EbtDouble; } + virtual bool isOpaque() const { return basicType == EbtSampler || basicType == EbtAtomicUint; } + // "Image" is a superset of "Subpass" virtual bool isImage() const { return basicType == EbtSampler && getSampler().isImage(); } virtual bool isSubpass() const { return basicType == EbtSampler && getSampler().isSubpass(); } @@ -1315,7 +1317,7 @@ public: virtual bool containsOpaque() const { - if (basicType == EbtSampler || basicType == EbtAtomicUint) + if (isOpaque()) return true; if (! structure) return false;