Fix interpolation functions for push constants When using push constants, we end up having dynamic offsets on the input parameter of the interpolation functions, so we need to be able to handle this case. Since this is for push constants, we assume that all dynamic offsets will be the same, for simplicity. Bug: b/171415086 Change-Id: I5de1720e383c234c9392421d507a66e6d7ba2445 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/52930 Presubmit-Ready: Alexis Hétu <sugoi@google.com> Reviewed-by: Nicolas Capens <nicolascapens@google.com> Kokoro-Result: kokoro <noreply+kokoro@google.com> Tested-by: Alexis Hétu <sugoi@google.com> Commit-Queue: Alexis Hétu <sugoi@google.com>
diff --git a/src/Pipeline/SpirvShaderGLSLstd450.cpp b/src/Pipeline/SpirvShaderGLSLstd450.cpp index 7455029..f1644a5 100644 --- a/src/Pipeline/SpirvShaderGLSLstd450.cpp +++ b/src/Pipeline/SpirvShaderGLSLstd450.cpp
@@ -54,6 +54,16 @@ return offset; } +rr::Int ComputeInterpolantOffset(rr::Int offset, uint32_t components_per_row, bool useArrayOffset) +{ + if(useArrayOffset) + { + rr::Int interpolant_offset = offset / rr::Int(components_per_row); + offset = (interpolant_offset << 2) + (offset - interpolant_offset * rr::Int(components_per_row)); + } + return offset; +} + } // namespace namespace sw { @@ -1064,13 +1074,26 @@ return SIMD::Float(0.0f); } - uint32_t offset = ComputeInterpolantOffset((ptr.staticOffsets[0] >> 2) + component, components_per_row, useArrayOffset); - if((interpolant + offset) >= inputs.size()) + Pointer<Byte> planeEquation = interpolationData.primitive + OFFSET(Primitive, V[interpolant]); + if(ptr.hasDynamicOffsets) { - return SIMD::Float(0.0f); + // This code assumes all dynamic offsets are equal + Int offset = ComputeInterpolantOffset(((Extract(ptr.dynamicOffsets, 0) + ptr.staticOffsets[0]) >> 2) + component, components_per_row, useArrayOffset); + offset = Min(offset, Int(inputs.size() - interpolant - 1)); + planeEquation += (offset * sizeof(PlaneEquation)); + } + else + { + ASSERT(ptr.hasStaticEqualOffsets()); + + uint32_t offset = ComputeInterpolantOffset((ptr.staticOffsets[0] >> 2) + component, components_per_row, useArrayOffset); + if((interpolant + offset) >= inputs.size()) + { + return SIMD::Float(0.0f); + } + planeEquation += offset * sizeof(PlaneEquation); } - Pointer<Byte> planeEquation = interpolationData.primitive + OFFSET(Primitive, V[interpolant]) + offset * sizeof(PlaneEquation); return SpirvRoutine::interpolateAtXY(x, y, rhw, planeEquation, false, true); }