filename | test/testta.c |
changeset | 754:35c496703380 |
prev | 561:533f6b478071 |
author | nkeynes |
date | Sun Jun 28 10:39:51 2009 +0000 (14 years ago) |
permissions | -rw-r--r-- |
last change | Remove -Wl,-z,defs from dpkg build Add explicit library deps (so that optional libs are Recommended/Suggested) Tweak copyright file |
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 }
.