Move required interpolation logic to SpirvShader
Some of the interpolation logic is required to properly implement
the GLSLstd450Interpolate* operations. In order to prevent code
duplication and to make sure the logic is always identical between
the regular fragment input interpolation and the one performed by
the GLSLstd450Interpolate* operations, the interpolateCentroid()
function was moved to SpirvShader and renamed with a more generic
name, interpolateXY(), as it will be used to interpolate all modes
(centroid, sample and offset).
Bug: b/171415086
Change-Id: Ifbffa2b395a0b8c22fa120b36643db05f867a306
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/51731
Tested-by: Alexis Hétu <sugoi@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Pipeline/PixelRoutine.cpp b/src/Pipeline/PixelRoutine.cpp
index 873700e..0653d7c 100644
--- a/src/Pipeline/PixelRoutine.cpp
+++ b/src/Pipeline/PixelRoutine.cpp
@@ -147,7 +147,7 @@
if(state.centroid)
{
- rhwCentroid = reciprocal(interpolateCentroid(XXXX, YYYY, rhwCentroid, primitive + OFFSET(Primitive, w), false, false));
+ rhwCentroid = reciprocal(SpirvRoutine::interpolateAtXY(XXXX, YYYY, rhwCentroid, primitive + OFFSET(Primitive, w), false, false));
}
}
@@ -161,9 +161,9 @@
if(input.Centroid && state.enableMultiSampling)
{
routine.inputs[interpolant] =
- interpolateCentroid(XXXX, YYYY, rhwCentroid,
- primitive + OFFSET(Primitive, V[interpolant]),
- input.Flat, !input.NoPerspective);
+ SpirvRoutine::interpolateAtXY(XXXX, YYYY, rhwCentroid,
+ primitive + OFFSET(Primitive, V[interpolant]),
+ input.Flat, !input.NoPerspective);
}
else
{
@@ -282,24 +282,6 @@
}
}
-Float4 PixelRoutine::interpolateCentroid(const Float4 &x, const Float4 &y, const Float4 &rhw, Pointer<Byte> planeEquation, bool flat, bool perspective)
-{
- Float4 interpolant = *Pointer<Float4>(planeEquation + OFFSET(PlaneEquation, C), 16);
-
- if(!flat)
- {
- interpolant += x * *Pointer<Float4>(planeEquation + OFFSET(PlaneEquation, A), 16) +
- y * *Pointer<Float4>(planeEquation + OFFSET(PlaneEquation, B), 16);
-
- if(perspective)
- {
- interpolant *= rhw;
- }
- }
-
- return interpolant;
-}
-
void PixelRoutine::stencilTest(const Pointer<Byte> &sBuffer, int q, const Int &x, Int &sMask, const Int &cMask)
{
if(!state.stencilActive)
diff --git a/src/Pipeline/PixelRoutine.hpp b/src/Pipeline/PixelRoutine.hpp
index d9d4f21..e4dc029 100644
--- a/src/Pipeline/PixelRoutine.hpp
+++ b/src/Pipeline/PixelRoutine.hpp
@@ -66,7 +66,6 @@
void linearToSRGB12_16(Vector4s &c);
private:
- Float4 interpolateCentroid(const Float4 &x, const Float4 &y, const Float4 &rhw, Pointer<Byte> planeEquation, bool flat, bool perspective);
Byte8 stencilReplaceRef(bool isBack);
void stencilTest(const Pointer<Byte> &sBuffer, int q, const Int &x, Int &sMask, const Int &cMask);
void stencilTest(Byte8 &value, VkCompareOp stencilCompareMode, bool isBack);
diff --git a/src/Pipeline/SpirvShader.hpp b/src/Pipeline/SpirvShader.hpp
index c479588..8631351 100644
--- a/src/Pipeline/SpirvShader.hpp
+++ b/src/Pipeline/SpirvShader.hpp
@@ -1406,6 +1406,8 @@
// common for all shader types.
void setImmutableInputBuiltins(SpirvShader const *shader);
+ static SIMD::Float interpolateAtXY(const SIMD::Float &x, const SIMD::Float &y, const SIMD::Float &rhw, Pointer<Byte> planeEquation, bool flat, bool perspective);
+
// setInputBuiltin() calls f() with the builtin and value if the shader
// uses the input builtin, otherwise the call is a no-op.
// F is a function with the signature:
diff --git a/src/Pipeline/SpirvShaderGLSLstd450.cpp b/src/Pipeline/SpirvShaderGLSLstd450.cpp
index 1d82a5b..e43a298 100644
--- a/src/Pipeline/SpirvShaderGLSLstd450.cpp
+++ b/src/Pipeline/SpirvShaderGLSLstd450.cpp
@@ -15,14 +15,35 @@
#include "SpirvShader.hpp"
#include "ShaderCore.hpp"
+#include "Device/Primitive.hpp"
#include <spirv/unified1/GLSL.std.450.h>
#include <spirv/unified1/spirv.hpp>
namespace {
constexpr float PI = 3.141592653589793f;
+
+sw::SIMD::Float Interpolate(const sw::SIMD::Float &x, const sw::SIMD::Float &y, const sw::SIMD::Float &rhw,
+ const sw::SIMD::Float &A, const sw::SIMD::Float &B, const sw::SIMD::Float &C,
+ bool flat, bool perspective)
+{
+ sw::SIMD::Float interpolant = C;
+
+ if(!flat)
+ {
+ interpolant += x * A + y * B;
+
+ if(perspective)
+ {
+ interpolant *= rhw;
+ }
+ }
+
+ return interpolant;
}
+} // namespace
+
namespace sw {
SpirvShader::EmitResult SpirvShader::EmitExtGLSLstd450(InsnIterator insn, EmitState *state) const
@@ -932,4 +953,19 @@
return EmitResult::Continue;
}
+SIMD::Float SpirvRoutine::interpolateAtXY(const SIMD::Float &x, const SIMD::Float &y, const SIMD::Float &rhw, Pointer<Byte> planeEquation, bool flat, bool perspective)
+{
+ SIMD::Float A;
+ SIMD::Float B;
+ SIMD::Float C = *Pointer<SIMD::Float>(planeEquation + OFFSET(PlaneEquation, C), 16);
+
+ if(!flat)
+ {
+ A = *Pointer<SIMD::Float>(planeEquation + OFFSET(PlaneEquation, A), 16);
+ B = *Pointer<SIMD::Float>(planeEquation + OFFSET(PlaneEquation, B), 16);
+ }
+
+ return ::Interpolate(x, y, rhw, A, B, C, flat, perspective);
+}
+
} // namespace sw
\ No newline at end of file