SPV: Correct semantics of atomic-counter decrement.

The semantics differ between GLSL/HLSL and SPIR-V.
Translate between these.
This commit is contained in:
John Kessenich
2017-10-06 21:21:48 -06:00
parent 592e8f0441
commit 48d6e798bc
3 changed files with 80 additions and 71 deletions

View File

@@ -4833,6 +4833,7 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
// - there are extra SPV operands with no glslang source
// - compare-exchange swaps the value and comparator
// - compare-exchange has an extra memory semantics
// - EOpAtomicCounterDecrement needs a post decrement
std::vector<spv::Id> spvAtomicOperands; // hold the spv operands
auto opIt = operands.begin(); // walk the glslang operands
spvAtomicOperands.push_back(*(opIt++));
@@ -4851,7 +4852,14 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
for (; opIt != operands.end(); ++opIt)
spvAtomicOperands.push_back(*opIt);
return builder.createOp(opCode, typeId, spvAtomicOperands);
spv::Id resultId = builder.createOp(opCode, typeId, spvAtomicOperands);
// GLSL and HLSL atomic-counter decrement return post-decrement value,
// while SPIR-V returns pre-decrement value. Translate between these semantics.
if (op == glslang::EOpAtomicCounterDecrement)
resultId = builder.createBinOp(spv::OpISub, typeId, resultId, builder.makeIntConstant(1));
return resultId;
}
// Create group invocation operations.