revision 189:615b70cfd729
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 189:615b70cfd729 |
parent | 188:91ee93613faa |
child | 190:f7653df5e832 |
author | nkeynes |
date | Wed Aug 02 04:06:45 2006 +0000 (17 years ago) |
Issue 0003: TA Vertex compiler
Initial implementation of the TA.
Renderer hooked up to the TA "properly" now as well
Initial implementation of the TA.
Renderer hooked up to the TA "properly" now as well
src/Makefile.am | view | annotate | diff | log | ||
src/Makefile.in | view | annotate | diff | log | ||
src/asic.h | view | annotate | diff | log | ||
src/pvr2/pvr2.c | view | annotate | diff | log | ||
src/pvr2/pvr2.h | view | annotate | diff | log | ||
src/pvr2/pvr2mmio.h | view | annotate | diff | log | ||
src/pvr2/rendcore.c | view | annotate | diff | log | ||
src/pvr2/render.c | view | annotate | diff | log | ||
src/pvr2/ta.c | view | annotate | diff | log | ||
src/pvr2/tacore.c | view | annotate | diff | log |
1.1 --- a/src/Makefile.am Tue Aug 01 21:56:48 2006 +00001.2 +++ b/src/Makefile.am Wed Aug 02 04:06:45 2006 +00001.3 @@ -22,7 +22,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 \1.7 - pvr2/ta.c pvr2/render.c \1.8 + pvr2/tacore.c pvr2/render.c pvr2/rendcore.c \1.9 pvr2/texcache.c \1.10 maple/maple.c maple/maple.h \1.11 maple/controller.c maple/controller.h \
2.1 --- a/src/Makefile.in Tue Aug 01 21:56:48 2006 +00002.2 +++ b/src/Makefile.in Wed Aug 02 04:06:45 2006 +00002.3 @@ -150,7 +150,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 \2.7 - pvr2/ta.c pvr2/render.c \2.8 + pvr2/tacore.c pvr2/render.c pvr2/rendcore.c \2.9 pvr2/texcache.c \2.10 maple/maple.c maple/maple.h \2.11 maple/controller.c maple/controller.h \2.12 @@ -185,13 +185,14 @@2.13 sh4core.$(OBJEXT) sh4dasm.$(OBJEXT) sh4mmio.$(OBJEXT) \2.14 scif.$(OBJEXT) armcore.$(OBJEXT) armdasm.$(OBJEXT) \2.15 armmem.$(OBJEXT) aica.$(OBJEXT) audio.$(OBJEXT) pvr2.$(OBJEXT) \2.16 - ta.$(OBJEXT) render.$(OBJEXT) texcache.$(OBJEXT) \2.17 - maple.$(OBJEXT) controller.$(OBJEXT) support.$(OBJEXT) \2.18 - interface.$(OBJEXT) callbacks.$(OBJEXT) gui.$(OBJEXT) \2.19 - mmr_win.$(OBJEXT) debug_win.$(OBJEXT) dump_win.$(OBJEXT) \2.20 - loader.$(OBJEXT) bootstrap.$(OBJEXT) util.$(OBJEXT) \2.21 - display.$(OBJEXT) audio_null.$(OBJEXT) audio_esd.$(OBJEXT) \2.22 - video_null.$(OBJEXT) video_gtk.$(OBJEXT) video_x11.$(OBJEXT)2.23 + tacore.$(OBJEXT) render.$(OBJEXT) rendcore.$(OBJEXT) \2.24 + texcache.$(OBJEXT) maple.$(OBJEXT) controller.$(OBJEXT) \2.25 + support.$(OBJEXT) interface.$(OBJEXT) callbacks.$(OBJEXT) \2.26 + gui.$(OBJEXT) mmr_win.$(OBJEXT) debug_win.$(OBJEXT) \2.27 + dump_win.$(OBJEXT) loader.$(OBJEXT) bootstrap.$(OBJEXT) \2.28 + util.$(OBJEXT) display.$(OBJEXT) audio_null.$(OBJEXT) \2.29 + audio_esd.$(OBJEXT) video_null.$(OBJEXT) video_gtk.$(OBJEXT) \2.30 + video_x11.$(OBJEXT)2.31 lxdream_OBJECTS = $(am_lxdream_OBJECTS)2.32 lxdream_DEPENDENCIES =2.33 lxdream_LDFLAGS =2.34 @@ -214,15 +215,15 @@2.35 @AMDEP_TRUE@ ./$(DEPDIR)/loader.Po ./$(DEPDIR)/main.Po \2.36 @AMDEP_TRUE@ ./$(DEPDIR)/maple.Po ./$(DEPDIR)/mem.Po \2.37 @AMDEP_TRUE@ ./$(DEPDIR)/mmr_win.Po ./$(DEPDIR)/nrg.Po \2.38 -@AMDEP_TRUE@ ./$(DEPDIR)/pvr2.Po ./$(DEPDIR)/render.Po \2.39 -@AMDEP_TRUE@ ./$(DEPDIR)/scif.Po ./$(DEPDIR)/sh4core.Po \2.40 -@AMDEP_TRUE@ ./$(DEPDIR)/sh4dasm.Po ./$(DEPDIR)/sh4mem.Po \2.41 -@AMDEP_TRUE@ ./$(DEPDIR)/sh4mmio.Po ./$(DEPDIR)/support.Po \2.42 -@AMDEP_TRUE@ ./$(DEPDIR)/syscall.Po ./$(DEPDIR)/ta.Po \2.43 -@AMDEP_TRUE@ ./$(DEPDIR)/texcache.Po ./$(DEPDIR)/timer.Po \2.44 -@AMDEP_TRUE@ ./$(DEPDIR)/util.Po ./$(DEPDIR)/video_gtk.Po \2.45 -@AMDEP_TRUE@ ./$(DEPDIR)/video_null.Po ./$(DEPDIR)/video_x11.Po \2.46 -@AMDEP_TRUE@ ./$(DEPDIR)/watch.Po2.47 +@AMDEP_TRUE@ ./$(DEPDIR)/pvr2.Po ./$(DEPDIR)/rendcore.Po \2.48 +@AMDEP_TRUE@ ./$(DEPDIR)/render.Po ./$(DEPDIR)/scif.Po \2.49 +@AMDEP_TRUE@ ./$(DEPDIR)/sh4core.Po ./$(DEPDIR)/sh4dasm.Po \2.50 +@AMDEP_TRUE@ ./$(DEPDIR)/sh4mem.Po ./$(DEPDIR)/sh4mmio.Po \2.51 +@AMDEP_TRUE@ ./$(DEPDIR)/support.Po ./$(DEPDIR)/syscall.Po \2.52 +@AMDEP_TRUE@ ./$(DEPDIR)/tacore.Po ./$(DEPDIR)/texcache.Po \2.53 +@AMDEP_TRUE@ ./$(DEPDIR)/timer.Po ./$(DEPDIR)/util.Po \2.54 +@AMDEP_TRUE@ ./$(DEPDIR)/video_gtk.Po ./$(DEPDIR)/video_null.Po \2.55 +@AMDEP_TRUE@ ./$(DEPDIR)/video_x11.Po ./$(DEPDIR)/watch.Po2.56 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \2.57 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)2.58 CCLD = $(CC)2.59 @@ -305,6 +306,7 @@2.60 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmr_win.Po@am__quote@2.61 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nrg.Po@am__quote@2.62 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pvr2.Po@am__quote@2.63 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rendcore.Po@am__quote@2.64 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/render.Po@am__quote@2.65 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scif.Po@am__quote@2.66 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh4core.Po@am__quote@2.67 @@ -313,7 +315,7 @@2.68 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh4mmio.Po@am__quote@2.69 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/support.Po@am__quote@2.70 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/syscall.Po@am__quote@2.71 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ta.Po@am__quote@2.72 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tacore.Po@am__quote@2.73 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texcache.Po@am__quote@2.74 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timer.Po@am__quote@2.75 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@2.76 @@ -740,27 +742,27 @@2.77 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.78 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pvr2.obj `if test -f 'pvr2/pvr2.c'; then $(CYGPATH_W) 'pvr2/pvr2.c'; else $(CYGPATH_W) '$(srcdir)/pvr2/pvr2.c'; fi`2.80 -ta.o: pvr2/ta.c2.81 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ta.o -MD -MP -MF "$(DEPDIR)/ta.Tpo" \2.82 -@am__fastdepCC_TRUE@ -c -o ta.o `test -f 'pvr2/ta.c' || echo '$(srcdir)/'`pvr2/ta.c; \2.83 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/ta.Tpo" "$(DEPDIR)/ta.Po"; \2.84 -@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/ta.Tpo"; exit 1; \2.85 +tacore.o: pvr2/tacore.c2.86 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tacore.o -MD -MP -MF "$(DEPDIR)/tacore.Tpo" \2.87 +@am__fastdepCC_TRUE@ -c -o tacore.o `test -f 'pvr2/tacore.c' || echo '$(srcdir)/'`pvr2/tacore.c; \2.88 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/tacore.Tpo" "$(DEPDIR)/tacore.Po"; \2.89 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/tacore.Tpo"; exit 1; \2.90 @am__fastdepCC_TRUE@ fi2.91 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pvr2/ta.c' object='ta.o' libtool=no @AMDEPBACKSLASH@2.92 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/ta.Po' tmpdepfile='$(DEPDIR)/ta.TPo' @AMDEPBACKSLASH@2.93 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pvr2/tacore.c' object='tacore.o' libtool=no @AMDEPBACKSLASH@2.94 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/tacore.Po' tmpdepfile='$(DEPDIR)/tacore.TPo' @AMDEPBACKSLASH@2.95 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.96 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ta.o `test -f 'pvr2/ta.c' || echo '$(srcdir)/'`pvr2/ta.c2.97 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tacore.o `test -f 'pvr2/tacore.c' || echo '$(srcdir)/'`pvr2/tacore.c2.99 -ta.obj: pvr2/ta.c2.100 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ta.obj -MD -MP -MF "$(DEPDIR)/ta.Tpo" \2.101 -@am__fastdepCC_TRUE@ -c -o ta.obj `if test -f 'pvr2/ta.c'; then $(CYGPATH_W) 'pvr2/ta.c'; else $(CYGPATH_W) '$(srcdir)/pvr2/ta.c'; fi`; \2.102 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/ta.Tpo" "$(DEPDIR)/ta.Po"; \2.103 -@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/ta.Tpo"; exit 1; \2.104 +tacore.obj: pvr2/tacore.c2.105 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tacore.obj -MD -MP -MF "$(DEPDIR)/tacore.Tpo" \2.106 +@am__fastdepCC_TRUE@ -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.107 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/tacore.Tpo" "$(DEPDIR)/tacore.Po"; \2.108 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/tacore.Tpo"; exit 1; \2.109 @am__fastdepCC_TRUE@ fi2.110 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pvr2/ta.c' object='ta.obj' libtool=no @AMDEPBACKSLASH@2.111 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/ta.Po' tmpdepfile='$(DEPDIR)/ta.TPo' @AMDEPBACKSLASH@2.112 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pvr2/tacore.c' object='tacore.obj' libtool=no @AMDEPBACKSLASH@2.113 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/tacore.Po' tmpdepfile='$(DEPDIR)/tacore.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 ta.obj `if test -f 'pvr2/ta.c'; then $(CYGPATH_W) 'pvr2/ta.c'; else $(CYGPATH_W) '$(srcdir)/pvr2/ta.c'; fi`2.116 +@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.118 render.o: pvr2/render.c2.119 @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.120 @@ -784,6 +786,28 @@2.121 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.122 @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.124 +rendcore.o: pvr2/rendcore.c2.125 +@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.126 +@am__fastdepCC_TRUE@ -c -o rendcore.o `test -f 'pvr2/rendcore.c' || echo '$(srcdir)/'`pvr2/rendcore.c; \2.127 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/rendcore.Tpo" "$(DEPDIR)/rendcore.Po"; \2.128 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/rendcore.Tpo"; exit 1; \2.129 +@am__fastdepCC_TRUE@ fi2.130 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pvr2/rendcore.c' object='rendcore.o' libtool=no @AMDEPBACKSLASH@2.131 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/rendcore.Po' tmpdepfile='$(DEPDIR)/rendcore.TPo' @AMDEPBACKSLASH@2.132 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.133 +@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.134 +2.135 +rendcore.obj: pvr2/rendcore.c2.136 +@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.137 +@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.138 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/rendcore.Tpo" "$(DEPDIR)/rendcore.Po"; \2.139 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/rendcore.Tpo"; exit 1; \2.140 +@am__fastdepCC_TRUE@ fi2.141 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pvr2/rendcore.c' object='rendcore.obj' libtool=no @AMDEPBACKSLASH@2.142 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/rendcore.Po' tmpdepfile='$(DEPDIR)/rendcore.TPo' @AMDEPBACKSLASH@2.143 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.144 +@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.145 +2.146 texcache.o: pvr2/texcache.c2.147 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT texcache.o -MD -MP -MF "$(DEPDIR)/texcache.Tpo" \2.148 @am__fastdepCC_TRUE@ -c -o texcache.o `test -f 'pvr2/texcache.c' || echo '$(srcdir)/'`pvr2/texcache.c; \
3.1 --- a/src/asic.h Tue Aug 01 21:56:48 2006 +00003.2 +++ b/src/asic.h Wed Aug 02 04:06:45 2006 +00003.3 @@ -1,5 +1,5 @@3.4 /**3.5 - * $Id: asic.h,v 1.12 2006-07-09 23:06:58 nkeynes Exp $3.6 + * $Id: asic.h,v 1.13 2006-08-02 04:06:42 nkeynes Exp $3.7 *3.8 * Support for the miscellaneous ASIC functions (Primarily event multiplexing,3.9 * and DMA). Includes MMIO definitions for the 5f6000 and 5f7000 regions,3.10 @@ -190,11 +190,13 @@3.11 #define EVENT_PVR_DMA 193.12 #define EVENT_PVR_PUNCHOUT_DONE 213.14 +#define EVENT_TA_ERROR 313.15 #define EVENT_IDE 323.16 #define EVENT_AICA 333.18 #define EVENT_PVR_PRIM_ALLOC_FAIL 663.19 #define EVENT_PVR_MATRIX_ALLOC_FAIL 673.20 +#define EVENT_PVR_BAD_INPUT 683.22 /**3.23 * Raise an ASIC event
4.1 --- a/src/pvr2/pvr2.c Tue Aug 01 21:56:48 2006 +00004.2 +++ b/src/pvr2/pvr2.c Wed Aug 02 04:06:45 2006 +00004.3 @@ -1,5 +1,5 @@4.4 /**4.5 - * $Id: pvr2.c,v 1.27 2006-06-18 11:57:05 nkeynes Exp $4.6 + * $Id: pvr2.c,v 1.28 2006-08-02 04:06:45 nkeynes Exp $4.7 *4.8 * PVR2 (Video) Core module implementation and MMIO registers.4.9 *4.10 @@ -214,32 +214,63 @@4.11 return;4.12 }4.14 - if( reg == PVRID ) {4.15 - ERROR( "Write attempted to readonly register PVRID: ", val );4.16 - return;4.17 - }4.18 -4.19 - MMIO_WRITE( PVR2, reg, val );4.20 -4.21 switch(reg) {4.22 + case PVRID:4.23 + case PVRVER:4.24 + case GUNPOS:4.25 + case TA_POLYPOS:4.26 + case TA_LISTPOS:4.27 + /* Readonly registers */4.28 + break;4.29 + case RENDSTART:4.30 + if( val == 0xFFFFFFFF )4.31 + pvr2_render_scene();4.32 + break;4.33 case DISPADDR1:4.34 + val &= 0x00FFFFFC;4.35 + MMIO_WRITE( PVR2, reg, val );4.36 if( pvr2_state.retrace ) {4.37 pvr2_display_frame();4.38 pvr2_state.retrace = FALSE;4.39 }4.40 break;4.41 + case HCLIP:4.42 + MMIO_WRITE( PVR2, reg, val & 0x07FF07FF );4.43 + break;4.44 + case VCLIP:4.45 + MMIO_WRITE( PVR2, reg, val & 0x03FF03FF );4.46 + break;4.47 + case HPOS_IRQ:4.48 + MMIO_WRITE( PVR2, reg, val & 0x03FF33FF );4.49 + break;4.50 case VPOS_IRQ:4.51 - pvr2_state.irq_vpos1 = (val >> 16) & 0x03FF;4.52 + val = val & 0x03FF03FF;4.53 + pvr2_state.irq_vpos1 = (val >> 16);4.54 pvr2_state.irq_vpos2 = val & 0x03FF;4.55 + MMIO_WRITE( PVR2, reg, val );4.56 break;4.57 - case TAINIT:4.58 + case TA_TILEBASE:4.59 + case TA_TILEEND:4.60 + case TA_LISTBASE:4.61 + MMIO_WRITE( PVR2, reg, val & 0x00FFFFE0 );4.62 + break;4.63 + case TA_POLYBASE:4.64 + case TA_POLYEND:4.65 + MMIO_WRITE( PVR2, reg, val & 0x00FFFFFC );4.66 + break;4.67 + case TA_TILESIZE:4.68 + MMIO_WRITE( PVR2, reg, val & 0x000F003F );4.69 + break;4.70 + case TA_TILECFG:4.71 + MMIO_WRITE( PVR2, reg, val & 0x00133333 );4.72 + break;4.73 + case TA_INIT:4.74 if( val & 0x80000000 )4.75 pvr2_ta_init();4.76 break;4.77 - case RENDSTART:4.78 - if( val == 0xFFFFFFFF )4.79 - pvr2_render_scene();4.80 - break;4.81 +4.82 + default:4.83 + MMIO_WRITE( PVR2, reg, val );4.84 }4.85 }4.87 @@ -270,7 +301,7 @@4.89 void mmio_region_PVR2TA_write( uint32_t reg, uint32_t val )4.90 {4.91 - pvr2_ta_write( &val, sizeof(uint32_t) );4.92 + pvr2_ta_write( (char *)&val, sizeof(uint32_t) );4.93 }
5.1 --- a/src/pvr2/pvr2.h Tue Aug 01 21:56:48 2006 +00005.2 +++ b/src/pvr2/pvr2.h Wed Aug 02 04:06:45 2006 +00005.3 @@ -1,5 +1,5 @@5.4 /**5.5 - * $Id: pvr2.h,v 1.14 2006-06-18 11:57:05 nkeynes Exp $5.6 + * $Id: pvr2.h,v 1.15 2006-08-02 04:06:45 nkeynes Exp $5.7 *5.8 * PVR2 (video chip) functions and macros.5.9 *5.10 @@ -22,6 +22,8 @@5.11 #include "pvr2/pvr2mmio.h"5.12 #include <GL/gl.h>5.14 +typedef unsigned int pvraddr_t;5.15 +typedef unsigned int pvr64addr_t;5.17 #define DISPMODE_DE 0x00000001 /* Display enable */5.18 #define DISPMODE_SD 0x00000002 /* Scan double */5.19 @@ -52,6 +54,7 @@5.20 #define PVR2_RAM_BASE_INT 0x040000005.21 #define PVR2_RAM_SIZE (8 * 1024 * 1024)5.22 #define PVR2_RAM_PAGES (PVR2_RAM_SIZE>>12)5.23 +#define PVR2_RAM_MASK 0x7FFFFF5.25 void pvr2_next_frame( void );5.26 void pvr2_set_base_address( uint32_t );
6.1 --- a/src/pvr2/pvr2mmio.h Tue Aug 01 21:56:48 2006 +00006.2 +++ b/src/pvr2/pvr2mmio.h Wed Aug 02 04:06:45 2006 +00006.3 @@ -1,5 +1,5 @@6.4 /**6.5 - * $Id: pvr2mmio.h,v 1.3 2006-03-23 13:19:55 nkeynes Exp $6.6 + * $Id: pvr2mmio.h,v 1.4 2006-08-02 04:06:45 nkeynes Exp $6.7 *6.8 * PVR2 (video chip) MMIO register definitions.6.9 *6.10 @@ -19,9 +19,9 @@6.11 #include "mmio.h"6.13 MMIO_REGION_BEGIN( 0x005F8000, PVR2, "Power VR/2" )6.14 - LONG_PORT( 0x000, PVRID, PORT_MR, 0x17FD11DB, "PVR2 Core ID" )6.15 - LONG_PORT( 0x004, PVRVER, PORT_MR, 0x00000011, "PVR2 Core Version" )6.16 - LONG_PORT( 0x008, PVRRST, PORT_MR, 0, "PVR2 Reset" )6.17 + LONG_PORT( 0x000, PVRID, PORT_R, 0x17FD11DB, "PVR2 Core ID" )6.18 + LONG_PORT( 0x004, PVRVER, PORT_R, 0x00000011, "PVR2 Core Version" )6.19 + LONG_PORT( 0x008, PVRRST, PORT_MRW, 0, "PVR2 Reset" )6.20 LONG_PORT( 0x014, RENDSTART, PORT_W, 0, "Start render" )6.21 LONG_PORT( 0x020, OBJBASE, PORT_MRW, 0, "Object buffer base offset" )6.22 LONG_PORT( 0x02C, TILEBASE, PORT_MRW, 0, "Tile buffer base offset" )6.23 @@ -42,12 +42,14 @@6.24 LONG_PORT( 0x084, TSPCLIP, PORT_MRW, 0, "Texture clip distance (float32)" )6.25 LONG_PORT( 0x088, BGPLANEZ, PORT_MRW, 0, "Background plane depth (float32)" )6.26 LONG_PORT( 0x08C, BGPLANE, PORT_MRW, 0, "Background plane config" )6.27 + LONG_PORT( 0x098, ISPCFG, PORT_MRW, 0, "ISP config" )6.28 LONG_PORT( 0x0B0, FOGTBLCOL, PORT_MRW, 0, "Fog table colour" )6.29 LONG_PORT( 0x0B4, FOGVRTCOL, PORT_MRW, 0, "Fog vertex colour" )6.30 LONG_PORT( 0x0B8, FOGCOEFF, PORT_MRW, 0, "Fog density coefficient (float16)" )6.31 LONG_PORT( 0x0BC, CLAMPHI, PORT_MRW, 0, "Clamp high colour" )6.32 LONG_PORT( 0x0C0, CLAMPLO, PORT_MRW, 0, "Clamp low colour" )6.33 LONG_PORT( 0x0C4, GUNPOS, PORT_MRW, 0, "Lightgun position" )6.34 + LONG_PORT( 0x0C8, HPOS_IRQ, PORT_MRW, 0, "Raster horizontal event position" )6.35 LONG_PORT( 0x0CC, VPOS_IRQ, PORT_MRW, 0, "Raster event position" )6.36 LONG_PORT( 0x0D0, DISPCFG, PORT_MRW, 0, "Sync configuration & enable" )6.37 LONG_PORT( 0x0D4, HBORDER, PORT_MRW, 0, "Horizontal border area" )6.38 @@ -60,16 +62,16 @@6.39 LONG_PORT( 0x0F4, SCALERCFG, PORT_MRW, 0, "Scaler configuration (?)" )6.40 LONG_PORT( 0x108, PALETTECFG, PORT_MRW, 0, "Palette configuration" )6.41 LONG_PORT( 0x10C, BEAMPOS, PORT_R, 0, "Raster beam position" )6.42 - LONG_PORT( 0x124, TAOBJPBASE, PORT_MRW, 0, "TA Object Pointer Buffer start" )6.43 - LONG_PORT( 0x128, TAOBJBASE, PORT_MRW, 0, "TA Object Buffer start" )6.44 - LONG_PORT( 0x12C, TAOBJPEND, PORT_MRW, 0, "TA Object Pointer Buffer end" )6.45 - LONG_PORT( 0x130, TAOBJEND, PORT_MRW, 0, "TA Object Buffer end" )6.46 - LONG_PORT( 0x134, TAOBJPPOS, PORT_MRW, 0, "TA Object Pointer Buffer position" )6.47 - LONG_PORT( 0x138, TAOBJPOS, PORT_MRW, 0, "TA Object Buffer position" )6.48 - LONG_PORT( 0x13C, TATBSZ, PORT_MRW, 0, "TA Tile Buffer size" )6.49 - LONG_PORT( 0x140, TAOPBCFG, PORT_MRW, 0, "TA Object Pointer Buffer config" )6.50 - LONG_PORT( 0x144, TAINIT, PORT_MRW, 0, "TA Initialize" )6.51 - LONG_PORT( 0x164, TAOPLST, PORT_MRW, 0, "TA Object Pointer List start" )6.52 + LONG_PORT( 0x124, TA_TILEBASE, PORT_MRW, 0, "TA Tile matrix start" )6.53 + LONG_PORT( 0x128, TA_POLYBASE, PORT_MRW, 0, "TA Polygon buffer start" )6.54 + LONG_PORT( 0x12C, TA_TILEEND, PORT_MRW, 0, "TA Tile matrix end" )6.55 + LONG_PORT( 0x130, TA_POLYEND, PORT_MRW, 0, "TA Polygon buffer end" )6.56 + LONG_PORT( 0x134, TA_LISTPOS, PORT_R, 0, "TA Tile list position" )6.57 + LONG_PORT( 0x138, TA_POLYPOS, PORT_R, 0, "TA Polygon buffer position" )6.58 + LONG_PORT( 0x13C, TA_TILESIZE, PORT_MRW, 0, "TA Tile matrix size" )6.59 + LONG_PORT( 0x140, TA_TILECFG, PORT_MRW, 0, "TA Tile matrix config" )6.60 + LONG_PORT( 0x144, TA_INIT, PORT_W, 0, "TA Initialize" )6.61 + LONG_PORT( 0x164, TA_LISTBASE, PORT_MRW, 0, "TA Tile list start" )6.62 MMIO_REGION_END6.64 MMIO_REGION_BEGIN( 0x005F9000, PVR2PAL, "Power VR/2 CLUT Palettes" )
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00007.2 +++ b/src/pvr2/rendcore.c Wed Aug 02 04:06:45 2006 +00007.3 @@ -0,0 +1,341 @@7.4 +/**7.5 + * $Id: rendcore.c,v 1.1 2006-08-02 04:06:45 nkeynes Exp $7.6 + *7.7 + * PVR2 renderer core.7.8 + *7.9 + * Copyright (c) 2005 Nathan Keynes.7.10 + *7.11 + * This program is free software; you can redistribute it and/or modify7.12 + * it under the terms of the GNU General Public License as published by7.13 + * the Free Software Foundation; either version 2 of the License, or7.14 + * (at your option) any later version.7.15 + *7.16 + * This program is distributed in the hope that it will be useful,7.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of7.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the7.19 + * GNU General Public License for more details.7.20 + */7.21 +#include "pvr2/pvr2.h"7.22 +#include "asic.h"7.23 +7.24 +static int pvr2_poly_depthmode[8] = { GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL,7.25 + GL_GREATER, GL_NOTEQUAL, GL_GEQUAL,7.26 + GL_ALWAYS };7.27 +static int pvr2_poly_srcblend[8] = {7.28 + GL_ZERO, GL_ONE, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR,7.29 + GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA,7.30 + GL_ONE_MINUS_DST_ALPHA };7.31 +static int pvr2_poly_dstblend[8] = {7.32 + GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR,7.33 + GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA,7.34 + GL_ONE_MINUS_DST_ALPHA };7.35 +static int pvr2_poly_texblend[4] = {7.36 + GL_REPLACE, GL_BLEND, GL_DECAL, GL_MODULATE };7.37 +static int pvr2_render_colour_format[8] = {7.38 + COLFMT_ARGB1555, COLFMT_RGB565, COLFMT_ARGB4444, COLFMT_ARGB1555,7.39 + COLFMT_RGB888, COLFMT_ARGB8888, COLFMT_ARGB8888, COLFMT_ARGB4444 };7.40 +#define POLY1_DEPTH_MODE(poly1) ( pvr2_poly_depthmode[(poly1)>>29] )7.41 +#define POLY1_DEPTH_ENABLE(poly1) (((poly1)&0x04000000) == 0 )7.42 +#define POLY1_CULL_MODE(poly1) (((poly1)>>27)&0x03)7.43 +#define POLY1_TEXTURED(poly1) (((poly1)&0x02000000))7.44 +#define POLY1_SPECULAR(poly1) (((poly1)&0x01000000))7.45 +#define POLY1_SHADE_MODEL(poly1) (((poly1)&0x00800000) ? GL_SMOOTH : GL_FLAT)7.46 +#define POLY1_UV16(poly1) (((poly1)&0x00400000))7.47 +#define POLY1_SINGLE_TILE(poly1) (((poly1)&0x00200000))7.48 +7.49 +#define POLY2_SRC_BLEND(poly2) ( pvr2_poly_srcblend[(poly2) >> 29] )7.50 +#define POLY2_DEST_BLEND(poly2) ( pvr2_poly_dstblend[((poly2)>>26)&0x07] )7.51 +#define POLY2_SRC_BLEND_ENABLE(poly2) ((poly2)&0x02000000)7.52 +#define POLY2_DEST_BLEND_ENABLE(poly2) ((poly2)&0x01000000)7.53 +#define POLY2_COLOUR_CLAMP_ENABLE(poly2) ((poly2)&0x00200000)7.54 +#define POLY2_ALPHA_ENABLE(poly2) ((poly2)&0x001000000)7.55 +#define POLY2_TEX_ALPHA_ENABLE(poly2) (((poly2)&0x00080000) == 0 )7.56 +#define POLY2_TEX_WIDTH(poly2) ( 1<< ((((poly2) >> 3) & 0x07 ) + 3) )7.57 +#define POLY2_TEX_HEIGHT(poly2) ( 1<< (((poly2) & 0x07 ) + 3) )7.58 +#define POLY2_TEX_BLEND(poly2) ( pvr2_poly_texblend[((poly2) >> 6)&0x03] )7.59 +7.60 +#define RENDER_ZONLY 07.61 +#define RENDER_NORMAL 1 /* Render non-modified polygons */7.62 +#define RENDER_CHEAPMOD 2 /* Render cheap-modified polygons */7.63 +#define RENDER_FULLMOD 3 /* Render the fully-modified version of the polygons */7.64 +7.65 +#define CULL_NONE 07.66 +#define CULL_SMALL 17.67 +#define CULL_CCW 27.68 +#define CULL_CW 37.69 +7.70 +#define SEGMENT_END 0x800000007.71 +#define SEGMENT_SORT_TRANS 0x200000007.72 +#define SEGMENT_START 0x100000007.73 +#define SEGMENT_X(c) (((c) >> 2) & 0x3F)7.74 +#define SEGMENT_Y(c) (((c) >> 8) & 0x3F)7.75 +#define NO_POINTER 0x800000007.76 +7.77 +extern char *video_base;7.78 +7.79 +struct tile_segment {7.80 + uint32_t control;7.81 + pvraddr_t opaque_ptr;7.82 + pvraddr_t opaquemod_ptr;7.83 + pvraddr_t trans_ptr;7.84 + pvraddr_t transmod_ptr;7.85 + pvraddr_t punchout_ptr;7.86 +};7.87 +7.88 +/**7.89 + * Convert a half-float (16-bit) FP number to a regular 32-bit float.7.90 + * Source is 1-bit sign, 5-bit exponent, 10-bit mantissa.7.91 + * TODO: Check the correctness of this.7.92 + */7.93 +float halftofloat( uint16_t half )7.94 +{7.95 + union {7.96 + float f;7.97 + uint32_t i;7.98 + } temp;7.99 + int e = ((half & 0x7C00) >> 10) - 15 + 127;7.100 +7.101 + temp.i = ((half & 0x8000) << 16) | (e << 23) |7.102 + ((half & 0x03FF) << 13);7.103 + return temp.f;7.104 +}7.105 +7.106 +7.107 +/**7.108 + * Setup the GL context for the supplied polygon context.7.109 + * @param context pointer to 3 or 5 words of polygon context7.110 + * @param modified boolean flag indicating that the modified7.111 + * version should be used, rather than the normal version.7.112 + */7.113 +void render_set_context( uint32_t *context, int render_mode )7.114 +{7.115 + uint32_t poly1 = context[0], poly2, texture;7.116 + if( render_mode == RENDER_FULLMOD ) {7.117 + poly2 = context[3];7.118 + texture = context[4];7.119 + } else {7.120 + poly2 = context[1];7.121 + texture = context[2];7.122 + }7.123 +7.124 + if( POLY1_DEPTH_ENABLE(poly1) ) {7.125 + glEnable( GL_DEPTH_TEST );7.126 + glDepthFunc( POLY1_DEPTH_MODE(poly1) );7.127 + } else {7.128 + glDisable( GL_DEPTH_TEST );7.129 + }7.130 +7.131 + switch( POLY1_CULL_MODE(poly1) ) {7.132 + case CULL_NONE:7.133 + case CULL_SMALL:7.134 + glDisable( GL_CULL_FACE );7.135 + break;7.136 + case CULL_CCW:7.137 + glEnable( GL_CULL_FACE );7.138 + glFrontFace( GL_CW );7.139 + break;7.140 + case CULL_CW:7.141 + glEnable( GL_CULL_FACE );7.142 + glFrontFace( GL_CCW );7.143 + break;7.144 + }7.145 +7.146 + if( POLY1_TEXTURED(poly1) ) {7.147 + int width = POLY2_TEX_WIDTH(poly2);7.148 + int height = POLY2_TEX_HEIGHT(poly2);7.149 + glEnable(GL_TEXTURE_2D);7.150 + texcache_get_texture( (texture&0x001FFFFF)<<3, width, height, texture );7.151 + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, POLY2_TEX_BLEND(poly2) );7.152 + } else {7.153 + glDisable( GL_TEXTURE_2D );7.154 + }7.155 +7.156 + glShadeModel( POLY1_SHADE_MODEL(poly1) );7.157 +7.158 + glBlendFunc( POLY2_SRC_BLEND(poly2), POLY2_DEST_BLEND(poly2) );7.159 + if( POLY2_TEX_ALPHA_ENABLE(poly2) ) {7.160 + glEnable(GL_BLEND);7.161 + } else {7.162 + glDisable(GL_BLEND);7.163 + }7.164 +}7.165 +7.166 +void render_vertexes( uint32_t poly1, uint32_t *vertexes, int num_vertexes, int vertex_size,7.167 + int render_mode )7.168 +{7.169 + int i, m=0;7.170 +7.171 + if( render_mode == RENDER_FULLMOD ) {7.172 + m = (vertex_size - 3)/2;7.173 + }7.174 +7.175 + glBegin( GL_TRIANGLE_STRIP );7.176 +7.177 + for( i=0; i<num_vertexes; i++ ) {7.178 + float *vertexf = (float *)vertexes;7.179 + uint32_t argb;7.180 + if( POLY1_TEXTURED(poly1) ) {7.181 + if( POLY1_UV16(poly1) ) {7.182 + glTexCoord2f( halftofloat(vertexes[m+3]>>16),7.183 + halftofloat(vertexes[m+3]) );7.184 + argb = vertexes[m+4];7.185 + } else {7.186 + glTexCoord2f( vertexf[m+3], vertexf[m+4] );7.187 + argb = vertexes[m+5];7.188 + }7.189 + } else {7.190 + argb = vertexes[m+3];7.191 + }7.192 +7.193 + glColor4ub( (GLubyte)(argb >> 16), (GLubyte)(argb >> 8),7.194 + (GLubyte)argb, (GLubyte)(argb >> 24) );7.195 + glVertex3f( vertexf[0], vertexf[1], vertexf[2] );7.196 + vertexes += vertex_size;7.197 + }7.198 +7.199 + glEnd();7.200 +}7.201 +7.202 +/**7.203 + * Render a simple (not auto-sorted) tile7.204 + */7.205 +void render_tile( pvraddr_t tile_entry, int render_mode, gboolean cheap_modifier_mode ) {7.206 +7.207 + uint32_t *tile_list = (uint32_t *)(video_base+tile_entry);7.208 + do {7.209 + uint32_t entry = *tile_list++;7.210 + if( entry >> 28 == 0x0F ) {7.211 + break;7.212 + } else if( entry >> 28 == 0x0E ) {7.213 + tile_list = (uint32_t *)(video_base + (entry&0x007FFFFF));7.214 + } else {7.215 + uint32_t *polygon = (uint32_t *)(video_base + ((entry & 0x001FFFFF) << 2));7.216 + int is_modified = entry & 0x01000000;7.217 + int vertex_length = (entry >> 21) & 0x07;7.218 + int context_length = 3;7.219 + if( is_modified && !cheap_modifier_mode ) {7.220 + context_length = 5;7.221 + vertex_length *= 2 ;7.222 + }7.223 + vertex_length += 3;7.224 +7.225 + if( (entry & 0xE0000000) == 0x80000000 ) {7.226 + /* Triangle(s) */7.227 + int strip_count = ((entry >> 25) & 0x0F)+1;7.228 + int polygon_length = 3 * vertex_length + context_length;7.229 + int i;7.230 + for( i=0; i<strip_count; i++ ) {7.231 + render_set_context( polygon, render_mode );7.232 + render_vertexes( *polygon, polygon+context_length, 3, vertex_length,7.233 + render_mode );7.234 + polygon += polygon_length;7.235 + }7.236 + } else if( (entry & 0xE0000000) == 0xA0000000 ) {7.237 + /* Sprite(s) */7.238 + int strip_count = (entry >> 25) & 0x0F;7.239 + int polygon_length = 4 * vertex_length + context_length;7.240 + int i;7.241 + for( i=0; i<strip_count; i++ ) {7.242 + render_set_context( polygon, render_mode );7.243 + render_vertexes( *polygon, polygon+context_length, 4, vertex_length,7.244 + render_mode );7.245 + polygon += polygon_length;7.246 + }7.247 + } else {7.248 + /* Polygon */7.249 + int i, first=-1, last = -1;7.250 + for( i=0; i<6; i++ ) {7.251 + if( entry & (0x40000000>>i) ) {7.252 + if( first == -1 ) first = i;7.253 + last = i;7.254 + }7.255 + }7.256 + if( first != -1 ) {7.257 + first = 0;7.258 + render_set_context(polygon, render_mode);7.259 + render_vertexes( *polygon, polygon+context_length + (first*vertex_length),7.260 + (last-first+3), vertex_length, render_mode );7.261 + }7.262 + }7.263 + }7.264 + } while( 1 );7.265 +}7.266 +7.267 +void render_autosort_tile( pvraddr_t tile_entry, int render_mode, gboolean cheap_modifier_mode ) {7.268 + //WARN( "Autosort not implemented yet" );7.269 + render_tile( tile_entry, render_mode, cheap_modifier_mode );7.270 +}7.271 +7.272 +void pvr2_render_tilebuffer( int width, int height, int clipx1, int clipy1,7.273 + int clipx2, int clipy2 ) {7.274 +7.275 + pvraddr_t segmentbase = MMIO_READ( PVR2, TILEBASE );7.276 + int tile_sort;7.277 + gboolean cheap_shadow;7.278 +7.279 + int obj_config = MMIO_READ( PVR2, OBJCFG );7.280 + int isp_config = MMIO_READ( PVR2, ISPCFG );7.281 + int shadow_cfg = MMIO_READ( PVR2, SHADOW );7.282 +7.283 + if( obj_config & 0x00200000 ) {7.284 + if( isp_config & 1 ) {7.285 + tile_sort = 0;7.286 + } else {7.287 + tile_sort = 2;7.288 + }7.289 + } else {7.290 + tile_sort = 1;7.291 + }7.292 +7.293 + cheap_shadow = shadow_cfg & 0x100 ? TRUE : FALSE;7.294 +7.295 + struct tile_segment *segment = (struct tile_segment *)(video_base + segmentbase);7.296 +7.297 + glEnable( GL_SCISSOR_TEST );7.298 + while( (segment->control & SEGMENT_END) == 0 ) {7.299 + int tilex = SEGMENT_X(segment->control);7.300 + int tiley = SEGMENT_Y(segment->control);7.301 +7.302 + int x1 = tilex << 5;7.303 + int y1 = tiley << 5;7.304 + if( x1 + 32 <= clipx1 ||7.305 + y1 + 32 <= clipy1 ||7.306 + x1 >= clipx2 ||7.307 + y1 >= clipy2 ) {7.308 + /* Tile completely clipped, skip */7.309 + segment++;7.310 + continue;7.311 + }7.312 +7.313 + /* Set a scissor on the visible part of the tile */7.314 + int w = MIN(x1+32, clipx2) - x1;7.315 + int h = MIN(y1+32, clipy2) - y1;7.316 + x1 = MAX(x1,clipx1);7.317 + y1 = MAX(y1,clipy1);7.318 + glScissor( x1, height-y1-h, w, h );7.319 +7.320 + if( (segment->opaque_ptr & NO_POINTER) == 0 ) {7.321 + if( (segment->opaquemod_ptr & NO_POINTER) == 0 ) {7.322 + /* TODO */7.323 + }7.324 + render_tile( segment->opaque_ptr, RENDER_NORMAL, cheap_shadow );7.325 + }7.326 +7.327 + if( (segment->trans_ptr & NO_POINTER) == 0 ) {7.328 + if( (segment->transmod_ptr & NO_POINTER) == 0 ) {7.329 + /* TODO */7.330 + }7.331 + if( tile_sort == 2 || (tile_sort == 1 && (segment->control & SEGMENT_SORT_TRANS)) ) {7.332 + render_autosort_tile( segment->trans_ptr, RENDER_NORMAL, cheap_shadow );7.333 + } else {7.334 + render_tile( segment->trans_ptr, RENDER_NORMAL, cheap_shadow );7.335 + }7.336 + }7.337 +7.338 + if( (segment->punchout_ptr & NO_POINTER) == 0 ) {7.339 + render_tile( segment->punchout_ptr, RENDER_NORMAL, cheap_shadow );7.340 + }7.341 + segment++;7.342 + }7.343 + glDisable( GL_SCISSOR_TEST );7.344 +}
8.1 --- a/src/pvr2/render.c Tue Aug 01 21:56:48 2006 +00008.2 +++ b/src/pvr2/render.c Wed Aug 02 04:06:45 2006 +00008.3 @@ -1,7 +1,7 @@8.4 /**8.5 - * $Id: render.c,v 1.10 2006-06-27 09:32:09 nkeynes Exp $8.6 + * $Id: render.c,v 1.11 2006-08-02 04:06:45 nkeynes Exp $8.7 *8.8 - * PVR2 Renderer support. This is where the real work happens.8.9 + * PVR2 Renderer support. This part is primarily8.10 *8.11 * Copyright (c) 2005 Nathan Keynes.8.12 *8.13 @@ -19,41 +19,10 @@8.14 #include "pvr2/pvr2.h"8.15 #include "asic.h"8.17 -8.18 -#define POLY_COLOUR_PACKED 0x000000008.19 -#define POLY_COLOUR_FLOAT 0x000000108.20 -#define POLY_COLOUR_INTENSITY 0x000000208.21 -#define POLY_COLOUR_INTENSITY_PREV 0x000000308.22 -8.23 -static int pvr2_poly_vertexes[4] = { 3, 4, 6, 8 };8.24 -static int pvr2_poly_type[4] = { GL_TRIANGLES, GL_QUADS, GL_TRIANGLE_STRIP, GL_TRIANGLE_STRIP };8.25 -static int pvr2_poly_depthmode[8] = { GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL,8.26 - GL_GREATER, GL_NOTEQUAL, GL_GEQUAL,8.27 - GL_ALWAYS };8.28 -static int pvr2_poly_srcblend[8] = {8.29 - GL_ZERO, GL_ONE, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR,8.30 - GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA,8.31 - GL_ONE_MINUS_DST_ALPHA };8.32 -static int pvr2_poly_dstblend[8] = {8.33 - GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR,8.34 - GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA,8.35 - GL_ONE_MINUS_DST_ALPHA };8.36 -static int pvr2_poly_texblend[4] = {8.37 - GL_REPLACE, GL_BLEND, GL_DECAL, GL_MODULATE };8.38 static int pvr2_render_colour_format[8] = {8.39 COLFMT_ARGB1555, COLFMT_RGB565, COLFMT_ARGB4444, COLFMT_ARGB1555,8.40 COLFMT_RGB888, COLFMT_ARGB8888, COLFMT_ARGB8888, COLFMT_ARGB4444 };8.42 -#define POLY_STRIP_TYPE(poly) ( pvr2_poly_type[((poly->command)>>18)&0x03] )8.43 -#define POLY_STRIP_VERTEXES(poly) ( pvr2_poly_vertexes[((poly->command)>>18)&0x03] )8.44 -#define POLY_DEPTH_MODE(poly) ( pvr2_poly_depthmode[poly->poly_cfg>>29] )8.45 -#define POLY_DEPTH_WRITE(poly) ((poly->poly_cfg&0x04000000) == 0 )8.46 -#define POLY_TEX_WIDTH(poly) ( 1<< (((poly->poly_mode >> 3) & 0x07 ) + 3) )8.47 -#define POLY_TEX_HEIGHT(poly) ( 1<< (((poly->poly_mode) & 0x07 ) + 3) )8.48 -#define POLY_BLEND_SRC(poly) ( pvr2_poly_srcblend[(poly->poly_mode) >> 29] )8.49 -#define POLY_BLEND_DEST(poly) ( pvr2_poly_dstblend[((poly->poly_mode)>>26)&0x07] )8.50 -#define POLY_TEX_BLEND(poly) ( pvr2_poly_texblend[((poly->poly_mode) >> 6)&0x03] )8.51 -#define POLY_COLOUR_TYPE(poly) ( poly->command & 0x00000030 )8.53 /**8.54 * Describes a rendering buffer that's actually held in GL, for when we need8.55 @@ -69,61 +38,6 @@8.56 struct pvr2_render_buffer front_buffer;8.57 struct pvr2_render_buffer back_buffer;8.59 -struct tile_descriptor {8.60 - uint32_t header[6];8.61 - struct tile_pointers {8.62 - uint32_t tile_id;8.63 - uint32_t opaque_ptr;8.64 - uint32_t opaque_mod_ptr;8.65 - uint32_t trans_ptr;8.66 - uint32_t trans_mod_ptr;8.67 - uint32_t punchout_ptr;8.68 - } tile[0];8.69 -};8.70 -8.71 -/* Textured polygon */8.72 -struct pvr2_poly {8.73 - uint32_t command;8.74 - uint32_t poly_cfg; /* Bitmask */8.75 - uint32_t poly_mode; /* texture/blending mask */8.76 - uint32_t texture; /* texture data */8.77 - float alpha;8.78 - float red;8.79 - float green;8.80 - float blue;8.81 -};8.82 -8.83 -struct pvr2_specular_highlight {8.84 - float base_alpha;8.85 - float base_red;8.86 - float base_green;8.87 - float base_blue;8.88 - float offset_alpha;8.89 - float offset_red;8.90 - float offset_green;8.91 - float offset_blue;8.92 -};8.93 -8.94 -8.95 -struct pvr2_vertex_packed {8.96 - uint32_t command;8.97 - float x, y, z;8.98 - float s,t;8.99 - uint32_t colour;8.100 - float f;8.101 -};8.102 -8.103 -struct pvr2_vertex_float {8.104 - uint32_t command;8.105 - float x,y,z;8.106 - float a, r, g, b;8.107 -};8.108 -8.109 -union pvr2_vertex {8.110 - struct pvr2_vertex_packed pack;8.111 - struct pvr2_vertex_float flt;8.112 -};8.113 -8.114 typedef struct pvr2_bgplane_packed {8.115 uint32_t poly_cfg, poly_mode;8.116 uint32_t texture_mode;8.117 @@ -160,6 +74,7 @@8.118 glDisable( GL_BLEND );8.119 glDisable( GL_TEXTURE_2D );8.120 glDisable( GL_ALPHA_TEST );8.121 + glDisable( GL_CULL_FACE );8.122 glListBase(pvr2_render_font_list - 32);8.123 glColor3f( 1.0, 1.0, 1.0 );8.124 glRasterPos2i( x, y );8.125 @@ -169,6 +84,27 @@8.126 return len;8.127 }8.129 +void glDrawGrid( int width, int height )8.130 +{8.131 + int i;8.132 + glDisable( GL_DEPTH_TEST );8.133 + glLineWidth(1);8.134 +8.135 + glBegin( GL_LINES );8.136 + glColor4f( 1.0, 1.0, 1.0, 1.0 );8.137 + for( i=32; i<width; i+=32 ) {8.138 + glVertex3f( i, 0.0, 3.0 );8.139 + glVertex3f( i,height-1, 3.0 );8.140 + }8.141 +8.142 + for( i=32; i<height; i+=32 ) {8.143 + glVertex3f( 0.0, i, 3.0 );8.144 + glVertex3f( width, i, 3.0 );8.145 + }8.146 + glEnd();8.147 +8.148 +}8.149 +8.151 gboolean pvr2_render_init( void )8.152 {8.153 @@ -276,160 +212,12 @@8.154 glCullFace( GL_BACK );8.156 /* Clear out the buffers */8.157 + glDisable( GL_SCISSOR_TEST );8.158 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);8.159 glClearDepth(bgplanez);8.160 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );8.161 }8.163 -static void pvr2_dump_display_list( uint32_t * display_list, uint32_t length )8.164 -{8.165 - uint32_t i;8.166 - gboolean vertex = FALSE;8.167 - for( i =0; i<length>>2; i++ ) {8.168 - if( (i % 8) == 0 ) {8.169 - if( i != 0 )8.170 - fprintf( stderr, "\n" );8.171 - fprintf( stderr, "%08X:", i*4 );8.172 - if( display_list[i] == 0xE0000000 ||8.173 - display_list[i] == 0xF0000000 )8.174 - vertex = TRUE;8.175 - else vertex = FALSE;8.176 - }8.177 - if( vertex && (i%8) > 0 && (i%8) < 4 )8.178 - fprintf( stderr, " %f", ((float *)display_list)[i] );8.179 - else8.180 - fprintf( stderr, " %08X", display_list[i] );8.181 - }8.182 - fprintf( stderr, "\n" );8.183 -}8.184 -8.185 -static void pvr2_render_display_list( uint32_t *display_list, uint32_t length )8.186 -{8.187 - uint32_t *cmd_ptr = display_list;8.188 - int strip_length = 0, vertex_count = 0;8.189 - int colour_type;8.190 - gboolean textured = FALSE;8.191 - gboolean shaded = FALSE;8.192 - struct pvr2_poly *poly;8.193 - if( pvr2_render_trace ) {8.194 - fprintf( stderr, "-------- %d\n", pvr2_get_frame_count() );8.195 - pvr2_dump_display_list( display_list, length );8.196 - }8.197 - while( cmd_ptr < display_list+(length>>2) ) {8.198 - unsigned int cmd = *cmd_ptr >> 24;8.199 - switch( cmd ) {8.200 - case PVR2_CMD_POLY_OPAQUE:8.201 - case PVR2_CMD_POLY_TRANS:8.202 - case PVR2_CMD_POLY_PUNCHOUT:8.203 - poly = (struct pvr2_poly *)cmd_ptr;8.204 - if( poly->command & PVR2_POLY_TEXTURED ) {8.205 - uint32_t addr = PVR2_TEX_ADDR(poly->texture);8.206 - int width = POLY_TEX_WIDTH(poly);8.207 - int height = POLY_TEX_HEIGHT(poly);8.208 - glEnable( GL_TEXTURE_2D );8.209 - texcache_get_texture( addr, width, height, poly->texture );8.210 - textured = TRUE;8.211 - glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, POLY_TEX_BLEND(poly) );8.212 - } else {8.213 - textured = FALSE;8.214 - glDisable( GL_TEXTURE_2D );8.215 - }8.216 - glBlendFunc( POLY_BLEND_SRC(poly), POLY_BLEND_DEST(poly) );8.217 - if( poly->command & PVR2_POLY_SPECULAR ) {8.218 - /* Second block expected */8.219 - }8.220 - if( POLY_DEPTH_WRITE(poly) ) {8.221 - glEnable( GL_DEPTH_TEST );8.222 - glDepthFunc( POLY_DEPTH_MODE(poly) );8.223 - } else {8.224 - glDisable( GL_DEPTH_TEST );8.225 - }8.226 -8.227 - switch( (poly->poly_cfg >> 27) & 0x03 ) {8.228 - case 0:8.229 - case 1:8.230 - glDisable( GL_CULL_FACE );8.231 - break;8.232 - case 2:8.233 - glEnable( GL_CULL_FACE );8.234 - glFrontFace( GL_CW );8.235 - break;8.236 - case 3:8.237 - glEnable( GL_CULL_FACE );8.238 - glFrontFace( GL_CCW );8.239 - }8.240 - strip_length = POLY_STRIP_VERTEXES( poly );8.241 - colour_type = POLY_COLOUR_TYPE( poly );8.242 - vertex_count = 0;8.243 - if( poly->command & PVR2_POLY_SHADED ) {8.244 - shaded = TRUE;8.245 - } else {8.246 - shaded = FALSE;8.247 - }8.248 - if( poly->poly_mode & PVR2_POLY_MODE_TEXALPHA ) {8.249 - glDisable( GL_BLEND );8.250 - } else {8.251 - glEnable( GL_BLEND );8.252 - }8.253 -8.254 - break;8.255 - case PVR2_CMD_MOD_OPAQUE:8.256 - case PVR2_CMD_MOD_TRANS:8.257 - /* TODO */8.258 - break;8.259 - case PVR2_CMD_END_OF_LIST:8.260 - break;8.261 - case PVR2_CMD_VERTEX_LAST:8.262 - case PVR2_CMD_VERTEX:8.263 - if( vertex_count == 0 ) {8.264 - glBegin( GL_TRIANGLE_STRIP );8.265 - }8.266 - vertex_count++;8.267 -8.268 - struct pvr2_vertex_packed *vertex = (struct pvr2_vertex_packed *)cmd_ptr;8.269 - if( textured ) {8.270 - glTexCoord2f( vertex->s, vertex->t );8.271 -8.272 - if( shaded || vertex_count == 1) {8.273 - switch( colour_type ) {8.274 - case POLY_COLOUR_PACKED:8.275 - glColor4ub( vertex->colour >> 16, vertex->colour >> 8,8.276 - vertex->colour, vertex->colour >> 24 );8.277 - break;8.278 - }8.279 - }8.280 - } else {8.281 - if( shaded || vertex_count == 1 ) {8.282 - switch( colour_type ) {8.283 - case POLY_COLOUR_PACKED:8.284 - glColor4ub( vertex->colour >> 16, vertex->colour >> 8,8.285 - vertex->colour, vertex->colour >> 24 );8.286 - break;8.287 - case POLY_COLOUR_FLOAT:8.288 - {8.289 - struct pvr2_vertex_float *v = (struct pvr2_vertex_float *)cmd_ptr;8.290 - glColor4f( v->r, v->g, v->b, v->a );8.291 - }8.292 - break;8.293 - }8.294 - }8.295 - }8.296 -8.297 - glVertex3f( vertex->x, vertex->y, vertex->z );8.298 -8.299 - if( cmd == PVR2_CMD_VERTEX_LAST ) {8.300 - glEnd();8.301 - vertex_count = 0;8.302 - }8.303 - break;8.304 - default:8.305 - ERROR( "Unhandled command %08X in display list", *cmd_ptr );8.306 - pvr2_dump_display_list( display_list, length );8.307 - return;8.308 - }8.309 - cmd_ptr += 8; /* Next record */8.310 - }8.311 -}8.313 #define MIN3( a,b,c ) ((a) < (b) ? ( (a) < (c) ? (a) : (c) ) : ((b) < (c) ? (b) : (c)) )8.314 #define MAX3( a,b,c ) ((a) > (b) ? ( (a) > (c) ? (a) : (c) ) : ((b) > (c) ? (b) : (c)) )8.315 @@ -440,11 +228,15 @@8.316 */8.317 void pvr2_render_draw_backplane( uint32_t mode, uint32_t *poly )8.318 {8.319 +8.320 if( (mode >> 24) == 0x01 ) {8.321 /* Packed colour. I think */8.322 pvr2_bgplane_packed_t bg = (pvr2_bgplane_packed_t)poly;8.323 if( bg->colour1 != bg->colour2 || bg->colour2 != bg->colour3 ) {8.324 WARN( "Multiple background colours specified. Confused" );8.325 + fprintf( stderr, "bgplane mode: %08X PBUF: %08X\n", mode,8.326 + MMIO_READ( PVR2, OBJBASE ) );8.327 + fwrite_dump( poly, 80, stderr );8.328 }8.329 float x1 = MIN3( bg->x1, bg->x2, bg->x3 );8.330 float y1 = MIN3( bg->y1, bg->y2, bg->y3 );8.331 @@ -500,38 +292,29 @@8.332 pvr2_render_prepare_context( render_addr, width, height, colour_format,8.333 bgplanez, render_to_tex );8.335 - uint32_t *display_list =8.336 - (uint32_t *)mem_get_region(PVR2_RAM_BASE + MMIO_READ( PVR2, OBJBASE ));8.337 -8.338 - uint32_t display_length = *display_list++;8.339 -8.340 int clip_x = MMIO_READ( PVR2, HCLIP ) & 0x03FF;8.341 int clip_y = MMIO_READ( PVR2, VCLIP ) & 0x03FF;8.342 int clip_width = ((MMIO_READ( PVR2, HCLIP ) >> 16) & 0x03FF) - clip_x + 1;8.343 int clip_height= ((MMIO_READ( PVR2, VCLIP ) >> 16) & 0x03FF) - clip_y + 1;8.345 - if( clip_x == 0 && clip_y == 0 && clip_width == width && clip_height == height ) {8.346 - glDisable( GL_SCISSOR_TEST );8.347 - } else {8.348 - glEnable( GL_SCISSOR_TEST );8.349 - glScissor( clip_x, clip_y, clip_width, clip_height );8.350 - }8.351 -8.352 /* Fog setup goes here */8.354 /* Render the background plane */8.355 uint32_t bgplane_mode = MMIO_READ(PVR2, BGPLANE);8.356 - uint32_t *bgplane = display_list + (((bgplane_mode & 0x00FFFFFF)) >> 3) - 1;8.357 + uint32_t *display_list =8.358 + (uint32_t *)mem_get_region(PVR2_RAM_BASE + MMIO_READ( PVR2, OBJBASE ));8.359 +8.360 + uint32_t *bgplane = display_list + (((bgplane_mode & 0x00FFFFFF)) >> 3) ;8.361 pvr2_render_draw_backplane( bgplane_mode, bgplane );8.363 - /* Render the display list */8.364 - pvr2_render_display_list( display_list, display_length );8.365 + pvr2_render_tilebuffer( width, height, clip_x, clip_y,8.366 + clip_x + clip_width, clip_y + clip_height );8.368 /* Post-render cleanup and update */8.370 /* Add frame, fps, etc data */8.371 + //glDrawGrid( width, height );8.372 glPrintf( 4, 16, "Frame %d", pvr2_get_frame_count() );8.373 -8.374 /* Generate end of render event */8.375 asic_event( EVENT_PVR_RENDER_DONE );8.376 DEBUG( "Rendered frame %d", pvr2_get_frame_count() );
9.1 --- a/src/pvr2/ta.c Tue Aug 01 21:56:48 2006 +00009.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +00009.3 @@ -1,120 +0,0 @@9.4 -/**9.5 - * $Id: ta.c,v 1.3 2006-03-15 13:16:50 nkeynes Exp $9.6 - *9.7 - * PVR2 Tile Accelerator support. In principle this does a lot more work9.8 - * than is currently implemented - we cheat. A lot.9.9 - *9.10 - * Copyright (c) 2005 Nathan Keynes.9.11 - *9.12 - * This program is free software; you can redistribute it and/or modify9.13 - * it under the terms of the GNU General Public License as published by9.14 - * the Free Software Foundation; either version 2 of the License, or9.15 - * (at your option) any later version.9.16 - *9.17 - * This program is distributed in the hope that it will be useful,9.18 - * but WITHOUT ANY WARRANTY; without even the implied warranty of9.19 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9.20 - * GNU General Public License for more details.9.21 - */9.22 -9.23 -#include "pvr2/pvr2.h"9.24 -#include "asic.h"9.25 -#include "dream.h"9.26 -9.27 -/** Tile Accelerator */9.28 -9.29 -struct tacmd {9.30 - uint32_t command;9.31 - uint32_t param1;9.32 - uint32_t param2;9.33 - uint32_t texture;9.34 - float alpha;9.35 - float red;9.36 - float green;9.37 - float blue;9.38 -};9.39 -9.40 -struct vertex_type1 {9.41 - uint32_t command;9.42 - float x, y, z;9.43 - uint32_t blank, blank2;9.44 - uint32_t col;9.45 - float f;9.46 -};9.47 -9.48 -struct pvr2_ta_status {9.49 - uint32_t *length;9.50 - unsigned int last_poly_type;9.51 -} pvr2_ta_status = {NULL,0};9.52 -9.53 -/**9.54 - * (Re)initialize the tile accelerator in preparation for the next scene.9.55 - * Normally called immediately before commencing polygon transmission.9.56 - */9.57 -void pvr2_ta_init( void )9.58 -{9.59 - /* Set the buffer indexes */9.60 - MMIO_WRITE( PVR2, TAOBJPOS, MMIO_READ( PVR2, TAOBJBASE ) );9.61 - MMIO_WRITE( PVR2, TAOBJPPOS, MMIO_READ( PVR2, TAOBJPBASE ) );9.62 - pvr2_ta_status.last_poly_type = 0;9.63 - pvr2_ta_status.length = NULL;9.64 -}9.65 -9.66 -/**9.67 - * Write a block of data to the tile accelerator, adding the data to the9.68 - * current scene. We don't make any particular attempt to interpret the data9.69 - * at this stage, deferring that until render time.9.70 - *9.71 - * Currently copies the data verbatim to the vertex buffer, processing only9.72 - * far enough to generate the correct end-of-list events. Tile buffer is9.73 - * entirely ignored.9.74 - */9.75 -void pvr2_ta_write( char *buf, uint32_t length )9.76 -{9.77 - int i;9.78 - struct tacmd *cmd_list = (struct tacmd *)buf;9.79 - uint32_t obj_addr = MMIO_READ( PVR2, TAOBJPOS );9.80 - if( pvr2_ta_status.length == NULL ) { /* Start */9.81 - pvr2_ta_status.length = (uint32_t *)mem_get_region( PVR2_RAM_BASE + obj_addr );9.82 - obj_addr += 4;9.83 - *pvr2_ta_status.length = length;9.84 - } else {9.85 - *pvr2_ta_status.length = *pvr2_ta_status.length + length;9.86 - }9.87 - mem_copy_to_sh4( PVR2_RAM_BASE + obj_addr, buf, length );9.88 - MMIO_WRITE( PVR2, TAOBJPOS, obj_addr + length );9.89 -9.90 - int count = length >> 5;9.91 - for( i=0; i<count; i++ ){9.92 - unsigned int type = (cmd_list[i].command >> 24) & 0xFF;9.93 - if( type == 0xE0 || type == 0xF0 ) {9.94 - struct vertex_type1 *vert = (struct vertex_type1 *)&cmd_list[i];9.95 - // DEBUG( "PVR2 vrt: %f %f %f %08X %08X %08X %f", vert->x, vert->y, vert->z, vert->blank, vert->blank2, vert->col, vert->f );9.96 - } else {9.97 - // DEBUG( "PVR2 cmd: %08X %08X %08X %08X %08X %08X %08X %08X", cmd_list[i].command, cmd_list[i].param1, cmd_list[i].param2, cmd_list[i].texture, cmd_list[i].alpha, cmd_list[i].red, cmd_list[i].green, cmd_list[i].blue );9.98 - }9.99 - if( type == 0 ) {9.100 - /* End of list */9.101 - switch( pvr2_ta_status.last_poly_type ) {9.102 - case 0x80: /* Opaque polys */9.103 - asic_event( EVENT_PVR_OPAQUE_DONE );9.104 - break;9.105 - case 0x81: /* Opaque poly modifier */9.106 - asic_event( EVENT_PVR_OPAQUEMOD_DONE );9.107 - break;9.108 - case 0x82: /* Transparent polys */9.109 - asic_event( EVENT_PVR_TRANS_DONE );9.110 - break;9.111 - case 0x83: /* Transparent poly modifier */9.112 - asic_event( EVENT_PVR_TRANSMOD_DONE );9.113 - break;9.114 - case 0x84: /* Punchthrough */9.115 - asic_event( EVENT_PVR_PUNCHOUT_DONE );9.116 - break;9.117 - }9.118 - pvr2_ta_status.last_poly_type = 0;9.119 - } else if( type >= 0x80 && type <= 0x84 ) {9.120 - pvr2_ta_status.last_poly_type = type;9.121 - }9.122 - }9.123 -}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +000010.2 +++ b/src/pvr2/tacore.c Wed Aug 02 04:06:45 2006 +000010.3 @@ -0,0 +1,975 @@10.4 +/**10.5 + * $Id: tacore.c,v 1.1 2006-08-02 04:06:45 nkeynes Exp $10.6 + *10.7 + * PVR2 Tile Accelerator implementation10.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 "pvr2.h"10.22 +#include "asic.h"10.23 +10.24 +#define STATE_IDLE 010.25 +#define STATE_IN_LIST 110.26 +#define STATE_EXPECT_POLY_BLOCK2 210.27 +#define STATE_EXPECT_VERTEX_BLOCK2 310.28 +#define STATE_ERROR 410.29 +#define STATE_EXPECT_END_VERTEX_BLOCK2 710.30 +10.31 +#define TA_CMD(i) ( (i) >> 29 )10.32 +#define TA_CMD_END_LIST 010.33 +#define TA_CMD_CLIP 110.34 +#define TA_CMD_POLYGON_CONTEXT 410.35 +#define TA_CMD_SPRITE_CONTEXT 510.36 +#define TA_CMD_VERTEX 710.37 +10.38 +#define TA_LIST_NONE -110.39 +#define TA_LIST_OPAQUE 010.40 +#define TA_LIST_OPAQUE_MOD 110.41 +#define TA_LIST_TRANS 210.42 +#define TA_LIST_TRANS_MOD 310.43 +#define TA_LIST_PUNCH_OUT 410.44 +#define TA_IS_MODIFIER_LIST(list) (list == TA_LIST_OPAQUE_MOD || list == TA_LIST_TRANS_MOD)10.45 +10.46 +#define TA_GROW_UP 010.47 +#define TA_GROW_DOWN 110.48 +10.49 +#define TA_VERTEX_NONE -110.50 +#define TA_VERTEX_PACKED 0x0010.51 +#define TA_VERTEX_TEX_PACKED 0x0810.52 +#define TA_VERTEX_TEX_SPEC_PACKED 0x0C10.53 +#define TA_VERTEX_TEX_UV16_PACKED 0x0910.54 +#define TA_VERTEX_TEX_UV16_SPEC_PACKED 0x0D10.55 +#define TA_VERTEX_FLOAT 0x1010.56 +#define TA_VERTEX_TEX_FLOAT 0x1810.57 +#define TA_VERTEX_TEX_SPEC_FLOAT 0x1C10.58 +#define TA_VERTEX_TEX_UV16_FLOAT 0x1910.59 +#define TA_VERTEX_TEX_UV16_SPEC_FLOAT 0x1D10.60 +#define TA_VERTEX_INTENSITY 0x2010.61 +#define TA_VERTEX_TEX_INTENSITY 0x2810.62 +#define TA_VERTEX_TEX_SPEC_INTENSITY 0x2C10.63 +#define TA_VERTEX_TEX_UV16_INTENSITY 0x2910.64 +#define TA_VERTEX_TEX_UV16_SPEC_INTENSITY 0x2D10.65 +#define TA_VERTEX_PACKED_MOD 0x4010.66 +#define TA_VERTEX_TEX_PACKED_MOD 0x4810.67 +#define TA_VERTEX_TEX_SPEC_PACKED_MOD 0x4C10.68 +#define TA_VERTEX_TEX_UV16_PACKED_MOD 0x4910.69 +#define TA_VERTEX_TEX_UV16_SPEC_PACKED_MOD 0x4D10.70 +#define TA_VERTEX_INTENSITY_MOD 0x6010.71 +#define TA_VERTEX_TEX_INTENSITY_MOD 0x6810.72 +#define TA_VERTEX_TEX_SPEC_INTENSITY_MOD 0x6C10.73 +#define TA_VERTEX_TEX_UV16_INTENSITY_MOD 0x6910.74 +#define TA_VERTEX_TEX_UV16_SPEC_INTENSITY_MOD 0x6D10.75 +#define TA_VERTEX_SPRITE 0x8010.76 +#define TA_VERTEX_TEX_SPRITE 0x8810.77 +#define TA_VERTEX_MOD_VOLUME 0x8110.78 +10.79 +#define TA_IS_NORMAL_POLY() (ta_status.current_vertex_type < TA_VERTEX_SPRITE)10.80 +10.81 +static int strip_lengths[4] = {3,4,6,8}; /* in vertexes */10.82 +#define TA_POLYCMD_LISTTYPE(i) ( ((i) >> 24) & 0x0F )10.83 +#define TA_POLYCMD_LENGTH(i) strip_lengths[((i >> 18) & 0x03)]10.84 +#define TA_POLYCMD_CLIP(i) ((i>>16)&0x03)10.85 +#define TA_POLYCMD_COLOURFMT(i) (i & 0x00000030)10.86 +#define TA_POLYCMD_COLOURFMT_ARGB32 0x0000000010.87 +#define TA_POLYCMD_COLOURFMT_FLOAT 0x0000001010.88 +#define TA_POLYCMD_COLOURFMT_INTENSITY 0x0000002010.89 +#define TA_POLYCMD_COLOURFMT_LASTINT 0x0000003010.90 +10.91 +#define TA_POLYCMD_MODIFIED 0x0000008010.92 +#define TA_POLYCMD_FULLMOD 0x0000004010.93 +#define TA_POLYCMD_TEXTURED 0x0000000810.94 +#define TA_POLYCMD_SPECULAR 0x0000000410.95 +#define TA_POLYCMD_SHADED 0x0000000210.96 +#define TA_POLYCMD_UV16 0x0000000110.97 +10.98 +#define TA_POLYCMD_IS_SPECULAR(i) ((i & 0x0000000C)==0x0000000C) /* Only applies to textured polys */10.99 +#define TA_POLYCMD_IS_FULLMOD(i) ((i & 0x000000C0)==0x000000C0)10.100 +10.101 +10.102 +#define TA_IS_END_VERTEX(i) (i & 0x10000000)10.103 +10.104 +#define MIN3( x1, x2, x3 ) ( (x1)<(x2)? ((x1)<(x3)?(x1):(x3)) : ((x2)<(x3)?(x2):(x3)) )10.105 +#define MAX3( x1, x2, x3 ) ( (x1)>(x2)? ((x1)>(x3)?(x1):(x3)) : ((x2)>(x3)?(x2):(x3)) )10.106 +10.107 +#define TILESLOT( x, y ) (ta_status.current_tile_matrix + (ta_status.current_tile_size * (y * ta_status.width+ x) << 2))10.108 +10.109 +extern char *video_base;10.110 +#define PVRRAM(addr) (*(uint32_t *)(video_base + ((addr)&PVR2_RAM_MASK)))10.111 +10.112 +struct pvr2_ta_vertex {10.113 + float x,y,z;10.114 + uint32_t detail[8]; /* 0-8 detail words */10.115 +};10.116 +10.117 +struct tile_bounds {10.118 + int x1, y1, x2, y2;10.119 +};10.120 +10.121 +struct pvr2_ta_status {10.122 + int state;10.123 + int width, height; /* Tile resolution, ie 20x15 */10.124 + int tilelist_dir; /* Growth direction of the tilelist, 0 = up, 1 = down */10.125 + uint32_t tilelist_size; /* Size of the tilelist segments */10.126 + int current_vertex_type;10.127 + int vertex_count; /* index of last start-vertex seen, or -1 if no vertexes10.128 + * are present10.129 + */10.130 + int max_vertex; /* Maximum number of vertexes in the current polygon (3/4/6/8) */10.131 + int current_list_type;10.132 + uint32_t current_tile_matrix; /* Memory location of the first tile for the current list. */10.133 + uint32_t current_tile_size; /* Size of the tile matrix space in 32-bit words (0/8/16/32)*/10.134 + uint32_t intensity1, intensity2;10.135 + /**10.136 + * Current working object10.137 + */10.138 + int poly_context_size;10.139 + int poly_vertex_size;10.140 + int poly_parity;10.141 + uint32_t poly_context[5];10.142 + uint32_t poly_pointer;10.143 + struct tile_bounds last_triangle_bounds;10.144 + struct pvr2_ta_vertex poly_vertex[8];10.145 + int debug_output;10.146 +};10.147 +10.148 +static struct pvr2_ta_status ta_status;10.149 +10.150 +static int tilematrix_sizes[4] = {0,8,16,32};10.151 +10.152 +/**10.153 + * Convenience union - ta data is either 32-bit integer or 32-bit float.10.154 + */10.155 +union ta_data {10.156 + unsigned int i;10.157 + float f;10.158 +};10.159 +10.160 +10.161 +void pvr2_ta_reset() {10.162 + ta_status.state = STATE_ERROR; /* State not valid until initialized */10.163 + ta_status.debug_output = 0;10.164 +}10.165 +10.166 +void pvr2_ta_init() {10.167 + ta_status.state = STATE_IDLE;10.168 + ta_status.current_list_type = -1;10.169 + ta_status.current_vertex_type = -1;10.170 + ta_status.poly_parity = 0;10.171 + ta_status.vertex_count = 0;10.172 + ta_status.max_vertex = 3;10.173 + ta_status.last_triangle_bounds.x1 = -1;10.174 +10.175 + uint32_t size = MMIO_READ( PVR2, TA_TILESIZE );10.176 + ta_status.width = (size & 0xFFFF) + 1;10.177 + ta_status.height = (size >> 16) + 1;10.178 + uint32_t control = MMIO_READ( PVR2, TA_TILECFG );10.179 + ta_status.tilelist_dir = (control >> 20) & 0x01;10.180 + ta_status.tilelist_size = tilematrix_sizes[ (control & 0x03) ];10.181 + MMIO_WRITE( PVR2, TA_POLYPOS, MMIO_READ( PVR2, TA_POLYBASE ) );10.182 + uint32_t plistpos = MMIO_READ( PVR2, TA_LISTBASE ) >> 2;10.183 + if( ta_status.tilelist_dir == TA_GROW_DOWN ) {10.184 + plistpos -= ta_status.tilelist_size;10.185 + }10.186 + MMIO_WRITE( PVR2, TA_LISTPOS, plistpos );10.187 +}10.188 +10.189 +static uint32_t parse_float_colour( float a, float r, float g, float b ) {10.190 + return10.191 + (((unsigned int)((256 * CLAMP(a,0.0,1.0))-1))<<24) |10.192 + (((unsigned int)((256 * CLAMP(r,0.0,1.0))-1))<<16) |10.193 + (((unsigned int)((256 * CLAMP(g,0.0,1.0))-1))<<8) |10.194 + (((unsigned int)((256 * CLAMP(b,0.0,1.0))-1)));10.195 +}10.196 +10.197 +static uint32_t parse_intensity_colour( uint32_t base, float intensity )10.198 +{10.199 + unsigned int i = (unsigned int)(256 * CLAMP(intensity, 0.0,1.0));10.200 +10.201 + return10.202 + (((((base & 0xFF) * i) & 0xFF00) |10.203 + (((base & 0xFF00) * i) & 0xFF0000) |10.204 + (((base & 0xFF0000) * i) & 0xFF000000)) >> 8) |10.205 + base & 0xFF000000;10.206 +}10.207 +10.208 +/**10.209 + * Initialize the specified TA list.10.210 + */10.211 +static void ta_init_list( unsigned int listtype ) {10.212 + int config = MMIO_READ( PVR2, TA_TILECFG );10.213 + int tile_matrix = MMIO_READ( PVR2, TA_TILEBASE );10.214 + if( listtype <= TA_LIST_PUNCH_OUT ) {10.215 + int i;10.216 + uint32_t *p;10.217 + for( i=0; i < listtype; i++ ) {10.218 + int size = tilematrix_sizes[(config & 0x03)] << 2;10.219 + tile_matrix += ta_status.width * ta_status.height * size;10.220 + config >>= 4;10.221 + }10.222 + ta_status.current_tile_matrix = tile_matrix;10.223 + ta_status.current_tile_size = tilematrix_sizes[(config & 0x03)];10.224 +10.225 + /* Initialize each tile to 0xF0000000 */10.226 + if( ta_status.current_tile_size != 0 ) {10.227 + p = (uint32_t *)(video_base + tile_matrix);10.228 + for( i=0; i< ta_status.width * ta_status.height; i++ ) {10.229 + *p = 0xF0000000;10.230 + p += ta_status.current_tile_size;10.231 + }10.232 + }10.233 + }10.234 + ta_status.state = STATE_IN_LIST;10.235 + ta_status.current_list_type = listtype;10.236 + ta_status.last_triangle_bounds.x1 = -1;10.237 +}10.238 +10.239 +static int list_events[5] = {EVENT_PVR_OPAQUE_DONE, EVENT_PVR_OPAQUEMOD_DONE,10.240 + EVENT_PVR_TRANS_DONE, EVENT_PVR_TRANSMOD_DONE,10.241 + EVENT_PVR_PUNCHOUT_DONE };10.242 +10.243 +static void ta_end_list() {10.244 + if( ta_status.current_list_type != TA_LIST_NONE ) {10.245 + asic_event( list_events[ta_status.current_list_type] );10.246 + ta_status.current_list_type = TA_LIST_NONE;10.247 + ta_status.current_vertex_type = -1;10.248 + ta_status.state = STATE_IDLE;10.249 + }10.250 +}10.251 +10.252 +/**10.253 + * Write data out to the polygon buffer.10.254 + * If the end-of-buffer is reached, asserts EVENT_PVR_PRIM_ALLOC_FAIL10.255 + * @param data to be written10.256 + * @param length Number of 32-bit words to write.10.257 + * @return number of words actually written10.258 + */10.259 +static int ta_write_polygon_buffer( uint32_t *data, int length )10.260 +{10.261 + int rv;10.262 + int posn = MMIO_READ( PVR2, TA_POLYPOS );10.263 + int end = MMIO_READ( PVR2, TA_POLYEND );10.264 + uint32_t *target = (uint32_t *)(video_base + posn);10.265 + for( rv=0; rv < length; rv++ ) {10.266 + if( posn == end ) {10.267 + asic_event( EVENT_PVR_PRIM_ALLOC_FAIL );10.268 + asic_event( EVENT_TA_ERROR );10.269 + // ta_status.state = STATE_ERROR;10.270 + break;10.271 + }10.272 + *target++ = *data++;10.273 + posn += 4;10.274 + }10.275 +10.276 + MMIO_WRITE( PVR2, TA_POLYPOS, posn );10.277 + return rv;10.278 +}10.279 +10.280 +/**10.281 + * Allocate a new tile list from the grow space10.282 + */10.283 +static uint32_t ta_alloc_tilelist() {10.284 + uint32_t posn = MMIO_READ( PVR2, TA_LISTPOS );10.285 + uint32_t newposn;10.286 + if( ta_status.tilelist_dir == TA_GROW_DOWN ) {10.287 + newposn = posn - ta_status.tilelist_size;10.288 + } else {10.289 + newposn = posn + ta_status.tilelist_size;10.290 + }10.291 + MMIO_WRITE( PVR2, TA_LISTPOS, newposn );10.292 + return posn << 2;10.293 +}10.294 +10.295 +/**10.296 + * Write a tile entry out to the matrix.10.297 + */10.298 +static int ta_write_tile_entry( int x, int y, uint32_t tile_entry ) {10.299 + uint32_t tile = TILESLOT(x,y);10.300 + uint32_t value;10.301 + uint32_t lasttri = 0;10.302 + int i,l;10.303 +10.304 + if( (tile_entry & 0x80000000) &&10.305 + ta_status.last_triangle_bounds.x1 != -1 &&10.306 + ta_status.last_triangle_bounds.x1 <= x &&10.307 + ta_status.last_triangle_bounds.x2 >= x &&10.308 + ta_status.last_triangle_bounds.y1 <= y &&10.309 + ta_status.last_triangle_bounds.y2 >= y ) {10.310 + /* potential for triangle stacking */10.311 + lasttri = tile_entry & 0xE1E00000;10.312 + }10.313 +10.314 +10.315 + if( PVRRAM(tile) == 0xF0000000 ) {10.316 + PVRRAM(tile) = tile_entry;10.317 + PVRRAM(tile+4) = 0xF0000000;10.318 + return;10.319 + }10.320 +10.321 + while(1) {10.322 + value = PVRRAM(tile);10.323 + for( i=1; i<ta_status.current_tile_size; i++ ) {10.324 + tile += 4;10.325 + uint32_t nextval = PVRRAM(tile);10.326 + if( nextval == 0xF0000000 ) {10.327 + if( lasttri != 0 && lasttri == (value&0xE1E00000) ) {10.328 + int count = (value & 0x1E000000) + 0x02000000;10.329 + if( count < 0x20000000 ) {10.330 + PVRRAM(tile-4) = (value & 0xE1FFFFFF) | count;10.331 + return;10.332 + }10.333 + }10.334 + if( i < ta_status.current_tile_size-1 ) {10.335 + PVRRAM(tile) = tile_entry;10.336 + PVRRAM(tile+4) = 0xF0000000;10.337 + return;10.338 + }10.339 + }10.340 + value = nextval;10.341 + }10.342 +10.343 + if( value == 0xF0000000 ) {10.344 + value = ta_alloc_tilelist();10.345 + PVRRAM(tile) = value | 0xE0000000;10.346 + tile = value;10.347 + PVRRAM(tile) = tile_entry;10.348 + PVRRAM(tile+4) = 0xF0000000;10.349 + return;10.350 + } else if( (value & 0xFF000000) == 0xE0000000 ) {10.351 + tile = (value & 0x00FFFFFF);10.352 + } else {10.353 + /* This should never happen */10.354 + return 0;10.355 + }10.356 + }10.357 +}10.358 +10.359 +/**10.360 + * Write a completed polygon out to the memory buffers10.361 + * OPTIMIZEME: This is not terribly efficient at the moment.10.362 + */10.363 +static void ta_commit_polygon( ) {10.364 + int i, x, y;10.365 + int tx[ta_status.vertex_count], ty[ta_status.vertex_count];10.366 + struct tile_bounds triangle_bound[ta_status.vertex_count - 2];10.367 + struct tile_bounds polygon_bound;10.368 + uint32_t poly_context[5];10.369 +10.370 + if( ta_status.vertex_count < 2 ) {10.371 + return; /* No polygons - ignore */10.372 + }10.373 + memcpy( poly_context, ta_status.poly_context, ta_status.poly_context_size * 4 );10.374 +10.375 + /* Compute the tile coordinates for each vertex (need to be careful with10.376 + * clamping here)10.377 + */10.378 + for( i=0; i<ta_status.vertex_count; i++ ) {10.379 + if( ta_status.poly_vertex[i].x < 0.0 ) {10.380 + tx[i] = -1;10.381 + } else if( ta_status.poly_vertex[i].x > (float)INT_MAX ) {10.382 + tx[i] = INT_MAX/32;10.383 + } else {10.384 + tx[i] = (int)(ta_status.poly_vertex[i].x / 32.0);10.385 + }10.386 + if( ta_status.poly_vertex[i].y < 0.0 ) {10.387 + ty[i] = -1;10.388 + } else if( ta_status.poly_vertex[i].y > (float)INT_MAX ) {10.389 + ty[i] = INT_MAX/32;10.390 + } else {10.391 + ty[i] = (int)(ta_status.poly_vertex[i].y / 32.0);10.392 + }10.393 +10.394 + }10.395 +10.396 + /* Compute bounding box for each triangle individually, as well10.397 + * as the overall polygon.10.398 + */10.399 +10.400 + for( i=0; i<ta_status.vertex_count-2; i++ ) {10.401 + triangle_bound[i].x1 = MIN3(tx[i],tx[i+1],tx[i+2]);10.402 + triangle_bound[i].x2 = MAX3(tx[i],tx[i+1],tx[i+2]);10.403 + triangle_bound[i].y1 = MIN3(ty[i],ty[i+1],ty[i+2]);10.404 + triangle_bound[i].y2 = MAX3(ty[i],ty[i+1],ty[i+2]);10.405 + if( i == 0 ) {10.406 + polygon_bound.x1 = triangle_bound[0].x1;10.407 + polygon_bound.y1 = triangle_bound[0].y1;10.408 + polygon_bound.x2 = triangle_bound[0].x2;10.409 + polygon_bound.y2 = triangle_bound[0].y2;10.410 + } else {10.411 + polygon_bound.x1 = MIN(polygon_bound.x1, triangle_bound[i].x1);10.412 + polygon_bound.x2 = MAX(polygon_bound.x2, triangle_bound[i].x2);10.413 + polygon_bound.y1 = MIN(polygon_bound.y1, triangle_bound[i].y1);10.414 + polygon_bound.y2 = MAX(polygon_bound.y2, triangle_bound[i].y2);10.415 + }10.416 + }10.417 +10.418 + /* If the polygon is actually entirely out of the frustum, clip it entirely */10.419 + if( polygon_bound.x2 < 0 || polygon_bound.x1 > ta_status.width ||10.420 + polygon_bound.y2 < 0 || polygon_bound.y1 > ta_status.height ) {10.421 + return;10.422 + }10.423 +10.424 + /* Clamp the polygon bounds to the frustum */10.425 + if( polygon_bound.x1 < 0 ) polygon_bound.x1 = 0;10.426 + if( polygon_bound.x2 >= ta_status.width ) polygon_bound.x2 = ta_status.width-1;10.427 + if( polygon_bound.y1 < 0 ) polygon_bound.y1 = 0;10.428 + if( polygon_bound.y2 >= ta_status.width ) polygon_bound.y2 = ta_status.height-1;10.429 +10.430 + /* Set the "single tile" flag if it's entirely contained in 1 tile */10.431 + if( polygon_bound.x1 == polygon_bound.x2 &&10.432 + polygon_bound.y1 == polygon_bound.y2 ) {10.433 + poly_context[0] |= 0x00200000;10.434 + }10.435 +10.436 + /* Ok, we're good to go - write out the polygon first */10.437 + uint32_t tile_entry = MMIO_READ( PVR2, TA_POLYPOS ) >> 2 | ta_status.poly_pointer;10.438 +10.439 + int status = ta_write_polygon_buffer( poly_context, ta_status.poly_context_size );10.440 + if( status == 0 ) {10.441 + /* No memory available - abort */10.442 + return;10.443 + } else {10.444 + for( i=0; i<ta_status.vertex_count && status != 0; i++ ) {10.445 + status = ta_write_polygon_buffer( (uint32_t *)(&ta_status.poly_vertex[i]), 3 + ta_status.poly_vertex_size );10.446 + }10.447 + }10.448 +10.449 + /* And now the tile entries. Triangles are different from everything else */10.450 + if( ta_status.vertex_count == 3 ) {10.451 + tile_entry |= 0x80000000;10.452 + for( y=polygon_bound.y1; y<=polygon_bound.y2; y++ ) {10.453 + for( x=polygon_bound.x1; x<=polygon_bound.x2; x++ ) {10.454 + ta_write_tile_entry( x,y,tile_entry );10.455 + }10.456 + }10.457 + ta_status.last_triangle_bounds.x1 = polygon_bound.x1;10.458 + ta_status.last_triangle_bounds.y1 = polygon_bound.y1;10.459 + ta_status.last_triangle_bounds.x2 = polygon_bound.x2;10.460 + ta_status.last_triangle_bounds.y2 = polygon_bound.y2;10.461 + } else if( ta_status.current_vertex_type == TA_VERTEX_SPRITE ||10.462 + ta_status.current_vertex_type == TA_VERTEX_TEX_SPRITE ) {10.463 + tile_entry |= 0xA0000000;10.464 + for( y=polygon_bound.y1; y<=polygon_bound.y2; y++ ) {10.465 + for( x=polygon_bound.x1; x<=polygon_bound.x2; x++ ) {10.466 + ta_write_tile_entry( x,y,tile_entry );10.467 + }10.468 + }10.469 + ta_status.last_triangle_bounds.x1 = polygon_bound.x1;10.470 + ta_status.last_triangle_bounds.y1 = polygon_bound.y1;10.471 + ta_status.last_triangle_bounds.x2 = polygon_bound.x2;10.472 + ta_status.last_triangle_bounds.y2 = polygon_bound.y2;10.473 + } else {10.474 + for( y=polygon_bound.y1; y<=polygon_bound.y2; y++ ) {10.475 + for( x=polygon_bound.x1; x<=polygon_bound.x2; x++ ) {10.476 + uint32_t entry = tile_entry;10.477 + for( i=0; i<ta_status.vertex_count-2; i++ ) {10.478 + if( triangle_bound[i].x1 <= x && triangle_bound[i].x2 >= x &&10.479 + triangle_bound[i].y1 <= y && triangle_bound[i].y2 >= y ) {10.480 + entry |= (0x40000000>>i);10.481 + }10.482 + }10.483 + ta_write_tile_entry( x, y, entry );10.484 + }10.485 + }10.486 + ta_status.last_triangle_bounds.x1 = -1;10.487 + }10.488 +}10.489 +10.490 +/**10.491 + * Variant of ta_split_polygon called when vertex_count == max_vertex, but10.492 + * the client hasn't sent the LAST VERTEX flag. Commit the poly as normal10.493 + * first, then start a new poly with the first 2 vertexes taken from the10.494 + * current one.10.495 + */10.496 +static void ta_split_polygon() {10.497 + ta_commit_polygon();10.498 + if( TA_IS_NORMAL_POLY() ) {10.499 + /* This only applies to ordinary polys - Sprites + modifier lists are10.500 + * handled differently10.501 + */10.502 + if( ta_status.vertex_count == 3 ) {10.503 + /* Triangles use an odd/even scheme */10.504 + if( ta_status.poly_parity == 0 ) {10.505 + memcpy( &ta_status.poly_vertex[0], &ta_status.poly_vertex[2],10.506 + sizeof(struct pvr2_ta_vertex) );10.507 + ta_status.poly_parity = 1;10.508 + } else {10.509 + memcpy( &ta_status.poly_vertex[1], &ta_status.poly_vertex[2],10.510 + sizeof(struct pvr2_ta_vertex) );10.511 + ta_status.poly_parity = 0;10.512 + }10.513 + } else {10.514 + /* Everything else just uses the last 2 vertexes in order */10.515 + memcpy( &ta_status.poly_vertex[0], &ta_status.poly_vertex[ta_status.vertex_count-2],10.516 + sizeof(struct pvr2_ta_vertex)*2 );10.517 + ta_status.poly_parity = 0;10.518 + }10.519 + ta_status.vertex_count = 2;10.520 + } else {10.521 + ta_status.vertex_count = 0;10.522 + }10.523 +}10.524 +10.525 +/**10.526 + * Parse the polygon context block and setup the internal state to receive10.527 + * vertexes.10.528 + * @param data 32 bytes of parameter data.10.529 + */10.530 +static void ta_parse_polygon_context( union ta_data *data ) {10.531 + int colourfmt = TA_POLYCMD_COLOURFMT(data[0].i);10.532 + ta_status.max_vertex = TA_POLYCMD_LENGTH(data[0].i);10.533 + ta_status.vertex_count = 0;10.534 + ta_status.poly_context[0] =10.535 + (data[1].i & 0xFC1FFFFF) | ((data[0].i & 0x0B) << 22);10.536 + ta_status.poly_context[1] = data[2].i;10.537 + ta_status.poly_context[3] = data[4].i;10.538 + ta_status.poly_parity = 0;10.539 + if( data[0].i & TA_POLYCMD_TEXTURED ) {10.540 + ta_status.current_vertex_type = data[0].i & 0x0D;10.541 + ta_status.poly_context[2] = data[3].i;10.542 + ta_status.poly_context[4] = data[5].i;10.543 + if( data[0].i & TA_POLYCMD_SPECULAR ) {10.544 + ta_status.poly_context[0] |= 0x01000000;10.545 + ta_status.poly_vertex_size = 4;10.546 + } else {10.547 + ta_status.poly_vertex_size = 3;10.548 + }10.549 + if( data[0].i & TA_POLYCMD_UV16 ) {10.550 + ta_status.poly_vertex_size--;10.551 + }10.552 + } else {10.553 + ta_status.current_vertex_type = 0;10.554 + ta_status.poly_vertex_size = 1;10.555 + ta_status.poly_context[2] = 0;10.556 + ta_status.poly_context[4] = 0;10.557 + }10.558 +10.559 + ta_status.poly_pointer = (ta_status.poly_vertex_size << 21);10.560 + ta_status.poly_context_size = 3;10.561 + if( data[0].i & TA_POLYCMD_MODIFIED ) {10.562 + ta_status.poly_pointer |= 0x01000000;10.563 + if( data[0].i & TA_POLYCMD_FULLMOD ) {10.564 + ta_status.poly_context_size = 5;10.565 + ta_status.poly_vertex_size <<= 1;10.566 + ta_status.current_vertex_type |= 0x40;10.567 + /* Modified/float not supported - behaves as per last intensity */10.568 + if( colourfmt == TA_POLYCMD_COLOURFMT_FLOAT ) {10.569 + colourfmt = TA_POLYCMD_COLOURFMT_LASTINT;10.570 + }10.571 + }10.572 + }10.573 +10.574 + if( colourfmt == TA_POLYCMD_COLOURFMT_INTENSITY ) {10.575 + if( TA_POLYCMD_IS_FULLMOD(data[0].i) ||10.576 + TA_POLYCMD_IS_SPECULAR(data[0].i) ) {10.577 + ta_status.state = STATE_EXPECT_POLY_BLOCK2;10.578 + } else {10.579 + ta_status.intensity1 =10.580 + parse_float_colour( data[4].f, data[5].f, data[6].f, data[7].f );10.581 + }10.582 + } else if( colourfmt == TA_POLYCMD_COLOURFMT_LASTINT ) {10.583 + colourfmt = TA_POLYCMD_COLOURFMT_INTENSITY;10.584 + }10.585 +10.586 + ta_status.current_vertex_type |= colourfmt;10.587 +}10.588 +10.589 +/**10.590 + * Parse the modifier volume context block and setup the internal state to10.591 + * receive modifier vertexes.10.592 + * @param data 32 bytes of parameter data.10.593 + */10.594 +static void ta_parse_modifier_context( union ta_data *data ) {10.595 + ta_status.current_vertex_type = TA_VERTEX_MOD_VOLUME;10.596 + ta_status.poly_vertex_size = 0;10.597 + ta_status.poly_context_size = 3;10.598 + ta_status.poly_context[0] = (data[1].i & 0xFC1FFFFF) |10.599 + ((data[0].i & 0x0B)<<22);10.600 + if( TA_POLYCMD_IS_SPECULAR(data[0].i) ) {10.601 + ta_status.poly_context[0] |= 0x01000000;10.602 + }10.603 + ta_status.poly_context[1] = 0;10.604 + ta_status.poly_context[2] = 0;10.605 + ta_status.vertex_count = 0;10.606 + ta_status.max_vertex = 3;10.607 + ta_status.poly_pointer = 0;10.608 +}10.609 +10.610 +/**10.611 + * Parse the sprite context block and setup the internal state to receive10.612 + * vertexes.10.613 + * @param data 32 bytes of parameter data.10.614 + */10.615 +static void ta_parse_sprite_context( union ta_data *data ) {10.616 + ta_status.poly_context_size = 3;10.617 + ta_status.poly_context[0] = (data[1].i & 0xFC1FFFFF) |10.618 + ((data[0].i & 0x0B)<<22) | 0x00400000;10.619 + if( TA_POLYCMD_IS_SPECULAR(data[0].i) ) {10.620 + ta_status.poly_context[0] |= 0x01000000;10.621 + }10.622 + ta_status.poly_context[1] = data[2].i;10.623 + ta_status.poly_context[2] = data[3].i;10.624 + if( data[0].i & TA_POLYCMD_TEXTURED ) {10.625 + ta_status.poly_vertex_size = 2;10.626 + ta_status.poly_vertex[2].detail[1] = data[4].i;10.627 + ta_status.current_vertex_type = TA_VERTEX_TEX_SPRITE;10.628 + } else {10.629 + ta_status.poly_vertex_size = 1;10.630 + ta_status.poly_vertex[2].detail[0] = data[4].i;10.631 + ta_status.current_vertex_type = TA_VERTEX_SPRITE;10.632 + }10.633 + ta_status.vertex_count = 0;10.634 + ta_status.max_vertex = 4;10.635 + ta_status.poly_pointer = (ta_status.poly_vertex_size << 21);10.636 +}10.637 +10.638 +/**10.639 + * Copy the last read vertex into all vertexes up to max_vertex. Used for10.640 + * Aborted polygons under some circumstances.10.641 + */10.642 +static void ta_fill_vertexes( ) {10.643 + int i;10.644 + for( i=ta_status.vertex_count; i<ta_status.max_vertex; i++ ) {10.645 + memcpy( &ta_status.poly_vertex[i], &ta_status.poly_vertex[ta_status.vertex_count-1],10.646 + sizeof( struct pvr2_ta_vertex ) );10.647 + }10.648 + ta_status.vertex_count = ta_status.max_vertex;10.649 +}10.650 +10.651 +static void ta_parse_vertex( union ta_data *data ) {10.652 + struct pvr2_ta_vertex *vertex = &ta_status.poly_vertex[ta_status.vertex_count];10.653 + vertex->x = data[1].f;10.654 + vertex->y = data[2].f;10.655 + vertex->z = data[3].f;10.656 +10.657 + switch( ta_status.current_vertex_type ) {10.658 + case TA_VERTEX_PACKED:10.659 + vertex->detail[0] = data[6].i;10.660 + break;10.661 + case TA_VERTEX_FLOAT:10.662 + vertex->detail[0] = parse_float_colour( data[4].f, data[5].f, data[6].f, data[7].f );10.663 + break;10.664 + case TA_VERTEX_INTENSITY:10.665 + vertex->detail[0] = parse_intensity_colour( ta_status.intensity1, data[6].f );10.666 + break;10.667 +10.668 + case TA_VERTEX_TEX_SPEC_PACKED:10.669 + vertex->detail[3] = data[7].i; /* ARGB */10.670 + /* Fallthrough */10.671 + case TA_VERTEX_TEX_PACKED:10.672 + vertex->detail[0] = data[4].i; /* U */10.673 + vertex->detail[1] = data[5].i; /* V */10.674 + vertex->detail[2] = data[6].i; /* ARGB */10.675 + break;10.676 + case TA_VERTEX_TEX_UV16_SPEC_PACKED:10.677 + vertex->detail[2] = data[7].i; /* ARGB */10.678 + /* Fallthrough */10.679 + case TA_VERTEX_TEX_UV16_PACKED:10.680 + vertex->detail[0] = data[4].i; /* UV */10.681 + vertex->detail[1] = data[6].i; /* ARGB */10.682 + break;10.683 +10.684 + case TA_VERTEX_TEX_FLOAT:10.685 + case TA_VERTEX_TEX_SPEC_FLOAT:10.686 + vertex->detail[0] = data[4].i; /* U */10.687 + vertex->detail[1] = data[5].i; /* UV */10.688 + ta_status.state = STATE_EXPECT_VERTEX_BLOCK2;10.689 + break;10.690 + case TA_VERTEX_TEX_UV16_FLOAT:10.691 + case TA_VERTEX_TEX_UV16_SPEC_FLOAT:10.692 + vertex->detail[0] = data[4].i; /* UV */10.693 + ta_status.state = STATE_EXPECT_VERTEX_BLOCK2;10.694 + break;10.695 +10.696 + case TA_VERTEX_TEX_SPEC_INTENSITY:10.697 + vertex->detail[3] = parse_intensity_colour( ta_status.intensity2, data[7].f );10.698 + /* Fallthrough */10.699 + case TA_VERTEX_TEX_INTENSITY:10.700 + vertex->detail[0] = data[4].i; /* U */10.701 + vertex->detail[1] = data[5].i; /* V */10.702 + vertex->detail[2] = parse_intensity_colour( ta_status.intensity1, data[6].f );10.703 + break;10.704 + case TA_VERTEX_TEX_UV16_SPEC_INTENSITY:10.705 + vertex->detail[2] = parse_intensity_colour( ta_status.intensity2, data[7].f );10.706 + /* Fallthrough */10.707 + case TA_VERTEX_TEX_UV16_INTENSITY:10.708 + vertex->detail[0] = data[4].i; /* UV */10.709 + vertex->detail[1] = parse_intensity_colour( ta_status.intensity1, data[6].f );10.710 + break;10.711 +10.712 + case TA_VERTEX_PACKED_MOD:10.713 + vertex->detail[0] = data[4].i; /* ARGB */10.714 + vertex->detail[1] = data[5].i; /* ARGB */10.715 + break;10.716 + case TA_VERTEX_INTENSITY_MOD:10.717 + vertex->detail[0] = parse_intensity_colour( ta_status.intensity1, data[4].f );10.718 + vertex->detail[1] = parse_intensity_colour( ta_status.intensity2, data[5].f );10.719 + break;10.720 +10.721 + case TA_VERTEX_TEX_SPEC_PACKED_MOD:10.722 + vertex->detail[3] = data[7].i; /* ARGB0 */10.723 + /* Fallthrough */10.724 + case TA_VERTEX_TEX_PACKED_MOD:10.725 + vertex->detail[0] = data[4].i; /* U0 */10.726 + vertex->detail[1] = data[5].i; /* V0 */10.727 + vertex->detail[2] = data[6].i; /* ARGB0 */10.728 + ta_status.state = STATE_EXPECT_VERTEX_BLOCK2;10.729 + break;10.730 + case TA_VERTEX_TEX_UV16_SPEC_PACKED_MOD:10.731 + vertex->detail[2] = data[7].i; /* ARGB0 */10.732 + /* Fallthrough */10.733 + case TA_VERTEX_TEX_UV16_PACKED_MOD:10.734 + vertex->detail[0] = data[4].i; /* UV0 */10.735 + vertex->detail[1] = data[6].i; /* ARGB0 */10.736 + ta_status.state = STATE_EXPECT_VERTEX_BLOCK2;10.737 + break;10.738 +10.739 + case TA_VERTEX_TEX_SPEC_INTENSITY_MOD:10.740 + vertex->detail[3] = parse_intensity_colour( ta_status.intensity1, data[7].f );10.741 + /* Fallthrough */10.742 + case TA_VERTEX_TEX_INTENSITY_MOD:10.743 + vertex->detail[0] = data[4].i; /* U0 */10.744 + vertex->detail[1] = data[5].i; /* V0 */10.745 + vertex->detail[2] = parse_intensity_colour( ta_status.intensity1, data[6].f );10.746 + ta_status.state = STATE_EXPECT_VERTEX_BLOCK2;10.747 + break;10.748 + case TA_VERTEX_TEX_UV16_SPEC_INTENSITY_MOD:10.749 + vertex->detail[2] = parse_intensity_colour( ta_status.intensity1, data[7].f );10.750 + /* Fallthrough */10.751 + case TA_VERTEX_TEX_UV16_INTENSITY_MOD:10.752 + vertex->detail[0] = data[4].i; /* UV0 */10.753 + vertex->detail[1] = parse_intensity_colour( ta_status.intensity1, data[6].f );10.754 + ta_status.state = STATE_EXPECT_VERTEX_BLOCK2;10.755 + break;10.756 +10.757 + case TA_VERTEX_SPRITE:10.758 + case TA_VERTEX_TEX_SPRITE:10.759 + case TA_VERTEX_MOD_VOLUME:10.760 + vertex++;10.761 + vertex->x = data[4].f;10.762 + vertex->y = data[5].f;10.763 + vertex->z = data[6].f;10.764 + vertex++;10.765 + vertex->x = data[7].f;10.766 + ta_status.vertex_count += 2;10.767 + ta_status.state = STATE_EXPECT_VERTEX_BLOCK2;10.768 + break;10.769 + }10.770 + ta_status.vertex_count++;10.771 +}10.772 +10.773 +static void ta_parse_vertex_block2( union ta_data *data ) {10.774 + struct pvr2_ta_vertex *vertex = &ta_status.poly_vertex[ta_status.vertex_count-1];10.775 +10.776 + switch( ta_status.current_vertex_type ) {10.777 + case TA_VERTEX_TEX_SPEC_FLOAT:10.778 + vertex->detail[3] = parse_float_colour( data[4].f, data[5].f, data[6].f, data[7].f );10.779 + /* Fallthrough */10.780 + case TA_VERTEX_TEX_FLOAT:10.781 + vertex->detail[2] = parse_float_colour( data[0].f, data[1].f, data[2].f, data[3].f );10.782 + break;10.783 + case TA_VERTEX_TEX_UV16_SPEC_FLOAT:10.784 + vertex->detail[2] = parse_float_colour( data[4].f, data[5].f, data[6].f, data[7].f );10.785 + /* Fallthrough */10.786 + case TA_VERTEX_TEX_UV16_FLOAT:10.787 + vertex->detail[1] = parse_float_colour( data[0].f, data[1].f, data[2].f, data[3].f );10.788 + break;10.789 + case TA_VERTEX_TEX_PACKED_MOD:10.790 + vertex->detail[3] = data[0].i; /* U1 */10.791 + vertex->detail[4] = data[1].i; /* V1 */10.792 + vertex->detail[5] = data[2].i; /* ARGB1 */10.793 + break;10.794 + case TA_VERTEX_TEX_SPEC_PACKED_MOD:10.795 + vertex->detail[4] = data[0].i; /* U1 */10.796 + vertex->detail[5] = data[1].i; /* V1 */10.797 + vertex->detail[6] = data[2].i; /* ARGB1 */10.798 + vertex->detail[7] = data[3].i; /* ARGB1 */10.799 + break;10.800 + case TA_VERTEX_TEX_UV16_PACKED_MOD:10.801 + vertex->detail[2] = data[0].i; /* UV1 */10.802 + vertex->detail[3] = data[2].i; /* ARGB1 */10.803 + break;10.804 + case TA_VERTEX_TEX_UV16_SPEC_PACKED_MOD:10.805 + vertex->detail[3] = data[0].i; /* UV1 */10.806 + vertex->detail[4] = data[2].i; /* ARGB1 */10.807 + vertex->detail[5] = data[3].i; /* ARGB1 */10.808 + break;10.809 +10.810 + case TA_VERTEX_TEX_INTENSITY_MOD:10.811 + vertex->detail[3] = data[0].i; /* U1 */10.812 + vertex->detail[4] = data[1].i; /* V1 */10.813 + vertex->detail[5] = parse_intensity_colour( ta_status.intensity2, data[2].f ); /* ARGB1 */10.814 + break;10.815 + case TA_VERTEX_TEX_SPEC_INTENSITY_MOD:10.816 + vertex->detail[4] = data[0].i; /* U1 */10.817 + vertex->detail[5] = data[1].i; /* V1 */10.818 + vertex->detail[6] = parse_intensity_colour( ta_status.intensity2, data[2].f ); /* ARGB1 */10.819 + vertex->detail[7] = parse_intensity_colour( ta_status.intensity2, data[3].f ); /* ARGB1 */10.820 + break;10.821 + case TA_VERTEX_TEX_UV16_INTENSITY_MOD:10.822 + vertex->detail[2] = data[0].i; /* UV1 */10.823 + vertex->detail[3] = parse_intensity_colour( ta_status.intensity2, data[2].f ); /* ARGB1 */10.824 + break;10.825 + case TA_VERTEX_TEX_UV16_SPEC_INTENSITY_MOD:10.826 + vertex->detail[3] = data[0].i; /* UV1 */10.827 + vertex->detail[4] = parse_intensity_colour( ta_status.intensity2, data[2].f ); /* ARGB1 */10.828 + vertex->detail[5] = parse_intensity_colour( ta_status.intensity2, data[3].f ); /* ARGB1 */10.829 + break;10.830 +10.831 + case TA_VERTEX_SPRITE:10.832 + vertex->y = data[0].f;10.833 + vertex->z = data[1].f;10.834 + vertex++;10.835 + ta_status.vertex_count++;10.836 + vertex->x = data[2].f;10.837 + vertex->y = data[3].f;10.838 + vertex->z = 0;10.839 + vertex->detail[0] = 0;10.840 + ta_status.poly_vertex[0].detail[0] = 0;10.841 + ta_status.poly_vertex[1].detail[0] = 0;10.842 + break;10.843 + case TA_VERTEX_TEX_SPRITE:10.844 + vertex->y = data[0].f;10.845 + vertex->z = data[1].f;10.846 + vertex++;10.847 + ta_status.vertex_count++;10.848 + vertex->x = data[2].f;10.849 + vertex->y = data[3].f;10.850 + vertex->z = 0;10.851 + vertex->detail[0] = 0;10.852 + vertex->detail[1] = 0;10.853 + ta_status.poly_vertex[0].detail[0] = data[5].i;10.854 + ta_status.poly_vertex[0].detail[1] = 0;10.855 + ta_status.poly_vertex[1].detail[0] = data[6].i;10.856 + ta_status.poly_vertex[1].detail[1] = 0;10.857 + ta_status.poly_vertex[2].detail[0] = data[7].i;10.858 + break;10.859 + case TA_VERTEX_MOD_VOLUME:10.860 + vertex->y = data[0].f;10.861 + vertex->z = data[1].f;10.862 + break;10.863 + }10.864 + ta_status.state = STATE_IN_LIST;10.865 +}10.866 +10.867 +/**10.868 + * Process 1 32-byte block of ta data10.869 + */10.870 +void pvr2_ta_process_block( char *input ) {10.871 + union ta_data *data = (union ta_data *)input;10.872 +10.873 + switch( ta_status.state ) {10.874 + case STATE_ERROR:10.875 + /* Error raised - stop processing until reset */10.876 + return;10.877 +10.878 + case STATE_EXPECT_POLY_BLOCK2:10.879 + /* This is always a pair of floating-point colours */10.880 + ta_status.intensity1 =10.881 + parse_float_colour( data[0].f, data[1].f, data[2].f, data[3].f );10.882 + ta_status.intensity2 =10.883 + parse_float_colour( data[4].f, data[5].f, data[6].f, data[7].f );10.884 + ta_status.state = STATE_IN_LIST;10.885 + break;10.886 +10.887 + case STATE_EXPECT_VERTEX_BLOCK2:10.888 + ta_parse_vertex_block2( data );10.889 + if( ta_status.vertex_count == ta_status.max_vertex ) {10.890 + ta_split_polygon();10.891 + }10.892 + break;10.893 +10.894 + case STATE_EXPECT_END_VERTEX_BLOCK2:10.895 + ta_parse_vertex_block2( data );10.896 + ta_commit_polygon();10.897 + ta_status.vertex_count = 0;10.898 + ta_status.poly_parity = 0;10.899 +10.900 + case STATE_IN_LIST:10.901 + case STATE_IDLE:10.902 + switch( TA_CMD( data->i ) ) {10.903 + case TA_CMD_END_LIST:10.904 + ta_end_list();10.905 + break;10.906 + case TA_CMD_CLIP: /* TODO */10.907 + break;10.908 + case TA_CMD_POLYGON_CONTEXT:10.909 + if( ta_status.state == STATE_IDLE ) {10.910 + ta_init_list( TA_POLYCMD_LISTTYPE( data->i ) );10.911 + }10.912 +10.913 + if( ta_status.vertex_count != 0 ) {10.914 + ta_fill_vertexes();10.915 + ta_commit_polygon();10.916 + }10.917 +10.918 + if( TA_IS_MODIFIER_LIST( ta_status.current_list_type ) ) {10.919 + ta_parse_modifier_context(data);10.920 + } else {10.921 + ta_parse_polygon_context(data);10.922 + }10.923 + break;10.924 + case TA_CMD_SPRITE_CONTEXT:10.925 + if( ta_status.state == STATE_IDLE ) {10.926 + ta_init_list( TA_POLYCMD_LISTTYPE( data->i ) );10.927 + }10.928 +10.929 + if( ta_status.vertex_count != 0 ) {10.930 + ta_fill_vertexes();10.931 + ta_commit_polygon();10.932 + }10.933 +10.934 + ta_parse_sprite_context(data);10.935 + break;10.936 + case TA_CMD_VERTEX:10.937 + ta_parse_vertex(data);10.938 +10.939 + if( ta_status.state == STATE_EXPECT_VERTEX_BLOCK2 ) {10.940 + if( TA_IS_END_VERTEX(data[0].i) ) {10.941 + ta_status.state = STATE_EXPECT_END_VERTEX_BLOCK2;10.942 + }10.943 + } else if( TA_IS_END_VERTEX(data->i) ) {10.944 + ta_commit_polygon();10.945 + ta_status.vertex_count = 0;10.946 + ta_status.poly_parity = 0;10.947 + } else if( ta_status.vertex_count == ta_status.max_vertex ) {10.948 + ta_split_polygon();10.949 + }10.950 + break;10.951 + }10.952 + break;10.953 + }10.954 +10.955 +}10.956 +10.957 +10.958 +10.959 +/**10.960 + * Write a block of data to the tile accelerator, adding the data to the10.961 + * current scene. We don't make any particular attempt to interpret the data10.962 + * at this stage, deferring that until render time.10.963 + *10.964 + * Currently copies the data verbatim to the vertex buffer, processing only10.965 + * far enough to generate the correct end-of-list events. Tile buffer is10.966 + * entirely ignored.10.967 + */10.968 +void pvr2_ta_write( char *buf, uint32_t length )10.969 +{10.970 + if( ta_status.debug_output ) {10.971 + fwrite_dump32( (uint32_t *)buf, length, stderr );10.972 + }10.973 +10.974 + for( ; length >=32; length -= 32 ) {10.975 + pvr2_ta_process_block( buf );10.976 + buf += 32;10.977 + }10.978 +}
.