Search
lxdream.org :: lxdream/src/pvr2/rendsort.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/pvr2/rendsort.c
changeset 653:3202ff01d48e
prev561:533f6b478071
next669:ab344e42bca9
author nkeynes
date Fri Mar 28 12:32:25 2008 +0000 (16 years ago)
permissions -rw-r--r--
last change Merge lxdream-render branch (643:670) to trunk
file annotate diff log raw
1.1 --- a/src/pvr2/rendsort.c Tue Jan 01 05:08:38 2008 +0000
1.2 +++ b/src/pvr2/rendsort.c Fri Mar 28 12:32:25 2008 +0000
1.3 @@ -16,21 +16,21 @@
1.4 * GNU General Public License for more details.
1.5 */
1.6 #include <sys/time.h>
1.7 +#include <string.h>
1.8 +#include <assert.h>
1.9 #include "pvr2/pvr2.h"
1.10 +#include "pvr2/scene.h"
1.11 #include "asic.h"
1.12
1.13 extern char *video_base;
1.14 -extern gboolean pvr2_force_fragment_alpha;
1.15
1.16 #define MIN3( a,b,c ) ((a) < (b) ? ( (a) < (c) ? (a) : (c) ) : ((b) < (c) ? (b) : (c)) )
1.17 #define MAX3( a,b,c ) ((a) > (b) ? ( (a) > (c) ? (a) : (c) ) : ((b) > (c) ? (b) : (c)) )
1.18
1.19 -struct render_triangle {
1.20 - uint32_t *polygon;
1.21 - int vertex_length; /* Number of 32-bit words in vertex, or 0 for an unpacked vertex */
1.22 - float minx,miny,minz;
1.23 - float maxx,maxy,maxz;
1.24 - float *vertexes[3];
1.25 +struct sort_triangle {
1.26 + struct polygon_struct *poly;
1.27 + int triangle_num; // triangle number in the poly, from 0
1.28 + float maxz;
1.29 };
1.30
1.31 #define SENTINEL 0xDEADBEEF
1.32 @@ -39,7 +39,7 @@
1.33 * Count the number of triangles in the list starting at the given
1.34 * pvr memory address.
1.35 */
1.36 -int render_count_triangles( pvraddr_t tile_entry ) {
1.37 +int sort_count_triangles( pvraddr_t tile_entry ) {
1.38 uint32_t *tile_list = (uint32_t *)(video_base+tile_entry);
1.39 int count = 0;
1.40 while(1) {
1.41 @@ -64,27 +64,12 @@
1.42 return count;
1.43 }
1.44
1.45 -static void compute_triangle_boxes( struct render_triangle *triangle, int num_triangles )
1.46 +/**
1.47 + * Extract a triangle list from the tile (basically indexes into the polygon list, plus
1.48 + * computing maxz while we go through it
1.49 + */
1.50 +int sort_extract_triangles( pvraddr_t tile_entry, struct sort_triangle *triangles )
1.51 {
1.52 - int i;
1.53 - for( i=0; i<num_triangles; i++ ) {
1.54 - triangle[i].minx = MIN3(triangle[i].vertexes[0][0],triangle[i].vertexes[1][0],triangle[i].vertexes[2][0]);
1.55 - triangle[i].maxx = MAX3(triangle[i].vertexes[0][0],triangle[i].vertexes[1][0],triangle[i].vertexes[2][0]);
1.56 - triangle[i].miny = MIN3(triangle[i].vertexes[0][1],triangle[i].vertexes[1][1],triangle[i].vertexes[2][1]);
1.57 - triangle[i].maxy = MAX3(triangle[i].vertexes[0][1],triangle[i].vertexes[1][1],triangle[i].vertexes[2][1]);
1.58 - float az = 1/triangle[i].vertexes[0][2];
1.59 - float bz = 1/triangle[i].vertexes[1][2];
1.60 - float cz = 1/triangle[i].vertexes[2][2];
1.61 - triangle[i].minz = MIN3(az,bz,cz);
1.62 - triangle[i].maxz = MAX3(az,bz,cz);
1.63 - }
1.64 -}
1.65 -
1.66 -void render_extract_triangles( pvraddr_t tile_entry, gboolean cheap_modifier_mode,
1.67 - struct render_triangle *triangles, int num_triangles,
1.68 - struct vertex_unpacked *vertex_space, int render_mode )
1.69 -{
1.70 - uint32_t poly_bank = MMIO_READ(PVR2,RENDER_POLYBASE);
1.71 uint32_t *tile_list = (uint32_t *)(video_base+tile_entry);
1.72 int count = 0;
1.73 while(1) {
1.74 @@ -94,11 +79,11 @@
1.75 } else if( entry >> 28 == 0x0E ) {
1.76 tile_list = (uint32_t *)(video_base+(entry&0x007FFFFF));
1.77 } else {
1.78 - uint32_t *polygon = (uint32_t *)(video_base + poly_bank + ((entry & 0x000FFFFF) << 2));
1.79 + uint32_t poly_addr = entry & 0x000FFFFF;
1.80 int is_modified = entry & 0x01000000;
1.81 int vertex_length = (entry >> 21) & 0x07;
1.82 int context_length = 3;
1.83 - if( is_modified && !cheap_modifier_mode ) {
1.84 + if( is_modified && pvr2_scene.full_shadow ) {
1.85 context_length = 5;
1.86 vertex_length *= 2 ;
1.87 }
1.88 @@ -110,127 +95,108 @@
1.89 int polygon_length = 3 * vertex_length + context_length;
1.90 int i;
1.91 for( i=0; i<strip_count; i++ ) {
1.92 - float *vertex = (float *)(polygon+context_length);
1.93 - triangles[count].polygon = polygon;
1.94 - triangles[count].vertex_length = vertex_length;
1.95 - triangles[count].vertexes[0] = vertex;
1.96 - vertex+=vertex_length;
1.97 - triangles[count].vertexes[1] = vertex;
1.98 - vertex+=vertex_length;
1.99 - triangles[count].vertexes[2] = vertex;
1.100 - polygon += polygon_length;
1.101 + struct polygon_struct *poly = pvr2_scene.buf_to_poly_map[poly_addr];
1.102 + triangles[count].poly = poly;
1.103 + triangles[count].triangle_num = 0;
1.104 + triangles[count].maxz = MAX3( pvr2_scene.vertex_array[poly->vertex_index].z,
1.105 + pvr2_scene.vertex_array[poly->vertex_index+1].z,
1.106 + pvr2_scene.vertex_array[poly->vertex_index+2].z );
1.107 + poly_addr += polygon_length;
1.108 count++;
1.109 }
1.110 } else if( (entry & 0xE0000000) == 0xA0000000 ) {
1.111 /* Quad(s) */
1.112 int strip_count = ((entry >> 25) & 0x0F)+1;
1.113 int polygon_length = 4 * vertex_length + context_length;
1.114 -
1.115 int i;
1.116 for( i=0; i<strip_count; i++ ) {
1.117 - render_unpack_quad( vertex_space, *polygon, (polygon+context_length),
1.118 - vertex_length, render_mode );
1.119 - triangles[count].polygon = polygon;
1.120 - triangles[count].vertex_length = 0;
1.121 - triangles[count].vertexes[0] = (float *)vertex_space;
1.122 - triangles[count].vertexes[1] = (float *)(vertex_space + 1);
1.123 - triangles[count].vertexes[2] = (float *)(vertex_space + 3);
1.124 + struct polygon_struct *poly = pvr2_scene.buf_to_poly_map[poly_addr];
1.125 + triangles[count].poly = poly;
1.126 + triangles[count].triangle_num = 0;
1.127 + triangles[count].maxz = MAX3( pvr2_scene.vertex_array[poly->vertex_index].z,
1.128 + pvr2_scene.vertex_array[poly->vertex_index+1].z,
1.129 + pvr2_scene.vertex_array[poly->vertex_index+2].z );
1.130 count++;
1.131 - /* Preserve face direction */
1.132 - triangles[count].polygon = polygon;
1.133 - triangles[count].vertex_length = 0;
1.134 - triangles[count].vertexes[0] = (float *)(vertex_space + 1);
1.135 - triangles[count].vertexes[1] = (float *)(vertex_space + 2);
1.136 - triangles[count].vertexes[2] = (float *)(vertex_space + 3);
1.137 + triangles[count].poly = poly;
1.138 + triangles[count].triangle_num = 1;
1.139 + triangles[count].maxz = MAX3( pvr2_scene.vertex_array[poly->vertex_index+1].z,
1.140 + pvr2_scene.vertex_array[poly->vertex_index+2].z,
1.141 + pvr2_scene.vertex_array[poly->vertex_index+3].z );
1.142 count++;
1.143 - vertex_space += 4;
1.144 - polygon += polygon_length;
1.145 + poly_addr += polygon_length;
1.146 }
1.147 } else {
1.148 /* Polygon */
1.149 int i;
1.150 - float *vertex = (float *)polygon+context_length;
1.151 + struct polygon_struct *poly = pvr2_scene.buf_to_poly_map[poly_addr];
1.152 for( i=0; i<6; i++ ) {
1.153 if( entry & (0x40000000>>i) ) {
1.154 - triangles[count].polygon = polygon;
1.155 - triangles[count].vertex_length = vertex_length;
1.156 - if( i&1 ) {
1.157 - triangles[count].vertexes[0] = vertex + vertex_length;
1.158 - triangles[count].vertexes[1] = vertex;
1.159 - triangles[count].vertexes[2] = vertex + (vertex_length<<1);
1.160 - } else {
1.161 - triangles[count].vertexes[0] = vertex;
1.162 - triangles[count].vertexes[1] = vertex + vertex_length;
1.163 - triangles[count].vertexes[2] = vertex + (vertex_length<<1);
1.164 - }
1.165 + triangles[count].poly = poly;
1.166 + triangles[count].triangle_num = i;
1.167 + triangles[count].maxz = MAX3( pvr2_scene.vertex_array[poly->vertex_index+i].z,
1.168 + pvr2_scene.vertex_array[poly->vertex_index+i+1].z,
1.169 + pvr2_scene.vertex_array[poly->vertex_index+i+2].z );
1.170 count++;
1.171 }
1.172 - vertex += vertex_length;
1.173 }
1.174 }
1.175 }
1.176 }
1.177 - if( count != num_triangles ) {
1.178 - ERROR( "Extracted triangles do not match expected count!" );
1.179 - }
1.180 + return count;
1.181 }
1.182
1.183 -void render_triangles( struct render_triangle *triangles, int num_triangles,
1.184 - int render_mode )
1.185 +void sort_render_triangles( struct sort_triangle *triangles, int num_triangles,
1.186 + int render_mode )
1.187 {
1.188 int i;
1.189 for( i=0; i<num_triangles; i++ ) {
1.190 - render_set_context( triangles[i].polygon, render_mode );
1.191 - glEnable(GL_DEPTH_TEST);
1.192 + struct polygon_struct *poly = triangles[i].poly;
1.193 + if( poly->tex_id != -1 ) {
1.194 + glBindTexture(GL_TEXTURE_2D, poly->tex_id);
1.195 + }
1.196 + render_set_context( poly->context, RENDER_NORMAL );
1.197 + glDepthMask(GL_FALSE);
1.198 glDepthFunc(GL_GEQUAL);
1.199 - if( triangles[i].vertex_length == 0 ) {
1.200 - render_unpacked_vertex_array( *triangles[i].polygon, (struct vertex_unpacked **)triangles[i].vertexes, 3 );
1.201 + /* Fix cull direction */
1.202 + if( triangles[i].triangle_num & 1 ) {
1.203 + glCullFace(GL_FRONT);
1.204 } else {
1.205 - render_vertex_array( *triangles[i].polygon, (uint32_t **)triangles[i].vertexes, 3,
1.206 - triangles[i].vertex_length, render_mode );
1.207 + glCullFace(GL_BACK);
1.208 }
1.209 +
1.210 + glDrawArrays(GL_TRIANGLE_STRIP, poly->vertex_index + triangles[i].triangle_num, 3 );
1.211 }
1.212 -
1.213 -
1.214 }
1.215
1.216 int compare_triangles( const void *a, const void *b )
1.217 {
1.218 - const struct render_triangle *tri1 = a;
1.219 - const struct render_triangle *tri2 = b;
1.220 - if( tri1->minz < tri2->minz ) {
1.221 - return 1; // No these _aren't_ back to front...
1.222 - } else if( tri1->minz > tri2->minz ) {
1.223 - return -1;
1.224 - } else {
1.225 - return 0;
1.226 - }
1.227 + const struct sort_triangle *tri1 = a;
1.228 + const struct sort_triangle *tri2 = b;
1.229 + return tri2->maxz - tri1->maxz;
1.230 }
1.231
1.232 -void sort_triangles( struct render_triangle *triangles, int num_triangles )
1.233 +void sort_triangles( struct sort_triangle *triangles, int num_triangles )
1.234 {
1.235 - qsort( triangles, num_triangles, sizeof(struct render_triangle), compare_triangles );
1.236 + qsort( triangles, num_triangles, sizeof(struct sort_triangle), compare_triangles );
1.237 }
1.238
1.239 -void render_autosort_tile( pvraddr_t tile_entry, int render_mode, gboolean cheap_modifier_mode )
1.240 +void render_autosort_tile( pvraddr_t tile_entry, int render_mode )
1.241 {
1.242 - int num_triangles = render_count_triangles(tile_entry);
1.243 + int num_triangles = sort_count_triangles(tile_entry);
1.244 if( num_triangles == 0 ) {
1.245 return; /* nothing to do */
1.246 } else if( num_triangles == 1 ) { /* Triangle can hardly overlap with itself */
1.247 - render_tile( tile_entry, render_mode, cheap_modifier_mode );
1.248 + gl_render_tilelist(tile_entry);
1.249 } else { /* Ooh boy here we go... */
1.250 - struct render_triangle triangles[num_triangles+1];
1.251 - struct vertex_unpacked vertex_space[num_triangles << 1];
1.252 + struct sort_triangle triangles[num_triangles+1];
1.253 // Reserve space for num_triangles / 2 * 4 vertexes (maximum possible number of
1.254 // quad vertices)
1.255 - triangles[num_triangles].polygon = (void *)SENTINEL;
1.256 - render_extract_triangles(tile_entry, cheap_modifier_mode, triangles, num_triangles, vertex_space, render_mode);
1.257 - compute_triangle_boxes(triangles, num_triangles);
1.258 + triangles[num_triangles].poly = (void *)SENTINEL;
1.259 + int extracted_triangles = sort_extract_triangles(tile_entry, triangles);
1.260 + assert( extracted_triangles == num_triangles );
1.261 sort_triangles( triangles, num_triangles );
1.262 - render_triangles(triangles, num_triangles, render_mode);
1.263 - if( triangles[num_triangles].polygon != (void *)SENTINEL ) {
1.264 - fprintf( stderr, "Triangle overflow in render_autosort_tile!" );
1.265 - }
1.266 + sort_render_triangles(triangles, num_triangles, render_mode);
1.267 + glCullFace(GL_BACK);
1.268 + assert( triangles[num_triangles].poly == (void *)SENTINEL );
1.269 }
1.270 }
.