Search
lxdream.org :: lxdream/src/pvr2/scene.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/pvr2/scene.c
changeset 639:162ee7614b60
prev636:2ccf94f966fc
next645:a7392098299c
author nkeynes
date Mon Feb 18 09:21:43 2008 +0000 (12 years ago)
branchlxdream-render
permissions -rw-r--r--
last change More render WIP - initial glrender.c
file annotate diff log raw
1.1 --- a/src/pvr2/scene.c Thu Feb 14 14:06:41 2008 +0000
1.2 +++ b/src/pvr2/scene.c Mon Feb 18 09:21:43 2008 +0000
1.3 @@ -28,6 +28,11 @@
1.4 #define VBO_EXT_STRING "GL_ARB_vertex_buffer_object"
1.5 #define PBO_EXT_STRING "GL_ARB_pixel_buffer_object"
1.6
1.7 +static inline uint32_t bgra_to_rgba(uint32_t bgra)
1.8 +{
1.9 + return (bgra&0xFF00FF00) | ((bgra&0x00FF0000)>>16) | ((bgra&0x000000FF)<<16);
1.10 +}
1.11 +
1.12 struct pvr2_scene_struct pvr2_scene;
1.13
1.14 static gboolean vbo_init = FALSE;
1.15 @@ -53,6 +58,16 @@
1.16 }
1.17 }
1.18
1.19 +/**
1.20 + * Clear the scene data structures in preparation for fresh data
1.21 + */
1.22 +void pvr2_scene_reset()
1.23 +{
1.24 + pvr2_scene.poly_count = 0;
1.25 + pvr2_scene.vertex_count = 0;
1.26 + memset( pvr2_scene.buf_to_poly_map, 0, BUF_POLY_MAP_SIZE );
1.27 +}
1.28 +
1.29 void pvr2_scene_shutdown()
1.30 {
1.31 if( vbo_supported ) {
1.32 @@ -70,13 +85,19 @@
1.33
1.34 void *vertex_buffer_map()
1.35 {
1.36 + glGetError();
1.37 uint32_t size = pvr2_scene.vertex_count * sizeof(struct vertex_struct);
1.38 if( vbo_supported ) {
1.39 glBindBufferARB( GL_ARRAY_BUFFER_ARB, pvr2_scene.vbo_id );
1.40 -
1.41 + assert( glGetError() == 0 );
1.42 if( size > pvr2_scene.vertex_array_size ) {
1.43 glBufferDataARB( GL_ARRAY_BUFFER_ARB, size, NULL, GL_DYNAMIC_DRAW_ARB );
1.44 - assert( glGetError() == 0 );
1.45 + int status = glGetError();
1.46 + if( status != 0 ) {
1.47 + fprintf( stderr, "Error %08X allocating vertex buffer\n", status );
1.48 + abort();
1.49 + }
1.50 + pvr2_scene.vertex_array_size = size;
1.51 }
1.52 pvr2_scene.vertex_array = glMapBufferARB( GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB );
1.53 assert(pvr2_scene.vertex_array != NULL );
1.54 @@ -98,7 +119,7 @@
1.55 }
1.56 }
1.57
1.58 -static struct polygon_struct *vertex_buffer_add_polygon( pvraddr_t poly_idx, int vertex_count,
1.59 +static struct polygon_struct *scene_add_polygon( pvraddr_t poly_idx, int vertex_count,
1.60 gboolean is_modified )
1.61 {
1.62 int vert_mul = is_modified ? 2 : 1;
1.63 @@ -114,6 +135,7 @@
1.64 poly->context = (uint32_t *)(video_base + MMIO_READ(PVR2,RENDER_POLYBASE) + (poly_idx<<2));
1.65 poly->vertex_count = vertex_count;
1.66 poly->vertex_index = -1;
1.67 + poly->next = NULL;
1.68 pvr2_scene.buf_to_poly_map[poly_idx] = poly;
1.69 pvr2_scene.vertex_count += (vertex_count * vert_mul);
1.70 return poly;
1.71 @@ -125,13 +147,16 @@
1.72 * volume)
1.73 * @param vert Pointer to output vertex structure
1.74 * @param poly1 First word of polygon context (needed to understand vertex)
1.75 + * @param poly2 Second word of polygon context
1.76 * @param pvr2_data Pointer to raw pvr2 vertex data (in VRAM)
1.77 * @param modify_offset Offset in 32-bit words to the tex/color data. 0 for
1.78 * the normal vertex, half the vertex length for the modified vertex.
1.79 */
1.80 static void pvr2_decode_render_vertex( struct vertex_struct *vert, uint32_t poly1,
1.81 - uint32_t *pvr2_data, int modify_offset )
1.82 + uint32_t poly2, uint32_t *pvr2_data,
1.83 + int modify_offset )
1.84 {
1.85 + gboolean force_alpha = !POLY2_ALPHA_ENABLE(poly2);
1.86 union pvr2_data_type {
1.87 uint32_t *ival;
1.88 float *fval;
1.89 @@ -161,10 +186,20 @@
1.90 vert->u = *data.fval++;
1.91 vert->v = *data.fval++;
1.92 }
1.93 + if( POLY2_TEX_BLEND(poly2) == 1 ) {
1.94 + force_alpha = TRUE;
1.95 + }
1.96 }
1.97 - vert->rgba = *data.ival++;
1.98 - if( POLY1_SPECULAR(poly1) ) {
1.99 - vert->offset_rgba = *data.ival++;
1.100 + if( force_alpha ) {
1.101 + vert->rgba = bgra_to_rgba((*data.ival++) | 0xFF000000);
1.102 + if( POLY1_SPECULAR(poly1) ) {
1.103 + vert->offset_rgba = bgra_to_rgba((*data.ival++) | 0xFF000000);
1.104 + }
1.105 + } else {
1.106 + vert->rgba = bgra_to_rgba(*data.ival++);
1.107 + if( POLY1_SPECULAR(poly1) ) {
1.108 + vert->offset_rgba = bgra_to_rgba(*data.ival++);
1.109 + }
1.110 }
1.111 }
1.112
1.113 @@ -172,7 +207,7 @@
1.114 * Compute texture, colour, and z values for a result point by interpolating from
1.115 * a set of 3 input points. The result point must define its x,y.
1.116 */
1.117 -static void vertex_buffer_compute_vertex( struct vertex_struct *result,
1.118 +static void scene_compute_vertex( struct vertex_struct *result,
1.119 struct vertex_struct *input,
1.120 gboolean is_solid_shaded )
1.121 {
1.122 @@ -236,7 +271,7 @@
1.123
1.124 }
1.125
1.126 -static void vertex_buffer_add_vertexes( pvraddr_t poly_idx, int vertex_length,
1.127 +static void scene_add_vertexes( pvraddr_t poly_idx, int vertex_length,
1.128 gboolean is_modified )
1.129 {
1.130 struct polygon_struct *poly = pvr2_scene.buf_to_poly_map[poly_idx];
1.131 @@ -248,9 +283,10 @@
1.132 if( poly->vertex_index == -1 ) {
1.133 ptr += (is_modified ? 5 : 3 );
1.134 poly->vertex_index = pvr2_scene.vertex_index;
1.135 +
1.136 assert( pvr2_scene.vertex_index + poly->vertex_count <= pvr2_scene.vertex_count );
1.137 for( i=0; i<poly->vertex_count; i++ ) {
1.138 - pvr2_decode_render_vertex( &pvr2_scene.vertex_array[pvr2_scene.vertex_index++], context[0], ptr, 0 );
1.139 + pvr2_decode_render_vertex( &pvr2_scene.vertex_array[pvr2_scene.vertex_index++], context[0], context[1], ptr, 0 );
1.140 ptr += vertex_length;
1.141 }
1.142 if( is_modified ) {
1.143 @@ -258,14 +294,14 @@
1.144 ptr = &pvr2_scene.pvr2_pbuf[poly_idx] + 5;
1.145 poly->mod_vertex_index = pvr2_scene.vertex_index;
1.146 for( i=0; i<poly->vertex_count; i++ ) {
1.147 - pvr2_decode_render_vertex( &pvr2_scene.vertex_array[pvr2_scene.vertex_index++], context[0], ptr, mod_offset );
1.148 + pvr2_decode_render_vertex( &pvr2_scene.vertex_array[pvr2_scene.vertex_index++], context[0], context[3], ptr, mod_offset );
1.149 ptr += vertex_length;
1.150 }
1.151 }
1.152 }
1.153 }
1.154
1.155 -static void vertex_buffer_add_quad_vertexes( pvraddr_t poly_idx, int vertex_length,
1.156 +static void scene_add_quad_vertexes( pvraddr_t poly_idx, int vertex_length,
1.157 gboolean is_modified )
1.158 {
1.159 struct polygon_struct *poly = pvr2_scene.buf_to_poly_map[poly_idx];
1.160 @@ -283,11 +319,14 @@
1.161 ptr += (is_modified ? 5 : 3 );
1.162 poly->vertex_index = pvr2_scene.vertex_index;
1.163 for( i=0; i<4; i++ ) {
1.164 - pvr2_decode_render_vertex( &quad[i], context[0], ptr, 0 );
1.165 + pvr2_decode_render_vertex( &quad[i], context[0], context[1], ptr, 0 );
1.166 ptr += vertex_length;
1.167 }
1.168 - vertex_buffer_compute_vertex( &quad[3], &quad[0], !POLY1_GOURAUD_SHADED(context[0]) );
1.169 - memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index], quad, sizeof(quad) );
1.170 + scene_compute_vertex( &quad[3], &quad[0], !POLY1_GOURAUD_SHADED(context[0]) );
1.171 + // Swap last two vertexes (quad arrangement => tri strip arrangement)
1.172 + memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index], quad, sizeof(struct vertex_struct)*2 );
1.173 + memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index+2], &quad[3], sizeof(struct vertex_struct) );
1.174 + memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index+3], &quad[2], sizeof(struct vertex_struct) );
1.175 pvr2_scene.vertex_index += 4;
1.176
1.177 if( is_modified ) {
1.178 @@ -295,17 +334,19 @@
1.179 ptr = &pvr2_scene.pvr2_pbuf[poly_idx] + 5;
1.180 poly->mod_vertex_index = pvr2_scene.vertex_index;
1.181 for( i=0; i<4; i++ ) {
1.182 - pvr2_decode_render_vertex( &quad[4], context[0], ptr, mod_offset );
1.183 + pvr2_decode_render_vertex( &quad[4], context[0], context[3], ptr, mod_offset );
1.184 ptr += vertex_length;
1.185 }
1.186 - vertex_buffer_compute_vertex( &quad[3], &quad[0], !POLY1_GOURAUD_SHADED(context[0]) );
1.187 - memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index], quad, sizeof(quad) );
1.188 + scene_compute_vertex( &quad[3], &quad[0], !POLY1_GOURAUD_SHADED(context[0]) );
1.189 + memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index], quad, sizeof(struct vertex_struct)*2 );
1.190 + memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index+2], &quad[3], sizeof(struct vertex_struct) );
1.191 + memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index+3], &quad[2], sizeof(struct vertex_struct) );
1.192 pvr2_scene.vertex_index += 4;
1.193 }
1.194 }
1.195 }
1.196
1.197 -static void vertex_buffer_extract_polygons( pvraddr_t tile_entry )
1.198 +static void scene_extract_polygons( pvraddr_t tile_entry )
1.199 {
1.200 uint32_t *tile_list = (uint32_t *)(video_base+tile_entry);
1.201 do {
1.202 @@ -332,7 +373,7 @@
1.203 int i;
1.204 struct polygon_struct *last_poly = NULL;
1.205 for( i=0; i<strip_count; i++ ) {
1.206 - struct polygon_struct *poly = vertex_buffer_add_polygon( polyaddr, 3, is_modified );
1.207 + struct polygon_struct *poly = scene_add_polygon( polyaddr, 3, is_modified );
1.208 polyaddr += polygon_length;
1.209 if( last_poly != NULL && last_poly->next == NULL ) {
1.210 last_poly->next = poly;
1.211 @@ -346,7 +387,7 @@
1.212 int i;
1.213 struct polygon_struct *last_poly = NULL;
1.214 for( i=0; i<strip_count; i++ ) {
1.215 - struct polygon_struct *poly = vertex_buffer_add_polygon( polyaddr, 4, is_modified );
1.216 + struct polygon_struct *poly = scene_add_polygon( polyaddr, 4, is_modified );
1.217 polyaddr += polygon_length;
1.218 if( last_poly != NULL && last_poly->next == NULL ) {
1.219 last_poly->next = poly;
1.220 @@ -363,14 +404,14 @@
1.221 }
1.222 }
1.223 if( last != -1 ) {
1.224 - vertex_buffer_add_polygon( polyaddr, last+3, is_modified );
1.225 + scene_add_polygon( polyaddr, last+3, is_modified );
1.226 }
1.227 }
1.228 }
1.229 } while( 1 );
1.230 }
1.231
1.232 -static void vertex_buffer_extract_vertexes( pvraddr_t tile_entry )
1.233 +static void scene_extract_vertexes( pvraddr_t tile_entry )
1.234 {
1.235 uint32_t *tile_list = (uint32_t *)(video_base+tile_entry);
1.236 do {
1.237 @@ -396,7 +437,7 @@
1.238 int polygon_length = 3 * vertex_length + context_length;
1.239 int i;
1.240 for( i=0; i<strip_count; i++ ) {
1.241 - vertex_buffer_add_vertexes( polyaddr, vertex_length, is_modified );
1.242 + scene_add_vertexes( polyaddr, vertex_length, is_modified );
1.243 polyaddr += polygon_length;
1.244 }
1.245 } else if( (entry & 0xE0000000) == 0xA0000000 ) {
1.246 @@ -405,7 +446,7 @@
1.247 int polygon_length = 4 * vertex_length + context_length;
1.248 int i;
1.249 for( i=0; i<strip_count; i++ ) {
1.250 - vertex_buffer_add_quad_vertexes( polyaddr, vertex_length, is_modified );
1.251 + scene_add_quad_vertexes( polyaddr, vertex_length, is_modified );
1.252 polyaddr += polygon_length;
1.253 }
1.254 } else {
1.255 @@ -418,13 +459,23 @@
1.256 }
1.257 }
1.258 if( last != -1 ) {
1.259 - vertex_buffer_add_vertexes( polyaddr, vertex_length, is_modified );
1.260 + scene_add_vertexes( polyaddr, vertex_length, is_modified );
1.261 }
1.262 }
1.263 }
1.264 } while( 1 );
1.265 }
1.266
1.267 +uint32_t pvr2_scene_buffer_width()
1.268 +{
1.269 + return pvr2_scene.buffer_width;
1.270 +}
1.271 +
1.272 +uint32_t pvr2_scene_buffer_height()
1.273 +{
1.274 + return pvr2_scene.buffer_height;
1.275 +}
1.276 +
1.277 /**
1.278 * Extract the current scene into the rendering structures. We run two passes
1.279 * - first pass extracts the polygons into pvr2_scene.poly_array (finding vertex counts),
1.280 @@ -439,9 +490,8 @@
1.281 void pvr2_scene_read( void )
1.282 {
1.283 pvr2_scene_init();
1.284 + pvr2_scene_reset();
1.285
1.286 - pvr2_scene.poly_count = 0;
1.287 - pvr2_scene.vertex_count = 0;
1.288 pvr2_scene.bounds[0] = MMIO_READ( PVR2, RENDER_HCLIP ) & 0x03FF;
1.289 pvr2_scene.bounds[1] = ((MMIO_READ( PVR2, RENDER_HCLIP ) >> 16) & 0x03FF) + 1;
1.290 pvr2_scene.bounds[2] = MMIO_READ( PVR2, RENDER_VCLIP ) & 0x03FF;
1.291 @@ -484,7 +534,7 @@
1.292 }
1.293 for( i=0; i<5; i++ ) {
1.294 if( (*segment & NO_POINTER) == 0 ) {
1.295 - vertex_buffer_extract_polygons( *segment );
1.296 + scene_extract_polygons( *segment );
1.297 }
1.298 segment++;
1.299 }
1.300 @@ -502,7 +552,7 @@
1.301 control = *segment++;
1.302 for( i=0; i<5; i++ ) {
1.303 if( (*segment & NO_POINTER) == 0 ) {
1.304 - vertex_buffer_extract_vertexes( *segment );
1.305 + scene_extract_vertexes( *segment );
1.306 }
1.307 segment++;
1.308 }
1.309 @@ -511,22 +561,3 @@
1.310 vertex_buffer_unmap();
1.311 }
1.312 }
1.313 -
1.314 -/**
1.315 - * Render the data in the scene structure. The GL target should already be setup.
1.316 - * Note: thar be GL code here.
1.317 - */
1.318 -void vertex_buffer_render()
1.319 -{
1.320 - /* Scene setup */
1.321 -
1.322 - glEnable( GL_SCISSOR_TEST );
1.323 -
1.324 - /* Scene render */
1.325 - struct tile_segment *segment = pvr2_scene.segment_list;
1.326 - do {
1.327 -
1.328 -
1.329 - } while( !IS_LAST_SEGMENT(segment) );
1.330 - glDisable( GL_SCISSOR_TEST );
1.331 -}
.