Commit 0264d8e1 by Ben Clayton

SpirvShader: Implement OpImageQuerySizeLod

Tests: dEQP-VK.ycbcr.query.size_lod.* Tests: dEQP-VK.glsl.texture_functions.query.texturesize.* Bug: b/129523279 Change-Id: I0a0db0f462d51b6b650ce798eacc66977a3fe896 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/30853 Presubmit-Ready: Ben Clayton <bclayton@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarBen Clayton <bclayton@google.com>
parent ecd38484
...@@ -868,6 +868,7 @@ namespace sw ...@@ -868,6 +868,7 @@ namespace sw
case spv::OpImageSampleProjDrefExplicitLod: case spv::OpImageSampleProjDrefExplicitLod:
case spv::OpImageFetch: case spv::OpImageFetch:
case spv::OpImageQuerySize: case spv::OpImageQuerySize:
case spv::OpImageQuerySizeLod:
case spv::OpImageRead: case spv::OpImageRead:
case spv::OpImageTexelPointer: case spv::OpImageTexelPointer:
case spv::OpGroupNonUniformElect: case spv::OpGroupNonUniformElect:
...@@ -2441,6 +2442,9 @@ namespace sw ...@@ -2441,6 +2442,9 @@ namespace sw
case spv::OpImageQuerySize: case spv::OpImageQuerySize:
return EmitImageQuerySize(insn, state); return EmitImageQuerySize(insn, state);
case spv::OpImageQuerySizeLod:
return EmitImageQuerySizeLod(insn, state);
case spv::OpImageRead: case spv::OpImageRead:
return EmitImageRead(insn, state); return EmitImageRead(insn, state);
...@@ -4728,49 +4732,93 @@ namespace sw ...@@ -4728,49 +4732,93 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitImageQuerySize(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitImageQuerySize(InsnIterator insn, EmitState *state) const
{ {
auto &resultType = getType(Type::ID(insn.word(1))); auto &resultTy = getType(Type::ID(insn.word(1)));
auto resultId = Object::ID(insn.word(2));
auto imageId = Object::ID(insn.word(3)); auto imageId = Object::ID(insn.word(3));
auto lodId = Object::ID(0);
auto &dst = state->routine->createIntermediate(resultId, resultTy.sizeInComponents);
GetImageDimensions(state->routine, resultTy, imageId, lodId, dst);
return EmitResult::Continue;
}
SpirvShader::EmitResult SpirvShader::EmitImageQuerySizeLod(InsnIterator insn, EmitState *state) const
{
auto &resultTy = getType(Type::ID(insn.word(1)));
auto resultId = Object::ID(insn.word(2));
auto imageId = Object::ID(insn.word(3));
auto lodId = Object::ID(insn.word(4));
auto &dst = state->routine->createIntermediate(resultId, resultTy.sizeInComponents);
GetImageDimensions(state->routine, resultTy, imageId, lodId, dst);
return EmitResult::Continue;
}
void SpirvShader::GetImageDimensions(SpirvRoutine const *routine, Type const &resultTy, Object::ID imageId, Object::ID lodId, Intermediate &dst) const
{
auto &image = getObject(imageId); auto &image = getObject(imageId);
auto &imageType = getType(image.type); auto &imageType = getType(image.type);
Object::ID resultId = insn.word(2);
ASSERT(imageType.definition.opcode() == spv::OpTypeImage); ASSERT(imageType.definition.opcode() == spv::OpTypeImage);
bool isArrayed = imageType.definition.word(5) != 0; bool isArrayed = imageType.definition.word(5) != 0;
bool isCubeMap = imageType.definition.word(3) == spv::DimCube; bool isCubeMap = imageType.definition.word(3) == spv::DimCube;
const DescriptorDecorations &d = descriptorDecorations.at(imageId); const DescriptorDecorations &d = descriptorDecorations.at(imageId);
auto setLayout = state->routine->pipelineLayout->getDescriptorSetLayout(d.DescriptorSet); auto setLayout = routine->pipelineLayout->getDescriptorSetLayout(d.DescriptorSet);
auto &bindingLayout = setLayout->getBindingLayout(d.Binding); auto &bindingLayout = setLayout->getBindingLayout(d.Binding);
Pointer<Byte> binding = state->routine->getPointer(imageId).base; Pointer<Byte> descriptor = routine->getPointer(imageId).base;
auto &dst = state->routine->createIntermediate(resultId, resultType.sizeInComponents); Pointer<Int> extent;
Int arrayLayers;
switch (bindingLayout.descriptorType) switch (bindingLayout.descriptorType)
{ {
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
{ {
Pointer<Byte> desc = binding; // StorageImageDescriptor* extent = descriptor + OFFSET(vk::StorageImageDescriptor, extent); // int[3]*
Pointer<Int> extent = desc + OFFSET(vk::StorageImageDescriptor, extent); // int[3]* arrayLayers = *Pointer<Int>(descriptor + OFFSET(vk::StorageImageDescriptor, arrayLayers)); // uint32_t
auto dimensions = resultType.sizeInComponents - (isArrayed ? 1 : 0); break;
}
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
{
extent = descriptor + OFFSET(vk::SampledImageDescriptor, extent); // int[3]*
arrayLayers = *Pointer<Int>(descriptor + OFFSET(vk::SampledImageDescriptor, arrayLayers)); // uint32_t
break;
}
default:
UNREACHABLE("Image descriptorType: %d", int(bindingLayout.descriptorType));
}
auto dimensions = resultTy.sizeInComponents - (isArrayed ? 1 : 0);
std::vector<Int> out;
if (lodId != 0)
{
auto lodVal = GenericValue(this, routine, lodId);
ASSERT(getType(lodVal.type).sizeInComponents == 1);
auto lod = lodVal.Int(0);
auto one = SIMD::Int(1);
for (uint32_t i = 0; i < dimensions; i++) for (uint32_t i = 0; i < dimensions; i++)
{ {
dst.move(i, SIMD::Int(extent[i])); dst.move(i, Max(SIMD::Int(extent[i]) >> lod, one));
} }
if (isArrayed) }
else
{
for (uint32_t i = 0; i < dimensions; i++)
{ {
auto arrayLayers = *Pointer<Int>(desc + OFFSET(vk::StorageImageDescriptor, arrayLayers)); // uint32_t dst.move(i, SIMD::Int(extent[i]));
auto numElements = isCubeMap ? arrayLayers / 6 : arrayLayers;
dst.move(dimensions, SIMD::Int(numElements));
} }
break;
}
default:
UNREACHABLE("Image descriptorType: %d", int(bindingLayout.descriptorType));
} }
return EmitResult::Continue; if (isArrayed)
{
auto numElements = isCubeMap ? (arrayLayers / 6) : RValue<Int>(arrayLayers);
dst.move(dimensions, SIMD::Int(numElements));
}
} }
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 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
......
...@@ -925,6 +925,7 @@ namespace sw ...@@ -925,6 +925,7 @@ namespace sw
EmitResult EmitImageFetch(InsnIterator insn, EmitState *state) const; EmitResult EmitImageFetch(InsnIterator insn, EmitState *state) const;
EmitResult EmitImageSample(ImageInstruction instruction, InsnIterator insn, EmitState *state) const; EmitResult EmitImageSample(ImageInstruction instruction, InsnIterator insn, EmitState *state) const;
EmitResult EmitImageQuerySize(InsnIterator insn, EmitState *state) const; EmitResult EmitImageQuerySize(InsnIterator insn, EmitState *state) const;
EmitResult EmitImageQuerySizeLod(InsnIterator insn, EmitState *state) const;
EmitResult EmitImageRead(InsnIterator insn, EmitState *state) const; EmitResult EmitImageRead(InsnIterator insn, EmitState *state) const;
EmitResult EmitImageWrite(InsnIterator insn, EmitState *state) const; EmitResult EmitImageWrite(InsnIterator insn, EmitState *state) const;
EmitResult EmitImageTexelPointer(InsnIterator insn, EmitState *state) const; EmitResult EmitImageTexelPointer(InsnIterator insn, EmitState *state) const;
...@@ -934,7 +935,8 @@ namespace sw ...@@ -934,7 +935,8 @@ namespace sw
EmitResult EmitCopyMemory(InsnIterator insn, EmitState *state) const; EmitResult EmitCopyMemory(InsnIterator insn, EmitState *state) const;
EmitResult EmitGroupNonUniform(InsnIterator insn, EmitState *state) const; EmitResult EmitGroupNonUniform(InsnIterator insn, EmitState *state) const;
SIMD::Pointer GetTexelAddress(SpirvRoutine const * routine, SIMD::Pointer base, GenericValue const & coordinate, Type const & imageType, Pointer<Byte> descriptor, int texelSize, Object::ID sampleId, bool useStencilAspect) const; void GetImageDimensions(SpirvRoutine const *routine, Type const &resultTy, Object::ID imageId, Object::ID lodId, Intermediate &dst) const;
SIMD::Pointer GetTexelAddress(SpirvRoutine const *routine, SIMD::Pointer base, GenericValue const & coordinate, Type const & imageType, Pointer<Byte> descriptor, int texelSize, Object::ID sampleId, bool useStencilAspect) const;
spv::Scope GetScope(Object::ID id) const; spv::Scope GetScope(Object::ID id) const;
// OpcodeName() returns the name of the opcode op. // OpcodeName() returns the name of the opcode op.
......
...@@ -320,6 +320,8 @@ void DescriptorSetLayout::WriteDescriptorSet(DescriptorSet *dstSet, VkDescriptor ...@@ -320,6 +320,8 @@ void DescriptorSetLayout::WriteDescriptorSet(DescriptorSet *dstSet, VkDescriptor
} }
imageSampler[i].imageView = imageView; imageSampler[i].imageView = imageView;
imageSampler[i].extent = imageView->getMipLevelExtent(0);
imageSampler[i].arrayLayers = imageView->getSubresourceRange().layerCount;
auto &subresourceRange = imageView->getSubresourceRange(); auto &subresourceRange = imageView->getSubresourceRange();
int baseLevel = subresourceRange.baseMipLevel; int baseLevel = subresourceRange.baseMipLevel;
......
...@@ -36,6 +36,8 @@ struct alignas(16) SampledImageDescriptor ...@@ -36,6 +36,8 @@ struct alignas(16) SampledImageDescriptor
const vk::ImageView *imageView; const vk::ImageView *imageView;
alignas(16) sw::Texture texture; alignas(16) sw::Texture texture;
VkExtent3D extent; // Of base mip-level.
int arrayLayers;
}; };
struct alignas(16) StorageImageDescriptor struct alignas(16) StorageImageDescriptor
......
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