Search
lxdream.org :: lxdream :: r189:615b70cfd729
lxdream 0.9.1
released Jun 29
Download Now
changeset189:615b70cfd729
parent188:91ee93613faa
child190:f7653df5e832
authornkeynes
dateWed 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
src/Makefile.am
src/Makefile.in
src/asic.h
src/pvr2/pvr2.c
src/pvr2/pvr2.h
src/pvr2/pvr2mmio.h
src/pvr2/rendcore.c
src/pvr2/render.c
src/pvr2/ta.c
src/pvr2/tacore.c
1.1 --- a/src/Makefile.am Tue Aug 01 21:56:48 2006 +0000
1.2 +++ b/src/Makefile.am Wed Aug 02 04:06:45 2006 +0000
1.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 +0000
2.2 +++ b/src/Makefile.in Wed Aug 02 04:06:45 2006 +0000
2.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.Po
2.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.Po
2.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.79
2.80 -ta.o: pvr2/ta.c
2.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.c
2.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@ fi
2.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.c
2.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.c
2.98
2.99 -ta.obj: pvr2/ta.c
2.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.c
2.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@ fi
2.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.117
2.118 render.o: pvr2/render.c
2.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.123
2.124 +rendcore.o: pvr2/rendcore.c
2.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@ fi
2.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.c
2.134 +
2.135 +rendcore.obj: pvr2/rendcore.c
2.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@ fi
2.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.c
2.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 +0000
3.2 +++ b/src/asic.h Wed Aug 02 04:06:45 2006 +0000
3.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 19
3.12 #define EVENT_PVR_PUNCHOUT_DONE 21
3.13
3.14 +#define EVENT_TA_ERROR 31
3.15 #define EVENT_IDE 32
3.16 #define EVENT_AICA 33
3.17
3.18 #define EVENT_PVR_PRIM_ALLOC_FAIL 66
3.19 #define EVENT_PVR_MATRIX_ALLOC_FAIL 67
3.20 +#define EVENT_PVR_BAD_INPUT 68
3.21
3.22 /**
3.23 * Raise an ASIC event
4.1 --- a/src/pvr2/pvr2.c Tue Aug 01 21:56:48 2006 +0000
4.2 +++ b/src/pvr2/pvr2.c Wed Aug 02 04:06:45 2006 +0000
4.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.13
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.86
4.87 @@ -270,7 +301,7 @@
4.88
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 }
4.94
4.95
5.1 --- a/src/pvr2/pvr2.h Tue Aug 01 21:56:48 2006 +0000
5.2 +++ b/src/pvr2/pvr2.h Wed Aug 02 04:06:45 2006 +0000
5.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.13
5.14 +typedef unsigned int pvraddr_t;
5.15 +typedef unsigned int pvr64addr_t;
5.16
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 0x04000000
5.21 #define PVR2_RAM_SIZE (8 * 1024 * 1024)
5.22 #define PVR2_RAM_PAGES (PVR2_RAM_SIZE>>12)
5.23 +#define PVR2_RAM_MASK 0x7FFFFF
5.24
5.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 +0000
6.2 +++ b/src/pvr2/pvr2mmio.h Wed Aug 02 04:06:45 2006 +0000
6.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.12
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_END
6.63
6.64 MMIO_REGION_BEGIN( 0x005F9000, PVR2PAL, "Power VR/2 CLUT Palettes" )
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/src/pvr2/rendcore.c Wed Aug 02 04:06:45 2006 +0000
7.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 modify
7.12 + * it under the terms of the GNU General Public License as published by
7.13 + * the Free Software Foundation; either version 2 of the License, or
7.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 of
7.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7.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 0
7.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 0
7.66 +#define CULL_SMALL 1
7.67 +#define CULL_CCW 2
7.68 +#define CULL_CW 3
7.69 +
7.70 +#define SEGMENT_END 0x80000000
7.71 +#define SEGMENT_SORT_TRANS 0x20000000
7.72 +#define SEGMENT_START 0x10000000
7.73 +#define SEGMENT_X(c) (((c) >> 2) & 0x3F)
7.74 +#define SEGMENT_Y(c) (((c) >> 8) & 0x3F)
7.75 +#define NO_POINTER 0x80000000
7.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 context
7.110 + * @param modified boolean flag indicating that the modified
7.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) tile
7.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 +0000
8.2 +++ b/src/pvr2/render.c Wed Aug 02 04:06:45 2006 +0000
8.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 primarily
8.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.16
8.17 -
8.18 -#define POLY_COLOUR_PACKED 0x00000000
8.19 -#define POLY_COLOUR_FLOAT 0x00000010
8.20 -#define POLY_COLOUR_INTENSITY 0x00000020
8.21 -#define POLY_COLOUR_INTENSITY_PREV 0x00000030
8.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.41
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.52
8.53 /**
8.54 * Describes a rendering buffer that's actually held in GL, for when we need
8.55 @@ -69,61 +38,6 @@
8.56 struct pvr2_render_buffer front_buffer;
8.57 struct pvr2_render_buffer back_buffer;
8.58
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.128
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.150
8.151 gboolean pvr2_render_init( void )
8.152 {
8.153 @@ -276,160 +212,12 @@
8.154 glCullFace( GL_BACK );
8.155
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.162
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 - else
8.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.312
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.334
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.344
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.353
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.362
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.367
8.368 /* Post-render cleanup and update */
8.369
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 +0000
9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
9.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 work
9.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 modify
9.13 - * it under the terms of the GNU General Public License as published by
9.14 - * the Free Software Foundation; either version 2 of the License, or
9.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 of
9.19 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9.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 the
9.68 - * current scene. We don't make any particular attempt to interpret the data
9.69 - * at this stage, deferring that until render time.
9.70 - *
9.71 - * Currently copies the data verbatim to the vertex buffer, processing only
9.72 - * far enough to generate the correct end-of-list events. Tile buffer is
9.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 +0000
10.2 +++ b/src/pvr2/tacore.c Wed Aug 02 04:06:45 2006 +0000
10.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 implementation
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 "pvr2.h"
10.22 +#include "asic.h"
10.23 +
10.24 +#define STATE_IDLE 0
10.25 +#define STATE_IN_LIST 1
10.26 +#define STATE_EXPECT_POLY_BLOCK2 2
10.27 +#define STATE_EXPECT_VERTEX_BLOCK2 3
10.28 +#define STATE_ERROR 4
10.29 +#define STATE_EXPECT_END_VERTEX_BLOCK2 7
10.30 +
10.31 +#define TA_CMD(i) ( (i) >> 29 )
10.32 +#define TA_CMD_END_LIST 0
10.33 +#define TA_CMD_CLIP 1
10.34 +#define TA_CMD_POLYGON_CONTEXT 4
10.35 +#define TA_CMD_SPRITE_CONTEXT 5
10.36 +#define TA_CMD_VERTEX 7
10.37 +
10.38 +#define TA_LIST_NONE -1
10.39 +#define TA_LIST_OPAQUE 0
10.40 +#define TA_LIST_OPAQUE_MOD 1
10.41 +#define TA_LIST_TRANS 2
10.42 +#define TA_LIST_TRANS_MOD 3
10.43 +#define TA_LIST_PUNCH_OUT 4
10.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 0
10.47 +#define TA_GROW_DOWN 1
10.48 +
10.49 +#define TA_VERTEX_NONE -1
10.50 +#define TA_VERTEX_PACKED 0x00
10.51 +#define TA_VERTEX_TEX_PACKED 0x08
10.52 +#define TA_VERTEX_TEX_SPEC_PACKED 0x0C
10.53 +#define TA_VERTEX_TEX_UV16_PACKED 0x09
10.54 +#define TA_VERTEX_TEX_UV16_SPEC_PACKED 0x0D
10.55 +#define TA_VERTEX_FLOAT 0x10
10.56 +#define TA_VERTEX_TEX_FLOAT 0x18
10.57 +#define TA_VERTEX_TEX_SPEC_FLOAT 0x1C
10.58 +#define TA_VERTEX_TEX_UV16_FLOAT 0x19
10.59 +#define TA_VERTEX_TEX_UV16_SPEC_FLOAT 0x1D
10.60 +#define TA_VERTEX_INTENSITY 0x20
10.61 +#define TA_VERTEX_TEX_INTENSITY 0x28
10.62 +#define TA_VERTEX_TEX_SPEC_INTENSITY 0x2C
10.63 +#define TA_VERTEX_TEX_UV16_INTENSITY 0x29
10.64 +#define TA_VERTEX_TEX_UV16_SPEC_INTENSITY 0x2D
10.65 +#define TA_VERTEX_PACKED_MOD 0x40
10.66 +#define TA_VERTEX_TEX_PACKED_MOD 0x48
10.67 +#define TA_VERTEX_TEX_SPEC_PACKED_MOD 0x4C
10.68 +#define TA_VERTEX_TEX_UV16_PACKED_MOD 0x49
10.69 +#define TA_VERTEX_TEX_UV16_SPEC_PACKED_MOD 0x4D
10.70 +#define TA_VERTEX_INTENSITY_MOD 0x60
10.71 +#define TA_VERTEX_TEX_INTENSITY_MOD 0x68
10.72 +#define TA_VERTEX_TEX_SPEC_INTENSITY_MOD 0x6C
10.73 +#define TA_VERTEX_TEX_UV16_INTENSITY_MOD 0x69
10.74 +#define TA_VERTEX_TEX_UV16_SPEC_INTENSITY_MOD 0x6D
10.75 +#define TA_VERTEX_SPRITE 0x80
10.76 +#define TA_VERTEX_TEX_SPRITE 0x88
10.77 +#define TA_VERTEX_MOD_VOLUME 0x81
10.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 0x00000000
10.87 +#define TA_POLYCMD_COLOURFMT_FLOAT 0x00000010
10.88 +#define TA_POLYCMD_COLOURFMT_INTENSITY 0x00000020
10.89 +#define TA_POLYCMD_COLOURFMT_LASTINT 0x00000030
10.90 +
10.91 +#define TA_POLYCMD_MODIFIED 0x00000080
10.92 +#define TA_POLYCMD_FULLMOD 0x00000040
10.93 +#define TA_POLYCMD_TEXTURED 0x00000008
10.94 +#define TA_POLYCMD_SPECULAR 0x00000004
10.95 +#define TA_POLYCMD_SHADED 0x00000002
10.96 +#define TA_POLYCMD_UV16 0x00000001
10.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 vertexes
10.128 + * are present
10.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 object
10.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 + return
10.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 + return
10.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_FAIL
10.255 + * @param data to be written
10.256 + * @param length Number of 32-bit words to write.
10.257 + * @return number of words actually written
10.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 space
10.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 buffers
10.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 with
10.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 well
10.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, but
10.492 + * the client hasn't sent the LAST VERTEX flag. Commit the poly as normal
10.493 + * first, then start a new poly with the first 2 vertexes taken from the
10.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 are
10.500 + * handled differently
10.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 receive
10.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 to
10.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 receive
10.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 for
10.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 data
10.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 the
10.961 + * current scene. We don't make any particular attempt to interpret the data
10.962 + * at this stage, deferring that until render time.
10.963 + *
10.964 + * Currently copies the data verbatim to the vertex buffer, processing only
10.965 + * far enough to generate the correct end-of-list events. Tile buffer is
10.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 +}
.