Skip to content

Commit

Permalink
Merge pull request KhronosGroup#2387 from BNieuwenhuizen/nonuniform
Browse files Browse the repository at this point in the history
NonUniform SPIR-V fixes.
  • Loading branch information
johnkslang authored Oct 30, 2020
2 parents 740ae9f + 8eb0bdc commit 142cb87
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 93 deletions.
37 changes: 18 additions & 19 deletions SPIRV/GlslangToSpv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2308,7 +2308,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)
Expand Down Expand Up @@ -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
std::vector<spv::Builder::AccessChain> complexLvalues; // for holding swizzling l-values too complex for
// SPIR-V, for an out parameter
std::vector<glslang::TQualifier> complexLValueQualifiers;
std::vector<spv::Id> temporaryLvalues; // temporaries to pass, as proxies for complexLValues

auto resultType = [&invertedType, &node, this](){ return invertedType != spv::NoType ?
Expand Down Expand Up @@ -2627,6 +2629,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
else
constructed = builder.createConstructor(precision, arguments, resultType());

if (node->getType().getQualifier().isNonUniform()) {
builder.addDecoration(constructed, spv::DecorationNonUniformEXT);
}

builder.clearAccessChain();
builder.setAccessChainRValue(constructed);

Expand Down Expand Up @@ -3001,6 +3007,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"));
Expand Down Expand Up @@ -3105,7 +3112,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]));
}
}

Expand Down Expand Up @@ -4170,7 +4177,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);
Expand Down Expand Up @@ -4766,12 +4773,15 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO

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
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()) {
case glslang::EOpImageQuerySize:
case glslang::EOpTextureQuerySize:
Expand Down Expand Up @@ -5025,10 +5035,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
auto opIt = arguments.begin();
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);
++opIt;

Expand Down Expand Up @@ -5089,13 +5095,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
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
if (cracked.gather) {
const auto& sourceExtensions = glslangIntermediate->getRequestedExtensions();
Expand Down Expand Up @@ -5255,7 +5254,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);
}
Expand Down
4 changes: 3 additions & 1 deletion SPIRV/SpvBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2761,12 +2761,14 @@ void Builder::accessChainPushSwizzle(std::vector<unsigned>& 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
Expand Down
3 changes: 2 additions & 1 deletion SPIRV/SpvBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,8 @@ class Builder {
}

// 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
Expand Down
Loading

0 comments on commit 142cb87

Please sign in to comment.