static int test_cliptest_function( clip_func func, int np, int psize, long *cycles ) { GLvector4f source[1], dest[1], ref[1]; GLubyte dm[TEST_COUNT], dco, dca; GLubyte rm[TEST_COUNT], rco, rca; int i, j; #ifdef RUN_DEBUG_BENCHMARK int cycle_i; /* the counter for the benchmarks we run */ #endif GLboolean viewport_z_clip = GL_TRUE; (void) cycles; if ( psize > 4 ) { _mesa_problem( NULL, "test_cliptest_function called with psize > 4\n" ); return 0; } for ( i = 0 ; i < TEST_COUNT ; i++) { ASSIGN_4V( d[i], 0.0, 0.0, 0.0, 1.0 ); ASSIGN_4V( s[i], 0.0, 0.0, 0.0, 1.0 ); for ( j = 0 ; j < psize ; j++ ) s[i][j] = rnd(); } source->data = (GLfloat(*)[4])s; source->start = (GLfloat *)s; source->count = TEST_COUNT; source->stride = sizeof(s[0]); source->size = 4; source->flags = 0; dest->data = (GLfloat(*)[4])d; dest->start = (GLfloat *)d; dest->count = TEST_COUNT; dest->stride = sizeof(float[4]); dest->size = 0; dest->flags = 0; ref->data = (GLfloat(*)[4])r; ref->start = (GLfloat *)r; ref->count = TEST_COUNT; ref->stride = sizeof(float[4]); ref->size = 0; ref->flags = 0; dco = rco = 0; dca = rca = CLIP_FRUSTUM_BITS; ref_cliptest[psize]( source, ref, rm, &rco, &rca, viewport_z_clip ); if ( mesa_profile ) { BEGIN_RACE( *cycles ); func( source, dest, dm, &dco, &dca, viewport_z_clip ); END_RACE( *cycles ); } else { func( source, dest, dm, &dco, &dca, viewport_z_clip ); } if ( dco != rco ) { printf( "\n-----------------------------\n" ); printf( "dco = 0x%02x rco = 0x%02x\n", dco, rco ); return 0; } if ( dca != rca ) { printf( "\n-----------------------------\n" ); printf( "dca = 0x%02x rca = 0x%02x\n", dca, rca ); return 0; } for ( i = 0 ; i < TEST_COUNT ; i++ ) { if ( dm[i] != rm[i] ) { GLfloat *c = source->start; STRIDE_F(c, source->stride * i); if (psize == 4 && xyz_close_to_w(c)) { /* The coordinate is very close to the clip plane. The clipmask * may vary depending on code path, but that's OK. */ continue; } printf( "\n-----------------------------\n" ); printf( "mask[%d] = 0x%02x ref mask[%d] = 0x%02x\n", i, dm[i], i,rm[i] ); printf(" coord = %f, %f, %f, %f\n", c[0], c[1], c[2], c[3]); return 0; } } /* Only verify output on projected points4 case. FIXME: Do we need * to test other cases? */ if ( np || psize < 4 ) return 1; for ( i = 0 ; i < TEST_COUNT ; i++ ) { for ( j = 0 ; j < 4 ; j++ ) { if ( significand_match( d[i][j], r[i][j] ) < REQUIRED_PRECISION ) { printf( "\n-----------------------------\n" ); printf( "(i = %i, j = %i) dm = 0x%02x rm = 0x%02x\n", i, j, dm[i], rm[i] ); printf( "%f \t %f \t [diff = %e - %i bit missed]\n", d[i][0], r[i][0], r[i][0]-d[i][0], MAX_PRECISION - significand_match( d[i][0], r[i][0] ) ); printf( "%f \t %f \t [diff = %e - %i bit missed]\n", d[i][1], r[i][1], r[i][1]-d[i][1], MAX_PRECISION - significand_match( d[i][1], r[i][1] ) ); printf( "%f \t %f \t [diff = %e - %i bit missed]\n", d[i][2], r[i][2], r[i][2]-d[i][2], MAX_PRECISION - significand_match( d[i][2], r[i][2] ) ); printf( "%f \t %f \t [diff = %e - %i bit missed]\n", d[i][3], r[i][3], r[i][3]-d[i][3], MAX_PRECISION - significand_match( d[i][3], r[i][3] ) ); return 0; } } } return 1; }
static int test_norm_function( normal_func func, int mtype, int masked, long *cycles ) { GLvector3f source[1], dest[1], dest2[1], ref[1], ref2[1]; GLmatrix mat[1]; GLfloat s[TEST_COUNT][5], d[TEST_COUNT][3], r[TEST_COUNT][3]; GLfloat d2[TEST_COUNT][3], r2[TEST_COUNT][3], length[TEST_COUNT]; GLfloat scale; GLfloat *m; GLubyte mask[TEST_COUNT]; int i, j; #ifdef RUN_XFORM_BENCHMARK int cycle_i; /* the counter for the benchmarks we run */ #endif (void) cycles; mat->m = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 ); mat->inv = m = mat->m; m[0] = 63.0; m[4] = 43.0; m[ 8] = 29.0; m[12] = 43.0; m[1] = 55.0; m[5] = 17.0; m[ 9] = 31.0; m[13] = 7.0; m[2] = 44.0; m[6] = 9.0; m[10] = 7.0; m[14] = 3.0; m[3] = 11.0; m[7] = 23.0; m[11] = 91.0; m[15] = 9.0; scale = 1.0F + rnd () * norm_scale_types[mtype]; for ( i = 0 ; i < 4 ; i++ ) { for ( j = 0 ; j < 4 ; j++ ) { switch ( norm_templates[mtype][i * 4 + j] ) { case NIL: m[j * 4 + i] = 0.0; break; case ONE: m[j * 4 + i] = 1.0; break; case NEG: m[j * 4 + i] = -1.0; break; case VAR: break; default: abort(); } } } for ( i = 0 ; i < TEST_COUNT ; i++ ) { mask[i] = i % 2; /* mask every 2nd element */ d[i][0] = s[i][0] = d2[i][0] = 0.0; d[i][1] = s[i][1] = d2[i][1] = 0.0; d[i][2] = s[i][2] = d2[i][2] = 0.0; for ( j = 0 ; j < 3 ; j++ ) s[i][j] = rnd(); length[i] = 1 / sqrt( s[i][0]*s[i][0] + s[i][1]*s[i][1] + s[i][2]*s[i][2] ); } source->data = (GLfloat(*)[3])s; source->start = (GLfloat *)s; source->count = TEST_COUNT; source->stride = sizeof(s[0]); source->flags = 0; dest->data = (GLfloat(*)[3])d; dest->start = (GLfloat *)d; dest->count = TEST_COUNT; dest->stride = sizeof(float[3]); dest->flags = 0; dest2->data = (GLfloat(*)[3])d2; dest2->start = (GLfloat *)d2; dest2->count = TEST_COUNT; dest2->stride = sizeof(float[3]); dest2->flags = 0; ref->data = (GLfloat(*)[3])r; ref->start = (GLfloat *)r; ref->count = TEST_COUNT; ref->stride = sizeof(float[3]); ref->flags = 0; ref2->data = (GLfloat(*)[3])r2; ref2->start = (GLfloat *)r2; ref2->count = TEST_COUNT; ref2->stride = sizeof(float[3]); ref2->flags = 0; if ( norm_normalize_types[mtype] == 0 ) { ref_norm_transform_rescale( mat, scale, source, NULL, NULL, ref ); } else { ref_norm_transform_normalize( mat, scale, source, NULL, NULL, ref ); ref_norm_transform_normalize( mat, scale, source, length, NULL, ref2 ); } if ( mesa_profile ) { if ( masked ) { BEGIN_RACE( *cycles ); func( mat, scale, source, NULL, mask, dest ); END_RACE( *cycles ); func( mat, scale, source, length, mask, dest2 ); } else { BEGIN_RACE( *cycles ); func( mat, scale, source, NULL, NULL, dest ); END_RACE( *cycles ); func( mat, scale, source, length, NULL, dest2 ); } } else { if ( masked ) { func( mat, scale, source, NULL, mask, dest ); func( mat, scale, source, length, mask, dest2 ); } else { func( mat, scale, source, NULL, NULL, dest ); func( mat, scale, source, length, NULL, dest2 ); } } for ( i = 0 ; i < TEST_COUNT ; i++ ) { if ( masked && !(mask[i] & 1) ) continue; for ( j = 0 ; j < 3 ; j++ ) { if ( significand_match( d[i][j], r[i][j] ) < REQUIRED_PRECISION ) { printf( "-----------------------------\n" ); printf( "(i = %i, j = %i)\n", i, j ); printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", d[i][0], r[i][0], r[i][0]/d[i][0], MAX_PRECISION - significand_match( d[i][0], r[i][0] ) ); printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", d[i][1], r[i][1], r[i][1]/d[i][1], MAX_PRECISION - significand_match( d[i][1], r[i][1] ) ); printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", d[i][2], r[i][2], r[i][2]/d[i][2], MAX_PRECISION - significand_match( d[i][2], r[i][2] ) ); return 0; } if ( norm_normalize_types[mtype] != 0 ) { if ( significand_match( d2[i][j], r2[i][j] ) < REQUIRED_PRECISION ) { printf( "------------------- precalculated length case ------\n" ); printf( "(i = %i, j = %i)\n", i, j ); printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", d2[i][0], r2[i][0], r2[i][0]/d2[i][0], MAX_PRECISION - significand_match( d2[i][0], r2[i][0] ) ); printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", d2[i][1], r2[i][1], r2[i][1]/d2[i][1], MAX_PRECISION - significand_match( d2[i][1], r2[i][1] ) ); printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", d2[i][2], r2[i][2], r2[i][2]/d2[i][2], MAX_PRECISION - significand_match( d2[i][2], r2[i][2] ) ); return 0; } } } } ALIGN_FREE( mat->m ); return 1; }
static int test_transform_function( transform_func func, int psize, int mtype, unsigned long *cycles ) { GLvector4f source[1], dest[1], ref[1]; GLmatrix mat[1]; GLfloat *m; int i, j; #ifdef RUN_DEBUG_BENCHMARK int cycle_i; /* the counter for the benchmarks we run */ #endif (void) cycles; if ( psize > 4 ) { _mesa_problem( NULL, "test_transform_function called with psize > 4\n" ); return 0; } mat->m = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 ); mat->type = mtypes[mtype]; m = mat->m; ASSERT( ((long)m & 15) == 0 ); init_matrix( m ); for ( i = 0 ; i < 4 ; i++ ) { for ( j = 0 ; j < 4 ; j++ ) { switch ( templates[mtype][i * 4 + j] ) { case NIL: m[j * 4 + i] = 0.0; break; case ONE: m[j * 4 + i] = 1.0; break; case NEG: m[j * 4 + i] = -1.0; break; case VAR: break; default: ASSERT(0); return 0; } } } for ( i = 0 ; i < TEST_COUNT ; i++) { ASSIGN_4V( d[i], 0.0, 0.0, 0.0, 1.0 ); ASSIGN_4V( s[i], 0.0, 0.0, 0.0, 1.0 ); for ( j = 0 ; j < psize ; j++ ) s[i][j] = rnd(); } source->data = (GLfloat(*)[4])s; source->start = (GLfloat *)s; source->count = TEST_COUNT; source->stride = sizeof(s[0]); source->size = 4; source->flags = 0; dest->data = (GLfloat(*)[4])d; dest->start = (GLfloat *)d; dest->count = TEST_COUNT; dest->stride = sizeof(float[4]); dest->size = 0; dest->flags = 0; ref->data = (GLfloat(*)[4])r; ref->start = (GLfloat *)r; ref->count = TEST_COUNT; ref->stride = sizeof(float[4]); ref->size = 0; ref->flags = 0; ref_transform( ref, mat, source ); if ( mesa_profile ) { BEGIN_RACE( *cycles ); func( dest, mat->m, source ); END_RACE( *cycles ); } else { func( dest, mat->m, source ); } for ( i = 0 ; i < TEST_COUNT ; i++ ) { for ( j = 0 ; j < 4 ; j++ ) { if ( significand_match( d[i][j], r[i][j] ) < REQUIRED_PRECISION ) { _mesa_printf("-----------------------------\n" ); _mesa_printf("(i = %i, j = %i)\n", i, j ); _mesa_printf("%f \t %f \t [diff = %e - %i bit missed]\n", d[i][0], r[i][0], r[i][0]-d[i][0], MAX_PRECISION - significand_match( d[i][0], r[i][0] ) ); _mesa_printf("%f \t %f \t [diff = %e - %i bit missed]\n", d[i][1], r[i][1], r[i][1]-d[i][1], MAX_PRECISION - significand_match( d[i][1], r[i][1] ) ); _mesa_printf("%f \t %f \t [diff = %e - %i bit missed]\n", d[i][2], r[i][2], r[i][2]-d[i][2], MAX_PRECISION - significand_match( d[i][2], r[i][2] ) ); _mesa_printf("%f \t %f \t [diff = %e - %i bit missed]\n", d[i][3], r[i][3], r[i][3]-d[i][3], MAX_PRECISION - significand_match( d[i][3], r[i][3] ) ); return 0; } } } ALIGN_FREE( mat->m ); return 1; }
static int test_transform_function( transform_func func, int psize, int mtype, int masked, long *cycles ) { GLvector4f source[1], dest[1], ref[1]; GLmatrix mat[1]; GLfloat *m; GLubyte mask[TEST_COUNT]; int i, j; #ifdef RUN_XFORM_BENCHMARK int cycle_i; /* the counter for the benchmarks we run */ #endif (void) cycles; if ( psize > 4 ) { gl_problem( NULL, "test_transform_function called with psize > 4\n" ); return 0; } mat->m = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 ); mat->type = mtypes[mtype]; m = mat->m; m[0] = 63.0; m[4] = 43.0; m[ 8] = 29.0; m[12] = 43.0; m[1] = 55.0; m[5] = 17.0; m[ 9] = 31.0; m[13] = 7.0; m[2] = 44.0; m[6] = 9.0; m[10] = 7.0; m[14] = 3.0; m[3] = 11.0; m[7] = 23.0; m[11] = 91.0; m[15] = 9.0; for ( i = 0 ; i < 4 ; i++ ) { for ( j = 0 ; j < 4 ; j++ ) { switch ( templates[mtype][i * 4 + j] ) { case NIL: m[j * 4 + i] = 0.0; break; case ONE: m[j * 4 + i] = 1.0; break; case NEG: m[j * 4 + i] = -1.0; break; case VAR: break; default: abort(); } } } for ( i = 0 ; i < TEST_COUNT ; i++) { mask[i] = i % 2; /* mask every 2nd element */ d[i][0] = s[i][0] = 0.0; d[i][1] = s[i][1] = 0.0; d[i][2] = s[i][2] = 0.0; d[i][3] = s[i][3] = 1.0; for ( j = 0 ; j < psize ; j++ ) s[i][j] = rnd(); } source->data = (GLfloat(*)[4])s; source->start = (GLfloat *)s; source->count = TEST_COUNT; source->stride = sizeof(s[0]); source->size = 4; source->flags = 0; dest->data = (GLfloat(*)[4])d; dest->start = (GLfloat *)d; dest->count = TEST_COUNT; dest->stride = sizeof(float[4]); dest->size = 0; dest->flags = 0; ref->data = (GLfloat(*)[4])r; ref->start = (GLfloat *)r; ref->count = TEST_COUNT; ref->stride = sizeof(float[4]); ref->size = 0; ref->flags = 0; ref_transform( ref, mat, source, NULL, 0 ); if ( mesa_profile ) { if ( masked ) { BEGIN_RACE( *cycles ); func( dest, mat->m, source, mask, 1 ); END_RACE( *cycles ); } else { BEGIN_RACE( *cycles ); func( dest, mat->m, source, NULL, 0 ); END_RACE( *cycles ); } } else { if ( masked ) { func( dest, mat->m, source, mask, 1 ); } else { func( dest, mat->m, source, NULL, 0 ); } } for ( i = 0 ; i < TEST_COUNT ; i++ ) { if ( masked && (mask[i] & 1) ) continue; for ( j = 0 ; j < 4 ; j++ ) { if ( significand_match( d[i][j], r[i][j] ) < REQUIRED_PRECISION ) { printf( "-----------------------------\n" ); printf( "(i = %i, j = %i)\n", i, j ); printf( "%f \t %f \t [diff = %e - %i bit missed]\n", d[i][0], r[i][0], r[i][0]-d[i][0], MAX_PRECISION - significand_match( d[i][0], r[i][0] ) ); printf( "%f \t %f \t [diff = %e - %i bit missed]\n", d[i][1], r[i][1], r[i][1]-d[i][1], MAX_PRECISION - significand_match( d[i][1], r[i][1] ) ); printf( "%f \t %f \t [diff = %e - %i bit missed]\n", d[i][2], r[i][2], r[i][2]-d[i][2], MAX_PRECISION - significand_match( d[i][2], r[i][2] ) ); printf( "%f \t %f \t [diff = %e - %i bit missed]\n", d[i][3], r[i][3], r[i][3]-d[i][3], MAX_PRECISION - significand_match( d[i][3], r[i][3] ) ); return 0; } } } ALIGN_FREE( mat->m ); return 1; }
static int test_norm_function( normal_func func, int mtype, long *cycles ) { GLvector4f source[1], dest[1], dest2[1], ref[1], ref2[1]; GLmatrix mat[1]; GLfloat s[TEST_COUNT][5], d[TEST_COUNT][4], r[TEST_COUNT][4]; GLfloat d2[TEST_COUNT][4], r2[TEST_COUNT][4], length[TEST_COUNT]; GLfloat scale; GLfloat *m; int i, j; #ifdef RUN_DEBUG_BENCHMARK int cycle_i; /* the counter for the benchmarks we run */ #endif (void) cycles; mat->m = (GLfloat *) _mesa_align_malloc( 16 * sizeof(GLfloat), 16 ); mat->inv = m = mat->m; init_matrix( m ); scale = 1.0F + rnd () * norm_scale_types[mtype]; for ( i = 0 ; i < 4 ; i++ ) { for ( j = 0 ; j < 4 ; j++ ) { switch ( norm_templates[mtype][i * 4 + j] ) { case NIL: m[j * 4 + i] = 0.0; break; case ONE: m[j * 4 + i] = 1.0; break; case NEG: m[j * 4 + i] = -1.0; break; case VAR: break; default: exit(1); } } } for ( i = 0 ; i < TEST_COUNT ; i++ ) { ASSIGN_3V( d[i], 0.0, 0.0, 0.0 ); ASSIGN_3V( s[i], 0.0, 0.0, 0.0 ); ASSIGN_3V( d2[i], 0.0, 0.0, 0.0 ); for ( j = 0 ; j < 3 ; j++ ) s[i][j] = rnd(); length[i] = 1 / SQRTF( LEN_SQUARED_3FV( s[i] ) ); } source->data = (GLfloat(*)[4]) s; source->start = (GLfloat *) s; source->count = TEST_COUNT; source->stride = sizeof(s[0]); source->flags = 0; dest->data = d; dest->start = (GLfloat *) d; dest->count = TEST_COUNT; dest->stride = sizeof(float[4]); dest->flags = 0; dest2->data = d2; dest2->start = (GLfloat *) d2; dest2->count = TEST_COUNT; dest2->stride = sizeof(float[4]); dest2->flags = 0; ref->data = r; ref->start = (GLfloat *) r; ref->count = TEST_COUNT; ref->stride = sizeof(float[4]); ref->flags = 0; ref2->data = r2; ref2->start = (GLfloat *) r2; ref2->count = TEST_COUNT; ref2->stride = sizeof(float[4]); ref2->flags = 0; if ( norm_normalize_types[mtype] == 0 ) { ref_norm_transform_rescale( mat, scale, source, NULL, ref ); } else { ref_norm_transform_normalize( mat, scale, source, NULL, ref ); ref_norm_transform_normalize( mat, scale, source, length, ref2 ); } if ( mesa_profile ) { BEGIN_RACE( *cycles ); func( mat, scale, source, NULL, dest ); END_RACE( *cycles ); func( mat, scale, source, length, dest2 ); } else { func( mat, scale, source, NULL, dest ); func( mat, scale, source, length, dest2 ); } for ( i = 0 ; i < TEST_COUNT ; i++ ) { for ( j = 0 ; j < 3 ; j++ ) { if ( significand_match( d[i][j], r[i][j] ) < REQUIRED_PRECISION ) { printf( "-----------------------------\n" ); printf( "(i = %i, j = %i)\n", i, j ); printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", d[i][0], r[i][0], r[i][0]/d[i][0], MAX_PRECISION - significand_match( d[i][0], r[i][0] ) ); printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", d[i][1], r[i][1], r[i][1]/d[i][1], MAX_PRECISION - significand_match( d[i][1], r[i][1] ) ); printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", d[i][2], r[i][2], r[i][2]/d[i][2], MAX_PRECISION - significand_match( d[i][2], r[i][2] ) ); return 0; } if ( norm_normalize_types[mtype] != 0 ) { if ( significand_match( d2[i][j], r2[i][j] ) < REQUIRED_PRECISION ) { printf( "------------------- precalculated length case ------\n" ); printf( "(i = %i, j = %i)\n", i, j ); printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", d2[i][0], r2[i][0], r2[i][0]/d2[i][0], MAX_PRECISION - significand_match( d2[i][0], r2[i][0] ) ); printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", d2[i][1], r2[i][1], r2[i][1]/d2[i][1], MAX_PRECISION - significand_match( d2[i][1], r2[i][1] ) ); printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", d2[i][2], r2[i][2], r2[i][2]/d2[i][2], MAX_PRECISION - significand_match( d2[i][2], r2[i][2] ) ); return 0; } } } } _mesa_align_free( mat->m ); return 1; }