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