summaryrefslogtreecommitdiff
path: root/libpcsxcore/pgxp_value.c
diff options
context:
space:
mode:
authoriCatButler <i.am.catbutler@gmail.com>2016-07-30 17:43:12 +0100
committeriCatButler <i.am.catbutler@gmail.com>2016-07-30 17:43:12 +0100
commit69f33a4782857bf2027db6c81f670409bed76b43 (patch)
treeca5ac7afe837748e8c1db89c2519eabf367df4ea /libpcsxcore/pgxp_value.c
parentd5b40fbbe0eee90573ec1848ac135962fba9438e (diff)
downloadpcsxr-69f33a4782857bf2027db6c81f670409bed76b43.tar.gz
Various CPU updates
- Sign extend values read using LH - Add conversion functions to represent Signed/Unsigned 16-bit ranges - Add overflow and truncation functions for 16-bit ranges - Sign extend imm value in ADD(U) - Add component overflow and truncation to ADD/SUB functions - Construct new value in logic operators where result using inputs is undefined - Return a valid W component from logic operators (if either input has one) - Compare against high value (y), then low value (x) in less than operators - Use doubles and implement overflow for Multiply operations to try to increase accuracy - Use unsigned values in both MUL and DIV operations to make output as accurate as possible - Implement several variants of shift operators. Trying both arithmetically correct and more analytical approaches with varying success. Debug updates - Added ability to force all values to be equal to low precision values before operating on them - Added feature to test output of operations against a tolerance and print only those which fail GPU updates - Colour vertices with valid XY coordinates but no W as cyan to make them easier to spot - Remove cyan colouring for stale vertices (wasn't useful) - Added ability to skip debug rendering when needed (like seeing the output of offscreen rendering applied to a sprite). - Added new mode which shows primitive type
Diffstat (limited to 'libpcsxcore/pgxp_value.c')
-rw-r--r--libpcsxcore/pgxp_value.c46
1 files changed, 43 insertions, 3 deletions
diff --git a/libpcsxcore/pgxp_value.c b/libpcsxcore/pgxp_value.c
index 5c46a7d4..c52a8999 100644
--- a/libpcsxcore/pgxp_value.c
+++ b/libpcsxcore/pgxp_value.c
@@ -1,5 +1,17 @@
#include "pgxp_value.h"
+#include "limits.h"
+void SetValue(PGXP_value *pV, u32 psxV)
+{
+ psx_value psx;
+ psx.d = psxV;
+
+ pV->x = psx.sw.l;
+ pV->y = psx.sw.h;
+ pV->z = 0.f;
+ pV->flags = VALID_01;
+ pV->value = psx.d;
+}
void MakeValid(PGXP_value *pV, u32 psxV)
{
@@ -9,8 +21,8 @@ void MakeValid(PGXP_value *pV, u32 psxV)
{
pV->x = psx.sw.l;
pV->y = psx.sw.h;
- pV->z = 1.f;
- pV->flags |= VALID_ALL;
+ pV->z = 0.f;
+ pV->flags |= VALID_01;
pV->value = psx.d;
}
}
@@ -18,11 +30,39 @@ void MakeValid(PGXP_value *pV, u32 psxV)
void Validate(PGXP_value *pV, u32 psxV)
{
// assume pV is not NULL
- pV->flags &= pV->value == psxV ? ALL : INV_VALID_ALL;
+ pV->flags &= (pV->value == psxV) ? ALL : INV_VALID_ALL;
}
void MaskValidate(PGXP_value *pV, u32 psxV, u32 mask, u32 validMask)
{
// assume pV is not NULL
pV->flags &= ((pV->value & mask) == (psxV & mask)) ? ALL : (ALL ^ (validMask));
+}
+
+u32 ValueToTolerance(PGXP_value *pV, u32 psxV, float tolerance)
+{
+ psx_value psx;
+ psx.d = psxV;
+ u32 retFlags = VALID_ALL;
+
+ if (fabs(pV->x - psx.sw.l) >= tolerance)
+ retFlags = retFlags & (VALID_1 | VALID_2 | VALID_3);
+
+ if (fabs(pV->y - psx.sw.h) >= tolerance)
+ retFlags = retFlags & (VALID_0 | VALID_2 | VALID_3);
+
+ return retFlags;
+}
+
+/// float logical arithmetic ///
+
+double f16Sign(double in) { u32 s = in * (double)((u32)1 << 16); return ((double)*((s32*)&s)) / (double)((s32)1 << 16); }
+double f16Unsign(double in) { return (in >= 0) ? in : ((double)in + (double)USHRT_MAX + 1); }
+double fu16Trunc(double in) { u32 u = in * (double)((u32)1 << 16); return (double)u / (double)((u32)1 << 16); }
+double f16Overflow(double in)
+{
+ double out = 0;
+ s64 v = ((s64)in) >> 16;
+ out = v;
+ return out;
} \ No newline at end of file