Unverified Commit 142cb87f by John Kessenich Committed by GitHub

Merge pull request #2387 from BNieuwenhuizen/nonuniform

NonUniform SPIR-V fixes.
parents 740ae9f6 8eb0bdce
...@@ -2308,7 +2308,8 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI ...@@ -2308,7 +2308,8 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
// The result of operation is always stored, but conditionally the // The result of operation is always stored, but conditionally the
// consumed result. The consumed result is always an r-value. // consumed result. The consumed result is always an r-value.
builder.accessChainStore(result); builder.accessChainStore(result,
TranslateNonUniformDecoration(node->getOperand()->getType().getQualifier()));
builder.clearAccessChain(); builder.clearAccessChain();
if (node->getOp() == glslang::EOpPreIncrement || if (node->getOp() == glslang::EOpPreIncrement ||
node->getOp() == glslang::EOpPreDecrement) node->getOp() == glslang::EOpPreDecrement)
...@@ -2384,6 +2385,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt ...@@ -2384,6 +2385,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
spv::Id invertedType = spv::NoType; // to use to override the natural type of the node spv::Id invertedType = spv::NoType; // to use to override the natural type of the node
std::vector<spv::Builder::AccessChain> complexLvalues; // for holding swizzling l-values too complex for std::vector<spv::Builder::AccessChain> complexLvalues; // for holding swizzling l-values too complex for
// SPIR-V, for an out parameter // SPIR-V, for an out parameter
std::vector<glslang::TQualifier> complexLValueQualifiers;
std::vector<spv::Id> temporaryLvalues; // temporaries to pass, as proxies for complexLValues std::vector<spv::Id> temporaryLvalues; // temporaries to pass, as proxies for complexLValues
auto resultType = [&invertedType, &node, this](){ return invertedType != spv::NoType ? auto resultType = [&invertedType, &node, this](){ return invertedType != spv::NoType ?
...@@ -2627,6 +2629,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt ...@@ -2627,6 +2629,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
else else
constructed = builder.createConstructor(precision, arguments, resultType()); constructed = builder.createConstructor(precision, arguments, resultType());
if (node->getType().getQualifier().isNonUniform()) {
builder.addDecoration(constructed, spv::DecorationNonUniformEXT);
}
builder.clearAccessChain(); builder.clearAccessChain();
builder.setAccessChainRValue(constructed); builder.setAccessChainRValue(constructed);
...@@ -3001,6 +3007,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt ...@@ -3001,6 +3007,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
// receive the result, and must later swizzle that into the original // receive the result, and must later swizzle that into the original
// l-value. // l-value.
complexLvalues.push_back(builder.getAccessChain()); complexLvalues.push_back(builder.getAccessChain());
complexLValueQualifiers.push_back(glslangOperands[arg]->getAsTyped()->getType().getQualifier());
temporaryLvalues.push_back(builder.createVariable( temporaryLvalues.push_back(builder.createVariable(
spv::NoPrecision, spv::StorageClassFunction, spv::NoPrecision, spv::StorageClassFunction,
builder.accessChainGetInferredType(), "swizzleTemp")); builder.accessChainGetInferredType(), "swizzleTemp"));
...@@ -3105,7 +3112,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt ...@@ -3105,7 +3112,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
for (unsigned int i = 0; i < temporaryLvalues.size(); ++i) { for (unsigned int i = 0; i < temporaryLvalues.size(); ++i) {
builder.setAccessChain(complexLvalues[i]); builder.setAccessChain(complexLvalues[i]);
builder.accessChainStore(builder.createLoad(temporaryLvalues[i], spv::NoPrecision)); builder.accessChainStore(builder.createLoad(temporaryLvalues[i], spv::NoPrecision), TranslateNonUniformDecoration(complexLValueQualifiers[i]));
} }
} }
...@@ -4170,7 +4177,7 @@ void TGlslangToSpvTraverser::accessChainStore(const glslang::TType& type, spv::I ...@@ -4170,7 +4177,7 @@ void TGlslangToSpvTraverser::accessChainStore(const glslang::TType& type, spv::I
unsigned int alignment = builder.getAccessChain().alignment; unsigned int alignment = builder.getAccessChain().alignment;
alignment |= type.getBufferReferenceAlignment(); alignment |= type.getBufferReferenceAlignment();
builder.accessChainStore(rvalue, builder.accessChainStore(rvalue, TranslateNonUniformDecoration(type.getQualifier()),
spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) &
~spv::MemoryAccessMakePointerVisibleKHRMask), ~spv::MemoryAccessMakePointerVisibleKHRMask),
TranslateMemoryScope(coherentFlags), alignment); TranslateMemoryScope(coherentFlags), alignment);
...@@ -4766,12 +4773,15 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO ...@@ -4766,12 +4773,15 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
const bool isUnsignedResult = node->getType().getBasicType() == glslang::EbtUint; const bool isUnsignedResult = node->getType().getBasicType() == glslang::EbtUint;
if (builder.isSampledImage(params.sampler) &&
((cracked.query && node->getOp() != glslang::EOpTextureQueryLod) || cracked.fragMask || cracked.fetch)) {
params.sampler = builder.createUnaryOp(spv::OpImage, builder.getImageType(params.sampler), params.sampler);
if (imageType.getQualifier().isNonUniform()) {
builder.addDecoration(params.sampler, spv::DecorationNonUniformEXT);
}
}
// Check for queries // Check for queries
if (cracked.query) { if (cracked.query) {
// OpImageQueryLod works on a sampled image, for other queries the image has to be extracted first
if (node->getOp() != glslang::EOpTextureQueryLod && builder.isSampledImage(params.sampler))
params.sampler = builder.createUnaryOp(spv::OpImage, builder.getImageType(params.sampler), params.sampler);
switch (node->getOp()) { switch (node->getOp()) {
case glslang::EOpImageQuerySize: case glslang::EOpImageQuerySize:
case glslang::EOpTextureQuerySize: case glslang::EOpTextureQuerySize:
...@@ -5025,10 +5035,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO ...@@ -5025,10 +5035,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
auto opIt = arguments.begin(); auto opIt = arguments.begin();
std::vector<spv::Id> operands; std::vector<spv::Id> operands;
// Extract the image if necessary
if (builder.isSampledImage(params.sampler))
params.sampler = builder.createUnaryOp(spv::OpImage, builder.getImageType(params.sampler), params.sampler);
operands.push_back(params.sampler); operands.push_back(params.sampler);
++opIt; ++opIt;
...@@ -5089,13 +5095,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO ...@@ -5089,13 +5095,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
bias = true; bias = true;
} }
// See if the sampler param should really be just the SPV image part
if (cracked.fetch) {
// a fetch needs to have the image extracted first
if (builder.isSampledImage(params.sampler))
params.sampler = builder.createUnaryOp(spv::OpImage, builder.getImageType(params.sampler), params.sampler);
}
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
if (cracked.gather) { if (cracked.gather) {
const auto& sourceExtensions = glslangIntermediate->getRequestedExtensions(); const auto& sourceExtensions = glslangIntermediate->getRequestedExtensions();
...@@ -5255,7 +5254,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO ...@@ -5255,7 +5254,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
builder.accessChainPush(builder.makeIntConstant(i), flags, 0); builder.accessChainPush(builder.makeIntConstant(i), flags, 0);
builder.accessChainStore(builder.createCompositeExtract(res, builder.getContainedTypeId(resType, i+1), builder.accessChainStore(builder.createCompositeExtract(res, builder.getContainedTypeId(resType, i+1),
i+1)); i+1), TranslateNonUniformDecoration(imageType.getQualifier()));
} }
return builder.createCompositeExtract(res, resultType(), 0); return builder.createCompositeExtract(res, resultType(), 0);
} }
......
...@@ -2761,12 +2761,14 @@ void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizz ...@@ -2761,12 +2761,14 @@ void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizz
} }
// Comments in header // 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); assert(accessChain.isRValue == false);
transferAccessChainSwizzle(true); transferAccessChainSwizzle(true);
Id base = collapseAccessChain(); Id base = collapseAccessChain();
addDecoration(base, nonUniform);
Id source = rvalue; Id source = rvalue;
// dynamic component should be gone // dynamic component should be gone
......
...@@ -721,7 +721,8 @@ public: ...@@ -721,7 +721,8 @@ public:
} }
// use accessChain and swizzle to store value // 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); spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
// use accessChain and swizzle to load an r-value // use accessChain and swizzle to load an r-value
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
layout(location=0) nonuniformEXT in vec4 nu_inv4; layout(location=0) nonuniformEXT in vec4 nu_inv4;
nonuniformEXT float nu_gf; nonuniformEXT float nu_gf;
layout(location=1) in nonuniformEXT flat int nu_ii; layout(location=1) in nonuniformEXT flat int nu_ii;
layout(location = 2) in vec2 inTexcoord;
layout(binding=0, input_attachment_index = 0) uniform subpassInput inputAttachmentDyn[]; layout(binding=0, input_attachment_index = 0) uniform subpassInput inputAttachmentDyn[];
layout(binding=1) uniform samplerBuffer uniformTexelBufferDyn[]; layout(binding=1) uniform samplerBuffer uniformTexelBufferDyn[];
...@@ -16,6 +17,8 @@ layout(binding=6, r32f) uniform image2D storag ...@@ -16,6 +17,8 @@ layout(binding=6, r32f) uniform image2D storag
layout(binding=7, input_attachment_index = 1) uniform subpassInput inputAttachment[]; layout(binding=7, input_attachment_index = 1) uniform subpassInput inputAttachment[];
layout(binding=8) uniform samplerBuffer uniformTexelBuffer[]; layout(binding=8) uniform samplerBuffer uniformTexelBuffer[];
layout(binding=9, r32f) uniform imageBuffer storageTexelBuffer[]; layout(binding=9, r32f) uniform imageBuffer storageTexelBuffer[];
layout(binding = 10) uniform texture2D uniformTexArr[8];
layout(binding = 11) uniform sampler uniformSampler;
nonuniformEXT int foo(nonuniformEXT int nupi, nonuniformEXT out int f) nonuniformEXT int foo(nonuniformEXT int nupi, nonuniformEXT out int f)
{ {
...@@ -42,6 +45,7 @@ void main() ...@@ -42,6 +45,7 @@ void main()
b += subpassLoad(inputAttachment[nu_ii]).x; b += subpassLoad(inputAttachment[nu_ii]).x;
b += texelFetch(uniformTexelBuffer[nu_ii], 1).x; b += texelFetch(uniformTexelBuffer[nu_ii], 1).x;
b += imageLoad(storageTexelBuffer[nu_ii], 1).x; b += imageLoad(storageTexelBuffer[nu_ii], 1).x;
b += texture(sampler2D(uniformTexArr[nu_ii], uniformSampler), inTexcoord.xy).x;
nonuniformEXT ivec4 v; nonuniformEXT ivec4 v;
nonuniformEXT mat4 m; nonuniformEXT mat4 m;
...@@ -52,4 +56,6 @@ void main() ...@@ -52,4 +56,6 @@ void main()
b += uniformBuffer[uv[nu_ii]].a; b += uniformBuffer[uv[nu_ii]].a;
b += uniformBuffer[int(m[2].z)].a; b += uniformBuffer[int(m[2].z)].a;
b += uniformBuffer[s.a].a; b += uniformBuffer[s.a].a;
storageBuffer[nu_ii].b = b;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment