Commit 5e8414e4 by Nicolas Capens Committed by Nicolas Capens

Implement atomic load/store

SIMD vector load and store are already atomic on x86 and ARM, and Vulkan only supports atomic operations on "scalar 32-bit integer type". Memory order semantics are handled in a follow-up change. Bug b/127472316 Test: dEQP-VK.spirv_assembly.instruction.compute.opatomic.load Test: dEQP-VK.spirv_assembly.instruction.compute.opatomic.store Change-Id: I4481fe7b7aa792b63f516bd3cb1aab1d773bbcbd Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/27649 Presubmit-Ready: Nicolas Capens <nicolascapens@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarChris Forbes <chrisforbes@google.com>
parent 4c1b8c87
...@@ -410,6 +410,7 @@ namespace sw ...@@ -410,6 +410,7 @@ namespace sw
case spv::OpDPdxFine: case spv::OpDPdxFine:
case spv::OpDPdyFine: case spv::OpDPdyFine:
case spv::OpFwidthFine: case spv::OpFwidthFine:
case spv::OpAtomicLoad:
// Instructions that yield an intermediate value // Instructions that yield an intermediate value
{ {
Type::ID typeId = insn.word(1); Type::ID typeId = insn.word(1);
...@@ -431,6 +432,7 @@ namespace sw ...@@ -431,6 +432,7 @@ namespace sw
} }
case spv::OpStore: case spv::OpStore:
case spv::OpAtomicStore:
// Don't need to do anything during analysis pass // Don't need to do anything during analysis pass
break; break;
...@@ -1187,10 +1189,12 @@ namespace sw ...@@ -1187,10 +1189,12 @@ namespace sw
break; break;
case spv::OpLoad: case spv::OpLoad:
case spv::OpAtomicLoad:
EmitLoad(insn, routine); EmitLoad(insn, routine);
break; break;
case spv::OpStore: case spv::OpStore:
case spv::OpAtomicStore:
EmitStore(insn, routine); EmitStore(insn, routine);
break; break;
...@@ -1393,6 +1397,7 @@ namespace sw ...@@ -1393,6 +1397,7 @@ namespace sw
ASSERT(getType(pointer.type).element == object.type); ASSERT(getType(pointer.type).element == object.type);
ASSERT(Type::ID(insn.word(1)) == object.type); ASSERT(Type::ID(insn.word(1)) == object.type);
ASSERT((insn.opcode() != spv::OpAtomicLoad) || getType(getType(pointer.type).element).opcode() == spv::OpTypeInt); // Vulkan 1.1: "Atomic instructions must declare a scalar 32-bit integer type, for the value pointed to by Pointer."
if (pointerBaseTy.storageClass == spv::StorageClassImage) if (pointerBaseTy.storageClass == spv::StorageClassImage)
{ {
...@@ -1490,8 +1495,9 @@ namespace sw ...@@ -1490,8 +1495,9 @@ namespace sw
void SpirvShader::EmitStore(InsnIterator insn, SpirvRoutine *routine) const void SpirvShader::EmitStore(InsnIterator insn, SpirvRoutine *routine) const
{ {
bool atomic = (insn.opcode() == spv::OpAtomicStore);
Object::ID pointerId = insn.word(1); Object::ID pointerId = insn.word(1);
Object::ID objectId = insn.word(2); Object::ID objectId = insn.word(atomic ? 4 : 2);
auto &object = getObject(objectId); auto &object = getObject(objectId);
auto &pointer = getObject(pointerId); auto &pointer = getObject(pointerId);
auto &pointerTy = getType(pointer.type); auto &pointerTy = getType(pointer.type);
...@@ -1499,6 +1505,8 @@ namespace sw ...@@ -1499,6 +1505,8 @@ namespace sw
auto &pointerBase = getObject(pointer.pointerBase); auto &pointerBase = getObject(pointer.pointerBase);
auto &pointerBaseTy = getType(pointerBase.type); auto &pointerBaseTy = getType(pointerBase.type);
ASSERT(!atomic || elementTy.opcode() == spv::OpTypeInt); // Vulkan 1.1: "Atomic instructions must declare a scalar 32-bit integer type, for the value pointed to by Pointer."
if (pointerBaseTy.storageClass == spv::StorageClassImage) if (pointerBaseTy.storageClass == spv::StorageClassImage)
{ {
UNIMPLEMENTED("StorageClassImage store not yet implemented"); UNIMPLEMENTED("StorageClassImage store not yet implemented");
......
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