diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index c8554160..9bf950ca 100644 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -2292,7 +2292,8 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI // The result of operation is always stored, but conditionally the // consumed result. The consumed result is always an r-value. - builder.accessChainStore(result); + builder.accessChainStore(result, + TranslateNonUniformDecoration(node->getOperand()->getType().getQualifier())); builder.clearAccessChain(); if (node->getOp() == glslang::EOpPreIncrement || node->getOp() == glslang::EOpPreDecrement) @@ -2368,6 +2369,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt spv::Id invertedType = spv::NoType; // to use to override the natural type of the node std::vector complexLvalues; // for holding swizzling l-values too complex for // SPIR-V, for an out parameter + std::vector complexLValueQualifiers; std::vector temporaryLvalues; // temporaries to pass, as proxies for complexLValues auto resultType = [&invertedType, &node, this](){ return invertedType != spv::NoType ? @@ -2985,6 +2987,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt // receive the result, and must later swizzle that into the original // l-value. complexLvalues.push_back(builder.getAccessChain()); + complexLValueQualifiers.push_back(glslangOperands[arg]->getAsTyped()->getType().getQualifier()); temporaryLvalues.push_back(builder.createVariable( spv::NoPrecision, spv::StorageClassFunction, builder.accessChainGetInferredType(), "swizzleTemp")); @@ -3089,7 +3092,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt for (unsigned int i = 0; i < temporaryLvalues.size(); ++i) { builder.setAccessChain(complexLvalues[i]); - builder.accessChainStore(builder.createLoad(temporaryLvalues[i], spv::NoPrecision)); + builder.accessChainStore(builder.createLoad(temporaryLvalues[i], spv::NoPrecision), TranslateNonUniformDecoration(complexLValueQualifiers[i])); } } @@ -4154,7 +4157,7 @@ void TGlslangToSpvTraverser::accessChainStore(const glslang::TType& type, spv::I unsigned int alignment = builder.getAccessChain().alignment; alignment |= type.getBufferReferenceAlignment(); - builder.accessChainStore(rvalue, + builder.accessChainStore(rvalue, TranslateNonUniformDecoration(type.getQualifier()), spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerVisibleKHRMask), TranslateMemoryScope(coherentFlags), alignment); @@ -5239,7 +5242,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO builder.accessChainPush(builder.makeIntConstant(i), flags, 0); builder.accessChainStore(builder.createCompositeExtract(res, builder.getContainedTypeId(resType, i+1), - i+1)); + i+1), TranslateNonUniformDecoration(imageType.getQualifier())); } return builder.createCompositeExtract(res, resultType(), 0); } diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp index 582b6cb7..4142cd95 100644 --- a/SPIRV/SpvBuilder.cpp +++ b/SPIRV/SpvBuilder.cpp @@ -2666,12 +2666,14 @@ void Builder::accessChainPushSwizzle(std::vector& swizzle, Id preSwizz } // Comments in header -void Builder::accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment) +void Builder::accessChainStore(Id rvalue, Decoration nonUniform, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment) { assert(accessChain.isRValue == false); transferAccessChainSwizzle(true); Id base = collapseAccessChain(); + addDecoration(base, nonUniform); + Id source = rvalue; // dynamic component should be gone diff --git a/SPIRV/SpvBuilder.h b/SPIRV/SpvBuilder.h index 83a7116a..fee0565a 100644 --- a/SPIRV/SpvBuilder.h +++ b/SPIRV/SpvBuilder.h @@ -714,7 +714,8 @@ public: } // use accessChain and swizzle to store value - void accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, + void accessChainStore(Id rvalue, Decoration nonUniform, + spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0); // use accessChain and swizzle to load an r-value diff --git a/Test/baseResults/spv.nonuniform.frag.out b/Test/baseResults/spv.nonuniform.frag.out index 8d61619c..b06a92d1 100644 --- a/Test/baseResults/spv.nonuniform.frag.out +++ b/Test/baseResults/spv.nonuniform.frag.out @@ -64,9 +64,12 @@ spv.nonuniform.frag Decorate 17(nu_li) DecorationNonUniformEXT Decorate 17(nu_li) DecorationNonUniformEXT Decorate 19 DecorationNonUniformEXT + Decorate 18(param) DecorationNonUniformEXT + Decorate 17(nu_li) DecorationNonUniformEXT Decorate 24 DecorationNonUniformEXT Decorate 28 DecorationNonUniformEXT Decorate 29 DecorationNonUniformEXT + Decorate 17(nu_li) DecorationNonUniformEXT Decorate 35(nu_inv4) Location 0 Decorate 35(nu_inv4) DecorationNonUniformEXT Decorate 39 DecorationNonUniformEXT @@ -126,6 +129,7 @@ spv.nonuniform.frag Decorate 150 DecorationNonUniformEXT Decorate 151 DecorationNonUniformEXT Decorate 152 DecorationNonUniformEXT + Decorate 153 DecorationNonUniformEXT Decorate 160(storageTexelBuffer) DescriptorSet 0 Decorate 160(storageTexelBuffer) Binding 9 Decorate 92(nu_ii) DecorationNonUniformEXT