Search
lxdream.org :: lxdream/test/testta.c
lxdream 0.9.1
released Jun 29
Download Now
filename test/testta.c
changeset 754:35c496703380
prev561:533f6b478071
author nkeynes
date Wed Dec 02 10:36:49 2009 +1000 (14 years ago)
permissions -rw-r--r--
last change Add missing SUBV instruction to the emulation core (translation core is ok),
along with test cases. Thanks to D. Jeff Dionne for pointing this out.
view annotate diff log raw
     1 /**
     2  * $Id$
     3  * 
     4  * Tile Accelerator test cases 
     5  *
     6  * Copyright (c) 2006 Nathan Keynes.
     7  *
     8  * This program is free software; you can redistribute it and/or modify
     9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  * GNU General Public License for more details.
    17  */
    19 #include <stdio.h>
    20 #include "testdata.h"
    21 #include "pvr.h"
    22 #include "lib.h"
    23 #include "asic.h"
    25 #define DMA_ALIGN(x)   ((void *)((((unsigned int)(x))+0x1F)&0xFFFFFFE0))
    27 #define OBJ_START 0x00010000
    28 #define OBJ_LENGTH 0x00010000
    29 #define TILE_START 0x00060000
    30 #define TILE_LENGTH 0x00010000
    32 #define MEM_FILL 0xFE
    34 int ta_tile_sizes[4] = { 0, 32, 64, 128 };
    36 #define TILE_SIZE(cfg, tile) ta_tile_sizes[((((cfg->ta_cfg) >> (4*tile))&0x03))]
    38 struct ta_config default_ta_config = { 0x00111111, GRID_SIZE(640,480), OBJ_START,
    39 				       OBJ_START+OBJ_LENGTH, TILE_START+TILE_LENGTH,
    40 				       TILE_START, TILE_START+TILE_LENGTH };
    43 int tile_sizes[5];
    44 int tile_events[5] = { EVENT_PVR_OPAQUE_DONE, EVENT_PVR_OPAQUEMOD_DONE,
    45 		       EVENT_PVR_TRANS_DONE, EVENT_PVR_TRANSMOD_DONE,
    46 		       EVENT_PVR_PUNCHOUT_DONE };
    47 char *tile_names[5] = { "Opaque", "Opaque Mod", "Trans", "Trans Mod", "Punch Out" };
    49 #define FLOAT(p) *((float *)(p))
    51 void make_expected_buffer( test_data_block_t expected_block, char *expect, int length )
    52 {
    53     memset( expect, MEM_FILL,length );
    55     if( expected_block != NULL ) {
    56 	if( expected_block->length > length ) {
    57 	    fprintf( stderr, "Test data error: expected tile length is %d, but tile size is only %d\n", expected_block->length, length );
    58 	    return;
    59 	}
    60 	memcpy( expect, expected_block->data, expected_block->length );
    62 	if( expected_block->length <= length-4 ) {
    63 	    *((unsigned int *)&expect[expected_block->length]) = 0xF0000000;
    64 	}
    65     }
    66 }
    68 int tilematrix_block_compare( test_data_block_t expected_block, char *tile_ptrs[], int tile_type, int offset )
    69 {
    70     int tile_size = tile_sizes[tile_type];
    71     char expect[tile_size];
    73     make_expected_buffer(expected_block, expect, tile_size);
    74     return memcmp( expect, tile_ptrs[tile_type]+(offset*tile_sizes[tile_type]), tile_size );
    75 }
    77 /**
    78  * Copy from vram, wrapping appropriately 
    79  */
    80 int memcpy_from_vram( char *dest, char *src, int len ) 
    81 {
    82     while( len > 0 ) {
    83 	*dest++ = *src++;
    84 	src = (char *)( ((unsigned int)src) & 0xFF7FFFFF );
    85 	len--;
    86     }
    87 }
    89 int test_ta( test_data_t test_case )
    90 {
    91     char buf[1024];
    92     unsigned int *p = DMA_ALIGN(buf);
    93     unsigned int *data = p;
    94     int haveFailure = 0;
    95     int checkedTile[5] = {0,0,0,0,0};
    96     int i;
    97     int hsegs,vsegs;
    98     char *tile_ptrs[5];
   100     asic_clear();
   102     memset( PVR_VRAM_BASE, MEM_FILL,  0x00090000 );
   103     test_data_block_t config_data = get_test_data( test_case, "config" );
   104     struct ta_config *config = &default_ta_config;
   105     if( config_data != NULL ) {
   106 	if( config_data->length != sizeof(struct ta_config) ) {
   107 	    fprintf( stderr, "Invalid config data length %d - aborting test %s\n",
   108 		     config_data->length, test_case->test_name );
   109 	    return -1;
   110 	}
   111 	config = (struct ta_config *)config_data->data;
   112     }
   113     char *result = (char *)(PVR_VRAM_BASE+config->obj_start);
   114     char *tilematrix = (char *)(PVR_VRAM_BASE+config->tile_start);
   116     ta_init(config);
   117     for( i=0; i<5; i++ ) {
   118 	tile_sizes[i] = TILE_SIZE(config,i);
   119     }
   120     hsegs = (config->grid_size & 0xFFFF)+1;
   121     vsegs = (config->grid_size >> 16) + 1;
   122     tile_ptrs[0] = tilematrix;
   123     tile_ptrs[1] = tile_ptrs[0] + (hsegs*vsegs*tile_sizes[0]);
   124     tile_ptrs[2] = tile_ptrs[1] + (hsegs*vsegs*tile_sizes[1]);
   125     tile_ptrs[3] = tile_ptrs[2] + (hsegs*vsegs*tile_sizes[2]);
   126     tile_ptrs[4] = tile_ptrs[3] + (hsegs*vsegs*tile_sizes[3]);
   129     test_data_block_t input = get_test_data(test_case, "input");
   130     test_data_block_t input2 = get_test_data(test_case, "input2");
   131     test_data_block_t output = get_test_data(test_case, "output");
   132     test_data_block_t error = get_test_data(test_case, "error");
   133     test_data_block_t sortconf = get_test_data(test_case, "sortconf");
   134     test_data_block_t sorttab = get_test_data(test_case, "sorttab");
   136     if( input == NULL || output == NULL ) {
   137 	fprintf( stderr, "Skipping test case '%s': data incomplete\n", test_case->test_name );
   138 	return -1;
   139     }
   141     if( sortconf != NULL && sorttab != NULL ) {
   142         if( sortconf->length != 8 ) {
   143             fprintf( stderr, "Invalid sort config length: %d - abort test %s\n", 
   144                      sortconf->length, test_case->test_name );
   145             return -1;
   146         }
   147         uint32_t *sc = (uint32_t *)sortconf->data;
   148         if( sort_dma_write( sorttab->data, sorttab->length, input->data, input->length, *sc, *(sc+1) ) == -1 ){
   149             return -1;
   150         }
   151     } else {
   152         if( pvr_dma_write( 0x10000000, input->data, input->length, 0 ) == -1 ) {
   153             return -1;
   154         }
   155     }
   157     if( input2 != NULL ) {
   158         ta_reinit();
   159         pvr_dma_write( 0x10000000, input2->data, input2->length, 0 );
   160     }
   163     if( error != NULL ) {
   164 	for( i=0; i<error->length; i++ ) {
   165 	    if( asic_wait( error->data[i] ) == -1 ) {
   166 		fprintf( stderr, "Test %s: failed (Timeout waiting for error event %d)\n",
   167 			 test_case->test_name, error->data[i] );
   168 		asic_dump( stderr );
   169 		return -1;
   170 	    }
   171 	}
   172     }
   174     for( i=0; i<MAX_DATA_BLOCKS; i++ ) {
   175 	test_data_block_t data = &test_case->item[i];
   176 	int tile, x, y, offset;
   177 	if( data->name != NULL ) {
   178 	    int result = sscanf( data->name, "tile %d %dx%d", &tile, &x, &y );
   179 	    if( result == 1 ) {
   180 		x = y = 0;
   181 	    } else if( result != 3 ) {
   182 		continue;
   183 	    }
   184 	    tile--;
   185 	    offset = x + (y * hsegs);
   187 	    if( checkedTile[tile] == 0 ) {
   188 		if( asic_wait( tile_events[tile] ) == -1 ) {
   189 		    fprintf( stderr, "Test %s: failed (Timeout waiting for %s done event)\n", 
   190 			     test_case->test_name, tile_names[tile] );
   191 		    ta_dump_regs();
   192 		    asic_dump( stderr );
   193 		    haveFailure = 1;
   194 		}
   195 	    }
   197 	    if( tilematrix_block_compare( data, tile_ptrs, tile, offset ) != 0 ) {
   198 		fprintf( stderr, "Test %s: Failed (%s matrix %dx%d). ", 
   199 			 test_case->test_name, tile_names[tile], x, y );
   200 		fwrite_diff32( stderr, data->data, data->length, 
   201 			       tile_ptrs[tile] + (tile_sizes[tile]*offset), tile_sizes[tile] );
   202 		haveFailure = 1;
   203 	    }
   204 	    checkedTile[tile] = 1;
   205 	}
   206     }
   208     /* Overflow */
   209     test_data_block_t plist = get_test_data(test_case, "plist" );
   210     if( plist != NULL ) {
   211 	unsigned int plist_posn, plist_end;
   212 	if( config->ta_cfg & 0x00100000 ) { /* Descending */
   213 	    plist_posn = pvr_get_plist_posn(); //+ tile_sizes[0];
   214 	    plist_end = config->plist_start;
   215 	} else {
   216 	    plist_posn = config->plist_start;
   217 	    plist_end = pvr_get_plist_posn() + tile_sizes[0];
   218 	}
   219 	char *plist_data = (char *)(PVR_VRAM_BASE + plist_posn);
   220 	if( test_block_compare( plist, plist_data, plist_end-plist_posn ) != 0 ) {
   221 	    fprintf( stderr, "Test %s: Failed (Plist buffer)", test_case->test_name );
   222 	    fwrite_diff32( stderr, plist->data, plist->length, (char *)plist_data, 
   223 			   plist_end - plist_posn );
   224 	    haveFailure = 1;
   225 	}
   226 	char block[tile_sizes[0]];
   227 	memset( block, MEM_FILL, tile_sizes[0] );
   228 	if( memcmp( block, plist_data - tile_sizes[0], tile_sizes[0] ) != 0 ) {
   229 	    fprintf( stderr, "Test %s: Failed (Plist buffer)", test_case->test_name );
   230 	    fwrite_diff32( stderr, block, tile_sizes[0], plist_data - tile_sizes[0],
   231 			   tile_sizes[0]);
   232 	    haveFailure = 1;
   233 	}
   234     }
   236     /* Vertex buffer */
   237     int result_length = pvr_get_objbuf_size();
   238     char tmp[result_length];
   239     memcpy_from_vram( tmp, result, result_length );
   240     if( test_block_compare( output, tmp, result_length ) != 0 ) {
   241 	fprintf( stderr, "Test %s: Failed (Vertex buffer). ", test_case->test_name );
   242 	fwrite_diff32( stderr, output->data, output->length, tmp, result_length );
   243 	haveFailure = 1;
   244     }
   247     for( i=0; i<5; i++ ) {
   248 	if( checkedTile[i] == 0 ) {
   249 	    if( tilematrix_block_compare( NULL, tile_ptrs, i, 0 ) != 0 ) {
   250 		fprintf( stderr, "Test %s: Failed (%s matrix). ", test_case->test_name, tile_names[i] );
   251                 fprintf( stderr, "Expected empty buffer at %08X, but was =>\n", 
   252 			 (unsigned int)(tile_ptrs[i]) );
   253 		fwrite_dump( stderr, tile_ptrs[i], tile_sizes[i] );
   254 		//		fwrite_dump( stderr, tile_ptrs[i] - 128, 256 );
   256 	    }
   257 	}
   258     }
   260     if( error == NULL ) {
   261 	if( asic_check(EVENT_TA_ERROR) || asic_check(EVENT_PVR_PRIM_ALLOC_FAIL) ||
   262 	    asic_check(EVENT_PVR_MATRIX_ALLOC_FAIL) || asic_check(EVENT_PVR_BAD_INPUT) ) {
   263 	    fprintf( stderr, "Test %s: Failed (unexpected error events)\n", test_case->test_name );
   264 	    asic_dump( stderr );
   265 	    haveFailure = 1;
   266 	}
   267     }
   269     if( haveFailure )
   270 	return -1;
   272     fprintf( stdout, "Test %s: OK\n", test_case->test_name );
   273     return 0;
   274 }
   276 int main( int argc, char *argv[] ) 
   277 {
   278     int test_cases = 0;
   279     int test_failures = 0;
   280     test_data_t test_data = load_test_dataset(stdin);
   281     test_data_t test_case = test_data;
   283     asic_mask_all();
   284     pvr_init();
   286     while( test_case != NULL ) {
   287 	test_cases++;
   288 	int result = test_ta(test_case);
   289 	if( result != 0 ) {
   290 	    test_failures++;
   291 	}
   292 	test_case = test_case->next;
   293     }
   294     free_test_dataset(test_data);
   295     if( test_failures != 0 ) {
   296 	fprintf( stderr, "%d/%d test failures!\n", test_failures, test_cases );
   297 	return 1;
   298     } else {
   299 	fprintf( stderr, "%d tests OK\n", test_cases );
   300 	return 0;
   301     }
   302 }
.