Commit fa82c34f by Chris Forbes

Add spirv-level support for splitting and combining sampler+image

- All of these objects are single pointers - When consuming the result of OpSampledImage, look through to find the pointer to the sampler descriptor Remove the SampledImage kind as it's no longer necessary. Test: dEQP-VK.image.* Test: dEQP-VK.pipeline.* Test: dEQP-VK.binding_model.* Change-Id: I94f4cd8a3e5175c08f263fb464e61e5ba1043833 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/29989Tested-by: 's avatarChris Forbes <chrisforbes@google.com> Presubmit-Ready: Chris Forbes <chrisforbes@google.com> Reviewed-by: 's avatarBen Clayton <bclayton@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
parent 022bd57b
......@@ -559,14 +559,8 @@ namespace sw
case spv::StorageClassPushConstant:
case spv::StorageClassPrivate:
case spv::StorageClassFunction:
break; // Correctly handled.
case spv::StorageClassUniformConstant:
// This storage class is for data stored within the descriptor itself,
// unlike StorageClassUniform which contains handles to buffers.
// For Vulkan it corresponds with samplers, images, or combined image samplers.
object.kind = Object::Kind::SampledImage;
break;
break; // Correctly handled.
case spv::StorageClassWorkgroup:
case spv::StorageClassCrossWorkgroup:
......@@ -711,6 +705,8 @@ namespace sw
case spv::OpLoad:
case spv::OpAccessChain:
case spv::OpInBoundsAccessChain:
case spv::OpSampledImage:
case spv::OpImage:
{
// Propagate the descriptor decorations to the result.
Object::ID resultId = insn.word(2);
......@@ -2165,6 +2161,7 @@ namespace sw
case spv::OpTypeFunction:
case spv::OpTypeImage:
case spv::OpTypeSampledImage:
case spv::OpTypeSampler:
case spv::OpExecutionMode:
case spv::OpMemoryModel:
case spv::OpFunction:
......@@ -2405,6 +2402,10 @@ namespace sw
case spv::OpImageTexelPointer:
return EmitImageTexelPointer(insn, state);
case spv::OpSampledImage:
case spv::OpImage:
return EmitSampledImageCombineOrSplit(insn, state);
default:
UNIMPLEMENTED("%s", OpcodeName(opcode).c_str());
break;
......@@ -2508,10 +2509,8 @@ namespace sw
if(pointerTy.storageClass == spv::StorageClassUniformConstant)
{
// Just propagate the pointer.
// TODO(b/129523279)
auto &ptr = routine->getPointer(pointerId);
routine->createPointer(resultId, ptr);
return EmitResult::Continue;
}
......@@ -4484,13 +4483,18 @@ namespace sw
auto &resultType = getType(resultTypeId);
auto &result = state->routine->createIntermediate(resultId, resultType.sizeInComponents);
auto &sampledImage = state->routine->getPointer(sampledImageId);
auto imageDescriptor = state->routine->getPointer(sampledImageId).base; // vk::SampledImageDescriptor*
// If using a separate sampler, look through the OpSampledImage instruction to find the sampler descriptor
auto &sampledImage = getObject(sampledImageId);
auto samplerDescriptor = (sampledImage.opcode() == spv::OpSampledImage) ?
state->routine->getPointer(sampledImage.definition.word(4)).base : imageDescriptor;
auto coordinate = GenericValue(this, state->routine, coordinateId);
auto &coordinateType = getType(coordinate.type);
auto descriptor = sampledImage.base; // vk::SampledImageDescriptor*
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 sampler = *Pointer<Pointer<Byte>>(samplerDescriptor + OFFSET(vk::SampledImageDescriptor, sampler)); // vk::Sampler*
auto imageView = *Pointer<Pointer<Byte>>(imageDescriptor + OFFSET(vk::SampledImageDescriptor, imageView)); // vk::ImageView*
uint32_t imageOperands = spv::ImageOperandsMaskNone;
bool bias = false;
......@@ -4607,7 +4611,7 @@ namespace sw
auto samplerFunc = Call(getImageSampler, instruction.parameters, imageView, sampler);
Array<SIMD::Float> out(4);
Call<ImageSampler>(samplerFunc, sampledImage.base, &in[0], &out[0], state->routine->constants);
Call<ImageSampler>(samplerFunc, imageDescriptor, &in[0], &out[0], state->routine->constants);
for (int i = 0; i < 4; i++) { result.move(i, out[i]); }
......@@ -5057,6 +5061,19 @@ namespace sw
return EmitResult::Continue;
}
SpirvShader::EmitResult SpirvShader::EmitSampledImageCombineOrSplit(InsnIterator insn, EmitState *state) const
{
// Propagate the image pointer in both cases.
// Consumers of OpSampledImage will look through to find the sampler pointer.
Object::ID resultId = insn.word(2);
Object::ID imageId = insn.word(3);
state->routine->createPointer(resultId, state->routine->getPointer(imageId));
return EmitResult::Continue;
}
SpirvShader::EmitResult SpirvShader::EmitAtomicOp(InsnIterator insn, EmitState *state) const
{
auto &resultType = getType(Type::ID(insn.word(1)));
......
......@@ -389,10 +389,6 @@ namespace sw
// A pointer to a vk::DescriptorSet*.
// Pointer held by SpirvRoutine::pointers.
DescriptorSet,
// Pointer to an image/sampler descriptor.
// Pointer held by SpirvRoutine::pointers.
SampledImage,
};
Kind kind = Kind::Unknown;
......@@ -880,6 +876,7 @@ namespace sw
EmitResult EmitImageTexelPointer(InsnIterator insn, EmitState *state) const;
EmitResult EmitAtomicOp(InsnIterator insn, EmitState *state) const;
EmitResult EmitAtomicCompareExchange(InsnIterator insn, EmitState *state) const;
EmitResult EmitSampledImageCombineOrSplit(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) 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