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 ...@@ -1094,14 +1094,23 @@ SIMD::Pointer SpirvShader::WalkExplicitLayoutAccessChain(Object::ID baseId, uint
Decorations d = {}; Decorations d = {};
ApplyDecorationsForId(&d, baseObject.typeId()); ApplyDecorationsForId(&d, baseObject.typeId());
uint32_t arrayIndex = 0; Int arrayIndex = 0;
if(baseObject.kind == Object::Kind::DescriptorSet) if(baseObject.kind == Object::Kind::DescriptorSet)
{ {
auto type = getType(typeId).definition.opcode(); auto type = getType(typeId).definition.opcode();
if(type == spv::OpTypeArray || type == spv::OpTypeRuntimeArray) if(type == spv::OpTypeArray || type == spv::OpTypeRuntimeArray)
{ {
ASSERT(getObject(indexIds[0]).kind == Object::Kind::Constant); auto &obj = getObject(indexIds[0]);
arrayIndex = GetConstScalarInt(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--; numIndexes--;
indexIds++; indexIds++;
...@@ -1223,21 +1232,25 @@ SIMD::Pointer SpirvShader::WalkAccessChain(Object::ID baseId, uint32_t numIndexe ...@@ -1223,21 +1232,25 @@ SIMD::Pointer SpirvShader::WalkAccessChain(Object::ID baseId, uint32_t numIndexe
case spv::OpTypeArray: case spv::OpTypeArray:
case spv::OpTypeRuntimeArray: case spv::OpTypeRuntimeArray:
{ {
// TODO: b/127950082: Check bounds. // TODO(b/127950082): Check bounds.
if(getType(baseObject).storageClass == spv::StorageClassUniformConstant) if(getType(baseObject).storageClass == spv::StorageClassUniformConstant)
{ {
// indexing into an array of descriptors. // 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); auto d = descriptorDecorations.at(baseId);
ASSERT(d.DescriptorSet >= 0); ASSERT(d.DescriptorSet >= 0);
ASSERT(d.Binding >= 0); ASSERT(d.Binding >= 0);
uint32_t descriptorSize = routine->pipelineLayout->getDescriptorSize(d.DescriptorSet, d.Binding); 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 else
{ {
......
...@@ -1120,12 +1120,11 @@ private: ...@@ -1120,12 +1120,11 @@ private:
// Returns a SIMD::Pointer to the underlying data for the given pointer // Returns a SIMD::Pointer to the underlying data for the given pointer
// object. // object.
// Handles objects of the following kinds: // Handles objects of the following kinds:
// • DescriptorSet // - DescriptorSet
// • DivergentPointer // - Pointer
// • InterfaceVariable // - InterfaceVariable
// • NonDivergentPointer
// Calling GetPointerToData with objects of any other kind will assert. // 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 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; 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 ...@@ -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 routine = state->routine;
auto &object = getObject(id); auto &object = getObject(id);
...@@ -390,7 +390,7 @@ SIMD::Pointer SpirvShader::GetPointerToData(Object::ID id, int arrayIndex, EmitS ...@@ -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 bindingOffset = routine->pipelineLayout->getBindingOffset(d.DescriptorSet, d.Binding);
uint32_t descriptorSize = routine->pipelineLayout->getDescriptorSize(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); auto set = state->getPointer(id);
Pointer<Byte> descriptor = set.base + descriptorOffset; // BufferDescriptor* Pointer<Byte> descriptor = set.base + descriptorOffset; // BufferDescriptor*
...@@ -399,7 +399,7 @@ SIMD::Pointer SpirvShader::GetPointerToData(Object::ID id, int arrayIndex, EmitS ...@@ -399,7 +399,7 @@ SIMD::Pointer SpirvShader::GetPointerToData(Object::ID id, int arrayIndex, EmitS
if(routine->pipelineLayout->isDescriptorDynamic(d.DescriptorSet, d.Binding)) if(routine->pipelineLayout->isDescriptorDynamic(d.DescriptorSet, d.Binding))
{ {
uint32_t dynamicOffsetIndex = Int dynamicOffsetIndex =
routine->pipelineLayout->getDynamicOffsetIndex(d.DescriptorSet, d.Binding) + routine->pipelineLayout->getDynamicOffsetIndex(d.DescriptorSet, d.Binding) +
arrayIndex; arrayIndex;
Int offset = routine->descriptorDynamicOffsets[dynamicOffsetIndex]; 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