Search
lxdream.org :: lxdream :: r645:a7392098299c
lxdream 0.9.1
released Jun 29
Download Now
changeset645:a7392098299c lxdream-render
parent639:162ee7614b60
child646:f9812647b818
authornkeynes
dateThu Mar 06 08:22:00 2008 +0000 (16 years ago)
branchlxdream-render
More refactor work in progress - nearly done now
src/Makefile.am
src/Makefile.in
src/pvr2/gl_slsrc.c
src/pvr2/glrender.c
src/pvr2/glutil.c
src/pvr2/pvr2.c
src/pvr2/pvr2.h
src/pvr2/pvr2mem.c
src/pvr2/rendbkg.c
src/pvr2/rendcore.c
src/pvr2/render.c
src/pvr2/rendsort.c
src/pvr2/scene.c
src/pvr2/scene.h
src/pvr2/tacore.c
src/pvr2/texcache.c
src/pvr2/vertex.glsl
1.1 --- a/src/Makefile.am Mon Feb 18 09:21:43 2008 +0000
1.2 +++ b/src/Makefile.am Thu Mar 06 08:22:00 2008 +0000
1.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 +0000
2.2 +++ b/src/Makefile.in Thu Mar 06 08:22:00 2008 +0000
2.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.c
2.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.c
2.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.105
2.106 -render.o: pvr2/render.c
2.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@ fi
2.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.c
2.116 -
2.117 -render.obj: pvr2/render.c
2.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@ fi
2.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.c
2.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@ fi
2.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.c
2.138 -
2.139 -rendcore.obj: pvr2/rendcore.c
2.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@ fi
2.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.c
2.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 +0000
3.2 +++ b/src/pvr2/gl_slsrc.c Thu Mar 06 08:22:00 2008 +0000
3.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 +0000
4.2 +++ b/src/pvr2/glrender.c Thu Mar 06 08:22:00 2008 +0000
4.3 @@ -16,10 +16,33 @@
4.4 * GNU General Public License for more details.
4.5 */
4.6
4.7 +#include <assert.h>
4.8 #include "display.h"
4.9 #include "pvr2/pvr2.h"
4.10 #include "pvr2/scene.h"
4.11
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_MODULATE
4.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.40
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 IDs
4.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.77
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 context
4.81 + * @param modified boolean flag indicating that the modified
4.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 mucking
4.137 + * with the texture format), but we get the same effect by forcing
4.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.181
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.230
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.239
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.259
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 +0000
5.2 +++ b/src/pvr2/glutil.c Thu Mar 06 08:22:00 2008 +0000
5.3 @@ -15,7 +15,7 @@
5.4 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5.5 * GNU General Public License for more details.
5.6 */
5.7 -
5.8 +#include <string.h>
5.9 #include "pvr2/glutil.h"
5.10
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't
5.18 + * available either. */
5.19 + return FALSE;
5.20 + }
5.21 /* It takes a bit of care to be fool-proof about parsing the
5.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 +0000
6.2 +++ b/src/pvr2/pvr2.c Thu Mar 06 08:22:00 2008 +0000
6.3 @@ -203,12 +203,17 @@
6.4 }
6.5
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.26
6.27 @@ -258,9 +263,7 @@
6.28 }
6.29
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 +0000
7.2 +++ b/src/pvr2/pvr2.h Thu Mar 06 08:22:00 2008 +0000
7.3 @@ -343,8 +343,7 @@
7.4 * If the texture has already been bound, return the ID to which it was
7.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.10
7.11 void pvr2_check_palette_changed(void);
7.12
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.24
7.25 -float halftofloat(uint16_t half);
7.26 -
7.27 #define CULL_NONE 0
7.28 #define CULL_SMALL 1
7.29 #define CULL_CCW 2
8.1 --- a/src/pvr2/pvr2mem.c Mon Feb 18 09:21:43 2008 +0000
8.2 +++ b/src/pvr2/pvr2mem.c Thu Mar 06 08:22:00 2008 +0000
8.3 @@ -15,10 +15,11 @@
8.4 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8.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.14
8.15 extern unsigned char *video_base;
8.16
9.1 --- a/src/pvr2/rendbkg.c Mon Feb 18 09:21:43 2008 +0000
9.2 +++ b/src/pvr2/rendbkg.c Thu Mar 06 08:22:00 2008 +0000
9.3 @@ -49,6 +49,70 @@
9.4 #define FARGB_B(x) (((float)(((x)&0xFF)+1))/256.0)
9.5
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 of
9.72 * r,g,b,a, or z) and determines the points at which the line intersects
9.73 * the viewport (0,0,width,height).
10.1 --- a/src/pvr2/rendcore.c Mon Feb 18 09:21:43 2008 +0000
10.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
10.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 modify
10.12 - * it under the terms of the GNU General Public License as published by
10.13 - * the Free Software Foundation; either version 2 of the License, or
10.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 of
10.18 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10.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_MODULATE
10.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 context
10.80 - * @param modified boolean flag indicating that the modified
10.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 mucking
10.138 - * with the texture format), but we get the same effect by forcing
10.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 last
10.226 - * vertex.
10.227 - * FIXME: Integrate this with rendbkg somehow
10.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) tile
10.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 up
10.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 (in
10.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 +0000
11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
11.3 @@ -1,153 +0,0 @@
11.4 -/**
11.5 - * $Id$
11.6 - *
11.7 - * PVR2 Renderer support. This part is primarily
11.8 - *
11.9 - * Copyright (c) 2005 Nathan Keynes.
11.10 - *
11.11 - * This program is free software; you can redistribute it and/or modify
11.12 - * it under the terms of the GNU General Public License as published by
11.13 - * the Free Software Foundation; either version 2 of the License, or
11.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 of
11.18 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11.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 0
11.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 -#endif
11.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 0
11.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 -#endif
11.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 are
11.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 +0000
12.2 +++ b/src/pvr2/rendsort.c Thu Mar 06 08:22:00 2008 +0000
12.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.12
12.13 extern char *video_base;
12.14 -extern gboolean pvr2_force_fragment_alpha;
12.15
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.18
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 0
12.28 + float minz;
12.29 };
12.30
12.31 #define SENTINEL 0xDEADBEEF
12.32 @@ -39,7 +39,7 @@
12.33 * Count the number of triangles in the list starting at the given
12.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.44
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, plus
12.48 + * computing minz while we go through it
12.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.182
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.213
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.229
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.236
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 of
12.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 +0000
13.2 +++ b/src/pvr2/scene.c Thu Mar 06 08:22:00 2008 +0000
13.3 @@ -19,6 +19,7 @@
13.4
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.14
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.39
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_BUFFER
13.46 if( isGLExtensionSupported(VBO_EXT_STRING) ) {
13.47 vbo_supported = TRUE;
13.48 pvr2_scene.vbo_id = 1;
13.49 }
13.50 +#endif
13.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.55
13.56 void pvr2_scene_shutdown()
13.57 {
13.58 +#ifdef ENABLE_VERTEX_BUFFER
13.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 +#endif
13.65 g_free( pvr2_scene.vertex_array );
13.66 pvr2_scene.vertex_array = NULL;
13.67 +#ifdef ENABLE_VERTEX_BUFFER
13.68 }
13.69 +#endif
13.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.77
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_BUFFER
13.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 +#endif
13.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_BUFFER
13.98 }
13.99 +#endif
13.100 return pvr2_scene.vertex_array;
13.101 }
13.102
13.103 gboolean vertex_buffer_unmap()
13.104 {
13.105 +#ifdef ENABLE_VERTEX_BUFFER
13.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 +#else
13.113 + return TRUE;
13.114 +#endif
13.115 }
13.116
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.128
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.155
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.160
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.175
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.182
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.196
13.197 // Pass 1: Extract polygon list
13.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 form
13.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 +0000
14.2 +++ b/src/pvr2/scene.h Thu Mar 06 08:22:00 2008 +0000
14.3 @@ -23,7 +23,7 @@
14.4
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 = 2
14.10 } tile_sort_mode_t;
14.11
14.12 @@ -38,7 +38,9 @@
14.13 uint32_t *context;
14.14 int cull; // culling mode
14.15 uint32_t vertex_count; // number of vertexes in polygon
14.16 + uint32_t tex_id;
14.17 int32_t vertex_index; // index of first vertex in vertex buffer
14.18 + uint32_t mod_tex_id;
14.19 int32_t mod_vertex_index; // index of first modified vertex in vertex buffer
14.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 +0000
15.2 +++ b/src/pvr2/tacore.c Thu Mar 06 08:22:00 2008 +0000
15.3 @@ -15,6 +15,7 @@
15.4 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15.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"
15.10
16.1 --- a/src/pvr2/texcache.c Mon Feb 18 09:21:43 2008 +0000
16.2 +++ b/src/pvr2/texcache.c Thu Mar 06 08:22:00 2008 +0000
16.3 @@ -509,20 +509,19 @@
16.4 * If the texture has already been bound, return the ID to which it was
16.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.34
16.35 /* Add entry to the lookup table */
16.36 @@ -563,9 +562,8 @@
16.37
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.42
16.43 - texcache_integrity_check();
16.44 return texcache_active_list[slot].texture_id;
16.45 }
16.46
17.1 --- a/src/pvr2/vertex.glsl Mon Feb 18 09:21:43 2008 +0000
17.2 +++ b/src/pvr2/vertex.glsl Thu Mar 06 08:22:00 2008 +0000
17.3 @@ -2,8 +2,8 @@
17.4
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;
.