Make image descriptor fields unsigned
All Vulkan width/height/depth variables are unsigned, while our
descriptor and sampling code used signed integers in various places.
While this was benign it added confusion about whether some of these
values could be negative and need special handling.
Note that the results produced by the 32-bit SamplerCore::address()
method are signed, because negative values represent out-of-bounds
sampling. So these are left unchanged and the image dimensions are
explicitly cast to signed where necessary.
The Mipmap::onePitchP field is also still signed, because it is used
in MulAdd() intrinsics which multiply pairs of signed 16-bit fields
and produce a 32-bit signed result (there is no unsigned PMADDWD
instruction variant). Note that multiplications which produce a result
of the same bit width as the operands are indifferent to signedness
(just like addition and subtraction).
Some assert_cast<>'s were used to catch unexpected overflows, and uses
of `auto` in the descriptor writing code were replaced with explicit
types to aid readability.
Bug: b/210880838
Bug: b/200806413
Change-Id: I8d8cb1b17cfd2d40b0ad3153e75c69a086e2ae40
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/61248
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Pipeline/SamplerCore.cpp b/src/Pipeline/SamplerCore.cpp
index 9ffddb9..37aa93a 100644
--- a/src/Pipeline/SamplerCore.cpp
+++ b/src/Pipeline/SamplerCore.cpp
@@ -480,8 +480,8 @@
if(!gather) // Blend
{
// Fractions
- UShort4 f0u = As<UShort4>(uuuu0) * UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, width)));
- UShort4 f0v = As<UShort4>(vvvv0) * UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, height)));
+ UShort4 f0u = As<UShort4>(uuuu0) * UShort4(*Pointer<UInt4>(mipmap + OFFSET(Mipmap, width)));
+ UShort4 f0v = As<UShort4>(vvvv0) * UShort4(*Pointer<UInt4>(mipmap + OFFSET(Mipmap, height)));
UShort4 f1u = ~f0u;
UShort4 f1v = ~f0v;
@@ -687,9 +687,9 @@
}
// Fractions
- UShort4 f0u = As<UShort4>(u[0][0][0]) * UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, width)));
- UShort4 f0v = As<UShort4>(v[0][0][0]) * UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, height)));
- UShort4 f0s = As<UShort4>(s[0][0][0]) * UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, depth)));
+ UShort4 f0u = As<UShort4>(u[0][0][0]) * UShort4(*Pointer<UInt4>(mipmap + OFFSET(Mipmap, width)));
+ UShort4 f0v = As<UShort4>(v[0][0][0]) * UShort4(*Pointer<UInt4>(mipmap + OFFSET(Mipmap, height)));
+ UShort4 f0s = As<UShort4>(s[0][0][0]) * UShort4(*Pointer<UInt4>(mipmap + OFFSET(Mipmap, depth)));
UShort4 f1u = ~f0u;
UShort4 f1v = ~f0v;
@@ -906,7 +906,7 @@
address(u, x0, x1, fu, mipmap, offset.x, filter, OFFSET(Mipmap, width), state.addressingModeU);
address(v, y0, y1, fv, mipmap, offset.y, filter, OFFSET(Mipmap, height), state.addressingModeV);
- Int4 pitchP = *Pointer<Int4>(mipmap + OFFSET(Mipmap, pitchP), 16);
+ Int4 pitchP = As<Int4>(*Pointer<UInt4>(mipmap + OFFSET(Mipmap, pitchP), 16));
y0 *= pitchP;
Int4 z;
@@ -999,8 +999,8 @@
address(v, y0, y1, fv, mipmap, offset.y, filter, OFFSET(Mipmap, height), state.addressingModeV);
address(w, z0, z1, fw, mipmap, offset.z, filter, OFFSET(Mipmap, depth), state.addressingModeW);
- Int4 pitchP = *Pointer<Int4>(mipmap + OFFSET(Mipmap, pitchP), 16);
- Int4 sliceP = *Pointer<Int4>(mipmap + OFFSET(Mipmap, sliceP), 16);
+ Int4 pitchP = As<Int4>(*Pointer<UInt4>(mipmap + OFFSET(Mipmap, pitchP), 16));
+ Int4 sliceP = As<Int4>(*Pointer<UInt4>(mipmap + OFFSET(Mipmap, sliceP), 16));
y0 *= pitchP;
z0 *= sliceP;
@@ -1315,22 +1315,22 @@
void SamplerCore::computeIndices(UInt index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, const Short4 &layerIndex, Vector4i &offset, const Int4 &sample, const Pointer<Byte> &mipmap)
{
- uuuu = MulHigh(As<UShort4>(uuuu), UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, width))));
+ uuuu = MulHigh(As<UShort4>(uuuu), UShort4(*Pointer<UInt4>(mipmap + OFFSET(Mipmap, width))));
if(function.offset)
{
- uuuu = applyOffset(uuuu, offset.x, *Pointer<Int4>(mipmap + OFFSET(Mipmap, width)), state.addressingModeU);
+ uuuu = applyOffset(uuuu, offset.x, *Pointer<UInt4>(mipmap + OFFSET(Mipmap, width)), state.addressingModeU);
}
UInt4 indices = Int4(uuuu);
if(state.is2D() || state.is3D() || state.isCube())
{
- vvvv = MulHigh(As<UShort4>(vvvv), UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, height))));
+ vvvv = MulHigh(As<UShort4>(vvvv), UShort4(*Pointer<UInt4>(mipmap + OFFSET(Mipmap, height))));
if(function.offset)
{
- vvvv = applyOffset(vvvv, offset.y, *Pointer<Int4>(mipmap + OFFSET(Mipmap, height)), state.addressingModeV);
+ vvvv = applyOffset(vvvv, offset.y, *Pointer<UInt4>(mipmap + OFFSET(Mipmap, height)), state.addressingModeV);
}
Short4 uv0uv1 = As<Short4>(UnpackLow(uuuu, vvvv));
@@ -2245,7 +2245,7 @@
return;
}
- Int4 dim = *Pointer<Int4>(mipmap + whd, 16);
+ Int4 dim = As<Int4>(*Pointer<UInt4>(mipmap + whd, 16));
Int4 maxXYZ = dim - Int4(1);
if(function == Fetch) // Unnormalized coordinates