filename | test/testta.c |
changeset | 754:35c496703380 |
prev | 561:533f6b478071 |
author | nkeynes |
date | Sat Dec 27 02:59:35 2008 +0000 (15 years ago) |
branch | lxdream-mem |
permissions | -rw-r--r-- |
last change | Replace fpscr_mask/fpscr flags in xlat_cache_block with a single xlat_sh4_mode, which tracks the field of the same name in sh4r - actually a little faster this way. Now depends on SR.MD, FPSCR.PR and FPSCR.SZ (although it doesn't benefit from the SR flag yet). Also fixed the failure to check the flags in the common case (code address returned by previous block) which took away the performance benefits, but oh well. |
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 }
.