Implement Bias image operand
Also fix Lod + Offset combination, and rename the parameter that holds
either lod or bias to lodOrBias.
Bug: b/129523279
Test: dEQP-VK.glsl.texture_functions.*
Change-Id: I397959421651e990d041f4297c4bcf55e1c00f03
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/30229
Reviewed-by: Chris Forbes <chrisforbes@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Pipeline/SamplerCore.cpp b/src/Pipeline/SamplerCore.cpp
index e1c6485..d60baa8 100644
--- a/src/Pipeline/SamplerCore.cpp
+++ b/src/Pipeline/SamplerCore.cpp
@@ -50,7 +50,7 @@
{
}
- Vector4f SamplerCore::sampleTexture(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function)
+ Vector4f SamplerCore::sampleTexture(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float4 &lodOrBias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function)
{
Vector4f c;
@@ -78,18 +78,18 @@
{
if(state.textureType != TEXTURE_CUBE)
{
- computeLod(texture, lod, anisotropy, uDelta, vDelta, uuuu, vvvv, bias.x, dsx, dsy, function);
+ computeLod(texture, lod, anisotropy, uDelta, vDelta, uuuu, vvvv, lodOrBias.x, dsx, dsy, function);
}
else
{
Float4 M;
cubeFace(face, uuuu, vvvv, u, v, w, M);
- computeLodCube(texture, lod, u, v, w, bias.x, dsx, dsy, M, function);
+ computeLodCube(texture, lod, u, v, w, lodOrBias.x, dsx, dsy, M, function);
}
}
else
{
- computeLod3D(texture, lod, uuuu, vvvv, wwww, bias.x, dsx, dsy, function);
+ computeLod3D(texture, lod, uuuu, vvvv, wwww, lodOrBias.x, dsx, dsy, function);
}
// FIXME: YUV is not supported by the floating point path
@@ -1137,7 +1137,7 @@
return lod;
}
- void SamplerCore::computeLod(Pointer<Byte> &texture, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Float4 &uuuu, Float4 &vvvv, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function)
+ void SamplerCore::computeLod(Pointer<Byte> &texture, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Float4 &uuuu, Float4 &vvvv, const Float &lodOrBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function)
{
if(function != Lod && function != Fetch)
{
@@ -1186,17 +1186,17 @@
if(function == Bias)
{
- lod += lodBias;
+ lod += lodOrBias;
}
}
else if(function == Lod)
{
- lod = lodBias;
+ lod = lodOrBias;
}
else if(function == Fetch)
{
// TODO: Eliminate int-float-int conversion.
- lod = Float(As<Int>(lodBias));
+ lod = Float(As<Int>(lodOrBias));
}
else if(function == Base)
{
@@ -1208,7 +1208,7 @@
lod = Min(lod, *Pointer<Float>(texture + OFFSET(Texture, maxLod)));
}
- void SamplerCore::computeLodCube(Pointer<Byte> &texture, Float &lod, Float4 &u, Float4 &v, Float4 &w, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, Float4 &M, SamplerFunction function)
+ void SamplerCore::computeLodCube(Pointer<Byte> &texture, Float &lod, Float4 &u, Float4 &v, Float4 &w, const Float &lodOrBias, Vector4f &dsx, Vector4f &dsy, Float4 &M, SamplerFunction function)
{
if(function != Lod && function != Fetch)
{
@@ -1252,17 +1252,17 @@
if(function == Bias)
{
- lod += lodBias;
+ lod += lodOrBias;
}
}
else if(function == Lod)
{
- lod = lodBias;
+ lod = lodOrBias;
}
else if(function == Fetch)
{
// TODO: Eliminate int-float-int conversion.
- lod = Float(As<Int>(lodBias));
+ lod = Float(As<Int>(lodOrBias));
}
else if(function == Base)
{
@@ -1274,7 +1274,7 @@
lod = Min(lod, *Pointer<Float>(texture + OFFSET(Texture, maxLod)));
}
- void SamplerCore::computeLod3D(Pointer<Byte> &texture, Float &lod, Float4 &uuuu, Float4 &vvvv, Float4 &wwww, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function)
+ void SamplerCore::computeLod3D(Pointer<Byte> &texture, Float &lod, Float4 &uuuu, Float4 &vvvv, Float4 &wwww, const Float &lodOrBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function)
{
if(function != Lod && function != Fetch)
{
@@ -1311,17 +1311,17 @@
if(function == Bias)
{
- lod += lodBias;
+ lod += lodOrBias;
}
}
else if(function == Lod)
{
- lod = lodBias;
+ lod = lodOrBias;
}
else if(function == Fetch)
{
// TODO: Eliminate int-float-int conversion.
- lod = Float(As<Int>(lodBias));
+ lod = Float(As<Int>(lodOrBias));
}
else if(function == Base)
{
diff --git a/src/Pipeline/SamplerCore.hpp b/src/Pipeline/SamplerCore.hpp
index 03817fe..9255e60 100644
--- a/src/Pipeline/SamplerCore.hpp
+++ b/src/Pipeline/SamplerCore.hpp
@@ -60,7 +60,7 @@
public:
SamplerCore(Pointer<Byte> &constants, const Sampler::State &state);
- Vector4f sampleTexture(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
+ Vector4f sampleTexture(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float4 &lodOrBias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
private:
void border(Short4 &mask, Float4 &coordinates);
@@ -78,9 +78,9 @@
Vector4f sampleFloat3D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function);
Float log2sqrt(Float lod);
Float log2(Float lod);
- void computeLod(Pointer<Byte> &texture, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Float4 &u, Float4 &v, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function);
- void computeLodCube(Pointer<Byte> &texture, Float &lod, Float4 &u, Float4 &v, Float4 &w, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, Float4 &M, SamplerFunction function);
- void computeLod3D(Pointer<Byte> &texture, Float &lod, Float4 &u, Float4 &v, Float4 &w, const Float &lodBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function);
+ void computeLod(Pointer<Byte> &texture, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Float4 &u, Float4 &v, const Float &lodOrBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function);
+ void computeLodCube(Pointer<Byte> &texture, Float &lod, Float4 &u, Float4 &v, Float4 &w, const Float &lodOrBias, Vector4f &dsx, Vector4f &dsy, Float4 &M, SamplerFunction function);
+ void computeLod3D(Pointer<Byte> &texture, Float &lod, Float4 &u, Float4 &v, Float4 &w, const Float &lodOrBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function);
void cubeFace(Int face[4], Float4 &U, Float4 &V, Float4 &x, Float4 &y, Float4 &z, Float4 &M);
Short4 applyOffset(Short4 &uvw, Float4 &offset, const Int4 &whd, AddressingMode mode);
void computeIndices(UInt index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, Vector4f &offset, const Pointer<Byte> &mipmap, SamplerFunction function);
diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp
index 11cf404..b3c7abe 100644
--- a/src/Pipeline/SpirvShader.cpp
+++ b/src/Pipeline/SpirvShader.cpp
@@ -4507,6 +4507,7 @@
SpirvShader::EmitResult SpirvShader::EmitImageSampleExplicitLod(Variant variant, InsnIterator insn, EmitState *state) const
{
uint32_t imageOperands = static_cast<spv::ImageOperandsMask>(insn.word(5));
+ imageOperands &= ~spv::ImageOperandsConstOffsetMask; // Dealt with later.
if((imageOperands & spv::ImageOperandsLodMask) == imageOperands)
{
@@ -4548,9 +4549,8 @@
auto imageView = *Pointer<Pointer<Byte>>(imageDescriptor + OFFSET(vk::SampledImageDescriptor, imageView)); // vk::ImageView*
uint32_t imageOperands = spv::ImageOperandsMaskNone;
- bool bias = false;
- bool lod = false;
- Object::ID lodId = 0;
+ bool lodOrBias = false;
+ Object::ID lodOrBiasId = 0;
bool grad = false;
Object::ID gradDxId = 0;
Object::ID gradDyId = 0;
@@ -4565,22 +4565,26 @@
if(imageOperands & spv::ImageOperandsBiasMask)
{
- UNIMPLEMENTED("Image operand %x", spv::ImageOperandsBiasMask); (void)bias;
- bias = true;
+ lodOrBias = true;
+ lodOrBiasId = insn.word(operand);
+ operand++;
imageOperands &= ~spv::ImageOperandsBiasMask;
+
+ ASSERT(instruction.samplerMethod == Implicit);
+ instruction.samplerMethod = Bias;
}
if(imageOperands & spv::ImageOperandsLodMask)
{
- lod = true;
- lodId = insn.word(operand);
+ lodOrBias = true;
+ lodOrBiasId = insn.word(operand);
operand++;
imageOperands &= ~spv::ImageOperandsLodMask;
}
if(imageOperands & spv::ImageOperandsGradMask)
{
- ASSERT(!lod); // SPIR-V 1.3: "It is invalid to set both the Lod and Grad bits."
+ ASSERT(!lodOrBias); // SPIR-V 1.3: "It is invalid to set both the Lod and Grad bits." Bias is for ImplicitLod, Grad for ExplicitLod.
grad = true;
gradDxId = insn.word(operand + 0);
gradDyId = insn.word(operand + 1);
@@ -4632,9 +4636,9 @@
UNIMPLEMENTED("OpImageSample*Dref*"); // TODO(b/129523279)
}
- if(lod)
+ if(lodOrBias)
{
- auto lodValue = GenericValue(this, state->routine, lodId);
+ auto lodValue = GenericValue(this, state->routine, lodOrBiasId);
in[i] = lodValue.Float(0);
i++;
}
diff --git a/src/Pipeline/SpirvShader.hpp b/src/Pipeline/SpirvShader.hpp
index 99b70e6..cf38289 100644
--- a/src/Pipeline/SpirvShader.hpp
+++ b/src/Pipeline/SpirvShader.hpp
@@ -515,7 +515,7 @@
// 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 lodOrBias : 1; // Indicated by SamplerMethod::Lod|Bias
uint32_t gradComponents : 2; // 0-3 (for each of dx / dy)
uint32_t offsetComponents : 2; // 0-3
};
diff --git a/src/Pipeline/SpirvShaderSampling.cpp b/src/Pipeline/SpirvShaderSampling.cpp
index 0762ec0..7fcd8a0 100644
--- a/src/Pipeline/SpirvShaderSampling.cpp
+++ b/src/Pipeline/SpirvShaderSampling.cpp
@@ -97,7 +97,7 @@
Pointer<Byte> texture = image + OFFSET(vk::SampledImageDescriptor, texture); // sw::Texture*
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).
+ SIMD::Float lodOrBias(0); // Explicit level-of-detail, or bias added to the implicit level-of-detail (depending on samplerMethod).
Vector4f dsx;
Vector4f dsy;
Vector4f offset;
@@ -117,10 +117,10 @@
uvw[1] = SIMD::Float(0);
}
- // Lod and Grad are explicit-lod image operands, and always come after the coordinates.
- if(instruction.samplerMethod == Lod)
+ if(instruction.samplerMethod == Lod || instruction.samplerMethod == Bias)
{
- bias = in[instruction.coordinates];
+ lodOrBias = in[i];
+ i++;
}
else if(instruction.samplerMethod == Grad)
{
@@ -143,7 +143,7 @@
}
}
- Vector4f sample = s.sampleTexture(texture, uvw[0], uvw[1], uvw[2], q, bias, dsx, dsy, offset, samplerFunction);
+ Vector4f sample = s.sampleTexture(texture, uvw[0], uvw[1], uvw[2], q, lodOrBias, dsx, dsy, offset, samplerFunction);
Pointer<SIMD::Float> rgba = out;
rgba[0] = sample.x;