SpirvShader: Implement constant variable initializers.
Non-constant initializers not yet implemented.
Tests: dEQP-VK.spirv_assembly.instruction.graphics.variable_init.*
Tests: dEQP-VK.spirv_assembly.instruction.compute.variable_init.*
Tests: dEQP-VK.spirv_assembly.instruction.compute.opunreachable.*
Tests: dEQP-VK.spirv_assembly.instruction.compute.shader_default_output.int.initialized
Bug: b/131681817
Change-Id: I8b283042d3be15028c2efe10988d6847c6256811
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/30213
Reviewed-by: Chris Forbes <chrisforbes@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Presubmit-Ready: Ben Clayton <bclayton@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Tested-by: Ben Clayton <bclayton@google.com>
diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp
index c28f22e..b429df7 100644
--- a/src/Pipeline/SpirvShader.cpp
+++ b/src/Pipeline/SpirvShader.cpp
@@ -534,8 +534,6 @@
Type::ID typeId = insn.word(1);
Object::ID resultId = insn.word(2);
auto storageClass = static_cast<spv::StorageClass>(insn.word(3));
- if (insn.wordCount() > 4)
- UNIMPLEMENTED("Variable initializers not yet supported");
auto &object = defs[resultId];
object.kind = Object::Kind::Pointer;
@@ -2515,6 +2513,35 @@
break;
}
+ if (insn.wordCount() > 4)
+ {
+ Object::ID initializerId = insn.word(4);
+ if (getObject(initializerId).kind != Object::Kind::Constant)
+ {
+ UNIMPLEMENTED("Non-constant initializers not yet implemented");
+ }
+ switch (objectTy.storageClass)
+ {
+ case spv::StorageClassOutput:
+ case spv::StorageClassPrivate:
+ case spv::StorageClassFunction:
+ {
+ bool interleavedByLane = IsStorageInterleavedByLane(objectTy.storageClass);
+ auto ptr = routine->getPointer(resultId);
+ GenericValue initialValue(this, routine, initializerId);
+ VisitMemoryObject(resultId, [&](uint32_t i, uint32_t offset)
+ {
+ auto p = ptr + offset;
+ if (interleavedByLane) { p = interleaveByLane(p); }
+ SIMD::Store(p, initialValue.Float(i), state->activeLaneMask());
+ });
+ break;
+ }
+ default:
+ ASSERT_MSG(initializerId == 0, "Vulkan does not permit variables of storage class %d to have initializers", int(objectTy.storageClass));
+ }
+ }
+
return EmitResult::Continue;
}