revision 645:a7392098299c
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 645:a7392098299c |
parent | 639:162ee7614b60 |
child | 646:f9812647b818 |
author | nkeynes |
date | Thu Mar 06 08:22:00 2008 +0000 (15 years ago) |
branch | lxdream-render |
More refactor work in progress - nearly done now
![]() | src/Makefile.am | view | annotate | diff | log | |
![]() | src/Makefile.in | view | annotate | diff | log | |
![]() | src/pvr2/gl_slsrc.c | view | annotate | diff | log | |
![]() | src/pvr2/glrender.c | view | annotate | diff | log | |
![]() | src/pvr2/glutil.c | view | annotate | diff | log | |
![]() | src/pvr2/pvr2.c | view | annotate | diff | log | |
![]() | src/pvr2/pvr2.h | view | annotate | diff | log | |
![]() | src/pvr2/pvr2mem.c | view | annotate | diff | log | |
![]() | src/pvr2/rendbkg.c | view | annotate | diff | log | |
src/pvr2/rendcore.c | view | annotate | diff | log | ||
src/pvr2/render.c | view | annotate | diff | log | ||
![]() | src/pvr2/rendsort.c | view | annotate | diff | log | |
![]() | src/pvr2/scene.c | view | annotate | diff | log | |
![]() | src/pvr2/scene.h | view | annotate | diff | log | |
![]() | src/pvr2/tacore.c | view | annotate | diff | log | |
![]() | src/pvr2/texcache.c | view | annotate | diff | log | |
![]() | src/pvr2/vertex.glsl | view | annotate | diff | log |
1.1 --- a/src/Makefile.am Mon Feb 18 09:21:43 2008 +00001.2 +++ b/src/Makefile.am Thu Mar 06 08:22:00 2008 +00001.3 @@ -33,7 +33,7 @@1.4 aica/armcore.c aica/armcore.h aica/armdasm.c aica/armmem.c \1.5 aica/aica.c aica/aica.h aica/audio.c aica/audio.h \1.6 pvr2/pvr2.c pvr2/pvr2.h pvr2/pvr2mem.c \1.7 - pvr2/tacore.c pvr2/render.c pvr2/rendcore.c pvr2/rendbkg.c pvr2/rendsort.c \1.8 + pvr2/tacore.c pvr2/rendbkg.c pvr2/rendsort.c \1.9 pvr2/texcache.c pvr2/yuv.c pvr2/rendsave.c pvr2/scene.c pvr2/scene.h \1.10 pvr2/gl_sl.c pvr2/gl_slsrc.c pvr2/glutil.c pvr2/glutil.h pvr2/glrender.c \1.11 maple/maple.c maple/maple.h \
2.1 --- a/src/Makefile.in Mon Feb 18 09:21:43 2008 +00002.2 +++ b/src/Makefile.in Thu Mar 06 08:22:00 2008 +00002.3 @@ -234,7 +234,7 @@2.4 aica/armcore.c aica/armcore.h aica/armdasm.c aica/armmem.c \2.5 aica/aica.c aica/aica.h aica/audio.c aica/audio.h \2.6 pvr2/pvr2.c pvr2/pvr2.h pvr2/pvr2mem.c \2.7 - pvr2/tacore.c pvr2/render.c pvr2/rendcore.c pvr2/rendbkg.c pvr2/rendsort.c \2.8 + pvr2/tacore.c pvr2/rendbkg.c pvr2/rendsort.c \2.9 pvr2/texcache.c pvr2/yuv.c pvr2/rendsave.c pvr2/scene.c pvr2/scene.h \2.10 pvr2/gl_sl.c pvr2/gl_slsrc.c pvr2/glutil.c pvr2/glutil.h pvr2/glrender.c \2.11 maple/maple.c maple/maple.h \2.12 @@ -291,25 +291,24 @@2.13 sh4/sh4stat.h sh4/xltcache.c sh4/xltcache.h sh4/sh4.h \2.14 aica/armcore.c aica/armcore.h aica/armdasm.c aica/armmem.c \2.15 aica/aica.c aica/aica.h aica/audio.c aica/audio.h pvr2/pvr2.c \2.16 - pvr2/pvr2.h pvr2/pvr2mem.c pvr2/tacore.c pvr2/render.c \2.17 - pvr2/rendcore.c pvr2/rendbkg.c pvr2/rendsort.c pvr2/texcache.c \2.18 - pvr2/yuv.c pvr2/rendsave.c pvr2/scene.c pvr2/scene.h \2.19 - pvr2/gl_sl.c pvr2/gl_slsrc.c pvr2/glutil.c pvr2/glutil.h \2.20 - pvr2/glrender.c maple/maple.c maple/maple.h maple/controller.c \2.21 - maple/controller.h maple/kbd.c maple/mouse.c loader.c \2.22 - bootstrap.c util.c display.c display.h dckeysyms.h \2.23 - drivers/audio_null.c drivers/video_null.c drivers/video_gl.c \2.24 - drivers/video_gl.h drivers/gl_fbo.c sh4/sh4x86.c sh4/x86op.h \2.25 - sh4/ia32abi.h sh4/ia32mac.h sh4/ia64abi.h sh4/sh4trans.c \2.26 - sh4/sh4trans.h x86dasm/x86dasm.c x86dasm/x86dasm.h \2.27 - x86dasm/i386-dis.c x86dasm/dis-init.c x86dasm/dis-buf.c \2.28 - gtkui/gtkui.c gtkui/gtkui.h gtkui/main_win.c gtkui/gtkcb.c \2.29 - gtkui/mmio_win.c gtkui/debug_win.c gtkui/dump_win.c \2.30 - gtkui/ctrl_dlg.c gtkui/path_dlg.c gtkui/gdrom_menu.c \2.31 - drivers/video_gtk.c drivers/video_gtk.h drivers/video_gdk.c \2.32 - drivers/video_gdk.h drivers/video_glx.c drivers/video_glx.h \2.33 - drivers/cd_linux.c drivers/cd_none.c drivers/joy_linux.c \2.34 - drivers/audio_esd.c2.35 + pvr2/pvr2.h pvr2/pvr2mem.c pvr2/tacore.c pvr2/rendbkg.c \2.36 + pvr2/rendsort.c pvr2/texcache.c pvr2/yuv.c pvr2/rendsave.c \2.37 + pvr2/scene.c pvr2/scene.h pvr2/gl_sl.c pvr2/gl_slsrc.c \2.38 + pvr2/glutil.c pvr2/glutil.h pvr2/glrender.c maple/maple.c \2.39 + maple/maple.h maple/controller.c maple/controller.h maple/kbd.c \2.40 + maple/mouse.c loader.c bootstrap.c util.c display.c display.h \2.41 + dckeysyms.h drivers/audio_null.c drivers/video_null.c \2.42 + drivers/video_gl.c drivers/video_gl.h drivers/gl_fbo.c \2.43 + sh4/sh4x86.c sh4/x86op.h sh4/ia32abi.h sh4/ia32mac.h \2.44 + sh4/ia64abi.h sh4/sh4trans.c sh4/sh4trans.h x86dasm/x86dasm.c \2.45 + x86dasm/x86dasm.h x86dasm/i386-dis.c x86dasm/dis-init.c \2.46 + x86dasm/dis-buf.c gtkui/gtkui.c gtkui/gtkui.h gtkui/main_win.c \2.47 + gtkui/gtkcb.c gtkui/mmio_win.c gtkui/debug_win.c \2.48 + gtkui/dump_win.c gtkui/ctrl_dlg.c gtkui/path_dlg.c \2.49 + gtkui/gdrom_menu.c drivers/video_gtk.c drivers/video_gtk.h \2.50 + drivers/video_gdk.c drivers/video_gdk.h drivers/video_glx.c \2.51 + drivers/video_glx.h drivers/cd_linux.c drivers/cd_none.c \2.52 + drivers/joy_linux.c drivers/audio_esd.c2.53 @BUILD_SH4X86_TRUE@am__objects_1 = sh4x86.$(OBJEXT) sh4trans.$(OBJEXT) \2.54 @BUILD_SH4X86_TRUE@ x86dasm.$(OBJEXT) i386-dis.$(OBJEXT) \2.55 @BUILD_SH4X86_TRUE@ dis-init.$(OBJEXT) dis-buf.$(OBJEXT)2.56 @@ -349,17 +348,17 @@2.57 sh4mmio.$(OBJEXT) scif.$(OBJEXT) sh4stat.$(OBJEXT) \2.58 xltcache.$(OBJEXT) armcore.$(OBJEXT) armdasm.$(OBJEXT) \2.59 armmem.$(OBJEXT) aica.$(OBJEXT) audio.$(OBJEXT) pvr2.$(OBJEXT) \2.60 - pvr2mem.$(OBJEXT) tacore.$(OBJEXT) render.$(OBJEXT) \2.61 - rendcore.$(OBJEXT) rendbkg.$(OBJEXT) rendsort.$(OBJEXT) \2.62 - texcache.$(OBJEXT) yuv.$(OBJEXT) rendsave.$(OBJEXT) \2.63 - scene.$(OBJEXT) gl_sl.$(OBJEXT) gl_slsrc.$(OBJEXT) \2.64 - glutil.$(OBJEXT) glrender.$(OBJEXT) maple.$(OBJEXT) \2.65 - controller.$(OBJEXT) kbd.$(OBJEXT) mouse.$(OBJEXT) \2.66 - loader.$(OBJEXT) bootstrap.$(OBJEXT) util.$(OBJEXT) \2.67 - display.$(OBJEXT) audio_null.$(OBJEXT) video_null.$(OBJEXT) \2.68 - video_gl.$(OBJEXT) gl_fbo.$(OBJEXT) $(am__objects_1) \2.69 - $(am__objects_2) $(am__objects_3) $(am__objects_4) \2.70 - $(am__objects_5) $(am__objects_6) $(am__objects_7)2.71 + pvr2mem.$(OBJEXT) tacore.$(OBJEXT) rendbkg.$(OBJEXT) \2.72 + rendsort.$(OBJEXT) texcache.$(OBJEXT) yuv.$(OBJEXT) \2.73 + rendsave.$(OBJEXT) scene.$(OBJEXT) gl_sl.$(OBJEXT) \2.74 + gl_slsrc.$(OBJEXT) glutil.$(OBJEXT) glrender.$(OBJEXT) \2.75 + maple.$(OBJEXT) controller.$(OBJEXT) kbd.$(OBJEXT) \2.76 + mouse.$(OBJEXT) loader.$(OBJEXT) bootstrap.$(OBJEXT) \2.77 + util.$(OBJEXT) display.$(OBJEXT) audio_null.$(OBJEXT) \2.78 + video_null.$(OBJEXT) video_gl.$(OBJEXT) gl_fbo.$(OBJEXT) \2.79 + $(am__objects_1) $(am__objects_2) $(am__objects_3) \2.80 + $(am__objects_4) $(am__objects_5) $(am__objects_6) \2.81 + $(am__objects_7)2.82 lxdream_OBJECTS = $(am_lxdream_OBJECTS)2.83 lxdream_DEPENDENCIES =2.84 lxdream_LDFLAGS =2.85 @@ -416,7 +415,6 @@2.86 @AMDEP_TRUE@ ./$(DEPDIR)/mouse.Po ./$(DEPDIR)/nrg.Po \2.87 @AMDEP_TRUE@ ./$(DEPDIR)/path_dlg.Po ./$(DEPDIR)/pvr2.Po \2.88 @AMDEP_TRUE@ ./$(DEPDIR)/pvr2mem.Po ./$(DEPDIR)/rendbkg.Po \2.89 -@AMDEP_TRUE@ ./$(DEPDIR)/rendcore.Po ./$(DEPDIR)/render.Po \2.90 @AMDEP_TRUE@ ./$(DEPDIR)/rendsave.Po ./$(DEPDIR)/rendsort.Po \2.91 @AMDEP_TRUE@ ./$(DEPDIR)/scene.Po ./$(DEPDIR)/scif.Po \2.92 @AMDEP_TRUE@ ./$(DEPDIR)/sh4.Po ./$(DEPDIR)/sh4core.Po \2.93 @@ -564,8 +562,6 @@2.94 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pvr2.Po@am__quote@2.95 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pvr2mem.Po@am__quote@2.96 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rendbkg.Po@am__quote@2.97 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rendcore.Po@am__quote@2.98 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/render.Po@am__quote@2.99 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rendsave.Po@am__quote@2.100 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rendsort.Po@am__quote@2.101 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scene.Po@am__quote@2.102 @@ -1277,50 +1273,6 @@2.103 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.104 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tacore.obj `if test -f 'pvr2/tacore.c'; then $(CYGPATH_W) 'pvr2/tacore.c'; else $(CYGPATH_W) '$(srcdir)/pvr2/tacore.c'; fi`2.106 -render.o: pvr2/render.c2.107 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT render.o -MD -MP -MF "$(DEPDIR)/render.Tpo" \2.108 -@am__fastdepCC_TRUE@ -c -o render.o `test -f 'pvr2/render.c' || echo '$(srcdir)/'`pvr2/render.c; \2.109 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/render.Tpo" "$(DEPDIR)/render.Po"; \2.110 -@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/render.Tpo"; exit 1; \2.111 -@am__fastdepCC_TRUE@ fi2.112 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pvr2/render.c' object='render.o' libtool=no @AMDEPBACKSLASH@2.113 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/render.Po' tmpdepfile='$(DEPDIR)/render.TPo' @AMDEPBACKSLASH@2.114 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.115 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o render.o `test -f 'pvr2/render.c' || echo '$(srcdir)/'`pvr2/render.c2.116 -2.117 -render.obj: pvr2/render.c2.118 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT render.obj -MD -MP -MF "$(DEPDIR)/render.Tpo" \2.119 -@am__fastdepCC_TRUE@ -c -o render.obj `if test -f 'pvr2/render.c'; then $(CYGPATH_W) 'pvr2/render.c'; else $(CYGPATH_W) '$(srcdir)/pvr2/render.c'; fi`; \2.120 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/render.Tpo" "$(DEPDIR)/render.Po"; \2.121 -@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/render.Tpo"; exit 1; \2.122 -@am__fastdepCC_TRUE@ fi2.123 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pvr2/render.c' object='render.obj' libtool=no @AMDEPBACKSLASH@2.124 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/render.Po' tmpdepfile='$(DEPDIR)/render.TPo' @AMDEPBACKSLASH@2.125 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.126 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o render.obj `if test -f 'pvr2/render.c'; then $(CYGPATH_W) 'pvr2/render.c'; else $(CYGPATH_W) '$(srcdir)/pvr2/render.c'; fi`2.127 -2.128 -rendcore.o: pvr2/rendcore.c2.129 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rendcore.o -MD -MP -MF "$(DEPDIR)/rendcore.Tpo" \2.130 -@am__fastdepCC_TRUE@ -c -o rendcore.o `test -f 'pvr2/rendcore.c' || echo '$(srcdir)/'`pvr2/rendcore.c; \2.131 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/rendcore.Tpo" "$(DEPDIR)/rendcore.Po"; \2.132 -@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/rendcore.Tpo"; exit 1; \2.133 -@am__fastdepCC_TRUE@ fi2.134 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pvr2/rendcore.c' object='rendcore.o' libtool=no @AMDEPBACKSLASH@2.135 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/rendcore.Po' tmpdepfile='$(DEPDIR)/rendcore.TPo' @AMDEPBACKSLASH@2.136 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.137 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rendcore.o `test -f 'pvr2/rendcore.c' || echo '$(srcdir)/'`pvr2/rendcore.c2.138 -2.139 -rendcore.obj: pvr2/rendcore.c2.140 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rendcore.obj -MD -MP -MF "$(DEPDIR)/rendcore.Tpo" \2.141 -@am__fastdepCC_TRUE@ -c -o rendcore.obj `if test -f 'pvr2/rendcore.c'; then $(CYGPATH_W) 'pvr2/rendcore.c'; else $(CYGPATH_W) '$(srcdir)/pvr2/rendcore.c'; fi`; \2.142 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/rendcore.Tpo" "$(DEPDIR)/rendcore.Po"; \2.143 -@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/rendcore.Tpo"; exit 1; \2.144 -@am__fastdepCC_TRUE@ fi2.145 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pvr2/rendcore.c' object='rendcore.obj' libtool=no @AMDEPBACKSLASH@2.146 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/rendcore.Po' tmpdepfile='$(DEPDIR)/rendcore.TPo' @AMDEPBACKSLASH@2.147 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.148 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rendcore.obj `if test -f 'pvr2/rendcore.c'; then $(CYGPATH_W) 'pvr2/rendcore.c'; else $(CYGPATH_W) '$(srcdir)/pvr2/rendcore.c'; fi`2.149 -2.150 rendbkg.o: pvr2/rendbkg.c2.151 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rendbkg.o -MD -MP -MF "$(DEPDIR)/rendbkg.Tpo" \2.152 @am__fastdepCC_TRUE@ -c -o rendbkg.o `test -f 'pvr2/rendbkg.c' || echo '$(srcdir)/'`pvr2/rendbkg.c; \
3.1 --- a/src/pvr2/gl_slsrc.c Mon Feb 18 09:21:43 2008 +00003.2 +++ b/src/pvr2/gl_slsrc.c Thu Mar 06 08:22:00 2008 +00003.3 @@ -6,8 +6,8 @@3.4 \n\3.5 void main()\n\3.6 {\n\3.7 - gl_Position.xy = ftransform().xy;\n\3.8 - gl_Position.z = gl_Vertex.z;\n\3.9 + gl_Position = ftransform();\n\3.10 +// gl_Position.z = log(gl_Vertex.z);\n\3.11 gl_FrontColor = gl_Color;\n\3.12 gl_FrontSecondaryColor = gl_SecondaryColor;\n\3.13 gl_TexCoord[0] = gl_MultiTexCoord0;\n\
4.1 --- a/src/pvr2/glrender.c Mon Feb 18 09:21:43 2008 +00004.2 +++ b/src/pvr2/glrender.c Thu Mar 06 08:22:00 2008 +00004.3 @@ -16,10 +16,33 @@4.4 * GNU General Public License for more details.4.5 */4.7 +#include <assert.h>4.8 #include "display.h"4.9 #include "pvr2/pvr2.h"4.10 #include "pvr2/scene.h"4.12 +int pvr2_poly_depthmode[8] = { GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL,4.13 + GL_GREATER, GL_NOTEQUAL, GL_GEQUAL,4.14 + GL_ALWAYS };4.15 +int pvr2_poly_srcblend[8] = {4.16 + GL_ZERO, GL_ONE, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR,4.17 + GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA,4.18 + GL_ONE_MINUS_DST_ALPHA };4.19 +int pvr2_poly_dstblend[8] = {4.20 + GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR,4.21 + GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA,4.22 + GL_ONE_MINUS_DST_ALPHA };4.23 +int pvr2_poly_texblend[4] = {4.24 + GL_REPLACE,4.25 + GL_MODULATE,4.26 + GL_DECAL,4.27 + GL_MODULATE4.28 +};4.29 +int pvr2_render_colour_format[8] = {4.30 + COLFMT_BGRA1555, COLFMT_RGB565, COLFMT_BGRA4444, COLFMT_BGRA1555,4.31 + COLFMT_BGR888, COLFMT_BGRA8888, COLFMT_BGRA8888, COLFMT_BGRA4444 };4.32 +4.33 +4.34 /**4.35 * Clip the tile bounds to the clipping plane.4.36 * @return TRUE if the tile was not clipped completely.4.37 @@ -33,13 +56,35 @@4.38 return tile[0] < tile[1] && tile[2] < tile[3];4.39 }4.41 +void pvr2_scene_load_textures()4.42 +{4.43 + int i;4.44 + for( i=0; i < pvr2_scene.poly_count; i++ ) {4.45 + struct polygon_struct *poly = &pvr2_scene.poly_array[i];4.46 + if( POLY1_TEXTURED(poly->context[0]) ) {4.47 + poly->tex_id = texcache_get_texture( poly->context[2],4.48 + POLY2_TEX_WIDTH(poly->context[1]),4.49 + POLY2_TEX_HEIGHT(poly->context[1]) );4.50 + if( poly->mod_vertex_index != -1 ) {4.51 + poly->mod_tex_id = texcache_get_texture( poly->context[4],4.52 + POLY2_TEX_WIDTH(poly->context[3]),4.53 + POLY2_TEX_HEIGHT(poly->context[3]) );4.54 + }4.55 + } else {4.56 + poly->tex_id = -1;4.57 + poly->mod_tex_id = -1;4.58 + }4.59 + }4.60 +}4.61 +4.62 +4.63 +4.64 /**4.65 * Once-off call to setup the OpenGL context.4.66 */4.67 void pvr2_setup_gl_context()4.68 {4.69 texcache_gl_init(); // Allocate texture IDs4.70 - glShadeModel(GL_SMOOTH);4.71 glCullFace( GL_BACK );4.72 glEnable( GL_BLEND );4.73 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);4.74 @@ -56,13 +101,111 @@4.75 glClearStencil(0);4.76 }4.78 +/**4.79 + * Setup the GL context for the supplied polygon context.4.80 + * @param context pointer to 3 or 5 words of polygon context4.81 + * @param modified boolean flag indicating that the modified4.82 + * version should be used, rather than the normal version.4.83 + */4.84 +void render_set_context( uint32_t *context, int render_mode )4.85 +{4.86 + uint32_t poly1 = context[0], poly2, texture;4.87 + if( render_mode == RENDER_FULLMOD ) {4.88 + poly2 = context[3];4.89 + texture = context[4];4.90 + } else {4.91 + poly2 = context[1];4.92 + texture = context[2];4.93 + }4.94 +4.95 + if( POLY1_DEPTH_ENABLE(poly1) ) {4.96 + glEnable( GL_DEPTH_TEST );4.97 + glDepthFunc( POLY1_DEPTH_MODE(poly1) );4.98 + } else {4.99 + glDisable( GL_DEPTH_TEST );4.100 + }4.101 +4.102 + switch( POLY1_CULL_MODE(poly1) ) {4.103 + case CULL_NONE:4.104 + case CULL_SMALL:4.105 + glDisable( GL_CULL_FACE );4.106 + break;4.107 + case CULL_CCW:4.108 + glEnable( GL_CULL_FACE );4.109 + glFrontFace( GL_CW );4.110 + break;4.111 + case CULL_CW:4.112 + glEnable( GL_CULL_FACE );4.113 + glFrontFace( GL_CCW );4.114 + break;4.115 + }4.116 +4.117 + if( POLY1_SPECULAR(poly1) ) {4.118 + glEnable(GL_COLOR_SUM);4.119 + } else {4.120 + glDisable(GL_COLOR_SUM);4.121 + }4.122 +4.123 +4.124 + if( POLY1_TEXTURED(poly1) ) {4.125 + int width = POLY2_TEX_WIDTH(poly2);4.126 + int height = POLY2_TEX_HEIGHT(poly2);4.127 + glEnable(GL_TEXTURE_2D);4.128 + switch( POLY2_TEX_BLEND(poly2) ) {4.129 + case 0: /* Replace */4.130 + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );4.131 + break;4.132 + case 2:/* Decal */4.133 + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );4.134 + break;4.135 + case 1: /* Modulate RGB */4.136 + /* This is not directly supported by opengl (other than by mucking4.137 + * with the texture format), but we get the same effect by forcing4.138 + * the fragment alpha to 1.0 and using GL_MODULATE.4.139 + */4.140 + case 3: /* Modulate RGBA */4.141 + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );4.142 + break;4.143 + }4.144 +4.145 + if( POLY2_TEX_CLAMP_U(poly2) ) {4.146 + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );4.147 + } else {4.148 + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );4.149 + }4.150 + if( POLY2_TEX_CLAMP_V(poly2) ) {4.151 + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );4.152 + } else {4.153 + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );4.154 + }4.155 + } else {4.156 + glDisable( GL_TEXTURE_2D );4.157 + }4.158 +4.159 + glShadeModel( POLY1_SHADE_MODEL(poly1) );4.160 +4.161 + int srcblend = POLY2_SRC_BLEND(poly2);4.162 + int destblend = POLY2_DEST_BLEND(poly2);4.163 + glBlendFunc( srcblend, destblend );4.164 +4.165 + if( POLY2_SRC_BLEND_TARGET(poly2) || POLY2_DEST_BLEND_TARGET(poly2) ) {4.166 + ERROR( "Accumulation buffer not supported" );4.167 + }4.168 +4.169 +}4.170 +4.171 +4.172 static void gl_render_poly( struct polygon_struct *poly )4.173 {4.174 + if( poly->tex_id != -1 ) {4.175 + glBindTexture(GL_TEXTURE_2D, poly->tex_id);4.176 + }4.177 render_set_context( poly->context, RENDER_NORMAL );4.178 glDrawArrays(GL_TRIANGLE_STRIP, poly->vertex_index, poly->vertex_count );4.179 +4.180 }4.182 -static void gl_render_tilelist( pvraddr_t tile_entry )4.183 +void gl_render_tilelist( pvraddr_t tile_entry )4.184 {4.185 uint32_t *tile_list = (uint32_t *)(video_base+tile_entry);4.186 int strip_count;4.187 @@ -76,21 +219,21 @@4.188 case 0x0E:4.189 tile_list = (uint32_t *)(video_base + (entry&0x007FFFFF));4.190 break;4.191 - case 0x08:4.192 - case 0x09:4.193 - case 0x0A:4.194 - case 0x0B:4.195 + case 0x08: case 0x09: case 0x0A: case 0x0B:4.196 strip_count = ((entry >> 25) & 0x0F)+1;4.197 poly = pvr2_scene.buf_to_poly_map[entry&0x000FFFFF];4.198 while( strip_count > 0 ) {4.199 + assert( poly != NULL );4.200 gl_render_poly( poly );4.201 poly = poly->next;4.202 strip_count--;4.203 }4.204 break;4.205 default:4.206 - poly = pvr2_scene.buf_to_poly_map[entry&0x000FFFFF];4.207 - gl_render_poly( poly );4.208 + if( entry & 0x7E000000 ) {4.209 + poly = pvr2_scene.buf_to_poly_map[entry&0x000FFFFF];4.210 + gl_render_poly( poly );4.211 + }4.212 }4.213 }4.214 }4.215 @@ -102,8 +245,17 @@4.216 void pvr2_scene_render( render_buffer_t buffer )4.217 {4.218 /* Scene setup */4.219 + struct timeval start_tv, tex_tv, end_tv;4.220 +4.221 + gettimeofday(&start_tv, NULL);4.222 display_driver->set_render_target(buffer);4.223 pvr2_check_palette_changed();4.224 + pvr2_scene_load_textures();4.225 +4.226 + gettimeofday( &tex_tv, NULL );4.227 + uint32_t ms = (tex_tv.tv_sec - start_tv.tv_sec) * 1000 +4.228 + (tex_tv.tv_usec - start_tv.tv_usec)/1000;4.229 + DEBUG( "Scene setup in %dms", ms );4.231 /* Setup view projection matrix */4.232 glMatrixMode(GL_PROJECTION);4.233 @@ -114,7 +266,7 @@4.234 farz*= 2.0;4.235 }4.236 glOrtho( 0, pvr2_scene.buffer_width, pvr2_scene.buffer_height, 0,4.237 - -nearz, -farz );4.238 + -nearz, -farz );4.240 /* Clear the buffer (FIXME: May not want always want to do this) */4.241 glDisable( GL_SCISSOR_TEST );4.242 @@ -148,7 +300,12 @@4.243 gl_render_tilelist(segment->opaque_ptr);4.244 }4.245 if( IS_TILE_PTR(segment->trans_ptr) ) {4.246 - gl_render_tilelist(segment->trans_ptr);4.247 + if( pvr2_scene.sort_mode == SORT_NEVER ||4.248 + (pvr2_scene.sort_mode == SORT_TILEFLAG && (segment->control&SEGMENT_SORT_TRANS))) {4.249 + gl_render_tilelist(segment->trans_ptr);4.250 + } else {4.251 + render_autosort_tile(segment->trans_ptr, RENDER_NORMAL, !pvr2_scene.full_shadow);4.252 + }4.253 }4.254 if( IS_TILE_PTR(segment->punchout_ptr) ) {4.255 gl_render_tilelist(segment->punchout_ptr);4.256 @@ -156,4 +313,8 @@4.257 } while( !IS_LAST_SEGMENT(segment++) );4.258 glDisable( GL_SCISSOR_TEST );4.260 + gettimeofday( &end_tv, NULL );4.261 + ms = (end_tv.tv_sec - tex_tv.tv_sec) * 1000 +4.262 + (end_tv.tv_usec - tex_tv.tv_usec)/1000;4.263 + DEBUG( "Scene render in %dms", ms );4.264 }
5.1 --- a/src/pvr2/glutil.c Mon Feb 18 09:21:43 2008 +00005.2 +++ b/src/pvr2/glutil.c Thu Mar 06 08:22:00 2008 +00005.3 @@ -15,7 +15,7 @@5.4 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the5.5 * GNU General Public License for more details.5.6 */5.7 -5.8 +#include <string.h>5.9 #include "pvr2/glutil.h"5.11 /**5.12 @@ -34,6 +34,11 @@5.13 if (where || *extension == '\0')5.14 return 0;5.15 extensions = glGetString(GL_EXTENSIONS);5.16 + if( extensions == NULL ) {5.17 + /* No GL available, so we're pretty sure the extension isn't5.18 + * available either. */5.19 + return FALSE;5.20 + }5.21 /* It takes a bit of care to be fool-proof about parsing the5.22 OpenGL extensions string. Don't be fooled by sub-strings,5.23 etc. */
6.1 --- a/src/pvr2/pvr2.c Mon Feb 18 09:21:43 2008 +00006.2 +++ b/src/pvr2/pvr2.c Thu Mar 06 08:22:00 2008 +00006.3 @@ -203,12 +203,17 @@6.4 }6.6 render_buffer_t buffer = pvr2_frame_buffer_to_render_buffer(frame);6.7 - assert( buffer != NULL );6.8 - fread( &buffer->rowstride, sizeof(buffer->rowstride), 1, f );6.9 - fread( &buffer->colour_format, sizeof(buffer->colour_format), 1, f );6.10 - fread( &buffer->address, sizeof(buffer->address), 1, f );6.11 - fread( &buffer->scale, sizeof(buffer->scale), 1, f );6.12 - fread( &buffer->flushed, sizeof(buffer->flushed), 1, f );6.13 + if( buffer != NULL ) {6.14 + fread( &buffer->rowstride, sizeof(buffer->rowstride), 1, f );6.15 + fread( &buffer->colour_format, sizeof(buffer->colour_format), 1, f );6.16 + fread( &buffer->address, sizeof(buffer->address), 1, f );6.17 + fread( &buffer->scale, sizeof(buffer->scale), 1, f );6.18 + fread( &buffer->flushed, sizeof(buffer->flushed), 1, f );6.19 + } else {6.20 + fseek( f, sizeof(buffer->rowstride)+sizeof(buffer->colour_format)+6.21 + sizeof(buffer->address)+sizeof(buffer->scale)+6.22 + sizeof(buffer->flushed), SEEK_CUR );6.23 + }6.24 return buffer;6.25 }6.27 @@ -258,9 +263,7 @@6.28 }6.30 for( i=0; i<count; i++ ) {6.31 - if( pvr2_load_render_buffer( f ) == NULL ) {6.32 - return FALSE;6.33 - }6.34 + pvr2_load_render_buffer( f );6.35 }6.36 return TRUE;6.37 }
7.1 --- a/src/pvr2/pvr2.h Mon Feb 18 09:21:43 2008 +00007.2 +++ b/src/pvr2/pvr2.h Thu Mar 06 08:22:00 2008 +00007.3 @@ -343,8 +343,7 @@7.4 * If the texture has already been bound, return the ID to which it was7.5 * bound. Otherwise obtain an unused texture ID and set it up appropriately.7.6 */7.7 -GLuint texcache_get_texture( uint32_t texture_addr, int width, int height,7.8 - int mode );7.9 +GLuint texcache_get_texture( uint32_t texture_word, int width, int height );7.11 void pvr2_check_palette_changed(void);7.13 @@ -355,6 +354,7 @@7.14 #define POLY1_DEPTH_MODE(poly1) ( pvr2_poly_depthmode[(poly1)>>29] )7.15 #define POLY1_DEPTH_ENABLE(poly1) (((poly1)&0x04000000) == 0 )7.16 #define POLY1_CULL_MODE(poly1) (((poly1)>>27)&0x03)7.17 +#define POLY1_CULL_ENABLE(poly1) (((poly1)>>28)&0x01)7.18 #define POLY1_TEXTURED(poly1) (((poly1)&0x02000000))7.19 #define POLY1_SPECULAR(poly1) (((poly1)&0x01000000))7.20 #define POLY1_GOURAUD_SHADED(poly1) ((poly1)&0x00800000)7.21 @@ -381,8 +381,6 @@7.22 extern int pvr2_poly_texblend[4];7.23 extern int pvr2_render_colour_format[8];7.25 -float halftofloat(uint16_t half);7.26 -7.27 #define CULL_NONE 07.28 #define CULL_SMALL 17.29 #define CULL_CCW 2
8.1 --- a/src/pvr2/pvr2mem.c Mon Feb 18 09:21:43 2008 +00008.2 +++ b/src/pvr2/pvr2mem.c Thu Mar 06 08:22:00 2008 +00008.3 @@ -15,10 +15,11 @@8.4 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the8.5 * GNU General Public License for more details.8.6 */8.7 +#include <string.h>8.8 +#include <stdio.h>8.9 +#include <errno.h>8.10 #include "pvr2.h"8.11 #include "asic.h"8.12 -#include <stdio.h>8.13 -#include <errno.h>8.15 extern unsigned char *video_base;
9.1 --- a/src/pvr2/rendbkg.c Mon Feb 18 09:21:43 2008 +00009.2 +++ b/src/pvr2/rendbkg.c Thu Mar 06 08:22:00 2008 +00009.3 @@ -49,6 +49,70 @@9.4 #define FARGB_B(x) (((float)(((x)&0xFF)+1))/256.0)9.6 /**9.7 + * Convert a half-float (16-bit) FP number to a regular 32-bit float.9.8 + * Source is 1-bit sign, 5-bit exponent, 10-bit mantissa.9.9 + * TODO: Check the correctness of this.9.10 + */9.11 +static float halftofloat( uint16_t half )9.12 +{9.13 + union {9.14 + float f;9.15 + uint32_t i;9.16 + } temp;9.17 + /* int e = ((half & 0x7C00) >> 10) - 15 + 127;9.18 +9.19 + temp.i = ((half & 0x8000) << 16) | (e << 23) |9.20 + ((half & 0x03FF) << 13); */9.21 + temp.i = ((uint32_t)half)<<16;9.22 + return temp.f;9.23 +}9.24 +9.25 +void render_unpack_vertexes( struct vertex_unpacked *out, uint32_t poly1,9.26 + uint32_t *vertexes, int num_vertexes,9.27 + int vertex_size, int render_mode )9.28 +{9.29 + int m = 0, i;9.30 + if( render_mode == RENDER_FULLMOD ) {9.31 + m = (vertex_size - 3)/2;9.32 + }9.33 +9.34 + for( i=0; i<num_vertexes; i++ ) {9.35 + float *vertexf = (float *)vertexes;9.36 + int k = m + 3;9.37 + out[i].x = vertexf[0];9.38 + out[i].y = vertexf[1];9.39 + out[i].z = vertexf[2];9.40 + if( POLY1_TEXTURED(poly1) ) {9.41 + if( POLY1_UV16(poly1) ) {9.42 + out[i].u = halftofloat(vertexes[k]>>16);9.43 + out[i].v = halftofloat(vertexes[k]);9.44 + k++;9.45 + } else {9.46 + out[i].u = vertexf[k];9.47 + out[i].v = vertexf[k+1];9.48 + k+=2;9.49 + }9.50 + } else {9.51 + out[i].u = 0;9.52 + out[i].v = 0;9.53 + }9.54 + uint32_t argb = vertexes[k++];9.55 + out[i].rgba[0] = FARGB_R(argb);9.56 + out[i].rgba[1] = FARGB_G(argb);9.57 + out[i].rgba[2] = FARGB_B(argb);9.58 + out[i].rgba[3] = FARGB_A(argb);9.59 + if( POLY1_SPECULAR(poly1) ) {9.60 + uint32_t offset = vertexes[k++];9.61 + out[i].offset_rgba[0] = FARGB_R(offset);9.62 + out[i].offset_rgba[1] = FARGB_G(offset);9.63 + out[i].offset_rgba[2] = FARGB_B(offset);9.64 + out[i].offset_rgba[3] = FARGB_A(offset);9.65 + }9.66 + vertexes += vertex_size;9.67 + }9.68 +}9.69 +9.70 +/**9.71 * Compute the line where k = target_k, (where k is normally one of9.72 * r,g,b,a, or z) and determines the points at which the line intersects9.73 * the viewport (0,0,width,height).
10.1 --- a/src/pvr2/rendcore.c Mon Feb 18 09:21:43 2008 +000010.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +000010.3 @@ -1,767 +0,0 @@10.4 -/**10.5 - * $Id$10.6 - *10.7 - * PVR2 renderer core.10.8 - *10.9 - * Copyright (c) 2005 Nathan Keynes.10.10 - *10.11 - * This program is free software; you can redistribute it and/or modify10.12 - * it under the terms of the GNU General Public License as published by10.13 - * the Free Software Foundation; either version 2 of the License, or10.14 - * (at your option) any later version.10.15 - *10.16 - * This program is distributed in the hope that it will be useful,10.17 - * but WITHOUT ANY WARRANTY; without even the implied warranty of10.18 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the10.19 - * GNU General Public License for more details.10.20 - */10.21 -#include <sys/time.h>10.22 -#include <assert.h>10.23 -#include <string.h>10.24 -#include "pvr2/pvr2.h"10.25 -#include "asic.h"10.26 -#include "display.h"10.27 -10.28 -int pvr2_poly_depthmode[8] = { GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL,10.29 - GL_GREATER, GL_NOTEQUAL, GL_GEQUAL,10.30 - GL_ALWAYS };10.31 -int pvr2_poly_srcblend[8] = {10.32 - GL_ZERO, GL_ONE, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR,10.33 - GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA,10.34 - GL_ONE_MINUS_DST_ALPHA };10.35 -int pvr2_poly_dstblend[8] = {10.36 - GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR,10.37 - GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA,10.38 - GL_ONE_MINUS_DST_ALPHA };10.39 -int pvr2_poly_texblend[4] = {10.40 - GL_REPLACE,10.41 - GL_MODULATE,10.42 - GL_DECAL,10.43 - GL_MODULATE10.44 -};10.45 -int pvr2_render_colour_format[8] = {10.46 - COLFMT_BGRA1555, COLFMT_RGB565, COLFMT_BGRA4444, COLFMT_BGRA1555,10.47 - COLFMT_BGR888, COLFMT_BGRA8888, COLFMT_BGRA8888, COLFMT_BGRA4444 };10.48 -10.49 -extern char *video_base;10.50 -10.51 -gboolean pvr2_force_fragment_alpha = FALSE;10.52 -gboolean pvr2_debug_render = FALSE;10.53 -10.54 -10.55 -void render_print_tilelist( FILE *f, uint32_t tile_entry );10.56 -10.57 -/**10.58 - * Convert a half-float (16-bit) FP number to a regular 32-bit float.10.59 - * Source is 1-bit sign, 5-bit exponent, 10-bit mantissa.10.60 - * TODO: Check the correctness of this.10.61 - */10.62 -float halftofloat( uint16_t half )10.63 -{10.64 - union {10.65 - float f;10.66 - uint32_t i;10.67 - } temp;10.68 - /* int e = ((half & 0x7C00) >> 10) - 15 + 127;10.69 -10.70 - temp.i = ((half & 0x8000) << 16) | (e << 23) |10.71 - ((half & 0x03FF) << 13); */10.72 - temp.i = ((uint32_t)half)<<16;10.73 - return temp.f;10.74 -}10.75 -10.76 -10.77 -/**10.78 - * Setup the GL context for the supplied polygon context.10.79 - * @param context pointer to 3 or 5 words of polygon context10.80 - * @param modified boolean flag indicating that the modified10.81 - * version should be used, rather than the normal version.10.82 - */10.83 -void render_set_context( uint32_t *context, int render_mode )10.84 -{10.85 - uint32_t poly1 = context[0], poly2, texture;10.86 - if( render_mode == RENDER_FULLMOD ) {10.87 - poly2 = context[3];10.88 - texture = context[4];10.89 - } else {10.90 - poly2 = context[1];10.91 - texture = context[2];10.92 - }10.93 -10.94 - if( POLY1_DEPTH_ENABLE(poly1) ) {10.95 - glEnable( GL_DEPTH_TEST );10.96 - glDepthFunc( POLY1_DEPTH_MODE(poly1) );10.97 - } else {10.98 - glDisable( GL_DEPTH_TEST );10.99 - }10.100 -10.101 - switch( POLY1_CULL_MODE(poly1) ) {10.102 - case CULL_NONE:10.103 - case CULL_SMALL:10.104 - glDisable( GL_CULL_FACE );10.105 - break;10.106 - case CULL_CCW:10.107 - glEnable( GL_CULL_FACE );10.108 - glFrontFace( GL_CW );10.109 - break;10.110 - case CULL_CW:10.111 - glEnable( GL_CULL_FACE );10.112 - glFrontFace( GL_CCW );10.113 - break;10.114 - }10.115 -10.116 - if( POLY1_SPECULAR(poly1) ) {10.117 - glEnable(GL_COLOR_SUM);10.118 - } else {10.119 - glDisable(GL_COLOR_SUM);10.120 - }10.121 -10.122 - pvr2_force_fragment_alpha = POLY2_ALPHA_ENABLE(poly2) ? FALSE : TRUE;10.123 -10.124 - if( POLY1_TEXTURED(poly1) ) {10.125 - int width = POLY2_TEX_WIDTH(poly2);10.126 - int height = POLY2_TEX_HEIGHT(poly2);10.127 - glEnable(GL_TEXTURE_2D);10.128 - texcache_get_texture( (texture&0x000FFFFF)<<3, width, height, texture );10.129 - switch( POLY2_TEX_BLEND(poly2) ) {10.130 - case 0: /* Replace */10.131 - glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );10.132 - break;10.133 - case 2:/* Decal */10.134 - glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );10.135 - break;10.136 - case 1: /* Modulate RGB */10.137 - /* This is not directly supported by opengl (other than by mucking10.138 - * with the texture format), but we get the same effect by forcing10.139 - * the fragment alpha to 1.0 and using GL_MODULATE.10.140 - */10.141 - pvr2_force_fragment_alpha = TRUE;10.142 - case 3: /* Modulate RGBA */10.143 - glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );10.144 - break;10.145 - }10.146 -10.147 - if( POLY2_TEX_CLAMP_U(poly2) ) {10.148 - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );10.149 - } else {10.150 - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );10.151 - }10.152 - if( POLY2_TEX_CLAMP_V(poly2) ) {10.153 - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );10.154 - } else {10.155 - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );10.156 - }10.157 - } else {10.158 - glDisable( GL_TEXTURE_2D );10.159 - }10.160 -10.161 - glShadeModel( POLY1_SHADE_MODEL(poly1) );10.162 -10.163 - int srcblend = POLY2_SRC_BLEND(poly2);10.164 - int destblend = POLY2_DEST_BLEND(poly2);10.165 - glBlendFunc( srcblend, destblend );10.166 -10.167 - if( POLY2_SRC_BLEND_TARGET(poly2) || POLY2_DEST_BLEND_TARGET(poly2) ) {10.168 - ERROR( "Accumulation buffer not supported" );10.169 - }10.170 -10.171 -10.172 -}10.173 -10.174 -#define FARGB_A(x) (((float)(((x)>>24)+1))/256.0)10.175 -#define FARGB_R(x) (((float)((((x)>>16)&0xFF)+1))/256.0)10.176 -#define FARGB_G(x) (((float)((((x)>>8)&0xFF)+1))/256.0)10.177 -#define FARGB_B(x) (((float)(((x)&0xFF)+1))/256.0)10.178 -10.179 -void render_unpack_vertexes( struct vertex_unpacked *out, uint32_t poly1,10.180 - uint32_t *vertexes, int num_vertexes,10.181 - int vertex_size, int render_mode )10.182 -{10.183 - int m = 0, i;10.184 - if( render_mode == RENDER_FULLMOD ) {10.185 - m = (vertex_size - 3)/2;10.186 - }10.187 -10.188 - for( i=0; i<num_vertexes; i++ ) {10.189 - float *vertexf = (float *)vertexes;10.190 - int k = m + 3;10.191 - out[i].x = vertexf[0];10.192 - out[i].y = vertexf[1];10.193 - out[i].z = vertexf[2];10.194 - if( POLY1_TEXTURED(poly1) ) {10.195 - if( POLY1_UV16(poly1) ) {10.196 - out[i].u = halftofloat(vertexes[k]>>16);10.197 - out[i].v = halftofloat(vertexes[k]);10.198 - k++;10.199 - } else {10.200 - out[i].u = vertexf[k];10.201 - out[i].v = vertexf[k+1];10.202 - k+=2;10.203 - }10.204 - } else {10.205 - out[i].u = 0;10.206 - out[i].v = 0;10.207 - }10.208 - uint32_t argb = vertexes[k++];10.209 - out[i].rgba[0] = FARGB_R(argb);10.210 - out[i].rgba[1] = FARGB_G(argb);10.211 - out[i].rgba[2] = FARGB_B(argb);10.212 - out[i].rgba[3] = FARGB_A(argb);10.213 - if( POLY1_SPECULAR(poly1) ) {10.214 - uint32_t offset = vertexes[k++];10.215 - out[i].offset_rgba[0] = FARGB_R(offset);10.216 - out[i].offset_rgba[1] = FARGB_G(offset);10.217 - out[i].offset_rgba[2] = FARGB_B(offset);10.218 - out[i].offset_rgba[3] = FARGB_A(offset);10.219 - }10.220 - vertexes += vertex_size;10.221 - }10.222 -}10.223 -10.224 -/**10.225 - * Unpack the vertexes for a quad, calculating the values for the last10.226 - * vertex.10.227 - * FIXME: Integrate this with rendbkg somehow10.228 - */10.229 -void render_unpack_quad( struct vertex_unpacked *unpacked, uint32_t poly1,10.230 - uint32_t *vertexes, int vertex_size,10.231 - int render_mode )10.232 -{10.233 - int i;10.234 - struct vertex_unpacked diff0, diff1;10.235 -10.236 - render_unpack_vertexes( unpacked, poly1, vertexes, 3, vertex_size, render_mode );10.237 -10.238 - diff0.x = unpacked[0].x - unpacked[1].x;10.239 - diff0.y = unpacked[0].y - unpacked[1].y;10.240 - diff1.x = unpacked[2].x - unpacked[1].x;10.241 - diff1.y = unpacked[2].y - unpacked[1].y;10.242 -10.243 - float detxy = ((diff1.y) * (diff0.x)) - ((diff0.y) * (diff1.x));10.244 - float *vertexf = (float *)(vertexes+(vertex_size*3));10.245 - if( detxy == 0 ) {10.246 - memcpy( &unpacked[3], &unpacked[2], sizeof(struct vertex_unpacked) );10.247 - unpacked[3].x = vertexf[0];10.248 - unpacked[3].y = vertexf[1];10.249 - return;10.250 - }10.251 -10.252 - unpacked[3].x = vertexf[0];10.253 - unpacked[3].y = vertexf[1];10.254 - float t = ((unpacked[3].x - unpacked[1].x) * diff1.y -10.255 - (unpacked[3].y - unpacked[1].y) * diff1.x) / detxy;10.256 - float s = ((unpacked[3].y - unpacked[1].y) * diff0.x -10.257 - (unpacked[3].x - unpacked[1].x) * diff0.y) / detxy;10.258 - diff0.z = unpacked[0].z - unpacked[1].z;10.259 - diff1.z = unpacked[2].z - unpacked[1].z;10.260 - unpacked[3].z = unpacked[1].z + (t*diff0.z) + (s*diff1.z);10.261 -10.262 - diff0.u = unpacked[0].u - unpacked[1].u;10.263 - diff0.v = unpacked[0].v - unpacked[1].v;10.264 - diff1.u = unpacked[2].u - unpacked[1].u;10.265 - diff1.v = unpacked[2].v - unpacked[1].v;10.266 - unpacked[3].u = unpacked[1].u + (t*diff0.u) + (s*diff1.u);10.267 - unpacked[3].v = unpacked[1].v + (t*diff0.v) + (s*diff1.v);10.268 -10.269 - if( !POLY1_GOURAUD_SHADED(poly1) ) {10.270 - memcpy( unpacked[3].rgba, unpacked[2].rgba, sizeof(unpacked[2].rgba) );10.271 - memcpy( unpacked[3].offset_rgba, unpacked[2].offset_rgba, sizeof(unpacked[2].offset_rgba) );10.272 - } else {10.273 - for( i=0; i<4; i++ ) {10.274 - float d0 = unpacked[0].rgba[i] - unpacked[1].rgba[i];10.275 - float d1 = unpacked[2].rgba[i] - unpacked[1].rgba[i];10.276 - unpacked[3].rgba[i] = unpacked[1].rgba[i] + (t*d0) + (s*d1);10.277 - d0 = unpacked[0].offset_rgba[i] - unpacked[1].offset_rgba[i];10.278 - d1 = unpacked[2].offset_rgba[i] - unpacked[1].offset_rgba[i];10.279 - unpacked[3].offset_rgba[i] = unpacked[1].offset_rgba[i] + (t*d0) + (s*d1);10.280 - }10.281 - }10.282 -}10.283 -10.284 -void render_unpacked_vertex_array( uint32_t poly1, struct vertex_unpacked *vertexes[],10.285 - int num_vertexes ) {10.286 - int i;10.287 -10.288 - glBegin( GL_TRIANGLE_STRIP );10.289 -10.290 - for( i=0; i<num_vertexes; i++ ) {10.291 - if( POLY1_TEXTURED(poly1) ) {10.292 - glTexCoord2f( vertexes[i]->u, vertexes[i]->v );10.293 - }10.294 -10.295 - if( pvr2_force_fragment_alpha ) {10.296 - glColor4f( vertexes[i]->rgba[0], vertexes[i]->rgba[1], vertexes[i]->rgba[2], 1.0 );10.297 - } else {10.298 - glColor4f( vertexes[i]->rgba[0], vertexes[i]->rgba[1], vertexes[i]->rgba[2],10.299 - vertexes[i]->rgba[3] );10.300 - }10.301 - if( POLY1_SPECULAR(poly1) ) {10.302 - glSecondaryColor3fEXT( vertexes[i]->offset_rgba[0],10.303 - vertexes[i]->offset_rgba[1],10.304 - vertexes[i]->offset_rgba[2] );10.305 - }10.306 - assert( vertexes[i]->z > 0 && !isinf(vertexes[i]->z) );10.307 - glVertex3f( vertexes[i]->x, vertexes[i]->y, vertexes[i]->z );10.308 - }10.309 -10.310 - glEnd();10.311 -}10.312 -10.313 -void render_quad_vertexes( uint32_t poly1, uint32_t *vertexes, int vertex_size, int render_mode )10.314 -{10.315 - struct vertex_unpacked unpacked[4];10.316 - struct vertex_unpacked *pt[4] = {&unpacked[0], &unpacked[1], &unpacked[3], &unpacked[2]};10.317 - render_unpack_quad( unpacked, poly1, vertexes, vertex_size, render_mode );10.318 - render_unpacked_vertex_array( poly1, pt, 4 );10.319 -}10.320 -10.321 -void render_vertex_array( uint32_t poly1, uint32_t *vert_array[], int num_vertexes, int vertex_size,10.322 - int render_mode )10.323 -{10.324 - int i, m=0;10.325 -10.326 - if( render_mode == RENDER_FULLMOD ) {10.327 - m = (vertex_size - 3)/2;10.328 - }10.329 -10.330 - glBegin( GL_TRIANGLE_STRIP );10.331 -10.332 - for( i=0; i<num_vertexes; i++ ) {10.333 - uint32_t *vertexes = vert_array[i];10.334 - float *vertexf = (float *)vert_array[i];10.335 - uint32_t argb;10.336 - int k = m + 3;10.337 - if( POLY1_TEXTURED(poly1) ) {10.338 - if( POLY1_UV16(poly1) ) {10.339 - glTexCoord2f( halftofloat(vertexes[k]>>16),10.340 - halftofloat(vertexes[k]) );10.341 - k++;10.342 - } else {10.343 - glTexCoord2f( vertexf[k], vertexf[k+1] );10.344 - k+=2;10.345 - }10.346 - }10.347 -10.348 - argb = vertexes[k++];10.349 - if( pvr2_force_fragment_alpha ) {10.350 - glColor4ub( (GLubyte)(argb >> 16), (GLubyte)(argb >> 8),10.351 - (GLubyte)argb, 0xFF );10.352 - } else {10.353 - glColor4ub( (GLubyte)(argb >> 16), (GLubyte)(argb >> 8),10.354 - (GLubyte)argb, (GLubyte)(argb >> 24) );10.355 - }10.356 -10.357 - if( POLY1_SPECULAR(poly1) ) {10.358 - uint32_t spec = vertexes[k++];10.359 - glSecondaryColor3ubEXT( (GLubyte)(spec >> 16), (GLubyte)(spec >> 8),10.360 - (GLubyte)spec );10.361 - }10.362 - // assert( vertexf[2] > 0 && !isinf(vertexf[2]) );10.363 - glVertex3f( vertexf[0], vertexf[1], vertexf[2] );10.364 - vertexes += vertex_size;10.365 - }10.366 -10.367 - glEnd();10.368 -}10.369 -10.370 -void render_vertexes( uint32_t poly1, uint32_t *vertexes, int num_vertexes, int vertex_size,10.371 - int render_mode )10.372 -{10.373 - uint32_t *vert_array[num_vertexes];10.374 - int i;10.375 - for( i=0; i<num_vertexes; i++ ) {10.376 - vert_array[i] = vertexes;10.377 - vertexes += vertex_size;10.378 - }10.379 - render_vertex_array( poly1, vert_array, num_vertexes, vertex_size, render_mode );10.380 -}10.381 -10.382 -/**10.383 - * Render a simple (not auto-sorted) tile10.384 - */10.385 -void render_tile( pvraddr_t tile_entry, int render_mode, gboolean cheap_modifier_mode ) {10.386 - uint32_t poly_bank = MMIO_READ(PVR2,RENDER_POLYBASE);10.387 - uint32_t *tile_list = (uint32_t *)(video_base+tile_entry);10.388 - do {10.389 - uint32_t entry = *tile_list++;10.390 - if( entry >> 28 == 0x0F ) {10.391 - break;10.392 - } else if( entry >> 28 == 0x0E ) {10.393 - tile_list = (uint32_t *)(video_base + (entry&0x007FFFFF));10.394 - } else {10.395 - uint32_t *polygon = (uint32_t *)(video_base + poly_bank + ((entry & 0x000FFFFF) << 2));10.396 - int is_modified = entry & 0x01000000;10.397 - int vertex_length = (entry >> 21) & 0x07;10.398 - int context_length = 3;10.399 - if( is_modified && !cheap_modifier_mode ) {10.400 - context_length = 5;10.401 - vertex_length *= 2 ;10.402 - }10.403 - vertex_length += 3;10.404 -10.405 - if( (entry & 0xE0000000) == 0x80000000 ) {10.406 - /* Triangle(s) */10.407 - int strip_count = ((entry >> 25) & 0x0F)+1;10.408 - int polygon_length = 3 * vertex_length + context_length;10.409 - int i;10.410 - for( i=0; i<strip_count; i++ ) {10.411 - render_set_context( polygon, render_mode );10.412 - render_vertexes( *polygon, polygon+context_length, 3, vertex_length,10.413 - render_mode );10.414 - polygon += polygon_length;10.415 - }10.416 - } else if( (entry & 0xE0000000) == 0xA0000000 ) {10.417 - /* Sprite(s) */10.418 - int strip_count = ((entry >> 25) & 0x0F)+1;10.419 - int polygon_length = 4 * vertex_length + context_length;10.420 - int i;10.421 - for( i=0; i<strip_count; i++ ) {10.422 - render_set_context( polygon, render_mode );10.423 - render_quad_vertexes( *polygon, polygon+context_length, vertex_length,10.424 - render_mode );10.425 - polygon += polygon_length;10.426 - }10.427 - } else {10.428 - /* Polygon */10.429 - int i, first=-1, last = -1;10.430 - for( i=0; i<6; i++ ) {10.431 - if( entry & (0x40000000>>i) ) {10.432 - if( first == -1 ) first = i;10.433 - last = i;10.434 - }10.435 - }10.436 - if( first != -1 ) {10.437 - first = 0;10.438 - render_set_context(polygon, render_mode);10.439 - render_vertexes( *polygon, polygon+context_length + (first*vertex_length),10.440 - (last-first+3), vertex_length, render_mode );10.441 - }10.442 - }10.443 - }10.444 - } while( 1 );10.445 -}10.446 -10.447 -void pvr2_render_tilebuffer( int width, int height, int clipx1, int clipy1,10.448 - int clipx2, int clipy2 ) {10.449 -10.450 - pvraddr_t segmentbase = MMIO_READ( PVR2, RENDER_TILEBASE );10.451 - int tile_sort;10.452 - gboolean cheap_shadow;10.453 -10.454 - int obj_config = MMIO_READ( PVR2, RENDER_OBJCFG );10.455 - int isp_config = MMIO_READ( PVR2, RENDER_ISPCFG );10.456 - int shadow_cfg = MMIO_READ( PVR2, RENDER_SHADOW );10.457 -10.458 - if( (obj_config & 0x00200000) == 0 ) {10.459 - if( isp_config & 1 ) {10.460 - tile_sort = 0;10.461 - } else {10.462 - tile_sort = 2;10.463 - }10.464 - } else {10.465 - tile_sort = 1;10.466 - }10.467 -10.468 - cheap_shadow = shadow_cfg & 0x100 ? TRUE : FALSE;10.469 -10.470 - struct tile_segment *segment = (struct tile_segment *)(video_base + segmentbase);10.471 -10.472 - glEnable( GL_SCISSOR_TEST );10.473 - do {10.474 - // fwrite_dump32v( (uint32_t *)segment, sizeof(struct tile_segment), 6, stderr );10.475 - int tilex = SEGMENT_X(segment->control);10.476 - int tiley = SEGMENT_Y(segment->control);10.477 -10.478 - int x1 = tilex << 5;10.479 - int y1 = tiley << 5;10.480 - if( x1 + 32 <= clipx1 ||10.481 - y1 + 32 <= clipy1 ||10.482 - x1 >= clipx2 ||10.483 - y1 >= clipy2 ) {10.484 - /* Tile completely clipped, skip */10.485 - continue;10.486 - }10.487 -10.488 - /* Set a scissor on the visible part of the tile */10.489 - int w = MIN(x1+32, clipx2) - x1;10.490 - int h = MIN(y1+32, clipy2) - y1;10.491 - x1 = MAX(x1,clipx1);10.492 - y1 = MAX(y1,clipy1);10.493 - glScissor( x1, height-y1-h, w, h );10.494 -10.495 - if( (segment->opaque_ptr & NO_POINTER) == 0 ) {10.496 - if( pvr2_debug_render ) {10.497 - fprintf( stderr, "Tile %d,%d Opaque\n", tilex, tiley );10.498 - render_print_tilelist( stderr, segment->opaque_ptr );10.499 - }10.500 - if( (segment->opaquemod_ptr & NO_POINTER) == 0 ) {10.501 - /* TODO */10.502 - }10.503 - render_tile( segment->opaque_ptr, RENDER_NORMAL, cheap_shadow );10.504 - }10.505 -10.506 - if( (segment->trans_ptr & NO_POINTER) == 0 ) {10.507 - if( pvr2_debug_render ) {10.508 - fprintf( stderr, "Tile %d,%d Trans\n", tilex, tiley );10.509 - render_print_tilelist( stderr, segment->trans_ptr );10.510 - }10.511 - if( (segment->transmod_ptr & NO_POINTER) == 0 ) {10.512 - /* TODO */10.513 - }10.514 - if( tile_sort == 2 ||10.515 - (tile_sort == 1 && ((segment->control & SEGMENT_SORT_TRANS)==0)) ) {10.516 - render_autosort_tile( segment->trans_ptr, RENDER_NORMAL, cheap_shadow );10.517 - } else {10.518 - render_tile( segment->trans_ptr, RENDER_NORMAL, cheap_shadow );10.519 - }10.520 - }10.521 -10.522 - if( (segment->punchout_ptr & NO_POINTER) == 0 ) {10.523 - if( pvr2_debug_render ) {10.524 - fprintf( stderr, "Tile %d,%d Punchout\n", tilex, tiley );10.525 - render_print_tilelist( stderr, segment->punchout_ptr );10.526 - }10.527 - render_tile( segment->punchout_ptr, RENDER_NORMAL, cheap_shadow );10.528 - }10.529 - } while( ((segment++)->control & SEGMENT_END) == 0 );10.530 - glDisable( GL_SCISSOR_TEST );10.531 -}10.532 -10.533 -static void render_find_maximum_tile_z( pvraddr_t tile_entry, float *minimumz, float *maximumz )10.534 -{10.535 - uint32_t poly_bank = MMIO_READ(PVR2,RENDER_POLYBASE);10.536 - uint32_t *tile_list = (uint32_t *)(video_base+tile_entry);10.537 - int shadow_cfg = MMIO_READ( PVR2, RENDER_SHADOW ) & 0x100;10.538 - int i, j;10.539 - do {10.540 - uint32_t entry = *tile_list++;10.541 - if( entry >> 28 == 0x0F ) {10.542 - break;10.543 - } else if( entry >> 28 == 0x0E ) {10.544 - tile_list = (uint32_t *)(video_base + (entry&0x007FFFFF));10.545 - } else {10.546 - uint32_t *polygon = (uint32_t *)(video_base + poly_bank + ((entry & 0x000FFFFF) << 2));10.547 - int vertex_length = (entry >> 21) & 0x07;10.548 - int context_length = 3;10.549 - if( (entry & 0x01000000) && (shadow_cfg==0) ) {10.550 - context_length = 5;10.551 - vertex_length *= 2 ;10.552 - }10.553 - vertex_length += 3;10.554 - if( (entry & 0xE0000000) == 0x80000000 ) {10.555 - /* Triangle(s) */10.556 - int strip_count = ((entry >> 25) & 0x0F)+1;10.557 - float *vertexz = (float *)(polygon+context_length+2);10.558 - for( i=0; i<strip_count; i++ ) {10.559 - for( j=0; j<3; j++ ) {10.560 - if( *vertexz > *maximumz ) {10.561 - *maximumz = *vertexz;10.562 - } else if( *vertexz < *minimumz ) {10.563 - *minimumz = *vertexz;10.564 - }10.565 - vertexz += vertex_length;10.566 - }10.567 - vertexz += context_length;10.568 - }10.569 - } else if( (entry & 0xE0000000) == 0xA0000000 ) {10.570 - /* Sprite(s) */10.571 - int strip_count = ((entry >> 25) & 0x0F)+1;10.572 - int i;10.573 - float *vertexz = (float *)(polygon+context_length+2);10.574 - for( i=0; i<strip_count; i++ ) {10.575 - for( j=0; j<4; j++ ) {10.576 - if( *vertexz > *maximumz ) {10.577 - *maximumz = *vertexz;10.578 - } else if( *vertexz < *minimumz ) {10.579 - *minimumz = *vertexz;10.580 - }10.581 - vertexz += vertex_length;10.582 - }10.583 - vertexz+=context_length;10.584 - }10.585 - } else {10.586 - /* Polygon */10.587 - int i;10.588 - float *vertexz = (float *)polygon+context_length+2;10.589 - for( i=0; i<6; i++ ) {10.590 - if( (entry & (0x40000000>>i)) ) {10.591 - if( *vertexz > *maximumz ) {10.592 - *maximumz = *vertexz;10.593 - } else if( *vertexz < *minimumz ) {10.594 - *minimumz = *vertexz;10.595 - }10.596 - }10.597 - vertexz += vertex_length;10.598 - }10.599 - }10.600 - }10.601 - } while(1);10.602 -}10.603 -10.604 -/**10.605 - * Scan through the scene to determine the largest z value (in order to set up10.606 - * an appropriate near clip plane).10.607 - */10.608 -void pvr2_render_find_z_range( float *minimumz, float *maximumz )10.609 -{10.610 - pvraddr_t segmentbase = MMIO_READ( PVR2, RENDER_TILEBASE );10.611 - *minimumz = MMIO_READF( PVR2, RENDER_FARCLIP ); /* Initialize to the far clip plane */10.612 - *maximumz = *minimumz;10.613 -10.614 - struct tile_segment *segment = (struct tile_segment *)(video_base + segmentbase);10.615 - do {10.616 -10.617 - if( (segment->opaque_ptr & NO_POINTER) == 0 ) {10.618 - render_find_maximum_tile_z(segment->opaque_ptr, minimumz, maximumz);10.619 - }10.620 - if( (segment->opaquemod_ptr & NO_POINTER) == 0 ) {10.621 - render_find_maximum_tile_z(segment->opaquemod_ptr, minimumz, maximumz);10.622 - }10.623 - if( (segment->trans_ptr & NO_POINTER) == 0 ) {10.624 - render_find_maximum_tile_z(segment->trans_ptr, minimumz, maximumz);10.625 - }10.626 - if( (segment->transmod_ptr & NO_POINTER) == 0 ) {10.627 - render_find_maximum_tile_z(segment->transmod_ptr, minimumz, maximumz);10.628 - }10.629 - if( (segment->punchout_ptr & NO_POINTER) == 0 ) {10.630 - render_find_maximum_tile_z(segment->punchout_ptr, minimumz, maximumz);10.631 - }10.632 -10.633 - } while( ((segment++)->control & SEGMENT_END) == 0 );10.634 -}10.635 -10.636 -/**10.637 - * Scan the segment info to determine the width and height of the render (in10.638 - * pixels).10.639 - * @param x,y output values to receive the width and height info.10.640 - */10.641 -void pvr2_render_getsize( int *x, int *y )10.642 -{10.643 - pvraddr_t segmentbase = MMIO_READ( PVR2, RENDER_TILEBASE );10.644 - int maxx = 0, maxy = 0;10.645 -10.646 - struct tile_segment *segment = (struct tile_segment *)(video_base + segmentbase);10.647 - do {10.648 - int tilex = SEGMENT_X(segment->control);10.649 - int tiley = SEGMENT_Y(segment->control);10.650 - if( tilex > maxx ) {10.651 - maxx = tilex;10.652 - }10.653 - if( tiley > maxy ) {10.654 - maxy = tiley;10.655 - }10.656 - } while( ((segment++)->control & SEGMENT_END) == 0 );10.657 -10.658 - *x = (maxx+1)<<5;10.659 - *y = (maxy+1)<<5;10.660 -}10.661 -10.662 -void render_print_vertexes( FILE *f, uint32_t poly1, uint32_t *vert_array[],10.663 - int num_vertexes, int vertex_size )10.664 -{10.665 - char buf[256], *p;10.666 - int i, k;10.667 - for( i=0; i<num_vertexes; i++ ) {10.668 - p = buf;10.669 - float *vertf = (float *)vert_array[i];10.670 - uint32_t *verti = (uint32_t *)vert_array[i];10.671 - p += sprintf( p, " V %9.5f,%9.5f,%9.5f ", vertf[0], vertf[1], vertf[2] );10.672 - k = 3;10.673 - if( POLY1_TEXTURED(poly1) ) {10.674 - if( POLY1_UV16(poly1) ) {10.675 - p += sprintf( p, "uv=%9.5f,%9.5f ",10.676 - halftofloat(verti[k]>>16),10.677 - halftofloat(verti[k]) );10.678 - k++;10.679 - } else {10.680 - p += sprintf( p, "uv=%9.5f,%9.5f ", vertf[k], vertf[k+1] );10.681 - k+=2;10.682 - }10.683 - }10.684 -10.685 - p += sprintf( p, "%08X ", verti[k++] );10.686 - if( POLY1_SPECULAR(poly1) ) {10.687 - p += sprintf( p, "%08X", verti[k++] );10.688 - }10.689 - p += sprintf( p, "\n" );10.690 - fprintf( f, buf );10.691 - }10.692 -}10.693 -10.694 -void render_print_polygon( FILE *f, uint32_t entry )10.695 -{10.696 - uint32_t poly_bank = MMIO_READ(PVR2,RENDER_POLYBASE);10.697 - int shadow_cfg = MMIO_READ( PVR2, RENDER_SHADOW ) & 0x100;10.698 - int i;10.699 -10.700 - if( entry >> 28 == 0x0F ) {10.701 - fprintf( f, "EOT\n" );10.702 - } else if( entry >> 28 == 0x0E ) {10.703 - fprintf( f, "LINK %08X\n", entry &0x7FFFFF );10.704 - } else {10.705 - uint32_t *polygon = (uint32_t *)(video_base + poly_bank + ((entry & 0x000FFFFF) << 2));10.706 - int vertex_length = (entry >> 21) & 0x07;10.707 - int context_length = 3;10.708 - if( (entry & 0x01000000) && (shadow_cfg==0) ) {10.709 - context_length = 5;10.710 - vertex_length *= 2 ;10.711 - }10.712 - vertex_length += 3;10.713 - if( (entry & 0xE0000000) == 0x80000000 ) {10.714 - /* Triangle(s) */10.715 - int strip_count = ((entry >> 25) & 0x0F)+1;10.716 - for( i=0; i<strip_count; i++ ) {10.717 - fprintf( f, "TRI %08X %08X %08X\n", polygon[0], polygon[1], polygon[2] );10.718 - uint32_t *array[3];10.719 - array[0] = polygon + context_length;10.720 - array[1] = array[0] + vertex_length;10.721 - array[2] = array[1] + vertex_length;10.722 - render_print_vertexes( f, *polygon, array, 3, vertex_length );10.723 - polygon = array[2] + vertex_length;10.724 - }10.725 - } else if( (entry & 0xE0000000) == 0xA0000000 ) {10.726 - /* Sprite(s) */10.727 - int strip_count = ((entry >> 25) & 0x0F)+1;10.728 - for( i=0; i<strip_count; i++ ) {10.729 - fprintf( f, "QUAD %08X %08X %08X\n", polygon[0], polygon[1], polygon[2] );10.730 - uint32_t *array[4];10.731 - array[0] = polygon + context_length;10.732 - array[1] = array[0] + vertex_length;10.733 - array[2] = array[1] + vertex_length;10.734 - array[3] = array[2] + vertex_length;10.735 - render_print_vertexes( f, *polygon, array, 4, vertex_length );10.736 - polygon = array[3] + vertex_length;10.737 - }10.738 - } else {10.739 - /* Polygon */10.740 - int last = -1;10.741 - uint32_t *array[8];10.742 - for( i=0; i<6; i++ ) {10.743 - if( entry & (0x40000000>>i) ) {10.744 - last = i;10.745 - }10.746 - }10.747 - fprintf( f, "POLY %08X %08X %08X\n", polygon[0], polygon[1], polygon[2] );10.748 - for( i=0; i<last+2; i++ ) {10.749 - array[i] = polygon + context_length + vertex_length*i;10.750 - }10.751 - render_print_vertexes( f, *polygon, array, last+2, vertex_length );10.752 - }10.753 - }10.754 -}10.755 -10.756 -void render_print_tilelist( FILE *f, uint32_t tile_entry )10.757 -{10.758 - uint32_t *tile_list = (uint32_t *)(video_base+tile_entry);10.759 - do {10.760 - uint32_t entry = *tile_list++;10.761 - if( entry >> 28 == 0x0F ) {10.762 - break;10.763 - } else if( entry >> 28 == 0x0E ) {10.764 - tile_list = (uint32_t *)(video_base + (entry&0x007FFFFF));10.765 - } else {10.766 - render_print_polygon(f, entry);10.767 - }10.768 - } while( 1 );10.769 -}10.770 -
11.1 --- a/src/pvr2/render.c Mon Feb 18 09:21:43 2008 +000011.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +000011.3 @@ -1,153 +0,0 @@11.4 -/**11.5 - * $Id$11.6 - *11.7 - * PVR2 Renderer support. This part is primarily11.8 - *11.9 - * Copyright (c) 2005 Nathan Keynes.11.10 - *11.11 - * This program is free software; you can redistribute it and/or modify11.12 - * it under the terms of the GNU General Public License as published by11.13 - * the Free Software Foundation; either version 2 of the License, or11.14 - * (at your option) any later version.11.15 - *11.16 - * This program is distributed in the hope that it will be useful,11.17 - * but WITHOUT ANY WARRANTY; without even the implied warranty of11.18 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the11.19 - * GNU General Public License for more details.11.20 - */11.21 -11.22 -#include <sys/time.h>11.23 -#include <time.h>11.24 -#include <math.h>11.25 -#include "pvr2/pvr2.h"11.26 -#include "asic.h"11.27 -11.28 -11.29 -int pvr2_render_trace = 0;11.30 -11.31 -#if 011.32 -int pvr2_render_font_list = -1;11.33 -int glPrintf( int x, int y, const char *fmt, ... )11.34 -{11.35 - va_list ap; /* our argument pointer */11.36 - char buf[256];11.37 - int len;11.38 - if (fmt == NULL) /* if there is no string to draw do nothing */11.39 - return 0;11.40 - va_start(ap, fmt);11.41 - len = vsnprintf(buf, sizeof(buf), fmt, ap);11.42 - va_end(ap);11.43 -11.44 -11.45 - glPushAttrib(GL_LIST_BIT);11.46 - glDisable( GL_DEPTH_TEST );11.47 - glDisable( GL_BLEND );11.48 - glDisable( GL_TEXTURE_2D );11.49 - glDisable( GL_ALPHA_TEST );11.50 - glDisable( GL_CULL_FACE );11.51 - glListBase(pvr2_render_font_list - 32);11.52 - glColor3f( 1.0, 1.0, 1.0 );11.53 - glRasterPos2i( x, y );11.54 - glCallLists(len, GL_UNSIGNED_BYTE, buf);11.55 - glPopAttrib();11.56 -11.57 - return len;11.58 -}11.59 -#endif11.60 -11.61 -void glDrawGrid( int width, int height )11.62 -{11.63 - int i;11.64 - glDisable( GL_DEPTH_TEST );11.65 - glLineWidth(1);11.66 -11.67 - glBegin( GL_LINES );11.68 - glColor4f( 1.0, 1.0, 1.0, 1.0 );11.69 - for( i=32; i<width; i+=32 ) {11.70 - glVertex3f( i, 0.0, 3.0 );11.71 - glVertex3f( i,height-1, 3.0 );11.72 - }11.73 -11.74 - for( i=32; i<height; i+=32 ) {11.75 - glVertex3f( 0.0, i, 3.0 );11.76 - glVertex3f( width, i, 3.0 );11.77 - }11.78 - glEnd();11.79 -11.80 -}11.81 -11.82 -/**11.83 - * Prepare the OpenGL context to receive instructions for a new frame.11.84 - */11.85 -static void pvr2_render_prepare_context( render_buffer_t buffer,11.86 - float nearz, float farz )11.87 -{11.88 - /* Select and initialize the render context */11.89 - display_driver->set_render_target(buffer);11.90 -#if 011.91 - if( pvr2_render_font_list == -1 ) {11.92 - pvr2_render_font_list = video_glx_load_font( "-*-helvetica-*-r-normal--16-*-*-*-p-*-iso8859-1");11.93 - }11.94 -#endif11.95 - pvr2_check_palette_changed();11.96 -11.97 - /* Setup the display model */11.98 - glShadeModel(GL_SMOOTH);11.99 - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);11.100 - glMatrixMode(GL_PROJECTION);11.101 - glLoadIdentity();11.102 - glOrtho( 0, buffer->width, buffer->height, 0, -nearz, -farz );11.103 - glMatrixMode(GL_MODELVIEW);11.104 - glLoadIdentity();11.105 - glCullFace( GL_BACK );11.106 - glEnable( GL_BLEND );11.107 -11.108 - /* Clear out the buffers */11.109 - glDisable( GL_SCISSOR_TEST );11.110 - glClearColor(0.0f, 0.0f, 0.0f, 0.0f);11.111 - glClearDepth(0);11.112 - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );11.113 - glEnableClientState( GL_COLOR_ARRAY );11.114 - glEnableClientState( GL_VERTEX_ARRAY );11.115 -}11.116 -11.117 -/**11.118 - * Render a complete scene into the OpenGL back buffer.11.119 - * Note: this will probably need to be broken up eventually once timings are11.120 - * determined.11.121 - */11.122 -void pvr2_render_scene( render_buffer_t buffer )11.123 -{11.124 - struct timeval tva, tvb;11.125 -11.126 - gettimeofday(&tva, NULL);11.127 -11.128 - float farz, nearz;11.129 - pvr2_render_find_z_range( &nearz, &farz );11.130 - float bgplanez = MMIO_READF( PVR2, RENDER_FARCLIP );11.131 - pvr2_render_prepare_context( buffer, nearz, farz );11.132 -11.133 - int clip_x = MMIO_READ( PVR2, RENDER_HCLIP ) & 0x03FF;11.134 - int clip_y = MMIO_READ( PVR2, RENDER_VCLIP ) & 0x03FF;11.135 - int clip_width = ((MMIO_READ( PVR2, RENDER_HCLIP ) >> 16) & 0x03FF) - clip_x + 1;11.136 - int clip_height= ((MMIO_READ( PVR2, RENDER_VCLIP ) >> 16) & 0x03FF) - clip_y + 1;11.137 -11.138 - /* Fog setup goes here? */11.139 -11.140 - /* Render the background plane */11.141 -11.142 - uint32_t bgplane_mode = MMIO_READ(PVR2, RENDER_BGPLANE);11.143 - uint32_t *display_list =11.144 - (uint32_t *)mem_get_region(PVR2_RAM_BASE + MMIO_READ( PVR2, RENDER_POLYBASE ));11.145 -11.146 - uint32_t *bgplane = display_list + (((bgplane_mode & 0x00FFFFFF)) >> 3) ;11.147 - render_backplane( bgplane, buffer->width, buffer->height, bgplane_mode );11.148 -11.149 - pvr2_render_tilebuffer( buffer->width, buffer->height, clip_x, clip_y,11.150 - clip_x + clip_width, clip_y + clip_height );11.151 -11.152 - gettimeofday( &tvb, NULL );11.153 - uint32_t ms = (tvb.tv_sec - tva.tv_sec) * 1000 +11.154 - (tvb.tv_usec - tva.tv_usec)/1000;11.155 - DEBUG( "Rendered frame %d to %08X in %dms", pvr2_get_frame_count(), buffer->address, ms );11.156 -}
12.1 --- a/src/pvr2/rendsort.c Mon Feb 18 09:21:43 2008 +000012.2 +++ b/src/pvr2/rendsort.c Thu Mar 06 08:22:00 2008 +000012.3 @@ -16,21 +16,21 @@12.4 * GNU General Public License for more details.12.5 */12.6 #include <sys/time.h>12.7 +#include <string.h>12.8 +#include <assert.h>12.9 #include "pvr2/pvr2.h"12.10 +#include "pvr2/scene.h"12.11 #include "asic.h"12.13 extern char *video_base;12.14 -extern gboolean pvr2_force_fragment_alpha;12.16 #define MIN3( a,b,c ) ((a) < (b) ? ( (a) < (c) ? (a) : (c) ) : ((b) < (c) ? (b) : (c)) )12.17 #define MAX3( a,b,c ) ((a) > (b) ? ( (a) > (c) ? (a) : (c) ) : ((b) > (c) ? (b) : (c)) )12.19 -struct render_triangle {12.20 - uint32_t *polygon;12.21 - int vertex_length; /* Number of 32-bit words in vertex, or 0 for an unpacked vertex */12.22 - float minx,miny,minz;12.23 - float maxx,maxy,maxz;12.24 - float *vertexes[3];12.25 +struct sort_triangle {12.26 + struct polygon_struct *poly;12.27 + int triangle_num; // triangle number in the poly, from 012.28 + float minz;12.29 };12.31 #define SENTINEL 0xDEADBEEF12.32 @@ -39,7 +39,7 @@12.33 * Count the number of triangles in the list starting at the given12.34 * pvr memory address.12.35 */12.36 -int render_count_triangles( pvraddr_t tile_entry ) {12.37 +int sort_count_triangles( pvraddr_t tile_entry ) {12.38 uint32_t *tile_list = (uint32_t *)(video_base+tile_entry);12.39 int count = 0;12.40 while(1) {12.41 @@ -64,27 +64,12 @@12.42 return count;12.43 }12.45 -static void compute_triangle_boxes( struct render_triangle *triangle, int num_triangles )12.46 +/**12.47 + * Extract a triangle list from the tile (basically indexes into the polygon list, plus12.48 + * computing minz while we go through it12.49 + */12.50 +int sort_extract_triangles( pvraddr_t tile_entry, struct sort_triangle *triangles )12.51 {12.52 - int i;12.53 - for( i=0; i<num_triangles; i++ ) {12.54 - triangle[i].minx = MIN3(triangle[i].vertexes[0][0],triangle[i].vertexes[1][0],triangle[i].vertexes[2][0]);12.55 - triangle[i].maxx = MAX3(triangle[i].vertexes[0][0],triangle[i].vertexes[1][0],triangle[i].vertexes[2][0]);12.56 - triangle[i].miny = MIN3(triangle[i].vertexes[0][1],triangle[i].vertexes[1][1],triangle[i].vertexes[2][1]);12.57 - triangle[i].maxy = MAX3(triangle[i].vertexes[0][1],triangle[i].vertexes[1][1],triangle[i].vertexes[2][1]);12.58 - float az = triangle[i].vertexes[0][2];12.59 - float bz = triangle[i].vertexes[1][2];12.60 - float cz = triangle[i].vertexes[2][2];12.61 - triangle[i].minz = MIN3(az,bz,cz);12.62 - triangle[i].maxz = MAX3(az,bz,cz);12.63 - }12.64 -}12.65 -12.66 -void render_extract_triangles( pvraddr_t tile_entry, gboolean cheap_modifier_mode,12.67 - struct render_triangle *triangles, int num_triangles,12.68 - struct vertex_unpacked *vertex_space, int render_mode )12.69 -{12.70 - uint32_t poly_bank = MMIO_READ(PVR2,RENDER_POLYBASE);12.71 uint32_t *tile_list = (uint32_t *)(video_base+tile_entry);12.72 int count = 0;12.73 while(1) {12.74 @@ -94,11 +79,11 @@12.75 } else if( entry >> 28 == 0x0E ) {12.76 tile_list = (uint32_t *)(video_base+(entry&0x007FFFFF));12.77 } else {12.78 - uint32_t *polygon = (uint32_t *)(video_base + poly_bank + ((entry & 0x000FFFFF) << 2));12.79 + uint32_t poly_addr = entry & 0x000FFFFF;12.80 int is_modified = entry & 0x01000000;12.81 int vertex_length = (entry >> 21) & 0x07;12.82 int context_length = 3;12.83 - if( is_modified && !cheap_modifier_mode ) {12.84 + if( is_modified && pvr2_scene.full_shadow ) {12.85 context_length = 5;12.86 vertex_length *= 2 ;12.87 }12.88 @@ -110,127 +95,106 @@12.89 int polygon_length = 3 * vertex_length + context_length;12.90 int i;12.91 for( i=0; i<strip_count; i++ ) {12.92 - float *vertex = (float *)(polygon+context_length);12.93 - triangles[count].polygon = polygon;12.94 - triangles[count].vertex_length = vertex_length;12.95 - triangles[count].vertexes[0] = vertex;12.96 - vertex+=vertex_length;12.97 - triangles[count].vertexes[1] = vertex;12.98 - vertex+=vertex_length;12.99 - triangles[count].vertexes[2] = vertex;12.100 - polygon += polygon_length;12.101 + struct polygon_struct *poly = pvr2_scene.buf_to_poly_map[poly_addr];12.102 + triangles[count].poly = poly;12.103 + triangles[count].triangle_num = 0;12.104 + triangles[count].minz = MIN3( pvr2_scene.vertex_array[poly->vertex_index].z,12.105 + pvr2_scene.vertex_array[poly->vertex_index+1].z,12.106 + pvr2_scene.vertex_array[poly->vertex_index+2].z );12.107 + poly_addr += polygon_length;12.108 count++;12.109 }12.110 } else if( (entry & 0xE0000000) == 0xA0000000 ) {12.111 /* Quad(s) */12.112 int strip_count = ((entry >> 25) & 0x0F)+1;12.113 int polygon_length = 4 * vertex_length + context_length;12.114 -12.115 int i;12.116 for( i=0; i<strip_count; i++ ) {12.117 - render_unpack_quad( vertex_space, *polygon, (polygon+context_length),12.118 - vertex_length, render_mode );12.119 - triangles[count].polygon = polygon;12.120 - triangles[count].vertex_length = 0;12.121 - triangles[count].vertexes[0] = (float *)vertex_space;12.122 - triangles[count].vertexes[1] = (float *)(vertex_space + 1);12.123 - triangles[count].vertexes[2] = (float *)(vertex_space + 3);12.124 + struct polygon_struct *poly = pvr2_scene.buf_to_poly_map[poly_addr];12.125 + triangles[count].poly = poly;12.126 + triangles[count].triangle_num = 0;12.127 + triangles[count].minz = MIN3( pvr2_scene.vertex_array[poly->vertex_index].z,12.128 + pvr2_scene.vertex_array[poly->vertex_index+1].z,12.129 + pvr2_scene.vertex_array[poly->vertex_index+2].z );12.130 count++;12.131 - /* Preserve face direction */12.132 - triangles[count].polygon = polygon;12.133 - triangles[count].vertex_length = 0;12.134 - triangles[count].vertexes[0] = (float *)(vertex_space + 1);12.135 - triangles[count].vertexes[1] = (float *)(vertex_space + 2);12.136 - triangles[count].vertexes[2] = (float *)(vertex_space + 3);12.137 + triangles[count].poly = poly;12.138 + triangles[count].triangle_num = 1;12.139 + triangles[count].minz = MIN3( pvr2_scene.vertex_array[poly->vertex_index+1].z,12.140 + pvr2_scene.vertex_array[poly->vertex_index+2].z,12.141 + pvr2_scene.vertex_array[poly->vertex_index+3].z );12.142 count++;12.143 - vertex_space += 4;12.144 - polygon += polygon_length;12.145 + poly_addr += polygon_length;12.146 }12.147 } else {12.148 /* Polygon */12.149 int i;12.150 - float *vertex = (float *)polygon+context_length;12.151 + struct polygon_struct *poly = pvr2_scene.buf_to_poly_map[poly_addr];12.152 for( i=0; i<6; i++ ) {12.153 if( entry & (0x40000000>>i) ) {12.154 - triangles[count].polygon = polygon;12.155 - triangles[count].vertex_length = vertex_length;12.156 - if( i&1 ) {12.157 - triangles[count].vertexes[0] = vertex + vertex_length;12.158 - triangles[count].vertexes[1] = vertex;12.159 - triangles[count].vertexes[2] = vertex + (vertex_length<<1);12.160 - } else {12.161 - triangles[count].vertexes[0] = vertex;12.162 - triangles[count].vertexes[1] = vertex + vertex_length;12.163 - triangles[count].vertexes[2] = vertex + (vertex_length<<1);12.164 - }12.165 + triangles[count].poly = poly;12.166 + triangles[count].triangle_num = i;12.167 + triangles[count].minz = MIN3( pvr2_scene.vertex_array[poly->vertex_index+i].z,12.168 + pvr2_scene.vertex_array[poly->vertex_index+i+1].z,12.169 + pvr2_scene.vertex_array[poly->vertex_index+i+2].z );12.170 count++;12.171 }12.172 - vertex += vertex_length;12.173 }12.174 }12.175 }12.176 }12.177 - if( count != num_triangles ) {12.178 - ERROR( "Extracted triangles do not match expected count!" );12.179 - }12.180 + return count;12.181 }12.183 -void render_triangles( struct render_triangle *triangles, int num_triangles,12.184 - int render_mode )12.185 +void sort_render_triangles( struct sort_triangle *triangles, int num_triangles,12.186 + int render_mode )12.187 {12.188 int i;12.189 for( i=0; i<num_triangles; i++ ) {12.190 - render_set_context( triangles[i].polygon, render_mode );12.191 + struct polygon_struct *poly = triangles[i].poly;12.192 + if( poly->tex_id != -1 ) {12.193 + glBindTexture(GL_TEXTURE_2D, poly->tex_id);12.194 + }12.195 + render_set_context( poly->context, RENDER_NORMAL );12.196 glEnable(GL_DEPTH_TEST);12.197 glDepthFunc(GL_GEQUAL);12.198 - if( triangles[i].vertex_length == 0 ) {12.199 - render_unpacked_vertex_array( *triangles[i].polygon, (struct vertex_unpacked **)triangles[i].vertexes, 3 );12.200 + if( triangles[i].triangle_num & 1 ) {12.201 + glCullFace(GL_FRONT);12.202 } else {12.203 - render_vertex_array( *triangles[i].polygon, (uint32_t **)triangles[i].vertexes, 3,12.204 - triangles[i].vertex_length, render_mode );12.205 + glCullFace(GL_BACK);12.206 }12.207 + /* Fix cull direction */12.208 + glDrawArrays(GL_TRIANGLE_STRIP, poly->vertex_index + triangles[i].triangle_num, 3 );12.209 }12.210 -12.211 -12.212 }12.214 int compare_triangles( const void *a, const void *b )12.215 {12.216 - const struct render_triangle *tri1 = a;12.217 - const struct render_triangle *tri2 = b;12.218 - if( tri1->minz > tri2->minz ) {12.219 - return 1;12.220 - } else if( tri1->minz < tri2->minz ) {12.221 - return -1;12.222 - } else {12.223 - return 0;12.224 - }12.225 + const struct sort_triangle *tri1 = a;12.226 + const struct sort_triangle *tri2 = b;12.227 + return tri1->minz - tri2->minz;12.228 }12.230 -void sort_triangles( struct render_triangle *triangles, int num_triangles )12.231 +void sort_triangles( struct sort_triangle *triangles, int num_triangles )12.232 {12.233 - qsort( triangles, num_triangles, sizeof(struct render_triangle), compare_triangles );12.234 + qsort( triangles, num_triangles, sizeof(struct sort_triangle), compare_triangles );12.235 }12.237 void render_autosort_tile( pvraddr_t tile_entry, int render_mode, gboolean cheap_modifier_mode )12.238 {12.239 - int num_triangles = render_count_triangles(tile_entry);12.240 + int num_triangles = sort_count_triangles(tile_entry);12.241 if( num_triangles == 0 ) {12.242 return; /* nothing to do */12.243 } else if( num_triangles == 1 ) { /* Triangle can hardly overlap with itself */12.244 - render_tile( tile_entry, render_mode, cheap_modifier_mode );12.245 + gl_render_tilelist(tile_entry);12.246 } else { /* Ooh boy here we go... */12.247 - struct render_triangle triangles[num_triangles+1];12.248 - struct vertex_unpacked vertex_space[num_triangles << 1];12.249 + struct sort_triangle triangles[num_triangles+1];12.250 // Reserve space for num_triangles / 2 * 4 vertexes (maximum possible number of12.251 // quad vertices)12.252 - triangles[num_triangles].polygon = (void *)SENTINEL;12.253 - render_extract_triangles(tile_entry, cheap_modifier_mode, triangles, num_triangles, vertex_space, render_mode);12.254 - compute_triangle_boxes(triangles, num_triangles);12.255 + triangles[num_triangles].poly = (void *)SENTINEL;12.256 + sort_extract_triangles(tile_entry, triangles);12.257 sort_triangles( triangles, num_triangles );12.258 - render_triangles(triangles, num_triangles, render_mode);12.259 - if( triangles[num_triangles].polygon != (void *)SENTINEL ) {12.260 - fprintf( stderr, "Triangle overflow in render_autosort_tile!" );12.261 - }12.262 + sort_render_triangles(triangles, num_triangles, render_mode);12.263 + glCullFace(GL_BACK);12.264 + assert( triangles[num_triangles].poly == (void *)SENTINEL );12.265 }12.266 }
13.1 --- a/src/pvr2/scene.c Mon Feb 18 09:21:43 2008 +000013.2 +++ b/src/pvr2/scene.c Thu Mar 06 08:22:00 2008 +000013.3 @@ -19,6 +19,7 @@13.5 #include <assert.h>13.6 #include <string.h>13.7 +#include <math.h>13.8 #include "lxdream.h"13.9 #include "display.h"13.10 #include "pvr2/pvr2.h"13.11 @@ -33,6 +34,29 @@13.12 return (bgra&0xFF00FF00) | ((bgra&0x00FF0000)>>16) | ((bgra&0x000000FF)<<16);13.13 }13.15 +/**13.16 + * Convert a half-float (16-bit) FP number to a regular 32-bit float.13.17 + * Source is 1-bit sign, 5-bit exponent, 10-bit mantissa.13.18 + * TODO: Check the correctness of this.13.19 + */13.20 +static float halftofloat( uint16_t half )13.21 +{13.22 + union {13.23 + float f;13.24 + uint32_t i;13.25 + } temp;13.26 + /* int e = ((half & 0x7C00) >> 10) - 15 + 127;13.27 +13.28 + temp.i = ((half & 0x8000) << 16) | (e << 23) |13.29 + ((half & 0x03FF) << 13); */13.30 + temp.i = ((uint32_t)half)<<16;13.31 + return temp.f;13.32 +}13.33 +13.34 +13.35 +13.36 +13.37 +13.38 struct pvr2_scene_struct pvr2_scene;13.40 static gboolean vbo_init = FALSE;13.41 @@ -46,10 +70,12 @@13.42 void pvr2_scene_init()13.43 {13.44 if( !vbo_init ) {13.45 +#ifdef ENABLE_VERTEX_BUFFER13.46 if( isGLExtensionSupported(VBO_EXT_STRING) ) {13.47 vbo_supported = TRUE;13.48 pvr2_scene.vbo_id = 1;13.49 }13.50 +#endif13.51 pvr2_scene.vertex_array = NULL;13.52 pvr2_scene.vertex_array_size = 0;13.53 pvr2_scene.poly_array = g_malloc( MAX_POLY_BUFFER_SIZE );13.54 @@ -70,16 +96,23 @@13.56 void pvr2_scene_shutdown()13.57 {13.58 +#ifdef ENABLE_VERTEX_BUFFER13.59 if( vbo_supported ) {13.60 glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );13.61 glDeleteBuffersARB( 1, &pvr2_scene.vbo_id );13.62 pvr2_scene.vbo_id = 0;13.63 } else {13.64 +#endif13.65 g_free( pvr2_scene.vertex_array );13.66 pvr2_scene.vertex_array = NULL;13.67 +#ifdef ENABLE_VERTEX_BUFFER13.68 }13.69 +#endif13.70 +13.71 g_free( pvr2_scene.poly_array );13.72 + pvr2_scene.poly_array = NULL;13.73 g_free( pvr2_scene.buf_to_poly_map );13.74 + pvr2_scene.buf_to_poly_map = NULL;13.75 vbo_init = FALSE;13.76 }13.78 @@ -87,9 +120,9 @@13.79 {13.80 glGetError();13.81 uint32_t size = pvr2_scene.vertex_count * sizeof(struct vertex_struct);13.82 +#ifdef ENABLE_VERTEX_BUFFER13.83 if( vbo_supported ) {13.84 glBindBufferARB( GL_ARRAY_BUFFER_ARB, pvr2_scene.vbo_id );13.85 - assert( glGetError() == 0 );13.86 if( size > pvr2_scene.vertex_array_size ) {13.87 glBufferDataARB( GL_ARRAY_BUFFER_ARB, size, NULL, GL_DYNAMIC_DRAW_ARB );13.88 int status = glGetError();13.89 @@ -102,21 +135,28 @@13.90 pvr2_scene.vertex_array = glMapBufferARB( GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB );13.91 assert(pvr2_scene.vertex_array != NULL );13.92 } else {13.93 +#endif13.94 if( size > pvr2_scene.vertex_array_size ) {13.95 pvr2_scene.vertex_array = g_realloc( pvr2_scene.vertex_array, size );13.96 }13.97 +#ifdef ENABLE_VERTEX_BUFFER13.98 }13.99 +#endif13.100 return pvr2_scene.vertex_array;13.101 }13.103 gboolean vertex_buffer_unmap()13.104 {13.105 +#ifdef ENABLE_VERTEX_BUFFER13.106 if( vbo_supported ) {13.107 pvr2_scene.vertex_array = NULL;13.108 return glUnmapBufferARB( GL_ARRAY_BUFFER_ARB );13.109 } else {13.110 return TRUE;13.111 }13.112 +#else13.113 + return TRUE;13.114 +#endif13.115 }13.117 static struct polygon_struct *scene_add_polygon( pvraddr_t poly_idx, int vertex_count,13.118 @@ -135,6 +175,7 @@13.119 poly->context = (uint32_t *)(video_base + MMIO_READ(PVR2,RENDER_POLYBASE) + (poly_idx<<2));13.120 poly->vertex_count = vertex_count;13.121 poly->vertex_index = -1;13.122 + poly->mod_vertex_index = -1;13.123 poly->next = NULL;13.124 pvr2_scene.buf_to_poly_map[poly_idx] = poly;13.125 pvr2_scene.vertex_count += (vertex_count * vert_mul);13.126 @@ -168,6 +209,9 @@13.127 vert->y = *data.fval++;13.129 float z = *data.fval++;13.130 + if( !isfinite(z) ) {13.131 + z = 0;13.132 + }13.133 if( z > pvr2_scene.bounds[5] ) {13.134 pvr2_scene.bounds[5] = z;13.135 } else if( z < pvr2_scene.bounds[4] && z != 0 ) {13.136 @@ -194,11 +238,15 @@13.137 vert->rgba = bgra_to_rgba((*data.ival++) | 0xFF000000);13.138 if( POLY1_SPECULAR(poly1) ) {13.139 vert->offset_rgba = bgra_to_rgba((*data.ival++) | 0xFF000000);13.140 + } else {13.141 + vert->offset_rgba = 0;13.142 }13.143 } else {13.144 vert->rgba = bgra_to_rgba(*data.ival++);13.145 if( POLY1_SPECULAR(poly1) ) {13.146 vert->offset_rgba = bgra_to_rgba(*data.ival++);13.147 + } else {13.148 + vert->offset_rgba = 0;13.149 }13.150 }13.151 }13.152 @@ -279,11 +327,11 @@13.153 uint32_t *context = ptr;13.154 unsigned int i;13.156 - assert( poly != NULL );13.157 if( poly->vertex_index == -1 ) {13.158 ptr += (is_modified ? 5 : 3 );13.159 poly->vertex_index = pvr2_scene.vertex_index;13.161 + assert( poly != NULL );13.162 assert( pvr2_scene.vertex_index + poly->vertex_count <= pvr2_scene.vertex_count );13.163 for( i=0; i<poly->vertex_count; i++ ) {13.164 pvr2_decode_render_vertex( &pvr2_scene.vertex_array[pvr2_scene.vertex_index++], context[0], context[1], ptr, 0 );13.165 @@ -291,6 +339,7 @@13.166 }13.167 if( is_modified ) {13.168 int mod_offset = (vertex_length - 3)>>1;13.169 + assert( pvr2_scene.vertex_index + poly->vertex_count <= pvr2_scene.vertex_count );13.170 ptr = &pvr2_scene.pvr2_pbuf[poly_idx] + 5;13.171 poly->mod_vertex_index = pvr2_scene.vertex_index;13.172 for( i=0; i<poly->vertex_count; i++ ) {13.173 @@ -316,6 +365,7 @@13.174 struct vertex_struct quad[4];13.176 assert( poly != NULL );13.177 + assert( pvr2_scene.vertex_index + poly->vertex_count <= pvr2_scene.vertex_count );13.178 ptr += (is_modified ? 5 : 3 );13.179 poly->vertex_index = pvr2_scene.vertex_index;13.180 for( i=0; i<4; i++ ) {13.181 @@ -331,6 +381,7 @@13.183 if( is_modified ) {13.184 int mod_offset = (vertex_length - 3)>>1;13.185 + assert( pvr2_scene.vertex_index + poly->vertex_count <= pvr2_scene.vertex_count );13.186 ptr = &pvr2_scene.pvr2_pbuf[poly_idx] + 5;13.187 poly->mod_vertex_index = pvr2_scene.vertex_index;13.188 for( i=0; i<4; i++ ) {13.189 @@ -516,7 +567,7 @@13.190 pvr2_scene.sort_mode = SORT_ALWAYS;13.191 }13.192 } else {13.193 - pvr2_scene.sort_mode = SORT_BYFLAG;13.194 + pvr2_scene.sort_mode = SORT_TILEFLAG;13.195 }13.197 // Pass 1: Extract polygon list13.198 @@ -557,7 +608,46 @@13.199 segment++;13.200 }13.201 } while( (control & SEGMENT_END) == 0 );13.202 -13.203 vertex_buffer_unmap();13.204 }13.205 }13.206 +13.207 +/**13.208 + * Dump the current scene to file in a (mostly) human readable form13.209 + */13.210 +void pvr2_scene_dump( FILE *f )13.211 +{13.212 + int i,j;13.213 +13.214 + fprintf( f, "Polygons: %d\n", pvr2_scene.poly_count );13.215 + for( i=0; i<pvr2_scene.poly_count; i++ ) {13.216 + struct polygon_struct *poly = &pvr2_scene.poly_array[i];13.217 + fprintf( f, " %08X ", ((char *)poly->context) - video_base );13.218 + switch( poly->vertex_count ) {13.219 + case 3: fprintf( f, "Tri " ); break;13.220 + case 4: fprintf( f, "Quad " ); break;13.221 + default: fprintf( f,"%d-Strip ", poly->vertex_count-2 ); break;13.222 + }13.223 + fprintf( f, "%08X %08X %08X ", poly->context[0], poly->context[1], poly->context[2] );13.224 + if( poly->mod_vertex_index != -1 ) {13.225 + fprintf( f, "%08X %08X\n", poly->context[3], poly->context[5] );13.226 + } else {13.227 + fprintf( f, "\n" );13.228 + }13.229 +13.230 + for( j=0; j<poly->vertex_count; j++ ) {13.231 + struct vertex_struct *v = &pvr2_scene.vertex_array[poly->vertex_index+j];13.232 + fprintf( f, " %.5f %.5f %.5f, (%.5f,%.5f) %08X %08X\n", v->x, v->y, v->z, v->u, v->v,13.233 + v->rgba, v->offset_rgba );13.234 + }13.235 + if( poly->mod_vertex_index != -1 ) {13.236 + fprintf( f, " ---\n" );13.237 + for( j=0; j<poly->vertex_count; j++ ) {13.238 + struct vertex_struct *v = &pvr2_scene.vertex_array[poly->mod_vertex_index+j];13.239 + fprintf( f, " %.5f %.5f %.5f, (%.5f,%.5f) %08X %08X\n", v->x, v->y, v->z, v->u, v->v,13.240 + v->rgba, v->offset_rgba );13.241 + }13.242 + }13.243 + }13.244 +13.245 +}
14.1 --- a/src/pvr2/scene.h Mon Feb 18 09:21:43 2008 +000014.2 +++ b/src/pvr2/scene.h Thu Mar 06 08:22:00 2008 +000014.3 @@ -23,7 +23,7 @@14.5 typedef enum {14.6 SORT_NEVER = 0,14.7 - SORT_BYFLAG = 1, /* In this mode, sorting is controlled by the per-segment flag */14.8 + SORT_TILEFLAG = 1, /* In this mode, sorting is controlled by the per-segment flag */14.9 SORT_ALWAYS = 214.10 } tile_sort_mode_t;14.12 @@ -38,7 +38,9 @@14.13 uint32_t *context;14.14 int cull; // culling mode14.15 uint32_t vertex_count; // number of vertexes in polygon14.16 + uint32_t tex_id;14.17 int32_t vertex_index; // index of first vertex in vertex buffer14.18 + uint32_t mod_tex_id;14.19 int32_t mod_vertex_index; // index of first modified vertex in vertex buffer14.20 float center_z;14.21 struct polygon_struct *next; // chain for tri/quad arrays
15.1 --- a/src/pvr2/tacore.c Mon Feb 18 09:21:43 2008 +000015.2 +++ b/src/pvr2/tacore.c Thu Mar 06 08:22:00 2008 +000015.3 @@ -15,6 +15,7 @@15.4 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the15.5 * GNU General Public License for more details.15.6 */15.7 +#include <string.h>15.8 #include "pvr2.h"15.9 #include "asic.h"
16.1 --- a/src/pvr2/texcache.c Mon Feb 18 09:21:43 2008 +000016.2 +++ b/src/pvr2/texcache.c Thu Mar 06 08:22:00 2008 +000016.3 @@ -509,20 +509,19 @@16.4 * If the texture has already been bound, return the ID to which it was16.5 * bound. Otherwise obtain an unused texture ID and set it up appropriately.16.6 */16.7 -GLuint texcache_get_texture( uint32_t texture_addr, int width, int height,16.8 - int mode )16.9 +GLuint texcache_get_texture( uint32_t texture_word, int width, int height )16.10 {16.11 + uint32_t texture_addr = (texture_word & 0x000FFFFF)<<3;16.12 uint32_t texture_page = texture_addr >> 12;16.13 texcache_entry_index next;16.14 texcache_entry_index idx = texcache_page_lookup[texture_page];16.15 while( idx != EMPTY_ENTRY ) {16.16 texcache_entry_t entry = &texcache_active_list[idx];16.17 if( entry->texture_addr == texture_addr &&16.18 - entry->mode == mode &&16.19 + entry->mode == texture_word &&16.20 entry->width == width &&16.21 entry->height == height ) {16.22 entry->lru_count = texcache_ref_counter++;16.23 - glBindTexture( GL_TEXTURE_2D, entry->texture_id );16.24 return entry->texture_id;16.25 }16.26 idx = entry->next;16.27 @@ -542,7 +541,7 @@16.28 texcache_active_list[slot].texture_addr = texture_addr;16.29 texcache_active_list[slot].width = width;16.30 texcache_active_list[slot].height = height;16.31 - texcache_active_list[slot].mode = mode;16.32 + texcache_active_list[slot].mode = texture_word;16.33 texcache_active_list[slot].lru_count = texcache_ref_counter++;16.35 /* Add entry to the lookup table */16.36 @@ -563,9 +562,8 @@16.38 /* Construct the GL texture */16.39 glBindTexture( GL_TEXTURE_2D, texcache_active_list[slot].texture_id );16.40 - texcache_load_texture( texture_addr, width, height, mode );16.41 + texcache_load_texture( texture_addr, width, height, texture_word );16.43 - texcache_integrity_check();16.44 return texcache_active_list[slot].texture_id;16.45 }
17.1 --- a/src/pvr2/vertex.glsl Mon Feb 18 09:21:43 2008 +000017.2 +++ b/src/pvr2/vertex.glsl Thu Mar 06 08:22:00 2008 +000017.3 @@ -2,8 +2,8 @@17.5 void main()17.6 {17.7 - gl_Position.xy = ftransform().xy;17.8 - gl_Position.z = gl_Vertex.z;17.9 + gl_Position = ftransform();17.10 +// gl_Position.z = log(gl_Vertex.z);17.11 gl_FrontColor = gl_Color;17.12 gl_FrontSecondaryColor = gl_SecondaryColor;17.13 gl_TexCoord[0] = gl_MultiTexCoord0;
.