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 ...@@ -559,14 +559,8 @@ namespace sw
case spv::StorageClassPushConstant: case spv::StorageClassPushConstant:
case spv::StorageClassPrivate: case spv::StorageClassPrivate:
case spv::StorageClassFunction: case spv::StorageClassFunction:
break; // Correctly handled.
case spv::StorageClassUniformConstant: case spv::StorageClassUniformConstant:
// This storage class is for data stored within the descriptor itself, break; // Correctly handled.
// unlike StorageClassUniform which contains handles to buffers.
// For Vulkan it corresponds with samplers, images, or combined image samplers.
object.kind = Object::Kind::SampledImage;
break;
case spv::StorageClassWorkgroup: case spv::StorageClassWorkgroup:
case spv::StorageClassCrossWorkgroup: case spv::StorageClassCrossWorkgroup:
...@@ -711,6 +705,8 @@ namespace sw ...@@ -711,6 +705,8 @@ namespace sw
case spv::OpLoad: case spv::OpLoad:
case spv::OpAccessChain: case spv::OpAccessChain:
case spv::OpInBoundsAccessChain: case spv::OpInBoundsAccessChain:
case spv::OpSampledImage:
case spv::OpImage:
{ {
// Propagate the descriptor decorations to the result. // Propagate the descriptor decorations to the result.
Object::ID resultId = insn.word(2); Object::ID resultId = insn.word(2);
...@@ -2165,6 +2161,7 @@ namespace sw ...@@ -2165,6 +2161,7 @@ namespace sw
case spv::OpTypeFunction: case spv::OpTypeFunction:
case spv::OpTypeImage: case spv::OpTypeImage:
case spv::OpTypeSampledImage: case spv::OpTypeSampledImage:
case spv::OpTypeSampler:
case spv::OpExecutionMode: case spv::OpExecutionMode:
case spv::OpMemoryModel: case spv::OpMemoryModel:
case spv::OpFunction: case spv::OpFunction:
...@@ -2405,6 +2402,10 @@ namespace sw ...@@ -2405,6 +2402,10 @@ namespace sw
case spv::OpImageTexelPointer: case spv::OpImageTexelPointer:
return EmitImageTexelPointer(insn, state); return EmitImageTexelPointer(insn, state);
case spv::OpSampledImage:
case spv::OpImage:
return EmitSampledImageCombineOrSplit(insn, state);
default: default:
UNIMPLEMENTED("%s", OpcodeName(opcode).c_str()); UNIMPLEMENTED("%s", OpcodeName(opcode).c_str());
break; break;
...@@ -2508,10 +2509,8 @@ namespace sw ...@@ -2508,10 +2509,8 @@ namespace sw
if(pointerTy.storageClass == spv::StorageClassUniformConstant) if(pointerTy.storageClass == spv::StorageClassUniformConstant)
{ {
// Just propagate the pointer. // Just propagate the pointer.
// TODO(b/129523279)
auto &ptr = routine->getPointer(pointerId); auto &ptr = routine->getPointer(pointerId);
routine->createPointer(resultId, ptr); routine->createPointer(resultId, ptr);
return EmitResult::Continue; return EmitResult::Continue;
} }
...@@ -4484,13 +4483,18 @@ namespace sw ...@@ -4484,13 +4483,18 @@ namespace sw
auto &resultType = getType(resultTypeId); auto &resultType = getType(resultTypeId);
auto &result = state->routine->createIntermediate(resultId, resultType.sizeInComponents); 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 coordinate = GenericValue(this, state->routine, coordinateId);
auto &coordinateType = getType(coordinate.type); auto &coordinateType = getType(coordinate.type);
auto descriptor = sampledImage.base; // vk::SampledImageDescriptor* auto sampler = *Pointer<Pointer<Byte>>(samplerDescriptor + OFFSET(vk::SampledImageDescriptor, sampler)); // vk::Sampler*
auto sampler = *Pointer<Pointer<Byte>>(descriptor + OFFSET(vk::SampledImageDescriptor, sampler)); // vk::Sampler* auto imageView = *Pointer<Pointer<Byte>>(imageDescriptor + OFFSET(vk::SampledImageDescriptor, imageView)); // vk::ImageView*
auto imageView = *Pointer<Pointer<Byte>>(descriptor + OFFSET(vk::SampledImageDescriptor, imageView)); // vk::ImageView*
uint32_t imageOperands = spv::ImageOperandsMaskNone; uint32_t imageOperands = spv::ImageOperandsMaskNone;
bool bias = false; bool bias = false;
...@@ -4607,7 +4611,7 @@ namespace sw ...@@ -4607,7 +4611,7 @@ namespace sw
auto samplerFunc = Call(getImageSampler, instruction.parameters, imageView, sampler); auto samplerFunc = Call(getImageSampler, instruction.parameters, imageView, sampler);
Array<SIMD::Float> out(4); 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]); } for (int i = 0; i < 4; i++) { result.move(i, out[i]); }
...@@ -5057,6 +5061,19 @@ namespace sw ...@@ -5057,6 +5061,19 @@ namespace sw
return EmitResult::Continue; 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 SpirvShader::EmitResult SpirvShader::EmitAtomicOp(InsnIterator insn, EmitState *state) const
{ {
auto &resultType = getType(Type::ID(insn.word(1))); auto &resultType = getType(Type::ID(insn.word(1)));
......
...@@ -389,10 +389,6 @@ namespace sw ...@@ -389,10 +389,6 @@ namespace sw
// A pointer to a vk::DescriptorSet*. // A pointer to a vk::DescriptorSet*.
// Pointer held by SpirvRoutine::pointers. // Pointer held by SpirvRoutine::pointers.
DescriptorSet, DescriptorSet,
// Pointer to an image/sampler descriptor.
// Pointer held by SpirvRoutine::pointers.
SampledImage,
}; };
Kind kind = Kind::Unknown; Kind kind = Kind::Unknown;
...@@ -880,6 +876,7 @@ namespace sw ...@@ -880,6 +876,7 @@ namespace sw
EmitResult EmitImageTexelPointer(InsnIterator insn, EmitState *state) const; EmitResult EmitImageTexelPointer(InsnIterator insn, EmitState *state) const;
EmitResult EmitAtomicOp(InsnIterator insn, EmitState *state) const; EmitResult EmitAtomicOp(InsnIterator insn, EmitState *state) const;
EmitResult EmitAtomicCompareExchange(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; 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