Implement ConstOffset image operand
Bug: b/129523279
Test: dEQP-VK.glsl.texture_functions.textureoffset.sampler2d_fixed_fragment
Change-Id: Ifc91f69e9eec8bde6b1e0cfaaed4d39dec672d06
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/30192
Presubmit-Ready: Nicolas Capens <nicolascapens@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
diff --git a/src/Pipeline/SamplerCore.hpp b/src/Pipeline/SamplerCore.hpp
index 030cb97..03817fe 100644
--- a/src/Pipeline/SamplerCore.hpp
+++ b/src/Pipeline/SamplerCore.hpp
@@ -41,7 +41,8 @@
enum SamplerOption
{
None,
- Offset // Offset sample location by provided integer coordinates.
+ Offset, // Offset sample location by provided integer coordinates.
+ SAMPLER_OPTION_LAST = Offset,
};
// TODO(b/129523279): Eliminate and use SpirvShader::ImageInstruction instead.
diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp
index 41d77b6..2c0a1ef 100644
--- a/src/Pipeline/SpirvShader.cpp
+++ b/src/Pipeline/SpirvShader.cpp
@@ -4500,6 +4500,7 @@
Object::ID gradDxId = 0;
Object::ID gradDyId = 0;
bool constOffset = false;
+ Object::ID offsetId = 0;
bool sample = false;
if(insn.wordCount() > 5)
@@ -4534,8 +4535,9 @@
if(imageOperands & spv::ImageOperandsConstOffsetMask)
{
- UNIMPLEMENTED("Image operand %x", spv::ImageOperandsConstOffsetMask); (void)constOffset;
constOffset = true;
+ offsetId = insn.word(operand);
+ operand++;
imageOperands &= ~spv::ImageOperandsConstOffsetMask;
}
@@ -4575,16 +4577,28 @@
instruction.gradComponents = dxyType.sizeInComponents;
- for(uint32_t j = 0; j < dxyType.sizeInComponents; j++)
+ for(uint32_t j = 0; j < dxyType.sizeInComponents; j++, i++)
{
in[i] = dxValue.Float(j);
- i++;
}
- for(uint32_t j = 0; j < dxyType.sizeInComponents; j++)
+ for(uint32_t j = 0; j < dxyType.sizeInComponents; j++, i++)
{
in[i] = dyValue.Float(j);
- i++;
+ }
+ }
+
+ if(constOffset)
+ {
+ auto offsetValue = GenericValue(this, state->routine, offsetId);
+ auto &offsetType = getType(offsetValue.type);
+
+ instruction.samplerOption = Offset;
+ instruction.offsetComponents = offsetType.sizeInComponents;
+
+ for(uint32_t j = 0; j < offsetType.sizeInComponents; j++, i++)
+ {
+ in[i] = offsetValue.Float(j); // Integer values, but transfered as float.
}
}
diff --git a/src/Pipeline/SpirvShader.hpp b/src/Pipeline/SpirvShader.hpp
index c94f61b..0cc6e91 100644
--- a/src/Pipeline/SpirvShader.hpp
+++ b/src/Pipeline/SpirvShader.hpp
@@ -481,9 +481,9 @@
// Unmarshal from raw 32-bit data
ImageInstruction(uint32_t parameters) : parameters(parameters) {}
- SamplerMethod getSamplerMethod() const
+ SamplerFunction getSamplerFunction() const
{
- return static_cast<SamplerMethod>(samplerMethod);
+ return { static_cast<SamplerMethod>(samplerMethod), static_cast<SamplerOption>(samplerOption) };
}
union
@@ -491,8 +491,10 @@
struct
{
uint32_t samplerMethod : BITS(SAMPLER_METHOD_LAST);
- uint32_t coordinates : 3; // 1-4
- uint32_t gradComponents : 2; // 0-3 (for each of dx / dy)
+ uint32_t samplerOption : BITS(SAMPLER_OPTION_LAST);
+ uint32_t coordinates : 3; // 1-4
+ uint32_t gradComponents : 2; // 0-3 (for each of dx / dy)
+ uint32_t offsetComponents : 2; // 0-3
};
uint32_t parameters = 0;
diff --git a/src/Pipeline/SpirvShaderSampling.cpp b/src/Pipeline/SpirvShaderSampling.cpp
index 3fb8575..68710d4 100644
--- a/src/Pipeline/SpirvShaderSampling.cpp
+++ b/src/Pipeline/SpirvShaderSampling.cpp
@@ -98,12 +98,13 @@
SIMD::Float uvw[3];
SIMD::Float q(0); // TODO(b/129523279)
SIMD::Float bias(0); // Bias added to the implicit level-of-detail, or explicit level-of-detail (depending on samplerMethod).
- Vector4f dsx; // TODO(b/129523279)
- Vector4f dsy; // TODO(b/129523279)
- Vector4f offset; // TODO(b/129523279)
- SamplerFunction samplerFunction = { instruction.getSamplerMethod(), None }; // TODO(b/129523279)
+ Vector4f dsx;
+ Vector4f dsy;
+ Vector4f offset;
+ SamplerFunction samplerFunction = instruction.getSamplerFunction();
- for(uint32_t i = 0; i < instruction.coordinates; i++)
+ uint32_t i = 0;
+ for( ; i < instruction.coordinates; i++)
{
uvw[i] = in[i];
}
@@ -123,14 +124,22 @@
}
else if(instruction.samplerMethod == Grad)
{
- for(uint32_t i = 0; i < instruction.gradComponents; i++)
+ for(uint32_t j = 0; j < instruction.gradComponents; j++, i++)
{
- dsx[i] = in[instruction.coordinates + i];
+ dsx[j] = in[i];
}
- for(uint32_t i = 0; i < instruction.gradComponents; i++)
+ for(uint32_t j = 0; j < instruction.gradComponents; j++, i++)
{
- dsy[i] = in[instruction.coordinates + instruction.gradComponents + i];
+ dsy[j] = in[i];
+ }
+ }
+
+ if(instruction.samplerOption == Offset)
+ {
+ for(uint32_t j = 0; j < instruction.offsetComponents; j++, i++)
+ {
+ offset[j] = in[i];
}
}