revision 352:f0df7a6d4703
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 352:f0df7a6d4703 |
parent | 351:41b7e55ee10f |
child | 353:b8569afb53fc |
author | nkeynes |
date | Sun Feb 11 10:09:32 2007 +0000 (17 years ago) |
Bug 27: Implement opengl framebuffer objects
Rewrite much of the final video output stage. Now uses generic "render
buffers", implemented on GL using framebuffer objects + textures.
Rewrite much of the final video output stage. Now uses generic "render
buffers", implemented on GL using framebuffer objects + textures.
src/Makefile.am | view | annotate | diff | log | ||
src/Makefile.in | view | annotate | diff | log | ||
src/display.c | view | annotate | diff | log | ||
src/display.h | view | annotate | diff | log | ||
src/drivers/gl_common.c | view | annotate | diff | log | ||
src/drivers/gl_common.h | view | annotate | diff | log | ||
src/drivers/gl_fbo.c | view | annotate | diff | log | ||
src/drivers/video_gl.c | view | annotate | diff | log | ||
src/drivers/video_gl.h | view | annotate | diff | log | ||
src/drivers/video_gtk.c | view | annotate | diff | log | ||
src/drivers/video_null.c | view | annotate | diff | log | ||
src/drivers/video_x11.c | view | annotate | diff | log | ||
src/drivers/video_x11.h | view | annotate | diff | log | ||
src/pvr2/pvr2.c | view | annotate | diff | log | ||
src/pvr2/pvr2.h | view | annotate | diff | log | ||
src/pvr2/pvr2mem.c | view | annotate | diff | log | ||
src/pvr2/rendcore.c | view | annotate | diff | log | ||
src/pvr2/render.c | view | annotate | diff | log | ||
src/pvr2/texcache.c | view | annotate | diff | log |
1.1 --- a/src/Makefile.am Tue Feb 06 07:59:06 2007 +00001.2 +++ b/src/Makefile.am Sun Feb 11 10:09:32 2007 +00001.3 @@ -36,7 +36,7 @@1.4 drivers/audio_null.c drivers/audio_esd.c \1.5 drivers/video_null.c drivers/video_gtk.c drivers/video_gtk.h \1.6 drivers/video_x11.c drivers/video_x11.h \1.7 - drivers/video_gl.c drivers/video_gl.h1.8 + drivers/gl_common.c drivers/gl_common.h drivers/gl_fbo.c1.10 lxdream_LDADD = @PACKAGE_LIBS@ $(INTLLIBS) -lesd
2.1 --- a/src/Makefile.in Tue Feb 06 07:59:06 2007 +00002.2 +++ b/src/Makefile.in Sun Feb 11 10:09:32 2007 +00002.3 @@ -170,7 +170,7 @@2.4 drivers/audio_null.c drivers/audio_esd.c \2.5 drivers/video_null.c drivers/video_gtk.c drivers/video_gtk.h \2.6 drivers/video_x11.c drivers/video_x11.h \2.7 - drivers/video_gl.c drivers/video_gl.h2.8 + drivers/gl_common.c drivers/gl_common.h drivers/gl_fbo.c2.11 lxdream_LDADD = @PACKAGE_LIBS@ $(INTLLIBS) -lesd2.12 @@ -202,7 +202,7 @@2.13 loader.$(OBJEXT) bootstrap.$(OBJEXT) util.$(OBJEXT) \2.14 display.$(OBJEXT) audio_null.$(OBJEXT) audio_esd.$(OBJEXT) \2.15 video_null.$(OBJEXT) video_gtk.$(OBJEXT) video_x11.$(OBJEXT) \2.16 - video_gl.$(OBJEXT)2.17 + gl_common.$(OBJEXT) gl_fbo.$(OBJEXT)2.18 lxdream_OBJECTS = $(am_lxdream_OBJECTS)2.19 lxdream_DEPENDENCIES =2.20 lxdream_LDFLAGS =2.21 @@ -221,6 +221,7 @@2.22 @AMDEP_TRUE@ ./$(DEPDIR)/dmac.Po ./$(DEPDIR)/dreamcast.Po \2.23 @AMDEP_TRUE@ ./$(DEPDIR)/dump_win.Po ./$(DEPDIR)/eventq.Po \2.24 @AMDEP_TRUE@ ./$(DEPDIR)/gdimage.Po ./$(DEPDIR)/gdrom.Po \2.25 +@AMDEP_TRUE@ ./$(DEPDIR)/gl_common.Po ./$(DEPDIR)/gl_fbo.Po \2.26 @AMDEP_TRUE@ ./$(DEPDIR)/gui.Po ./$(DEPDIR)/ide.Po \2.27 @AMDEP_TRUE@ ./$(DEPDIR)/intc.Po ./$(DEPDIR)/interface.Po \2.28 @AMDEP_TRUE@ ./$(DEPDIR)/linux.Po ./$(DEPDIR)/loader.Po \2.29 @@ -235,10 +236,9 @@2.30 @AMDEP_TRUE@ ./$(DEPDIR)/sh4mmio.Po ./$(DEPDIR)/support.Po \2.31 @AMDEP_TRUE@ ./$(DEPDIR)/syscall.Po ./$(DEPDIR)/tacore.Po \2.32 @AMDEP_TRUE@ ./$(DEPDIR)/texcache.Po ./$(DEPDIR)/timer.Po \2.33 -@AMDEP_TRUE@ ./$(DEPDIR)/util.Po ./$(DEPDIR)/video_gl.Po \2.34 -@AMDEP_TRUE@ ./$(DEPDIR)/video_gtk.Po ./$(DEPDIR)/video_null.Po \2.35 -@AMDEP_TRUE@ ./$(DEPDIR)/video_x11.Po ./$(DEPDIR)/watch.Po \2.36 -@AMDEP_TRUE@ ./$(DEPDIR)/yuv.Po2.37 +@AMDEP_TRUE@ ./$(DEPDIR)/util.Po ./$(DEPDIR)/video_gtk.Po \2.38 +@AMDEP_TRUE@ ./$(DEPDIR)/video_null.Po ./$(DEPDIR)/video_x11.Po \2.39 +@AMDEP_TRUE@ ./$(DEPDIR)/watch.Po ./$(DEPDIR)/yuv.Po2.40 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \2.41 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)2.42 CCLD = $(CC)2.43 @@ -312,6 +312,8 @@2.44 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eventq.Po@am__quote@2.45 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gdimage.Po@am__quote@2.46 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gdrom.Po@am__quote@2.47 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gl_common.Po@am__quote@2.48 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gl_fbo.Po@am__quote@2.49 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui.Po@am__quote@2.50 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ide.Po@am__quote@2.51 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/intc.Po@am__quote@2.52 @@ -341,7 +343,6 @@2.53 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texcache.Po@am__quote@2.54 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timer.Po@am__quote@2.55 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@2.56 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video_gl.Po@am__quote@2.57 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video_gtk.Po@am__quote@2.58 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video_null.Po@am__quote@2.59 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video_x11.Po@am__quote@2.60 @@ -1316,27 +1317,49 @@2.61 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.62 @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.64 -video_gl.o: drivers/video_gl.c2.65 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT video_gl.o -MD -MP -MF "$(DEPDIR)/video_gl.Tpo" \2.66 -@am__fastdepCC_TRUE@ -c -o video_gl.o `test -f 'drivers/video_gl.c' || echo '$(srcdir)/'`drivers/video_gl.c; \2.67 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/video_gl.Tpo" "$(DEPDIR)/video_gl.Po"; \2.68 -@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/video_gl.Tpo"; exit 1; \2.69 +gl_common.o: drivers/gl_common.c2.70 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gl_common.o -MD -MP -MF "$(DEPDIR)/gl_common.Tpo" \2.71 +@am__fastdepCC_TRUE@ -c -o gl_common.o `test -f 'drivers/gl_common.c' || echo '$(srcdir)/'`drivers/gl_common.c; \2.72 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gl_common.Tpo" "$(DEPDIR)/gl_common.Po"; \2.73 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/gl_common.Tpo"; exit 1; \2.74 @am__fastdepCC_TRUE@ fi2.75 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='drivers/video_gl.c' object='video_gl.o' libtool=no @AMDEPBACKSLASH@2.76 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/video_gl.Po' tmpdepfile='$(DEPDIR)/video_gl.TPo' @AMDEPBACKSLASH@2.77 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='drivers/gl_common.c' object='gl_common.o' libtool=no @AMDEPBACKSLASH@2.78 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/gl_common.Po' tmpdepfile='$(DEPDIR)/gl_common.TPo' @AMDEPBACKSLASH@2.79 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.80 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o video_gl.o `test -f 'drivers/video_gl.c' || echo '$(srcdir)/'`drivers/video_gl.c2.81 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gl_common.o `test -f 'drivers/gl_common.c' || echo '$(srcdir)/'`drivers/gl_common.c2.83 -video_gl.obj: drivers/video_gl.c2.84 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT video_gl.obj -MD -MP -MF "$(DEPDIR)/video_gl.Tpo" \2.85 -@am__fastdepCC_TRUE@ -c -o video_gl.obj `if test -f 'drivers/video_gl.c'; then $(CYGPATH_W) 'drivers/video_gl.c'; else $(CYGPATH_W) '$(srcdir)/drivers/video_gl.c'; fi`; \2.86 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/video_gl.Tpo" "$(DEPDIR)/video_gl.Po"; \2.87 -@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/video_gl.Tpo"; exit 1; \2.88 +gl_common.obj: drivers/gl_common.c2.89 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gl_common.obj -MD -MP -MF "$(DEPDIR)/gl_common.Tpo" \2.90 +@am__fastdepCC_TRUE@ -c -o gl_common.obj `if test -f 'drivers/gl_common.c'; then $(CYGPATH_W) 'drivers/gl_common.c'; else $(CYGPATH_W) '$(srcdir)/drivers/gl_common.c'; fi`; \2.91 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gl_common.Tpo" "$(DEPDIR)/gl_common.Po"; \2.92 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/gl_common.Tpo"; exit 1; \2.93 @am__fastdepCC_TRUE@ fi2.94 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='drivers/video_gl.c' object='video_gl.obj' libtool=no @AMDEPBACKSLASH@2.95 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/video_gl.Po' tmpdepfile='$(DEPDIR)/video_gl.TPo' @AMDEPBACKSLASH@2.96 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='drivers/gl_common.c' object='gl_common.obj' libtool=no @AMDEPBACKSLASH@2.97 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/gl_common.Po' tmpdepfile='$(DEPDIR)/gl_common.TPo' @AMDEPBACKSLASH@2.98 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.99 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o video_gl.obj `if test -f 'drivers/video_gl.c'; then $(CYGPATH_W) 'drivers/video_gl.c'; else $(CYGPATH_W) '$(srcdir)/drivers/video_gl.c'; fi`2.100 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gl_common.obj `if test -f 'drivers/gl_common.c'; then $(CYGPATH_W) 'drivers/gl_common.c'; else $(CYGPATH_W) '$(srcdir)/drivers/gl_common.c'; fi`2.101 +2.102 +gl_fbo.o: drivers/gl_fbo.c2.103 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gl_fbo.o -MD -MP -MF "$(DEPDIR)/gl_fbo.Tpo" \2.104 +@am__fastdepCC_TRUE@ -c -o gl_fbo.o `test -f 'drivers/gl_fbo.c' || echo '$(srcdir)/'`drivers/gl_fbo.c; \2.105 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gl_fbo.Tpo" "$(DEPDIR)/gl_fbo.Po"; \2.106 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/gl_fbo.Tpo"; exit 1; \2.107 +@am__fastdepCC_TRUE@ fi2.108 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='drivers/gl_fbo.c' object='gl_fbo.o' libtool=no @AMDEPBACKSLASH@2.109 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/gl_fbo.Po' tmpdepfile='$(DEPDIR)/gl_fbo.TPo' @AMDEPBACKSLASH@2.110 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.111 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gl_fbo.o `test -f 'drivers/gl_fbo.c' || echo '$(srcdir)/'`drivers/gl_fbo.c2.112 +2.113 +gl_fbo.obj: drivers/gl_fbo.c2.114 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gl_fbo.obj -MD -MP -MF "$(DEPDIR)/gl_fbo.Tpo" \2.115 +@am__fastdepCC_TRUE@ -c -o gl_fbo.obj `if test -f 'drivers/gl_fbo.c'; then $(CYGPATH_W) 'drivers/gl_fbo.c'; else $(CYGPATH_W) '$(srcdir)/drivers/gl_fbo.c'; fi`; \2.116 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gl_fbo.Tpo" "$(DEPDIR)/gl_fbo.Po"; \2.117 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/gl_fbo.Tpo"; exit 1; \2.118 +@am__fastdepCC_TRUE@ fi2.119 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='drivers/gl_fbo.c' object='gl_fbo.obj' libtool=no @AMDEPBACKSLASH@2.120 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/gl_fbo.Po' tmpdepfile='$(DEPDIR)/gl_fbo.TPo' @AMDEPBACKSLASH@2.121 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.122 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gl_fbo.obj `if test -f 'drivers/gl_fbo.c'; then $(CYGPATH_W) 'drivers/gl_fbo.c'; else $(CYGPATH_W) '$(srcdir)/drivers/gl_fbo.c'; fi`2.123 uninstall-info-am:2.125 ETAGS = etags
3.1 --- a/src/display.c Tue Feb 06 07:59:06 2007 +00003.2 +++ b/src/display.c Sun Feb 11 10:09:32 2007 +00003.3 @@ -1,5 +1,5 @@3.4 /**3.5 - * $Id: display.c,v 1.5 2007-01-25 13:03:23 nkeynes Exp $3.6 + * $Id: display.c,v 1.6 2007-02-11 10:09:32 nkeynes Exp $3.7 *3.8 * Generic support for keyboard and other input sources. The active display3.9 * driver is expected to deliver events here, where they're translated and3.10 @@ -39,7 +39,8 @@3.11 { GL_UNSIGNED_SHORT_4_4_4_4_REV, GL_BGRA, GL_RGBA4, 2 },3.12 { GL_UNSIGNED_INT_8_8_8_8_REV, GL_BGRA, GL_RGBA8, 4 }, /* YUV decoded to ARGB8888 */3.13 { GL_UNSIGNED_BYTE, GL_BGR, GL_RGB, 3 },3.14 - { GL_UNSIGNED_INT_8_8_8_8_REV, GL_BGRA, GL_RGBA8, 4 }3.15 + { GL_UNSIGNED_INT_8_8_8_8_REV, GL_BGRA, GL_RGBA8, 4 },3.16 +3.17 };3.19 /**3.20 @@ -151,7 +152,5 @@3.21 display_driver = driver;3.22 if( driver->init_driver != NULL )3.23 driver->init_driver();3.24 - driver->set_display_format( 640, 480, COLFMT_ARGB8888 );3.25 - driver->set_render_format( 640, 480, COLFMT_ARGB8888, FALSE );3.26 texcache_gl_init();3.27 }
4.1 --- a/src/display.h Tue Feb 06 07:59:06 2007 +00004.2 +++ b/src/display.h Sun Feb 11 10:09:32 2007 +00004.3 @@ -1,5 +1,5 @@4.4 /**4.5 - * $Id: display.h,v 1.4 2007-01-27 12:03:53 nkeynes Exp $4.6 + * $Id: display.h,v 1.5 2007-02-11 10:09:32 nkeynes Exp $4.7 *4.8 * The PC side of the video support (responsible for actually displaying /4.9 * rendering frames)4.10 @@ -20,6 +20,7 @@4.11 #ifndef dream_video_H4.12 #define dream_video_H4.14 +#include "mem.h"4.15 #include <stdint.h>4.16 #include <glib.h>4.17 #include <GL/gl.h>4.18 @@ -50,17 +51,38 @@4.20 extern int colour_format_bytes[];4.22 -typedef struct video_buffer {4.23 - uint32_t hres;4.24 - uint32_t vres;4.25 +/**4.26 + * Structure to hold pixel data held in GL buffers.4.27 + */4.28 +typedef struct render_buffer {4.29 + uint32_t width;4.30 + uint32_t height;4.31 uint32_t rowstride;4.32 int colour_format;4.33 - gboolean line_double;4.34 - char *data;4.35 -} *video_buffer_t;4.36 + sh4addr_t address; /* Address buffer was rendered to, or -1 for unrendered */4.37 + uint32_t size; /* Size of buffer in bytes, must be width*height*bpp */4.38 + int scale;4.39 + int buf_id; /* driver-specific buffer id, if applicable */4.40 + gboolean flushed; /* True if the buffer has been flushed to vram */4.41 +} *render_buffer_t;4.43 /**4.44 - * Core video driver - expected to directly support an OpenGL context4.45 + * Structure to hold pixel data stored in pvr2 vram, as opposed to data in4.46 + * GL buffers.4.47 + */4.48 +typedef struct frame_buffer {4.49 + uint32_t width;4.50 + uint32_t height;4.51 + uint32_t rowstride;4.52 + int colour_format;4.53 + sh4addr_t address;4.54 + uint32_t size; /* Size of buffer in bytes, must be width*height*bpp */4.55 + char *data;4.56 +} * frame_buffer_t;4.57 +4.58 +/**4.59 + * Core video driver - exports function to setup a GL context, as well as handle4.60 + * keyboard input and display resultant output.4.61 */4.62 typedef struct display_driver {4.63 char *name;4.64 @@ -87,47 +109,44 @@4.65 uint16_t (*resolve_keysym)( const gchar *keysym );4.67 /**4.68 - * Set the current display format to the specified values. This is4.69 - * called immediately prior to any display frame call where the4.70 - * parameters have changed from the previous frame4.71 + * Create a render target with the given width and height.4.72 */4.73 - gboolean (*set_display_format)( uint32_t hres, uint32_t vres,4.74 - int colour_fmt );4.75 + render_buffer_t (*create_render_buffer)( uint32_t width, uint32_t height );4.77 /**4.78 - * Set the current rendering format to the specified values. This is4.79 - * called immediately prior to starting rendering of a frame where the4.80 - * parameters have changed from the previous frame. Note that the driver4.81 - * is not required to precisely support the requested colour format.4.82 - *4.83 - * This method is also responsible for setting up an appropriate GL4.84 - * context for the main engine to render into.4.85 - *4.86 - * @param hres The horizontal resolution (ie 640)4.87 - * @param vres The vertical resolution (ie 480)4.88 - * @param colour_fmt The colour format of the buffer (ie COLFMT_ARGB4444)4.89 - * @param texture Flag indicating that the frame being rendered is a4.90 - * texture, rather than a display frame.4.91 + * Destroy the specified render buffer and release any associated4.92 + * resources.4.93 */4.94 - gboolean (*set_render_format)( uint32_t hres, uint32_t vres,4.95 - int colour_fmt, gboolean texture );4.96 + void (*destroy_render_buffer)( render_buffer_t buffer );4.97 +4.98 /**4.99 - * Display a single frame using the supplied pixmap data. Is assumed to4.100 - * invalidate the current GL front buffer (but not the back buffer).4.101 + * Set the current rendering target to the specified buffer.4.102 */4.103 - gboolean (*display_frame)( video_buffer_t buffer );4.104 + gboolean (*set_render_target)( render_buffer_t buffer );4.105 +4.106 + /**4.107 + * Display a single frame using the supplied pixmap data.4.108 + */4.109 + gboolean (*display_frame_buffer)( frame_buffer_t buffer );4.110 +4.111 + /**4.112 + * Display a single frame using a previously rendered GL buffer.4.113 + */4.114 + gboolean (*display_render_buffer)( render_buffer_t buffer );4.116 /**4.117 * Display a single blanked frame using a fixed colour for the4.118 - * entire frame (specified in RGB888 format). Is assumed to invalidate4.119 - * the current GL front buffer (but not the back buffer).4.120 + * entire frame (specified in RGB888 format).4.121 */4.122 - gboolean (*display_blank_frame)( uint32_t rgb );4.123 + gboolean (*display_blank)( uint32_t rgb );4.125 /**4.126 - * Promote the current render back buffer to the front buffer4.127 + * Copy the image data from the GL buffer to the target memory buffer,4.128 + * using the format etc from the buffer. This may force a glFinish()4.129 + * but does not invalidate the buffer.4.130 */4.131 - void (*display_back_buffer)( void );4.132 + gboolean (*read_render_buffer)( render_buffer_t buffer, char *target );4.133 +4.134 } *display_driver_t;4.136 void video_open( void );
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00005.2 +++ b/src/drivers/gl_common.c Sun Feb 11 10:09:32 2007 +00005.3 @@ -0,0 +1,160 @@5.4 +/**5.5 + * $Id: gl_common.c,v 1.1 2007-02-11 10:09:32 nkeynes Exp $5.6 + *5.7 + * Common GL code that doesn't depend on a specific implementation5.8 + *5.9 + * Copyright (c) 2005 Nathan Keynes.5.10 + *5.11 + * This program is free software; you can redistribute it and/or modify5.12 + * it under the terms of the GNU General Public License as published by5.13 + * the Free Software Foundation; either version 2 of the License, or5.14 + * (at your option) any later version.5.15 + *5.16 + * This program is distributed in the hope that it will be useful,5.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of5.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the5.19 + * GNU General Public License for more details.5.20 + */5.21 +5.22 +#include <GL/gl.h>5.23 +#include "dream.h"5.24 +#include "drivers/gl_common.h"5.25 +5.26 +extern uint32_t video_width, video_height;5.27 +5.28 +char *required_extensions[] = { "GL_EXT_framebuffer_object", NULL };5.29 +5.30 +/**5.31 + * Test if a specific extension is supported. From opengl.org5.32 + * @param extension extension name to check for5.33 + * @return TRUE if supported, otherwise FALSE.5.34 + */5.35 +gboolean isGLExtensionSupported( const char *extension )5.36 +{5.37 + const GLubyte *extensions = NULL;5.38 + const GLubyte *start;5.39 + GLubyte *where, *terminator;5.40 +5.41 + /* Extension names should not have spaces. */5.42 + where = (GLubyte *) strchr(extension, ' ');5.43 + if (where || *extension == '\0')5.44 + return 0;5.45 + extensions = glGetString(GL_EXTENSIONS);5.46 + /* It takes a bit of care to be fool-proof about parsing the5.47 + OpenGL extensions string. Don't be fooled by sub-strings,5.48 + etc. */5.49 + start = extensions;5.50 + for (;;) {5.51 + where = (GLubyte *) strstr((const char *) start, extension);5.52 + if (!where)5.53 + break;5.54 + terminator = where + strlen(extension);5.55 + if (where == start || *(where - 1) == ' ')5.56 + if (*terminator == ' ' || *terminator == '\0')5.57 + return TRUE;5.58 + start = terminator;5.59 + }5.60 + return FALSE;5.61 +}5.62 +5.63 +gboolean hasRequiredGLExtensions( )5.64 +{5.65 + int i;5.66 + gboolean isOK = TRUE;5.67 +5.68 + for( i=0; required_extensions[i] != NULL; i++ ) {5.69 + if( !isGLExtensionSupported(required_extensions[i]) ) {5.70 + ERROR( "Required OpenGL extension not supported: %s", required_extensions[i] );5.71 + isOK = FALSE;5.72 + }5.73 + }5.74 + return isOK;5.75 +}5.76 +5.77 +5.78 +gboolean gl_display_frame_buffer( frame_buffer_t frame )5.79 +{5.80 + GLenum type = colour_formats[frame->colour_format].type;5.81 + GLenum format = colour_formats[frame->colour_format].format;5.82 + int bpp = colour_formats[frame->colour_format].bpp;5.83 + GLint texid;5.84 +5.85 + glViewport( 0, 0, video_width, video_height );5.86 + glMatrixMode(GL_PROJECTION);5.87 + glLoadIdentity();5.88 + glOrtho( 0, video_width, video_height, 0, 0, -65535 );5.89 + glMatrixMode(GL_MODELVIEW);5.90 + glLoadIdentity();5.91 +5.92 + /* Disable everything */5.93 + glDisable( GL_TEXTURE_2D );5.94 + glDisable( GL_ALPHA_TEST );5.95 + glDisable( GL_DEPTH_TEST );5.96 + glDisable( GL_SCISSOR_TEST );5.97 + glDisable( GL_CULL_FACE );5.98 +5.99 + float scale = ((float)video_height) / frame->height;5.100 + int rowstride = (frame->rowstride / bpp) - frame->width;5.101 +5.102 +5.103 + /*5.104 + glGenTextures( 1, &texid );5.105 + glBindTexture( GL_TEXTURE_2D, texid );5.106 + glTexImage2D( GL_TEXTURE_2D, 0, colour_formats[frame->colour_format].int_format,5.107 + frame->width, frame->height, 0, format, type, frame->data );5.108 + glBegin( GL_QUADS );5.109 + glTexCoord2i( 0, 1.0 );5.110 + glVertex2f( 0.0, 0.0 );5.111 + glTexCoord2i( 1.0, 1.0 );5.112 + glVertex2f( frame->width, 0.0 );5.113 + glTexCoord2i( 1.0, 0.0 );5.114 + glVertex2f( frame->width, frame->height );5.115 + glTexCoord2i( 0, 0.0 );5.116 + glVertex2f( 0.0, frame->height );5.117 + glEnd();5.118 + glDeleteTextures( 1, &texid );5.119 + */5.120 + glRasterPos2i( 0, 0 );5.121 + glPixelZoom( 1.0f, -scale );5.122 + glPixelStorei( GL_UNPACK_ROW_LENGTH, rowstride );5.123 + glDrawPixels( frame->width, frame->height, format, type,5.124 + frame->data );5.125 +5.126 + glFlush();5.127 + return TRUE;5.128 +}5.129 +5.130 +gboolean gl_display_blank( uint32_t colour )5.131 +{5.132 + glViewport( 0, 0, video_width, video_height );5.133 + glMatrixMode( GL_PROJECTION );5.134 + glLoadIdentity();5.135 + glOrtho( 0, video_width, video_height, 0, 0, -65535 );5.136 + glMatrixMode(GL_MODELVIEW);5.137 + glLoadIdentity();5.138 + glColor3b( (colour >> 16) & 0xFF, (colour >> 8) & 0xFF, colour & 0xFF );5.139 + glRecti(0,0, video_width, video_height );5.140 + glFlush();5.141 + return TRUE;5.142 +}5.143 +5.144 +/**5.145 + * Generic GL read_render_buffer. This function assumes that the caller5.146 + * has already set the appropriate glReadBuffer(); in other words, unless5.147 + * there's only one buffer this needs to be wrapped.5.148 + */5.149 +gboolean gl_read_render_buffer( render_buffer_t buffer, char *target )5.150 +{5.151 + if( buffer->address == -1 )5.152 + return FALSE;5.153 + glFinish();5.154 + GLenum type = colour_formats[buffer->colour_format].type;5.155 + GLenum format = colour_formats[buffer->colour_format].format;5.156 + int line_size = buffer->width * colour_formats[buffer->colour_format].bpp;5.157 + int size = line_size * buffer->height;5.158 + int rowstride = (buffer->rowstride / colour_formats[buffer->colour_format].bpp) - buffer->width;5.159 + // glPixelStorei( GL_PACK_ROW_LENGTH, rowstride );5.160 +5.161 + glReadPixels( 0, 0, buffer->width, buffer->height, format, type, target );5.162 + return TRUE;5.163 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00006.2 +++ b/src/drivers/gl_common.h Sun Feb 11 10:09:32 2007 +00006.3 @@ -0,0 +1,57 @@6.4 +/**6.5 + * $Id: gl_common.h,v 1.1 2007-02-11 10:09:32 nkeynes Exp $6.6 + *6.7 + * Parent for all X11 display drivers.6.8 + *6.9 + * Copyright (c) 2005 Nathan Keynes.6.10 + *6.11 + * This program is free software; you can redistribute it and/or modify6.12 + * it under the terms of the GNU General Public License as published by6.13 + * the Free Software Foundation; either version 2 of the License, or6.14 + * (at your option) any later version.6.15 + *6.16 + * This program is distributed in the hope that it will be useful,6.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of6.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the6.19 + * GNU General Public License for more details.6.20 + */6.21 +6.22 +#ifndef video_gl_common_H6.23 +#define video_gl_common_H6.24 +6.25 +#include "display.h"6.26 +6.27 +/**6.28 + * Test if a specific extension is supported. From opengl.org6.29 + * @param extension extension name to check for6.30 + * @return TRUE if supported, otherwise FALSE.6.31 + */6.32 +gboolean isGLExtensionSupported( const char *extension );6.33 +6.34 +gboolean hasRequiredGLExtensions();6.35 +6.36 +/**6.37 + * Generic GL routine to draw the given frame buffer in the display view.6.38 + */6.39 +gboolean gl_display_frame_buffer( frame_buffer_t frame );6.40 +6.41 +/**6.42 + * Generic GL routine to blank the display view with the specified colour.6.43 + */6.44 +gboolean gl_display_blank( uint32_t colour );6.45 +6.46 +6.47 +/**6.48 + * Generic GL read_render_buffer. This function assumes that the caller6.49 + * has already set the appropriate glReadBuffer(); in other words, unless6.50 + * there's only one buffer this needs to be wrapped.6.51 + */6.52 +gboolean gl_read_render_buffer( render_buffer_t buffer, char *target );6.53 +6.54 +6.55 +/****** FBO handling (gl_fbo.c) ******/6.56 +gboolean gl_fbo_is_supported();6.57 +void gl_fbo_shutdown();6.58 +void gl_fbo_init( display_driver_t driver );6.59 +6.60 +#endif /* !video_gl_common_H */
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00007.2 +++ b/src/drivers/gl_fbo.c Sun Feb 11 10:09:32 2007 +00007.3 @@ -0,0 +1,299 @@7.4 +/**7.5 + * $Id: gl_fbo.c,v 1.1 2007-02-11 10:09:32 nkeynes Exp $7.6 + *7.7 + * GL framebuffer-based driver shell. This requires the EXT_framebuffer_object7.8 + * extension, but is much nicer/faster/etc than pbuffers when it's available.7.9 + * This is (optionally) used indirectly by the top-level GLX driver.7.10 + *7.11 + * Strategy-wise, we maintain 2 framebuffers with up to 4 target colour7.12 + * buffers a piece. Effectively this reserves one fb for display output,7.13 + * and the other for texture output (each fb has a single size).7.14 + *7.15 + * Copyright (c) 2005 Nathan Keynes.7.16 + *7.17 + * This program is free software; you can redistribute it and/or modify7.18 + * it under the terms of the GNU General Public License as published by7.19 + * the Free Software Foundation; either version 2 of the License, or7.20 + * (at your option) any later version.7.21 + *7.22 + * This program is distributed in the hope that it will be useful,7.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of7.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the7.25 + * GNU General Public License for more details.7.26 + */7.27 +7.28 +#include <GL/gl.h>7.29 +#include "display.h"7.30 +7.31 +#define MAX_FRAMEBUFFERS 27.32 +#define MAX_TEXTURES_PER_FB 47.33 +7.34 +static render_buffer_t gl_fbo_create_render_buffer( uint32_t width, uint32_t height );7.35 +static void gl_fbo_destroy_render_buffer( render_buffer_t buffer );7.36 +static gboolean gl_fbo_set_render_target( render_buffer_t buffer );7.37 +static gboolean gl_fbo_display_render_buffer( render_buffer_t buffer );7.38 +static gboolean gl_fbo_display_frame_buffer( frame_buffer_t buffer );7.39 +static gboolean gl_fbo_display_blank( uint32_t colour );7.40 +static gboolean gl_fbo_read_render_buffer( render_buffer_t buffer, char *target );7.41 +7.42 +extern uint32_t video_width, video_height;7.43 +7.44 +/**7.45 + * Framebuffer info structure7.46 + */7.47 +struct gl_fbo_info {7.48 + GLuint fb_id;7.49 + GLuint depth_id;7.50 + GLuint stencil_id;7.51 + GLuint tex_ids[MAX_TEXTURES_PER_FB];7.52 + int width, height;7.53 +};7.54 +7.55 +static struct gl_fbo_info fbo[MAX_FRAMEBUFFERS];7.56 +const static int ATTACHMENT_POINTS[MAX_TEXTURES_PER_FB] = {7.57 + GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT,7.58 + GL_COLOR_ATTACHMENT2_EXT, GL_COLOR_ATTACHMENT3_EXT };7.59 +static int last_used_fbo;7.60 +7.61 +gboolean gl_fbo_is_supported()7.62 +{7.63 + return isGLExtensionSupported("GL_EXT_framebuffer_object");7.64 +}7.65 +7.66 +/**7.67 + * Construct the initial frame buffers and allocate ids for everything.7.68 + * The render handling driver methods are set to the fbo versions.7.69 + */7.70 +void gl_fbo_init( display_driver_t driver )7.71 +{7.72 + int i,j;7.73 + int fbids[MAX_FRAMEBUFFERS];7.74 + int rbids[MAX_FRAMEBUFFERS*2]; /* depth buffer, stencil buffer per fb */7.75 +7.76 + glGenFramebuffersEXT( MAX_FRAMEBUFFERS, &fbids );7.77 + glGenRenderbuffersEXT( MAX_FRAMEBUFFERS*2, &rbids );7.78 + for( i=0; i<MAX_FRAMEBUFFERS; i++ ) {7.79 + fbo[i].fb_id = fbids[i];7.80 + fbo[i].depth_id = rbids[i*2];7.81 + fbo[i].stencil_id = rbids[i*2+1];7.82 + fbo[i].width = -1;7.83 + fbo[i].height = -1;7.84 + for( j=0; j<MAX_TEXTURES_PER_FB; j++ ) {7.85 + fbo[i].tex_ids[j] = -1;7.86 + }7.87 + }7.88 + last_used_fbo = 0;7.89 +7.90 + driver->create_render_buffer = gl_fbo_create_render_buffer;7.91 + driver->destroy_render_buffer = gl_fbo_destroy_render_buffer;7.92 + driver->set_render_target = gl_fbo_set_render_target;7.93 + driver->display_render_buffer = gl_fbo_display_render_buffer;7.94 + driver->display_frame_buffer = gl_fbo_display_frame_buffer;7.95 + driver->display_blank = gl_fbo_display_blank;7.96 + driver->read_render_buffer = gl_fbo_read_render_buffer;7.97 +}7.98 +7.99 +void gl_fbo_shutdown()7.100 +{7.101 + int i;7.102 + glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );7.103 + for( i=0; i<MAX_FRAMEBUFFERS; i++ ) {7.104 + glDeleteFramebuffersEXT( 1, &fbo[i].fb_id );7.105 + glDeleteRenderbuffersEXT( 2, &fbo[i].depth_id );7.106 + }7.107 +}7.108 +7.109 +void gl_fbo_setup_framebuffer( int bufno, int width, int height )7.110 +{7.111 + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo[bufno].fb_id);7.112 + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo[bufno].depth_id);7.113 + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, width, height);7.114 + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,7.115 + GL_RENDERBUFFER_EXT, fbo[bufno].depth_id);7.116 + /* Stencil doesn't work on ATI, and we're not using it at the moment anyway, so...7.117 + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo[bufno].stencil_id);7.118 + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX, width, height);7.119 + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,7.120 + GL_RENDERBUFFER_EXT, fbo[bufno].stencil_id);7.121 + */7.122 + fbo[bufno].width = width;7.123 + fbo[bufno].height = height;7.124 +}7.125 +7.126 +int gl_fbo_get_framebuffer( int width, int height )7.127 +{7.128 + int bufno = -1, i;7.129 + /* find a compatible framebuffer context */7.130 + for( i=0; i<MAX_FRAMEBUFFERS; i++ ) {7.131 + if( fbo[i].width == -1 && bufno == -1 ) {7.132 + bufno = i;7.133 + } else if( fbo[i].width == width && fbo[i].height == height ) {7.134 + bufno = i;7.135 + break;7.136 + }7.137 + }7.138 + if( bufno == -1 ) {7.139 + bufno = last_used_fbo + 1;7.140 + if( bufno > MAX_FRAMEBUFFERS ) {7.141 + bufno = 0;7.142 + }7.143 + last_used_fbo = bufno;7.144 + }7.145 + if( fbo[bufno].width == width && fbo[bufno].height == height ) {7.146 + glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fbo[bufno].fb_id );7.147 + } else {7.148 + gl_fbo_setup_framebuffer( bufno, width, height );7.149 + }7.150 + return bufno;7.151 +}7.152 +7.153 +/**7.154 + * Attach a texture to the framebuffer. The texture must already be initialized7.155 + * to the correct dimensions etc.7.156 + */7.157 +static GLint gl_fbo_attach_texture( int fbo_no, GLint tex_id ) {7.158 + int attach = -1, i;7.159 + for( i=0; i<MAX_TEXTURES_PER_FB; i++ ) {7.160 + if( fbo[fbo_no].tex_ids[i] == tex_id ) {7.161 + glDrawBuffer(ATTACHMENT_POINTS[i]);7.162 + glReadBuffer(ATTACHMENT_POINTS[i]);7.163 + return ATTACHMENT_POINTS[i]; // already attached7.164 + } else if( fbo[fbo_no].tex_ids[i] == -1 && attach == -1 ) {7.165 + attach = i;7.166 + }7.167 + }7.168 + if( attach == -1 ) {7.169 + /* should never happen */7.170 + attach = 0;7.171 + }7.172 + fbo[fbo_no].tex_ids[attach] = tex_id;7.173 + glBindTexture( GL_TEXTURE_RECTANGLE_ARB, 0 ); // Ensure the output texture is unbound7.174 + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, ATTACHMENT_POINTS[attach],7.175 + GL_TEXTURE_RECTANGLE_ARB, tex_id, 0 );7.176 + /* Set draw/read buffers by default */7.177 + glDrawBuffer(ATTACHMENT_POINTS[attach]);7.178 + glReadBuffer(ATTACHMENT_POINTS[attach]);7.179 +7.180 +7.181 + GLint status = glGetError();7.182 + if( status != GL_NO_ERROR ) {7.183 + ERROR( "GL error setting render target (%x)!", status );7.184 + }7.185 + status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);7.186 + if( status != GL_FRAMEBUFFER_COMPLETE_EXT ) {7.187 + ERROR( "Framebuffer failure: %x", status );7.188 + exit(1);7.189 + }7.190 +7.191 + return ATTACHMENT_POINTS[attach];7.192 +}7.193 +7.194 +static render_buffer_t gl_fbo_create_render_buffer( uint32_t width, uint32_t height )7.195 +{7.196 + render_buffer_t buffer = calloc( sizeof(struct render_buffer), 1 );7.197 + buffer->width = width;7.198 + buffer->height = height;7.199 + glGenTextures( 1, &buffer->buf_id );7.200 + glBindTexture( GL_TEXTURE_RECTANGLE_ARB, buffer->buf_id );7.201 + glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP );7.202 + glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP );7.203 + glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST );7.204 + glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST );7.205 + glTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );7.206 + return buffer;7.207 +}7.208 +7.209 +static void gl_fbo_destroy_render_buffer( render_buffer_t buffer )7.210 +{7.211 + int i,j;7.212 + for( i=0; i<MAX_FRAMEBUFFERS; i++ ) {7.213 + for( j=0; j < MAX_TEXTURES_PER_FB; j++ ) {7.214 + if( fbo[i].tex_ids[j] == buffer->buf_id ) {7.215 + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, ATTACHMENT_POINTS[j],7.216 + GL_TEXTURE_RECTANGLE_ARB, GL_NONE, 0 );7.217 + fbo[i].tex_ids[j] = -1;7.218 + }7.219 + }7.220 + }7.221 +7.222 + glDeleteTextures( 1, &buffer->buf_id );7.223 + buffer->buf_id = 0;7.224 + free( buffer );7.225 +}7.226 +7.227 +static gboolean gl_fbo_set_render_target( render_buffer_t buffer )7.228 +{7.229 + glGetError();7.230 + int fb = gl_fbo_get_framebuffer( buffer->width, buffer->height );7.231 + GLint attach = gl_fbo_attach_texture( fb, buffer->buf_id );7.232 + /* setup the gl context */7.233 + glViewport( 0, 0, buffer->width, buffer->height );7.234 +7.235 + return TRUE;7.236 +}7.237 +7.238 +/**7.239 + * Render the texture holding the given buffer to the front window7.240 + * buffer.7.241 + */7.242 +static gboolean gl_fbo_display_render_buffer( render_buffer_t buffer )7.243 +{7.244 + glFinish();7.245 + glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); // real window7.246 + glViewport( 0, 0, video_width, video_height );7.247 + glEnable( GL_TEXTURE_RECTANGLE_ARB );7.248 + glBindTexture( GL_TEXTURE_RECTANGLE_ARB, buffer->buf_id );7.249 + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );7.250 + glDrawBuffer( GL_FRONT );7.251 + glReadBuffer( GL_FRONT );7.252 + glDisable( GL_ALPHA_TEST );7.253 + glDisable( GL_DEPTH_TEST );7.254 + glDisable( GL_SCISSOR_TEST );7.255 + glDisable( GL_CULL_FACE );7.256 +7.257 + glMatrixMode(GL_PROJECTION);7.258 + glLoadIdentity();7.259 + glOrtho( 0, buffer->width, buffer->height, 0, 0, -65535 );7.260 + glMatrixMode(GL_MODELVIEW);7.261 + glLoadIdentity();7.262 + glEnable( GL_BLEND );7.263 + glBlendFunc( GL_ONE, GL_ZERO );7.264 + glDisable( GL_DEPTH_TEST );7.265 + glBegin( GL_QUADS );7.266 + glTexCoord2i( 0, buffer->height );7.267 + glVertex2f( 0.0, 0.0 );7.268 + glTexCoord2i( buffer->width, buffer->height );7.269 + glVertex2f( buffer->width, 0.0 );7.270 + glTexCoord2i( buffer->width, 0 );7.271 + glVertex2f( buffer->width, buffer->height );7.272 + glTexCoord2i( 0, 0 );7.273 + glVertex2f( 0.0, buffer->height );7.274 + glEnd();7.275 + glDisable( GL_TEXTURE_RECTANGLE_ARB );7.276 + glFlush();7.277 + return TRUE;7.278 +}7.279 +7.280 +static gboolean gl_fbo_display_frame_buffer( frame_buffer_t buffer )7.281 +{7.282 + glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );7.283 + glDrawBuffer( GL_FRONT );7.284 + glReadBuffer( GL_FRONT );7.285 + return gl_display_frame_buffer( buffer );7.286 +}7.287 +7.288 +static gboolean gl_fbo_display_blank( uint32_t colour )7.289 +{7.290 + glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );7.291 + glDrawBuffer( GL_FRONT );7.292 + glReadBuffer( GL_FRONT );7.293 + return gl_display_blank( colour );7.294 +}7.295 +7.296 +static gboolean gl_fbo_read_render_buffer( render_buffer_t buffer, char *target )7.297 +{7.298 + int fb = gl_fbo_get_framebuffer( buffer->width, buffer->height );7.299 + GLint attach = gl_fbo_attach_texture( fb, buffer->buf_id );7.300 + return gl_read_render_buffer( buffer, target );7.301 +}7.302 +
8.1 --- a/src/drivers/video_gl.c Tue Feb 06 07:59:06 2007 +00008.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +00008.3 @@ -1,70 +0,0 @@8.4 -/**8.5 - * $Id: video_gl.c,v 1.2 2007-01-15 12:57:12 nkeynes Exp $8.6 - *8.7 - * Common GL code that doesn't depend on a specific implementation8.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 "dream.h"8.23 -#include "drivers/video_gl.h"8.24 -#include <GL/gl.h>8.25 -8.26 -char *required_extensions[] = { "GL_EXT_framebuffer_object", NULL };8.27 -8.28 -/**8.29 - * Test if a specific extension is supported. From opengl.org8.30 - * @param extension extension name to check for8.31 - * @return TRUE if supported, otherwise FALSE.8.32 - */8.33 -gboolean isGLExtensionSupported( const char *extension )8.34 -{8.35 - const GLubyte *extensions = NULL;8.36 - const GLubyte *start;8.37 - GLubyte *where, *terminator;8.38 -8.39 - /* Extension names should not have spaces. */8.40 - where = (GLubyte *) strchr(extension, ' ');8.41 - if (where || *extension == '\0')8.42 - return 0;8.43 - extensions = glGetString(GL_EXTENSIONS);8.44 - /* It takes a bit of care to be fool-proof about parsing the8.45 - OpenGL extensions string. Don't be fooled by sub-strings,8.46 - etc. */8.47 - start = extensions;8.48 - for (;;) {8.49 - where = (GLubyte *) strstr((const char *) start, extension);8.50 - if (!where)8.51 - break;8.52 - terminator = where + strlen(extension);8.53 - if (where == start || *(where - 1) == ' ')8.54 - if (*terminator == ' ' || *terminator == '\0')8.55 - return TRUE;8.56 - start = terminator;8.57 - }8.58 - return FALSE;8.59 -}8.60 -8.61 -gboolean hasRequiredGLExtensions( )8.62 -{8.63 - int i;8.64 - gboolean isOK = TRUE;8.65 -8.66 - for( i=0; required_extensions[i] != NULL; i++ ) {8.67 - if( !isGLExtensionSupported(required_extensions[i]) ) {8.68 - ERROR( "Required OpenGL extension not supported: %s", required_extensions[i] );8.69 - isOK = FALSE;8.70 - }8.71 - }8.72 - return isOK;8.73 -}
9.1 --- a/src/drivers/video_gl.h Tue Feb 06 07:59:06 2007 +00009.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +00009.3 @@ -1,32 +0,0 @@9.4 -/**9.5 - * $Id: video_gl.h,v 1.1 2007-01-14 02:55:06 nkeynes Exp $9.6 - *9.7 - * Parent for all X11 display drivers.9.8 - *9.9 - * Copyright (c) 2005 Nathan Keynes.9.10 - *9.11 - * This program is free software; you can redistribute it and/or modify9.12 - * it under the terms of the GNU General Public License as published by9.13 - * the Free Software Foundation; either version 2 of the License, or9.14 - * (at your option) any later version.9.15 - *9.16 - * This program is distributed in the hope that it will be useful,9.17 - * but WITHOUT ANY WARRANTY; without even the implied warranty of9.18 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9.19 - * GNU General Public License for more details.9.20 - */9.21 -9.22 -#ifndef video_gl_common_H9.23 -#define video_gl_common_H9.24 -9.25 -9.26 -/**9.27 - * Test if a specific extension is supported. From opengl.org9.28 - * @param extension extension name to check for9.29 - * @return TRUE if supported, otherwise FALSE.9.30 - */9.31 -gboolean isGLExtensionSupported( const char *extension );9.32 -9.33 -gboolean hasRequiredGLExtensions();9.34 -9.35 -#endif /* !video_gl_common_H */
10.1 --- a/src/drivers/video_gtk.c Tue Feb 06 07:59:06 2007 +000010.2 +++ b/src/drivers/video_gtk.c Sun Feb 11 10:09:32 2007 +000010.3 @@ -1,5 +1,5 @@10.4 /**10.5 - * $Id: video_gtk.c,v 1.9 2007-01-27 12:03:53 nkeynes Exp $10.6 + * $Id: video_gtk.c,v 1.10 2007-02-11 10:09:32 nkeynes Exp $10.7 *10.8 * The PC side of the video support (responsible for actually displaying /10.9 * rendering frames)10.10 @@ -29,25 +29,15 @@10.11 GtkWidget *video_area = NULL;10.12 uint32_t video_width = 640;10.13 uint32_t video_height = 480;10.14 -uint32_t video_frame_count = 0;10.16 +gboolean video_gtk_init();10.17 +void video_gtk_shutdown();10.18 uint16_t video_gtk_resolve_keysym( const gchar *keysym );10.19 -gboolean video_gtk_set_output_format( uint32_t width, uint32_t height,10.20 - int colour_format );10.21 -gboolean video_gtk_set_render_format( uint32_t width, uint32_t height,10.22 - int colour_format, gboolean texture );10.23 -gboolean video_gtk_display_frame( video_buffer_t frame );10.24 -gboolean video_gtk_blank( uint32_t rgb );10.26 -struct display_driver display_gtk_driver = { "gtk",10.27 - NULL,10.28 - NULL,10.29 - video_gtk_resolve_keysym,10.30 - video_gtk_set_output_format,10.31 - video_gtk_set_render_format,10.32 - video_gtk_display_frame,10.33 - video_gtk_blank,10.34 - video_glx_swap_buffers };10.35 +struct display_driver display_gtk_driver = { "gtk", video_gtk_init, NULL,10.36 + video_gtk_resolve_keysym,10.37 + NULL, NULL, NULL, NULL, NULL, NULL, NULL };10.38 +10.40 gboolean video_gtk_keydown_callback(GtkWidget *widget,10.41 GdkEventKey *event,10.42 @@ -71,115 +61,39 @@10.43 input_event_keyup( event->keyval );10.44 }10.46 -gboolean video_gtk_set_output_format( uint32_t width, uint32_t height,10.47 - int colour_format )10.48 +gboolean video_gtk_init()10.49 {10.50 - if( video_win == NULL ) {10.51 - video_win = GTK_WINDOW(gtk_window_new( GTK_WINDOW_TOPLEVEL ));10.52 - gtk_window_set_title( video_win, APP_NAME " - Emulation Window" );10.53 - gtk_window_set_policy( video_win, FALSE, FALSE, FALSE );10.54 - gtk_window_set_default_size( video_win, video_width, video_height );10.55 + video_win = GTK_WINDOW(gtk_window_new( GTK_WINDOW_TOPLEVEL ));10.56 + gtk_window_set_title( video_win, APP_NAME " - Emulation Window" );10.57 + gtk_window_set_policy( video_win, FALSE, FALSE, FALSE );10.59 - g_signal_connect( video_win, "key_press_event",10.60 - G_CALLBACK(video_gtk_keydown_callback), NULL );10.61 - g_signal_connect( video_win, "key_release_event",10.62 - G_CALLBACK(video_gtk_keyup_callback), NULL );10.63 - gtk_widget_add_events( GTK_WIDGET(video_win),10.64 - GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK |10.65 - GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK );10.66 - video_area = gtk_image_new();10.67 - gtk_widget_show( GTK_WIDGET(video_area) );10.68 - gtk_container_add( GTK_CONTAINER(video_win), GTK_WIDGET(video_area) );10.69 - gtk_widget_show( GTK_WIDGET(video_win) );10.70 - video_x11_set_display( gdk_x11_display_get_xdisplay( gtk_widget_get_display(video_area)),10.71 - gdk_x11_screen_get_xscreen( gtk_widget_get_screen(video_area)),10.72 - GDK_WINDOW_XWINDOW( GTK_WIDGET(video_win)->window ) );10.73 -10.74 - }10.75 + g_signal_connect( video_win, "key_press_event",10.76 + G_CALLBACK(video_gtk_keydown_callback), NULL );10.77 + g_signal_connect( video_win, "key_release_event",10.78 + G_CALLBACK(video_gtk_keyup_callback), NULL );10.79 + gtk_widget_add_events( GTK_WIDGET(video_win),10.80 + GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK |10.81 + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK );10.82 + video_area = gtk_image_new();10.83 + gtk_widget_show( GTK_WIDGET(video_area) );10.84 + gtk_container_add( GTK_CONTAINER(video_win), GTK_WIDGET(video_area) );10.85 + gtk_widget_show( GTK_WIDGET(video_win) );10.86 + video_img = gdk_image_new( GDK_IMAGE_FASTEST, gdk_visual_get_system(),10.87 + video_width, video_height );10.88 + gtk_image_set_from_image( GTK_IMAGE(video_area), video_img, NULL );10.89 +10.90 gtk_window_set_default_size( video_win, video_width, video_height );10.91 - video_img = gdk_image_new( GDK_IMAGE_FASTEST, gdk_visual_get_system(),10.92 - video_width, video_height );10.93 - gtk_image_set_from_image( GTK_IMAGE(video_area), video_img, NULL );10.94 - /* Note old image is auto de-refed */10.95 +10.96 + video_glx_init( gdk_x11_display_get_xdisplay( gtk_widget_get_display(GTK_WIDGET(video_win))),10.97 + gdk_x11_screen_get_xscreen( gtk_widget_get_screen(GTK_WIDGET(video_win))),10.98 + GDK_WINDOW_XWINDOW( GTK_WIDGET(video_win)->window ),10.99 + video_width, video_height, &display_gtk_driver );10.100 return TRUE;10.101 }10.103 +void video_gtk_shutdown()10.104 +{10.106 -/**10.107 - * Fill the entire frame with the specified colour (00RRGGBB)10.108 - */10.109 -gboolean video_gtk_blank( uint32_t colour )10.110 -{10.111 - video_glx_blank( video_width, video_height, colour );10.112 +10.113 }10.115 -gboolean video_gtk_display_frame( video_buffer_t frame )10.116 -{10.117 - uint32_t bytes_per_line, x, y;10.118 - char *src = frame->data;10.119 - char *dest = video_img->mem;10.120 -10.121 - return video_glx_display_frame( frame );10.122 -10.123 - switch( frame->colour_format ) {10.124 - case COLFMT_ARGB1555:10.125 - for( y=0; y < frame->vres; y++ ) {10.126 - uint16_t *p = (uint16_t *)src;10.127 - for( x=0; x < frame->hres; x++ ) {10.128 - uint16_t pixel = *p++;10.129 - *dest++ = (pixel & 0x1F) << 3;10.130 - *dest++ = (pixel & 0x3E0) >> 2;10.131 - *dest++ = (pixel & 0x7C00) >> 7;10.132 - *dest++ = 0;10.133 - }10.134 - src += frame->rowstride;10.135 - }10.136 - break;10.137 - case COLFMT_RGB565:10.138 - for( y=0; y < frame->vres; y++ ) {10.139 - uint16_t *p = (uint16_t *)src;10.140 - for( x=0; x < frame->hres; x++ ) {10.141 - uint16_t pixel = *p++;10.142 - *dest++ = (pixel & 0x1F) << 3;10.143 - *dest++ = (pixel & 0x7E0) >> 3;10.144 - *dest++ = (pixel & 0xF800) >> 8;10.145 - *dest++ = 0;10.146 - }10.147 - src += frame->rowstride;10.148 - }10.149 - break;10.150 - case COLFMT_RGB888:10.151 - for( y=0; y< frame->vres; y++ ) {10.152 - char *p = src;10.153 - for( x=0; x < frame->hres; x++ ) {10.154 - *dest++ = *p++;10.155 - *dest++ = *p++;10.156 - *dest++ = *p++;10.157 - *dest++ = 0;10.158 - }10.159 - src += frame->rowstride;10.160 - }10.161 - break;10.162 - case COLFMT_ARGB8888:10.163 - bytes_per_line = frame->hres << 2;10.164 - if( bytes_per_line == frame->rowstride ) {10.165 - /* A little bit faster */10.166 - memcpy( dest, src, bytes_per_line * frame->vres );10.167 - } else {10.168 - for( y=0; y< frame->vres; y++ ) {10.169 - memcpy( dest, src, bytes_per_line );10.170 - src += frame->rowstride;10.171 - dest += bytes_per_line;10.172 - }10.173 - }10.174 - break;10.175 - }10.176 - gtk_widget_queue_draw( video_area );10.177 - return TRUE;10.178 -}10.179 -10.180 -gboolean video_gtk_set_render_format( uint32_t width, uint32_t height,10.181 - int colour_format, gboolean texture )10.182 -{10.183 - return video_glx_set_render_format( 0, 0, width, height );10.184 -}
11.1 --- a/src/drivers/video_null.c Tue Feb 06 07:59:06 2007 +000011.2 +++ b/src/drivers/video_null.c Sun Feb 11 10:09:32 2007 +000011.3 @@ -1,5 +1,5 @@11.4 /**11.5 - * $Id: video_null.c,v 1.2 2006-05-15 08:28:52 nkeynes Exp $11.6 + * $Id: video_null.c,v 1.3 2007-02-11 10:09:32 nkeynes Exp $11.7 *11.8 * Null video output driver (ie no video output whatsoever)11.9 *11.10 @@ -18,24 +18,37 @@11.12 #include "display.h"11.14 -gboolean video_null_set_output_format( uint32_t hres, uint32_t vres,11.15 - int colour_format )11.16 +render_buffer_t video_null_create_render_buffer( uint32_t hres, uint32_t vres )11.17 +{11.18 + return NULL;11.19 +}11.20 +11.21 +void video_null_destroy_render_buffer( render_buffer_t buffer )11.22 {11.23 return TRUE;11.24 }11.26 -gboolean video_null_set_render_format( uint32_t hres, uint32_t vres,11.27 - int colour_format, gboolean tex )11.28 +gboolean video_null_set_render_target( render_buffer_t buffer )11.29 {11.30 return TRUE;11.31 }11.33 -gboolean video_null_display_frame( video_buffer_t buffer )11.34 +gboolean video_null_display_render_buffer( render_buffer_t buffer )11.35 {11.36 return TRUE;11.37 }11.39 -gboolean video_null_blank( uint32_t colour )11.40 +gboolean video_null_read_render_buffer( render_buffer_t buffer, char *target )11.41 +{11.42 + return TRUE;11.43 +}11.44 +11.45 +gboolean video_null_display_frame_buffer( frame_buffer_t buffer )11.46 +{11.47 + return TRUE;11.48 +}11.49 +11.50 +gboolean video_null_display_blank( uint32_t colour )11.51 {11.52 return TRUE;11.53 }11.54 @@ -46,10 +59,13 @@11.57 struct display_driver display_null_driver = { "null",11.58 - NULL,11.59 - NULL,11.60 - video_null_set_output_format,11.61 - video_null_set_render_format,11.62 - video_null_display_frame,11.63 - video_null_blank,11.64 - video_null_display_back_buffer };11.65 + NULL,11.66 + NULL,11.67 + NULL,11.68 + video_null_create_render_buffer,11.69 + video_null_destroy_render_buffer,11.70 + video_null_set_render_target,11.71 + video_null_display_render_buffer,11.72 + video_null_display_frame_buffer,11.73 + video_null_display_blank,11.74 + video_null_read_render_buffer };
12.1 --- a/src/drivers/video_x11.c Tue Feb 06 07:59:06 2007 +000012.2 +++ b/src/drivers/video_x11.c Sun Feb 11 10:09:32 2007 +000012.3 @@ -1,5 +1,5 @@12.4 /**12.5 - * $Id: video_x11.c,v 1.11 2007-01-27 12:03:53 nkeynes Exp $12.6 + * $Id: video_x11.c,v 1.12 2007-02-11 10:09:32 nkeynes Exp $12.7 *12.8 * Shared functions for all X11-based display drivers.12.9 *12.10 @@ -21,30 +21,46 @@12.11 #include "dream.h"12.12 #include "drivers/video_x11.h"12.14 +extern uint32_t video_width, video_height;12.15 +12.16 /**12.17 * General X11 parameters. The front-end driver is expected to set this up12.18 - * by calling video_x11_set_display after initializing itself.12.19 + * by calling video_glx_init after initializing itself.12.20 */12.21 -Display *video_x11_display = NULL;12.22 -Screen *video_x11_screen = NULL;12.23 -Window video_x11_window = 0;12.24 -extern uint32_t video_width, video_height;12.25 +static Display *video_x11_display = NULL;12.26 +static Screen *video_x11_screen = NULL;12.27 +static Window video_x11_window = 0;12.28 +12.29 /**12.30 * GLX parameters.12.31 */12.32 -GLXContext glx_context;12.33 -Window glx_window;12.34 -gboolean glx_open = FALSE;12.35 +static GLXContext glx_context;12.36 +static Window glx_window;12.37 +static XSetWindowAttributes win_attrs;12.39 -void video_x11_set_display( Display *display, Screen *screen, Window window )12.40 +gboolean video_glx_init( Display *display, Screen *screen, Window window,12.41 + int width, int height, display_driver_t driver )12.42 {12.43 video_x11_display = display;12.44 video_x11_screen = screen;12.45 video_x11_window = window;12.46 +12.47 + if( !video_glx_create_window(width,height) ) {12.48 + return FALSE;12.49 + }12.50 +12.51 + if( gl_fbo_is_supported() ) {12.52 + gl_fbo_init(driver);12.53 + return TRUE;12.54 + } else {12.55 + /* Pbuffers? */12.56 + ERROR( "Framebuffer objects not supported (required in this version)" );12.57 + video_glx_shutdown();12.58 + return FALSE;12.59 + }12.60 }12.62 -12.63 -gboolean video_glx_create_window( int x, int y, int width, int height )12.64 +gboolean video_glx_create_window( int width, int height )12.65 {12.66 int major, minor;12.67 const char *glxExts, *glxServer;12.68 @@ -56,7 +72,6 @@12.69 GLX_DOUBLEBUFFER,12.70 None };12.71 int screen = XScreenNumberOfScreen(video_x11_screen);12.72 - XSetWindowAttributes win_attrs;12.73 XVisualInfo *visual;12.75 if( glXQueryVersion( video_x11_display, &major, &minor ) == False ) {12.76 @@ -68,11 +83,6 @@12.77 return FALSE;12.78 }12.80 - glxExts = glXQueryExtensionsString( video_x11_display, screen );12.81 - glxServer = glXQueryServerString( video_x11_display, screen, GLX_VENDOR );12.82 - INFO( "GLX version %d.%d, %s. Supported exts: %s", major, minor,12.83 - glxServer, glxExts );12.84 -12.85 /* Find ourselves a nice visual */12.86 visual = glXChooseVisual( video_x11_display,12.87 screen,12.88 @@ -100,7 +110,7 @@12.89 RootWindowOfScreen(video_x11_screen),12.90 visual->visual, AllocNone );12.91 glx_window = XCreateWindow( video_x11_display, video_x11_window,12.92 - x, y, width, height, 0, visual->depth,12.93 + 0, 0, width, height, 0, visual->depth,12.94 InputOutput, visual->visual,12.95 CWColormap | CWEventMask,12.96 &win_attrs );12.97 @@ -123,11 +133,15 @@12.98 glXDestroyContext( video_x11_display, glx_context );12.99 return FALSE;12.100 }12.101 -12.102 - hasRequiredGLExtensions();12.103 - glx_open = TRUE;12.104 return TRUE;12.105 }12.106 +void video_glx_shutdown()12.107 +{12.108 + XDestroyWindow( video_x11_display, glx_window );12.109 + XFreeColormap( video_x11_display, win_attrs.colormap );12.110 + glXDestroyContext( video_x11_display, glx_context );12.111 +}12.112 +12.114 int video_glx_load_font( const gchar *font_name )12.115 {12.116 @@ -142,61 +156,8 @@12.117 }12.120 -12.121 -gboolean video_glx_set_render_format( int x, int y, int width, int height )12.122 -{12.123 - if( glx_open )12.124 - return TRUE;12.125 - return video_glx_create_window( x, y, width, height );12.126 -}12.127 -12.128 -gboolean video_glx_display_frame( video_buffer_t frame )12.129 -{12.130 - GLenum type = colour_formats[frame->colour_format].type;12.131 - GLenum format = colour_formats[frame->colour_format].format;12.132 - int bpp = colour_formats[frame->colour_format].bpp;12.133 -12.134 - glDrawBuffer( GL_FRONT );12.135 - glViewport( 0, 0, video_width, video_height );12.136 - glMatrixMode(GL_PROJECTION);12.137 - glLoadIdentity();12.138 - glOrtho( 0, frame->hres, frame->vres, 0, 0, -65535 );12.139 - glMatrixMode(GL_MODELVIEW);12.140 - glLoadIdentity();12.141 - glRasterPos2i( 0, 0 );12.142 - glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT );12.143 - float scale = 480.0 / frame->vres;12.144 - glPixelZoom( 1.0f, -scale );12.145 - int rowstride = (frame->rowstride / bpp) - frame->hres;12.146 - glPixelStorei( GL_PACK_ROW_LENGTH, rowstride );12.147 - glDrawPixels( frame->hres, frame->vres, format, type,12.148 - frame->data );12.149 - glPopClientAttrib();12.150 - glFlush();12.151 - return TRUE;12.152 -}12.153 -12.154 -gboolean video_glx_blank( int width, int height, uint32_t colour )12.155 -{12.156 - glDrawBuffer( GL_FRONT );12.157 - glViewport( 0, 0, width, height );12.158 - glMatrixMode( GL_PROJECTION );12.159 - glLoadIdentity();12.160 - glOrtho( 0, width, height, 0, 0, -65535 );12.161 - glMatrixMode(GL_MODELVIEW);12.162 - glLoadIdentity();12.163 - glColor3b( (colour >> 16) & 0xFF, (colour >> 8) & 0xFF, colour & 0xFF );12.164 - glRecti(0,0, width, height );12.165 - glFlush();12.166 - return TRUE;12.167 -}12.168 -12.169 void video_glx_swap_buffers( void )12.170 {12.171 glXSwapBuffers( video_x11_display, glx_window );12.172 }12.174 -void video_glx_create_pixmap( int width, int height )12.175 -{12.176 -12.177 -}
13.1 --- a/src/drivers/video_x11.h Tue Feb 06 07:59:06 2007 +000013.2 +++ b/src/drivers/video_x11.h Sun Feb 11 10:09:32 2007 +000013.3 @@ -1,5 +1,5 @@13.4 /**13.5 - * $Id: video_x11.h,v 1.3 2006-05-15 08:28:52 nkeynes Exp $13.6 + * $Id: video_x11.h,v 1.4 2007-02-11 10:09:32 nkeynes Exp $13.7 *13.8 * Parent for all X11 display drivers.13.9 *13.10 @@ -22,14 +22,7 @@13.11 #include "X11/Xlib.h"13.12 #include "display.h"13.14 -void video_x11_set_display( Display *display, Screen *screen, Window window );13.15 -13.16 -extern Display *video_x11_display;13.17 -extern Screen *video_x11_screen;13.18 -extern Window video_x11_window;13.19 -13.20 -13.21 -gboolean video_glx_set_render_format( int x, int y, int width, int height );13.22 -void video_glx_swap_buffers();13.23 +gboolean video_glx_init( Display *display, Screen *screen, Window window,13.24 + int width, int height, display_driver_t driver );13.26 #endif
14.1 --- a/src/pvr2/pvr2.c Tue Feb 06 07:59:06 2007 +000014.2 +++ b/src/pvr2/pvr2.c Sun Feb 11 10:09:32 2007 +000014.3 @@ -1,5 +1,5 @@14.4 /**14.5 - * $Id: pvr2.c,v 1.43 2007-01-28 11:36:00 nkeynes Exp $14.6 + * $Id: pvr2.c,v 1.44 2007-02-11 10:09:32 nkeynes Exp $14.7 *14.8 * PVR2 (Video) Core module implementation and MMIO registers.14.9 *14.10 @@ -30,6 +30,8 @@14.12 char *video_base;14.14 +#define MAX_RENDER_BUFFERS 414.15 +14.16 #define HPOS_PER_FRAME 014.17 #define HPOS_PER_LINECOUNT 114.19 @@ -40,11 +42,13 @@14.20 static int pvr2_load_state( FILE *f );14.21 static void pvr2_update_raster_posn( uint32_t nanosecs );14.22 static void pvr2_schedule_scanline_event( int eventid, int line, int minimum_lines, int line_time_ns );14.23 +static render_buffer_t pvr2_get_render_buffer( frame_buffer_t frame );14.24 +static render_buffer_t pvr2_next_render_buffer( );14.25 uint32_t pvr2_get_sync_status();14.27 void pvr2_display_frame( void );14.29 -int colour_format_bytes[] = { 2, 2, 2, 1, 3, 4, 1, 1 };14.30 +static int output_colour_formats[] = { COLFMT_ARGB1555, COLFMT_RGB565, COLFMT_RGB888, COLFMT_ARGB8888 };14.32 struct dreamcast_module pvr2_module = { "PVR2", pvr2_init, pvr2_reset, NULL,14.33 pvr2_run_slice, NULL,14.34 @@ -53,16 +57,6 @@14.36 display_driver_t display_driver = NULL;14.38 -struct video_timing {14.39 - int fields_per_second;14.40 - int total_lines;14.41 - int retrace_lines;14.42 - int line_time_ns;14.43 -};14.44 -14.45 -struct video_timing pal_timing = { 50, 625, 65, 31945 };14.46 -struct video_timing ntsc_timing= { 60, 525, 65, 31746 };14.47 -14.48 struct pvr2_state {14.49 uint32_t frame_count;14.50 uint32_t line_count;14.51 @@ -89,11 +83,10 @@14.52 uint32_t retrace_start_line;14.53 uint32_t retrace_end_line;14.54 gboolean interlaced;14.55 - struct video_timing timing;14.56 } pvr2_state;14.58 -struct video_buffer video_buffer[2];14.59 -int video_buffer_idx = 0;14.60 +render_buffer_t render_buffers[MAX_RENDER_BUFFERS];14.61 +int render_buffer_count = 0;14.63 /**14.64 * Event handler for the hpos callback14.65 @@ -127,6 +120,7 @@14.67 static void pvr2_init( void )14.68 {14.69 + int i;14.70 register_io_region( &mmio_region_PVR2 );14.71 register_io_region( &mmio_region_PVR2PAL );14.72 register_io_region( &mmio_region_PVR2TA );14.73 @@ -138,6 +132,10 @@14.74 pvr2_reset();14.75 pvr2_ta_reset();14.76 pvr2_state.save_next_render_filename = NULL;14.77 + for( i=0; i<MAX_RENDER_BUFFERS; i++ ) {14.78 + render_buffers[i] = NULL;14.79 + }14.80 + render_buffer_count = 0;14.81 }14.83 static void pvr2_reset( void )14.84 @@ -147,7 +145,6 @@14.85 pvr2_state.cycles_run = 0;14.86 pvr2_state.irq_vpos1 = 0;14.87 pvr2_state.irq_vpos2 = 0;14.88 - pvr2_state.timing = ntsc_timing;14.89 pvr2_state.dot_clock = PVR2_DOT_CLOCK;14.90 pvr2_state.back_porch_ns = 4000;14.91 pvr2_state.palette_changed = FALSE;14.92 @@ -155,10 +152,8 @@14.93 mmio_region_PVR2_write( DISP_SYNCTIME, 0x07D6A53F );14.94 mmio_region_PVR2_write( YUV_ADDR, 0 );14.95 mmio_region_PVR2_write( YUV_CFG, 0 );14.96 - video_buffer_idx = 0;14.98 pvr2_ta_init();14.99 - pvr2_render_init();14.100 texcache_flush();14.101 }14.103 @@ -241,82 +236,64 @@14.104 */14.105 void pvr2_display_frame( void )14.106 {14.107 - uint32_t display_addr;14.108 - int dispsize = MMIO_READ( PVR2, DISP_SIZE );14.109 int dispmode = MMIO_READ( PVR2, DISP_MODE );14.110 int vidcfg = MMIO_READ( PVR2, DISP_SYNCCFG );14.111 - int vid_stride = (((dispsize & DISPSIZE_MODULO) >> 20) - 1);14.112 - int vid_lpf = ((dispsize & DISPSIZE_LPF) >> 10) + 1;14.113 - int vid_ppl = ((dispsize & DISPSIZE_PPL)) + 1;14.114 gboolean bEnabled = (dispmode & DISPMODE_ENABLE) && (vidcfg & DISPCFG_VO ) ? TRUE : FALSE;14.115 - gboolean interlaced = (vidcfg & DISPCFG_I ? TRUE : FALSE);14.116 - video_buffer_t buffer = &video_buffer[video_buffer_idx];14.117 - video_buffer_idx = !video_buffer_idx;14.118 - video_buffer_t last = &video_buffer[video_buffer_idx];14.119 - buffer->rowstride = (vid_ppl + vid_stride) << 2;14.120 - buffer->data = video_base + MMIO_READ( PVR2, DISP_ADDR1 );14.121 - buffer->line_double = (dispmode & DISPMODE_LINEDOUBLE) ? TRUE : FALSE;14.122 - buffer->vres = vid_lpf;14.123 - if( interlaced ) {14.124 - if( vid_ppl == vid_stride ) { /* Magic deinterlace */14.125 - buffer->vres <<= 1;14.126 - buffer->rowstride = vid_ppl << 2;14.127 - display_addr = MMIO_READ( PVR2, DISP_ADDR1 );14.128 - } else {14.129 - /* Just display the field as is, folks. This is slightly tricky -14.130 - * we pick the field based on which frame is about to come through,14.131 - * which may not be the same as the odd_even_field.14.132 - */14.133 - gboolean oddfield = pvr2_state.odd_even_field;14.134 - if( pvr2_state.line_count >= pvr2_state.retrace_start_line ) {14.135 - oddfield = !oddfield;14.136 +14.137 + if( display_driver == NULL ) {14.138 + return; /* can't really do anything much */14.139 + } else if( !bEnabled ) {14.140 + /* Output disabled == black */14.141 + display_driver->display_blank( 0 );14.142 + } else if( MMIO_READ( PVR2, DISP_CFG2 ) & 0x08 ) {14.143 + /* Enabled but blanked - border colour */14.144 + uint32_t colour = MMIO_READ( PVR2, DISP_BORDER );14.145 + display_driver->display_blank( colour );14.146 + } else {14.147 + /* Real output - determine dimensions etc */14.148 + struct frame_buffer fbuf;14.149 + uint32_t dispsize = MMIO_READ( PVR2, DISP_SIZE );14.150 + int vid_stride = (((dispsize & DISPSIZE_MODULO) >> 20) - 1);14.151 + int vid_ppl = ((dispsize & DISPSIZE_PPL)) + 1;14.152 +14.153 + fbuf.colour_format = output_colour_formats[(dispmode & DISPMODE_COLFMT) >> 2];14.154 + fbuf.width = vid_ppl << 2 / colour_formats[fbuf.colour_format].bpp;14.155 + fbuf.height = ((dispsize & DISPSIZE_LPF) >> 10) + 1;14.156 + fbuf.size = vid_ppl << 2 * fbuf.height;14.157 + fbuf.rowstride = (vid_ppl + vid_stride) << 2;14.158 +14.159 + /* Determine the field to display, and deinterlace if possible */14.160 + if( pvr2_state.interlaced ) {14.161 + if( vid_ppl == vid_stride ) { /* Magic deinterlace */14.162 + fbuf.height = fbuf.height << 1;14.163 + fbuf.rowstride = vid_ppl << 2;14.164 + fbuf.address = MMIO_READ( PVR2, DISP_ADDR1 );14.165 + } else {14.166 + /* Just display the field as is, folks. This is slightly tricky -14.167 + * we pick the field based on which frame is about to come through,14.168 + * which may not be the same as the odd_even_field.14.169 + */14.170 + gboolean oddfield = pvr2_state.odd_even_field;14.171 + if( pvr2_state.line_count >= pvr2_state.retrace_start_line ) {14.172 + oddfield = !oddfield;14.173 + }14.174 + if( oddfield ) {14.175 + fbuf.address = MMIO_READ( PVR2, DISP_ADDR1 );14.176 + } else {14.177 + fbuf.address = MMIO_READ( PVR2, DISP_ADDR2 );14.178 + }14.179 }14.180 - if( oddfield ) {14.181 - display_addr = MMIO_READ( PVR2, DISP_ADDR1 );14.182 - } else {14.183 - display_addr = MMIO_READ( PVR2, DISP_ADDR2 );14.184 - }14.185 + } else {14.186 + fbuf.address = MMIO_READ( PVR2, DISP_ADDR1 );14.187 }14.188 - } else {14.189 - display_addr = MMIO_READ( PVR2, DISP_ADDR1 );14.190 - }14.191 - switch( (dispmode & DISPMODE_COLFMT) >> 2 ) {14.192 - case 0:14.193 - buffer->colour_format = COLFMT_ARGB1555;14.194 - buffer->hres = vid_ppl << 1;14.195 - break;14.196 - case 1:14.197 - buffer->colour_format = COLFMT_RGB565;14.198 - buffer->hres = vid_ppl << 1;14.199 - break;14.200 - case 2:14.201 - buffer->colour_format = COLFMT_RGB888;14.202 - buffer->hres = (vid_ppl << 2) / 3;14.203 - break;14.204 - case 3:14.205 - buffer->colour_format = COLFMT_ARGB8888;14.206 - buffer->hres = vid_ppl;14.207 - break;14.208 - }14.209 -14.210 - if( buffer->hres <=8 )14.211 - buffer->hres = 640;14.212 - if( buffer->vres <=8 )14.213 - buffer->vres = 480;14.214 - if( display_driver != NULL ) {14.215 - if( buffer->hres != last->hres ||14.216 - buffer->vres != last->vres ||14.217 - buffer->colour_format != last->colour_format) {14.218 - display_driver->set_display_format( buffer->hres, buffer->vres,14.219 - buffer->colour_format );14.220 - }14.221 - if( !bEnabled ) {14.222 - display_driver->display_blank_frame( 0 );14.223 - } else if( MMIO_READ( PVR2, DISP_CFG2 ) & 0x08 ) { /* Blanked */14.224 - uint32_t colour = MMIO_READ( PVR2, DISP_BORDER );14.225 - display_driver->display_blank_frame( colour );14.226 - } else if( !pvr2_render_display_frame( PVR2_RAM_BASE + display_addr ) ) {14.227 - display_driver->display_frame( buffer );14.228 + fbuf.address = (fbuf.address & 0x00FFFFFF) + PVR2_RAM_BASE;14.229 +14.230 + render_buffer_t rbuf = pvr2_get_render_buffer( &fbuf );14.231 + if( rbuf != NULL ) {14.232 + display_driver->display_render_buffer( rbuf );14.233 + } else {14.234 + fbuf.data = video_base + (fbuf.address&0x00FFFFFF);14.235 + display_driver->display_frame_buffer( &fbuf );14.236 }14.237 }14.238 }14.239 @@ -349,7 +326,9 @@14.240 g_free( pvr2_state.save_next_render_filename );14.241 pvr2_state.save_next_render_filename = NULL;14.242 }14.243 - pvr2_render_scene();14.244 + render_buffer_t buffer = pvr2_next_render_buffer();14.245 + pvr2_render_scene( buffer );14.246 + asic_event( EVENT_PVR_RENDER_DONE );14.247 break;14.248 case RENDER_POLYBASE:14.249 MMIO_WRITE( PVR2, reg, val&0x00F00000 );14.250 @@ -372,23 +351,11 @@14.251 case DISP_ADDR1:14.252 val &= 0x00FFFFFC;14.253 MMIO_WRITE( PVR2, reg, val );14.254 - /*14.255 pvr2_update_raster_posn(sh4r.slice_cycle);14.256 - fprintf( stderr, "Set Field 1 addr: %08X\n", val );14.257 - if( (pvr2_state.line_count >= pvr2_state.retrace_start_line && !pvr2_state.odd_even_field) ||14.258 - (pvr2_state.line_count < pvr2_state.retrace_end_line && pvr2_state.odd_even_field) ) {14.259 - pvr2_display_frame();14.260 - }14.261 - */14.262 break;14.263 case DISP_ADDR2:14.264 MMIO_WRITE( PVR2, reg, val&0x00FFFFFC );14.265 pvr2_update_raster_posn(sh4r.slice_cycle);14.266 - /*14.267 - if( (pvr2_state.line_count >= pvr2_state.retrace_start_line && pvr2_state.odd_even_field) ||14.268 - (pvr2_state.line_count < pvr2_state.retrace_end_line && !pvr2_state.odd_even_field) ) {14.269 - pvr2_display_frame();14.270 - }*/14.271 break;14.272 case DISP_SIZE:14.273 MMIO_WRITE( PVR2, reg, val&0x3FFFFFFF );14.274 @@ -722,3 +689,139 @@14.275 pvr2_ta_write( (char *)&val, sizeof(uint32_t) );14.276 }14.278 +/**14.279 + * Find the render buffer corresponding to the requested output frame14.280 + * (does not consider texture renders).14.281 + * @return the render_buffer if found, or null if no such buffer.14.282 + *14.283 + * Note: Currently does not consider "partial matches", ie partial14.284 + * frame overlap - it probably needs to do this.14.285 + */14.286 +render_buffer_t pvr2_get_render_buffer( frame_buffer_t frame )14.287 +{14.288 + int i;14.289 + for( i=0; i<render_buffer_count; i++ ) {14.290 + if( render_buffers[i] != NULL && render_buffers[i]->address == frame->address ) {14.291 + return render_buffers[i];14.292 + }14.293 + }14.294 + return NULL;14.295 +}14.296 +14.297 +/**14.298 + * Determine the next render buffer to write into. The order of preference is:14.299 + * 1. An existing buffer with the same address. (not flushed unless the new14.300 + * size is smaller than the old one).14.301 + * 2. An existing buffer with the same size chosen by LRU order. Old buffer14.302 + * is flushed to vram.14.303 + * 3. A new buffer if one can be created.14.304 + * 4. The current display buff14.305 + * Note: The current display field(s) will never be overwritten except as a last14.306 + * resort.14.307 + */14.308 +render_buffer_t pvr2_next_render_buffer()14.309 +{14.310 + render_buffer_t result = NULL;14.311 + uint32_t render_addr = MMIO_READ( PVR2, RENDER_ADDR1 );14.312 + uint32_t render_mode = MMIO_READ( PVR2, RENDER_MODE );14.313 + uint32_t render_scale = MMIO_READ( PVR2, RENDER_SCALER );14.314 + uint32_t render_stride = MMIO_READ( PVR2, RENDER_SIZE ) << 3;14.315 + gboolean render_to_tex;14.316 + if( render_addr & 0x01000000 ) { /* vram64 */14.317 + render_addr = (render_addr & 0x00FFFFFF) + PVR2_RAM_BASE_INT;14.318 + } else { /* vram32 */14.319 + render_addr = (render_addr & 0x00FFFFFF) + PVR2_RAM_BASE;14.320 + }14.321 +14.322 + int width, height, i;14.323 + int colour_format = pvr2_render_colour_format[render_mode&0x07];14.324 + pvr2_render_getsize( &width, &height );14.325 +14.326 + /* Check existing buffers for an available buffer */14.327 + for( i=0; i<render_buffer_count; i++ ) {14.328 + if( render_buffers[i]->width == width && render_buffers[i]->height == height ) {14.329 + /* needs to be the right dimensions */14.330 + if( render_buffers[i]->address == render_addr ) {14.331 + /* perfect */14.332 + result = render_buffers[i];14.333 + break;14.334 + } else if( render_buffers[i]->address == -1 && result == NULL ) {14.335 + result = render_buffers[i];14.336 + }14.337 + } else if( render_buffers[i]->address == render_addr ) {14.338 + /* right address, wrong size - if it's larger, flush it, otherwise14.339 + * nuke it quietly */14.340 + if( render_buffers[i]->width * render_buffers[i]->height >14.341 + width*height ) {14.342 + pvr2_render_buffer_copy_to_sh4( render_buffers[i] );14.343 + }14.344 + render_buffers[i]->address == -1;14.345 + }14.346 + }14.347 +14.348 + /* Nothing available - make one */14.349 + if( result == NULL ) {14.350 + if( render_buffer_count == MAX_RENDER_BUFFERS ) {14.351 + /* maximum buffers reached - need to throw one away */14.352 + uint32_t field1_addr = MMIO_READ( PVR2, DISP_ADDR1 );14.353 + uint32_t field2_addr = MMIO_READ( PVR2, DISP_ADDR2 );14.354 + for( i=0; i<render_buffer_count; i++ ) {14.355 + if( render_buffers[i]->address != field1_addr &&14.356 + render_buffers[i]->address != field2_addr ) {14.357 + /* Never throw away the current "front buffer(s)" */14.358 + result = render_buffers[i];14.359 + pvr2_render_buffer_copy_to_sh4( result );14.360 + if( result->width != width || result->height != height ) {14.361 + display_driver->destroy_render_buffer(render_buffers[i]);14.362 + result = display_driver->create_render_buffer(width,height);14.363 + render_buffers[i] = result;14.364 + }14.365 + break;14.366 + }14.367 + }14.368 + } else {14.369 + result = display_driver->create_render_buffer(width,height);14.370 + if( result != NULL ) {14.371 + render_buffers[render_buffer_count++] = result;14.372 + } else {14.373 + ERROR( "Failed to obtain a render buffer!" );14.374 + return NULL;14.375 + }14.376 + }14.377 + }14.378 +14.379 + /* Setup the buffer */14.380 + result->rowstride = render_stride;14.381 + result->colour_format = colour_format;14.382 + result->scale = render_scale;14.383 + result->size = width * height * colour_formats[colour_format].bpp;14.384 + result->address = render_addr;14.385 + result->flushed = FALSE;14.386 + return result;14.387 +}14.388 +14.389 +/**14.390 + * Invalidate any caching on the supplied address. Specifically, if it falls14.391 + * within any of the render buffers, flush the buffer back to PVR2 ram.14.392 + */14.393 +gboolean pvr2_render_buffer_invalidate( sh4addr_t address, gboolean isWrite )14.394 +{14.395 + int i;14.396 + address = address & 0x1FFFFFFF;14.397 + for( i=0; i<render_buffer_count; i++ ) {14.398 + uint32_t bufaddr = render_buffers[i]->address;14.399 + uint32_t size = render_buffers[i]->size;14.400 + if( bufaddr != -1 && bufaddr <= address &&14.401 + (bufaddr + render_buffers[i]->size) > address ) {14.402 + if( !render_buffers[i]->flushed ) {14.403 + pvr2_render_buffer_copy_to_sh4( render_buffers[i] );14.404 + render_buffers[i]->flushed = TRUE;14.405 + }14.406 + if( isWrite ) {14.407 + render_buffers[i]->address = -1; /* Invalid */14.408 + }14.409 + return TRUE; /* should never have overlapping buffers */14.410 + }14.411 + }14.412 + return FALSE;14.413 +}
15.1 --- a/src/pvr2/pvr2.h Tue Feb 06 07:59:06 2007 +000015.2 +++ b/src/pvr2/pvr2.h Sun Feb 11 10:09:32 2007 +000015.3 @@ -1,5 +1,5 @@15.4 /**15.5 - * $Id: pvr2.h,v 1.34 2007-02-05 08:51:34 nkeynes Exp $15.6 + * $Id: pvr2.h,v 1.35 2007-02-11 10:09:32 nkeynes Exp $15.7 *15.8 * PVR2 (video chip) functions and macros.15.9 *15.10 @@ -175,19 +175,6 @@15.11 */15.12 void pvr2_vram64_dump( sh4addr_t addr, uint32_t length, FILE *f );15.14 -15.15 -/**15.16 - * Describes a rendering buffer that's actually held in GL, for when we need15.17 - * to fetch the bits back to vram.15.18 - */15.19 -typedef struct pvr2_render_buffer {15.20 - sh4addr_t render_addr; /* The actual address rendered to in pvr ram */15.21 - uint32_t size; /* Length of rendering region in bytes */15.22 - int width, height;15.23 - int colour_format;15.24 - int scale;15.25 -} *pvr2_render_buffer_t;15.26 -15.27 /**15.28 * Flush the indicated render buffer back to PVR. Caller is responsible for15.29 * tracking whether there is actually anything in the buffer.15.30 @@ -197,25 +184,12 @@15.31 * @param backBuffer TRUE to flush the back buffer, FALSE for15.32 * the front buffer.15.33 */15.34 -void pvr2_render_buffer_copy_to_sh4( pvr2_render_buffer_t buffer,15.35 - gboolean backBuffer );15.36 -15.37 -/**15.38 - * Copy data from PVR ram into the GL render buffer.15.39 - *15.40 - * @param buffer A render buffer indicating the address to read from, and the15.41 - * format the data is in.15.42 - * @param backBuffer TRUE to write the back buffer, FALSE for15.43 - * the front buffer.15.44 - */15.45 -void pvr2_render_buffer_copy_from_sh4( pvr2_render_buffer_t buffer,15.46 - gboolean backBuffer );15.47 -15.48 +void pvr2_render_buffer_copy_to_sh4( render_buffer_t buffer );15.50 /**15.51 * Invalidate any caching on the supplied SH4 address15.52 */15.53 -gboolean pvr2_render_buffer_invalidate( sh4addr_t addr );15.54 +gboolean pvr2_render_buffer_invalidate( sh4addr_t addr, gboolean isWrite );15.57 /**************************** Tile Accelerator ***************************/15.58 @@ -250,15 +224,9 @@15.59 /********************************* Renderer ******************************/15.61 /**15.62 - * Initialize the rendering pipeline.15.63 - * @return TRUE on success, FALSE on failure.15.64 - */15.65 -gboolean pvr2_render_init( void );15.66 -15.67 -/**15.68 * Render the current scene stored in PVR ram to the GL back buffer.15.69 */15.70 -void pvr2_render_scene( void );15.71 +void pvr2_render_scene( render_buffer_t buffer );15.73 /**15.74 * Display the scene rendered to the supplied address.
16.1 --- a/src/pvr2/pvr2mem.c Tue Feb 06 07:59:06 2007 +000016.2 +++ b/src/pvr2/pvr2mem.c Sun Feb 11 10:09:32 2007 +000016.3 @@ -1,5 +1,5 @@16.4 /**16.5 - * $Id: pvr2mem.c,v 1.8 2007-01-27 06:21:35 nkeynes Exp $16.6 + * $Id: pvr2mem.c,v 1.9 2007-02-11 10:09:32 nkeynes Exp $16.7 *16.8 * PVR2 (Video) VRAM handling routines (mainly for the 64-bit region)16.9 *16.10 @@ -484,7 +484,7 @@16.11 ERROR( "Unable to write to dump file '%s' (%s)", filename, strerror(errno) );16.12 return;16.13 }16.14 - pvr2_vram64_read( tmp, addr, length );16.15 + pvr2_vram64_read( (char *)tmp, addr, length );16.16 fprintf( f, "%08X\n", addr );16.17 for( i =0; i<length>>2; i+=8 ) {16.18 for( j=i; j<i+8; j++ ) {16.19 @@ -516,77 +516,23 @@16.20 * @param backBuffer TRUE to flush the back buffer, FALSE for16.21 * the front buffer.16.22 */16.23 -void pvr2_render_buffer_copy_to_sh4( pvr2_render_buffer_t buffer,16.24 - gboolean backBuffer )16.25 +void pvr2_render_buffer_copy_to_sh4( render_buffer_t buffer )16.26 {16.27 - if( buffer->render_addr == -1 )16.28 - return;16.29 - GLenum type = colour_formats[buffer->colour_format].type;16.30 - GLenum format = colour_formats[buffer->colour_format].format;16.31 - int line_size = buffer->width * colour_formats[buffer->colour_format].bpp;16.32 - int size = line_size * buffer->height;16.33 -16.34 - if( backBuffer ) {16.35 - glFinish();16.36 - glReadBuffer( GL_BACK );16.37 - } else {16.38 - glReadBuffer( GL_FRONT );16.39 - }16.40 -16.41 - if( buffer->render_addr & 0xFF000000 == 0x04000000 ) {16.42 + if( buffer->address & 0xFF000000 == 0x04000000 ) {16.43 /* Interlaced buffer. Go the double copy... :( */16.44 - char target[size];16.45 - glReadPixels( 0, 0, buffer->width, buffer->height, format, type, target );16.46 - pvr2_vram64_write( buffer->render_addr, target, size );16.47 + char target[buffer->size];16.48 + display_driver->read_render_buffer( buffer, target );16.49 + pvr2_vram64_write( buffer->address, target, buffer->size );16.50 } else {16.51 /* Regular buffer */16.52 - char target[size];16.53 - glReadPixels( 0, 0, buffer->width, buffer->height, format, type, target );16.54 - if( (buffer->scale & 0xFFFF) == 0x0800 ) {16.55 - pvr2_vram_write_invert( buffer->render_addr, target, size, line_size, line_size << 1 );16.56 - } else {16.57 - pvr2_vram_write_invert( buffer->render_addr, target, size, line_size, line_size );16.58 - }16.59 + char target[buffer->size];16.60 + int line_size = buffer->width * colour_formats[buffer->colour_format].bpp;16.61 + display_driver->read_render_buffer( buffer, target );16.62 + if( (buffer->scale & 0xFFFF) == 0x0800 ) {16.63 + pvr2_vram_write_invert( buffer->address, target, buffer->size, line_size, line_size << 1 );16.64 + } else {16.65 + pvr2_vram_write_invert( buffer->address, target, buffer->size, line_size, line_size );16.66 + }16.67 }16.68 }16.70 -16.71 -/**16.72 - * Copy data from PVR ram into the GL render buffer.16.73 - *16.74 - * @param buffer A render buffer indicating the address to read from, and the16.75 - * format the data is in.16.76 - * @param backBuffer TRUE to write the back buffer, FALSE for16.77 - * the front buffer.16.78 - */16.79 -void pvr2_render_buffer_copy_from_sh4( pvr2_render_buffer_t buffer,16.80 - gboolean backBuffer )16.81 -{16.82 - if( buffer->render_addr == -1 )16.83 - return;16.84 -16.85 - GLenum type = colour_formats[buffer->colour_format].type;16.86 - GLenum format = colour_formats[buffer->colour_format].format;16.87 - int line_size = buffer->width * colour_formats[buffer->colour_format].bpp;16.88 - int size = line_size * buffer->height;16.89 -16.90 - if( backBuffer ) {16.91 - glDrawBuffer( GL_BACK );16.92 - } else {16.93 - glDrawBuffer( GL_FRONT );16.94 - }16.95 -16.96 - glRasterPos2i( 0, 0 );16.97 - if( buffer->render_addr & 0xFF000000 == 0x04000000 ) {16.98 - /* Interlaced buffer. Go the double copy... :( */16.99 - char target[size];16.100 - pvr2_vram64_read( target, buffer->render_addr, size );16.101 - glDrawPixels( buffer->width, buffer->height,16.102 - format, type, target );16.103 - } else {16.104 - /* Regular buffer - go direct */16.105 - char *target = mem_get_region( buffer->render_addr );16.106 - glDrawPixels( buffer->width, buffer->height,16.107 - format, type, target );16.108 - }16.109 -}
17.1 --- a/src/pvr2/rendcore.c Tue Feb 06 07:59:06 2007 +000017.2 +++ b/src/pvr2/rendcore.c Sun Feb 11 10:09:32 2007 +000017.3 @@ -1,5 +1,5 @@17.4 /**17.5 - * $Id: rendcore.c,v 1.18 2007-02-06 07:59:06 nkeynes Exp $17.6 + * $Id: rendcore.c,v 1.19 2007-02-11 10:09:32 nkeynes Exp $17.7 *17.8 * PVR2 renderer core.17.9 *17.10 @@ -159,7 +159,7 @@17.11 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );17.12 break;17.13 }17.14 - glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, POLY2_TEX_BLEND(poly2) );17.15 +17.16 if( POLY2_TEX_CLAMP_U(poly2) ) {17.17 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );17.18 } else {
18.1 --- a/src/pvr2/render.c Tue Feb 06 07:59:06 2007 +000018.2 +++ b/src/pvr2/render.c Sun Feb 11 10:09:32 2007 +000018.3 @@ -1,5 +1,5 @@18.4 /**18.5 - * $Id: render.c,v 1.23 2007-01-29 11:24:44 nkeynes Exp $18.6 + * $Id: render.c,v 1.24 2007-02-11 10:09:32 nkeynes Exp $18.7 *18.8 * PVR2 Renderer support. This part is primarily18.9 *18.10 @@ -20,20 +20,6 @@18.11 #include "asic.h"18.14 -struct pvr2_render_buffer front_buffer;18.15 -struct pvr2_render_buffer back_buffer;18.16 -18.17 -typedef struct pvr2_bgplane_packed {18.18 - uint32_t poly_cfg, poly_mode;18.19 - uint32_t texture_mode;18.20 - float x1, y1, z1;18.21 - uint32_t colour1;18.22 - float x2, y2, z2;18.23 - uint32_t colour2;18.24 - float x3, y3, z3;18.25 - uint32_t colour3;18.26 -} *pvr2_bgplane_packed_t;18.27 -18.28 int pvr2_render_font_list = -1;18.29 int pvr2_render_trace = 0;18.31 @@ -85,111 +71,27 @@18.33 }18.35 -18.36 -gboolean pvr2_render_init( void )18.37 -{18.38 - front_buffer.render_addr = -1;18.39 - back_buffer.render_addr = -1;18.40 -}18.41 -18.42 -/**18.43 - * Invalidate any caching on the supplied address. Specifically, if it falls18.44 - * within either the front buffer or back buffer, flush the buffer back to18.45 - * PVR2 ram (note that front buffer flush may be corrupt under some18.46 - * circumstances).18.47 - */18.48 -gboolean pvr2_render_buffer_invalidate( sh4addr_t address )18.49 -{18.50 - address = address & 0x1FFFFFFF;18.51 - if( front_buffer.render_addr != -1 &&18.52 - front_buffer.render_addr <= address &&18.53 - (front_buffer.render_addr + front_buffer.size) > address ) {18.54 - pvr2_render_buffer_copy_to_sh4( &front_buffer, FALSE );18.55 - front_buffer.render_addr = -1;18.56 - return TRUE;18.57 - } else if( back_buffer.render_addr != -1 &&18.58 - back_buffer.render_addr <= address &&18.59 - (back_buffer.render_addr + back_buffer.size) > address ) {18.60 - pvr2_render_buffer_copy_to_sh4( &back_buffer, TRUE );18.61 - back_buffer.render_addr = -1;18.62 - return TRUE;18.63 - }18.64 - return FALSE;18.65 -}18.66 -18.67 -/**18.68 - * Display a rendered frame if one is available.18.69 - * @param address An address in PVR ram (0500000 range).18.70 - * @return TRUE if a frame was available to be displayed, otherwise false.18.71 - */18.72 -gboolean pvr2_render_display_frame( uint32_t address )18.73 -{18.74 - if( front_buffer.render_addr == address ) {18.75 - /* Current front buffer is already displayed, so do nothing18.76 - * and tell the caller that all is well.18.77 - */18.78 - return TRUE;18.79 - }18.80 - if( back_buffer.render_addr == address ) {18.81 - /* The more useful case - back buffer is to be displayed. Swap18.82 - * the buffers18.83 - */18.84 - display_driver->display_back_buffer();18.85 - front_buffer = back_buffer;18.86 - back_buffer.render_addr = -1;18.87 - return TRUE;18.88 - }18.89 - return FALSE;18.90 -}18.91 -18.92 /**18.93 * Prepare the OpenGL context to receive instructions for a new frame.18.94 */18.95 -static void pvr2_render_prepare_context( sh4addr_t render_addr,18.96 - uint32_t width, uint32_t height,18.97 - uint32_t colour_format,18.98 - float bgplanez, float nearz,18.99 - gboolean texture_target )18.100 +static void pvr2_render_prepare_context( render_buffer_t buffer,18.101 + float bgplanez, float nearz )18.102 {18.103 /* Select and initialize the render context */18.104 - display_driver->set_render_format( width, height, colour_format, texture_target );18.105 + display_driver->set_render_target(buffer);18.107 if( pvr2_render_font_list == -1 ) {18.108 pvr2_render_font_list = video_glx_load_font( "-*-helvetica-*-r-normal--16-*-*-*-p-*-iso8859-1");18.109 }18.111 - if( back_buffer.render_addr != -1 &&18.112 - back_buffer.render_addr != render_addr ) {18.113 - /* There's a current back buffer, and we're rendering somewhere else -18.114 - * flush the back buffer back to vram and start a new back buffer18.115 - */18.116 - pvr2_render_buffer_copy_to_sh4( &back_buffer, TRUE );18.117 - }18.118 -18.119 - if( front_buffer.render_addr == render_addr ) {18.120 - /* In case we've been asked to render to the current front buffer -18.121 - * invalidate the front buffer and render to the back buffer, ensuring18.122 - * we swap at the next frame display.18.123 - */18.124 - front_buffer.render_addr = -1;18.125 - }18.126 - back_buffer.render_addr = render_addr;18.127 - back_buffer.width = width;18.128 - back_buffer.height = height;18.129 - back_buffer.colour_format = colour_format;18.130 - back_buffer.scale = MMIO_READ( PVR2, RENDER_SCALER );18.131 - back_buffer.size = width * height * colour_format_bytes[colour_format];18.132 -18.133 pvr2_check_palette_changed();18.135 /* Setup the display model */18.136 - glDrawBuffer(GL_BACK);18.137 glShadeModel(GL_SMOOTH);18.138 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);18.139 - glViewport( 0, 0, width, height );18.140 glMatrixMode(GL_PROJECTION);18.141 glLoadIdentity();18.142 - glOrtho( 0, width, height, 0, -bgplanez, -nearz );18.143 + glOrtho( 0, buffer->width, buffer->height, 0, -bgplanez, -nearz );18.144 glMatrixMode(GL_MODELVIEW);18.145 glLoadIdentity();18.146 glCullFace( GL_BACK );18.147 @@ -200,7 +102,6 @@18.148 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);18.149 glClearDepth(0);18.150 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );18.151 -18.152 }18.154 /**18.155 @@ -208,58 +109,32 @@18.156 * Note: this will probably need to be broken up eventually once timings are18.157 * determined.18.158 */18.159 -void pvr2_render_scene( )18.160 +void pvr2_render_scene( render_buffer_t buffer )18.161 {18.162 struct tile_descriptor *tile_desc =18.163 (struct tile_descriptor *)mem_get_region(PVR2_RAM_BASE + MMIO_READ( PVR2, RENDER_TILEBASE ));18.165 - uint32_t render_addr = MMIO_READ( PVR2, RENDER_ADDR1 );18.166 - gboolean render_to_tex;18.167 - if( render_addr & 0x01000000 ) {18.168 - render_addr = (render_addr & 0x00FFFFFF) + PVR2_RAM_BASE_INT;18.169 - /* Heuristic - if we're rendering to the interlaced region we're18.170 - * probably creating a texture rather than rendering actual output.18.171 - * We can optimise for this case a little18.172 - */18.173 - render_to_tex = TRUE;18.174 - WARN( "Render to texture not supported properly yet" );18.175 - } else {18.176 - render_addr = (render_addr & 0x00FFFFFF) + PVR2_RAM_BASE;18.177 - render_to_tex = FALSE;18.178 - }18.179 -18.180 float bgplanez = 1/MMIO_READF( PVR2, RENDER_FARCLIP );18.181 - uint32_t render_mode = MMIO_READ( PVR2, RENDER_MODE );18.182 - int width, height;18.183 - pvr2_render_getsize( &width, &height );18.184 - int colour_format = pvr2_render_colour_format[render_mode&0x07];18.185 - pvr2_render_prepare_context( render_addr, width, height, colour_format,18.186 - bgplanez, 0, render_to_tex );18.187 + pvr2_render_prepare_context( buffer, bgplanez, 0 );18.189 int clip_x = MMIO_READ( PVR2, RENDER_HCLIP ) & 0x03FF;18.190 int clip_y = MMIO_READ( PVR2, RENDER_VCLIP ) & 0x03FF;18.191 int clip_width = ((MMIO_READ( PVR2, RENDER_HCLIP ) >> 16) & 0x03FF) - clip_x + 1;18.192 int clip_height= ((MMIO_READ( PVR2, RENDER_VCLIP ) >> 16) & 0x03FF) - clip_y + 1;18.194 - /* Fog setup goes here */18.195 + /* Fog setup goes here? */18.197 /* Render the background plane */18.198 +18.199 uint32_t bgplane_mode = MMIO_READ(PVR2, RENDER_BGPLANE);18.200 uint32_t *display_list =18.201 (uint32_t *)mem_get_region(PVR2_RAM_BASE + MMIO_READ( PVR2, RENDER_POLYBASE ));18.203 uint32_t *bgplane = display_list + (((bgplane_mode & 0x00FFFFFF)) >> 3) ;18.204 - render_backplane( bgplane, width, height, bgplane_mode );18.205 -18.206 - pvr2_render_tilebuffer( width, height, clip_x, clip_y,18.207 + render_backplane( bgplane, buffer->width, buffer->height, bgplane_mode );18.208 +18.209 + pvr2_render_tilebuffer( buffer->width, buffer->height, clip_x, clip_y,18.210 clip_x + clip_width, clip_y + clip_height );18.211 -18.212 - /* Post-render cleanup and update */18.213 -18.214 - /* Add frame, fps, etc data */18.215 - //glDrawGrid( width, height );18.216 - glPrintf( 4, 16, "Frame %d", pvr2_get_frame_count() );18.217 - /* Generate end of render event */18.218 - asic_event( EVENT_PVR_RENDER_DONE );18.219 - DEBUG( "Rendered frame %d to %08X", pvr2_get_frame_count(), render_addr );18.220 +18.221 + DEBUG( "Rendered frame %d to %08X", pvr2_get_frame_count(), buffer->address );18.222 }
19.1 --- a/src/pvr2/texcache.c Tue Feb 06 07:59:06 2007 +000019.2 +++ b/src/pvr2/texcache.c Sun Feb 11 10:09:32 2007 +000019.3 @@ -1,5 +1,5 @@19.4 /**19.5 - * $Id: texcache.c,v 1.25 2007-02-05 08:52:59 nkeynes Exp $19.6 + * $Id: texcache.c,v 1.26 2007-02-11 10:09:32 nkeynes Exp $19.7 *19.8 * Texture cache. Responsible for maintaining a working set of OpenGL19.9 * textures.19.10 @@ -326,6 +326,7 @@19.11 struct vq_codebook codebook;19.12 GLint filter = GL_LINEAR;19.14 + glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );19.15 /* Decode the format parameters */19.16 switch( tex_format ) {19.17 case PVR2_TEX_FORMAT_IDX4:
.