[ioquake3] 13/21: Fix floating point precision loss in renderer [part 2]

Simon McVittie smcv at debian.org
Fri Aug 4 20:39:13 UTC 2017


This is an automated email from the git hooks/post-receive script.

smcv pushed a commit to branch debian/master
in repository ioquake3.

commit 59b1262b82a2d2fa80f7f5ffce098cb4d3459a14
Author: Zack Middleton <zack at cloemail.com>
Date:   Wed Aug 2 23:29:46 2017 -0500

    Fix floating point precision loss in renderer [part 2]
    
    Fix floatTime using float precision instead of double using GCC.
    Fix R_BindAnimatedImage to be in sync with function table.
    Fix vertexDeform bulge, vertexDeform normals, noise wave function
    at high level time.
    
    Revert unnecessary float -> double conversions.
---
 code/renderercommon/tr_common.h  |  2 +-
 code/renderercommon/tr_noise.c   |  2 +-
 code/renderergl1/tr_backend.c    |  2 +-
 code/renderergl1/tr_local.h      | 10 +++----
 code/renderergl1/tr_scene.c      |  2 +-
 code/renderergl1/tr_shade.c      |  7 ++---
 code/renderergl1/tr_shade_calc.c | 20 ++++++--------
 code/renderergl2/tr_backend.c    |  2 +-
 code/renderergl2/tr_local.h      | 59 +++++++++++++++++++++-------------------
 code/renderergl2/tr_scene.c      |  2 +-
 code/renderergl2/tr_shade.c      |  7 ++---
 code/renderergl2/tr_shade_calc.c | 16 +++++------
 12 files changed, 62 insertions(+), 69 deletions(-)

diff --git a/code/renderercommon/tr_common.h b/code/renderercommon/tr_common.h
index 9f15a2d..eb79fdf 100644
--- a/code/renderercommon/tr_common.h
+++ b/code/renderercommon/tr_common.h
@@ -116,7 +116,7 @@ extern	cvar_t	*r_saveFontData;
 
 qboolean	R_GetModeInfo( int *width, int *height, float *windowAspect, int mode );
 
-float R_NoiseGet4f( float x, float y, float z, float t );
+float R_NoiseGet4f( float x, float y, float z, double t );
 void  R_NoiseInit( void );
 
 image_t     *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags );
diff --git a/code/renderercommon/tr_noise.c b/code/renderercommon/tr_noise.c
index 445ef82..abd27cb 100644
--- a/code/renderercommon/tr_noise.c
+++ b/code/renderercommon/tr_noise.c
@@ -49,7 +49,7 @@ void R_NoiseInit( void )
 	}
 }
 
-float R_NoiseGet4f( float x, float y, float z, float t )
+float R_NoiseGet4f( float x, float y, float z, double t )
 {
 	int i;
 	int ix, iy, iz, it;
diff --git a/code/renderergl1/tr_backend.c b/code/renderergl1/tr_backend.c
index 22ec048..869bfcd 100644
--- a/code/renderergl1/tr_backend.c
+++ b/code/renderergl1/tr_backend.c
@@ -716,7 +716,7 @@ void	RB_SetGL2D (void) {
 
 	// set time for 2D shaders
 	backEnd.refdef.time = ri.Milliseconds();
-	backEnd.refdef.floatTime = (double)backEnd.refdef.time * 0.001f;
+	backEnd.refdef.floatTime = backEnd.refdef.time * 0.001;
 }
 
 
diff --git a/code/renderergl1/tr_local.h b/code/renderergl1/tr_local.h
index 54279a6..ffd824a 100644
--- a/code/renderergl1/tr_local.h
+++ b/code/renderergl1/tr_local.h
@@ -189,10 +189,10 @@ typedef enum {
 typedef struct {
 	genFunc_t	func;
 
-	double base;
-	double amplitude;
-	double phase;
-	double frequency;
+	float base;
+	float amplitude;
+	float phase;
+	float frequency;
 } waveForm_t;
 
 #define TR_MAX_TEXMODS 4
@@ -252,7 +252,7 @@ typedef struct {
 typedef struct {
 	image_t			*image[MAX_IMAGE_ANIMATIONS];
 	int				numImageAnimations;
-	double			imageAnimationSpeed;
+	float			imageAnimationSpeed;
 
 	texCoordGen_t	tcGen;
 	vec3_t			tcGenVectors[2];
diff --git a/code/renderergl1/tr_scene.c b/code/renderergl1/tr_scene.c
index 5d7a3dd..639f4e2 100644
--- a/code/renderergl1/tr_scene.c
+++ b/code/renderergl1/tr_scene.c
@@ -344,7 +344,7 @@ void RE_RenderScene( const refdef_t *fd ) {
 
 	// derived info
 
-	tr.refdef.floatTime = tr.refdef.time * 0.001f;
+	tr.refdef.floatTime = tr.refdef.time * 0.001;
 
 	tr.refdef.numDrawSurfs = r_firstSceneDrawSurf;
 	tr.refdef.drawSurfs = backEndData->drawSurfs;
diff --git a/code/renderergl1/tr_shade.c b/code/renderergl1/tr_shade.c
index ab5813f..61a6e0b 100644
--- a/code/renderergl1/tr_shade.c
+++ b/code/renderergl1/tr_shade.c
@@ -219,7 +219,6 @@ R_BindAnimatedImage
 */
 static void R_BindAnimatedImage( textureBundle_t *bundle ) {
 	int64_t index;
-	double	v;
 
 	if ( bundle->isVideoMap ) {
 		ri.CIN_RunCinematic(bundle->videoMapHandle);
@@ -234,10 +233,8 @@ static void R_BindAnimatedImage( textureBundle_t *bundle ) {
 
 	// it is necessary to do this messy calc to make sure animations line up
 	// exactly with waveforms of the same frequency
-	//index = ri.ftol(tess.shaderTime * bundle->imageAnimationSpeed * FUNCTABLE_SIZE);
-	//index >>= FUNCTABLE_SIZE2;
-	v = tess.shaderTime * bundle->imageAnimationSpeed;
-	index = v;
+	index = tess.shaderTime * bundle->imageAnimationSpeed * FUNCTABLE_SIZE;
+	index >>= FUNCTABLE_SIZE2;
 
 	if ( index < 0 ) {
 		index = 0;	// may happen with shader time offsets
diff --git a/code/renderergl1/tr_shade_calc.c b/code/renderergl1/tr_shade_calc.c
index 34975e2..58b5427 100644
--- a/code/renderergl1/tr_shade_calc.c
+++ b/code/renderergl1/tr_shade_calc.c
@@ -27,7 +27,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #endif
 
 
-#define	WAVEVALUE( table, base, amplitude, phase, freq )  ((base) + table[ (int)( ( ( (phase) + tess.shaderTime * (freq) ) * FUNCTABLE_SIZE ) ) & FUNCTABLE_MASK ] * (amplitude))
+#define	WAVEVALUE( table, base, amplitude, phase, freq )  ((base) + table[ ( (int64_t) ( ( (phase) + tess.shaderTime * (freq) ) * FUNCTABLE_SIZE ) ) & FUNCTABLE_MASK ] * (amplitude))
 
 static float *TableForFunc( genFunc_t func ) 
 {
@@ -206,12 +206,12 @@ void RB_CalcBulgeVertexes( deformStage_t *ds ) {
 	const float *st = ( const float * ) tess.texCoords[0];
 	float		*xyz = ( float * ) tess.xyz;
 	float		*normal = ( float * ) tess.normal;
-	float		now;
+	double		now;
 
-	now = backEnd.refdef.time * ds->bulgeSpeed * 0.001f;
+	now = backEnd.refdef.time * 0.001 * ds->bulgeSpeed;
 
 	for ( i = 0; i < tess.numVertexes; i++, xyz += 4, st += 4, normal += 4 ) {
-		int		off;
+		int64_t off;
 		float scale;
 
 		off = (float)( FUNCTABLE_SIZE / (M_PI*2) ) * ( st[0] * ds->bulgeWidth + now );
@@ -929,8 +929,8 @@ void RB_CalcTurbulentTexCoords( const waveForm_t *wf, float *st )
 		float s = st[0];
 		float t = st[1];
 
-		st[0] = s + tr.sinTable[ ( ( int ) ( ( ( tess.xyz[i][0] + tess.xyz[i][2] )* 1.0/128 * 0.125 + now ) * FUNCTABLE_SIZE ) ) & ( FUNCTABLE_MASK ) ] * wf->amplitude;
-		st[1] = t + tr.sinTable[ ( ( int ) ( ( tess.xyz[i][1] * 1.0/128 * 0.125 + now ) * FUNCTABLE_SIZE ) ) & ( FUNCTABLE_MASK ) ] * wf->amplitude;
+		st[0] = s + tr.sinTable[ ( ( int64_t ) ( ( ( tess.xyz[i][0] + tess.xyz[i][2] )* 1.0/128 * 0.125 + now ) * FUNCTABLE_SIZE ) ) & ( FUNCTABLE_MASK ) ] * wf->amplitude;
+		st[1] = t + tr.sinTable[ ( ( int64_t ) ( ( tess.xyz[i][1] * 1.0/128 * 0.125 + now ) * FUNCTABLE_SIZE ) ) & ( FUNCTABLE_MASK ) ] * wf->amplitude;
 	}
 }
 
@@ -954,13 +954,11 @@ void RB_CalcScaleTexCoords( const float scale[2], float *st )
 void RB_CalcScrollTexCoords( const float scrollSpeed[2], float *st )
 {
 	int i;
-	double timeScale;
+	double timeScale = tess.shaderTime;
 	double adjustedScrollS, adjustedScrollT;
 
-	timeScale = tess.shaderTime;
-
-	adjustedScrollS = (double)scrollSpeed[0] * timeScale;
-	adjustedScrollT = (double)scrollSpeed[1] * timeScale;
+	adjustedScrollS = scrollSpeed[0] * timeScale;
+	adjustedScrollT = scrollSpeed[1] * timeScale;
 
 	// clamp so coordinates don't continuously get larger, causing problems
 	// with hardware limits
diff --git a/code/renderergl2/tr_backend.c b/code/renderergl2/tr_backend.c
index 4f8f3f4..decccbf 100644
--- a/code/renderergl2/tr_backend.c
+++ b/code/renderergl2/tr_backend.c
@@ -661,7 +661,7 @@ void	RB_SetGL2D (void) {
 
 	// set time for 2D shaders
 	backEnd.refdef.time = ri.Milliseconds();
-	backEnd.refdef.floatTime = (double)backEnd.refdef.time * 0.001f;
+	backEnd.refdef.floatTime = backEnd.refdef.time * 0.001;
 }
 
 
diff --git a/code/renderergl2/tr_local.h b/code/renderergl2/tr_local.h
index 9426ede..4926149 100644
--- a/code/renderergl2/tr_local.h
+++ b/code/renderergl2/tr_local.h
@@ -268,10 +268,10 @@ typedef enum {
 typedef struct {
 	genFunc_t	func;
 
-	double base;
-	double amplitude;
-	double phase;
-	double frequency;
+	float base;
+	float amplitude;
+	float phase;
+	float frequency;
 } waveForm_t;
 
 #define TR_MAX_TEXMODS 4
@@ -331,7 +331,7 @@ typedef struct {
 typedef struct {
 	image_t			*image[MAX_IMAGE_ANIMATIONS];
 	int				numImageAnimations;
-	double			imageAnimationSpeed;
+	float			imageAnimationSpeed;
 
 	texCoordGen_t	tcGen;
 	vec3_t			tcGenVectors[2];
@@ -479,29 +479,6 @@ typedef struct shader_s {
 	struct	shader_s	*next;
 } shader_t;
 
-static ID_INLINE qboolean ShaderRequiresCPUDeforms(const shader_t * shader)
-{
-	if(shader->numDeforms)
-	{
-		const deformStage_t *ds = &shader->deforms[0];
-
-		if (shader->numDeforms > 1)
-			return qtrue;
-
-		switch (ds->deformation)
-		{
-			case DEFORM_WAVE:
-			case DEFORM_BULGE:
-				return qfalse;
-
-			default:
-				return qtrue;
-		}
-	}
-
-	return qfalse;
-}
-
 enum
 {
 	ATTR_INDEX_POSITION       = 0,
@@ -1791,6 +1768,32 @@ extern cvar_t	*r_marksOnTriangleMeshes;
 
 //====================================================================
 
+static ID_INLINE qboolean ShaderRequiresCPUDeforms(const shader_t * shader)
+{
+	if(shader->numDeforms)
+	{
+		const deformStage_t *ds = &shader->deforms[0];
+
+		if (shader->numDeforms > 1)
+			return qtrue;
+
+		switch (ds->deformation)
+		{
+			case DEFORM_WAVE:
+			case DEFORM_BULGE:
+				// need CPU deforms at high level-times to avoid floating point percision loss
+				return ( backEnd.refdef.floatTime != (float)backEnd.refdef.floatTime );
+
+			default:
+				return qtrue;
+		}
+	}
+
+	return qfalse;
+}
+
+//====================================================================
+
 void R_SwapBuffers( int );
 
 void R_RenderView( viewParms_t *parms );
diff --git a/code/renderergl2/tr_scene.c b/code/renderergl2/tr_scene.c
index e336978..ff0a22e 100644
--- a/code/renderergl2/tr_scene.c
+++ b/code/renderergl2/tr_scene.c
@@ -400,7 +400,7 @@ void RE_BeginScene(const refdef_t *fd)
 
 	// derived info
 
-	tr.refdef.floatTime = tr.refdef.time * 0.001f;
+	tr.refdef.floatTime = tr.refdef.time * 0.001;
 
 	tr.refdef.numDrawSurfs = r_firstSceneDrawSurf;
 	tr.refdef.drawSurfs = backEndData->drawSurfs;
diff --git a/code/renderergl2/tr_shade.c b/code/renderergl2/tr_shade.c
index 0fd1548..b0ca862 100644
--- a/code/renderergl2/tr_shade.c
+++ b/code/renderergl2/tr_shade.c
@@ -66,7 +66,6 @@ R_BindAnimatedImageToTMU
 */
 static void R_BindAnimatedImageToTMU( textureBundle_t *bundle, int tmu ) {
 	int64_t index;
-	double	v;
 
 	if ( bundle->isVideoMap ) {
 		ri.CIN_RunCinematic(bundle->videoMapHandle);
@@ -82,10 +81,8 @@ static void R_BindAnimatedImageToTMU( textureBundle_t *bundle, int tmu ) {
 
 	// it is necessary to do this messy calc to make sure animations line up
 	// exactly with waveforms of the same frequency
-	//index = ri.ftol(tess.shaderTime * bundle->imageAnimationSpeed * FUNCTABLE_SIZE);
-	//index >>= FUNCTABLE_SIZE2;
-	v = tess.shaderTime * bundle->imageAnimationSpeed;
-	index = v;
+	index = tess.shaderTime * bundle->imageAnimationSpeed * FUNCTABLE_SIZE;
+	index >>= FUNCTABLE_SIZE2;
 
 	if ( index < 0 ) {
 		index = 0;	// may happen with shader time offsets
diff --git a/code/renderergl2/tr_shade_calc.c b/code/renderergl2/tr_shade_calc.c
index c411e03..8369ad7 100644
--- a/code/renderergl2/tr_shade_calc.c
+++ b/code/renderergl2/tr_shade_calc.c
@@ -27,7 +27,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #endif
 
 
-#define	WAVEVALUE( table, base, amplitude, phase, freq )  ((base) + table[ (int)( ( ( (phase) + tess.shaderTime * (freq) ) * FUNCTABLE_SIZE ) ) & FUNCTABLE_MASK ] * (amplitude))
+#define	WAVEVALUE( table, base, amplitude, phase, freq )  ((base) + table[ ( (int64_t) ( ( (phase) + tess.shaderTime * (freq) ) * FUNCTABLE_SIZE ) ) & FUNCTABLE_MASK ] * (amplitude))
 
 static float *TableForFunc( genFunc_t func ) 
 {
@@ -204,12 +204,12 @@ void RB_CalcBulgeVertexes( deformStage_t *ds ) {
 	const float *st = ( const float * ) tess.texCoords[0];
 	float		*xyz = ( float * ) tess.xyz;
 	int16_t	*normal = tess.normal[0];
-	float		now;
+	double		now;
 
-	now = backEnd.refdef.time * ds->bulgeSpeed * 0.001f;
+	now = backEnd.refdef.time * 0.001 * ds->bulgeSpeed;
 
 	for ( i = 0; i < tess.numVertexes; i++, xyz += 4, st += 2, normal += 4 ) {
-		int		off;
+		int64_t off;
 		float scale;
 		vec3_t fNormal;
 
@@ -776,18 +776,16 @@ void RB_CalcScaleTexMatrix( const float scale[2], float *matrix )
 */
 void RB_CalcScrollTexMatrix( const float scrollSpeed[2], float *matrix )
 {
-	double timeScale;
+	double timeScale = tess.shaderTime;
 	double adjustedScrollS, adjustedScrollT;
 
-	timeScale = tess.shaderTime;
-
 	adjustedScrollS = scrollSpeed[0] * timeScale;
 	adjustedScrollT = scrollSpeed[1] * timeScale;
 
 	// clamp so coordinates don't continuously get larger, causing problems
 	// with hardware limits
-	adjustedScrollS = (double)adjustedScrollS - floor( adjustedScrollS );
-	adjustedScrollT = (double)adjustedScrollT - floor( adjustedScrollT );
+	adjustedScrollS = adjustedScrollS - floor( adjustedScrollS );
+	adjustedScrollT = adjustedScrollT - floor( adjustedScrollT );
 
 	matrix[0] = 1.0f; matrix[2] = 0.0f; matrix[4] = adjustedScrollS;
 	matrix[1] = 0.0f; matrix[3] = 1.0f; matrix[5] = adjustedScrollT;

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/ioquake3.git



More information about the Pkg-games-commits mailing list