Commit 0b092cd9 by Chris Forbes

Add support for indexing into arrays of image descriptors

- OpLoad of pointer to descriptor is passthrough; reflect that in Kind. - Actually pass through all the descriptor types in EmitLoad - Fix Walk*AccessChain to not create useless divergence; constant offset was added in the wrong place. - Adjust WalkAccessChain to adjust pointers into descriptor arrays using the descriptor stride - Adjust storage image descriptor content to not assume layerPitch == slicePitch, since that isn't true. Bug: b/131082089 Test: dEQP-VK.binding_model.* Test: dEQP-VK.spirv_assembly.* Test: dEQP-VK.glsl.* Change-Id: I6cc4ae7b0fdeb54ede111f532c7e3fd1f108803c Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/29549Tested-by: 's avatarChris Forbes <chrisforbes@google.com> Presubmit-Ready: Chris Forbes <chrisforbes@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 621a7bd0
...@@ -1383,15 +1383,34 @@ namespace sw ...@@ -1383,15 +1383,34 @@ namespace sw
case spv::OpTypeRuntimeArray: case spv::OpTypeRuntimeArray:
{ {
// TODO: b/127950082: Check bounds. // TODO: b/127950082: Check bounds.
auto stride = getType(type.element).sizeInComponents * sizeof(float); if (getType(baseObject.type).storageClass == spv::StorageClassUniformConstant)
auto & obj = getObject(indexIds[i]);
if (obj.kind == Object::Kind::Constant)
{ {
constantOffset += stride * GetConstantInt(indexIds[i]); // indexing into an array of descriptors.
auto &obj = getObject(indexIds[i]);
if (obj.kind != Object::Kind::Constant)
{
UNIMPLEMENTED("Nonconstant indexing of descriptor arrays is not supported");
}
auto d = descriptorDecorations.at(baseId);
ASSERT(d.DescriptorSet >= 0);
ASSERT(d.Binding >= 0);
auto setLayout = routine->pipelineLayout->getDescriptorSetLayout(d.DescriptorSet);
auto stride = setLayout->getBindingStride(d.Binding);
ptr.base += stride * GetConstantInt(indexIds[i]);
} }
else else
{ {
ptr.addOffset(SIMD::Int(stride) * routine->getIntermediate(indexIds[i]).Int(0)); auto stride = getType(type.element).sizeInComponents * sizeof(float);
auto & obj = getObject(indexIds[i]);
if (obj.kind == Object::Kind::Constant)
{
constantOffset += stride * GetConstantInt(indexIds[i]);
}
else
{
ptr.addOffset(SIMD::Int(stride) * routine->getIntermediate(indexIds[i]).Int(0));
}
} }
typeId = type.element; typeId = type.element;
break; break;
...@@ -1404,7 +1423,7 @@ namespace sw ...@@ -1404,7 +1423,7 @@ namespace sw
if (constantOffset != 0) if (constantOffset != 0)
{ {
ptr.addOffset(SIMD::Int(constantOffset)); ptr.addOffset(constantOffset);
} }
return ptr; return ptr;
} }
...@@ -1598,8 +1617,20 @@ namespace sw ...@@ -1598,8 +1617,20 @@ namespace sw
Object::ID resultId = insn.word(2); Object::ID resultId = insn.word(2);
auto &object = defs[resultId]; auto &object = defs[resultId];
object.type = typeId; object.type = typeId;
object.kind = (getType(typeId).opcode() == spv::OpTypePointer)
? Object::Kind::DivergentPointer : Object::Kind::Intermediate; switch (getType(typeId).opcode())
{
case spv::OpTypePointer:
case spv::OpTypeImage:
case spv::OpTypeSampledImage:
case spv::OpTypeSampler:
object.kind = Object::Kind::DivergentPointer;
break;
default:
object.kind = Object::Kind::Intermediate;
}
object.definition = insn; object.definition = insn;
} }
...@@ -2302,7 +2333,7 @@ namespace sw ...@@ -2302,7 +2333,7 @@ namespace sw
ASSERT(Type::ID(insn.word(1)) == result.type); ASSERT(Type::ID(insn.word(1)) == result.type);
ASSERT(!atomic || 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." ASSERT(!atomic || 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(pointer.kind == Object::Kind::SampledImage) if(pointerTy.storageClass == spv::StorageClassUniformConstant)
{ {
// Just propagate the pointer. // Just propagate the pointer.
// TODO(b/129523279) // TODO(b/129523279)
...@@ -4358,12 +4389,7 @@ namespace sw ...@@ -4358,12 +4389,7 @@ namespace sw
Pointer<Byte> constants; // FIXME(b/129523279) Pointer<Byte> constants; // FIXME(b/129523279)
const DescriptorDecorations &d = descriptorDecorations.at(sampledImageId); auto descriptor = sampledImage.base; // vk::SampledImageDescriptor*
uint32_t arrayIndex = 0; // TODO(b/129523279)
auto setLayout = state->routine->pipelineLayout->getDescriptorSetLayout(d.DescriptorSet);
size_t bindingOffset = setLayout->getBindingOffset(d.Binding, arrayIndex);
auto descriptor = state->routine->descriptorSets[d.DescriptorSet] + bindingOffset; // vk::SampledImageDescriptor*
auto sampler = *Pointer<Pointer<Byte>>(descriptor + OFFSET(vk::SampledImageDescriptor, sampler)); // vk::Sampler* auto sampler = *Pointer<Pointer<Byte>>(descriptor + OFFSET(vk::SampledImageDescriptor, sampler)); // vk::Sampler*
auto imageView = *Pointer<Pointer<Byte>>(descriptor + OFFSET(vk::SampledImageDescriptor, imageView)); // vk::ImageView* auto imageView = *Pointer<Pointer<Byte>>(descriptor + OFFSET(vk::SampledImageDescriptor, imageView)); // vk::ImageView*
...@@ -4469,7 +4495,9 @@ namespace sw ...@@ -4469,7 +4495,9 @@ namespace sw
auto coordinate = GenericValue(this, state->routine, insn.word(4)); auto coordinate = GenericValue(this, state->routine, insn.word(4));
Pointer<Byte> binding = state->routine->getPointer(imageId).base; auto pointer = state->routine->getPointer(imageId);
ASSERT(pointer.uniform);
Pointer<Byte> binding = pointer.base;
Pointer<Byte> imageBase = *Pointer<Pointer<Byte>>(binding + OFFSET(vk::StorageImageDescriptor, ptr)); Pointer<Byte> imageBase = *Pointer<Pointer<Byte>>(binding + OFFSET(vk::StorageImageDescriptor, ptr));
auto &dst = state->routine->createIntermediate(resultId, resultType.sizeInComponents); auto &dst = state->routine->createIntermediate(resultId, resultType.sizeInComponents);
......
...@@ -176,6 +176,12 @@ size_t DescriptorSetLayout::getBindingCount() const ...@@ -176,6 +176,12 @@ size_t DescriptorSetLayout::getBindingCount() const
return bindingCount; return bindingCount;
} }
size_t DescriptorSetLayout::getBindingStride(uint32_t binding) const
{
uint32_t index = getBindingIndex(binding);
return GetDescriptorSize(bindings[index].descriptorType);
}
size_t DescriptorSetLayout::getBindingOffset(uint32_t binding, size_t arrayElement) const size_t DescriptorSetLayout::getBindingOffset(uint32_t binding, size_t arrayElement) const
{ {
uint32_t index = getBindingIndex(binding); uint32_t index = getBindingIndex(binding);
...@@ -442,7 +448,9 @@ void DescriptorSetLayout::WriteDescriptorSet(const VkWriteDescriptorSet& writeDe ...@@ -442,7 +448,9 @@ void DescriptorSetLayout::WriteDescriptorSet(const VkWriteDescriptorSet& writeDe
descriptor[i].ptr = imageView->getOffsetPointer({0, 0, 0}, VK_IMAGE_ASPECT_COLOR_BIT); descriptor[i].ptr = imageView->getOffsetPointer({0, 0, 0}, VK_IMAGE_ASPECT_COLOR_BIT);
descriptor[i].extent = imageView->getMipLevelExtent(0); descriptor[i].extent = imageView->getMipLevelExtent(0);
descriptor[i].rowPitchBytes = imageView->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0); descriptor[i].rowPitchBytes = imageView->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
descriptor[i].slicePitchBytes = imageView->slicePitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0); descriptor[i].slicePitchBytes = imageView->getSubresourceRange().layerCount > 1
? imageView->layerPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT)
: imageView->slicePitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
descriptor[i].arrayLayers = imageView->getSubresourceRange().layerCount; descriptor[i].arrayLayers = imageView->getSubresourceRange().layerCount;
} }
} }
......
...@@ -70,6 +70,9 @@ public: ...@@ -70,6 +70,9 @@ public:
// the given binding and array element within that binding. // the given binding and array element within that binding.
size_t getBindingOffset(uint32_t binding, size_t arrayElement) const; size_t getBindingOffset(uint32_t binding, size_t arrayElement) const;
// Returns the stride of an array of descriptors
size_t getBindingStride(uint32_t binding) const;
// Returns the number of descriptors across all bindings that are dynamic // Returns the number of descriptors across all bindings that are dynamic
// (see isBindingDynamic). // (see isBindingDynamic).
uint32_t getDynamicDescriptorCount() const; uint32_t getDynamicDescriptorCount() const;
......
...@@ -67,6 +67,7 @@ public: ...@@ -67,6 +67,7 @@ public:
void* getTexelPointer(const VkOffset3D& offset, const VkImageSubresourceLayers& subresource) const; void* getTexelPointer(const VkOffset3D& offset, const VkImageSubresourceLayers& subresource) const;
bool isCube() const; bool isCube() const;
uint8_t* end() const; uint8_t* end() const;
VkDeviceSize getLayerSize(VkImageAspectFlagBits aspect) const;
static Format GetFormat(const vk::Format& format, VkImageAspectFlagBits aspect); static Format GetFormat(const vk::Format& format, VkImageAspectFlagBits aspect);
...@@ -75,7 +76,6 @@ private: ...@@ -75,7 +76,6 @@ private:
VkDeviceSize getStorageSize(VkImageAspectFlags flags) const; VkDeviceSize getStorageSize(VkImageAspectFlags flags) const;
VkDeviceSize getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel) const; VkDeviceSize getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
VkDeviceSize getMultiSampledLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel) const; VkDeviceSize getMultiSampledLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
VkDeviceSize getLayerSize(VkImageAspectFlagBits aspect) const;
VkDeviceSize getMemoryOffset(VkImageAspectFlagBits aspect, uint32_t mipLevel) const; VkDeviceSize getMemoryOffset(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
VkDeviceSize getMemoryOffset(VkImageAspectFlagBits aspect, uint32_t mipLevel, uint32_t layer) const; VkDeviceSize getMemoryOffset(VkImageAspectFlagBits aspect, uint32_t mipLevel, uint32_t layer) const;
VkDeviceSize texelOffsetBytesInStorage(const VkOffset3D& offset, const VkImageSubresourceLayers& subresource) const; VkDeviceSize texelOffsetBytesInStorage(const VkOffset3D& offset, const VkImageSubresourceLayers& subresource) const;
......
...@@ -41,6 +41,7 @@ public: ...@@ -41,6 +41,7 @@ public:
int getSampleCount() const { return image->getSampleCountFlagBits(); } int getSampleCount() const { return image->getSampleCountFlagBits(); }
int rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel) const { return image->rowPitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel); } int rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel) const { return image->rowPitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel); }
int slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel) const { return image->slicePitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel); } int slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel) const { return image->slicePitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel); }
int layerPitchBytes(VkImageAspectFlagBits aspect) const { return static_cast<int>(image->getLayerSize(aspect)); }
VkExtent3D getMipLevelExtent(uint32_t mipLevel) const { return image->getMipLevelExtent(subresourceRange.baseMipLevel + mipLevel); } VkExtent3D getMipLevelExtent(uint32_t mipLevel) const { return image->getMipLevelExtent(subresourceRange.baseMipLevel + mipLevel); }
void *getOffsetPointer(const VkOffset3D& offset, VkImageAspectFlagBits aspect) const; void *getOffsetPointer(const VkOffset3D& offset, VkImageAspectFlagBits aspect) const;
......
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