SpirvShader: Implement OpImageQuerySamples
Tests: dEQP-VK.glsl.texture_functions.query.texturesamples.*
Bug: b/129523279
Change-Id: I17008f03f5e86313249b4bcb061b8b3f16e56b19
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/31112
Presubmit-Ready: Ben Clayton <bclayton@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Tested-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp
index 30eaf96..f59ce6b 100644
--- a/src/Pipeline/SpirvShader.cpp
+++ b/src/Pipeline/SpirvShader.cpp
@@ -902,6 +902,7 @@
case spv::OpImageQuerySize:
case spv::OpImageQuerySizeLod:
case spv::OpImageQueryLevels:
+ case spv::OpImageQuerySamples:
case spv::OpImageRead:
case spv::OpImageTexelPointer:
case spv::OpGroupNonUniformElect:
@@ -2495,6 +2496,9 @@
case spv::OpImageQueryLevels:
return EmitImageQueryLevels(insn, state);
+ case spv::OpImageQuerySamples:
+ return EmitImageQuerySamples(insn, state);
+
case spv::OpImageRead:
return EmitImageRead(insn, state);
@@ -4918,10 +4922,8 @@
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
- {
mipLevels = *Pointer<Int>(descriptor + OFFSET(vk::SampledImageDescriptor, mipLevels)); // uint32_t
break;
- }
default:
UNREACHABLE("Image descriptorType: %d", int(bindingLayout.descriptorType));
}
@@ -4932,6 +4934,43 @@
return EmitResult::Continue;
}
+ SpirvShader::EmitResult SpirvShader::EmitImageQuerySamples(InsnIterator insn, EmitState *state) const
+ {
+ auto &resultTy = getType(Type::ID(insn.word(1)));
+ ASSERT(resultTy.sizeInComponents == 1);
+ auto resultId = Object::ID(insn.word(2));
+ auto imageId = Object::ID(insn.word(3));
+ auto imageTy = getType(getObject(imageId).type);
+ ASSERT(imageTy.definition.opcode() == spv::OpTypeImage);
+ ASSERT(imageTy.definition.word(3) == spv::Dim2D);
+ ASSERT(imageTy.definition.word(6 /* MS */) == 1);
+
+ const DescriptorDecorations &d = descriptorDecorations.at(imageId);
+ auto setLayout = state->routine->pipelineLayout->getDescriptorSetLayout(d.DescriptorSet);
+ auto &bindingLayout = setLayout->getBindingLayout(d.Binding);
+
+ Pointer<Byte> descriptor = state->routine->getPointer(imageId).base;
+ Int sampleCount = 0;
+ switch (bindingLayout.descriptorType)
+ {
+ case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+ sampleCount = *Pointer<Int>(descriptor + OFFSET(vk::StorageImageDescriptor, sampleCount)); // uint32_t
+ break;
+ case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+ case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
+ case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
+ sampleCount = *Pointer<Int>(descriptor + OFFSET(vk::SampledImageDescriptor, sampleCount)); // uint32_t
+ break;
+ default:
+ UNREACHABLE("Image descriptorType: %d", int(bindingLayout.descriptorType));
+ }
+
+ auto &dst = state->routine->createIntermediate(resultId, 1);
+ dst.move(0, SIMD::Int(sampleCount));
+
+ return EmitResult::Continue;
+ }
+
SIMD::Pointer SpirvShader::GetTexelAddress(SpirvRoutine const *routine, SIMD::Pointer ptr, GenericValue const & coordinate, Type const & imageType, Pointer<Byte> descriptor, int texelSize, Object::ID sampleId, bool useStencilAspect) const
{
bool isArrayed = imageType.definition.word(5) != 0;
diff --git a/src/Pipeline/SpirvShader.hpp b/src/Pipeline/SpirvShader.hpp
index 2c98e4f..58c3063 100644
--- a/src/Pipeline/SpirvShader.hpp
+++ b/src/Pipeline/SpirvShader.hpp
@@ -942,6 +942,7 @@
EmitResult EmitImageQuerySize(InsnIterator insn, EmitState *state) const;
EmitResult EmitImageQuerySizeLod(InsnIterator insn, EmitState *state) const;
EmitResult EmitImageQueryLevels(InsnIterator insn, EmitState *state) const;
+ EmitResult EmitImageQuerySamples(InsnIterator insn, EmitState *state) const;
EmitResult EmitImageRead(InsnIterator insn, EmitState *state) const;
EmitResult EmitImageWrite(InsnIterator insn, EmitState *state) const;
EmitResult EmitImageTexelPointer(InsnIterator insn, EmitState *state) const;
diff --git a/src/Vulkan/VkDescriptorSetLayout.cpp b/src/Vulkan/VkDescriptorSetLayout.cpp
index dfb8362..8ea47e6 100644
--- a/src/Vulkan/VkDescriptorSetLayout.cpp
+++ b/src/Vulkan/VkDescriptorSetLayout.cpp
@@ -315,6 +315,7 @@
imageSampler[i].extent = { numElements, 1, 1 };
imageSampler[i].arrayLayers = 1;
imageSampler[i].mipLevels = 1;
+ imageSampler[i].sampleCount = 1;
imageSampler[i].texture.widthWidthHeightHeight = sw::vector(numElements, numElements, 1, 1);
imageSampler[i].texture.width = sw::replicate(numElements);
imageSampler[i].texture.height = sw::replicate(1);
@@ -353,6 +354,7 @@
imageSampler[i].extent = imageView->getMipLevelExtent(0);
imageSampler[i].arrayLayers = imageView->getSubresourceRange().layerCount;
imageSampler[i].mipLevels = imageView->getSubresourceRange().levelCount;
+ imageSampler[i].sampleCount = imageView->getSampleCount();
imageSampler[i].type = imageView->getType();
imageSampler[i].swizzle = imageView->getComponentMapping();
imageSampler[i].format = imageView->getFormat(ImageView::SAMPLING);
@@ -531,6 +533,7 @@
: imageView->slicePitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
descriptor[i].slicePitchBytes = descriptor[i].samplePitchBytes * imageView->getSampleCount();
descriptor[i].arrayLayers = imageView->getSubresourceRange().layerCount;
+ descriptor[i].sampleCount = imageView->getSampleCount();
descriptor[i].sizeInBytes = imageView->getImageSizeInBytes();
if (imageView->getFormat().isStencil())
@@ -557,6 +560,7 @@
descriptor[i].slicePitchBytes = 0;
descriptor[i].samplePitchBytes = 0;
descriptor[i].arrayLayers = 1;
+ descriptor[i].sampleCount = 1;
descriptor[i].sizeInBytes = bufferView->getRangeInBytes();
}
}
diff --git a/src/Vulkan/VkDescriptorSetLayout.hpp b/src/Vulkan/VkDescriptorSetLayout.hpp
index c368b1d..dd14de3 100644
--- a/src/Vulkan/VkDescriptorSetLayout.hpp
+++ b/src/Vulkan/VkDescriptorSetLayout.hpp
@@ -42,6 +42,7 @@
VkExtent3D extent; // Of base mip-level.
int arrayLayers;
int mipLevels;
+ int sampleCount;
};
struct alignas(16) StorageImageDescriptor
@@ -52,6 +53,7 @@
int slicePitchBytes;
int samplePitchBytes;
int arrayLayers;
+ int sampleCount;
int sizeInBytes;
void *stencilPtr;