SoftGPU: Move the GE clip and viewport helpers to GEMath.h

So the hardware backends' software transform can use them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-10-08 16:16:24 +02:00
1 parent 0b4c29c883
commit 964b5dc00a
2 files changed
+44 -44

No files matched your search

-44
View File
@@ -154,19 +154,6 @@ WorldCoords TransformUnit::ModelToWorldNormal(const ModelCoords &coords) {
return WorldCoords(GEDot(coords, Vec3f(m[0], m[3], m[6])), GEDot(coords, Vec3f(m[1], m[4], m[7])), GEDot(coords, Vec3f(m[2], m[5], m[8])));
}
// A clip space component from the combined matrix (gpu/probe exp32, exp34, exp42). The position is a
// float24; the translation is a term of its own.
static inline float GEClipComponent(const Vec3f &v, const float m[16], int c) {
GERowTerm terms[4] = {
GEProduct(TruncateToFloat24(v.x), m[c]),
GEProduct(TruncateToFloat24(v.y), m[4 + c]),
GEProduct(TruncateToFloat24(v.z), m[8 + c]),
GEProduct(1.0f, m[12 + c]),
};
return GERowSum(terms, 4);
}
// A texture coordinate from the 4x3 texture matrix, summed like a clip space row (gpu/probe exp64).
static inline float GETexGenComponent(const Vec3f &v, const float m[12], int c) {
GERowTerm terms[4] = {
@@ -178,37 +165,6 @@ static inline float GETexGenComponent(const Vec3f &v, const float m[12], int c)
return GERowSum(terms, 4);
}
// Multiplies two matrices the way the GE combines world, view and projection (gpu/probe exp35, exp42):
// in the order (world * view) * projection, each entry summed like a row in GEClipComponent.
static void GECombineMatrices(float out[16], const float a[16], const float b[16]) {
for (int r = 0; r < 4; ++r) {
for (int c = 0; c < 4; ++c) {
GERowTerm terms[4];
for (int k = 0; k < 4; ++k) {
terms[k] = GEProduct(a[r * 4 + k], b[k * 4 + c]);
}
out[r * 4 + c] = GERowSum(terms, 4);
}
}
}
// A screen coordinate as the GE computes it (gpu/depth/transformprecision for Z, gpu/probe for X and Y):
// the component divided by w is it times the reciprocal above, truncated to a float24, then scaled and
// offset with GEAdd. Around a center of 2048, that lands X and Y on the 1/16 subpixel grid.
static inline float GEViewport(float clipC, float clipW, float scale, float center) {
const float w = TruncateToFloat24(clipW);
if (!std::isfinite(w) || !std::isfinite(clipC) || fabsf(w) < FLT_MIN) {
return clipC * scale / clipW + center;
}
const float ndc = ProductToFloat24((double)TruncateToFloat24(clipC) * GERecip(w));
return GEAdd(ProductToFloat24((double)ndc * scale), center);
}
// Screen Z is floored.
static inline float GEScreenZ(float clipZ, float clipW, float zScale, float zCenter) {
return floorf(GEViewport(clipZ, clipW, zScale, zCenter));
}
template <bool depthClamp, bool alwaysCheckRange>
static ScreenCoords ClipToScreenInternal(Vec3f scaled, const ClipCoords &coords, bool *outside_range_flag) {
// Account for rounding for X and Y.