Implement OpImageSampleProjImplicitLod and OpImageSampleProjExplicitLod
Also add stubs for Dref variants.
Bug: b/129523279
Test: dEQP-VK.glsl.texture_functions.*
Test: dEQP-VK.spirv_assembly.instruction.graphics.image_sampler.*
Change-Id: I810c8e32758c9124f7649c62d51b34751ee9bfae
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/30193
Presubmit-Ready: Nicolas Capens <nicolascapens@google.com>
Tested-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 65a86b2..23499f9 100644
--- a/src/Pipeline/SpirvShader.cpp
+++ b/src/Pipeline/SpirvShader.cpp
@@ -842,6 +842,12 @@
case spv::OpPhi:
case spv::OpImageSampleImplicitLod:
case spv::OpImageSampleExplicitLod:
+ case spv::OpImageSampleDrefImplicitLod:
+ case spv::OpImageSampleDrefExplicitLod:
+ case spv::OpImageSampleProjImplicitLod:
+ case spv::OpImageSampleProjExplicitLod:
+ case spv::OpImageSampleProjDrefImplicitLod:
+ case spv::OpImageSampleProjDrefExplicitLod:
case spv::OpImageFetch:
case spv::OpImageQuerySize:
case spv::OpImageRead:
@@ -2386,10 +2392,28 @@
return EmitKill(insn, state);
case spv::OpImageSampleImplicitLod:
- return EmitImageSampleImplicitLod(insn, state);
+ return EmitImageSampleImplicitLod(None, insn, state);
case spv::OpImageSampleExplicitLod:
- return EmitImageSampleExplicitLod(insn, state);
+ return EmitImageSampleExplicitLod(None, insn, state);
+
+ case spv::OpImageSampleDrefImplicitLod:
+ return EmitImageSampleImplicitLod(Dref, insn, state);
+
+ case spv::OpImageSampleDrefExplicitLod:
+ return EmitImageSampleExplicitLod(Dref, insn, state);
+
+ case spv::OpImageSampleProjImplicitLod:
+ return EmitImageSampleImplicitLod(Proj, insn, state);
+
+ case spv::OpImageSampleProjExplicitLod:
+ return EmitImageSampleExplicitLod(Proj, insn, state);
+
+ case spv::OpImageSampleProjDrefImplicitLod:
+ return EmitImageSampleImplicitLod(ProjDref, insn, state);
+
+ case spv::OpImageSampleProjDrefExplicitLod:
+ return EmitImageSampleExplicitLod(ProjDref, insn, state);
case spv::OpImageFetch:
return EmitImageFetch(insn, state);
@@ -4457,22 +4481,22 @@
return EmitResult::Continue;
}
- SpirvShader::EmitResult SpirvShader::EmitImageSampleImplicitLod(InsnIterator insn, EmitState *state) const
+ SpirvShader::EmitResult SpirvShader::EmitImageSampleImplicitLod(Variant variant, InsnIterator insn, EmitState *state) const
{
- return EmitImageSample({Implicit}, insn, state);
+ return EmitImageSample({variant, Implicit}, insn, state);
}
- SpirvShader::EmitResult SpirvShader::EmitImageSampleExplicitLod(InsnIterator insn, EmitState *state) const
+ SpirvShader::EmitResult SpirvShader::EmitImageSampleExplicitLod(Variant variant, InsnIterator insn, EmitState *state) const
{
uint32_t imageOperands = static_cast<spv::ImageOperandsMask>(insn.word(5));
if((imageOperands & spv::ImageOperandsLodMask) == imageOperands)
{
- return EmitImageSample({Lod}, insn, state);
+ return EmitImageSample({variant, Lod}, insn, state);
}
else if((imageOperands & spv::ImageOperandsGradMask) == imageOperands)
{
- return EmitImageSample({Grad}, insn, state);
+ return EmitImageSample({variant, Grad}, insn, state);
}
else UNIMPLEMENTED("Image Operands %x", imageOperands);
return EmitResult::Continue;
@@ -4569,10 +4593,25 @@
Array<SIMD::Float> in(16); // Maximum 16 input parameter components.
+ uint32_t coordinates = coordinateType.sizeInComponents - instruction.isProj();
+ instruction.coordinates = coordinates;
+
uint32_t i = 0;
- for( ; i < coordinateType.sizeInComponents; i++)
+ for( ; i < coordinates; i++)
{
- in[i] = coordinate.Float(i);
+ if(instruction.isProj())
+ {
+ in[i] = coordinate.Float(i) / coordinate.Float(coordinates); // TODO(b/129523279): Optimize using reciprocal.
+ }
+ else
+ {
+ in[i] = coordinate.Float(i);
+ }
+ }
+
+ if(instruction.isDref())
+ {
+ UNIMPLEMENTED("OpImageSample*Dref*"); // TODO(b/129523279)
}
if(lod)
@@ -4615,8 +4654,6 @@
}
}
- instruction.coordinates = coordinateType.sizeInComponents;
-
auto samplerFunc = Call(getImageSampler, instruction.parameters, imageView, sampler);
Array<SIMD::Float> out(4);
diff --git a/src/Pipeline/SpirvShader.hpp b/src/Pipeline/SpirvShader.hpp
index c97d690..1d09f88 100644
--- a/src/Pipeline/SpirvShader.hpp
+++ b/src/Pipeline/SpirvShader.hpp
@@ -466,12 +466,25 @@
inline operator Object::ID() const { return Object::ID(value()); }
};
+ // OpImageSample variants
+ enum Variant
+ {
+ None,
+ Dref,
+ Proj,
+ ProjDref,
+ VARIANT_LAST = ProjDref
+ };
+
// Compact representation of image instruction parameters that is passed to the
// trampoline function for retrieving/generating the corresponding sampling routine.
struct ImageInstruction
{
- ImageInstruction(SamplerMethod samplerMethod) : samplerMethod(samplerMethod)
+ ImageInstruction(Variant variant, SamplerMethod samplerMethod)
+ : parameters(0)
{
+ this->variant = variant;
+ this->samplerMethod = samplerMethod;
}
// Unmarshal from raw 32-bit data
@@ -482,18 +495,32 @@
return { static_cast<SamplerMethod>(samplerMethod), static_cast<SamplerOption>(samplerOption) };
}
+ bool isDref() const
+ {
+ return (variant == Dref) || (variant == ProjDref);
+ }
+
+ bool isProj() const
+ {
+ return (variant == Proj) || (variant == ProjDref);
+ }
+
union
{
struct
{
+ uint32_t variant : BITS(VARIANT_LAST);
uint32_t samplerMethod : BITS(SAMPLER_METHOD_LAST);
uint32_t samplerOption : BITS(SAMPLER_OPTION_LAST);
- uint32_t coordinates : 3; // 1-4
+
+ // Parameters are passed to the sampling routine in this order:
+ uint32_t coordinates : 3; // 1-4 (does not contain projection component)
+ // uint32_t lod : 1; // Indicated by SamplerMethod::Lod
uint32_t gradComponents : 2; // 0-3 (for each of dx / dy)
uint32_t offsetComponents : 2; // 0-3
};
- uint32_t parameters = 0;
+ uint32_t parameters;
};
};
@@ -867,8 +894,8 @@
EmitResult EmitReturn(InsnIterator insn, EmitState *state) const;
EmitResult EmitKill(InsnIterator insn, EmitState *state) const;
EmitResult EmitPhi(InsnIterator insn, EmitState *state) const;
- EmitResult EmitImageSampleImplicitLod(InsnIterator insn, EmitState *state) const;
- EmitResult EmitImageSampleExplicitLod(InsnIterator insn, EmitState *state) const;
+ EmitResult EmitImageSampleImplicitLod(Variant variant, InsnIterator insn, EmitState *state) const;
+ EmitResult EmitImageSampleExplicitLod(Variant variant, InsnIterator insn, EmitState *state) const;
EmitResult EmitImageFetch(InsnIterator insn, EmitState *state) const;
EmitResult EmitImageSample(ImageInstruction instruction, InsnIterator insn, EmitState *state) const;
EmitResult EmitImageQuerySize(InsnIterator insn, EmitState *state) const;