Simplify scaling of 16-bit sampled texel components
For image formats that get sampled using v4i16 vectors as intermediate
results we place each texel component's bits in the upper part of the
16-bit vector components. On conversion to floating-point we need to
(un)scale. For example, a 565 format uses 0xF800 to represent 1.0 in the
16-bit vector components so this is the scaling factor used for
normalization.
Previously, determining the scaling factor used the Format::getScale()
method, which returns the scale for when the texel's fields are placed
in the lower part of integer vectors. This floating-point value was
converted to integer, shifted, and then converted back to floating-point
to get the scaling factor for fields placed in the upper bits instead.
This change simplifies it by computing the value which represents 1.0
using just integer arithmetic. For signed components the sign bit is
masked off. The max() operation has been removed since all formats which
are sampled using vectors with 16-bit components as intermediate result
must have no more than 16 bits per component field.
Bug: b/204709464
Change-Id: Id9365065f3d171f67ba2bcf6de5329d323eaf2a9
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/60428
Reviewed-by: Alexis Hétu <sugoi@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Commit-Queue: Nicolas Capens <nicolascapens@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
diff --git a/src/Pipeline/SamplerCore.cpp b/src/Pipeline/SamplerCore.cpp
index 5c426e1..b79532d 100644
--- a/src/Pipeline/SamplerCore.cpp
+++ b/src/Pipeline/SamplerCore.cpp
@@ -2586,15 +2586,14 @@
break;
};
- const sw::float4 scale = state.textureFormat.getScale();
const sw::int4 bits = state.textureFormat.bitsPerComponent();
- const sw::int4 shift = sw::int4(std::max(16 - bits.x, 0), std::max(16 - bits.y, 0), std::max(16 - bits.z, 0),
- std::max(16 - bits.w, 0));
+ const sw::int4 shift = sw::int4(16 - bits.x, 16 - bits.y, 16 - bits.z, 16 - bits.w);
+ const uint16_t sign = state.textureFormat.isUnsigned() ? 0xFFFF : 0x7FFF;
- return sw::float4(static_cast<uint16_t>(scale.x) << shift.x,
- static_cast<uint16_t>(scale.y) << shift.y,
- static_cast<uint16_t>(scale.z) << shift.z,
- static_cast<uint16_t>(scale.w) << shift.w);
+ return sw::float4(static_cast<uint16_t>(0xFFFF << shift.x) & sign,
+ static_cast<uint16_t>(0xFFFF << shift.y) & sign,
+ static_cast<uint16_t>(0xFFFF << shift.z) & sign,
+ static_cast<uint16_t>(0xFFFF << shift.w) & sign);
}
int SamplerCore::getGatherComponent() const