Commit 479d1431 by Nicolas Capens Committed by Nicolas Capens

Implement dynamic descriptor array indexing

Bug: b/146166966 Bug: angleproject:4071 Tests: dEQP-VK.* Change-Id: I07008936fbb09f134283a21a6d3bba881f97fe09 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/40668Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Kokoro-Result: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com>
parent 9b83ddb1
......@@ -1094,14 +1094,23 @@ SIMD::Pointer SpirvShader::WalkExplicitLayoutAccessChain(Object::ID baseId, uint
Decorations d = {};
ApplyDecorationsForId(&d, baseObject.typeId());
uint32_t arrayIndex = 0;
Int arrayIndex = 0;
if(baseObject.kind == Object::Kind::DescriptorSet)
{
auto type = getType(typeId).definition.opcode();
if(type == spv::OpTypeArray || type == spv::OpTypeRuntimeArray)
{
ASSERT(getObject(indexIds[0]).kind == Object::Kind::Constant);
arrayIndex = GetConstScalarInt(indexIds[0]);
auto &obj = getObject(indexIds[0]);
ASSERT(obj.kind == Object::Kind::Constant || obj.kind == Object::Kind::Intermediate);
if(obj.kind == Object::Kind::Constant)
{
arrayIndex = GetConstScalarInt(indexIds[0]);
}
else
{
// Note: the value of indexIds[0] must be dynamically uniform.
arrayIndex = Extract(state->getIntermediate(indexIds[0]).Int(0), 0);
}
numIndexes--;
indexIds++;
......@@ -1223,21 +1232,25 @@ SIMD::Pointer SpirvShader::WalkAccessChain(Object::ID baseId, uint32_t numIndexe
case spv::OpTypeArray:
case spv::OpTypeRuntimeArray:
{
// TODO: b/127950082: Check bounds.
// TODO(b/127950082): Check bounds.
if(getType(baseObject).storageClass == spv::StorageClassUniformConstant)
{
// indexing into an array of descriptors.
auto &obj = getObject(indexIds[i]);
if(obj.kind != Object::Kind::Constant)
{
UNSUPPORTED("SPIR-V SampledImageArrayDynamicIndexing Capability");
}
auto d = descriptorDecorations.at(baseId);
ASSERT(d.DescriptorSet >= 0);
ASSERT(d.Binding >= 0);
uint32_t descriptorSize = routine->pipelineLayout->getDescriptorSize(d.DescriptorSet, d.Binding);
ptr.base += descriptorSize * GetConstScalarInt(indexIds[i]);
auto &obj = getObject(indexIds[i]);
if(obj.kind == Object::Kind::Constant)
{
ptr.base += descriptorSize * GetConstScalarInt(indexIds[i]);
}
else
{
// Note: the value of indexIds[i] must be dynamically uniform.
ptr.base += descriptorSize * Extract(state->getIntermediate(indexIds[i]).Int(0), 0);
}
}
else
{
......
......@@ -1120,12 +1120,11 @@ private:
// Returns a SIMD::Pointer to the underlying data for the given pointer
// object.
// Handles objects of the following kinds:
// • DescriptorSet
// • DivergentPointer
// • InterfaceVariable
// • NonDivergentPointer
// - DescriptorSet
// - Pointer
// - InterfaceVariable
// Calling GetPointerToData with objects of any other kind will assert.
SIMD::Pointer GetPointerToData(Object::ID id, int arrayIndex, EmitState const *state) const;
SIMD::Pointer GetPointerToData(Object::ID id, Int arrayIndex, EmitState const *state) const;
SIMD::Pointer WalkExplicitLayoutAccessChain(Object::ID id, uint32_t numIndexes, uint32_t const *indexIds, EmitState const *state) const;
SIMD::Pointer WalkAccessChain(Object::ID id, uint32_t numIndexes, uint32_t const *indexIds, EmitState const *state) const;
......
......@@ -372,7 +372,7 @@ void SpirvShader::VisitMemoryObject(Object::ID id, const MemoryVisitor &f) const
}
}
SIMD::Pointer SpirvShader::GetPointerToData(Object::ID id, int arrayIndex, EmitState const *state) const
SIMD::Pointer SpirvShader::GetPointerToData(Object::ID id, Int arrayIndex, EmitState const *state) const
{
auto routine = state->routine;
auto &object = getObject(id);
......@@ -390,7 +390,7 @@ SIMD::Pointer SpirvShader::GetPointerToData(Object::ID id, int arrayIndex, EmitS
uint32_t bindingOffset = routine->pipelineLayout->getBindingOffset(d.DescriptorSet, d.Binding);
uint32_t descriptorSize = routine->pipelineLayout->getDescriptorSize(d.DescriptorSet, d.Binding);
uint32_t descriptorOffset = bindingOffset + descriptorSize * arrayIndex;
Int descriptorOffset = bindingOffset + descriptorSize * arrayIndex;
auto set = state->getPointer(id);
Pointer<Byte> descriptor = set.base + descriptorOffset; // BufferDescriptor*
......@@ -399,7 +399,7 @@ SIMD::Pointer SpirvShader::GetPointerToData(Object::ID id, int arrayIndex, EmitS
if(routine->pipelineLayout->isDescriptorDynamic(d.DescriptorSet, d.Binding))
{
uint32_t dynamicOffsetIndex =
Int dynamicOffsetIndex =
routine->pipelineLayout->getDynamicOffsetIndex(d.DescriptorSet, d.Binding) +
arrayIndex;
Int offset = routine->descriptorDynamicOffsets[dynamicOffsetIndex];
......
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