SPV: Correct semantics of atomic-counter decrement.
The semantics differ between GLSL/HLSL and SPIR-V. Translate between these.
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user