revision 103:9b9cfc5855e0
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 103:9b9cfc5855e0 |
parent | 102:844a3f2a76ff |
child | 104:94b2d9962b59 |
author | nkeynes |
date | Mon Mar 13 12:39:07 2006 +0000 (18 years ago) |
More rendering work in progress. Almost there now...
src/Makefile.am | view | annotate | diff | log | ||
src/Makefile.in | view | annotate | diff | log | ||
src/drivers/gl_glx.c | view | annotate | diff | log | ||
src/drivers/video_gtk.c | view | annotate | diff | log | ||
src/drivers/video_x11.c | 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/render.c | view | annotate | diff | log | ||
src/pvr2/ta.c | view | annotate | diff | log | ||
src/pvr2/texcache.c | view | annotate | diff | log | ||
src/sh4/sh4mem.c | view | annotate | diff | log | ||
src/video.h | view | annotate | diff | log |
1.1 --- a/src/Makefile.am Mon Mar 13 12:38:39 2006 +00001.2 +++ b/src/Makefile.am Mon Mar 13 12:39:07 2006 +00001.3 @@ -12,7 +12,7 @@1.4 main.c \1.5 mem.c mem.h mmio.h watch.c \1.6 asic.c asic.h \1.7 - bios.c bios.h \1.8 + syscall.c syscall.h bios.c dcload.c \1.9 gdrom/ide.c gdrom/ide.h \1.10 dreamcast.c dreamcast.h \1.11 sh4/intc.c sh4/intc.h sh4/sh4mem.c sh4/timer.c sh4/dmac.c \1.12 @@ -22,6 +22,7 @@1.13 aica/aica.c aica/aica.h aica/audio.c aica/audio.h \1.14 pvr2/pvr2.c pvr2/pvr2.h \1.15 pvr2/ta.c pvr2/render.c \1.16 + pvr2/texcache.c \1.17 maple/maple.c maple/maple.h \1.18 maple/controller.c maple/controller.h \1.19 gui/support.c gui/support.h \1.20 @@ -32,8 +33,7 @@1.21 loader.c bootstrap.c util.c \1.22 drivers/audio_null.c drivers/audio_esd.c \1.23 drivers/video_gtk.c drivers/video_gtk.h \1.24 - drivers/video_x11.c drivers/video_x11.h \1.25 - drivers/gl_glx.c1.26 + drivers/video_x11.c drivers/video_x11.h1.28 dream_LDADD = @PACKAGE_LIBS@ $(INTLLIBS) -lesd
2.1 --- a/src/Makefile.in Mon Mar 13 12:38:39 2006 +00002.2 +++ b/src/Makefile.in Mon Mar 13 12:39:07 2006 +00002.3 @@ -139,7 +139,7 @@2.4 main.c \2.5 mem.c mem.h mmio.h watch.c \2.6 asic.c asic.h \2.7 - bios.c bios.h \2.8 + syscall.c syscall.h bios.c dcload.c \2.9 gdrom/ide.c gdrom/ide.h \2.10 dreamcast.c dreamcast.h \2.11 sh4/intc.c sh4/intc.h sh4/sh4mem.c sh4/timer.c sh4/dmac.c \2.12 @@ -149,6 +149,7 @@2.13 aica/aica.c aica/aica.h aica/audio.c aica/audio.h \2.14 pvr2/pvr2.c pvr2/pvr2.h \2.15 pvr2/ta.c pvr2/render.c \2.16 + pvr2/texcache.c \2.17 maple/maple.c maple/maple.h \2.18 maple/controller.c maple/controller.h \2.19 gui/support.c gui/support.h \2.20 @@ -159,8 +160,7 @@2.21 loader.c bootstrap.c util.c \2.22 drivers/audio_null.c drivers/audio_esd.c \2.23 drivers/video_gtk.c drivers/video_gtk.h \2.24 - drivers/video_x11.c drivers/video_x11.h \2.25 - drivers/gl_glx.c2.26 + drivers/video_x11.c drivers/video_x11.h2.29 dream_LDADD = @PACKAGE_LIBS@ $(INTLLIBS) -lesd2.30 @@ -175,18 +175,19 @@2.31 PROGRAMS = $(bin_PROGRAMS)2.33 am_dream_OBJECTS = main.$(OBJEXT) mem.$(OBJEXT) watch.$(OBJEXT) \2.34 - asic.$(OBJEXT) bios.$(OBJEXT) ide.$(OBJEXT) dreamcast.$(OBJEXT) \2.35 + asic.$(OBJEXT) syscall.$(OBJEXT) bios.$(OBJEXT) \2.36 + dcload.$(OBJEXT) ide.$(OBJEXT) dreamcast.$(OBJEXT) \2.37 intc.$(OBJEXT) sh4mem.$(OBJEXT) timer.$(OBJEXT) dmac.$(OBJEXT) \2.38 sh4core.$(OBJEXT) sh4dasm.$(OBJEXT) sh4mmio.$(OBJEXT) \2.39 scif.$(OBJEXT) armcore.$(OBJEXT) armdasm.$(OBJEXT) \2.40 armmem.$(OBJEXT) aica.$(OBJEXT) audio.$(OBJEXT) pvr2.$(OBJEXT) \2.41 - ta.$(OBJEXT) render.$(OBJEXT) maple.$(OBJEXT) \2.42 - controller.$(OBJEXT) support.$(OBJEXT) interface.$(OBJEXT) \2.43 - callbacks.$(OBJEXT) gui.$(OBJEXT) mmr_win.$(OBJEXT) \2.44 - debug_win.$(OBJEXT) dump_win.$(OBJEXT) loader.$(OBJEXT) \2.45 - bootstrap.$(OBJEXT) util.$(OBJEXT) audio_null.$(OBJEXT) \2.46 - audio_esd.$(OBJEXT) video_gtk.$(OBJEXT) video_x11.$(OBJEXT) \2.47 - gl_glx.$(OBJEXT)2.48 + ta.$(OBJEXT) render.$(OBJEXT) texcache.$(OBJEXT) \2.49 + maple.$(OBJEXT) controller.$(OBJEXT) support.$(OBJEXT) \2.50 + interface.$(OBJEXT) callbacks.$(OBJEXT) gui.$(OBJEXT) \2.51 + mmr_win.$(OBJEXT) debug_win.$(OBJEXT) dump_win.$(OBJEXT) \2.52 + loader.$(OBJEXT) bootstrap.$(OBJEXT) util.$(OBJEXT) \2.53 + audio_null.$(OBJEXT) audio_esd.$(OBJEXT) video_gtk.$(OBJEXT) \2.54 + video_x11.$(OBJEXT)2.55 dream_OBJECTS = $(am_dream_OBJECTS)2.56 dream_DEPENDENCIES =2.57 dream_LDFLAGS =2.58 @@ -200,9 +201,9 @@2.59 @AMDEP_TRUE@ ./$(DEPDIR)/audio_esd.Po ./$(DEPDIR)/audio_null.Po \2.60 @AMDEP_TRUE@ ./$(DEPDIR)/bios.Po ./$(DEPDIR)/bootstrap.Po \2.61 @AMDEP_TRUE@ ./$(DEPDIR)/callbacks.Po ./$(DEPDIR)/controller.Po \2.62 -@AMDEP_TRUE@ ./$(DEPDIR)/debug_win.Po ./$(DEPDIR)/dmac.Po \2.63 -@AMDEP_TRUE@ ./$(DEPDIR)/dreamcast.Po ./$(DEPDIR)/dump_win.Po \2.64 -@AMDEP_TRUE@ ./$(DEPDIR)/gl_glx.Po ./$(DEPDIR)/gui.Po \2.65 +@AMDEP_TRUE@ ./$(DEPDIR)/dcload.Po ./$(DEPDIR)/debug_win.Po \2.66 +@AMDEP_TRUE@ ./$(DEPDIR)/dmac.Po ./$(DEPDIR)/dreamcast.Po \2.67 +@AMDEP_TRUE@ ./$(DEPDIR)/dump_win.Po ./$(DEPDIR)/gui.Po \2.68 @AMDEP_TRUE@ ./$(DEPDIR)/ide.Po ./$(DEPDIR)/intc.Po \2.69 @AMDEP_TRUE@ ./$(DEPDIR)/interface.Po ./$(DEPDIR)/loader.Po \2.70 @AMDEP_TRUE@ ./$(DEPDIR)/main.Po ./$(DEPDIR)/maple.Po \2.71 @@ -211,7 +212,8 @@2.72 @AMDEP_TRUE@ ./$(DEPDIR)/scif.Po ./$(DEPDIR)/sh4core.Po \2.73 @AMDEP_TRUE@ ./$(DEPDIR)/sh4dasm.Po ./$(DEPDIR)/sh4mem.Po \2.74 @AMDEP_TRUE@ ./$(DEPDIR)/sh4mmio.Po ./$(DEPDIR)/support.Po \2.75 -@AMDEP_TRUE@ ./$(DEPDIR)/ta.Po ./$(DEPDIR)/timer.Po \2.76 +@AMDEP_TRUE@ ./$(DEPDIR)/syscall.Po ./$(DEPDIR)/ta.Po \2.77 +@AMDEP_TRUE@ ./$(DEPDIR)/texcache.Po ./$(DEPDIR)/timer.Po \2.78 @AMDEP_TRUE@ ./$(DEPDIR)/util.Po ./$(DEPDIR)/video_gtk.Po \2.79 @AMDEP_TRUE@ ./$(DEPDIR)/video_x11.Po ./$(DEPDIR)/watch.Po2.80 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \2.81 @@ -277,11 +279,11 @@2.82 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bootstrap.Po@am__quote@2.83 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callbacks.Po@am__quote@2.84 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/controller.Po@am__quote@2.85 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dcload.Po@am__quote@2.86 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug_win.Po@am__quote@2.87 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dmac.Po@am__quote@2.88 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dreamcast.Po@am__quote@2.89 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dump_win.Po@am__quote@2.90 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gl_glx.Po@am__quote@2.91 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui.Po@am__quote@2.92 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ide.Po@am__quote@2.93 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/intc.Po@am__quote@2.94 @@ -299,7 +301,9 @@2.95 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh4mem.Po@am__quote@2.96 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh4mmio.Po@am__quote@2.97 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/support.Po@am__quote@2.98 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/syscall.Po@am__quote@2.99 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ta.Po@am__quote@2.100 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texcache.Po@am__quote@2.101 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timer.Po@am__quote@2.102 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@2.103 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video_gtk.Po@am__quote@2.104 @@ -702,6 +706,28 @@2.105 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.106 @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.108 +texcache.o: pvr2/texcache.c2.109 +@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.110 +@am__fastdepCC_TRUE@ -c -o texcache.o `test -f 'pvr2/texcache.c' || echo '$(srcdir)/'`pvr2/texcache.c; \2.111 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/texcache.Tpo" "$(DEPDIR)/texcache.Po"; \2.112 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/texcache.Tpo"; exit 1; \2.113 +@am__fastdepCC_TRUE@ fi2.114 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pvr2/texcache.c' object='texcache.o' libtool=no @AMDEPBACKSLASH@2.115 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/texcache.Po' tmpdepfile='$(DEPDIR)/texcache.TPo' @AMDEPBACKSLASH@2.116 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.117 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o texcache.o `test -f 'pvr2/texcache.c' || echo '$(srcdir)/'`pvr2/texcache.c2.118 +2.119 +texcache.obj: pvr2/texcache.c2.120 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT texcache.obj -MD -MP -MF "$(DEPDIR)/texcache.Tpo" \2.121 +@am__fastdepCC_TRUE@ -c -o texcache.obj `if test -f 'pvr2/texcache.c'; then $(CYGPATH_W) 'pvr2/texcache.c'; else $(CYGPATH_W) '$(srcdir)/pvr2/texcache.c'; fi`; \2.122 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/texcache.Tpo" "$(DEPDIR)/texcache.Po"; \2.123 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/texcache.Tpo"; exit 1; \2.124 +@am__fastdepCC_TRUE@ fi2.125 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pvr2/texcache.c' object='texcache.obj' libtool=no @AMDEPBACKSLASH@2.126 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/texcache.Po' tmpdepfile='$(DEPDIR)/texcache.TPo' @AMDEPBACKSLASH@2.127 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.128 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o texcache.obj `if test -f 'pvr2/texcache.c'; then $(CYGPATH_W) 'pvr2/texcache.c'; else $(CYGPATH_W) '$(srcdir)/pvr2/texcache.c'; fi`2.129 +2.130 maple.o: maple/maple.c2.131 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maple.o -MD -MP -MF "$(DEPDIR)/maple.Tpo" \2.132 @am__fastdepCC_TRUE@ -c -o maple.o `test -f 'maple/maple.c' || echo '$(srcdir)/'`maple/maple.c; \2.133 @@ -987,28 +1013,6 @@2.134 @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/video_x11.Po' tmpdepfile='$(DEPDIR)/video_x11.TPo' @AMDEPBACKSLASH@2.135 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.136 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o video_x11.obj `if test -f 'drivers/video_x11.c'; then $(CYGPATH_W) 'drivers/video_x11.c'; else $(CYGPATH_W) '$(srcdir)/drivers/video_x11.c'; fi`2.137 -2.138 -gl_glx.o: drivers/gl_glx.c2.139 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gl_glx.o -MD -MP -MF "$(DEPDIR)/gl_glx.Tpo" \2.140 -@am__fastdepCC_TRUE@ -c -o gl_glx.o `test -f 'drivers/gl_glx.c' || echo '$(srcdir)/'`drivers/gl_glx.c; \2.141 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gl_glx.Tpo" "$(DEPDIR)/gl_glx.Po"; \2.142 -@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/gl_glx.Tpo"; exit 1; \2.143 -@am__fastdepCC_TRUE@ fi2.144 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='drivers/gl_glx.c' object='gl_glx.o' libtool=no @AMDEPBACKSLASH@2.145 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/gl_glx.Po' tmpdepfile='$(DEPDIR)/gl_glx.TPo' @AMDEPBACKSLASH@2.146 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.147 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gl_glx.o `test -f 'drivers/gl_glx.c' || echo '$(srcdir)/'`drivers/gl_glx.c2.148 -2.149 -gl_glx.obj: drivers/gl_glx.c2.150 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gl_glx.obj -MD -MP -MF "$(DEPDIR)/gl_glx.Tpo" \2.151 -@am__fastdepCC_TRUE@ -c -o gl_glx.obj `if test -f 'drivers/gl_glx.c'; then $(CYGPATH_W) 'drivers/gl_glx.c'; else $(CYGPATH_W) '$(srcdir)/drivers/gl_glx.c'; fi`; \2.152 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gl_glx.Tpo" "$(DEPDIR)/gl_glx.Po"; \2.153 -@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/gl_glx.Tpo"; exit 1; \2.154 -@am__fastdepCC_TRUE@ fi2.155 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='drivers/gl_glx.c' object='gl_glx.obj' libtool=no @AMDEPBACKSLASH@2.156 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/gl_glx.Po' tmpdepfile='$(DEPDIR)/gl_glx.TPo' @AMDEPBACKSLASH@2.157 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.158 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gl_glx.obj `if test -f 'drivers/gl_glx.c'; then $(CYGPATH_W) 'drivers/gl_glx.c'; else $(CYGPATH_W) '$(srcdir)/drivers/gl_glx.c'; fi`2.159 uninstall-info-am:2.161 ETAGS = etags
3.1 --- a/src/drivers/gl_glx.c Mon Mar 13 12:38:39 2006 +00003.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +00003.3 @@ -1,135 +0,0 @@3.4 -/**3.5 - * $Id: gl_glx.c,v 1.2 2006-02-15 12:39:13 nkeynes Exp $3.6 - *3.7 - * GLX framebuffer support. Note depends on an X11 video driver3.8 - * (ie video_gtk) to maintain the X11 side of things.3.9 - *3.10 - * Copyright (c) 2005 Nathan Keynes.3.11 - *3.12 - * This program is free software; you can redistribute it and/or modify3.13 - * it under the terms of the GNU General Public License as published by3.14 - * the Free Software Foundation; either version 2 of the License, or3.15 - * (at your option) any later version.3.16 - *3.17 - * This program is distributed in the hope that it will be useful,3.18 - * but WITHOUT ANY WARRANTY; without even the implied warranty of3.19 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the3.20 - * GNU General Public License for more details.3.21 - */3.22 -3.23 -#include "dream.h"3.24 -#include <X11/Xlib.h>3.25 -#include <GL/glx.h>3.26 -#include "video.h"3.27 -#include "drivers/video_x11.h"3.28 -3.29 -GLXContext glx_context;3.30 -Window glx_window;3.31 -gboolean glx_open = FALSE;3.32 -3.33 -gboolean gl_glx_create_window( uint32_t width, uint32_t height )3.34 -{3.35 - int major, minor;3.36 - const char *glxExts, *glxServer;3.37 - int visual_attrs[] = { GLX_RGBA, GLX_RED_SIZE, 4,3.38 - GLX_GREEN_SIZE, 4,3.39 - GLX_BLUE_SIZE, 4,3.40 - GLX_ALPHA_SIZE, 4,3.41 - GLX_DEPTH_SIZE, 16,3.42 - GLX_DOUBLEBUFFER,3.43 - None };3.44 - int screen = XScreenNumberOfScreen(video_x11_screen);3.45 - XSetWindowAttributes win_attrs;3.46 - XVisualInfo *visual;3.47 -3.48 - if( glXQueryVersion( video_x11_display, &major, &minor ) == False ) {3.49 - ERROR( "X Display lacks the GLX nature" );3.50 - return FALSE;3.51 - }3.52 - if( major < 1 || minor < 2 ) {3.53 - ERROR( "X display supports GLX %d.%d, but we need at least 1.2", major, minor );3.54 - return FALSE;3.55 - }3.56 -3.57 - glxExts = glXQueryExtensionsString( video_x11_display, screen );3.58 - glxServer = glXQueryServerString( video_x11_display, screen, GLX_VENDOR );3.59 - INFO( "GLX version %d.%d, %s. Supported exts: %s", major, minor,3.60 - glxServer, glxExts );3.61 -3.62 - /* Find ourselves a nice visual */3.63 - visual = glXChooseVisual( video_x11_display,3.64 - screen,3.65 - visual_attrs );3.66 - if( visual == NULL ) {3.67 - ERROR( "Unable to obtain a compatible visual" );3.68 - return FALSE;3.69 - }3.70 -3.71 - /* And a matching gl context */3.72 - glx_context = glXCreateContext( video_x11_display, visual, None, True );3.73 - if( glx_context == NULL ) {3.74 - ERROR( "Unable to obtain a GLX Context. Possibly your system is broken in some small, undefineable way" );3.75 - return FALSE;3.76 - }3.77 -3.78 -3.79 - /* Ok, all good so far. Unfortunately the visual we need to use will3.80 - * almost certainly be different from the one our frame is using. Which3.81 - * means we have to jump through the following hoops to create a3.82 - * child window with the appropriate settings.3.83 - */3.84 - win_attrs.event_mask = 0;3.85 - win_attrs.colormap = XCreateColormap( video_x11_display,3.86 - RootWindowOfScreen(video_x11_screen),3.87 - visual->visual, AllocNone );3.88 - glx_window = XCreateWindow( video_x11_display, video_x11_window,3.89 - 0, 0, width, height, 0, visual->depth,3.90 - InputOutput, visual->visual,3.91 - CWColormap | CWEventMask,3.92 - &win_attrs );3.93 - if( glx_window == None ) {3.94 - /* Hrm. Aww, no window? */3.95 - ERROR( "Unable to create GLX window" );3.96 - glXDestroyContext( video_x11_display, glx_context );3.97 - if( win_attrs.colormap )3.98 - XFreeColormap( video_x11_display, win_attrs.colormap );3.99 - return FALSE;3.100 - }3.101 - XMapRaised( video_x11_display, glx_window );3.102 -3.103 - /* And finally set the window to be the active drawing area */3.104 - if( glXMakeCurrent( video_x11_display, glx_window, glx_context ) == False ) {3.105 - /* Oh you have _GOT_ to be kidding me */3.106 - ERROR( "Unable to prepare GLX window for drawing" );3.107 - XDestroyWindow( video_x11_display, glx_window );3.108 - XFreeColormap( video_x11_display, win_attrs.colormap );3.109 - glXDestroyContext( video_x11_display, glx_context );3.110 - return FALSE;3.111 - }3.112 -3.113 - glx_open = TRUE;3.114 - return TRUE;3.115 -}3.116 -3.117 -3.118 -3.119 -gboolean gl_glx_set_output_format( uint32_t width, uint32_t height,3.120 - int colour_format )3.121 -{3.122 - GLXFBConfig config;3.123 - int screen = XScreenNumberOfScreen(video_x11_screen);3.124 - int buffer_attrs[] = { GLX_PBUFFER_WIDTH, width,3.125 - GLX_PBUFFER_HEIGHT, height,3.126 - GLX_PRESERVED_CONTENTS, True,3.127 - None };3.128 - if( !glx_open ) {3.129 - if( !gl_glx_create_window( width, height ) )3.130 - return FALSE;3.131 - }3.132 - return TRUE;3.133 -}3.134 -3.135 -gboolean gl_glx_swap_frame( )3.136 -{3.137 - return FALSE;3.138 -}
4.1 --- a/src/drivers/video_gtk.c Mon Mar 13 12:38:39 2006 +00004.2 +++ b/src/drivers/video_gtk.c Mon Mar 13 12:39:07 2006 +00004.3 @@ -1,5 +1,5 @@4.4 /**4.5 - * $Id: video_gtk.c,v 1.1 2006-02-05 04:05:27 nkeynes Exp $4.6 + * $Id: video_gtk.c,v 1.2 2006-03-13 12:39:07 nkeynes Exp $4.7 *4.8 * The PC side of the video support (responsible for actually displaying /4.9 * rendering frames)4.10 @@ -35,9 +35,14 @@4.11 gboolean video_gtk_display_frame( video_buffer_t frame );4.12 gboolean video_gtk_blank( uint32_t rgb );4.14 -struct video_driver video_gtk_driver = { "Gtk", video_gtk_set_output_format,4.15 +struct video_driver video_gtk_driver = { "Gtk",4.16 + NULL,4.17 + NULL,4.18 + video_gtk_set_output_format,4.19 + NULL,4.20 video_gtk_display_frame,4.21 - video_gtk_blank };4.22 + video_gtk_blank,4.23 + NULL };4.25 gboolean video_gtk_set_output_format( uint32_t width, uint32_t height,4.26 int colour_format )4.27 @@ -90,10 +95,10 @@4.28 char *dest = video_img->mem;4.30 switch( frame->colour_format ) {4.31 - case COLFMT_RGB15:4.32 + case COLFMT_ARGB1555:4.33 for( y=0; y < frame->vres; y++ ) {4.34 uint16_t *p = (uint16_t *)src;4.35 - for( x=0; x < frame->vres; x++ ) {4.36 + for( x=0; x < frame->hres; x++ ) {4.37 uint16_t pixel = *p++;4.38 *dest++ = (pixel & 0x1F) << 3;4.39 *dest++ = (pixel & 0x3E0) >> 2;4.40 @@ -103,10 +108,10 @@4.41 src += frame->rowstride;4.42 }4.43 break;4.44 - case COLFMT_RGB16:4.45 + case COLFMT_RGB565:4.46 for( y=0; y < frame->vres; y++ ) {4.47 uint16_t *p = (uint16_t *)src;4.48 - for( x=0; x < frame->vres; x++ ) {4.49 + for( x=0; x < frame->hres; x++ ) {4.50 uint16_t pixel = *p++;4.51 *dest++ = (pixel & 0x1F) << 3;4.52 *dest++ = (pixel & 0x7E0) >> 3;4.53 @@ -116,7 +121,19 @@4.54 src += frame->rowstride;4.55 }4.56 break;4.57 - case COLFMT_RGB32:4.58 + case COLFMT_RGB888:4.59 + for( y=0; y< frame->vres; y++ ) {4.60 + char *p = src;4.61 + for( x=0; x < frame->hres; x++ ) {4.62 + *dest++ = *p++;4.63 + *dest++ = *p++;4.64 + *dest++ = *p++;4.65 + *dest++ = 0;4.66 + }4.67 + src += frame->rowstride;4.68 + }4.69 + break;4.70 + case COLFMT_ARGB8888:4.71 bytes_per_line = frame->hres << 2;4.72 if( bytes_per_line == frame->rowstride ) {4.73 /* A little bit faster */
5.1 --- a/src/drivers/video_x11.c Mon Mar 13 12:38:39 2006 +00005.2 +++ b/src/drivers/video_x11.c Mon Mar 13 12:39:07 2006 +00005.3 @@ -1,7 +1,7 @@5.4 /**5.5 - * $Id: video_x11.c,v 1.1 2006-02-05 04:05:27 nkeynes Exp $5.6 + * $Id: video_x11.c,v 1.2 2006-03-13 12:39:07 nkeynes Exp $5.7 *5.8 - * Parent for all X11 display drivers.5.9 + * Shared functions for all X11-based display drivers.5.10 *5.11 * Copyright (c) 2005 Nathan Keynes.5.12 *5.13 @@ -16,12 +16,27 @@5.14 * GNU General Public License for more details.5.15 */5.17 +#include <X11/Xlib.h>5.18 +#include <GL/glx.h>5.19 +#include "dream.h"5.20 +#include "video.h"5.21 #include "drivers/video_x11.h"5.23 +/**5.24 + * General X11 parameters. The front-end driver is expected to set this up5.25 + * by calling video_x11_set_display after initializing itself.5.26 + */5.27 Display *video_x11_display = NULL;5.28 Screen *video_x11_screen = NULL;5.29 Window video_x11_window = 0;5.31 +/**5.32 + * GLX parameters.5.33 + */5.34 +GLXContext glx_context;5.35 +Window glx_window;5.36 +gboolean glx_open = FALSE;5.37 +5.38 void video_x11_set_display( Display *display, Screen *screen, Window window )5.39 {5.40 video_x11_display = display;5.41 @@ -29,3 +44,97 @@5.42 video_x11_window = window;5.43 }5.45 +5.46 +gboolean video_glx_create_window( int x, int y, int width, int height )5.47 +{5.48 + int major, minor;5.49 + const char *glxExts, *glxServer;5.50 + int visual_attrs[] = { GLX_RGBA, GLX_RED_SIZE, 4,5.51 + GLX_GREEN_SIZE, 4,5.52 + GLX_BLUE_SIZE, 4,5.53 + GLX_ALPHA_SIZE, 4,5.54 + GLX_DEPTH_SIZE, 16,5.55 + GLX_DOUBLEBUFFER,5.56 + None };5.57 + int screen = XScreenNumberOfScreen(video_x11_screen);5.58 + XSetWindowAttributes win_attrs;5.59 + XVisualInfo *visual;5.60 +5.61 + if( glXQueryVersion( video_x11_display, &major, &minor ) == False ) {5.62 + ERROR( "X Display lacks the GLX nature" );5.63 + return FALSE;5.64 + }5.65 + if( major < 1 || minor < 2 ) {5.66 + ERROR( "X display supports GLX %d.%d, but we need at least 1.2", major, minor );5.67 + return FALSE;5.68 + }5.69 +5.70 + glxExts = glXQueryExtensionsString( video_x11_display, screen );5.71 + glxServer = glXQueryServerString( video_x11_display, screen, GLX_VENDOR );5.72 + INFO( "GLX version %d.%d, %s. Supported exts: %s", major, minor,5.73 + glxServer, glxExts );5.74 +5.75 + /* Find ourselves a nice visual */5.76 + visual = glXChooseVisual( video_x11_display,5.77 + screen,5.78 + visual_attrs );5.79 + if( visual == NULL ) {5.80 + ERROR( "Unable to obtain a compatible visual" );5.81 + return FALSE;5.82 + }5.83 +5.84 + /* And a matching gl context */5.85 + glx_context = glXCreateContext( video_x11_display, visual, None, True );5.86 + if( glx_context == NULL ) {5.87 + ERROR( "Unable to obtain a GLX Context. Possibly your system is broken in some small, undefineable way" );5.88 + return FALSE;5.89 + }5.90 +5.91 +5.92 + /* Ok, all good so far. Unfortunately the visual we need to use will5.93 + * almost certainly be different from the one our frame is using. Which5.94 + * means we have to jump through the following hoops to create a5.95 + * child window with the appropriate settings.5.96 + */5.97 + win_attrs.event_mask = 0;5.98 + win_attrs.colormap = XCreateColormap( video_x11_display,5.99 + RootWindowOfScreen(video_x11_screen),5.100 + visual->visual, AllocNone );5.101 + glx_window = XCreateWindow( video_x11_display, video_x11_window,5.102 + x, y, width, height, 0, visual->depth,5.103 + InputOutput, visual->visual,5.104 + CWColormap | CWEventMask,5.105 + &win_attrs );5.106 + if( glx_window == None ) {5.107 + /* Hrm. Aww, no window? */5.108 + ERROR( "Unable to create GLX window" );5.109 + glXDestroyContext( video_x11_display, glx_context );5.110 + if( win_attrs.colormap )5.111 + XFreeColormap( video_x11_display, win_attrs.colormap );5.112 + return FALSE;5.113 + }5.114 + XMapRaised( video_x11_display, glx_window );5.115 +5.116 + /* And finally set the window to be the active drawing area */5.117 + if( glXMakeCurrent( video_x11_display, glx_window, glx_context ) == False ) {5.118 + /* Ok you have _GOT_ to be kidding me */5.119 + ERROR( "Unable to prepare GLX window for drawing" );5.120 + XDestroyWindow( video_x11_display, glx_window );5.121 + XFreeColormap( video_x11_display, win_attrs.colormap );5.122 + glXDestroyContext( video_x11_display, glx_context );5.123 + return FALSE;5.124 + }5.125 +5.126 + glx_open = TRUE;5.127 + return TRUE;5.128 +}5.129 +5.130 +void video_glx_swap_buffers( void )5.131 +{5.132 + glXSwapBuffers( video_x11_display, glx_window );5.133 +}5.134 +5.135 +void video_glx_create_pixmap( int width, int height )5.136 +{5.137 +5.138 +}
6.1 --- a/src/pvr2/pvr2.c Mon Mar 13 12:38:39 2006 +00006.2 +++ b/src/pvr2/pvr2.c Mon Mar 13 12:39:07 2006 +00006.3 @@ -1,5 +1,5 @@6.4 /**6.5 - * $Id: pvr2.c,v 1.16 2006-02-15 13:11:46 nkeynes Exp $6.6 + * $Id: pvr2.c,v 1.17 2006-03-13 12:39:07 nkeynes Exp $6.7 *6.8 * PVR2 (Video) Core MMIO registers.6.9 *6.10 @@ -21,10 +21,10 @@6.11 #include "video.h"6.12 #include "mem.h"6.13 #include "asic.h"6.14 -#include "pvr2.h"6.15 +#include "pvr2/pvr2.h"6.16 #include "sh4/sh4core.h"6.17 #define MMIO_IMPL6.18 -#include "pvr2.h"6.19 +#include "pvr2/pvr2mmio.h"6.21 char *video_base;6.23 @@ -32,10 +32,25 @@6.24 uint32_t pvr2_run_slice( uint32_t );6.25 void pvr2_display_frame( void );6.27 +/**6.28 + * Current PVR2 ram address of the data (if any) currently held in the6.29 + * OpenGL buffers.6.30 + */6.31 +6.32 video_driver_t video_driver = NULL;6.33 struct video_buffer video_buffer[2];6.34 int video_buffer_idx = 0;6.36 +struct video_timing {6.37 + int fields_per_second;6.38 + int total_lines;6.39 + int display_lines;6.40 + int line_time_ns;6.41 +};6.42 +6.43 +struct video_timing pal_timing = { 50, 625, 575, 32000 };6.44 +struct video_timing ntsc_timing= { 60, 525, 480, 31746 };6.45 +6.46 struct dreamcast_module pvr2_module = { "PVR2", pvr2_init, NULL, NULL,6.47 pvr2_run_slice, NULL,6.48 NULL, NULL };6.49 @@ -47,19 +62,36 @@6.50 register_io_region( &mmio_region_PVR2TA );6.51 video_base = mem_get_region_by_name( MEM_REGION_VIDEO );6.52 video_driver = &video_gtk_driver;6.53 - video_driver->set_output_format( 640, 480, COLFMT_RGB32 );6.54 + video_driver->set_display_format( 640, 480, COLFMT_RGB32 );6.55 }6.57 +uint32_t pvr2_line_count = 0;6.58 +uint32_t pvr2_line_remainder = 0;6.59 +uint32_t pvr2_irq_vpos1 = 0;6.60 +uint32_t pvr2_irq_vpos2 = 0;6.61 +struct video_timing *pvr2_timing = &ntsc_timing;6.62 uint32_t pvr2_time_counter = 0;6.63 uint32_t pvr2_frame_counter = 0;6.64 uint32_t pvr2_time_per_frame = 20000000;6.66 uint32_t pvr2_run_slice( uint32_t nanosecs )6.67 {6.68 - pvr2_time_counter += nanosecs;6.69 - while( pvr2_time_counter >= pvr2_time_per_frame ) {6.70 - pvr2_display_frame();6.71 - pvr2_time_counter -= pvr2_time_per_frame;6.72 + pvr2_line_remainder += nanosecs;6.73 + while( pvr2_line_remainder >= pvr2_timing->line_time_ns ) {6.74 + pvr2_line_remainder -= pvr2_timing->line_time_ns;6.75 + pvr2_line_count++;6.76 + if( pvr2_line_count == pvr2_irq_vpos1 ) {6.77 + asic_event( EVENT_SCANLINE1 );6.78 + }6.79 + if( pvr2_line_count == pvr2_irq_vpos2 ) {6.80 + asic_event( EVENT_SCANLINE2 );6.81 + }6.82 + if( pvr2_line_count == pvr2_timing->display_lines ) {6.83 + asic_event( EVENT_RETRACE );6.84 + } else if( pvr2_line_count == pvr2_timing->total_lines ) {6.85 + pvr2_display_frame();6.86 + pvr2_line_count = 0;6.87 + }6.88 }6.89 return nanosecs;6.90 }6.91 @@ -68,48 +100,61 @@6.92 int interlaced, bChanged = 1, bEnabled = 0, vid_size = 0;6.93 char *frame_start; /* current video start address (in real memory) */6.95 -/*6.96 +/**6.97 * Display the next frame, copying the current contents of video ram to6.98 * the window. If the video configuration has changed, first recompute the6.99 * new frame size/depth.6.100 */6.101 void pvr2_display_frame( void )6.102 {6.103 + uint32_t display_addr = MMIO_READ( PVR2, DISPADDR1 );6.104 +6.105 int dispsize = MMIO_READ( PVR2, DISPSIZE );6.106 int dispmode = MMIO_READ( PVR2, DISPMODE );6.107 - int vidcfg = MMIO_READ( PVR2, VIDCFG );6.108 + int vidcfg = MMIO_READ( PVR2, DISPCFG );6.109 int vid_stride = ((dispsize & DISPSIZE_MODULO) >> 20) - 1;6.110 int vid_lpf = ((dispsize & DISPSIZE_LPF) >> 10) + 1;6.111 int vid_ppl = ((dispsize & DISPSIZE_PPL)) + 1;6.112 - gboolean bEnabled = (dispmode & DISPMODE_DE) && (vidcfg & VIDCFG_VO ) ? TRUE : FALSE;6.113 - gboolean interlaced = (vidcfg & VIDCFG_I ? TRUE : FALSE);6.114 + gboolean bEnabled = (dispmode & DISPMODE_DE) && (vidcfg & DISPCFG_VO ) ? TRUE : FALSE;6.115 + gboolean interlaced = (vidcfg & DISPCFG_I ? TRUE : FALSE);6.116 if( bEnabled ) {6.117 video_buffer_t buffer = &video_buffer[video_buffer_idx];6.118 video_buffer_idx = !video_buffer_idx;6.119 video_buffer_t last = &video_buffer[video_buffer_idx];6.120 - buffer->colour_format = (dispmode & DISPMODE_COL);6.121 buffer->rowstride = (vid_ppl + vid_stride) << 2;6.122 buffer->data = frame_start = video_base + MMIO_READ( PVR2, DISPADDR1 );6.123 buffer->vres = vid_lpf;6.124 if( interlaced ) buffer->vres <<= 1;6.125 - switch( buffer->colour_format ) {6.126 - case COLFMT_RGB15:6.127 - case COLFMT_RGB16: buffer->hres = vid_ppl << 1; break;6.128 - case COLFMT_RGB24: buffer->hres = (vid_ppl << 2) / 3; break;6.129 - case COLFMT_RGB32: buffer->hres = vid_ppl; break;6.130 + switch( (dispmode & DISPMODE_COL) >> 2 ) {6.131 + case 0:6.132 + buffer->colour_format = COLFMT_ARGB1555;6.133 + buffer->hres = vid_ppl << 1;6.134 + break;6.135 + case 1:6.136 + buffer->colour_format = COLFMT_RGB565;6.137 + buffer->hres = vid_ppl << 1;6.138 + break;6.139 + case 2:6.140 + buffer->colour_format = COLFMT_RGB888;6.141 + buffer->hres = (vid_ppl << 2) / 3;6.142 + break;6.143 + case 3:6.144 + buffer->colour_format = COLFMT_ARGB8888;6.145 + buffer->hres = vid_ppl;6.146 + break;6.147 }6.149 if( video_driver != NULL ) {6.150 if( buffer->hres != last->hres ||6.151 buffer->vres != last->vres ||6.152 buffer->colour_format != last->colour_format) {6.153 - video_driver->set_output_format( buffer->hres, buffer->vres,6.154 - buffer->colour_format );6.155 + video_driver->set_display_format( buffer->hres, buffer->vres,6.156 + buffer->colour_format );6.157 }6.158 - if( MMIO_READ( PVR2, VIDCFG2 ) & 0x08 ) { /* Blanked */6.159 + if( MMIO_READ( PVR2, DISPCFG2 ) & 0x08 ) { /* Blanked */6.160 uint32_t colour = MMIO_READ( PVR2, DISPBORDER );6.161 video_driver->display_blank_frame( colour );6.162 - } else {6.163 + } else if( !pvr2_render_display_frame( PVR2_RAM_BASE + display_addr ) ) {6.164 video_driver->display_frame( buffer );6.165 }6.166 }6.167 @@ -135,6 +180,10 @@6.168 MMIO_REGID(PVR2,reg), MMIO_REGDESC(PVR2,reg) );6.170 switch(reg) {6.171 + case VPOS_IRQ:6.172 + pvr2_irq_vpos1 = (val >> 16) & 0x03FF;6.173 + pvr2_irq_vpos2 = val & 0x03FF;6.174 + break;6.175 case TAINIT:6.176 if( val & 0x80000000 )6.177 pvr2_ta_init();6.178 @@ -178,4 +227,88 @@6.179 }6.182 +void pvr2_vram64_write( sh4addr_t destaddr, char *src, uint32_t length )6.183 +{6.184 + int bank_flag = (destaddr & 0x04) >> 2;6.185 + uint32_t *banks[2];6.186 + uint32_t *dwsrc;6.187 + int i;6.189 + destaddr = destaddr & 0x7FFFFF;6.190 + if( destaddr + length > 0x800000 ) {6.191 + length = 0x800000 - destaddr;6.192 + }6.193 +6.194 + for( i=destaddr & 0xFFFFF000; i < destaddr + length; i+= PAGE_SIZE ) {6.195 + texcache_invalidate_page( i );6.196 + }6.197 +6.198 + banks[0] = ((uint32_t *)(video_base + (destaddr>>3)));6.199 + banks[1] = banks[0] + 0x100000;6.200 +6.201 + /* Handle non-aligned start of source */6.202 + if( destaddr & 0x03 ) {6.203 + char *dest = ((char *)banks[bank_flag]) + (destaddr & 0x03);6.204 + for( i= destaddr & 0x03; i < 4 && length > 0; i++, length-- ) {6.205 + *dest++ = *src++;6.206 + }6.207 + bank_flag = !bank_flag;6.208 + }6.209 +6.210 + dwsrc = (uint32_t *)src;6.211 + while( length >= 4 ) {6.212 + *banks[bank_flag]++ = *dwsrc++;6.213 + bank_flag = !bank_flag;6.214 + length -= 4;6.215 + }6.216 +6.217 + /* Handle non-aligned end of source */6.218 + if( length ) {6.219 + src = (char *)dwsrc;6.220 + char *dest = (char *)banks[bank_flag];6.221 + while( length-- > 0 ) {6.222 + *dest++ = *src++;6.223 + }6.224 + }6.225 +6.226 +}6.227 +6.228 +void pvr2_vram64_read( char *dest, sh4addr_t srcaddr, uint32_t length )6.229 +{6.230 + int bank_flag = (srcaddr & 0x04) >> 2;6.231 + uint32_t *banks[2];6.232 + uint32_t *dwdest;6.233 + int i;6.234 +6.235 + srcaddr = srcaddr & 0x7FFFFF;6.236 + if( srcaddr + length > 0x800000 )6.237 + length = 0x800000 - srcaddr;6.238 +6.239 + banks[0] = ((uint32_t *)(video_base + (srcaddr>>3)));6.240 + banks[1] = banks[0] + 0x100000;6.241 +6.242 + /* Handle non-aligned start of source */6.243 + if( srcaddr & 0x03 ) {6.244 + char *src = ((char *)banks[bank_flag]) + (srcaddr & 0x03);6.245 + for( i= srcaddr & 0x03; i < 4 && length > 0; i++, length-- ) {6.246 + *dest++ = *src++;6.247 + }6.248 + bank_flag = !bank_flag;6.249 + }6.250 +6.251 + dwdest = (uint32_t *)dest;6.252 + while( length >= 4 ) {6.253 + *dwdest++ = *banks[bank_flag]++;6.254 + bank_flag = !bank_flag;6.255 + length -= 4;6.256 + }6.257 +6.258 + /* Handle non-aligned end of source */6.259 + if( length ) {6.260 + dest = (char *)dwdest;6.261 + char *src = (char *)banks[bank_flag];6.262 + while( length-- > 0 ) {6.263 + *dest++ = *src++;6.264 + }6.265 + }6.266 +}
7.1 --- a/src/pvr2/pvr2.h Mon Mar 13 12:38:39 2006 +00007.2 +++ b/src/pvr2/pvr2.h Mon Mar 13 12:39:07 2006 +00007.3 @@ -1,7 +1,7 @@7.4 /**7.5 - * $Id: pvr2.h,v 1.8 2006-02-15 13:11:46 nkeynes Exp $7.6 + * $Id: pvr2.h,v 1.9 2006-03-13 12:39:07 nkeynes Exp $7.7 *7.8 - * PVR2 (video chip) MMIO registers and functions.7.9 + * PVR2 (video chip) functions and macros.7.10 *7.11 * Copyright (c) 2005 Nathan Keynes.7.12 *7.13 @@ -16,67 +16,12 @@7.14 * GNU General Public License for more details.7.15 */7.17 -#include "mmio.h"7.18 +#include "dream.h"7.19 +#include "mem.h"7.20 +#include "video.h"7.21 +#include "pvr2/pvr2mmio.h"7.22 +#include <GL/gl.h>7.24 -MMIO_REGION_BEGIN( 0x005F8000, PVR2, "Power VR/2" )7.25 - LONG_PORT( 0x000, PVRID, PORT_MR, 0x17FD11DB, "PVR2 Core ID" )7.26 - LONG_PORT( 0x004, PVRVER, PORT_MR, 0x00000011, "PVR2 Core Version" )7.27 - LONG_PORT( 0x008, PVRRST, PORT_MR, 0, "PVR2 Reset" )7.28 - LONG_PORT( 0x014, RENDSTART, PORT_W, 0, "Start render" )7.29 - LONG_PORT( 0x020, OBJBASE, PORT_MRW, 0, "Object buffer base offset" )7.30 - LONG_PORT( 0x02C, TILEBASE, PORT_MRW, 0, "Tile buffer base offset" )7.31 - LONG_PORT( 0x040, DISPBORDER, PORT_MRW, 0, "Border Colour (RGB)" )7.32 - LONG_PORT( 0x044, DISPMODE, PORT_MRW, 0, "Display Mode" )7.33 - LONG_PORT( 0x048, RENDMODE, PORT_MRW, 0, "Rendering Mode" )7.34 - LONG_PORT( 0x04C, RENDSIZE, PORT_MRW, 0, "Rendering width (bytes/2)" )7.35 - LONG_PORT( 0x050, DISPADDR1, PORT_MRW, 0, "Video memory base 1" )7.36 - LONG_PORT( 0x054, DISPADDR2, PORT_MRW, 0, "Video memory base 2" )7.37 - LONG_PORT( 0x05C, DISPSIZE, PORT_MRW, 0, "Display size" )7.38 - LONG_PORT( 0x060, RENDADDR1, PORT_MRW, 0, "Rendering memory base 1" )7.39 - LONG_PORT( 0x064, RENDADDR2, PORT_MRW, 0, "Rendering memory base 2" )7.40 - LONG_PORT( 0x068, HCLIP, PORT_MRW, 0, "Horizontal clipping area" )7.41 - LONG_PORT( 0x06C, VCLIP, PORT_MRW, 0, "Vertical clipping area" )7.42 - LONG_PORT( 0x074, SHADOW, PORT_MRW, 0, "Shadowing" )7.43 - LONG_PORT( 0x078, OBJCLIP, PORT_MRW, 0, "Object clip distance (float32)" )7.44 - LONG_PORT( 0x084, TSPCLIP, PORT_MRW, 0, "Texture clip distance (float32)" )7.45 - LONG_PORT( 0x088, BGPLANEZ, PORT_MRW, 0, "Background plane depth (float32)" )7.46 - LONG_PORT( 0x08C, BGPLANECFG, PORT_MRW, 0, "Background plane config" )7.47 - LONG_PORT( 0x0B0, FGTBLCOL, PORT_MRW, 0, "Fog table colour" )7.48 - LONG_PORT( 0x0B4, FGVRTCOL, PORT_MRW, 0, "Fog vertex colour" )7.49 - LONG_PORT( 0x0B8, FGCOEFF, PORT_MRW, 0, "Fog density coefficient (float16)" )7.50 - LONG_PORT( 0x0BC, CLAMPHI, PORT_MRW, 0, "Clamp high colour" )7.51 - LONG_PORT( 0x0C0, CLAMPLO, PORT_MRW, 0, "Clamp low colour" )7.52 - LONG_PORT( 0x0C4, GUNPOS, PORT_MRW, 0, "Lightgun position" )7.53 - LONG_PORT( 0x0CC, EVTPOS, PORT_MRW, 0, "Raster event position" )7.54 - LONG_PORT( 0x0D0, VIDCFG, PORT_MRW, 0, "Sync configuration & enable" )7.55 - LONG_PORT( 0x0D4, HBORDER, PORT_MRW, 0, "Horizontal border area" )7.56 - LONG_PORT( 0x0D8, REFRESH, PORT_MRW, 0, "Refresh rates?" )7.57 - LONG_PORT( 0x0DC, VBORDER, PORT_MRW, 0, "Vertical border area" )7.58 - LONG_PORT( 0x0E0, SYNCPOS, PORT_MRW, 0, "Sync pulse timing" )7.59 - LONG_PORT( 0x0E4, TSPCFG, PORT_MRW, 0, "Texture modulo width" )7.60 - LONG_PORT( 0x0E8, VIDCFG2, PORT_MRW, 0, "Video configuration 2" )7.61 - LONG_PORT( 0x0F0, VPOS, PORT_MRW, 0, "Vertical display position" )7.62 - LONG_PORT( 0x0F4, SCALERCFG, PORT_MRW, 0, "Scaler configuration (?)" )7.63 - LONG_PORT( 0x10C, BEAMPOS, PORT_R, 0, "Raster beam position" )7.64 - LONG_PORT( 0x124, TAOPBST, PORT_MRW, 0, "TA Object Pointer Buffer start" )7.65 - LONG_PORT( 0x128, TAOBST, PORT_MRW, 0, "TA Object Buffer start" )7.66 - LONG_PORT( 0x12C, TAOPBEN, PORT_MRW, 0, "TA Object Pointer Buffer end" )7.67 - LONG_PORT( 0x130, TAOBEN, PORT_MRW, 0, "TA Object Buffer end" )7.68 - LONG_PORT( 0x134, TAOPBPOS, PORT_MRW, 0, "TA Object Pointer Buffer position" )7.69 - LONG_PORT( 0x138, TAOBPOS, PORT_MRW, 0, "TA Object Buffer position" )7.70 - LONG_PORT( 0x13C, TATBSZ, PORT_MRW, 0, "TA Tile Buffer size" )7.71 - LONG_PORT( 0x140, TAOPBCFG, PORT_MRW, 0, "TA Object Pointer Buffer config" )7.72 - LONG_PORT( 0x144, TAINIT, PORT_MRW, 0, "TA Initialize" )7.73 - LONG_PORT( 0x164, TAOPLST, PORT_MRW, 0, "TA Object Pointer List start" )7.74 -MMIO_REGION_END7.75 -7.76 -MMIO_REGION_BEGIN( 0x005F9000, PVR2PAL, "Power VR/2 CLUT Palettes" )7.77 - LONG_PORT( 0x000, PAL0_0, PORT_MRW, 0, "Pal0 colour 0" )7.78 -MMIO_REGION_END7.79 -7.80 -MMIO_REGION_BEGIN( 0x10000000, PVR2TA, "Power VR/2 TA Command port" )7.81 - LONG_PORT( 0x000, TACMD, PORT_MRW, 0, "TA Command port" )7.82 -MMIO_REGION_END7.84 #define DISPMODE_DE 0x00000001 /* Display enable */7.85 #define DISPMODE_SD 0x00000002 /* Scan double */7.86 @@ -92,26 +37,136 @@7.87 #define DISPSIZE_LPF 0x000FFC00 /* lines per field */7.88 #define DISPSIZE_PPL 0x000003FF /* pixel words (32 bit) per line */7.90 -#define VIDCFG_VP 0x00000001 /* V-sync polarity */7.91 -#define VIDCFG_HP 0x00000002 /* H-sync polarity */7.92 -#define VIDCFG_I 0x00000010 /* Interlace enable */7.93 -#define VIDCFG_BS 0x000000C0 /* Broadcast standard */7.94 -#define VIDCFG_VO 0x00000100 /* Video output enable */7.95 +#define DISPCFG_VP 0x00000001 /* V-sync polarity */7.96 +#define DISPCFG_HP 0x00000002 /* H-sync polarity */7.97 +#define DISPCFG_I 0x00000010 /* Interlace enable */7.98 +#define DISPCFG_BS 0x000000C0 /* Broadcast standard */7.99 +#define DISPCFG_VO 0x00000100 /* Video output enable */7.101 #define BS_NTSC 0x000000007.102 #define BS_PAL 0x000000407.103 #define BS_PALM 0x00000080 /* ? */7.104 #define BS_PALN 0x000000C0 /* ? */7.106 +#define PVR2_RAM_BASE 0x050000007.107 +#define PVR2_RAM_BASE_INT 0x040000007.108 +#define PVR2_RAM_SIZE (8 * 1024 * 1024)7.109 +#define PVR2_RAM_PAGES (PVR2_RAM_SIZE>>12)7.110 +7.111 void pvr2_next_frame( void );7.112 void pvr2_set_base_address( uint32_t );7.114 +#define PVR2_CMD_END_OF_LIST 0x007.115 +#define PVR2_CMD_USER_CLIP 0x207.116 +#define PVR2_CMD_POLY_OPAQUE 0x807.117 +#define PVR2_CMD_MOD_OPAQUE 0x817.118 +#define PVR2_CMD_POLY_TRANS 0x827.119 +#define PVR2_CMD_MOD_TRANS 0x837.120 +#define PVR2_CMD_POLY_PUNCHOUT 0x847.121 +#define PVR2_CMD_VERTEX 0xE07.122 +#define PVR2_CMD_VERTEX_LAST 0xF07.123 +7.124 +#define PVR2_POLY_TEXTURED 0x000000087.125 +#define PVR2_POLY_SPECULAR 0x000000047.126 +#define PVR2_POLY_SHADED 0x000000027.127 +#define PVR2_POLY_UV_16BIT 0x000000017.128 +7.129 +#define PVR2_TEX_FORMAT_ARGB1555 0x000000007.130 +#define PVR2_TEX_FORMAT_RGB565 0x080000007.131 +#define PVR2_TEX_FORMAT_ARGB4444 0x100000007.132 +#define PVR2_TEX_FORMAT_YUV422 0x180000007.133 +#define PVR2_TEX_FORMAT_BUMPMAP 0x200000007.134 +#define PVR2_TEX_FORMAT_IDX4 0x280000007.135 +#define PVR2_TEX_FORMAT_IDX8 0x300000007.136 +7.137 +#define PVR2_TEX_MIPMAP 0x800000007.138 +#define PVR2_TEX_COMPRESSED 0x400000007.139 +#define PVR2_TEX_FORMAT_MASK 0x380000007.140 +#define PVR2_TEX_UNTWIDDLED 0x040000007.141 +7.142 +#define PVR2_TEX_ADDR(x) ( ((x)&0x1FFFFF)<<3 );7.143 +#define PVR2_TEX_IS_MIPMAPPED(x) ( (x) & PVR2_TEX_MIPMAP )7.144 +#define PVR2_TEX_IS_COMPRESSED(x) ( (x) & PVR2_TEX_COMPRESSED )7.145 +#define PVR2_TEX_IS_TWIDDLED(x) (((x) & PVR2_TEX_UNTWIDDLED) == 0)7.146 +7.147 +extern video_driver_t video_driver;7.148 +7.149 +/****************************** Frame Buffer *****************************/7.150 +7.151 +/**7.152 + * Write to the interleaved memory address space (aka 64-bit address space).7.153 + */7.154 +void pvr2_vram64_write( sh4addr_t dest, char *src, uint32_t length );7.155 +7.156 +/**7.157 + * Read from the interleaved memory address space (aka 64-bit address space)7.158 + */7.159 +void pvr2_vram64_read( char *dest, sh4addr_t src, uint32_t length );7.160 +7.161 +/**************************** Tile Accelerator ***************************/7.162 /**7.163 * Process the data in the supplied buffer as an array of TA command lists.7.164 * Any excess bytes are held pending until a complete list is sent7.165 */7.166 void pvr2_ta_write( char *buf, uint32_t length );7.168 -void pvr2_init( void );7.170 +/**7.171 + * (Re)initialize the tile accelerator in preparation for the next scene.7.172 + * Normally called immediately before commencing polygon transmission.7.173 + */7.174 +void pvr2_ta_init( void );7.175 +7.176 +/********************************* Renderer ******************************/7.177 +7.178 +/**7.179 + * Initialize the rendering pipeline.7.180 + * @return TRUE on success, FALSE on failure.7.181 + */7.182 +gboolean pvr2_render_init( void );7.183 +7.184 +/**7.185 + * Render the current scene stored in PVR ram to the GL back buffer.7.186 + */7.187 void pvr2_render_scene( void );7.188 +7.189 +/**7.190 + * Display the scene rendered to the supplied address.7.191 + * @return TRUE if there was an available render that was displayed,7.192 + * otherwise FALSE (and no action was taken)7.193 + */7.194 +gboolean pvr2_render_display_frame( uint32_t address );7.195 +7.196 +/****************************** Texture Cache ****************************/7.197 +7.198 +/**7.199 + * Initialize the texture cache. Note that the GL context must have been7.200 + * initialized before calling this function.7.201 + */7.202 +void texcache_init( void );7.203 +7.204 +7.205 +/**7.206 + * Flush all textures and delete. The cache will be non-functional until7.207 + * the next call to texcache_init(). This would typically be done if7.208 + * switching GL targets.7.209 + */7.210 +void texcache_shutdown( void );7.211 +7.212 +/**7.213 + * Evict all textures contained in the page identified by a texture address.7.214 + */7.215 +void texcache_invalidate_page( uint32_t texture_addr );7.216 +7.217 +/**7.218 + * Return a texture ID for the texture specified at the supplied address7.219 + * and given parameters (the same sequence of bytes could in theory have7.220 + * multiple interpretations). We use the texture address as the primary7.221 + * index, but allow for multiple instances at each address. The texture7.222 + * will be bound to the GL_TEXTURE_2D target before being returned.7.223 + *7.224 + * If the texture has already been bound, return the ID to which it was7.225 + * bound. Otherwise obtain an unused texture ID and set it up appropriately.7.226 + */7.227 +GLuint texcache_get_texture( uint32_t texture_addr, int width, int height,7.228 + int mode );
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00008.2 +++ b/src/pvr2/pvr2mmio.h Mon Mar 13 12:39:07 2006 +00008.3 @@ -0,0 +1,80 @@8.4 +/**8.5 + * $Id: pvr2mmio.h,v 1.1 2006-03-13 12:39:07 nkeynes Exp $8.6 + *8.7 + * PVR2 (video chip) MMIO register definitions.8.8 + *8.9 + * Copyright (c) 2005 Nathan Keynes.8.10 + *8.11 + * This program is free software; you can redistribute it and/or modify8.12 + * it under the terms of the GNU General Public License as published by8.13 + * the Free Software Foundation; either version 2 of the License, or8.14 + * (at your option) any later version.8.15 + *8.16 + * This program is distributed in the hope that it will be useful,8.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of8.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the8.19 + * GNU General Public License for more details.8.20 + */8.21 +8.22 +#include "mmio.h"8.23 +8.24 +MMIO_REGION_BEGIN( 0x005F8000, PVR2, "Power VR/2" )8.25 + LONG_PORT( 0x000, PVRID, PORT_MR, 0x17FD11DB, "PVR2 Core ID" )8.26 + LONG_PORT( 0x004, PVRVER, PORT_MR, 0x00000011, "PVR2 Core Version" )8.27 + LONG_PORT( 0x008, PVRRST, PORT_MR, 0, "PVR2 Reset" )8.28 + LONG_PORT( 0x014, RENDSTART, PORT_W, 0, "Start render" )8.29 + LONG_PORT( 0x020, OBJBASE, PORT_MRW, 0, "Object buffer base offset" )8.30 + LONG_PORT( 0x02C, TILEBASE, PORT_MRW, 0, "Tile buffer base offset" )8.31 + LONG_PORT( 0x040, DISPBORDER, PORT_MRW, 0, "Border Colour (RGB)" )8.32 + LONG_PORT( 0x044, DISPMODE, PORT_MRW, 0, "Display Mode" )8.33 + LONG_PORT( 0x048, RENDMODE, PORT_MRW, 0, "Rendering Mode" )8.34 + LONG_PORT( 0x04C, RENDSIZE, PORT_MRW, 0, "Rendering width (bytes/2)" )8.35 + LONG_PORT( 0x050, DISPADDR1, PORT_MRW, 0, "Video memory base 1" )8.36 + LONG_PORT( 0x054, DISPADDR2, PORT_MRW, 0, "Video memory base 2" )8.37 + LONG_PORT( 0x05C, DISPSIZE, PORT_MRW, 0, "Display size" )8.38 + LONG_PORT( 0x060, RENDADDR1, PORT_MRW, 0, "Rendering memory base 1" )8.39 + LONG_PORT( 0x064, RENDADDR2, PORT_MRW, 0, "Rendering memory base 2" )8.40 + LONG_PORT( 0x068, HCLIP, PORT_MRW, 0, "Horizontal clipping area" )8.41 + LONG_PORT( 0x06C, VCLIP, PORT_MRW, 0, "Vertical clipping area" )8.42 + LONG_PORT( 0x074, SHADOW, PORT_MRW, 0, "Shadowing" )8.43 + LONG_PORT( 0x078, OBJCLIP, PORT_MRW, 0, "Object clip distance (float32)" )8.44 + LONG_PORT( 0x07C, OBJCFG, PORT_MRW, 0, "Object config" )8.45 + LONG_PORT( 0x084, TSPCLIP, PORT_MRW, 0, "Texture clip distance (float32)" )8.46 + LONG_PORT( 0x088, BGPLANEZ, PORT_MRW, 0, "Background plane depth (float32)" )8.47 + LONG_PORT( 0x08C, BGPLANECFG, PORT_MRW, 0, "Background plane config" )8.48 + LONG_PORT( 0x0B0, FOGTBLCOL, PORT_MRW, 0, "Fog table colour" )8.49 + LONG_PORT( 0x0B4, FOGVRTCOL, PORT_MRW, 0, "Fog vertex colour" )8.50 + LONG_PORT( 0x0B8, FOGCOEFF, PORT_MRW, 0, "Fog density coefficient (float16)" )8.51 + LONG_PORT( 0x0BC, CLAMPHI, PORT_MRW, 0, "Clamp high colour" )8.52 + LONG_PORT( 0x0C0, CLAMPLO, PORT_MRW, 0, "Clamp low colour" )8.53 + LONG_PORT( 0x0C4, GUNPOS, PORT_MRW, 0, "Lightgun position" )8.54 + LONG_PORT( 0x0CC, VPOS_IRQ, PORT_MRW, 0, "Raster event position" )8.55 + LONG_PORT( 0x0D0, DISPCFG, PORT_MRW, 0, "Sync configuration & enable" )8.56 + LONG_PORT( 0x0D4, HBORDER, PORT_MRW, 0, "Horizontal border area" )8.57 + LONG_PORT( 0x0D8, REFRESH, PORT_MRW, 0, "Refresh rates?" )8.58 + LONG_PORT( 0x0DC, VBORDER, PORT_MRW, 0, "Vertical border area" )8.59 + LONG_PORT( 0x0E0, SYNCPOS, PORT_MRW, 0, "Sync pulse timing" )8.60 + LONG_PORT( 0x0E4, TSPCFG, PORT_MRW, 0, "Texture modulo width" )8.61 + LONG_PORT( 0x0E8, DISPCFG2, PORT_MRW, 0, "Video configuration 2" )8.62 + LONG_PORT( 0x0F0, VPOS, PORT_MRW, 0, "Vertical display position" )8.63 + LONG_PORT( 0x0F4, SCALERCFG, PORT_MRW, 0, "Scaler configuration (?)" )8.64 + LONG_PORT( 0x10C, BEAMPOS, PORT_R, 0, "Raster beam position" )8.65 + LONG_PORT( 0x124, TAOBJPBASE, PORT_MRW, 0, "TA Object Pointer Buffer start" )8.66 + LONG_PORT( 0x128, TAOBJBASE, PORT_MRW, 0, "TA Object Buffer start" )8.67 + LONG_PORT( 0x12C, TAOBJPEND, PORT_MRW, 0, "TA Object Pointer Buffer end" )8.68 + LONG_PORT( 0x130, TAOBJEND, PORT_MRW, 0, "TA Object Buffer end" )8.69 + LONG_PORT( 0x134, TAOBJPPOS, PORT_MRW, 0, "TA Object Pointer Buffer position" )8.70 + LONG_PORT( 0x138, TAOBJPOS, PORT_MRW, 0, "TA Object Buffer position" )8.71 + LONG_PORT( 0x13C, TATBSZ, PORT_MRW, 0, "TA Tile Buffer size" )8.72 + LONG_PORT( 0x140, TAOPBCFG, PORT_MRW, 0, "TA Object Pointer Buffer config" )8.73 + LONG_PORT( 0x144, TAINIT, PORT_MRW, 0, "TA Initialize" )8.74 + LONG_PORT( 0x164, TAOPLST, PORT_MRW, 0, "TA Object Pointer List start" )8.75 +MMIO_REGION_END8.76 +8.77 +MMIO_REGION_BEGIN( 0x005F9000, PVR2PAL, "Power VR/2 CLUT Palettes" )8.78 + LONG_PORT( 0x000, PAL0_0, PORT_MRW, 0, "Pal0 colour 0" )8.79 +MMIO_REGION_END8.80 +8.81 +MMIO_REGION_BEGIN( 0x10000000, PVR2TA, "Power VR/2 TA Command port" )8.82 + LONG_PORT( 0x000, TACMD, PORT_MRW, 0, "TA Command port" )8.83 +MMIO_REGION_END
9.1 --- a/src/pvr2/render.c Mon Mar 13 12:38:39 2006 +00009.2 +++ b/src/pvr2/render.c Mon Mar 13 12:39:07 2006 +00009.3 @@ -1,5 +1,5 @@9.4 /**9.5 - * $Id: render.c,v 1.1 2006-02-15 13:11:46 nkeynes Exp $9.6 + * $Id: render.c,v 1.2 2006-03-13 12:39:07 nkeynes Exp $9.7 *9.8 * PVR2 Renderer support. This is where the real work happens.9.9 *9.10 @@ -18,20 +18,422 @@9.12 #include "pvr2/pvr2.h"9.13 #include "asic.h"9.14 -#include "dream.h"9.15 +9.16 +9.17 +#define POLY_COLOUR_ARGB8888 0x000000009.18 +#define POLY_COLOUR_ARGBFLOAT 0x000000109.19 +9.20 +static int pvr2_poly_vertexes[4] = { 3, 4, 6, 8 };9.21 +static int pvr2_poly_type[4] = { GL_TRIANGLES, GL_QUADS, GL_TRIANGLE_STRIP, GL_TRIANGLE_STRIP };9.22 +static int pvr2_poly_depthmode[8] = { GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL,9.23 + GL_GREATER, GL_NOTEQUAL, GL_GEQUAL,9.24 + GL_ALWAYS };9.25 +static int pvr2_poly_srcblend[8] = {9.26 + GL_ZERO, GL_ONE, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR,9.27 + GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA,9.28 + GL_ONE_MINUS_DST_ALPHA };9.29 +static int pvr2_poly_dstblend[8] = {9.30 + GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR,9.31 + GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA,9.32 + GL_ONE_MINUS_DST_ALPHA };9.33 +static int pvr2_render_colour_format[8] = {9.34 + COLFMT_ARGB1555, COLFMT_RGB565, COLFMT_ARGB4444, COLFMT_ARGB1555,9.35 + COLFMT_RGB888, COLFMT_ARGB8888, COLFMT_ARGB8888, COLFMT_ARGB4444 };9.36 +9.37 +#define POLY_STRIP_TYPE(poly) ( pvr2_poly_type[((poly->command)>>18)&0x03] )9.38 +#define POLY_STRIP_VERTEXES(poly) ( pvr2_poly_vertexes[((poly->command)>>18)&0x03] )9.39 +#define POLY_DEPTH_MODE(poly) ( pvr2_poly_depthmode[poly->poly_cfg>>29] )9.40 +#define POLY_DEPTH_WRITE(poly) (poly->poly_cfg&0x04000000)9.41 +#define POLY_TEX_WIDTH(poly) ( 1<< (((poly->poly_mode >> 3) & 0x07 ) + 3) )9.42 +#define POLY_TEX_HEIGHT(poly) ( 1<< (((poly->poly_mode) & 0x07 ) + 3) )9.43 +#define POLY_BLEND_SRC(poly) ( pvr2_poly_srcblend[(poly->poly_mode) >> 29] )9.44 +#define POLY_BLEND_DEST(poly) ( pvr2_poly_dstblend[((poly->poly_mode)>>26)&0x07] )9.46 extern uint32_t pvr2_frame_counter;9.48 /**9.49 - * Render a complete scene into an OpenGL buffer.9.50 - * Note: this may need to be broken up eventually once timings are9.51 + * Describes a rendering buffer that's actually held in GL, for when we need9.52 + * to fetch the bits back to vram.9.53 + */9.54 +typedef struct pvr2_render_buffer {9.55 + uint32_t render_addr; /* The actual address rendered to in pvr ram */9.56 + int width, height;9.57 + int colour_format;9.58 +} *pvr2_render_buffer_t;9.59 +9.60 +struct pvr2_render_buffer front_buffer;9.61 +struct pvr2_render_buffer back_buffer;9.62 +9.63 +struct tile_descriptor {9.64 + uint32_t header[6];9.65 + struct tile_pointers {9.66 + uint32_t tile_id;9.67 + uint32_t opaque_ptr;9.68 + uint32_t opaque_mod_ptr;9.69 + uint32_t trans_ptr;9.70 + uint32_t trans_mod_ptr;9.71 + uint32_t punchout_ptr;9.72 + } tile[0];9.73 +};9.74 +9.75 +/* Textured polygon */9.76 +struct pvr2_poly {9.77 + uint32_t command;9.78 + uint32_t poly_cfg; /* Bitmask */9.79 + uint32_t poly_mode; /* texture/blending mask */9.80 + uint32_t texture; /* texture data */9.81 + float alpha;9.82 + float red;9.83 + float green;9.84 + float blue;9.85 +};9.86 +9.87 +struct pvr2_specular_highlight {9.88 + float base_alpha;9.89 + float base_red;9.90 + float base_green;9.91 + float base_blue;9.92 + float offset_alpha;9.93 + float offset_red;9.94 + float offset_green;9.95 + float offset_blue;9.96 +};9.97 +9.98 +9.99 +struct pvr2_vertex_basic {9.100 + uint32_t command;9.101 + float x, y, z;9.102 + float s,t;9.103 + uint32_t col;9.104 + float f;9.105 +};9.106 +9.107 +9.108 +void pvr2_render_copy_to_sh4( pvr2_render_buffer_t buffer,9.109 + gboolean backBuffer );9.110 +9.111 +9.112 +gboolean pvr2_render_init( void )9.113 +{9.114 + front_buffer.render_addr = -1;9.115 + back_buffer.render_addr = -1;9.116 +}9.117 +9.118 +/**9.119 + * Display a rendered frame if one is available.9.120 + * @param address An address in PVR ram (0500000 range).9.121 + * @return TRUE if a frame was available to be displayed, otherwise false.9.122 + */9.123 +gboolean pvr2_render_display_frame( uint32_t address )9.124 +{9.125 + if( front_buffer.render_addr == address ) {9.126 + /* Current front buffer is already displayed, so do nothing9.127 + * and tell the caller that all is well.9.128 + */9.129 + return TRUE;9.130 + }9.131 + if( back_buffer.render_addr == address ) {9.132 + /* The more useful case - back buffer is to be displayed. Swap9.133 + * the buffers9.134 + */9.135 + video_driver->display_back_buffer();9.136 + front_buffer = back_buffer;9.137 + back_buffer.render_addr = -1;9.138 + return TRUE;9.139 + }9.140 + return FALSE;9.141 +}9.142 +9.143 +/**9.144 + * Prepare the OpenGL context to receive instructions for a new frame.9.145 + */9.146 +static void pvr2_render_prepare_context( sh4addr_t render_addr,9.147 + uint32_t width, uint32_t height,9.148 + uint32_t colour_format,9.149 + gboolean texture_target )9.150 +{9.151 + /* Select and initialize the render context */9.152 + video_driver->set_render_format( width, height, colour_format, texture_target );9.153 +9.154 + if( back_buffer.render_addr != -1 &&9.155 + back_buffer.render_addr != render_addr ) {9.156 + /* There's a current back buffer, and we're rendering somewhere else -9.157 + * flush the back buffer back to vram and start a new back buffer9.158 + */9.159 + pvr2_render_copy_to_sh4( &back_buffer, TRUE );9.160 + }9.161 +9.162 + if( front_buffer.render_addr == render_addr ) {9.163 + /* In case we've been asked to render to the current front buffer -9.164 + * invalidate the front buffer and render to the back buffer, ensuring9.165 + * we swap at the next frame display.9.166 + */9.167 + front_buffer.render_addr = -1;9.168 + }9.169 + back_buffer.render_addr = render_addr;9.170 + back_buffer.width = width;9.171 + back_buffer.height = height;9.172 + back_buffer.colour_format = colour_format;9.173 +9.174 + /* Setup the display model */9.175 + glDrawBuffer(GL_BACK);9.176 + glShadeModel(GL_SMOOTH);9.177 + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);9.178 + glViewport( 0, 0, width, height );9.179 + glMatrixMode(GL_PROJECTION);9.180 + glLoadIdentity();9.181 + glOrtho( 0, width, height, 0, 0, 65535 );9.182 + glMatrixMode(GL_MODELVIEW);9.183 + glLoadIdentity();9.184 +9.185 + /* Clear out the buffers */9.186 + glClearColor(0.0f, 0.0f, 0.0f, 0.0f);9.187 + glClearDepth(1.0f);9.188 + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );9.189 +}9.190 +9.191 +static void pvr2_render_display_list( uint32_t *display_list, uint32_t length )9.192 +{9.193 + uint32_t *cmd_ptr = display_list;9.194 + int expect_vertexes = 0;9.195 + gboolean textured = FALSE;9.196 + struct pvr2_poly *poly;9.197 + while( cmd_ptr < display_list+length ) {9.198 + switch( *cmd_ptr >> 24 ) {9.199 + case PVR2_CMD_POLY_OPAQUE:9.200 + poly = (struct pvr2_poly *)cmd_ptr;9.201 +9.202 + if( poly->command & PVR2_POLY_TEXTURED ) {9.203 + uint32_t addr = PVR2_TEX_ADDR(poly->texture);9.204 + int width = POLY_TEX_WIDTH(poly);9.205 + int height = POLY_TEX_HEIGHT(poly);9.206 + texcache_get_texture( addr, width, height, poly->texture );9.207 + textured = TRUE;9.208 + glEnable( GL_TEXTURE_2D );9.209 + } else {9.210 + textured = FALSE;9.211 + glDisable( GL_TEXTURE_2D );9.212 + }9.213 + glBlendFunc( POLY_BLEND_SRC(poly), POLY_BLEND_DEST(poly) );9.214 + if( poly->command & PVR2_POLY_SPECULAR ) {9.215 + /* Second block expected */9.216 + }9.217 + if( POLY_DEPTH_WRITE(poly) ) {9.218 + glEnable( GL_DEPTH_TEST );9.219 + glDepthFunc( POLY_DEPTH_MODE(poly) );9.220 + } else {9.221 + glDisable( GL_DEPTH_TEST );9.222 + }9.223 +9.224 + expect_vertexes = POLY_STRIP_VERTEXES( poly );9.225 + if( expect_vertexes == 3 )9.226 + glBegin( GL_TRIANGLES );9.227 + else if( expect_vertexes == 4 )9.228 + glBegin( GL_QUADS );9.229 + else9.230 + glBegin( GL_TRIANGLE_STRIP );9.231 + break;9.232 + case PVR2_CMD_VERTEX_LAST:9.233 + case PVR2_CMD_VERTEX:9.234 + if( expect_vertexes == 0 ) {9.235 + ERROR( "Unexpected vertex!" );9.236 + return;9.237 + }9.238 + expect_vertexes--;9.239 + struct pvr2_vertex_basic *vertex = (struct pvr2_vertex_basic *)cmd_ptr;9.240 + if( textured ) {9.241 + glTexCoord2f( vertex->s, vertex->t );9.242 + }9.243 + glVertex3f( vertex->x, vertex->y, vertex->z );9.244 +9.245 + if( expect_vertexes == 0 )9.246 + glEnd();9.247 + break;9.248 + }9.249 + cmd_ptr += 8; /* Next record */9.250 + }9.251 +}9.252 +9.253 +/**9.254 + * Render a complete scene into the OpenGL back buffer.9.255 + * Note: this will probably need to be broken up eventually once timings are9.256 * determined.9.257 */9.258 -void pvr2_render_scene( void )9.259 +void pvr2_render_scene( )9.260 {9.261 - /* Actual rendering goes here :) */9.262 + struct tile_descriptor *tile_desc =9.263 + (struct tile_descriptor *)mem_get_region(PVR2_RAM_BASE + MMIO_READ( PVR2, TILEBASE ));9.265 - /* End of render event */9.266 + uint32_t render_addr = MMIO_READ( PVR2, RENDADDR1 );9.267 + gboolean render_to_tex;9.268 + if( render_addr & 0x01000000 ) {9.269 + render_addr = (render_addr & 0x00FFFFFF) + PVR2_RAM_BASE_INT;9.270 + /* Heuristic - if we're rendering to the interlaced region we're9.271 + * probably creating a texture rather than rendering actual output.9.272 + * We can optimise for this case a little9.273 + */9.274 + render_to_tex = TRUE;9.275 + } else {9.276 + render_addr = (render_addr & 0x00FFFFFF) + PVR2_RAM_BASE;9.277 + render_to_tex = FALSE;9.278 + }9.279 + uint32_t render_mode = MMIO_READ( PVR2, RENDMODE );9.280 + int width = 640; /* FIXME - get this from the tile buffer */9.281 + int height = 480;9.282 + int colour_format = pvr2_render_colour_format[render_mode&0x07];9.283 + pvr2_render_prepare_context( render_addr, width, height, colour_format,9.284 + render_to_tex );9.285 +9.286 + uint32_t *display_list =9.287 + (uint32_t *)mem_get_region(PVR2_RAM_BASE + MMIO_READ( PVR2, OBJBASE ));9.288 + uint32_t display_length = *display_list++;9.289 +9.290 + int clip_x = MMIO_READ( PVR2, HCLIP ) & 0x03FF;9.291 + int clip_y = MMIO_READ( PVR2, VCLIP ) & 0x03FF;9.292 + int clip_width = ((MMIO_READ( PVR2, HCLIP ) >> 16) & 0x03FF) - clip_x + 1;9.293 + int clip_height= ((MMIO_READ( PVR2, VCLIP ) >> 16) & 0x03FF) - clip_y + 1;9.294 +9.295 + if( clip_x == 0 && clip_y == 0 && clip_width == width && clip_height == height ) {9.296 + glDisable( GL_SCISSOR_TEST );9.297 + } else {9.298 + glEnable( GL_SCISSOR_TEST );9.299 + glScissor( clip_x, clip_y, clip_width, clip_height );9.300 + }9.301 +9.302 + /* Fog setup goes here */9.303 +9.304 + /* Render the display list */9.305 + pvr2_render_display_list( display_list, display_length );9.306 +9.307 + /* Post-render cleanup and update */9.308 +9.309 +9.310 + /* Generate end of render event */9.311 asic_event( EVENT_PVR_RENDER_DONE );9.312 DEBUG( "Rendered frame %d", pvr2_frame_counter );9.313 }9.314 +9.315 +9.316 +/**9.317 + * Flush the indicated render buffer back to PVR. Caller is responsible for9.318 + * tracking whether there is actually anything in the buffer.9.319 + *9.320 + * @param buffer A render buffer indicating the address to store to, and the9.321 + * format the data needs to be in.9.322 + * @param backBuffer TRUE to flush the back buffer, FALSE for9.323 + * the front buffer.9.324 + */9.325 +void pvr2_render_copy_to_sh4( pvr2_render_buffer_t buffer,9.326 + gboolean backBuffer )9.327 +{9.328 + if( buffer->render_addr == -1 )9.329 + return;9.330 + GLenum type, format = GL_RGBA;9.331 + int size = buffer->width * buffer->height;9.332 +9.333 + switch( buffer->colour_format ) {9.334 + case COLFMT_RGB565:9.335 + type = GL_UNSIGNED_SHORT_5_6_5;9.336 + format = GL_RGB;9.337 + size <<= 1;9.338 + break;9.339 + case COLFMT_RGB888:9.340 + type = GL_UNSIGNED_INT;9.341 + format = GL_RGB;9.342 + size = (size<<1)+size;9.343 + break;9.344 + case COLFMT_ARGB1555:9.345 + type = GL_UNSIGNED_SHORT_5_5_5_1;9.346 + size <<= 1;9.347 + break;9.348 + case COLFMT_ARGB4444:9.349 + type = GL_UNSIGNED_SHORT_4_4_4_4;9.350 + size <<= 1;9.351 + break;9.352 + case COLFMT_ARGB8888:9.353 + type = GL_UNSIGNED_INT_8_8_8_8;9.354 + size <<= 2;9.355 + break;9.356 + }9.357 +9.358 + if( backBuffer ) {9.359 + glFinish();9.360 + glReadBuffer( GL_BACK );9.361 + } else {9.362 + glReadBuffer( GL_FRONT );9.363 + }9.364 +9.365 + if( buffer->render_addr & 0xFF000000 == 0x04000000 ) {9.366 + /* Interlaced buffer. Go the double copy... :( */9.367 + char target[size];9.368 + glReadPixels( 0, 0, buffer->width, buffer->height, format, type, target );9.369 + pvr2_vram64_write( buffer->render_addr, target, size );9.370 + } else {9.371 + /* Regular buffer - go direct */9.372 + char *target = mem_get_region( buffer->render_addr );9.373 + glReadPixels( 0, 0, buffer->width, buffer->height, format, type, target );9.374 + }9.375 +}9.376 +9.377 +9.378 +/**9.379 + * Copy data from PVR ram into the GL render buffer.9.380 + *9.381 + * @param buffer A render buffer indicating the address to read from, and the9.382 + * format the data is in.9.383 + * @param backBuffer TRUE to write the back buffer, FALSE for9.384 + * the front buffer.9.385 + */9.386 +void pvr2_render_copy_from_sh4( pvr2_render_buffer_t buffer,9.387 + gboolean backBuffer )9.388 +{9.389 + if( buffer->render_addr == -1 )9.390 + return;9.391 + GLenum type, format = GL_RGBA;9.392 + int size = buffer->width * buffer->height;9.393 +9.394 + switch( buffer->colour_format ) {9.395 + case COLFMT_RGB565:9.396 + type = GL_UNSIGNED_SHORT_5_6_5;9.397 + format = GL_RGB;9.398 + size <<= 1;9.399 + break;9.400 + case COLFMT_RGB888:9.401 + type = GL_UNSIGNED_INT;9.402 + format = GL_RGB;9.403 + size = (size<<1)+size;9.404 + break;9.405 + case COLFMT_ARGB1555:9.406 + type = GL_UNSIGNED_SHORT_5_5_5_1;9.407 + size <<= 1;9.408 + break;9.409 + case COLFMT_ARGB4444:9.410 + type = GL_UNSIGNED_SHORT_4_4_4_4;9.411 + size <<= 1;9.412 + break;9.413 + case COLFMT_ARGB8888:9.414 + type = GL_UNSIGNED_INT_8_8_8_8;9.415 + size <<= 2;9.416 + break;9.417 + }9.418 +9.419 + if( backBuffer ) {9.420 + glDrawBuffer( GL_BACK );9.421 + } else {9.422 + glDrawBuffer( GL_FRONT );9.423 + }9.424 +9.425 + glRasterPos2i( 0, 0 );9.426 + if( buffer->render_addr & 0xFF000000 == 0x04000000 ) {9.427 + /* Interlaced buffer. Go the double copy... :( */9.428 + char target[size];9.429 + pvr2_vram64_read( target, buffer->render_addr, size );9.430 + glDrawPixels( buffer->width, buffer->height,9.431 + format, type, target );9.432 + } else {9.433 + /* Regular buffer - go direct */9.434 + char *target = mem_get_region( buffer->render_addr );9.435 + glDrawPixels( buffer->width, buffer->height,9.436 + format, type, target );9.437 + }9.438 +}
10.1 --- a/src/pvr2/ta.c Mon Mar 13 12:38:39 2006 +000010.2 +++ b/src/pvr2/ta.c Mon Mar 13 12:39:07 2006 +000010.3 @@ -1,5 +1,5 @@10.4 /**10.5 - * $Id: ta.c,v 1.1 2006-02-15 13:11:46 nkeynes Exp $10.6 + * $Id: ta.c,v 1.2 2006-03-13 12:39:07 nkeynes Exp $10.7 *10.8 * PVR2 Tile Accelerator support. In principle this does a lot more work10.9 * than is currently implemented - we cheat. A lot.10.10 @@ -42,27 +42,48 @@10.11 float f;10.12 };10.14 +struct pvr2_ta_status {10.15 + uint32_t *length;10.16 + unsigned int last_poly_type;10.17 +} pvr2_ta_status = {NULL,0};10.18 +10.19 /**10.20 * (Re)initialize the tile accelerator in preparation for the next scene.10.21 * Normally called immediately before commencing polygon transmission.10.22 */10.23 void pvr2_ta_init( void )10.24 {10.25 -10.26 + /* Set the buffer indexes */10.27 + MMIO_WRITE( PVR2, TAOBJPOS, MMIO_READ( PVR2, TAOBJBASE ) );10.28 + MMIO_WRITE( PVR2, TAOBJPPOS, MMIO_READ( PVR2, TAOBJPBASE ) );10.29 + pvr2_ta_status.last_poly_type = 0;10.30 + pvr2_ta_status.length = NULL;10.31 }10.33 -char pvr2ta_remainder[8];10.34 -unsigned int pvr2_last_poly_type = 0;10.35 -10.36 /**10.37 * Write a block of data to the tile accelerator, adding the data to the10.38 * current scene. We don't make any particular attempt to interpret the data10.39 * at this stage, deferring that until render time.10.40 + *10.41 + * Currently copies the data verbatim to the vertex buffer, processing only10.42 + * far enough to generate the correct end-of-list events. Tile buffer is10.43 + * entirely ignored.10.44 */10.45 void pvr2_ta_write( char *buf, uint32_t length )10.46 {10.47 int i;10.48 struct tacmd *cmd_list = (struct tacmd *)buf;10.49 + uint32_t obj_addr = MMIO_READ( PVR2, TAOBJPOS );10.50 + if( pvr2_ta_status.length == NULL ) { /* Start */10.51 + pvr2_ta_status.length = (uint32_t *)mem_get_region( PVR2_RAM_BASE + obj_addr );10.52 + obj_addr += 4;10.53 + *pvr2_ta_status.length = length;10.54 + } else {10.55 + *pvr2_ta_status.length = *pvr2_ta_status.length + length;10.56 + }10.57 + mem_copy_to_sh4( PVR2_RAM_BASE + obj_addr, buf, length );10.58 + MMIO_WRITE( PVR2, TAOBJPOS, obj_addr + length );10.59 +10.60 int count = length >> 5;10.61 for( i=0; i<count; i++ ){10.62 unsigned int type = (cmd_list[i].command >> 24) & 0xFF;10.63 @@ -74,7 +95,7 @@10.64 }10.65 if( type == 0 ) {10.66 /* End of list */10.67 - switch( pvr2_last_poly_type ) {10.68 + switch( pvr2_ta_status.last_poly_type ) {10.69 case 0x80: /* Opaque polys */10.70 asic_event( EVENT_PVR_OPAQUE_DONE );10.71 break;10.72 @@ -91,9 +112,9 @@10.73 asic_event( EVENT_PVR_PUNCHOUT_DONE );10.74 break;10.75 }10.76 - pvr2_last_poly_type = 0;10.77 + pvr2_ta_status.last_poly_type = 0;10.78 } else if( type >= 0x80 && type <= 0x84 ) {10.79 - pvr2_last_poly_type = type;10.80 + pvr2_ta_status.last_poly_type = type;10.81 }10.82 }10.83 }
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +000011.2 +++ b/src/pvr2/texcache.c Mon Mar 13 12:39:07 2006 +000011.3 @@ -0,0 +1,291 @@11.4 +/**11.5 + * $Id: texcache.c,v 1.1 2006-03-13 12:39:07 nkeynes Exp $11.6 + *11.7 + * Texture cache. Responsible for maintaining a working set of OpenGL11.8 + * textures.11.9 + *11.10 + *11.11 + * Copyright (c) 2005 Nathan Keynes.11.12 + *11.13 + * This program is free software; you can redistribute it and/or modify11.14 + * it under the terms of the GNU General Public License as published by11.15 + * the Free Software Foundation; either version 2 of the License, or11.16 + * (at your option) any later version.11.17 + *11.18 + * This program is distributed in the hope that it will be useful,11.19 + * but WITHOUT ANY WARRANTY; without even the implied warranty of11.20 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the11.21 + * GNU General Public License for more details.11.22 + */11.23 +11.24 +#include <assert.h>11.25 +#include "pvr2/pvr2.h"11.26 +11.27 +/** Specifies the maximum number of OpenGL11.28 + * textures we're willing to have open at a time. If more are11.29 + * needed, textures will be evicted in LRU order.11.30 + */11.31 +#define MAX_TEXTURES 6411.32 +11.33 +/**11.34 + * Data structure:11.35 + *11.36 + * Main operations:11.37 + * find entry by texture_addr11.38 + * add new entry11.39 + * move entry to tail of lru list11.40 + * remove entry11.41 + */11.42 +11.43 +typedef signed short texcache_entry_index;11.44 +#define EMPTY_ENTRY -111.45 +11.46 +static texcache_entry_index texcache_free_ptr;11.47 +static GLuint texcache_free_list[MAX_TEXTURES];11.48 +11.49 +typedef struct texcache_entry {11.50 + uint32_t texture_addr;11.51 + int width, height, mode;11.52 + GLuint texture_id;11.53 + texcache_entry_index next;11.54 + uint32_t lru_count;11.55 +} *texcache_entry_t;11.56 +11.57 +static uint8_t texcache_page_lookup[PVR2_RAM_PAGES];11.58 +static uint32_t texcache_active_ptr;11.59 +static uint32_t texcache_ref_counter;11.60 +static struct texcache_entry texcache_active_list[MAX_TEXTURES];11.61 +11.62 +/**11.63 + * Initialize the texture cache. Note that the GL context must have been11.64 + * initialized before calling this function.11.65 + */11.66 +void texcache_init( )11.67 +{11.68 + int i;11.69 + GLuint texids[MAX_TEXTURES];11.70 + glGenTextures( MAX_TEXTURES, texids );11.71 + for( i=0; i<PVR2_RAM_PAGES; i++ ) {11.72 + texcache_page_lookup[i] = EMPTY_ENTRY;11.73 + }11.74 + for( i=0; i<MAX_TEXTURES; i++ ) {11.75 + texcache_active_list[i].texture_id = texids[i];11.76 + texcache_free_list[i] = i;11.77 + }11.78 + texcache_free_ptr = 0;11.79 + texcache_ref_counter = 0;11.80 +}11.81 +11.82 +/**11.83 + * Flush all textures from the cache, returning them to the free list.11.84 + */11.85 +void texcache_flush( )11.86 +{11.87 + int i;11.88 + /* clear structures */11.89 + for( i=0; i<PVR2_RAM_PAGES; i++ ) {11.90 + texcache_page_lookup[i] = EMPTY_ENTRY;11.91 + }11.92 + for( i=0; i<MAX_TEXTURES; i++ ) {11.93 + texcache_free_list[i] = i;11.94 + }11.95 + texcache_free_ptr = 0;11.96 + texcache_ref_counter = 0;11.97 +}11.98 +11.99 +/**11.100 + * Flush all textures and delete. The cache will be non-functional until11.101 + * the next call to texcache_init(). This would typically be done if11.102 + * switching GL targets.11.103 + */11.104 +void texcache_shutdown( )11.105 +{11.106 + GLuint texids[MAX_TEXTURES];11.107 + int i;11.108 + texcache_flush();11.109 +11.110 + for( i=0; i<MAX_TEXTURES; i++ ) {11.111 + texids[i] = texcache_active_list[i].texture_id;11.112 + }11.113 + glDeleteTextures( MAX_TEXTURES, texids );11.114 +}11.115 +11.116 +/**11.117 + * Evict all textures contained in the page identified by a texture address.11.118 + */11.119 +void texcache_invalidate_page( uint32_t texture_addr ) {11.120 + uint32_t texture_page = texture_addr >> 12;11.121 + texcache_entry_index idx = texcache_page_lookup[texture_page];11.122 + if( idx == EMPTY_ENTRY )11.123 + return;11.124 + assert( texcache_free_ptr > 0 );11.125 + do {11.126 + texcache_entry_t entry = &texcache_active_list[idx];11.127 + /* release entry */11.128 + texcache_free_ptr--;11.129 + texcache_free_list[texcache_free_ptr] = idx;11.130 + idx = entry->next;11.131 + entry->next = EMPTY_ENTRY;11.132 + } while( idx != EMPTY_ENTRY );11.133 + texcache_page_lookup[texture_page] = EMPTY_ENTRY;11.134 +}11.135 +11.136 +/**11.137 + * Evict a single texture from the cache.11.138 + * @return the slot of the evicted texture.11.139 + */11.140 +static texcache_entry_index texcache_evict( void )11.141 +{11.142 + /* Full table scan - take over the entry with the lowest lru value */11.143 + texcache_entry_index slot = 0;11.144 + int lru_value = texcache_active_list[0].lru_count;11.145 + int i;11.146 + for( i=1; i<MAX_TEXTURES; i++ ) {11.147 + /* FIXME: account for rollover */11.148 + if( texcache_active_list[i].lru_count < lru_value ) {11.149 + slot = i;11.150 + lru_value = texcache_active_list[i].lru_count;11.151 + }11.152 + }11.153 +11.154 + /* Remove the selected slot from the lookup table */11.155 + uint32_t evict_page = texcache_active_list[slot].texture_addr;11.156 + texcache_entry_index replace_next = texcache_active_list[slot].next;11.157 + texcache_active_list[slot].next = EMPTY_ENTRY; /* Just for safety */11.158 + if( texcache_page_lookup[evict_page] == slot ) {11.159 + texcache_page_lookup[evict_page] = replace_next;11.160 + } else {11.161 + texcache_entry_index idx = texcache_page_lookup[evict_page];11.162 + texcache_entry_index next;11.163 + do {11.164 + next = texcache_active_list[idx].next;11.165 + if( next == slot ) {11.166 + texcache_active_list[idx].next = replace_next;11.167 + break;11.168 + }11.169 + idx = next;11.170 + } while( next != EMPTY_ENTRY );11.171 + }11.172 + return slot;11.173 +}11.174 +11.175 +/**11.176 + * Load texture data from the given address and parameters into the currently11.177 + * bound OpenGL texture.11.178 + */11.179 +static texcache_load_texture( uint32_t texture_addr, int width, int height,11.180 + int mode ) {11.181 + uint32_t bytes = width * height;11.182 + int bpp = 2;11.183 + GLint intFormat, format, type;11.184 + switch( mode & PVR2_TEX_FORMAT_MASK ) {11.185 + case PVR2_TEX_FORMAT_ARGB1555:11.186 + bytes <<= 1;11.187 + intFormat = GL_RGB5_A1;11.188 + format = GL_RGBA;11.189 + type = GL_UNSIGNED_SHORT_5_5_5_1;11.190 + break;11.191 + case PVR2_TEX_FORMAT_RGB565:11.192 + bytes <<= 1;11.193 + intFormat = GL_RGBA;11.194 + format = GL_RGBA;11.195 + type = GL_UNSIGNED_SHORT_5_6_5;11.196 + break;11.197 + case PVR2_TEX_FORMAT_ARGB4444:11.198 + bytes <<= 1;11.199 + intFormat = GL_RGBA4;11.200 + format = GL_RGBA;11.201 + type = GL_UNSIGNED_SHORT_4_4_4_4;11.202 + break;11.203 + case PVR2_TEX_FORMAT_YUV422:11.204 + ERROR( "YUV textures not supported" );11.205 + break;11.206 + case PVR2_TEX_FORMAT_BUMPMAP:11.207 + ERROR( "Bumpmap not supported" );11.208 + break;11.209 + case PVR2_TEX_FORMAT_IDX4:11.210 + /* Supported? */11.211 + bytes >>= 1;11.212 + intFormat = GL_INTENSITY4;11.213 + format = GL_COLOR_INDEX;11.214 + type = GL_UNSIGNED_BYTE;11.215 + bpp = 0;11.216 + break;11.217 + case PVR2_TEX_FORMAT_IDX8:11.218 + intFormat = GL_INTENSITY8;11.219 + format = GL_COLOR_INDEX;11.220 + type = GL_UNSIGNED_BYTE;11.221 + bpp = 1;11.222 + break;11.223 + }11.224 +11.225 + unsigned char data[bytes];11.226 + /* load data from image, detwiddling/uncompressing as required */11.227 + if( PVR2_TEX_IS_COMPRESSED(mode) ) {11.228 + ERROR( "VQ Compression not supported" );11.229 + } else {11.230 + pvr2_vram64_read( &data, texture_addr, bytes );11.231 + if( PVR2_TEX_IS_TWIDDLED(mode) ) {11.232 + /* Untwiddle */11.233 + }11.234 + }11.235 + /* Pass to GL */11.236 + glTexImage2D( GL_TEXTURE_2D, 0, intFormat, width, height, 0, format, type,11.237 + data );11.238 +}11.239 +11.240 +/**11.241 + * Return a texture ID for the texture specified at the supplied address11.242 + * and given parameters (the same sequence of bytes could in theory have11.243 + * multiple interpretations). We use the texture address as the primary11.244 + * index, but allow for multiple instances at each address. The texture11.245 + * will be bound to the GL_TEXTURE_2D target before being returned.11.246 + *11.247 + * If the texture has already been bound, return the ID to which it was11.248 + * bound. Otherwise obtain an unused texture ID and set it up appropriately.11.249 + */11.250 +GLuint texcache_get_texture( uint32_t texture_addr, int width, int height,11.251 + int mode )11.252 +{11.253 + uint32_t texture_page = texture_addr >> 12;11.254 + texcache_entry_index idx = texcache_page_lookup[texture_page];11.255 + while( idx != EMPTY_ENTRY ) {11.256 + texcache_entry_t entry = &texcache_active_list[idx];11.257 + if( entry->texture_addr == texture_addr &&11.258 + entry->mode == mode &&11.259 + entry->width == width &&11.260 + entry->height == height ) {11.261 + entry->lru_count = texcache_ref_counter++;11.262 + glBindTexture( GL_TEXTURE_2D, entry->texture_id );11.263 + return entry->texture_id;11.264 + }11.265 + idx = entry->next;11.266 + }11.267 +11.268 + /* Not found - check the free list */11.269 + int slot = 0;11.270 +11.271 + if( texcache_free_ptr < MAX_TEXTURES ) {11.272 + slot = texcache_free_list[texcache_free_ptr++];11.273 + } else {11.274 + slot = texcache_evict();11.275 + }11.276 +11.277 + /* Construct new entry */11.278 + texcache_active_list[slot].texture_addr = texture_addr;11.279 + texcache_active_list[slot].width = width;11.280 + texcache_active_list[slot].height = height;11.281 + texcache_active_list[slot].mode = mode;11.282 + texcache_active_list[slot].lru_count = texcache_ref_counter++;11.283 +11.284 + /* Add entry to the lookup table */11.285 + texcache_active_list[slot].next = texcache_page_lookup[texture_page];11.286 + texcache_page_lookup[texture_page] = slot;11.287 +11.288 + /* Construct the GL texture */11.289 + GLuint texid = texcache_free_list[texcache_free_ptr++];11.290 + glBindTexture( GL_TEXTURE_2D, texid );11.291 + texcache_load_texture( texture_addr, width, height, mode );11.292 +11.293 + return texcache_active_list[slot].texture_id;11.294 +}
12.1 --- a/src/sh4/sh4mem.c Mon Mar 13 12:38:39 2006 +000012.2 +++ b/src/sh4/sh4mem.c Mon Mar 13 12:39:07 2006 +000012.3 @@ -1,5 +1,5 @@12.4 /**12.5 - * $Id: sh4mem.c,v 1.7 2006-02-15 13:11:50 nkeynes Exp $12.6 + * $Id: sh4mem.c,v 1.8 2006-03-13 12:39:07 nkeynes Exp $12.7 * sh4mem.c is responsible for the SH4's access to memory (including memory12.8 * mapped I/O), using the page maps created in mem.c12.9 *12.10 @@ -315,40 +315,29 @@12.11 * into the same memory black12.12 */12.13 void mem_copy_from_sh4( char *dest, uint32_t srcaddr, size_t count ) {12.14 - char *src = mem_get_region(srcaddr);12.15 - memcpy( dest, src, count );12.16 + if( srcaddr >= 0x04000000 && srcaddr < 0x05000000 ) {12.17 + pvr2_vram64_read( dest, srcaddr, count );12.18 + } else {12.19 + char *src = mem_get_region(srcaddr);12.20 + if( src == NULL ) {12.21 + ERROR( "Attempted block read from unknown address %08X", srcaddr );12.22 + } else {12.23 + memcpy( dest, src, count );12.24 + }12.25 + }12.26 }12.28 void mem_copy_to_sh4( uint32_t destaddr, char *src, size_t count ) {12.29 if( destaddr >= 0x10000000 && destaddr < 0x20000000 ) {12.30 pvr2_ta_write( src, count );12.31 - } else if( destaddr >= 04000000 && destaddr < 0x5000000 ) {12.32 - /* 64-bit video write. Oh. Yuck */12.33 - uint32_t *dest32[2];12.34 - uint32_t *src32 = (uint32_t *)src;12.35 - int flag = 0;12.36 - if( destaddr & 0x03 != 0 ) {12.37 - }12.38 - dest32[0] = (uint32_t *)mem_get_region(TRANSLATE_VIDEO_64BIT_ADDRESS(destaddr));12.39 - dest32[1] = (uint32_t *)mem_get_region(TRANSLATE_VIDEO_64BIT_ADDRESS(destaddr+4));12.40 - while( count >= 4 ) {12.41 - *dest32[flag]++ = *src32++;12.42 - flag = !flag;12.43 - count -=4;12.44 - }12.45 - if( count != 0 ) {12.46 - src = (char *)src32;12.47 - char *dest = dest32[flag];12.48 - do {12.49 - *dest++ = *src++;12.50 - count--;12.51 - } while( count > 0 );12.52 - }12.53 + } else if( destaddr >= 0x04000000 && destaddr < 0x05000000 ) {12.54 + pvr2_vram64_write( destaddr, src, count );12.55 } else {12.56 char *dest = mem_get_region(destaddr);12.57 if( dest == NULL )12.58 - ERROR( "Attempted block write to undefined region %08X", destaddr );12.59 - else12.60 + ERROR( "Attempted block write to unknown address %08X", destaddr );12.61 + else {12.62 memcpy( dest, src, count );12.63 + }12.64 }12.65 }
13.1 --- a/src/video.h Mon Mar 13 12:38:39 2006 +000013.2 +++ b/src/video.h Mon Mar 13 12:39:07 2006 +000013.3 @@ -1,5 +1,5 @@13.4 /**13.5 - * $Id: video.h,v 1.4 2006-02-05 04:05:27 nkeynes Exp $13.6 + * $Id: video.h,v 1.5 2006-03-13 12:39:03 nkeynes Exp $13.7 *13.8 * The PC side of the video support (responsible for actually displaying /13.9 * rendering frames)13.10 @@ -27,10 +27,18 @@13.11 extern "C" {13.12 #endif13.14 -#define COLFMT_RGB15 0x0000000013.15 -#define COLFMT_RGB16 0x0000000413.16 -#define COLFMT_RGB24 0x0000000813.17 -#define COLFMT_RGB32 0x0000000C13.18 +/**13.19 + * Supported colour formats. Note that ARGB4444 is only ever used for texture13.20 + * rendering (it's not valid for display purposes).13.21 + */13.22 +#define COLFMT_RGB565 113.23 +#define COLFMT_RGB888 413.24 +#define COLFMT_ARGB1555 013.25 +#define COLFMT_ARGB8888 513.26 +#define COLFMT_ARGB4444 213.27 +#define COLFMT_YUV422 3 /* 8-bit YUV (texture source only) */13.28 +#define COLFMT_INDEX4 6 /* 4 bit indexed colour (texture source only) */13.29 +#define COLFMT_INDEX8 7 /* 8-bit indexed colour (texture source only) */13.31 typedef struct video_buffer {13.32 uint32_t hres;13.33 @@ -40,15 +48,69 @@13.34 char *data;13.35 } *video_buffer_t;13.37 +/**13.38 + * Core video driver - expected to directly support an OpenGL context13.39 + */13.40 typedef struct video_driver {13.41 char *name;13.42 - gboolean (*set_output_format)( uint32_t hres, uint32_t vres,13.43 - int colour_fmt );13.44 + /**13.45 + * Initialize the driver. This is called only once at startup time, and13.46 + * is guaranteed to be called before any other methods.13.47 + * @return TRUE if the driver was successfully initialized, otherwise13.48 + * FALSE.13.49 + */13.50 + gboolean (*init_driver)(void);13.51 +13.52 + /**13.53 + * Cleanly shutdown the driver. Normally only called at system shutdown13.54 + * time.13.55 + */13.56 + void (*shutdown_driver)(void);13.57 +13.58 + /**13.59 + * Set the current display format to the specified values. This is13.60 + * called immediately prior to any display frame call where the13.61 + * parameters have changed from the previous frame13.62 + */13.63 + gboolean (*set_display_format)( uint32_t hres, uint32_t vres,13.64 + int colour_fmt );13.65 +13.66 + /**13.67 + * Set the current rendering format to the specified values. This is13.68 + * called immediately prior to starting rendering of a frame where the13.69 + * parameters have changed from the previous frame. Note that the driver13.70 + * is not required to precisely support the requested colour format.13.71 + *13.72 + * This method is also responsible for setting up an appropriate GL13.73 + * context for the main engine to render into.13.74 + *13.75 + * @param hres The horizontal resolution (ie 640)13.76 + * @param vres The vertical resolution (ie 480)13.77 + * @param colour_fmt The colour format of the buffer (ie COLFMT_ARGB4444)13.78 + * @param texture Flag indicating that the frame being rendered is a13.79 + * texture, rather than a display frame.13.80 + */13.81 + gboolean (*set_render_format)( uint32_t hres, uint32_t vres,13.82 + int colour_fmt, gboolean texture );13.83 + /**13.84 + * Display a single frame using the supplied pixmap data. Is assumed to13.85 + * invalidate the current GL front buffer (but not the back buffer).13.86 + */13.87 gboolean (*display_frame)( video_buffer_t buffer );13.88 +13.89 + /**13.90 + * Display a single blanked frame using a fixed colour for the13.91 + * entire frame (specified in RGB888 format). Is assumed to invalidate13.92 + * the current GL front buffer (but not the back buffer).13.93 + */13.94 gboolean (*display_blank_frame)( uint32_t rgb );13.95 +13.96 + /**13.97 + * Promote the current render back buffer to the front buffer13.98 + */13.99 + void (*display_back_buffer)( void );13.100 } *video_driver_t;13.102 -13.103 void video_open( void );13.104 void video_update_frame( void );13.105 void video_update_size( int, int, int );
.