Search
lxdream.org :: lxdream :: r103:9b9cfc5855e0
lxdream 0.9.1
released Jun 29
Download Now
changeset103:9b9cfc5855e0
parent102:844a3f2a76ff
child104:94b2d9962b59
authornkeynes
dateMon Mar 13 12:39:07 2006 +0000 (18 years ago)
More rendering work in progress. Almost there now...
src/Makefile.am
src/Makefile.in
src/drivers/gl_glx.c
src/drivers/video_gtk.c
src/drivers/video_x11.c
src/pvr2/pvr2.c
src/pvr2/pvr2.h
src/pvr2/pvr2mmio.h
src/pvr2/render.c
src/pvr2/ta.c
src/pvr2/texcache.c
src/sh4/sh4mem.c
src/video.h
1.1 --- a/src/Makefile.am Mon Mar 13 12:38:39 2006 +0000
1.2 +++ b/src/Makefile.am Mon Mar 13 12:39:07 2006 +0000
1.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.c
1.26 + drivers/video_x11.c drivers/video_x11.h
1.27
1.28 dream_LDADD = @PACKAGE_LIBS@ $(INTLLIBS) -lesd
1.29
2.1 --- a/src/Makefile.in Mon Mar 13 12:38:39 2006 +0000
2.2 +++ b/src/Makefile.in Mon Mar 13 12:39:07 2006 +0000
2.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.c
2.26 + drivers/video_x11.c drivers/video_x11.h
2.27
2.28
2.29 dream_LDADD = @PACKAGE_LIBS@ $(INTLLIBS) -lesd
2.30 @@ -175,18 +175,19 @@
2.31 PROGRAMS = $(bin_PROGRAMS)
2.32
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.Po
2.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.107
2.108 +texcache.o: pvr2/texcache.c
2.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@ fi
2.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.c
2.118 +
2.119 +texcache.obj: pvr2/texcache.c
2.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@ fi
2.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.c
2.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.c
2.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@ fi
2.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.c
2.148 -
2.149 -gl_glx.obj: drivers/gl_glx.c
2.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@ fi
2.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.160
2.161 ETAGS = etags
3.1 --- a/src/drivers/gl_glx.c Mon Mar 13 12:38:39 2006 +0000
3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
3.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 driver
3.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 modify
3.13 - * it under the terms of the GNU General Public License as published by
3.14 - * the Free Software Foundation; either version 2 of the License, or
3.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 of
3.19 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3.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 will
3.80 - * almost certainly be different from the one our frame is using. Which
3.81 - * means we have to jump through the following hoops to create a
3.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 +0000
4.2 +++ b/src/drivers/video_gtk.c Mon Mar 13 12:39:07 2006 +0000
4.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.13
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.24
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.29
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 +0000
5.2 +++ b/src/drivers/video_x11.c Mon Mar 13 12:39:07 2006 +0000
5.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.16
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.22
5.23 +/**
5.24 + * General X11 parameters. The front-end driver is expected to set this up
5.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.30
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.44
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 will
5.93 + * almost certainly be different from the one our frame is using. Which
5.94 + * means we have to jump through the following hoops to create a
5.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 +0000
6.2 +++ b/src/pvr2/pvr2.c Mon Mar 13 12:39:07 2006 +0000
6.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_IMPL
6.18 -#include "pvr2.h"
6.19 +#include "pvr2/pvr2mmio.h"
6.20
6.21 char *video_base;
6.22
6.23 @@ -32,10 +32,25 @@
6.24 uint32_t pvr2_run_slice( uint32_t );
6.25 void pvr2_display_frame( void );
6.26
6.27 +/**
6.28 + * Current PVR2 ram address of the data (if any) currently held in the
6.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.35
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.56
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.65
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.94
6.95 -/*
6.96 +/**
6.97 * Display the next frame, copying the current contents of video ram to
6.98 * the window. If the video configuration has changed, first recompute the
6.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.148
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.169
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.180
6.181
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.188
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 +0000
7.2 +++ b/src/pvr2/pvr2.h Mon Mar 13 12:39:07 2006 +0000
7.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.16
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.23
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_END
7.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_END
7.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_END
7.83
7.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.89
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.100
7.101 #define BS_NTSC 0x00000000
7.102 #define BS_PAL 0x00000040
7.103 #define BS_PALM 0x00000080 /* ? */
7.104 #define BS_PALN 0x000000C0 /* ? */
7.105
7.106 +#define PVR2_RAM_BASE 0x05000000
7.107 +#define PVR2_RAM_BASE_INT 0x04000000
7.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.113
7.114 +#define PVR2_CMD_END_OF_LIST 0x00
7.115 +#define PVR2_CMD_USER_CLIP 0x20
7.116 +#define PVR2_CMD_POLY_OPAQUE 0x80
7.117 +#define PVR2_CMD_MOD_OPAQUE 0x81
7.118 +#define PVR2_CMD_POLY_TRANS 0x82
7.119 +#define PVR2_CMD_MOD_TRANS 0x83
7.120 +#define PVR2_CMD_POLY_PUNCHOUT 0x84
7.121 +#define PVR2_CMD_VERTEX 0xE0
7.122 +#define PVR2_CMD_VERTEX_LAST 0xF0
7.123 +
7.124 +#define PVR2_POLY_TEXTURED 0x00000008
7.125 +#define PVR2_POLY_SPECULAR 0x00000004
7.126 +#define PVR2_POLY_SHADED 0x00000002
7.127 +#define PVR2_POLY_UV_16BIT 0x00000001
7.128 +
7.129 +#define PVR2_TEX_FORMAT_ARGB1555 0x00000000
7.130 +#define PVR2_TEX_FORMAT_RGB565 0x08000000
7.131 +#define PVR2_TEX_FORMAT_ARGB4444 0x10000000
7.132 +#define PVR2_TEX_FORMAT_YUV422 0x18000000
7.133 +#define PVR2_TEX_FORMAT_BUMPMAP 0x20000000
7.134 +#define PVR2_TEX_FORMAT_IDX4 0x28000000
7.135 +#define PVR2_TEX_FORMAT_IDX8 0x30000000
7.136 +
7.137 +#define PVR2_TEX_MIPMAP 0x80000000
7.138 +#define PVR2_TEX_COMPRESSED 0x40000000
7.139 +#define PVR2_TEX_FORMAT_MASK 0x38000000
7.140 +#define PVR2_TEX_UNTWIDDLED 0x04000000
7.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 sent
7.165 */
7.166 void pvr2_ta_write( char *buf, uint32_t length );
7.167
7.168 -void pvr2_init( void );
7.169
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 been
7.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 until
7.207 + * the next call to texcache_init(). This would typically be done if
7.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 address
7.219 + * and given parameters (the same sequence of bytes could in theory have
7.220 + * multiple interpretations). We use the texture address as the primary
7.221 + * index, but allow for multiple instances at each address. The texture
7.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 was
7.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 +0000
8.2 +++ b/src/pvr2/pvr2mmio.h Mon Mar 13 12:39:07 2006 +0000
8.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 modify
8.12 + * it under the terms of the GNU General Public License as published by
8.13 + * the Free Software Foundation; either version 2 of the License, or
8.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 of
8.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8.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_END
8.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_END
8.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 +0000
9.2 +++ b/src/pvr2/render.c Mon Mar 13 12:39:07 2006 +0000
9.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.11
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 0x00000000
9.18 +#define POLY_COLOUR_ARGBFLOAT 0x00000010
9.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.45
9.46 extern uint32_t pvr2_frame_counter;
9.47
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 are
9.51 + * Describes a rendering buffer that's actually held in GL, for when we need
9.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 nothing
9.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. Swap
9.133 + * the buffers
9.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 buffer
9.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, ensuring
9.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 + else
9.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 are
9.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.264
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're
9.271 + * probably creating a texture rather than rendering actual output.
9.272 + * We can optimise for this case a little
9.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 for
9.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 the
9.321 + * format the data needs to be in.
9.322 + * @param backBuffer TRUE to flush the back buffer, FALSE for
9.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 the
9.382 + * format the data is in.
9.383 + * @param backBuffer TRUE to write the back buffer, FALSE for
9.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 +0000
10.2 +++ b/src/pvr2/ta.c Mon Mar 13 12:39:07 2006 +0000
10.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 work
10.9 * than is currently implemented - we cheat. A lot.
10.10 @@ -42,27 +42,48 @@
10.11 float f;
10.12 };
10.13
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.32
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 the
10.38 * current scene. We don't make any particular attempt to interpret the data
10.39 * at this stage, deferring that until render time.
10.40 + *
10.41 + * Currently copies the data verbatim to the vertex buffer, processing only
10.42 + * far enough to generate the correct end-of-list events. Tile buffer is
10.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 +0000
11.2 +++ b/src/pvr2/texcache.c Mon Mar 13 12:39:07 2006 +0000
11.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 OpenGL
11.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 modify
11.14 + * it under the terms of the GNU General Public License as published by
11.15 + * the Free Software Foundation; either version 2 of the License, or
11.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 of
11.20 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11.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 OpenGL
11.28 + * textures we're willing to have open at a time. If more are
11.29 + * needed, textures will be evicted in LRU order.
11.30 + */
11.31 +#define MAX_TEXTURES 64
11.32 +
11.33 +/**
11.34 + * Data structure:
11.35 + *
11.36 + * Main operations:
11.37 + * find entry by texture_addr
11.38 + * add new entry
11.39 + * move entry to tail of lru list
11.40 + * remove entry
11.41 + */
11.42 +
11.43 +typedef signed short texcache_entry_index;
11.44 +#define EMPTY_ENTRY -1
11.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 been
11.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 until
11.101 + * the next call to texcache_init(). This would typically be done if
11.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 currently
11.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 address
11.242 + * and given parameters (the same sequence of bytes could in theory have
11.243 + * multiple interpretations). We use the texture address as the primary
11.244 + * index, but allow for multiple instances at each address. The texture
11.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 was
11.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 +0000
12.2 +++ b/src/sh4/sh4mem.c Mon Mar 13 12:39:07 2006 +0000
12.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 memory
12.8 * mapped I/O), using the page maps created in mem.c
12.9 *
12.10 @@ -315,40 +315,29 @@
12.11 * into the same memory black
12.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.27
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 - else
12.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 +0000
13.2 +++ b/src/video.h Mon Mar 13 12:39:07 2006 +0000
13.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 #endif
13.13
13.14 -#define COLFMT_RGB15 0x00000000
13.15 -#define COLFMT_RGB16 0x00000004
13.16 -#define COLFMT_RGB24 0x00000008
13.17 -#define COLFMT_RGB32 0x0000000C
13.18 +/**
13.19 + * Supported colour formats. Note that ARGB4444 is only ever used for texture
13.20 + * rendering (it's not valid for display purposes).
13.21 + */
13.22 +#define COLFMT_RGB565 1
13.23 +#define COLFMT_RGB888 4
13.24 +#define COLFMT_ARGB1555 0
13.25 +#define COLFMT_ARGB8888 5
13.26 +#define COLFMT_ARGB4444 2
13.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.30
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.36
13.37 +/**
13.38 + * Core video driver - expected to directly support an OpenGL context
13.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, and
13.46 + * is guaranteed to be called before any other methods.
13.47 + * @return TRUE if the driver was successfully initialized, otherwise
13.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 shutdown
13.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 is
13.60 + * called immediately prior to any display frame call where the
13.61 + * parameters have changed from the previous frame
13.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 is
13.68 + * called immediately prior to starting rendering of a frame where the
13.69 + * parameters have changed from the previous frame. Note that the driver
13.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 GL
13.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 a
13.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 to
13.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 the
13.91 + * entire frame (specified in RGB888 format). Is assumed to invalidate
13.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 buffer
13.98 + */
13.99 + void (*display_back_buffer)( void );
13.100 } *video_driver_t;
13.101
13.102 -
13.103 void video_open( void );
13.104 void video_update_frame( void );
13.105 void video_update_size( int, int, int );
.