# HG changeset patch # User nkeynes # Date 1219546635 0 # Node ID d333f424872706573766476fcc50f75bdc63f102 # Parent 69f2c9f1e6088d0d0462604c8701af52474a13fa Adjust the hclip when the horizontal scaler is active --- a/src/pvr2/pvr2.h Sun Aug 24 02:43:28 2008 +0000 +++ b/src/pvr2/pvr2.h Sun Aug 24 02:57:15 2008 +0000 @@ -58,6 +58,8 @@ #define BS_PALM 0x00000080 /* ? */ #define BS_PALN 0x000000C0 /* ? */ +#define SCALER_HSCALE 0x00010000 + #define PVR2_RAM_BASE 0x05000000 #define PVR2_RAM_BASE_INT 0x04000000 #define PVR2_RAM_SIZE (8 * 1024 * 1024) @@ -129,7 +131,7 @@ /****************************** Frame Buffer *****************************/ /** - * Write a block of data to an address in the DMA range (0x10000000 - + * Write a block of data to an address in the DMA range (0x10000000 - * 0x13FFFFFF), ie TA, YUV, or texture ram. */ void pvr2_dma_write( sh4addr_t dest, unsigned char *src, uint32_t length ); @@ -153,7 +155,7 @@ /** * Read a twiddled image from interleaved memory address space (aka 64-bit address - * space), writing the image to the destination buffer in detwiddled format. + * space), writing the image to the destination buffer in detwiddled format. * Width and height must be powers of 2 * This version reads 4-bit pixels. */ @@ -162,7 +164,7 @@ /** * Read a twiddled image from interleaved memory address space (aka 64-bit address - * space), writing the image to the destination buffer in detwiddled format. + * space), writing the image to the destination buffer in detwiddled format. * Width and height must be powers of 2 * This version reads 8-bit pixels. */ @@ -170,21 +172,21 @@ /** * Read a twiddled image from interleaved memory address space (aka 64-bit address - * space), writing the image to the destination buffer in detwiddled format. + * space), writing the image to the destination buffer in detwiddled format. * Width and height must be powers of 2, and src must be 16-bit aligned. * This version reads 16-bit pixels. */ void pvr2_vram64_read_twiddled_16( unsigned char *dest, sh4addr_t src, uint32_t width, uint32_t height ); /** - * Read an image from the interleaved memory address space (aka 64-bit address space) + * Read an image from the interleaved memory address space (aka 64-bit address space) * where the source and destination line sizes may differ. Note that both byte * counts must be a multiple of 4, and the src address must be 32-bit aligned. */ void pvr2_vram64_read_stride( unsigned char *dest, uint32_t dest_line_bytes, sh4addr_t srcaddr, uint32_t src_line_bytes, uint32_t line_count ); /** - * Dump a portion of vram to a stream from the interleaved memory address + * Dump a portion of vram to a stream from the interleaved memory address * space. */ void pvr2_vram64_dump( sh4addr_t addr, uint32_t length, FILE *f ); @@ -195,7 +197,7 @@ * * @param buffer A render buffer indicating the address to store to, and the * format the data needs to be in. - * @param backBuffer TRUE to flush the back buffer, FALSE for + * @param backBuffer TRUE to flush the back buffer, FALSE for * the front buffer. */ void pvr2_render_buffer_copy_to_sh4( render_buffer_t buffer ); @@ -216,7 +218,7 @@ /** * Find the first polygon or sprite context in the supplied buffer of TA * data. - * @return A pointer to the context, or NULL if it cannot be found + * @return A pointer to the context, or NULL if it cannot be found */ uint32_t *pvr2_ta_find_polygon_context( uint32_t *buf, uint32_t length ); @@ -298,7 +300,7 @@ * Flush all textures and delete. The cache will be non-functional until * the next call to texcache_init(). This would typically be done if * switching GL targets. - */ + */ void texcache_shutdown( void ); /** @@ -322,7 +324,7 @@ * multiple interpretations). We use the texture address as the primary * index, but allow for multiple instances at each address. The texture * will be bound to the GL_TEXTURE_2D target before being returned. - * + * * If the texture has already been bound, return the ID to which it was * bound. Otherwise obtain an unused texture ID and set it up appropriately. */ --- a/src/pvr2/pvr2mem.c Sun Aug 24 02:43:28 2008 +0000 +++ b/src/pvr2/pvr2mem.c Sun Aug 24 02:57:15 2008 +0000 @@ -56,7 +56,7 @@ unsigned char *dest = mem_get_region(destaddr); memcpy( dest, src, count ); } - } + } } void pvr2_vram64_write( sh4addr_t destaddr, unsigned char *src, uint32_t length ) @@ -77,7 +77,7 @@ banks[0] = ((uint32_t *)(video_base + ((destaddr & 0x007FFFF8) >>1))); banks[1] = banks[0] + 0x100000; - if( bank_flag ) + if( bank_flag ) banks[0]++; /* Handle non-aligned start of source */ @@ -103,7 +103,7 @@ while( length-- > 0 ) { *dest++ = *src++; } - } + } } /** @@ -111,7 +111,7 @@ * The destaddr must be 32-bit aligned, and both line_bytes and line_stride_bytes * must be multiples of 4. */ -void pvr2_vram64_write_stride( sh4addr_t destaddr, unsigned char *src, uint32_t line_bytes, +void pvr2_vram64_write_stride( sh4addr_t destaddr, unsigned char *src, uint32_t line_bytes, uint32_t line_stride_bytes, uint32_t line_count ) { int bank_flag = (destaddr & 0x04) >> 2; @@ -133,7 +133,7 @@ banks[0] = (uint32_t *)(video_base + (destaddr >>1)); banks[1] = banks[0] + 0x100000; - if( bank_flag ) + if( bank_flag ) banks[0]++; dwsrc = (uint32_t *)src; @@ -148,7 +148,7 @@ banks[bank_flag]++; bank_flag = !bank_flag; } - } + } } /** @@ -200,7 +200,7 @@ banks[bank_flag]++; bank_flag = !bank_flag; } - } + } } @@ -296,7 +296,7 @@ } /** - * Read an image from 64-bit vram stored as twiddled 4-bit pixels. The + * Read an image from 64-bit vram stored as twiddled 4-bit pixels. The * image is written out to the destination in detwiddled form. * @param dest destination buffer, which must be at least width*height/2 in length * @param srcaddr source address in vram @@ -335,11 +335,11 @@ *wdest = *banks[0]; } else { pvr2_vram64_detwiddle_4( wdest, banks, offset_flag, 0, 0, width, stride ); - } + } } /** - * Read an image from 64-bit vram stored as twiddled 8-bit pixels. The + * Read an image from 64-bit vram stored as twiddled 8-bit pixels. The * image is written out to the destination in detwiddled form. * @param dest destination buffer, which must be at least width*height in length * @param srcaddr source address in vram @@ -377,11 +377,11 @@ *wdest = *banks[0]; } else { pvr2_vram64_detwiddle_8( wdest, banks, offset_flag, 0, 0, width, width ); - } + } } /** - * Read an image from 64-bit vram stored as twiddled 16-bit pixels. The + * Read an image from 64-bit vram stored as twiddled 16-bit pixels. The * image is written out to the destination in detwiddled form. * @param dest destination buffer, which must be at least width*height*2 in length * @param srcaddr source address in vram (must be 16-bit aligned) @@ -419,7 +419,7 @@ *wdest = *banks[0]; } else { pvr2_vram64_detwiddle_16( wdest, banks, offset_flag, 0, 0, width, width ); - } + } } void pvr2_vram_write_invert( sh4addr_t destaddr, unsigned char *src, uint32_t length, uint32_t line_length, @@ -500,7 +500,7 @@ fclose(f); } -void pvr2_vram64_dump( sh4addr_t addr, uint32_t length, FILE *f ) +void pvr2_vram64_dump( sh4addr_t addr, uint32_t length, FILE *f ) { unsigned char tmp[length]; pvr2_vram64_read( tmp, addr, length ); @@ -513,9 +513,11 @@ * Flush the indicated render buffer back to PVR. Caller is responsible for * tracking whether there is actually anything in the buffer. * + * FIXME: Handle horizontal scaler + * * @param buffer A render buffer indicating the address to store to, and the * format the data needs to be in. - * @param backBuffer TRUE to flush the back buffer, FALSE for + * @param backBuffer TRUE to flush the back buffer, FALSE for * the front buffer. */ void pvr2_render_buffer_copy_to_sh4( render_buffer_t buffer ) --- a/src/pvr2/scene.c Sun Aug 24 02:43:28 2008 +0000 +++ b/src/pvr2/scene.c Sun Aug 24 02:57:15 2008 +0000 @@ -1,7 +1,7 @@ /** * $Id$ * - * Manage the internal vertex/polygon buffers and scene data structure. + * Manage the internal vertex/polygon buffers and scene data structure. * Where possible this uses VBOs for the vertex + index data. * * Copyright (c) 2005 Nathan Keynes. @@ -166,7 +166,7 @@ } static struct polygon_struct *scene_add_polygon( pvraddr_t poly_idx, int vertex_count, - gboolean is_modified ) + gboolean is_modified ) { int vert_mul = is_modified ? 2 : 1; @@ -199,8 +199,8 @@ * @param modify_offset Offset in 32-bit words to the tex/color data. 0 for * the normal vertex, half the vertex length for the modified vertex. */ -static void pvr2_decode_render_vertex( struct vertex_struct *vert, uint32_t poly1, - uint32_t poly2, uint32_t *pvr2_data, +static void pvr2_decode_render_vertex( struct vertex_struct *vert, uint32_t poly1, + uint32_t poly2, uint32_t *pvr2_data, int modify_offset ) { gboolean force_alpha = !POLY2_ALPHA_ENABLE(poly2); @@ -250,7 +250,7 @@ vert->offset_rgba[0] = 0.0; vert->offset_rgba[1] = 0.0; vert->offset_rgba[2] = 0.0; - vert->offset_rgba[3] = 0.0; + vert->offset_rgba[3] = 0.0; } if( force_alpha ) { @@ -263,7 +263,7 @@ * Compute texture, colour, and z values for 1 or more result points by interpolating from * a set of 3 input points. The result point(s) must define their x,y. */ -static void scene_compute_vertexes( struct vertex_struct *result, +static void scene_compute_vertexes( struct vertex_struct *result, int result_count, struct vertex_struct *input, gboolean is_solid_shaded ) @@ -276,7 +276,7 @@ float detxy = ((sy) * (tx)) - ((ty) * (sx)); if( detxy == 0 ) { - // If the input points fall on a line, they don't define a usable + // If the input points fall on a line, they don't define a usable // polygon - the PVR2 takes the last input point as the result in // this case. for( i=0; i pvr2_scene.bounds[5] ) { pvr2_scene.bounds[5] = rz; } else if( rz < pvr2_scene.bounds[4] ) { - pvr2_scene.bounds[4] = rz; + pvr2_scene.bounds[4] = rz; } result[i].z = rz; result[i].u = input[1].u + (t*tu) + (s*su); @@ -360,7 +360,7 @@ } } -static void scene_add_quad_vertexes( pvraddr_t poly_idx, int vertex_length, +static void scene_add_quad_vertexes( pvraddr_t poly_idx, int vertex_length, gboolean is_modified ) { struct polygon_struct *poly = pvr2_scene.buf_to_poly_map[poly_idx]; @@ -369,7 +369,7 @@ unsigned int i; if( poly->vertex_index == -1 ) { - // Construct it locally and copy to the vertex buffer, as the VBO is + // Construct it locally and copy to the vertex buffer, as the VBO is // allowed to be horribly slow for reads (ie it could be direct-mapped // vram). struct vertex_struct quad[4]; @@ -524,7 +524,7 @@ } } } - } while( 1 ); + } while( 1 ); } static void scene_extract_background( void ) @@ -543,7 +543,7 @@ context_length = 5; vertex_length <<= 1; poly->mod_vertex_index = pvr2_scene.vertex_count + 4; - pvr2_scene.vertex_count += 8; + pvr2_scene.vertex_count += 8; } else { poly->mod_vertex_index = -1; pvr2_scene.vertex_count += 4; @@ -555,7 +555,7 @@ pvr2_scene.bkgnd_poly = poly; struct vertex_struct base_vertexes[3]; - uint32_t *ptr = context + context_length; + uint32_t *ptr = context + context_length; for( i=0; i<3; i++ ) { pvr2_decode_render_vertex( &base_vertexes[i], context[0], context[1], ptr, 0 ); @@ -599,10 +599,10 @@ /** * Extract the current scene into the rendering structures. We run two passes - * - first pass extracts the polygons into pvr2_scene.poly_array (finding vertex counts), + * - first pass extracts the polygons into pvr2_scene.poly_array (finding vertex counts), * second pass extracts the vertex data into the VBO/vertex array. * - * Difficult to do in single pass as we don't generally know the size of a + * Difficult to do in single pass as we don't generally know the size of a * polygon for certain until we've seen all tiles containing it. It also means we * can count the vertexes and allocate the appropriate size VBO. * @@ -619,6 +619,15 @@ pvr2_scene.bounds[3] = ((MMIO_READ( PVR2, RENDER_VCLIP ) >> 16) & 0x03FF) + 1; pvr2_scene.bounds[4] = pvr2_scene.bounds[5] = MMIO_READF( PVR2, RENDER_FARCLIP ); + uint32_t scaler = MMIO_READ( PVR2, RENDER_SCALER ); + if( scaler & SCALER_HSCALE ) { + /* If the horizontal scaler is in use, we're (in principle) supposed to + * divide everything by 2. However in the interests of display quality, + * instead we want to render to the unscaled resolution and downsample + * only if/when required. + */ + pvr2_scene.bounds[1] *= 2; + } uint32_t *tilebuffer = (uint32_t *)(video_base + MMIO_READ( PVR2, RENDER_TILEBASE )); uint32_t *segment = tilebuffer; pvr2_scene.segment_list = (struct tile_segment *)tilebuffer; @@ -640,7 +649,7 @@ pvr2_scene.sort_mode = SORT_TILEFLAG; } - // Pass 1: Extract polygon list + // Pass 1: Extract polygon list uint32_t control; int i; do { @@ -649,7 +658,7 @@ int tile_y = SEGMENT_Y(control); if( tile_x > max_tile_x ) { max_tile_x = tile_x; - } + } if( tile_y > max_tile_y ) { max_tile_y = tile_y; } @@ -709,7 +718,7 @@ for( j=0; jvertex_count; j++ ) { struct vertex_struct *v = &pvr2_scene.vertex_array[poly->vertex_index+j]; fprintf( f, " %.5f %.5f %.5f, (%.5f,%.5f) %.5f,%.5f,%.5f,%.5f %.5f %.5f %.5f %.5f\n", v->x, v->y, v->z, v->u, v->v, - v->rgba[0], v->rgba[1], v->rgba[2], v->rgba[3], + v->rgba[0], v->rgba[1], v->rgba[2], v->rgba[3], v->offset_rgba[0], v->offset_rgba[1], v->offset_rgba[2], v->offset_rgba[3] ); } if( poly->mod_vertex_index != -1 ) { @@ -717,7 +726,7 @@ for( j=0; jvertex_count; j++ ) { struct vertex_struct *v = &pvr2_scene.vertex_array[poly->mod_vertex_index+j]; fprintf( f, " %.5f %.5f %.5f, (%.5f,%.5f) %.5f,%.5f,%.5f,%.5f %.5f %.5f %.5f %.5f\n", v->x, v->y, v->z, v->u, v->v, - v->rgba[0], v->rgba[1], v->rgba[2], v->rgba[3], + v->rgba[0], v->rgba[1], v->rgba[2], v->rgba[3], v->offset_rgba[0], v->offset_rgba[1], v->offset_rgba[2], v->offset_rgba[3] ); } }