From 01b71b8f7a77b3eb5ccc009342c1ebdc7b3dda80 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 2 Nov 2007 13:25:13 -0600 Subject: new file for st_framebuffer stuff --- src/mesa/state_tracker/st_framebuffer.c | 103 ++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 src/mesa/state_tracker/st_framebuffer.c (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c new file mode 100644 index 00000000000..3997681f360 --- /dev/null +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -0,0 +1,103 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "main/imports.h" +#include "main/context.h" +#include "st_public.h" +#include "st_context.h" + + +struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual ) +{ + struct st_framebuffer *stfb + = CALLOC_STRUCT(st_framebuffer); + if (stfb) { + +#if 0 + /* from intel driver... */ + + GLboolean swStencil = (mesaVis->stencilBits > 0 && + mesaVis->depthBits != 24); + GLenum rgbFormat = (mesaVis->redBits == 5 ? GL_RGB5 : GL_RGBA8); + + struct intel_framebuffer *intel_fb = CALLOC_STRUCT(intel_framebuffer); + if (!intel_fb) + return GL_FALSE; + + _mesa_initialize_framebuffer(&intel_fb->Base, mesaVis); + + /* + * XXX Create pipe_surfaces for front/back buffers, + * hand them to state tracker to create a framebuffer object. + */ + + { + /* fake frontbuffer */ + /* XXX allocation should only happen in the unusual case + it's actually needed */ + struct gl_renderbuffer *rb = st_new_renderbuffer_fb(rgbFormat); + _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT, rb); + } + + if (mesaVis->doubleBufferMode) { + struct gl_renderbuffer *rb = st_new_renderbuffer_fb(rgbFormat); + _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT, rb); + } + + if (mesaVis->depthBits == 24 && mesaVis->stencilBits == 8) { + /* combined depth/stencil buffer */ + struct gl_renderbuffer *depthStencilRb + = st_new_renderbuffer_fb(GL_DEPTH24_STENCIL8_EXT); + /* note: bind RB to two attachment points */ + _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH, depthStencilRb); + _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_STENCIL,depthStencilRb); + } + else if (mesaVis->depthBits == 16) { + /* just 16-bit depth buffer, no hw stencil */ + struct gl_renderbuffer *depthRb + = st_new_renderbuffer_fb(GL_DEPTH_COMPONENT16); + _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH, depthRb); + } + + + /* now add any/all software-based renderbuffers we may need */ + _mesa_add_soft_renderbuffers(&intel_fb->Base, + GL_FALSE, /* never sw color */ + GL_FALSE, /* never sw depth */ + swStencil, mesaVis->accumRedBits > 0, + GL_FALSE, /* never sw alpha */ + GL_FALSE /* never sw aux */ ); + driDrawPriv->driverPrivate = (void *) intel_fb; + +#endif + + } + return stfb; +} + + -- cgit v1.2.3 From e49efdab4a05d41f4b2f0bf989cdf036ab25879c Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 3 Nov 2007 09:39:12 -0600 Subject: st_create_framebuffer() working --- src/mesa/state_tracker/st_framebuffer.c | 47 ++++++++++++--------------------- 1 file changed, 17 insertions(+), 30 deletions(-) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 3997681f360..18669712c2f 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -28,8 +28,11 @@ #include "main/imports.h" #include "main/context.h" +#include "main/framebuffer.h" +#include "main/renderbuffer.h" #include "st_public.h" #include "st_context.h" +#include "st_cb_fbo.h" struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual ) @@ -37,64 +40,48 @@ struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual ) struct st_framebuffer *stfb = CALLOC_STRUCT(st_framebuffer); if (stfb) { + GLboolean swStencil = (visual->stencilBits > 0 && + visual->depthBits != 24); + GLenum rgbFormat = (visual->redBits == 5 ? GL_RGB5 : GL_RGBA8); -#if 0 - /* from intel driver... */ - - GLboolean swStencil = (mesaVis->stencilBits > 0 && - mesaVis->depthBits != 24); - GLenum rgbFormat = (mesaVis->redBits == 5 ? GL_RGB5 : GL_RGBA8); - - struct intel_framebuffer *intel_fb = CALLOC_STRUCT(intel_framebuffer); - if (!intel_fb) - return GL_FALSE; - - _mesa_initialize_framebuffer(&intel_fb->Base, mesaVis); - - /* - * XXX Create pipe_surfaces for front/back buffers, - * hand them to state tracker to create a framebuffer object. - */ + _mesa_initialize_framebuffer(&stfb->Base, visual); { /* fake frontbuffer */ /* XXX allocation should only happen in the unusual case it's actually needed */ struct gl_renderbuffer *rb = st_new_renderbuffer_fb(rgbFormat); - _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT, rb); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb); } - if (mesaVis->doubleBufferMode) { + if (visual->doubleBufferMode) { struct gl_renderbuffer *rb = st_new_renderbuffer_fb(rgbFormat); - _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT, rb); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb); } - if (mesaVis->depthBits == 24 && mesaVis->stencilBits == 8) { + if (visual->depthBits == 24 && visual->stencilBits == 8) { /* combined depth/stencil buffer */ struct gl_renderbuffer *depthStencilRb = st_new_renderbuffer_fb(GL_DEPTH24_STENCIL8_EXT); /* note: bind RB to two attachment points */ - _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH, depthStencilRb); - _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_STENCIL,depthStencilRb); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthStencilRb); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL,depthStencilRb); } - else if (mesaVis->depthBits == 16) { + else if (visual->depthBits == 16) { /* just 16-bit depth buffer, no hw stencil */ struct gl_renderbuffer *depthRb = st_new_renderbuffer_fb(GL_DEPTH_COMPONENT16); - _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH, depthRb); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); } /* now add any/all software-based renderbuffers we may need */ - _mesa_add_soft_renderbuffers(&intel_fb->Base, + _mesa_add_soft_renderbuffers(&stfb->Base, GL_FALSE, /* never sw color */ GL_FALSE, /* never sw depth */ - swStencil, mesaVis->accumRedBits > 0, + swStencil, visual->accumRedBits > 0, GL_FALSE, /* never sw alpha */ GL_FALSE /* never sw aux */ ); - driDrawPriv->driverPrivate = (void *) intel_fb; - -#endif } return stfb; -- cgit v1.2.3 From 3d14b2c01e12823877ae9270c7a79da65681f25c Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 3 Nov 2007 10:19:10 -0600 Subject: added st_resize_framebuffer() --- src/mesa/state_tracker/st_framebuffer.c | 14 ++++++++++++++ src/mesa/state_tracker/st_public.h | 3 +++ 2 files changed, 17 insertions(+) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 18669712c2f..99638c5d5ff 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -88,3 +88,17 @@ struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual ) } +void st_resize_framebuffer( struct st_framebuffer *stfb, + GLuint width, GLuint height ) +{ + if (stfb->Base.Width != width || stfb->Base.Height != height) { + GET_CURRENT_CONTEXT(ctx); + if (ctx) { + _mesa_resize_framebuffer(ctx, &stfb->Base, width, height); + + assert(stfb->Base.Width == width); + assert(stfb->Base.Height == height); + } + } +} + diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h index 94d1cdfde45..74a94d1abc6 100644 --- a/src/mesa/state_tracker/st_public.h +++ b/src/mesa/state_tracker/st_public.h @@ -48,6 +48,9 @@ void st_destroy_context2( struct st_context *st ); struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual ); +void st_resize_framebuffer( struct st_framebuffer *, + GLuint width, GLuint height ); + void st_make_current(struct st_context *st, struct st_framebuffer *draw, struct st_framebuffer *read); -- cgit v1.2.3 From ed8774e920706acb3445471833709dcaa691cb0c Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 3 Nov 2007 10:25:59 -0600 Subject: set stfb->Base.Initialized --- src/mesa/state_tracker/st_framebuffer.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 99638c5d5ff..f454499fd85 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -83,6 +83,9 @@ struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual ) GL_FALSE, /* never sw alpha */ GL_FALSE /* never sw aux */ ); + + stfb->Base.Initialized = GL_TRUE; + } return stfb; } -- cgit v1.2.3 From 44dfed15e0c5113d42d781e3937a2f619284454a Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 5 Nov 2007 08:41:45 -0700 Subject: added st_unreference_framebuffer() --- src/mesa/state_tracker/st_framebuffer.c | 7 +++++++ src/mesa/state_tracker/st_public.h | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index f454499fd85..54ae175e60e 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -105,3 +105,10 @@ void st_resize_framebuffer( struct st_framebuffer *stfb, } } + +void st_unreference_framebuffer( struct st_framebuffer **stfb ) +{ + _mesa_unreference_framebuffer((struct gl_framebuffer **) stfb); +} + + diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h index 74a94d1abc6..abdfcca80f1 100644 --- a/src/mesa/state_tracker/st_public.h +++ b/src/mesa/state_tracker/st_public.h @@ -48,9 +48,11 @@ void st_destroy_context2( struct st_context *st ); struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual ); -void st_resize_framebuffer( struct st_framebuffer *, +void st_resize_framebuffer( struct st_framebuffer *stfb, GLuint width, GLuint height ); +void st_unreference_framebuffer( struct st_framebuffer **stfb ); + void st_make_current(struct st_context *st, struct st_framebuffer *draw, struct st_framebuffer *read); -- cgit v1.2.3 From 616bf3556939d94852b1dfe73f92ef94b10782c4 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 5 Nov 2007 09:52:14 -0700 Subject: added st_get_framebuffer_surface() and ST_SURFACE_x tokens --- src/mesa/state_tracker/st_framebuffer.c | 20 ++++++++++++++++++++ src/mesa/state_tracker/st_public.h | 10 ++++++++++ 2 files changed, 30 insertions(+) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 54ae175e60e..326773c505e 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -112,3 +112,23 @@ void st_unreference_framebuffer( struct st_framebuffer **stfb ) } + +/** + * Return the pipe_surface for the given renderbuffer. + */ +struct pipe_surface * +st_get_framebuffer_surface(struct st_framebuffer *stfb, uint surfIndex) +{ + struct st_renderbuffer *strb; + + assert(surfIndex <= ST_SURFACE_BACK_RIGHT); + + /* sanity checks, ST tokens should match Mesa tokens */ + assert(ST_SURFACE_FRONT_LEFT == BUFFER_FRONT_LEFT); + assert(ST_SURFACE_BACK_RIGHT == BUFFER_BACK_RIGHT); + + strb = st_renderbuffer(stfb->Base.Attachment[surfIndex].Renderbuffer); + if (strb) + return strb->surface; + return NULL; +} diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h index 93239e66d63..acbf54d5ab3 100644 --- a/src/mesa/state_tracker/st_public.h +++ b/src/mesa/state_tracker/st_public.h @@ -30,6 +30,13 @@ #include "mtypes.h" + +#define ST_SURFACE_FRONT_LEFT 0 +#define ST_SURFACE_BACK_LEFT 1 +#define ST_SURFACE_FRONT_RIGHT 2 +#define ST_SURFACE_BACK_RIGHT 3 + + struct st_context; struct st_framebuffer; @@ -51,6 +58,9 @@ struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual ); void st_resize_framebuffer( struct st_framebuffer *stfb, GLuint width, GLuint height ); +struct pipe_surface *st_get_framebuffer_surface(struct st_framebuffer *stfb, + uint surfIndex); + void st_unreference_framebuffer( struct st_framebuffer **stfb ); void st_make_current(struct st_context *st, -- cgit v1.2.3 From 74866737db739bef8b7593d5060e4f80d91ff33a Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 5 Nov 2007 09:59:34 -0700 Subject: added st_notify_swapbuffers() --- src/mesa/state_tracker/st_framebuffer.c | 17 +++++++++++++++++ src/mesa/state_tracker/st_public.h | 2 ++ 2 files changed, 19 insertions(+) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 326773c505e..2e7687d9c91 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -132,3 +132,20 @@ st_get_framebuffer_surface(struct st_framebuffer *stfb, uint surfIndex) return strb->surface; return NULL; } + + +/** + * This function is to be called prior to SwapBuffers on the given + * framebuffer. It checks if the current context is bound to the framebuffer + * and flushes rendering if needed. + */ +void +st_notify_swapbuffers(struct st_framebuffer *stfb) +{ + GET_CURRENT_CONTEXT(ctx); + + if (ctx && ctx->DrawBuffer == &stfb->Base) { + st_flush(ctx->st); + } +} + diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h index acbf54d5ab3..8162ceeffab 100644 --- a/src/mesa/state_tracker/st_public.h +++ b/src/mesa/state_tracker/st_public.h @@ -71,4 +71,6 @@ void st_invalidate_state(GLcontext * ctx, GLuint new_state); void st_flush( struct st_context *st ); +void st_notify_swapbuffers(struct st_framebuffer *stfb); + #endif -- cgit v1.2.3 From e39f1b4cbea6d41dc09430bd3d811cb7bbdea5f8 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 5 Nov 2007 15:59:55 -0700 Subject: Update xlib driver to use newer state tracker context/framebuffer functions. XMesaContext has an st_context * which contains a mesa context. --- src/mesa/drivers/dri/intel_winsys/intel_screen.c | 2 +- src/mesa/pipe/xlib/fakeglx.c | 17 ++- src/mesa/pipe/xlib/xm_api.c | 160 ++++++++++------------- src/mesa/pipe/xlib/xmesaP.h | 31 ++++- src/mesa/state_tracker/st_context.c | 7 + src/mesa/state_tracker/st_context.h | 3 +- src/mesa/state_tracker/st_framebuffer.c | 84 ++++++------ src/mesa/state_tracker/st_public.h | 9 +- 8 files changed, 170 insertions(+), 143 deletions(-) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/drivers/dri/intel_winsys/intel_screen.c b/src/mesa/drivers/dri/intel_winsys/intel_screen.c index fa5c19ecd7f..899988340ef 100644 --- a/src/mesa/drivers/dri/intel_winsys/intel_screen.c +++ b/src/mesa/drivers/dri/intel_winsys/intel_screen.c @@ -283,7 +283,7 @@ intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, if (!intelfb) return GL_FALSE; - intelfb->stfb = st_create_framebuffer(mesaVis); + intelfb->stfb = st_create_framebuffer(mesaVis, GL_TRUE, (void*) intelfb); if (!intelfb->stfb) { free(intelfb); return GL_FALSE; diff --git a/src/mesa/pipe/xlib/fakeglx.c b/src/mesa/pipe/xlib/fakeglx.c index 7a170b4d3d1..d7e7b292d1f 100644 --- a/src/mesa/pipe/xlib/fakeglx.c +++ b/src/mesa/pipe/xlib/fakeglx.c @@ -51,6 +51,9 @@ #include "version.h" #include "xfonts.h" #include "xmesaP.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_public.h" + #ifdef __VMS #define _mesa_sprintf sprintf @@ -1617,7 +1620,7 @@ Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, if (MakeCurrent_PrevContext == src) { _mesa_Flush(); } - _mesa_copy_context( &(xm_src->mesa), &(xm_dst->mesa), (GLuint) mask ); + st_copy_context_state( xm_src->st, xm_dst->st, (GLuint) mask ); } @@ -2383,16 +2386,16 @@ Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, switch (attribute) { case GLX_WIDTH: - *value = xmbuf->mesa_buffer.Width; + *value = xmesa_buffer_width(xmbuf); break; case GLX_HEIGHT: - *value = xmbuf->mesa_buffer.Height; + *value = xmesa_buffer_width(xmbuf); break; case GLX_PRESERVED_CONTENTS: *value = True; break; case GLX_LARGEST_PBUFFER: - *value = xmbuf->mesa_buffer.Width * xmbuf->mesa_buffer.Height; + *value = xmesa_buffer_width(xmbuf) * xmesa_buffer_height(xmbuf); break; case GLX_FBCONFIG_ID: *value = xmbuf->xm_visual->visinfo->visualid; @@ -2762,13 +2765,13 @@ Fake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, un *value = True; break; case GLX_LARGEST_PBUFFER_SGIX: - *value = xmbuf->mesa_buffer.Width * xmbuf->mesa_buffer.Height; + *value = xmesa_buffer_width(xmbuf) * xmesa_buffer_height(xmbuf); break; case GLX_WIDTH_SGIX: - *value = xmbuf->mesa_buffer.Width; + *value = xmesa_buffer_width(xmbuf); break; case GLX_HEIGHT_SGIX: - *value = xmbuf->mesa_buffer.Height; + *value = xmesa_buffer_height(xmbuf); break; case GLX_EVENT_MASK_SGIX: *value = 0; /* XXX might be wrong */ diff --git a/src/mesa/pipe/xlib/xm_api.c b/src/mesa/pipe/xlib/xm_api.c index 7f144a5d32b..abd0b4f2926 100644 --- a/src/mesa/pipe/xlib/xm_api.c +++ b/src/mesa/pipe/xlib/xm_api.c @@ -300,6 +300,7 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type, XMesaVisual vis, XMesaColormap cmap) { XMesaBuffer b; + GLframebuffer *fb; ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER); @@ -312,8 +313,13 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type, b->type = type; b->cmap = cmap; - _mesa_initialize_framebuffer(&b->mesa_buffer, &vis->mesa_visual); - b->mesa_buffer.Delete = xmesa_delete_framebuffer; + /* + * Create framebuffer, but we'll plug in our own renderbuffers below. + */ + b->stfb = st_create_framebuffer(&vis->mesa_visual, GL_FALSE, (void *) b); + fb = &b->stfb->Base; + + fb->Delete = xmesa_delete_framebuffer; /* * XXX we want to create surfaces for pipe, not renderbuffers for Mesa. @@ -330,8 +336,7 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type, b->frontxrb->Parent = b; b->frontxrb->drawable = d; b->frontxrb->pixmap = (XMesaPixmap) d; - _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_FRONT_LEFT, - &b->frontxrb->St.Base); + _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &b->frontxrb->St.Base); #if 0 /* sketch... */ { struct pipe_surface *front_surf; @@ -339,8 +344,6 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type, } #endif - - /* * Back renderbuffer */ @@ -355,8 +358,7 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type, /* determine back buffer implementation */ b->db_mode = vis->ximage_flag ? BACK_XIMAGE : BACK_PIXMAP; - _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_BACK_LEFT, - &b->backxrb->St.Base); + _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &b->backxrb->St.Base); } /* @@ -379,34 +381,34 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type, /* combined depth/stencil */ struct gl_renderbuffer *rb = st_new_renderbuffer_fb(GL_DEPTH24_STENCIL8_EXT); - _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_DEPTH, rb); - _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_STENCIL, rb); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); + _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb); } else { if (vis->mesa_visual.depthBits > 0) { struct gl_renderbuffer *rb = st_new_renderbuffer_fb(GL_DEPTH_COMPONENT32); - _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_DEPTH, rb); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); } if (vis->mesa_visual.stencilBits > 0) { struct gl_renderbuffer *rb = st_new_renderbuffer_fb(GL_STENCIL_INDEX8_EXT); - _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_STENCIL, rb); + _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb); } } if (vis->mesa_visual.accumRedBits > 0) { struct gl_renderbuffer *rb = st_new_renderbuffer_fb(GL_RGBA16); - _mesa_add_renderbuffer(&b->mesa_buffer, BUFFER_ACCUM, rb); + _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb); } /* * Other renderbuffer (depth, stencil, etc) */ - _mesa_add_soft_renderbuffers(&b->mesa_buffer, + _mesa_add_soft_renderbuffers(fb, GL_FALSE, /* color */ GL_FALSE, /*vis->mesa_visual.haveDepthBuffer,*/ GL_FALSE, /* stencil */ @@ -454,7 +456,7 @@ xmesa_free_buffer(XMesaBuffer buffer) for (b = XMesaBufferList; b; b = b->Next) { if (b == buffer) { - struct gl_framebuffer *fb = &buffer->mesa_buffer; + struct gl_framebuffer *fb = &buffer->stfb->Base; /* unlink buffer from list */ if (prev) @@ -1112,11 +1114,12 @@ initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b, * Convert an RGBA color to a pixel value. */ unsigned long -xmesa_color_to_pixel(GLcontext *ctx, +xmesa_color_to_pixel(XMesaContext xmesa, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLuint pixelFormat) { - XMesaContext xmesa = XMESA_CONTEXT(ctx); + GLcontext *ctx = xmesa->st->ctx; + switch (pixelFormat) { case PF_Index: return 0; @@ -1444,9 +1447,11 @@ PUBLIC XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) { static GLboolean firstTime = GL_TRUE; + struct pipe_context *pipe; XMesaContext c; GLcontext *mesaCtx; - struct dd_function_table functions; + + (void) xmesa_init_driver_functions; if (firstTime) { _glthread_INIT_MUTEX(_xmesa_lock); @@ -1458,29 +1463,20 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) if (!c) return NULL; - mesaCtx = &(c->mesa); - - /* initialize with default driver functions, then plug in XMesa funcs */ -#if 0 - _mesa_init_driver_functions(&functions); -#else - memset(&functions, 0, sizeof(functions)); -#endif - xmesa_init_driver_functions(v, &functions); - st_init_driver_functions(&functions); + pipe = xmesa_create_softpipe( c ); - if (!_mesa_initialize_context(mesaCtx, &v->mesa_visual, - share_list ? &(share_list->mesa) : (GLcontext *) NULL, - &functions, (void *) c)) { - _mesa_free(c); - return NULL; - } + c->st = st_create_context2(pipe, &v->mesa_visual, + share_list ? share_list->st : NULL); + mesaCtx = c->st->ctx; + c->st->ctx->DriverCtx = c; +#if 00 _mesa_enable_sw_extensions(mesaCtx); _mesa_enable_1_3_extensions(mesaCtx); _mesa_enable_1_4_extensions(mesaCtx); _mesa_enable_1_5_extensions(mesaCtx); _mesa_enable_2_0_extensions(mesaCtx); +#endif #ifdef XFree86Server /* If we're running in the X server, do bounds checking to prevent @@ -1496,25 +1492,18 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) c->display = v->display; c->pixelformat = v->dithered_pf; /* Dithering is enabled by default */ - st_create_context( mesaCtx, - xmesa_create_softpipe( c ) ); - /* override these functions, as if the xlib driver were derived from * the softpipe driver. */ -#if 0 - mesaCtx->st->pipe->surface_alloc = xmesa_surface_alloc; - mesaCtx->st->pipe->is_format_supported = xmesa_is_format_supported; -#endif - mesaCtx->st->pipe->get_tile = xmesa_get_tile; - mesaCtx->st->pipe->put_tile = xmesa_put_tile; - mesaCtx->st->pipe->get_tile_rgba = xmesa_get_tile_rgba; - mesaCtx->st->pipe->put_tile_rgba = xmesa_put_tile_rgba; + pipe->get_tile = xmesa_get_tile; + pipe->put_tile = xmesa_put_tile; + pipe->get_tile_rgba = xmesa_get_tile_rgba; + pipe->put_tile_rgba = xmesa_put_tile_rgba; - mesaCtx->st->haveFramebufferRegions = GL_FALSE; + c->st->haveFramebufferRegions = GL_FALSE; /* special pipe->clear function */ - mesaCtx->st->pipe->clear = xmesa_clear; + pipe->clear = xmesa_clear; return c; } @@ -1524,10 +1513,8 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) PUBLIC void XMesaDestroyContext( XMesaContext c ) { - GLcontext *mesaCtx = &c->mesa; - - _mesa_free_context_data( mesaCtx ); - _mesa_free( c ); + st_destroy_context2(c->st); + _mesa_free(c); } @@ -1645,7 +1632,7 @@ XMesaCreatePixmapTextureBuffer(XMesaVisual v, XMesaPixmap p, /* get pixmap size, update framebuffer/renderbuffer dims */ xmesa_get_window_size(v->display, b, &width, &height); - _mesa_resize_framebuffer(NULL, &(b->mesa_buffer), width, height); + _mesa_resize_framebuffer(NULL, &(b->stfb->Base), width, height); if (target == 0) { /* examine dims */ @@ -1746,12 +1733,7 @@ xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer) { GLuint width, height; xmesa_get_window_size(drawBuffer->display, drawBuffer, &width, &height); - if (drawBuffer->mesa_buffer.Width != width || - drawBuffer->mesa_buffer.Height != height) { - GLcontext *ctx = xmctx ? &xmctx->mesa : NULL; - _mesa_resize_framebuffer(ctx, &(drawBuffer->mesa_buffer), width, height); - } - drawBuffer->mesa_buffer.Initialized = GL_TRUE; /* XXX TEMPORARY? */ + st_resize_framebuffer(drawBuffer->stfb, width, height); } @@ -1775,6 +1757,8 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer, if (!drawBuffer || !readBuffer) return GL_FALSE; /* must specify buffers! */ +#if 0 + /* XXX restore this optimization */ if (&(c->mesa) == _mesa_get_current_context() && c->mesa.DrawBuffer == &drawBuffer->mesa_buffer && c->mesa.ReadBuffer == &readBuffer->mesa_buffer @@ -1782,6 +1766,7 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer, /* same context and buffer, do nothing */ return GL_TRUE; } +#endif c->xm_buffer = drawBuffer; @@ -1794,16 +1779,15 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer, if (readBuffer != drawBuffer) xmesa_check_and_update_buffer_size(c, readBuffer); - _mesa_make_current(&(c->mesa), - &drawBuffer->mesa_buffer, - &readBuffer->mesa_buffer); + st_make_current(c->st, drawBuffer->stfb, readBuffer->stfb); +#if 0 if (c->xm_visual->mesa_visual.rgbMode) { /* * Must recompute and set these pixel values because colormap * can be different for different windows. */ - c->clearpixel = xmesa_color_to_pixel( &c->mesa, + c->clearpixel = xmesa_color_to_pixel( c, c->clearcolor[0], c->clearcolor[1], c->clearcolor[2], @@ -1811,13 +1795,14 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer, c->xm_visual->undithered_pf); XMesaSetForeground(c->display, drawBuffer->cleargc, c->clearpixel); } +#endif /* Solution to Stephane Rehel's problem with glXReleaseBuffersMESA(): */ drawBuffer->wasCurrent = GL_TRUE; } else { /* Detach */ - _mesa_make_current( NULL, NULL, NULL ); + st_make_current( NULL, NULL, NULL ); } return GL_TRUE; } @@ -1925,8 +1910,6 @@ GLboolean XMesaSetFXmode( GLint mode ) PUBLIC void XMesaSwapBuffers( XMesaBuffer b ) { - GET_CURRENT_CONTEXT(ctx); - if (!b->backxrb) { /* single buffered */ return; @@ -1935,8 +1918,7 @@ void XMesaSwapBuffers( XMesaBuffer b ) /* If we're swapping the buffer associated with the current context * we have to flush any pending rendering commands first. */ - if (ctx && ctx->DrawBuffer == &(b->mesa_buffer)) - _mesa_notifySwapBuffers(ctx); + st_notify_swapbuffers(b->stfb); if (b->db_mode) { if (b->backxrb->ximage) { @@ -1947,7 +1929,7 @@ void XMesaSwapBuffers( XMesaBuffer b ) XShmPutImage( b->xm_visual->display, b->frontxrb->drawable, b->swapgc, b->backxrb->ximage, 0, 0, - 0, 0, b->mesa_buffer.Width, b->mesa_buffer.Height, + 0, 0, xmesa_buffer_width(b), xmesa_buffer_height(b), False ); /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/ } @@ -1958,7 +1940,8 @@ void XMesaSwapBuffers( XMesaBuffer b ) XMesaPutImage( b->xm_visual->display, b->frontxrb->drawable, b->swapgc, b->backxrb->ximage, 0, 0, - 0, 0, b->mesa_buffer.Width, b->mesa_buffer.Height ); + 0, 0, + xmesa_buffer_width(b), xmesa_buffer_height(b)); /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/ } } @@ -1969,14 +1952,16 @@ void XMesaSwapBuffers( XMesaBuffer b ) b->backxrb->pixmap, /* source drawable */ b->frontxrb->drawable, /* dest. drawable */ b->swapgc, - 0, 0, b->mesa_buffer.Width, b->mesa_buffer.Height, + 0, 0, xmesa_buffer_width(b), xmesa_buffer_height(b), 0, 0 /* dest region */ ); /*_glthread_UNLOCK_MUTEX(_xmesa_lock);*/ } - if (b->swAlpha) - _mesa_copy_soft_alpha_renderbuffers(ctx, &b->mesa_buffer); + if (b->swAlpha) { + GET_CURRENT_CONTEXT(ctx); + _mesa_copy_soft_alpha_renderbuffers(ctx, &b->stfb->Base); + } } #if !defined(XFree86Server) XSync( b->xm_visual->display, False ); @@ -1990,21 +1975,18 @@ void XMesaSwapBuffers( XMesaBuffer b ) */ void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height ) { - GET_CURRENT_CONTEXT(ctx); - - /* If we're swapping the buffer associated with the current context - * we have to flush any pending rendering commands first. - */ - if (ctx && ctx->DrawBuffer == &(b->mesa_buffer)) - _mesa_notifySwapBuffers(ctx); - if (!b->backxrb) { /* single buffered */ return; } + /* If we're swapping the buffer associated with the current context + * we have to flush any pending rendering commands first. + */ + st_notify_swapbuffers(b->stfb); + if (b->db_mode) { - int yTop = b->mesa_buffer.Height - y - height; + int yTop = xmesa_buffer_height(b) - y - height; if (b->backxrb->ximage) { /* Copy Ximage from host's memory to server's window */ #if defined(USE_XSHM) && !defined(XFree86Server) @@ -2082,7 +2064,7 @@ GLboolean XMesaGetDepthBuffer( XMesaBuffer b, GLint *width, GLint *height, GLint *bytesPerValue, void **buffer ) { struct gl_renderbuffer *rb - = b->mesa_buffer.Attachment[BUFFER_DEPTH].Renderbuffer; + = b->stfb->Base.Attachment[BUFFER_DEPTH].Renderbuffer; if (!rb || !rb->Data) { *width = 0; *height = 0; @@ -2091,9 +2073,9 @@ GLboolean XMesaGetDepthBuffer( XMesaBuffer b, GLint *width, GLint *height, return GL_FALSE; } else { - *width = b->mesa_buffer.Width; - *height = b->mesa_buffer.Height; - *bytesPerValue = b->mesa_buffer.Visual.depthBits <= 16 + *width = xmesa_buffer_width(b); + *height = xmesa_buffer_height(b); + *bytesPerValue = b->stfb->Base.Visual.depthBits <= 16 ? sizeof(GLushort) : sizeof(GLuint); *buffer = rb->Data; return GL_TRUE; @@ -2103,11 +2085,11 @@ GLboolean XMesaGetDepthBuffer( XMesaBuffer b, GLint *width, GLint *height, void XMesaFlush( XMesaContext c ) { - if (c && c->xm_visual) { + if (c && c->display) { #ifdef XFree86Server /* NOT_NEEDED */ #else - XSync( c->xm_visual->display, False ); + XSync( c->display, False ); #endif } } @@ -2185,7 +2167,7 @@ unsigned long XMesaDitherColor( XMesaContext xmesa, GLint x, GLint y, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ) { - GLcontext *ctx = &xmesa->mesa; + GLcontext *ctx = xmesa->st->ctx; GLint r = (GLint) (red * 255.0F); GLint g = (GLint) (green * 255.0F); GLint b = (GLint) (blue * 255.0F); @@ -2311,7 +2293,7 @@ XMesaBindTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer, if (drawable->TextureFormat == GLX_TEXTURE_FORMAT_NONE_EXT) return; /* BadMatch error */ - rb = drawable->mesa_buffer.Attachment[b].Renderbuffer; + rb = drawable->stfb->Base.Attachment[b].Renderbuffer; if (!rb) { /* invalid buffer */ return; diff --git a/src/mesa/pipe/xlib/xmesaP.h b/src/mesa/pipe/xlib/xmesaP.h index 506db859bbf..f1ca2a8fe80 100644 --- a/src/mesa/pipe/xlib/xmesaP.h +++ b/src/mesa/pipe/xlib/xmesaP.h @@ -33,6 +33,8 @@ #include "xm_image.h" #endif #include "state_tracker/st_cb_fbo.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_public.h" #include "pipe/softpipe/sp_context.h" #include "pipe/softpipe/sp_surface.h" @@ -116,7 +118,8 @@ struct xmesa_visual { * Basically corresponds to a GLXContext. */ struct xmesa_context { - GLcontext mesa; /* the core library context (containment) */ + struct st_context *st; + XMesaVisual xm_visual; /* Describes the buffers */ XMesaBuffer xm_buffer; /* current span/point/line/triangle buffer */ @@ -187,8 +190,8 @@ struct xmesa_renderbuffer * Basically corresponds to a GLXDrawable. */ struct xmesa_buffer { - GLframebuffer mesa_buffer; /* depth, stencil, accum, etc buffers */ - /* This MUST BE FIRST! */ + struct st_framebuffer *stfb; + GLboolean wasCurrent; /* was ever the current buffer? */ XMesaVisual xm_visual; /* the X/Mesa visual */ @@ -458,7 +461,7 @@ extern XMesaBuffer xmesa_find_buffer(XMesaDisplay *dpy, XMesaColormap cmap, XMesaBuffer notThis); extern unsigned long -xmesa_color_to_pixel( GLcontext *ctx, +xmesa_color_to_pixel( XMesaContext xmesa, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLuint pixelFormat ); @@ -492,7 +495,7 @@ xmesa_renderbuffer(struct gl_renderbuffer *rb) static INLINE XMesaContext XMESA_CONTEXT(GLcontext *ctx) { - return (XMesaContext) ctx; + return (XMesaContext) ctx->DriverCtx; } @@ -502,9 +505,10 @@ XMESA_CONTEXT(GLcontext *ctx) * XXX should use inlined function for better type safety. */ static INLINE XMesaBuffer -XMESA_BUFFER(GLframebuffer *b) +XMESA_BUFFER(GLframebuffer *fb) { - return (XMesaBuffer) b; + struct st_framebuffer *stfb = (struct st_framebuffer *) fb; + return (XMesaBuffer) st_framebuffer_private(stfb); } @@ -564,4 +568,17 @@ xmesa_put_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps, extern struct pipe_surface * xmesa_create_front_surface(XMesaVisual vis, Window win); +static INLINE GLuint +xmesa_buffer_width(XMesaBuffer b) +{ + return b->stfb->Base.Width; +} + +static INLINE GLuint +xmesa_buffer_height(XMesaBuffer b) +{ + return b->stfb->Base.Height; +} + + #endif diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index a8cc618d770..138f18aa99b 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -174,6 +174,13 @@ void st_make_current(struct st_context *st, } +void st_copy_context_state(struct st_context *dst, + struct st_context *src, + uint mask) +{ + _mesa_copy_context(dst->ctx, src->ctx, mask); +} + void st_init_driver_functions(struct dd_function_table *functions) { diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 9b232827f4a..30407768b95 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -168,12 +168,13 @@ static INLINE struct st_context *st_context(GLcontext *ctx) /** - * Wrapper for GLframebuffer, nothing extra for now. + * Wrapper for GLframebuffer. * This is an opaque type to the outside world. */ struct st_framebuffer { GLframebuffer Base; + void *Private; }; diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 2e7687d9c91..ec120ba39ab 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -35,7 +35,9 @@ #include "st_cb_fbo.h" -struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual ) +struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual, + boolean createRenderbuffers, + void *private) { struct st_framebuffer *stfb = CALLOC_STRUCT(st_framebuffer); @@ -46,46 +48,48 @@ struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual ) _mesa_initialize_framebuffer(&stfb->Base, visual); - { - /* fake frontbuffer */ - /* XXX allocation should only happen in the unusual case - it's actually needed */ - struct gl_renderbuffer *rb = st_new_renderbuffer_fb(rgbFormat); - _mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb); + if (createRenderbuffers) { + { + /* fake frontbuffer */ + /* XXX allocation should only happen in the unusual case + it's actually needed */ + struct gl_renderbuffer *rb = st_new_renderbuffer_fb(rgbFormat); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb); + } + + if (visual->doubleBufferMode) { + struct gl_renderbuffer *rb = st_new_renderbuffer_fb(rgbFormat); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb); + } + + if (visual->depthBits == 24 && visual->stencilBits == 8) { + /* combined depth/stencil buffer */ + struct gl_renderbuffer *depthStencilRb + = st_new_renderbuffer_fb(GL_DEPTH24_STENCIL8_EXT); + /* note: bind RB to two attachment points */ + _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthStencilRb); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL,depthStencilRb); + } + else if (visual->depthBits == 16) { + /* just 16-bit depth buffer, no hw stencil */ + struct gl_renderbuffer *depthRb + = st_new_renderbuffer_fb(GL_DEPTH_COMPONENT16); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); + } + + + /* now add any/all software-based renderbuffers we may need */ + _mesa_add_soft_renderbuffers(&stfb->Base, + GL_FALSE, /* never sw color */ + GL_FALSE, /* never sw depth */ + swStencil, visual->accumRedBits > 0, + GL_FALSE, /* never sw alpha */ + GL_FALSE /* never sw aux */ ); } - if (visual->doubleBufferMode) { - struct gl_renderbuffer *rb = st_new_renderbuffer_fb(rgbFormat); - _mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb); - } - - if (visual->depthBits == 24 && visual->stencilBits == 8) { - /* combined depth/stencil buffer */ - struct gl_renderbuffer *depthStencilRb - = st_new_renderbuffer_fb(GL_DEPTH24_STENCIL8_EXT); - /* note: bind RB to two attachment points */ - _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthStencilRb); - _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL,depthStencilRb); - } - else if (visual->depthBits == 16) { - /* just 16-bit depth buffer, no hw stencil */ - struct gl_renderbuffer *depthRb - = st_new_renderbuffer_fb(GL_DEPTH_COMPONENT16); - _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); - } - - - /* now add any/all software-based renderbuffers we may need */ - _mesa_add_soft_renderbuffers(&stfb->Base, - GL_FALSE, /* never sw color */ - GL_FALSE, /* never sw depth */ - swStencil, visual->accumRedBits > 0, - GL_FALSE, /* never sw alpha */ - GL_FALSE /* never sw aux */ ); - - stfb->Base.Initialized = GL_TRUE; + stfb->Private = private; } return stfb; } @@ -149,3 +153,9 @@ st_notify_swapbuffers(struct st_framebuffer *stfb) } } + +void *st_framebuffer_private( struct st_framebuffer *stfb ) +{ + return stfb->Private; +} + diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h index 8162ceeffab..c94e8d32c8a 100644 --- a/src/mesa/state_tracker/st_public.h +++ b/src/mesa/state_tracker/st_public.h @@ -53,7 +53,12 @@ void st_destroy_context( struct st_context *st ); void st_destroy_context2( struct st_context *st ); -struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual ); +void st_copy_context_state(struct st_context *dst, struct st_context *src, + uint mask); + +struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual, + GLboolean createRenderbuffers, + void *privateData); void st_resize_framebuffer( struct st_framebuffer *stfb, GLuint width, GLuint height ); @@ -61,6 +66,8 @@ void st_resize_framebuffer( struct st_framebuffer *stfb, struct pipe_surface *st_get_framebuffer_surface(struct st_framebuffer *stfb, uint surfIndex); +void *st_framebuffer_private( struct st_framebuffer *stfb ); + void st_unreference_framebuffer( struct st_framebuffer **stfb ); void st_make_current(struct st_context *st, -- cgit v1.2.3 From ced9c0f8c4246c055aee85f428af705f232702bc Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 5 Nov 2007 16:38:07 -0700 Subject: don't include mtypes.h in st_public.h --- src/mesa/state_tracker/st_framebuffer.c | 2 +- src/mesa/state_tracker/st_public.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index ec120ba39ab..b43b9b7b9b1 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -96,7 +96,7 @@ struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual, void st_resize_framebuffer( struct st_framebuffer *stfb, - GLuint width, GLuint height ) + uint width, uint height ) { if (stfb->Base.Width != width || stfb->Base.Height != height) { GET_CURRENT_CONTEXT(ctx); diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h index d81cf605033..9e36e1e6e59 100644 --- a/src/mesa/state_tracker/st_public.h +++ b/src/mesa/state_tracker/st_public.h @@ -28,7 +28,7 @@ #ifndef ST_PUBLIC_H #define ST_PUBLIC_H -#include "mtypes.h" +#include "pipe/p_compiler.h" #define ST_SURFACE_FRONT_LEFT 0 @@ -53,11 +53,11 @@ void st_copy_context_state(struct st_context *dst, struct st_context *src, uint mask); struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual, - GLboolean createRenderbuffers, + boolean createRenderbuffers, void *privateData); void st_resize_framebuffer( struct st_framebuffer *stfb, - GLuint width, GLuint height ); + uint width, uint height ); struct pipe_surface *st_get_framebuffer_surface(struct st_framebuffer *stfb, uint surfIndex); -- cgit v1.2.3 From 26eb608a352ec017b534579e1c81c2d1fedf3d1b Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 6 Nov 2007 17:38:47 +0000 Subject: Handle the corner case of 24bit depth buffer with 0bit stencil buffer. --- src/mesa/state_tracker/st_framebuffer.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index b43b9b7b9b1..4833d10322e 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -43,6 +43,7 @@ struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual, = CALLOC_STRUCT(st_framebuffer); if (stfb) { GLboolean swStencil = (visual->stencilBits > 0 && + visual->stencilBits != 8 && visual->depthBits != 24); GLenum rgbFormat = (visual->redBits == 5 ? GL_RGB5 : GL_RGBA8); @@ -62,13 +63,14 @@ struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual, _mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb); } - if (visual->depthBits == 24 && visual->stencilBits == 8) { + if (visual->depthBits == 24) { /* combined depth/stencil buffer */ struct gl_renderbuffer *depthStencilRb = st_new_renderbuffer_fb(GL_DEPTH24_STENCIL8_EXT); /* note: bind RB to two attachment points */ _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthStencilRb); - _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL,depthStencilRb); + if(visual->stencilBits == 8) + _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL,depthStencilRb); } else if (visual->depthBits == 16) { /* just 16-bit depth buffer, no hw stencil */ @@ -76,7 +78,8 @@ struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual, = st_new_renderbuffer_fb(GL_DEPTH_COMPONENT16); _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); } - + else + assert(0); /* now add any/all software-based renderbuffers we may need */ _mesa_add_soft_renderbuffers(&stfb->Base, -- cgit v1.2.3 From 85c7683f1f5f1d0d9e95eb59270705a2975fa437 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 6 Nov 2007 17:34:32 -0700 Subject: Improved logic for setting up depth/stencil buffers in st_create_framebuffer() --- src/mesa/state_tracker/st_framebuffer.c | 55 ++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 14 deletions(-) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 4833d10322e..b04dcdb79df 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -42,9 +42,6 @@ struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual, struct st_framebuffer *stfb = CALLOC_STRUCT(st_framebuffer); if (stfb) { - GLboolean swStencil = (visual->stencilBits > 0 && - visual->stencilBits != 8 && - visual->depthBits != 24); GLenum rgbFormat = (visual->redBits == 5 ? GL_RGB5 : GL_RGBA8); _mesa_initialize_framebuffer(&stfb->Base, visual); @@ -63,29 +60,59 @@ struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual, _mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb); } - if (visual->depthBits == 24) { + if (visual->depthBits == 24 && visual->stencilBits == 8) { /* combined depth/stencil buffer */ struct gl_renderbuffer *depthStencilRb = st_new_renderbuffer_fb(GL_DEPTH24_STENCIL8_EXT); /* note: bind RB to two attachment points */ _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthStencilRb); - if(visual->stencilBits == 8) - _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL,depthStencilRb); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, depthStencilRb); } - else if (visual->depthBits == 16) { - /* just 16-bit depth buffer, no hw stencil */ - struct gl_renderbuffer *depthRb - = st_new_renderbuffer_fb(GL_DEPTH_COMPONENT16); - _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); + else { + /* separate depth and/or stencil */ + + if (visual->depthBits == 32) { + /* 32-bit depth buffer */ + struct gl_renderbuffer *depthRb + = st_new_renderbuffer_fb(GL_DEPTH_COMPONENT32); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); + } + else if (visual->depthBits == 24) { + /* 24-bit depth buffer, ignore stencil bits */ + struct gl_renderbuffer *depthRb + = st_new_renderbuffer_fb(GL_DEPTH24_STENCIL8_EXT); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); + } + else if (visual->depthBits > 0) { + /* 16-bit depth buffer */ + struct gl_renderbuffer *depthRb + = st_new_renderbuffer_fb(GL_DEPTH_COMPONENT16); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); + } + + if (visual->stencilBits > 0) { + /* 8-bit stencil */ + struct gl_renderbuffer *stencilRb + = st_new_renderbuffer_fb(GL_STENCIL_INDEX8_EXT); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, stencilRb); + } } - else - assert(0); + +#if 0 + if (visual->accumRedBits > 0) { + /* 16-bit/channel accum */ + struct gl_renderbuffer *accumRb + = st_new_renderbuffer_fb(GL_RGBA16); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_ACCUM, accumRb); + } +#endif /* now add any/all software-based renderbuffers we may need */ _mesa_add_soft_renderbuffers(&stfb->Base, GL_FALSE, /* never sw color */ GL_FALSE, /* never sw depth */ - swStencil, visual->accumRedBits > 0, + GL_FALSE, /* stencil */ + visual->accumRedBits > 0, GL_FALSE, /* never sw alpha */ GL_FALSE /* never sw aux */ ); } -- cgit v1.2.3 From ae44a81d1bd40852a7cea9b8025dfa3821adc785 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 7 Nov 2007 16:59:37 -0700 Subject: New PIPE_FLUSH_WAIT flag for pipe->flush(). The state tracker doesn't have to directly call winsys->wait_idle() anymore. glFlush and glFinish both go through pipe->flush() now. --- src/mesa/drivers/dri/intel_winsys/intel_context.c | 4 ++-- src/mesa/pipe/i915simple/i915_flush.c | 6 +++++- src/mesa/pipe/p_defines.h | 3 ++- src/mesa/state_tracker/st_cb_flush.c | 11 ++++------- src/mesa/state_tracker/st_framebuffer.c | 2 +- src/mesa/state_tracker/st_public.h | 2 +- 6 files changed, 15 insertions(+), 13 deletions(-) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/drivers/dri/intel_winsys/intel_context.c b/src/mesa/drivers/dri/intel_winsys/intel_context.c index 47be72b2330..480350492f1 100644 --- a/src/mesa/drivers/dri/intel_winsys/intel_context.c +++ b/src/mesa/drivers/dri/intel_winsys/intel_context.c @@ -227,7 +227,7 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) assert(intel); /* should never be null */ if (intel) { - st_flush(intel->st); + st_flush(intel->st, PIPE_FLUSH_WAIT); intel_batchbuffer_free(intel->batch); @@ -255,7 +255,7 @@ GLboolean intelUnbindContext(__DRIcontextPrivate * driContextPriv) { struct intel_context *intel = intel_context(driContextPriv); - st_flush(intel->st); + st_flush(intel->st, 0x0); /* XXX make_current(NULL)? */ return GL_TRUE; } diff --git a/src/mesa/pipe/i915simple/i915_flush.c b/src/mesa/pipe/i915simple/i915_flush.c index 9c2adf87637..5a80ed5e2f5 100644 --- a/src/mesa/pipe/i915simple/i915_flush.c +++ b/src/mesa/pipe/i915simple/i915_flush.c @@ -47,7 +47,7 @@ static void i915_flush( struct pipe_context *pipe, /* Do we need to emit an MI_FLUSH command to flush the hardware * caches? */ - if (flags) { + if (flags & (PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_TEXTURE_CACHE)) { unsigned flush = MI_FLUSH; if (!(flags & PIPE_FLUSH_RENDER_CACHE)) @@ -67,6 +67,10 @@ static void i915_flush( struct pipe_context *pipe, /* If there are no flags, just flush pending commands to hardware: */ FLUSH_BATCH(); + + if (flags & PIPE_FLUSH_WAIT) { + i915->pipe.winsys->wait_idle(i915->pipe.winsys, i915->pipe.private); + } } diff --git a/src/mesa/pipe/p_defines.h b/src/mesa/pipe/p_defines.h index ca9929bfeec..6b5881b64db 100644 --- a/src/mesa/pipe/p_defines.h +++ b/src/mesa/pipe/p_defines.h @@ -187,8 +187,9 @@ /** * Flush types: */ -#define PIPE_FLUSH_RENDER_CACHE 0x1 +#define PIPE_FLUSH_RENDER_CACHE 0x1 #define PIPE_FLUSH_TEXTURE_CACHE 0x2 +#define PIPE_FLUSH_WAIT 0x4 /** diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c index 6354306e752..39a9f29bca8 100644 --- a/src/mesa/state_tracker/st_cb_flush.c +++ b/src/mesa/state_tracker/st_cb_flush.c @@ -43,7 +43,7 @@ #include "pipe/p_winsys.h" -void st_flush( struct st_context *st ) +void st_flush( struct st_context *st, uint pipeFlushFlags ) { GLframebuffer *fb = st->ctx->DrawBuffer; @@ -53,7 +53,7 @@ void st_flush( struct st_context *st ) * short-circuiting this, or perhaps pass an "optional" flag down * to the driver so that it can make the decision. */ - st->pipe->flush( st->pipe, 0 ); + st->pipe->flush( st->pipe, pipeFlushFlags ); if (!fb) return; @@ -83,7 +83,7 @@ void st_flush( struct st_context *st ) */ static void st_Flush(GLcontext *ctx) { - st_flush(ctx->st); + st_flush(ctx->st, 0x0); } @@ -92,10 +92,7 @@ static void st_Flush(GLcontext *ctx) */ static void st_Finish(GLcontext *ctx) { - struct st_context *st = ctx->st; - - st_flush( st ); - st->pipe->winsys->wait_idle( st->pipe->winsys, st->pipe->private ); + st_flush(ctx->st, PIPE_FLUSH_WAIT); } diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index b04dcdb79df..4ae2837f0a0 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -179,7 +179,7 @@ st_notify_swapbuffers(struct st_framebuffer *stfb) GET_CURRENT_CONTEXT(ctx); if (ctx && ctx->DrawBuffer == &stfb->Base) { - st_flush(ctx->st); + st_flush(ctx->st, 0x0); } } diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h index 9e36e1e6e59..408e1927e5b 100644 --- a/src/mesa/state_tracker/st_public.h +++ b/src/mesa/state_tracker/st_public.h @@ -70,7 +70,7 @@ void st_make_current(struct st_context *st, struct st_framebuffer *draw, struct st_framebuffer *read); -void st_flush( struct st_context *st ); +void st_flush( struct st_context *st, uint pipeFlushFlags ); void st_notify_swapbuffers(struct st_framebuffer *stfb); -- cgit v1.2.3 From f77ce9e4fa6430fd6f4aaf07c58ed12569dec481 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 7 Dec 2007 07:53:21 -0700 Subject: added ST_SURFACE_DEPTH --- src/mesa/state_tracker/st_framebuffer.c | 2 +- src/mesa/state_tracker/st_public.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 4ae2837f0a0..8633f431b29 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -155,7 +155,7 @@ st_get_framebuffer_surface(struct st_framebuffer *stfb, uint surfIndex) { struct st_renderbuffer *strb; - assert(surfIndex <= ST_SURFACE_BACK_RIGHT); + assert(surfIndex <= ST_SURFACE_DEPTH); /* sanity checks, ST tokens should match Mesa tokens */ assert(ST_SURFACE_FRONT_LEFT == BUFFER_FRONT_LEFT); diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h index 408e1927e5b..307635936bc 100644 --- a/src/mesa/state_tracker/st_public.h +++ b/src/mesa/state_tracker/st_public.h @@ -35,6 +35,7 @@ #define ST_SURFACE_BACK_LEFT 1 #define ST_SURFACE_FRONT_RIGHT 2 #define ST_SURFACE_BACK_RIGHT 3 +#define ST_SURFACE_DEPTH 8 struct st_context; -- cgit v1.2.3 From 4f58d9af9addb1506a1b2abc7dd8012147772b78 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 10 Dec 2007 13:48:09 -0700 Subject: Add 'type' parameter to is_format_supported() to specify texture vs. drawing surface, etc. Additional types may be added in the future. --- .../drivers/dri/intel_winsys/intel_winsys_pipe.c | 2 +- src/mesa/pipe/i915simple/i915_context.c | 77 ++++++++---------- src/mesa/pipe/p_context.h | 3 +- src/mesa/pipe/p_defines.h | 7 +- src/mesa/pipe/softpipe/sp_context.c | 24 ++++-- src/mesa/pipe/softpipe/sp_winsys.h | 16 ++-- src/mesa/pipe/xlib/xm_winsys.c | 26 +----- src/mesa/state_tracker/st_cb_drawpixels.c | 4 +- src/mesa/state_tracker/st_cb_fbo.c | 11 ++- src/mesa/state_tracker/st_cb_fbo.h | 3 +- src/mesa/state_tracker/st_format.c | 95 +++++++++++----------- src/mesa/state_tracker/st_format.h | 2 +- src/mesa/state_tracker/st_framebuffer.c | 29 +++---- 13 files changed, 142 insertions(+), 157 deletions(-) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/drivers/dri/intel_winsys/intel_winsys_pipe.c b/src/mesa/drivers/dri/intel_winsys/intel_winsys_pipe.c index 86ea86a58fc..9c643dd0baf 100644 --- a/src/mesa/drivers/dri/intel_winsys/intel_winsys_pipe.c +++ b/src/mesa/drivers/dri/intel_winsys/intel_winsys_pipe.c @@ -191,7 +191,7 @@ intel_i915_surface_pitch(struct pipe_winsys *winsys, */ /* XXX is the pitch different for textures vs. drawables? */ - if (flags & PIPE_SURFACE_FLAG_TEXTURE) /* or PIPE_SURFACE_FLAG_RENDER? */ + if (1/*flags & PIPE_SURFACE_FLAG_TEXTURE*/) /* or PIPE_SURFACE_FLAG_RENDER? */ return ((cpp * width + 63) & ~63) / cpp; else return ((cpp * width + 63) & ~63) / cpp; diff --git a/src/mesa/pipe/i915simple/i915_context.c b/src/mesa/pipe/i915simple/i915_context.c index b915a677908..f505ff6ae65 100644 --- a/src/mesa/pipe/i915simple/i915_context.c +++ b/src/mesa/pipe/i915simple/i915_context.c @@ -39,72 +39,61 @@ /** - * Query format support. - * If we find texture and drawable support differs, add a selector - * parameter or another function. + * Query format support for creating a texture, drawing surface, etc. + * \param format the format to test + * \param type one of PIPE_TEXTURE, PIPE_SURFACE, PIPE_SCREEN_SURFACE */ static boolean i915_is_format_supported( struct pipe_context *pipe, - enum pipe_format format ) + enum pipe_format format, uint type ) { -#if 0 - /* XXX: This is broken -- rewrite if still needed. */ - static const unsigned tex_supported[] = { + static const enum pipe_format tex_supported[] = { PIPE_FORMAT_R8G8B8A8_UNORM, PIPE_FORMAT_A8R8G8B8_UNORM, PIPE_FORMAT_R5G6B5_UNORM, PIPE_FORMAT_U_L8, PIPE_FORMAT_U_A8, PIPE_FORMAT_U_I8, - PIPE_FORMAT_U_L8_A8, + PIPE_FORMAT_U_A8_L8, PIPE_FORMAT_YCBCR, PIPE_FORMAT_YCBCR_REV, PIPE_FORMAT_S8Z24_UNORM, + PIPE_FORMAT_NONE /* list terminator */ }; - - - /* Actually a lot more than this - add later: - */ - static const unsigned render_supported[] = { + static const enum pipe_format surface_supported[] = { PIPE_FORMAT_A8R8G8B8_UNORM, PIPE_FORMAT_R5G6B5_UNORM, - }; - - /* - */ - static const unsigned z_stencil_supported[] = { - PIPE_FORMAT_Z16_UNORM, - PIPE_FORMAT_Z32_UNORM, PIPE_FORMAT_S8Z24_UNORM, + PIPE_FORMAT_R16G16B16A16_SNORM, + PIPE_FORMAT_NONE /* list terminator */ + }; + static const enum pipe_format screen_surface_supported[] = { + PIPE_FORMAT_A8R8G8B8_UNORM, + PIPE_FORMAT_NONE /* list terminator */ }; + const enum pipe_format *list; + uint i; switch (type) { - case PIPE_RENDER_FORMAT: - *numFormats = Elements(render_supported); - return render_supported; - - case PIPE_TEX_FORMAT: - *numFormats = Elements(tex_supported); - return render_supported; - - case PIPE_Z_STENCIL_FORMAT: - *numFormats = Elements(render_supported); - return render_supported; - + case PIPE_TEXTURE: + list = tex_supported; + break; + case PIPE_SURFACE: + list = surface_supported; + break; + case PIPE_SCREEN_SURFACE: + list = screen_surface_supported; + break; default: - *numFormats = 0; - return NULL; + assert(0); } -#else - switch( format ) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_S8Z24_UNORM: - return TRUE; - default: - return FALSE; - }; -#endif + + for (i = 0; list[i] != PIPE_FORMAT_NONE; i++) { + if (list[i] == format) + return TRUE; + } + + return FALSE; } diff --git a/src/mesa/pipe/p_context.h b/src/mesa/pipe/p_context.h index b3a2122ade9..00379fbacfe 100644 --- a/src/mesa/pipe/p_context.h +++ b/src/mesa/pipe/p_context.h @@ -50,8 +50,9 @@ struct pipe_context { /* * Queries */ + /** type is one of PIPE_SURFACE, PIPE_TEXTURE, etc. */ boolean (*is_format_supported)( struct pipe_context *pipe, - enum pipe_format format ); + enum pipe_format format, uint type ); const char *(*get_name)( struct pipe_context *pipe ); diff --git a/src/mesa/pipe/p_defines.h b/src/mesa/pipe/p_defines.h index 8dce3aba904..d3afef95b47 100644 --- a/src/mesa/pipe/p_defines.h +++ b/src/mesa/pipe/p_defines.h @@ -161,10 +161,11 @@ #define PIPE_TEX_FACE_MAX 6 /** - * Surface flags + * Surfaces, textures, etc. (others may be added) */ -#define PIPE_SURFACE_FLAG_TEXTURE 0x1 -#define PIPE_SURFACE_FLAG_RENDER 0x2 +#define PIPE_TEXTURE 1 +#define PIPE_SURFACE 2 /**< user-created surfaces */ +#define PIPE_SCREEN_SURFACE 3 /**< On-screen front/back colorbuffer */ /** diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c index 809b165f450..8b8e04c2f9e 100644 --- a/src/mesa/pipe/softpipe/sp_context.c +++ b/src/mesa/pipe/softpipe/sp_context.c @@ -46,17 +46,29 @@ /** - * Query format support. - * If we find texture and drawable support differs, add a selector - * parameter or another function. + * Query format support for creating a texture, drawing surface, etc. + * \param format the format to test + * \param type one of PIPE_TEXTURE, PIPE_SURFACE, PIPE_SCREEN_SURFACE */ static boolean softpipe_is_format_supported( struct pipe_context *pipe, - enum pipe_format format ) + enum pipe_format format, uint type ) { struct softpipe_context *softpipe = softpipe_context( pipe ); - /* ask winsys if the format is supported */ - return softpipe->winsys->is_format_supported( softpipe->winsys, format ); + + switch (type) { + case PIPE_TEXTURE: + /* softpipe supports all texture formats */ + return TRUE; + case PIPE_SURFACE: + /* softpipe supports all (off-screen) surface formats */ + return TRUE; + case PIPE_SCREEN_SURFACE: + return softpipe->winsys->is_format_supported( softpipe->winsys, format ); + default: + assert(0); + return FALSE; + } } diff --git a/src/mesa/pipe/softpipe/sp_winsys.h b/src/mesa/pipe/softpipe/sp_winsys.h index 1912e59b9f4..cbf64ebb850 100644 --- a/src/mesa/pipe/softpipe/sp_winsys.h +++ b/src/mesa/pipe/softpipe/sp_winsys.h @@ -25,21 +25,23 @@ * **************************************************************************/ +/* This is the interface that softpipe requires any window system + * hosting it to implement. This is the only include file in softpipe + * which is public. + */ + + #ifndef SP_WINSYS_H #define SP_WINSYS_H -#include "pipe/p_compiler.h" // for boolean +#include "pipe/p_compiler.h" /* for boolean */ -/* This is the interface that softpipe requires any window system - * hosting it to implement. This is the only include file in softpipe - * which is public. - */ - struct softpipe_winsys { + /** test if the given format is supported for front/back color bufs */ boolean (*is_format_supported)( struct softpipe_winsys *sws, - uint format ); + enum pipe_format format ); }; diff --git a/src/mesa/pipe/xlib/xm_winsys.c b/src/mesa/pipe/xlib/xm_winsys.c index c347d1c2a31..68f9c39116d 100644 --- a/src/mesa/pipe/xlib/xm_winsys.c +++ b/src/mesa/pipe/xlib/xm_winsys.c @@ -71,7 +71,7 @@ struct xmesa_surface struct xmesa_softpipe_winsys { struct softpipe_winsys spws; - uint pixelformat; + enum pipe_format pixelformat; }; @@ -377,35 +377,17 @@ xmesa_get_pipe_winsys(void) /** + * Called via softpipe_winsys->is_format_supported(). + * This function is only called to test formats for front/back color surfaces. * The winsys being queried will have been created at glXCreateContext * time, with a pixel format corresponding to the context's visual. - * - * XXX we should pass a flag indicating if the format is going to be - * use for a drawing surface vs. a texture. In the later case, we - * can support any format. */ static boolean xmesa_is_format_supported(struct softpipe_winsys *sws, enum pipe_format format) { struct xmesa_softpipe_winsys *xmws = xmesa_softpipe_winsys(sws); - - if (format == xmws->pixelformat) { - return TRUE; - } - else { - /* non-color / window surface format */ - switch (format) { - case PIPE_FORMAT_R16G16B16A16_SNORM: - case PIPE_FORMAT_S8Z24_UNORM: - case PIPE_FORMAT_U_S8: - case PIPE_FORMAT_Z16_UNORM: - case PIPE_FORMAT_Z32_UNORM: - return TRUE; - default: - return FALSE; - } - } + return (format == xmws->pixelformat); } diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index c0e41dbeec5..01790003532 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -993,13 +993,13 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height, int row, col; /* find a texture format we know */ - if (pipe->is_format_supported( pipe, PIPE_FORMAT_U_I8 )) { + if (pipe->is_format_supported( pipe, PIPE_FORMAT_U_I8, PIPE_TEXTURE )) { format = PIPE_FORMAT_U_I8; internal_format = GL_INTENSITY8; cpp = 1; comp = 0; } - else if (pipe->is_format_supported( pipe, PIPE_FORMAT_A8R8G8B8_UNORM )) { + else if (pipe->is_format_supported( pipe, PIPE_FORMAT_A8R8G8B8_UNORM, PIPE_TEXTURE )) { format = PIPE_FORMAT_A8R8G8B8_UNORM; internal_format = GL_RGBA8; cpp = 4; diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 36d25a576db..6e9e7e3a248 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -87,12 +87,14 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, { struct pipe_context *pipe = ctx->st->pipe; struct st_renderbuffer *strb = st_renderbuffer(rb); + uint type = strb->screenSurface ? PIPE_SCREEN_SURFACE : PIPE_SURFACE; const enum pipe_format pipeFormat - = st_choose_pipe_format(pipe, internalFormat, GL_NONE, GL_NONE); + = st_choose_pipe_format(pipe, internalFormat, GL_NONE, GL_NONE, type); GLuint cpp; - GLbitfield flags = PIPE_SURFACE_FLAG_RENDER; /* want to render to surface */ + GLbitfield flags = 0x0; /* XXX needed? */ cpp = init_renderbuffer_bits(strb, pipeFormat); + assert(cpp); if (strb->surface && strb->surface->format != pipeFormat) { /* need to change surface types, free this surface */ @@ -201,9 +203,11 @@ st_new_renderbuffer(GLcontext *ctx, GLuint name) /** * Allocate a renderbuffer for a an on-screen window (not a user-created * renderbuffer). The window system code determines the internal format. + * \param screenSurface indicates if the renderbuffer is a front/back color + * buffer that'll be displayed/copied to the screen */ struct gl_renderbuffer * -st_new_renderbuffer_fb(GLenum intFormat) +st_new_renderbuffer_fb(GLenum intFormat, GLboolean screenSurface) { struct st_renderbuffer *strb; @@ -216,6 +220,7 @@ st_new_renderbuffer_fb(GLenum intFormat) _mesa_init_renderbuffer(&strb->Base, 0); strb->Base.ClassID = 0x4242; /* just a unique value */ strb->Base.InternalFormat = intFormat; + strb->screenSurface = screenSurface; switch (intFormat) { case GL_RGB5: diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h index 2280441db59..bd85bfc549f 100644 --- a/src/mesa/state_tracker/st_cb_fbo.h +++ b/src/mesa/state_tracker/st_cb_fbo.h @@ -39,6 +39,7 @@ struct st_renderbuffer { struct gl_renderbuffer Base; struct pipe_surface *surface; + GLboolean screenSurface; /**< A front/back colorbuffer? */ }; @@ -50,7 +51,7 @@ st_renderbuffer(struct gl_renderbuffer *rb) extern struct gl_renderbuffer * -st_new_renderbuffer_fb(GLenum intFormat); +st_new_renderbuffer_fb(GLenum intFormat, GLboolean screen_surface); extern void diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c index 8d39e1bec69..c292a975f38 100644 --- a/src/mesa/state_tracker/st_format.c +++ b/src/mesa/state_tracker/st_format.c @@ -276,10 +276,9 @@ st_mesa_format_to_pipe_format(GLuint mesaFormat) * Find an RGBA format supported by the context/winsys. */ static GLuint -default_rgba_format( - struct pipe_context *pipe ) +default_rgba_format(struct pipe_context *pipe, uint type) { - static const uint colorFormats[] = { + static const enum pipe_format colorFormats[] = { PIPE_FORMAT_R8G8B8A8_UNORM, PIPE_FORMAT_A8R8G8B8_UNORM, PIPE_FORMAT_B8G8R8A8_UNORM, @@ -287,7 +286,7 @@ default_rgba_format( }; uint i; for (i = 0; i < Elements(colorFormats); i++) { - if (pipe->is_format_supported( pipe, colorFormats[i] )) { + if (pipe->is_format_supported( pipe, colorFormats[i], type )) { return colorFormats[i]; } } @@ -299,10 +298,9 @@ default_rgba_format( * Search list of formats for first RGBA format with >8 bits/channel. */ static GLuint -default_deep_rgba_format( - struct pipe_context *pipe ) +default_deep_rgba_format(struct pipe_context *pipe, uint type) { - if (pipe->is_format_supported( pipe, PIPE_FORMAT_R16G16B16A16_SNORM )) { + if (pipe->is_format_supported(pipe, PIPE_FORMAT_R16G16B16A16_SNORM, type)) { return PIPE_FORMAT_R16G16B16A16_SNORM; } return PIPE_FORMAT_NONE; @@ -313,10 +311,9 @@ default_deep_rgba_format( * Find an Z format supported by the context/winsys. */ static GLuint -default_depth_format( - struct pipe_context *pipe ) +default_depth_format(struct pipe_context *pipe, uint type) { - static const uint zFormats[] = { + static const enum pipe_format zFormats[] = { PIPE_FORMAT_Z16_UNORM, PIPE_FORMAT_Z32_UNORM, PIPE_FORMAT_S8Z24_UNORM, @@ -324,7 +321,7 @@ default_depth_format( }; uint i; for (i = 0; i < Elements(zFormats); i++) { - if (pipe->is_format_supported( pipe, zFormats[i] )) { + if (pipe->is_format_supported( pipe, zFormats[i], type )) { return zFormats[i]; } } @@ -348,67 +345,71 @@ default_depth_format( */ GLuint st_choose_pipe_format(struct pipe_context *pipe, GLint internalFormat, - GLenum format, GLenum type) + GLenum format, GLenum type, uint surfType) { + assert(surfType == PIPE_TEXTURE || + surfType == PIPE_SURFACE || + surfType == PIPE_SCREEN_SURFACE); + switch (internalFormat) { case 4: case GL_RGBA: case GL_COMPRESSED_RGBA: if (format == GL_BGRA) { if (type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT_8_8_8_8_REV) { - if (pipe->is_format_supported( pipe, PIPE_FORMAT_A8R8G8B8_UNORM )) + if (pipe->is_format_supported( pipe, PIPE_FORMAT_A8R8G8B8_UNORM, surfType )) return PIPE_FORMAT_A8R8G8B8_UNORM; } else if (type == GL_UNSIGNED_SHORT_4_4_4_4_REV) { - if (pipe->is_format_supported( pipe, PIPE_FORMAT_A4R4G4B4_UNORM )) + if (pipe->is_format_supported( pipe, PIPE_FORMAT_A4R4G4B4_UNORM, surfType )) return PIPE_FORMAT_A4R4G4B4_UNORM; } else if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV) { - if (pipe->is_format_supported( pipe, PIPE_FORMAT_A1R5G5B5_UNORM )) + if (pipe->is_format_supported( pipe, PIPE_FORMAT_A1R5G5B5_UNORM, surfType )) return PIPE_FORMAT_A1R5G5B5_UNORM; } } - return default_rgba_format( pipe ); + return default_rgba_format( pipe, surfType ); case 3: case GL_RGB: case GL_COMPRESSED_RGB: if (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) { - if (pipe->is_format_supported( pipe, PIPE_FORMAT_R5G6B5_UNORM )) + if (pipe->is_format_supported( pipe, PIPE_FORMAT_R5G6B5_UNORM, surfType )) return PIPE_FORMAT_R5G6B5_UNORM; } - return default_rgba_format( pipe ); + return default_rgba_format( pipe, surfType ); case GL_RGBA8: case GL_RGB10_A2: case GL_RGBA12: - return default_rgba_format( pipe ); + return default_rgba_format( pipe, surfType ); case GL_RGBA16: - return default_deep_rgba_format( pipe ); + return default_deep_rgba_format( pipe, surfType ); case GL_RGBA4: case GL_RGBA2: - if (pipe->is_format_supported( pipe, PIPE_FORMAT_A4R4G4B4_UNORM )) + if (pipe->is_format_supported( pipe, PIPE_FORMAT_A4R4G4B4_UNORM, surfType )) return PIPE_FORMAT_A4R4G4B4_UNORM; - return default_rgba_format( pipe ); + return default_rgba_format( pipe, surfType ); case GL_RGB5_A1: - if (pipe->is_format_supported( pipe, PIPE_FORMAT_A1R5G5B5_UNORM )) + if (pipe->is_format_supported( pipe, PIPE_FORMAT_A1R5G5B5_UNORM, surfType )) return PIPE_FORMAT_A1R5G5B5_UNORM; - return default_rgba_format( pipe ); + return default_rgba_format( pipe, surfType ); case GL_RGB8: case GL_RGB10: case GL_RGB12: case GL_RGB16: - return default_rgba_format( pipe ); + return default_rgba_format( pipe, surfType ); case GL_RGB5: case GL_RGB4: case GL_R3_G3_B2: - if (pipe->is_format_supported( pipe, PIPE_FORMAT_A1R5G5B5_UNORM )) + if (pipe->is_format_supported( pipe, PIPE_FORMAT_A1R5G5B5_UNORM, surfType )) return PIPE_FORMAT_A1R5G5B5_UNORM; - return default_rgba_format( pipe ); + return default_rgba_format( pipe, surfType ); case GL_ALPHA: case GL_ALPHA4: @@ -416,9 +417,9 @@ st_choose_pipe_format(struct pipe_context *pipe, GLint internalFormat, case GL_ALPHA12: case GL_ALPHA16: case GL_COMPRESSED_ALPHA: - if (pipe->is_format_supported( pipe, PIPE_FORMAT_U_A8 )) + if (pipe->is_format_supported( pipe, PIPE_FORMAT_U_A8, surfType )) return PIPE_FORMAT_U_A8; - return default_rgba_format( pipe ); + return default_rgba_format( pipe, surfType ); case 1: case GL_LUMINANCE: @@ -427,9 +428,9 @@ st_choose_pipe_format(struct pipe_context *pipe, GLint internalFormat, case GL_LUMINANCE12: case GL_LUMINANCE16: case GL_COMPRESSED_LUMINANCE: - if (pipe->is_format_supported( pipe, PIPE_FORMAT_U_A8 )) + if (pipe->is_format_supported( pipe, PIPE_FORMAT_U_A8, surfType )) return PIPE_FORMAT_U_A8; - return default_rgba_format( pipe ); + return default_rgba_format( pipe, surfType ); case 2: case GL_LUMINANCE_ALPHA: @@ -440,9 +441,9 @@ st_choose_pipe_format(struct pipe_context *pipe, GLint internalFormat, case GL_LUMINANCE12_ALPHA12: case GL_LUMINANCE16_ALPHA16: case GL_COMPRESSED_LUMINANCE_ALPHA: - if (pipe->is_format_supported( pipe, PIPE_FORMAT_U_A8_L8 )) + if (pipe->is_format_supported( pipe, PIPE_FORMAT_U_A8_L8, surfType )) return PIPE_FORMAT_U_A8_L8; - return default_rgba_format( pipe ); + return default_rgba_format( pipe, surfType ); case GL_INTENSITY: case GL_INTENSITY4: @@ -450,17 +451,17 @@ st_choose_pipe_format(struct pipe_context *pipe, GLint internalFormat, case GL_INTENSITY12: case GL_INTENSITY16: case GL_COMPRESSED_INTENSITY: - if (pipe->is_format_supported( pipe, PIPE_FORMAT_U_I8 )) + if (pipe->is_format_supported( pipe, PIPE_FORMAT_U_I8, surfType )) return PIPE_FORMAT_U_I8; - return default_rgba_format( pipe ); + return default_rgba_format( pipe, surfType ); case GL_YCBCR_MESA: if (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE) { - if (pipe->is_format_supported( pipe, PIPE_FORMAT_YCBCR )) + if (pipe->is_format_supported( pipe, PIPE_FORMAT_YCBCR, surfType )) return PIPE_FORMAT_YCBCR; } else { - if (pipe->is_format_supported( pipe, PIPE_FORMAT_YCBCR_REV )) + if (pipe->is_format_supported( pipe, PIPE_FORMAT_YCBCR_REV, surfType )) return PIPE_FORMAT_YCBCR_REV; } return PIPE_FORMAT_NONE; @@ -489,40 +490,40 @@ st_choose_pipe_format(struct pipe_context *pipe, GLint internalFormat, #endif case GL_DEPTH_COMPONENT16: - if (pipe->is_format_supported( pipe, PIPE_FORMAT_Z16_UNORM )) + if (pipe->is_format_supported( pipe, PIPE_FORMAT_Z16_UNORM, surfType )) return PIPE_FORMAT_Z16_UNORM; /* fall-through */ case GL_DEPTH_COMPONENT24: - if (pipe->is_format_supported( pipe, PIPE_FORMAT_S8Z24_UNORM )) + if (pipe->is_format_supported( pipe, PIPE_FORMAT_S8Z24_UNORM, surfType )) return PIPE_FORMAT_S8Z24_UNORM; - if (pipe->is_format_supported( pipe, PIPE_FORMAT_Z24S8_UNORM )) + if (pipe->is_format_supported( pipe, PIPE_FORMAT_Z24S8_UNORM, surfType )) return PIPE_FORMAT_Z24S8_UNORM; /* fall-through */ case GL_DEPTH_COMPONENT32: - if (pipe->is_format_supported( pipe, PIPE_FORMAT_Z32_UNORM )) + if (pipe->is_format_supported( pipe, PIPE_FORMAT_Z32_UNORM, surfType )) return PIPE_FORMAT_Z32_UNORM; /* fall-through */ case GL_DEPTH_COMPONENT: - return default_depth_format( pipe ); + return default_depth_format( pipe, surfType ); case GL_STENCIL_INDEX: case GL_STENCIL_INDEX1_EXT: case GL_STENCIL_INDEX4_EXT: case GL_STENCIL_INDEX8_EXT: case GL_STENCIL_INDEX16_EXT: - if (pipe->is_format_supported( pipe, PIPE_FORMAT_U_S8 )) + if (pipe->is_format_supported( pipe, PIPE_FORMAT_U_S8, surfType )) return PIPE_FORMAT_U_S8; - if (pipe->is_format_supported( pipe, PIPE_FORMAT_S8Z24_UNORM )) + if (pipe->is_format_supported( pipe, PIPE_FORMAT_S8Z24_UNORM, surfType )) return PIPE_FORMAT_S8Z24_UNORM; - if (pipe->is_format_supported( pipe, PIPE_FORMAT_Z24S8_UNORM )) + if (pipe->is_format_supported( pipe, PIPE_FORMAT_Z24S8_UNORM, surfType )) return PIPE_FORMAT_Z24S8_UNORM; return PIPE_FORMAT_NONE; case GL_DEPTH_STENCIL_EXT: case GL_DEPTH24_STENCIL8_EXT: - if (pipe->is_format_supported( pipe, PIPE_FORMAT_S8Z24_UNORM )) + if (pipe->is_format_supported( pipe, PIPE_FORMAT_S8Z24_UNORM, surfType )) return PIPE_FORMAT_S8Z24_UNORM; - if (pipe->is_format_supported( pipe, PIPE_FORMAT_Z24S8_UNORM )) + if (pipe->is_format_supported( pipe, PIPE_FORMAT_Z24S8_UNORM, surfType )) return PIPE_FORMAT_Z24S8_UNORM; return PIPE_FORMAT_NONE; diff --git a/src/mesa/state_tracker/st_format.h b/src/mesa/state_tracker/st_format.h index 6ccf5536f9d..ebff7c5b912 100644 --- a/src/mesa/state_tracker/st_format.h +++ b/src/mesa/state_tracker/st_format.h @@ -65,7 +65,7 @@ st_mesa_format_to_pipe_format(GLuint mesaFormat); extern GLuint st_choose_pipe_format(struct pipe_context *pipe, GLint internalFormat, - GLenum format, GLenum type); + GLenum format, GLenum type, uint surfType); extern const struct gl_texture_format * diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 8633f431b29..454306b8743 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -51,19 +51,21 @@ struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual, /* fake frontbuffer */ /* XXX allocation should only happen in the unusual case it's actually needed */ - struct gl_renderbuffer *rb = st_new_renderbuffer_fb(rgbFormat); + struct gl_renderbuffer *rb + = st_new_renderbuffer_fb(rgbFormat, GL_TRUE); _mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb); } if (visual->doubleBufferMode) { - struct gl_renderbuffer *rb = st_new_renderbuffer_fb(rgbFormat); + struct gl_renderbuffer *rb + = st_new_renderbuffer_fb(rgbFormat, GL_TRUE); _mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb); } if (visual->depthBits == 24 && visual->stencilBits == 8) { /* combined depth/stencil buffer */ struct gl_renderbuffer *depthStencilRb - = st_new_renderbuffer_fb(GL_DEPTH24_STENCIL8_EXT); + = st_new_renderbuffer_fb(GL_DEPTH24_STENCIL8_EXT, GL_FALSE); /* note: bind RB to two attachment points */ _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthStencilRb); _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, depthStencilRb); @@ -74,47 +76,36 @@ struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual, if (visual->depthBits == 32) { /* 32-bit depth buffer */ struct gl_renderbuffer *depthRb - = st_new_renderbuffer_fb(GL_DEPTH_COMPONENT32); + = st_new_renderbuffer_fb(GL_DEPTH_COMPONENT32, GL_FALSE); _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); } else if (visual->depthBits == 24) { /* 24-bit depth buffer, ignore stencil bits */ struct gl_renderbuffer *depthRb - = st_new_renderbuffer_fb(GL_DEPTH24_STENCIL8_EXT); + = st_new_renderbuffer_fb(GL_DEPTH24_STENCIL8_EXT, GL_FALSE); _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); } else if (visual->depthBits > 0) { /* 16-bit depth buffer */ struct gl_renderbuffer *depthRb - = st_new_renderbuffer_fb(GL_DEPTH_COMPONENT16); + = st_new_renderbuffer_fb(GL_DEPTH_COMPONENT16, GL_FALSE); _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); } if (visual->stencilBits > 0) { /* 8-bit stencil */ struct gl_renderbuffer *stencilRb - = st_new_renderbuffer_fb(GL_STENCIL_INDEX8_EXT); + = st_new_renderbuffer_fb(GL_STENCIL_INDEX8_EXT, GL_FALSE); _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, stencilRb); } } -#if 0 if (visual->accumRedBits > 0) { /* 16-bit/channel accum */ struct gl_renderbuffer *accumRb - = st_new_renderbuffer_fb(GL_RGBA16); + = st_new_renderbuffer_fb(GL_RGBA16, GL_FALSE); _mesa_add_renderbuffer(&stfb->Base, BUFFER_ACCUM, accumRb); } -#endif - - /* now add any/all software-based renderbuffers we may need */ - _mesa_add_soft_renderbuffers(&stfb->Base, - GL_FALSE, /* never sw color */ - GL_FALSE, /* never sw depth */ - GL_FALSE, /* stencil */ - visual->accumRedBits > 0, - GL_FALSE, /* never sw alpha */ - GL_FALSE /* never sw aux */ ); } stfb->Base.Initialized = GL_TRUE; -- cgit v1.2.3 From 20eae595faa20dba8a59d8a4bfd01aa6b458cecd Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 12 Dec 2007 14:55:57 -0700 Subject: Re-org of st_create_framebuffer() and renderbuffer format selection. st_create_framebuffer() now takes pipe_formats for the color, depth, stencil buffers. This avoids a round-about chain of calls to pipe->is_format_supported() for window renderbuffers (their format never changes). Renderbuffer format selection code in st_format.c is simpler now too. --- src/mesa/drivers/dri/intel_winsys/intel_screen.c | 25 ++++- src/mesa/pipe/softpipe/sp_surface.c | 5 + src/mesa/pipe/xlib/xm_api.c | 120 ++++++++++++++--------- src/mesa/state_tracker/st_cb_fbo.c | 59 +++++++---- src/mesa/state_tracker/st_cb_fbo.h | 5 +- src/mesa/state_tracker/st_format.c | 58 ++--------- src/mesa/state_tracker/st_format.h | 5 +- src/mesa/state_tracker/st_framebuffer.c | 31 +++--- src/mesa/state_tracker/st_public.h | 4 + 9 files changed, 173 insertions(+), 139 deletions(-) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/drivers/dri/intel_winsys/intel_screen.c b/src/mesa/drivers/dri/intel_winsys/intel_screen.c index 1b520f71353..bce6c5699a1 100644 --- a/src/mesa/drivers/dri/intel_winsys/intel_screen.c +++ b/src/mesa/drivers/dri/intel_winsys/intel_screen.c @@ -274,11 +274,34 @@ intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, return GL_FALSE; /* not implemented */ } else { + enum pipe_format colorFormat, depthFormat, stencilFormat; struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer); + if (!intelfb) return GL_FALSE; - intelfb->stfb = st_create_framebuffer(visual, GL_TRUE, (void*) intelfb); + if (visual->redBits == 5) + colorFormat = PIPE_FORMAT_R5G6B5_UNORM; + else + colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; + + if (visual->depthBits == 16) + depthFormat = PIPE_FORMAT_Z16_UNORM; + else if (visual->depthBits == 24) + depthFormat = PIPE_FORMAT_S8Z24_UNORM; + else + depthFormat = PIPE_FORMAT_NONE; + + if (visual->stencilBits == 8) + stencilFormat = PIPE_FORMAT_S8Z24_UNORM; + else + stencilFormat = PIPE_FORMAT_NONE; + + intelfb->stfb = st_create_framebuffer(visual, GL_TRUE, + colorFormat, + depthFormat, + stencilFormat, + (void*) intelfb); if (!intelfb->stfb) { free(intelfb); return GL_FALSE; diff --git a/src/mesa/pipe/softpipe/sp_surface.c b/src/mesa/pipe/softpipe/sp_surface.c index 1dc494d6ff8..c81e0f9c188 100644 --- a/src/mesa/pipe/softpipe/sp_surface.c +++ b/src/mesa/pipe/softpipe/sp_surface.c @@ -783,6 +783,11 @@ softpipe_put_tile_rgba(struct pipe_context *pipe, case PIPE_FORMAT_A1R5G5B5_UNORM: /*a1r5g5b5_put_tile(ps, x, y, w, h, p);*/ break; + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_R8G8B8A8_UNORM: + /* XXX need these */ + fprintf(stderr, "unsup pipe format in softpipe_put_tile_rgba()\n"); + break; case PIPE_FORMAT_U_L8: /*l8_put_tile(ps, x, y, w, h, p);*/ break; diff --git a/src/mesa/pipe/xlib/xm_api.c b/src/mesa/pipe/xlib/xm_api.c index 4021af187c7..142074bc650 100644 --- a/src/mesa/pipe/xlib/xm_api.c +++ b/src/mesa/pipe/xlib/xm_api.c @@ -251,6 +251,52 @@ xmesa_get_window_size(XMesaDisplay *dpy, XMesaBuffer b, } +/** + * Choose the pixel format for the given visual. + * This will tell the gallium driver how to pack pixel data into + * drawing surfaces. + */ +static GLuint +choose_pixel_format(XMesaVisual v) +{ + if ( GET_REDMASK(v) == 0x0000ff + && GET_GREENMASK(v) == 0x00ff00 + && GET_BLUEMASK(v) == 0xff0000 + && v->BitsPerPixel == 32) { + if (CHECK_BYTE_ORDER(v)) { + /* no byteswapping needed */ + return 0 /* PIXEL_FORMAT_U_A8_B8_G8_R8 */; + } + else { + return PIPE_FORMAT_R8G8B8A8_UNORM; + } + } + else if ( GET_REDMASK(v) == 0xff0000 + && GET_GREENMASK(v) == 0x00ff00 + && GET_BLUEMASK(v) == 0x0000ff + && v->BitsPerPixel == 32) { + if (CHECK_BYTE_ORDER(v)) { + /* no byteswapping needed */ + return PIPE_FORMAT_A8R8G8B8_UNORM; + } + else { + return PIPE_FORMAT_B8G8R8A8_UNORM; + } + } + else if ( GET_REDMASK(v) == 0xf800 + && GET_GREENMASK(v) == 0x07e0 + && GET_BLUEMASK(v) == 0x001f + && CHECK_BYTE_ORDER(v) + && v->BitsPerPixel == 16) { + /* 5-6-5 RGB */ + return PIPE_FORMAT_R5G6B5_UNORM; + } + + assert(0); + return 0; +} + + /**********************************************************************/ /***** Linked list of XMesaBuffers *****/ @@ -276,6 +322,7 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type, { XMesaBuffer b; GLframebuffer *fb; + enum pipe_format colorFormat, depthFormat, stencilFormat; ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER); @@ -289,10 +336,35 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type, b->type = type; b->cmap = cmap; + /* determine PIPE_FORMATs for buffers */ + colorFormat = choose_pixel_format(vis); + + if (vis->mesa_visual.depthBits == 0) + depthFormat = PIPE_FORMAT_NONE; + else if (vis->mesa_visual.depthBits <= 16) + depthFormat = PIPE_FORMAT_Z16_UNORM; + else if (vis->mesa_visual.depthBits <= 24) + depthFormat = PIPE_FORMAT_S8Z24_UNORM; + else + depthFormat = PIPE_FORMAT_Z32_UNORM; + + if (vis->mesa_visual.stencilBits == 8) { + if (depthFormat == PIPE_FORMAT_S8Z24_UNORM) + stencilFormat = depthFormat; + else + stencilFormat = PIPE_FORMAT_S8_UNORM; + } + else { + stencilFormat = PIPE_FORMAT_NONE; + } + + /* * Create framebuffer, but we'll plug in our own renderbuffers below. */ - b->stfb = st_create_framebuffer(&vis->mesa_visual, GL_TRUE, (void *) b); + b->stfb = st_create_framebuffer(&vis->mesa_visual, GL_TRUE, + colorFormat, depthFormat, stencilFormat, + (void *) b); fb = &b->stfb->Base; /* @@ -387,52 +459,6 @@ xmesa_free_buffer(XMesaBuffer buffer) /**********************************************************************/ -/** - * Choose the pixel format for the given visual. - * This will tell the gallium driver how to pack pixel data into - * drawing surfaces. - */ -static GLuint -choose_pixel_format(XMesaVisual v) -{ - if ( GET_REDMASK(v) == 0x0000ff - && GET_GREENMASK(v) == 0x00ff00 - && GET_BLUEMASK(v) == 0xff0000 - && v->BitsPerPixel == 32) { - if (CHECK_BYTE_ORDER(v)) { - /* no byteswapping needed */ - return 0 /* PIXEL_FORMAT_U_A8_B8_G8_R8 */; - } - else { - return PIPE_FORMAT_R8G8B8A8_UNORM; - } - } - else if ( GET_REDMASK(v) == 0xff0000 - && GET_GREENMASK(v) == 0x00ff00 - && GET_BLUEMASK(v) == 0x0000ff - && v->BitsPerPixel == 32) { - if (CHECK_BYTE_ORDER(v)) { - /* no byteswapping needed */ - return PIPE_FORMAT_A8R8G8B8_UNORM; - } - else { - return PIPE_FORMAT_B8G8R8A8_UNORM; - } - } - else if ( GET_REDMASK(v) == 0xf800 - && GET_GREENMASK(v) == 0x07e0 - && GET_BLUEMASK(v) == 0x001f - && CHECK_BYTE_ORDER(v) - && v->BitsPerPixel == 16) { - /* 5-6-5 RGB */ - return PIPE_FORMAT_R5G6B5_UNORM; - } - - assert(0); - return 0; -} - - /** * When a context is bound for the first time, we can finally finish * initializing the context's visual and buffer information. diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 047de412e32..254740ff20a 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -87,9 +87,7 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, { struct pipe_context *pipe = ctx->st->pipe; struct st_renderbuffer *strb = st_renderbuffer(rb); - uint type = strb->screenSurface ? PIPE_SCREEN_SURFACE : PIPE_SURFACE; - const enum pipe_format pipeFormat - = st_choose_pipe_format(pipe, internalFormat, GL_NONE, GL_NONE, type); + enum pipe_format pipeFormat; GLbitfield flags = 0x0; /* XXX needed? */ if (!strb->surface) { @@ -106,6 +104,18 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, pipe->winsys->buffer_reference(pipe->winsys, &strb->surface->buffer, NULL); + /* Determine surface format here */ + if (strb->format != PIPE_FORMAT_NONE) { + assert(strb->format != 0); + /* we'll hit this for front/back color bufs */ + pipeFormat = strb->format; + } + else { + pipeFormat = st_choose_renderbuffer_format(pipe, internalFormat); + } + + init_renderbuffer_bits(strb, pipeFormat); + pipe->winsys->surface_alloc_storage(pipe->winsys, strb->surface, width, @@ -185,6 +195,7 @@ st_new_renderbuffer(GLcontext *ctx, GLuint name) strb->Base.Delete = st_renderbuffer_delete; strb->Base.AllocStorage = st_renderbuffer_alloc_storage; strb->Base.GetPointer = null_get_pointer; + strb->format = PIPE_FORMAT_NONE; return &strb->Base; } return NULL; @@ -193,12 +204,10 @@ st_new_renderbuffer(GLcontext *ctx, GLuint name) /** * Allocate a renderbuffer for a an on-screen window (not a user-created - * renderbuffer). The window system code determines the internal format. - * \param screenSurface indicates if the renderbuffer is a front/back color - * buffer that'll be displayed/copied to the screen + * renderbuffer). The window system code determines the format. */ struct gl_renderbuffer * -st_new_renderbuffer_fb(GLenum intFormat, GLboolean screenSurface) +st_new_renderbuffer_fb(enum pipe_format format) { struct st_renderbuffer *strb; @@ -210,28 +219,37 @@ st_new_renderbuffer_fb(GLenum intFormat, GLboolean screenSurface) _mesa_init_renderbuffer(&strb->Base, 0); strb->Base.ClassID = 0x4242; /* just a unique value */ - strb->Base.InternalFormat = intFormat; - strb->screenSurface = screenSurface; - - switch (intFormat) { - case GL_RGB5: - case GL_RGBA8: - case GL_RGBA16: + strb->format = format; + + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_A1R5G5B5_UNORM: + case PIPE_FORMAT_A4R4G4B4_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + strb->Base.InternalFormat = GL_RGBA; strb->Base._BaseFormat = GL_RGBA; break; - case GL_DEPTH_COMPONENT16: - case GL_DEPTH_COMPONENT32: + case PIPE_FORMAT_Z16_UNORM: + strb->Base.InternalFormat = GL_DEPTH_COMPONENT16; strb->Base._BaseFormat = GL_DEPTH_COMPONENT; break; - case GL_DEPTH24_STENCIL8_EXT: + case PIPE_FORMAT_Z32_UNORM: + strb->Base.InternalFormat = GL_DEPTH_COMPONENT32; + strb->Base._BaseFormat = GL_DEPTH_COMPONENT; + break; + case PIPE_FORMAT_S8Z24_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + strb->Base.InternalFormat = GL_DEPTH24_STENCIL8_EXT; strb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT; break; - case GL_STENCIL_INDEX8_EXT: - strb->Base._BaseFormat = GL_STENCIL_INDEX; + case PIPE_FORMAT_R16G16B16A16_SNORM: + strb->Base.InternalFormat = GL_RGBA16; + strb->Base._BaseFormat = GL_RGBA; break; default: _mesa_problem(NULL, - "Unexpected intFormat in st_new_renderbuffer"); + "Unexpected format in st_new_renderbuffer_fb"); return NULL; } @@ -248,6 +266,7 @@ st_new_renderbuffer_fb(GLenum intFormat, GLboolean screenSurface) + /** * Called via ctx->Driver.BindFramebufferEXT(). */ diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h index bd85bfc549f..21e531d1d06 100644 --- a/src/mesa/state_tracker/st_cb_fbo.h +++ b/src/mesa/state_tracker/st_cb_fbo.h @@ -39,7 +39,7 @@ struct st_renderbuffer { struct gl_renderbuffer Base; struct pipe_surface *surface; - GLboolean screenSurface; /**< A front/back colorbuffer? */ + enum pipe_format format; /** preferred format, or PIPE_FORMAT_NONE */ }; @@ -51,8 +51,7 @@ st_renderbuffer(struct gl_renderbuffer *rb) extern struct gl_renderbuffer * -st_new_renderbuffer_fb(GLenum intFormat, GLboolean screen_surface); - +st_new_renderbuffer_fb(enum pipe_format format); extern void st_init_fbo_functions(struct dd_function_table *functions); diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c index 287a0054b92..2a23445ca2b 100644 --- a/src/mesa/state_tracker/st_format.c +++ b/src/mesa/state_tracker/st_format.c @@ -283,9 +283,9 @@ static GLuint default_rgba_format(struct pipe_context *pipe, uint type) { static const enum pipe_format colorFormats[] = { - PIPE_FORMAT_R8G8B8A8_UNORM, PIPE_FORMAT_A8R8G8B8_UNORM, PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_R8G8B8A8_UNORM, PIPE_FORMAT_R5G6B5_UNORM }; uint i; @@ -334,56 +334,22 @@ default_depth_format(struct pipe_context *pipe, uint type) /** - * Choose the PIPE_FORMAT_ to use for storing a texture image based - * on the user's internalFormat, format and type parameters. - * We query the pipe device for a list of formats which it supports - * and choose from them. - * If we find a device that needs a more intricate selection mechanism, - * this function _could_ get pushed down into the pipe device. - * - * Note: also used for glRenderbufferStorageEXT() - * - * Note: format and type may be GL_NONE (see renderbuffers) + * Choose the PIPE_FORMAT_ to use for user-created renderbuffers. * * \return PIPE_FORMAT_NONE if error/problem. */ -GLuint -st_choose_pipe_format(struct pipe_context *pipe, GLint internalFormat, - GLenum format, GLenum type, uint surfType) +enum pipe_format +st_choose_renderbuffer_format(struct pipe_context *pipe, GLint internalFormat) { - assert(surfType == PIPE_TEXTURE || - surfType == PIPE_SURFACE || - surfType == PIPE_SCREEN_SURFACE); + uint surfType = PIPE_SURFACE; switch (internalFormat) { case 4: case GL_RGBA: case GL_COMPRESSED_RGBA: - if (format == GL_BGRA) { - if (type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT_8_8_8_8_REV) { - if (pipe->is_format_supported( pipe, PIPE_FORMAT_A8R8G8B8_UNORM, surfType )) - return PIPE_FORMAT_A8R8G8B8_UNORM; - } - else if (type == GL_UNSIGNED_SHORT_4_4_4_4_REV) { - if (pipe->is_format_supported( pipe, PIPE_FORMAT_A4R4G4B4_UNORM, surfType )) - return PIPE_FORMAT_A4R4G4B4_UNORM; - } - else if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV) { - if (pipe->is_format_supported( pipe, PIPE_FORMAT_A1R5G5B5_UNORM, surfType )) - return PIPE_FORMAT_A1R5G5B5_UNORM; - } - } - return default_rgba_format( pipe, surfType ); - case 3: case GL_RGB: case GL_COMPRESSED_RGB: - if (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) { - if (pipe->is_format_supported( pipe, PIPE_FORMAT_R5G6B5_UNORM, surfType )) - return PIPE_FORMAT_R5G6B5_UNORM; - } - return default_rgba_format( pipe, surfType ); - case GL_RGBA8: case GL_RGB10_A2: case GL_RGBA12: @@ -434,7 +400,7 @@ st_choose_pipe_format(struct pipe_context *pipe, GLint internalFormat, case GL_LUMINANCE12: case GL_LUMINANCE16: case GL_COMPRESSED_LUMINANCE: - if (pipe->is_format_supported( pipe, PIPE_FORMAT_U_A8, surfType )) + if (pipe->is_format_supported( pipe, PIPE_FORMAT_U_L8, surfType )) return PIPE_FORMAT_U_A8; return default_rgba_format( pipe, surfType ); @@ -461,18 +427,10 @@ st_choose_pipe_format(struct pipe_context *pipe, GLint internalFormat, return PIPE_FORMAT_U_I8; return default_rgba_format( pipe, surfType ); +#if 0 + /* not supported for renderbuffers */ case GL_YCBCR_MESA: - if (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE) { - if (pipe->is_format_supported( pipe, PIPE_FORMAT_YCBCR, surfType )) - return PIPE_FORMAT_YCBCR; - } - else { - if (pipe->is_format_supported( pipe, PIPE_FORMAT_YCBCR_REV, surfType )) - return PIPE_FORMAT_YCBCR_REV; - } return PIPE_FORMAT_NONE; - -#if 0 case GL_COMPRESSED_RGB_FXT1_3DFX: return &_mesa_texformat_rgb_fxt1; case GL_COMPRESSED_RGBA_FXT1_3DFX: diff --git a/src/mesa/state_tracker/st_format.h b/src/mesa/state_tracker/st_format.h index ebff7c5b912..c9a11de5043 100644 --- a/src/mesa/state_tracker/st_format.h +++ b/src/mesa/state_tracker/st_format.h @@ -63,9 +63,8 @@ extern enum pipe_format st_mesa_format_to_pipe_format(GLuint mesaFormat); -extern GLuint -st_choose_pipe_format(struct pipe_context *pipe, GLint internalFormat, - GLenum format, GLenum type, uint surfType); +extern enum pipe_format +st_choose_renderbuffer_format(struct pipe_context *pipe, GLint internalFormat); extern const struct gl_texture_format * diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 454306b8743..b81a894ef18 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -35,15 +35,16 @@ #include "st_cb_fbo.h" -struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual, - boolean createRenderbuffers, - void *private) +struct st_framebuffer * +st_create_framebuffer( const __GLcontextModes *visual, + boolean createRenderbuffers, /* XXX remove? */ + enum pipe_format colorFormat, + enum pipe_format depthFormat, + enum pipe_format stencilFormat, + void *private) { - struct st_framebuffer *stfb - = CALLOC_STRUCT(st_framebuffer); + struct st_framebuffer *stfb = CALLOC_STRUCT(st_framebuffer); if (stfb) { - GLenum rgbFormat = (visual->redBits == 5 ? GL_RGB5 : GL_RGBA8); - _mesa_initialize_framebuffer(&stfb->Base, visual); if (createRenderbuffers) { @@ -52,20 +53,20 @@ struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual, /* XXX allocation should only happen in the unusual case it's actually needed */ struct gl_renderbuffer *rb - = st_new_renderbuffer_fb(rgbFormat, GL_TRUE); + = st_new_renderbuffer_fb(colorFormat); _mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb); } if (visual->doubleBufferMode) { struct gl_renderbuffer *rb - = st_new_renderbuffer_fb(rgbFormat, GL_TRUE); + = st_new_renderbuffer_fb(colorFormat); _mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb); } if (visual->depthBits == 24 && visual->stencilBits == 8) { /* combined depth/stencil buffer */ struct gl_renderbuffer *depthStencilRb - = st_new_renderbuffer_fb(GL_DEPTH24_STENCIL8_EXT, GL_FALSE); + = st_new_renderbuffer_fb(depthFormat); /* note: bind RB to two attachment points */ _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthStencilRb); _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, depthStencilRb); @@ -76,26 +77,26 @@ struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual, if (visual->depthBits == 32) { /* 32-bit depth buffer */ struct gl_renderbuffer *depthRb - = st_new_renderbuffer_fb(GL_DEPTH_COMPONENT32, GL_FALSE); + = st_new_renderbuffer_fb(depthFormat); _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); } else if (visual->depthBits == 24) { /* 24-bit depth buffer, ignore stencil bits */ struct gl_renderbuffer *depthRb - = st_new_renderbuffer_fb(GL_DEPTH24_STENCIL8_EXT, GL_FALSE); + = st_new_renderbuffer_fb(depthFormat); _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); } else if (visual->depthBits > 0) { /* 16-bit depth buffer */ struct gl_renderbuffer *depthRb - = st_new_renderbuffer_fb(GL_DEPTH_COMPONENT16, GL_FALSE); + = st_new_renderbuffer_fb(depthFormat); _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); } if (visual->stencilBits > 0) { /* 8-bit stencil */ struct gl_renderbuffer *stencilRb - = st_new_renderbuffer_fb(GL_STENCIL_INDEX8_EXT, GL_FALSE); + = st_new_renderbuffer_fb(stencilFormat); _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, stencilRb); } } @@ -103,7 +104,7 @@ struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual, if (visual->accumRedBits > 0) { /* 16-bit/channel accum */ struct gl_renderbuffer *accumRb - = st_new_renderbuffer_fb(GL_RGBA16, GL_FALSE); + = st_new_renderbuffer_fb(PIPE_FORMAT_R16G16B16A16_SNORM); _mesa_add_renderbuffer(&stfb->Base, BUFFER_ACCUM, accumRb); } } diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h index 307635936bc..558b20f1e87 100644 --- a/src/mesa/state_tracker/st_public.h +++ b/src/mesa/state_tracker/st_public.h @@ -29,6 +29,7 @@ #define ST_PUBLIC_H #include "pipe/p_compiler.h" +#include "pipe/p_format.h" #define ST_SURFACE_FRONT_LEFT 0 @@ -55,6 +56,9 @@ void st_copy_context_state(struct st_context *dst, struct st_context *src, struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual, boolean createRenderbuffers, + enum pipe_format colorFormat, + enum pipe_format depthFormat, + enum pipe_format stencilFormat, void *privateData); void st_resize_framebuffer( struct st_framebuffer *stfb, -- cgit v1.2.3 From c664302c3e34a29b4bbb02fd3789dd3f7d92849c Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 19 Dec 2007 13:45:00 -0700 Subject: Fix problem with initial viewport/scissor size. If an app never called glViewport, the viewport size was always 0 by 0 pixels. Now pass initial size to st_create_framebuffer() and initialize the viewport and scissor bounds in st_make_current(). This could also be fixed by ensuring the gl_framebuffers passed to _mesa_make_current() were initialized to the right size. But that involves allocating the renderbuffers/pipe_surfaces earlier and that runs into some other issues ATM. Also remove obsolete createRenderbuffers param to st_create_framebuffer(). --- src/mesa/drivers/dri/intel_winsys/intel_screen.c | 4 +- src/mesa/pipe/xlib/xm_api.c | 8 +- src/mesa/state_tracker/st_context.c | 14 +++ src/mesa/state_tracker/st_context.h | 1 + src/mesa/state_tracker/st_framebuffer.c | 109 +++++++++++------------ src/mesa/state_tracker/st_public.h | 2 +- 6 files changed, 79 insertions(+), 59 deletions(-) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/drivers/dri/intel_winsys/intel_screen.c b/src/mesa/drivers/dri/intel_winsys/intel_screen.c index bce6c5699a1..9e31c013a95 100644 --- a/src/mesa/drivers/dri/intel_winsys/intel_screen.c +++ b/src/mesa/drivers/dri/intel_winsys/intel_screen.c @@ -297,10 +297,12 @@ intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, else stencilFormat = PIPE_FORMAT_NONE; - intelfb->stfb = st_create_framebuffer(visual, GL_TRUE, + intelfb->stfb = st_create_framebuffer(visual, colorFormat, depthFormat, stencilFormat, + driDrawPriv->w, + driDrawPriv->h, (void*) intelfb); if (!intelfb->stfb) { free(intelfb); diff --git a/src/mesa/pipe/xlib/xm_api.c b/src/mesa/pipe/xlib/xm_api.c index 186a712b52c..ebf4c21eaf6 100644 --- a/src/mesa/pipe/xlib/xm_api.c +++ b/src/mesa/pipe/xlib/xm_api.c @@ -207,7 +207,7 @@ static GLboolean window_exists( XMesaDisplay *dpy, Window win ) } static Status -get_drawable_size( XMesaDisplay *dpy, Drawable d, GLuint *width, GLuint *height ) +get_drawable_size( XMesaDisplay *dpy, Drawable d, uint *width, uint *height ) { Window root; Status stat; @@ -323,6 +323,7 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type, XMesaBuffer b; GLframebuffer *fb; enum pipe_format colorFormat, depthFormat, stencilFormat; + uint width, height; ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER); @@ -359,11 +360,14 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type, } + get_drawable_size(vis->display, d, &width, &height); + /* * Create framebuffer, but we'll plug in our own renderbuffers below. */ - b->stfb = st_create_framebuffer(&vis->mesa_visual, GL_TRUE, + b->stfb = st_create_framebuffer(&vis->mesa_visual, colorFormat, depthFormat, stencilFormat, + width, height, (void *) b); fb = &b->stfb->Base; diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 524e06fb00a..1d26da474e0 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -28,6 +28,8 @@ #include "main/imports.h" #include "main/context.h" #include "main/extensions.h" +#include "main/matrix.h" +#include "main/buffers.h" #include "vbo/vbo.h" #include "shader/shader_api.h" #include "st_public.h" @@ -163,7 +165,19 @@ void st_make_current(struct st_context *st, struct st_framebuffer *read) { if (st) { + GLboolean firstTime = st->ctx->FirstTimeCurrent; _mesa_make_current(st->ctx, &draw->Base, &read->Base); + /* Need to initialize viewport here since draw->Base->Width/Height + * will still be zero at this point. + * This could be improved, but would require rather extensive work + * elsewhere (allocate rb surface storage sooner) + */ + if (firstTime) { + GLuint w = draw->InitWidth, h = draw->InitHeight; + _mesa_set_viewport(st->ctx, 0, 0, w, h); + _mesa_set_scissor(st->ctx, 0, 0, w, h); + + } } else { _mesa_make_current(NULL, NULL, NULL); diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index c3919d474cf..0f40f3ceee9 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -191,6 +191,7 @@ struct st_framebuffer { GLframebuffer Base; void *Private; + GLuint InitWidth, InitHeight; }; diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index b81a894ef18..5e0943f75cc 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -37,80 +37,79 @@ struct st_framebuffer * st_create_framebuffer( const __GLcontextModes *visual, - boolean createRenderbuffers, /* XXX remove? */ enum pipe_format colorFormat, enum pipe_format depthFormat, enum pipe_format stencilFormat, + uint width, uint height, void *private) { struct st_framebuffer *stfb = CALLOC_STRUCT(st_framebuffer); if (stfb) { _mesa_initialize_framebuffer(&stfb->Base, visual); - if (createRenderbuffers) { - { - /* fake frontbuffer */ - /* XXX allocation should only happen in the unusual case - it's actually needed */ - struct gl_renderbuffer *rb - = st_new_renderbuffer_fb(colorFormat); - _mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb); - } + { + /* fake frontbuffer */ + /* XXX allocation should only happen in the unusual case + it's actually needed */ + struct gl_renderbuffer *rb + = st_new_renderbuffer_fb(colorFormat); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb); + } - if (visual->doubleBufferMode) { - struct gl_renderbuffer *rb - = st_new_renderbuffer_fb(colorFormat); - _mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb); - } + if (visual->doubleBufferMode) { + struct gl_renderbuffer *rb + = st_new_renderbuffer_fb(colorFormat); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb); + } + + if (visual->depthBits == 24 && visual->stencilBits == 8) { + /* combined depth/stencil buffer */ + struct gl_renderbuffer *depthStencilRb + = st_new_renderbuffer_fb(depthFormat); + /* note: bind RB to two attachment points */ + _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthStencilRb); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, depthStencilRb); + } + else { + /* separate depth and/or stencil */ - if (visual->depthBits == 24 && visual->stencilBits == 8) { - /* combined depth/stencil buffer */ - struct gl_renderbuffer *depthStencilRb + if (visual->depthBits == 32) { + /* 32-bit depth buffer */ + struct gl_renderbuffer *depthRb = st_new_renderbuffer_fb(depthFormat); - /* note: bind RB to two attachment points */ - _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthStencilRb); - _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, depthStencilRb); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); } - else { - /* separate depth and/or stencil */ - - if (visual->depthBits == 32) { - /* 32-bit depth buffer */ - struct gl_renderbuffer *depthRb - = st_new_renderbuffer_fb(depthFormat); - _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); - } - else if (visual->depthBits == 24) { - /* 24-bit depth buffer, ignore stencil bits */ - struct gl_renderbuffer *depthRb - = st_new_renderbuffer_fb(depthFormat); - _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); - } - else if (visual->depthBits > 0) { - /* 16-bit depth buffer */ - struct gl_renderbuffer *depthRb - = st_new_renderbuffer_fb(depthFormat); - _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); - } - - if (visual->stencilBits > 0) { - /* 8-bit stencil */ - struct gl_renderbuffer *stencilRb - = st_new_renderbuffer_fb(stencilFormat); - _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, stencilRb); - } + else if (visual->depthBits == 24) { + /* 24-bit depth buffer, ignore stencil bits */ + struct gl_renderbuffer *depthRb + = st_new_renderbuffer_fb(depthFormat); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); + } + else if (visual->depthBits > 0) { + /* 16-bit depth buffer */ + struct gl_renderbuffer *depthRb + = st_new_renderbuffer_fb(depthFormat); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); } - if (visual->accumRedBits > 0) { - /* 16-bit/channel accum */ - struct gl_renderbuffer *accumRb - = st_new_renderbuffer_fb(PIPE_FORMAT_R16G16B16A16_SNORM); - _mesa_add_renderbuffer(&stfb->Base, BUFFER_ACCUM, accumRb); + if (visual->stencilBits > 0) { + /* 8-bit stencil */ + struct gl_renderbuffer *stencilRb + = st_new_renderbuffer_fb(stencilFormat); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, stencilRb); } } - stfb->Base.Initialized = GL_TRUE; + if (visual->accumRedBits > 0) { + /* 16-bit/channel accum */ + struct gl_renderbuffer *accumRb + = st_new_renderbuffer_fb(PIPE_FORMAT_R16G16B16A16_SNORM); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_ACCUM, accumRb); + } + stfb->Base.Initialized = GL_TRUE; + stfb->InitWidth = width; + stfb->InitHeight = height; stfb->Private = private; } return stfb; diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h index 558b20f1e87..ed5ef1f1590 100644 --- a/src/mesa/state_tracker/st_public.h +++ b/src/mesa/state_tracker/st_public.h @@ -55,10 +55,10 @@ void st_copy_context_state(struct st_context *dst, struct st_context *src, uint mask); struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual, - boolean createRenderbuffers, enum pipe_format colorFormat, enum pipe_format depthFormat, enum pipe_format stencilFormat, + uint width, uint height, void *privateData); void st_resize_framebuffer( struct st_framebuffer *stfb, -- cgit v1.2.3 From a85535b7cb0886f23e5686e37d1fa54394cdece4 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 20 Dec 2007 13:47:46 +0000 Subject: gallium: make state tracker explictly ask for rendercache flushes --- src/mesa/state_tracker/st_cb_accum.c | 2 +- src/mesa/state_tracker/st_cb_drawpixels.c | 4 ++-- src/mesa/state_tracker/st_cb_fbo.c | 2 +- src/mesa/state_tracker/st_cb_flush.c | 4 ++-- src/mesa/state_tracker/st_cb_readpixels.c | 2 +- src/mesa/state_tracker/st_framebuffer.c | 3 ++- 6 files changed, 9 insertions(+), 8 deletions(-) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c index ea0b1187fc9..cf2e9db51cb 100644 --- a/src/mesa/state_tracker/st_cb_accum.c +++ b/src/mesa/state_tracker/st_cb_accum.c @@ -321,7 +321,7 @@ st_Accum(GLcontext *ctx, GLenum op, GLfloat value) const GLint height = ctx->DrawBuffer->_Ymax - ypos; /* make sure color bufs aren't cached */ - pipe->flush(pipe, 0); + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE); switch (op) { case GL_ADD: diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index e70a5b49e12..2db12c653b6 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -849,7 +849,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, GLint skipPixels; ubyte *stmap; - pipe->flush(pipe, 0); + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE); /* map the stencil buffer */ stmap = pipe_surface_map(ps); @@ -1208,7 +1208,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, uint format; /* make sure rendering has completed */ - pipe->flush(pipe, 0x0); + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE); st_validate_state(st); diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index c40f75417fa..bc0f26ffb05 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -365,7 +365,7 @@ st_finish_render_texture(GLcontext *ctx, assert(strb); - ctx->st->pipe->flush(ctx->st->pipe, 0x0); + ctx->st->pipe->flush(ctx->st->pipe, PIPE_FLUSH_RENDER_CACHE); /* printf("FINISH RENDER TO TEXTURE surf=%p\n", strb->surface); diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c index 95149a32006..9808b1f8f65 100644 --- a/src/mesa/state_tracker/st_cb_flush.c +++ b/src/mesa/state_tracker/st_cb_flush.c @@ -83,7 +83,7 @@ void st_flush( struct st_context *st, uint pipeFlushFlags ) */ static void st_Flush(GLcontext *ctx) { - st_flush(ctx->st, 0x0); + st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE); } @@ -92,7 +92,7 @@ static void st_Flush(GLcontext *ctx) */ static void st_Finish(GLcontext *ctx) { - st_flush(ctx->st, PIPE_FLUSH_WAIT); + st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_WAIT); } diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 96829fcfa0f..b0c9275c6f8 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -155,7 +155,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, } /* make sure rendering has completed */ - pipe->flush(pipe, 0x0); + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE); if (pack->BufferObj && pack->BufferObj->Name) { /* reading into a PBO */ diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 5e0943f75cc..7ddc74e355c 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -33,6 +33,7 @@ #include "st_public.h" #include "st_context.h" #include "st_cb_fbo.h" +#include "pipe/p_defines.h" struct st_framebuffer * @@ -170,7 +171,7 @@ st_notify_swapbuffers(struct st_framebuffer *stfb) GET_CURRENT_CONTEXT(ctx); if (ctx && ctx->DrawBuffer == &stfb->Base) { - st_flush(ctx->st, 0x0); + st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE); } } -- cgit v1.2.3 From 596a92ee7590cd3819aad0139cf779d28e57874d Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Jan 2008 20:22:49 +0000 Subject: gallium: specialize glFlush vs other flush semantics --- src/mesa/state_tracker/st_cb_flush.c | 44 ++++++++++++++++++++++++--------- src/mesa/state_tracker/st_framebuffer.c | 7 +++++- 2 files changed, 38 insertions(+), 13 deletions(-) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c index 9808b1f8f65..dbec993f1ba 100644 --- a/src/mesa/state_tracker/st_cb_flush.c +++ b/src/mesa/state_tracker/st_cb_flush.c @@ -45,21 +45,32 @@ void st_flush( struct st_context *st, uint pipeFlushFlags ) { - GLframebuffer *fb = st->ctx->DrawBuffer; - FLUSH_VERTICES(st->ctx, 0); - /* If there has been no rendering to the frontbuffer, consider - * short-circuiting this, or perhaps pass an "optional" flag down - * to the driver so that it can make the decision. - */ st->pipe->flush( st->pipe, pipeFlushFlags ); +} + + +static void st_gl_flush( struct st_context *st, uint pipeFlushFlags ) +{ + GLframebuffer *fb = st->ctx->DrawBuffer; + + FLUSH_VERTICES(st->ctx, 0); if (!fb) return; /* XXX: temporary hack. This flag should only be set if we do any * rendering to the front buffer. + * + * Further more, the scissor rectangle could be tracked to + * construct a dirty region of the front buffer, to avoid + * situations where it must be copied repeatedly. + * + * In the extreme case, some kind of timer could be set up to allow + * coalescing of multiple flushes to the frontbuffer, which can be + * quite a performance drain if there are a sufficient number of + * them. */ st->flags.frontbuffer_dirty = (fb->_ColorDrawBufferMask[0] & BUFFER_BIT_FRONT_LEFT); @@ -69,6 +80,15 @@ void st_flush( struct st_context *st, uint pipeFlushFlags ) = st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); struct pipe_surface *front_surf = strb->surface; + /* If we aren't rendering to the frontbuffer, this is a noop. + * This should be uncontroversial for glFlush, though people may + * feel more strongly about glFinish. + * + * Additionally, need to make sure that the frontbuffer_dirty + * flag really gets set on frontbuffer rendering. + */ + st->pipe->flush( st->pipe, pipeFlushFlags ); + /* Hook for copying "fake" frontbuffer if necessary: */ st->pipe->winsys->flush_frontbuffer( st->pipe->winsys, front_surf, @@ -81,23 +101,23 @@ void st_flush( struct st_context *st, uint pipeFlushFlags ) /** * Called via ctx->Driver.Flush() */ -static void st_Flush(GLcontext *ctx) +static void st_glFlush(GLcontext *ctx) { - st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE); + st_gl_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE); } /** * Called via ctx->Driver.Finish() */ -static void st_Finish(GLcontext *ctx) +static void st_glFinish(GLcontext *ctx) { - st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_WAIT); + st_gl_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_WAIT); } void st_init_flush_functions(struct dd_function_table *functions) { - functions->Flush = st_Flush; - functions->Finish = st_Finish; + functions->Flush = st_glFlush; + functions->Finish = st_glFinish; } diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 7ddc74e355c..42e8e24896c 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -34,6 +34,7 @@ #include "st_context.h" #include "st_cb_fbo.h" #include "pipe/p_defines.h" +#include "pipe/p_context.h" struct st_framebuffer * @@ -171,7 +172,11 @@ st_notify_swapbuffers(struct st_framebuffer *stfb) GET_CURRENT_CONTEXT(ctx); if (ctx && ctx->DrawBuffer == &stfb->Base) { - st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE); + st_flush( ctx->st, + PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_SWAPBUFFERS); + } +} + } } -- cgit v1.2.3 From 6d2d41294ce7de78d56051261bb4fc345517bf9b Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Jan 2008 20:23:32 +0000 Subject: gallium: add notify_swapbuffers_complete, use it to set surfaces to undefined state --- src/mesa/state_tracker/st_framebuffer.c | 20 ++++++++++++++++++++ src/mesa/state_tracker/st_public.h | 1 + 2 files changed, 21 insertions(+) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 42e8e24896c..bca3fa5c383 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -177,6 +177,26 @@ st_notify_swapbuffers(struct st_framebuffer *stfb) } } + +/** + * Quick hack - allows the winsys to inform the driver that surface + * states are now undefined after a glXSwapBuffers or similar. + */ +void +st_notify_swapbuffers_complete(struct st_framebuffer *stfb) +{ + GET_CURRENT_CONTEXT(ctx); + + if (ctx && ctx->DrawBuffer == &stfb->Base) { + struct st_renderbuffer *strb; + int i; + + for (i = 0; i < BUFFER_COUNT; i++) { + if (stfb->Base.Attachment[i].Renderbuffer) { + strb = st_renderbuffer(stfb->Base.Attachment[i].Renderbuffer); + strb->surface->status = PIPE_SURFACE_STATUS_UNDEFINED; + } + } } } diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h index 78a8fde82b5..3c397b126a9 100644 --- a/src/mesa/state_tracker/st_public.h +++ b/src/mesa/state_tracker/st_public.h @@ -81,5 +81,6 @@ void st_make_current(struct st_context *st, void st_flush( struct st_context *st, uint pipeFlushFlags ); void st_notify_swapbuffers(struct st_framebuffer *stfb); +void st_notify_swapbuffers_complete(struct st_framebuffer *stfb); #endif -- cgit v1.2.3 From b93cf55f4ecd94f5e9d5dda49d9092e3b769d044 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 26 Feb 2008 14:26:40 -0700 Subject: gallium: fix zero-sized viewport bug If st_create_framebuffer() is called with width=0, height=0 and the program never called glViewport, the viewport wasn't properly initalized. This fixes that. --- src/mesa/state_tracker/st_framebuffer.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index bca3fa5c383..47d47daf2a1 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -124,6 +124,17 @@ void st_resize_framebuffer( struct st_framebuffer *stfb, if (stfb->Base.Width != width || stfb->Base.Height != height) { GET_CURRENT_CONTEXT(ctx); if (ctx) { + if (stfb->InitWidth == 0 && stfb->InitHeight == 0) { + /* didn't have a valid size until now */ + stfb->InitWidth = width; + stfb->InitHeight = height; + if (ctx->Viewport.Width <= 1) { + /* set context's initial viewport/scissor size */ + _mesa_set_viewport(ctx, 0, 0, width, height); + _mesa_set_scissor(ctx, 0, 0, width, height); + } + } + _mesa_resize_framebuffer(ctx, &stfb->Base, width, height); assert(stfb->Base.Width == width); -- cgit v1.2.3 From d5ab6507f7c368e86f653e76b759f2e71273469f Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 26 Feb 2008 14:34:19 -0700 Subject: gallium: #includes to silence warnings --- src/mesa/state_tracker/st_framebuffer.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 47d47daf2a1..d46a9178b19 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -27,8 +27,10 @@ #include "main/imports.h" +#include "main/buffers.h" #include "main/context.h" #include "main/framebuffer.h" +#include "main/matrix.h" #include "main/renderbuffer.h" #include "st_public.h" #include "st_context.h" -- cgit v1.2.3 From 4abe1eb980ed76d2b2d3383eaab520d0aa2ae6f4 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Wed, 26 Mar 2008 09:36:40 +0000 Subject: gallium: Change pipe->flush() interface to optionally return a fence. The cell driver still uses an internal CELL_FLUSH_WAIT flag, in the long run proper fencing should be implemented for it. --- src/gallium/auxiliary/util/u_gen_mipmap.c | 2 +- src/gallium/drivers/cell/ppu/cell_flush.c | 15 +++++++--- src/gallium/drivers/cell/ppu/cell_flush.h | 5 +++- src/gallium/drivers/cell/ppu/cell_vbuf.c | 2 +- src/gallium/drivers/cell/ppu/cell_vertex_shader.c | 2 +- src/gallium/drivers/failover/fo_context.c | 4 +-- src/gallium/drivers/i915simple/i915_batch.h | 4 +-- src/gallium/drivers/i915simple/i915_blit.c | 4 +-- src/gallium/drivers/i915simple/i915_flush.c | 14 +++------- src/gallium/drivers/i915simple/i915_prim_emit.c | 2 +- src/gallium/drivers/i915simple/i915_prim_vbuf.c | 2 +- src/gallium/drivers/i915simple/i915_state_emit.c | 2 +- src/gallium/drivers/i915simple/i915_winsys.h | 5 ++-- src/gallium/drivers/i965simple/brw_flush.c | 13 ++------- src/gallium/drivers/softpipe/sp_flush.c | 10 +++---- src/gallium/drivers/softpipe/sp_flush.h | 4 ++- src/gallium/include/pipe/p_context.h | 5 ++-- src/gallium/include/pipe/p_defines.h | 3 +- src/gallium/winsys/dri/intel/intel_context.c | 4 +-- src/gallium/winsys/dri/intel/intel_winsys_i915.c | 25 ++++++++++------- src/gallium/winsys/xlib/xm_winsys.c | 31 +++++++++++++++++++++ src/mesa/state_tracker/st_cb_accum.c | 2 +- src/mesa/state_tracker/st_cb_drawpixels.c | 4 +-- src/mesa/state_tracker/st_cb_fbo.c | 2 +- src/mesa/state_tracker/st_cb_flush.c | 34 +++++++++++++---------- src/mesa/state_tracker/st_cb_readpixels.c | 2 +- src/mesa/state_tracker/st_framebuffer.c | 3 +- src/mesa/state_tracker/st_public.h | 5 +++- 28 files changed, 127 insertions(+), 83 deletions(-) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index e129c062be6..ed12768e7f8 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -935,7 +935,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, 4, /* verts */ 2); /* attribs/vert */ - pipe->flush(pipe, PIPE_FLUSH_WAIT); + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); /* need to signal that the texture has changed _after_ rendering to it */ pipe->texture_update(pipe, pt, face, (1 << dstLevel)); diff --git a/src/gallium/drivers/cell/ppu/cell_flush.c b/src/gallium/drivers/cell/ppu/cell_flush.c index 66a5627d844..3aaf3de6684 100644 --- a/src/gallium/drivers/cell/ppu/cell_flush.c +++ b/src/gallium/drivers/cell/ppu/cell_flush.c @@ -35,12 +35,19 @@ void -cell_flush(struct pipe_context *pipe, unsigned flags) +cell_flush(struct pipe_context *pipe, unsigned flags, + struct pipe_fence_handle **fence) { struct cell_context *cell = cell_context(pipe); + if (fence) { + *fence = NULL; + /* XXX: Implement real fencing */ + flags |= CELL_FLUSH_WAIT; + } + if (flags & PIPE_FLUSH_SWAPBUFFERS) - flags |= PIPE_FLUSH_WAIT; + flags |= CELL_FLUSH_WAIT; draw_flush( cell->draw ); cell_flush_int(pipe, flags); @@ -58,7 +65,7 @@ cell_flush_int(struct pipe_context *pipe, unsigned flags) ASSERT(!flushing); flushing = TRUE; - if (flags & PIPE_FLUSH_WAIT) { + if (flags & CELL_FLUSH_WAIT) { uint64_t *cmd = (uint64_t *) cell_batch_alloc(cell, sizeof(uint64_t)); *cmd = CELL_CMD_FINISH; } @@ -72,7 +79,7 @@ cell_flush_int(struct pipe_context *pipe, unsigned flags) } #endif - if (flags & PIPE_FLUSH_WAIT) { + if (flags & CELL_FLUSH_WAIT) { /* Wait for ack */ for (i = 0; i < cell->num_spus; i++) { uint k = wait_mbox_message(cell_global.spe_contexts[i]); diff --git a/src/gallium/drivers/cell/ppu/cell_flush.h b/src/gallium/drivers/cell/ppu/cell_flush.h index 7f940ae76b6..8f0645c4293 100644 --- a/src/gallium/drivers/cell/ppu/cell_flush.h +++ b/src/gallium/drivers/cell/ppu/cell_flush.h @@ -29,8 +29,11 @@ #ifndef CELL_FLUSH #define CELL_FLUSH +#define CELL_FLUSH_WAIT 0x80000000 + extern void -cell_flush(struct pipe_context *pipe, unsigned flags); +cell_flush(struct pipe_context *pipe, unsigned flags, + struct pipe_fence_handle **fence); extern void cell_flush_int(struct pipe_context *pipe, unsigned flags); diff --git a/src/gallium/drivers/cell/ppu/cell_vbuf.c b/src/gallium/drivers/cell/ppu/cell_vbuf.c index cc727ff4edb..3a181b585c5 100644 --- a/src/gallium/drivers/cell/ppu/cell_vbuf.c +++ b/src/gallium/drivers/cell/ppu/cell_vbuf.c @@ -243,7 +243,7 @@ cell_vbuf_draw(struct vbuf_render *vbr, #if 0 /* helpful for debug */ - cell_flush_int(&cell->pipe, PIPE_FLUSH_WAIT); + cell_flush_int(&cell->pipe, CELL_FLUSH_WAIT); #endif } diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c index f5c27852c14..b418857ccd8 100644 --- a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c @@ -133,7 +133,7 @@ cell_vertex_shader_queue_flush(struct draw_context *draw) vs->num_elts = n; send_mbox_message(cell_global.spe_contexts[0], CELL_CMD_VS_EXECUTE); - cell_flush_int(& cell->pipe, PIPE_FLUSH_WAIT); + cell_flush_int(& cell->pipe, CELL_FLUSH_WAIT); } draw->vs.post_nr = draw->vs.queue_nr; diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c index afc0d7eb1ec..cb95ba516f9 100644 --- a/src/gallium/drivers/failover/fo_context.c +++ b/src/gallium/drivers/failover/fo_context.c @@ -69,7 +69,7 @@ static boolean failover_draw_elements( struct pipe_context *pipe, start, count )) { - failover->hw->flush( failover->hw, ~0 ); + failover->hw->flush( failover->hw, ~0, NULL ); failover->mode = FO_SW; } } @@ -92,7 +92,7 @@ static boolean failover_draw_elements( struct pipe_context *pipe, * intervening flush. Unlikely to be much performance impact to * this: */ - failover->sw->flush( failover->sw, ~0 ); + failover->sw->flush( failover->sw, ~0, NULL ); } return TRUE; diff --git a/src/gallium/drivers/i915simple/i915_batch.h b/src/gallium/drivers/i915simple/i915_batch.h index fb88cd6db0d..4ea06ce02bf 100644 --- a/src/gallium/drivers/i915simple/i915_batch.h +++ b/src/gallium/drivers/i915simple/i915_batch.h @@ -44,9 +44,9 @@ #define ADVANCE_BATCH() -#define FLUSH_BATCH() do { \ +#define FLUSH_BATCH(fence) do { \ if (0) i915_dump_batchbuffer( i915 ); \ - i915->winsys->batch_flush( i915->winsys ); \ + i915->winsys->batch_flush( i915->winsys, fence ); \ i915->batch_start = NULL; \ i915->hardware_dirty = ~0; \ } while (0) diff --git a/src/gallium/drivers/i915simple/i915_blit.c b/src/gallium/drivers/i915simple/i915_blit.c index db4671ff553..24449e3fb33 100644 --- a/src/gallium/drivers/i915simple/i915_blit.c +++ b/src/gallium/drivers/i915simple/i915_blit.c @@ -70,7 +70,7 @@ i915_fill_blit(struct i915_context *i915, if (!BEGIN_BATCH(6, 1)) { - FLUSH_BATCH(); + FLUSH_BATCH(NULL); assert(BEGIN_BATCH(6, 1)); } OUT_BATCH(CMD); @@ -145,7 +145,7 @@ i915_copy_blit( struct i915_context *i915, if (!BEGIN_BATCH(8, 2)) { - FLUSH_BATCH(); + FLUSH_BATCH(NULL); assert(BEGIN_BATCH(8, 2)); } OUT_BATCH(CMD); diff --git a/src/gallium/drivers/i915simple/i915_flush.c b/src/gallium/drivers/i915simple/i915_flush.c index 96a54281f11..7d23e6b6b90 100644 --- a/src/gallium/drivers/i915simple/i915_flush.c +++ b/src/gallium/drivers/i915simple/i915_flush.c @@ -37,11 +37,9 @@ #include "i915_batch.h" -/** - * In future we may want a fence-like interface instead of finish. - */ static void i915_flush( struct pipe_context *pipe, - unsigned flags ) + unsigned flags, + struct pipe_fence_handle **fence ) { struct i915_context *i915 = i915_context(pipe); @@ -60,7 +58,7 @@ static void i915_flush( struct pipe_context *pipe, flush |= FLUSH_MAP_CACHE; if (!BEGIN_BATCH(1, 0)) { - FLUSH_BATCH(); + FLUSH_BATCH(NULL); assert(BEGIN_BATCH(1, 0)); } OUT_BATCH( flush ); @@ -69,11 +67,7 @@ static void i915_flush( struct pipe_context *pipe, /* If there are no flags, just flush pending commands to hardware: */ - FLUSH_BATCH(); - - if (flags & PIPE_FLUSH_WAIT) { - i915->winsys->batch_finish(i915->winsys); - } + FLUSH_BATCH(fence); } diff --git a/src/gallium/drivers/i915simple/i915_prim_emit.c b/src/gallium/drivers/i915simple/i915_prim_emit.c index d8de5178f60..b6fb0a6d88f 100644 --- a/src/gallium/drivers/i915simple/i915_prim_emit.c +++ b/src/gallium/drivers/i915simple/i915_prim_emit.c @@ -140,7 +140,7 @@ emit_prim( struct draw_stage *stage, assert(vertex_size >= 12); /* never smaller than 12 bytes */ if (!BEGIN_BATCH( 1 + nr * vertex_size / 4, 0 )) { - FLUSH_BATCH(); + FLUSH_BATCH(NULL); /* Make sure state is re-emitted after a flush: */ diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c index eb64f51943b..7fb2adbb53b 100644 --- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c @@ -161,7 +161,7 @@ i915_vbuf_render_draw( struct vbuf_render *render, i915_emit_hardware_state( i915 ); if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) { - FLUSH_BATCH(); + FLUSH_BATCH(NULL); /* Make sure state is re-emitted after a flush: */ diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c index a7498d22b7e..6f947d43468 100644 --- a/src/gallium/drivers/i915simple/i915_state_emit.c +++ b/src/gallium/drivers/i915simple/i915_state_emit.c @@ -115,7 +115,7 @@ i915_emit_hardware_state(struct i915_context *i915 ) #endif if(!BEGIN_BATCH(dwords, relocs)) { - FLUSH_BATCH(); + FLUSH_BATCH(NULL); assert(BEGIN_BATCH(dwords, relocs)); } diff --git a/src/gallium/drivers/i915simple/i915_winsys.h b/src/gallium/drivers/i915simple/i915_winsys.h index aea30032818..5e16543f4ec 100644 --- a/src/gallium/drivers/i915simple/i915_winsys.h +++ b/src/gallium/drivers/i915simple/i915_winsys.h @@ -56,6 +56,7 @@ extern "C" { */ struct pipe_buffer; +struct pipe_fence_handle; struct pipe_winsys; struct pipe_screen; @@ -103,8 +104,8 @@ struct i915_winsys { unsigned access_flags, unsigned delta ); - void (*batch_flush)( struct i915_winsys *sws ); - void (*batch_finish)( struct i915_winsys *sws ); + void (*batch_flush)( struct i915_winsys *sws, + struct pipe_fence_handle **fence ); }; #define I915_BUFFER_ACCESS_WRITE 0x1 diff --git a/src/gallium/drivers/i965simple/brw_flush.c b/src/gallium/drivers/i965simple/brw_flush.c index 5216c680cf6..e6001c30d94 100644 --- a/src/gallium/drivers/i965simple/brw_flush.c +++ b/src/gallium/drivers/i965simple/brw_flush.c @@ -36,14 +36,11 @@ #include "brw_batch.h" -/** - * In future we may want a fence-like interface instead of finish. - */ static void brw_flush( struct pipe_context *pipe, - unsigned flags ) + unsigned flags, + struct pipe_fence_handle **fence ) { struct brw_context *brw = brw_context(pipe); - struct pipe_fence_handle *fence; /* Do we need to emit an MI_FLUSH command to flush the hardware * caches? @@ -65,11 +62,7 @@ static void brw_flush( struct pipe_context *pipe, /* If there are no flags, just flush pending commands to hardware: */ - FLUSH_BATCH( &fence ); - - if (flags & PIPE_FLUSH_WAIT) { -// brw->winsys->wait_fence(brw->winsys, fence); - } + FLUSH_BATCH( fence ); } diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c index 2cbd0d7cabe..0625b69099b 100644 --- a/src/gallium/drivers/softpipe/sp_flush.c +++ b/src/gallium/drivers/softpipe/sp_flush.c @@ -40,13 +40,10 @@ #include "sp_winsys.h" -/* There will be actual work to do here. In future we may want a - * fence-like interface instead of finish, and perhaps flush will take - * flags to indicate what type of flush is required. - */ void softpipe_flush( struct pipe_context *pipe, - unsigned flags ) + unsigned flags, + struct pipe_fence_handle **fence ) { struct softpipe_context *softpipe = softpipe_context(pipe); uint i; @@ -72,5 +69,8 @@ softpipe_flush( struct pipe_context *pipe, * to unmap surfaces when flushing. */ softpipe_unmap_surfaces(softpipe); + + if (fence) + *fence = NULL; } diff --git a/src/gallium/drivers/softpipe/sp_flush.h b/src/gallium/drivers/softpipe/sp_flush.h index 34ec617866b..68d9b5fa835 100644 --- a/src/gallium/drivers/softpipe/sp_flush.h +++ b/src/gallium/drivers/softpipe/sp_flush.h @@ -29,7 +29,9 @@ #define SP_FLUSH_H struct pipe_context; +struct pipe_fence_handle; -void softpipe_flush(struct pipe_context *pipe, unsigned flags ); +void softpipe_flush(struct pipe_context *pipe, unsigned flags, + struct pipe_fence_handle **fence); #endif diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index a3824601be9..b2e49bef4cf 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -37,7 +37,7 @@ extern "C" { struct pipe_screen; - +struct pipe_fence_handle; struct pipe_state_cache; /* Opaque driver handles: @@ -202,7 +202,8 @@ struct pipe_context { /* Flush rendering: */ void (*flush)( struct pipe_context *pipe, - unsigned flags ); + unsigned flags, + struct pipe_fence_handle **fence ); }; diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index bc938ba2538..586951d9566 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -201,8 +201,7 @@ enum pipe_texture_target { */ #define PIPE_FLUSH_RENDER_CACHE 0x1 #define PIPE_FLUSH_TEXTURE_CACHE 0x2 -#define PIPE_FLUSH_WAIT 0x4 -#define PIPE_FLUSH_SWAPBUFFERS 0x8 +#define PIPE_FLUSH_SWAPBUFFERS 0x4 /** diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index 79b320c6bf4..8eba33c3139 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -228,7 +228,7 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) assert(intel); /* should never be null */ if (intel) { - st_flush(intel->st, PIPE_FLUSH_WAIT); + st_finish(intel->st); intel_batchbuffer_free(intel->batch); @@ -256,7 +256,7 @@ GLboolean intelUnbindContext(__DRIcontextPrivate * driContextPriv) { struct intel_context *intel = intel_context(driContextPriv); - st_flush(intel->st, 0x0); + st_flush(intel->st, PIPE_FLUSH_RENDER_CACHE, NULL); /* XXX make_current(NULL)? */ return GL_TRUE; } diff --git a/src/gallium/winsys/dri/intel/intel_winsys_i915.c b/src/gallium/winsys/dri/intel/intel_winsys_i915.c index 2def1afc31e..4d183db7c37 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_i915.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_i915.c @@ -39,12 +39,14 @@ #include "intel_winsys.h" #include "pipe/p_util.h" +#include "pipe/p_winsys.h" #include "i915simple/i915_winsys.h" #include "i915simple/i915_screen.h" struct intel_i915_winsys { struct i915_winsys winsys; /**< batch buffer funcs */ + struct pipe_winsys *pws; struct intel_context *intel; }; @@ -112,19 +114,22 @@ static void intel_i915_batch_reloc( struct i915_winsys *sws, -static void intel_i915_batch_flush( struct i915_winsys *sws ) +static void intel_i915_batch_flush( struct i915_winsys *sws, + struct pipe_fence_handle **fence ) { - struct intel_context *intel = intel_i915_winsys(sws)->intel; + struct intel_i915_winsys *iws = intel_i915_winsys(sws); + struct intel_context *intel = iws->intel; + union { + struct _DriFenceObject *dri; + struct pipe_fence_handle *pipe; + } fu; - intel_batchbuffer_flush( intel->batch ); -// if (0) intel_i915_batch_wait_idle( sws ); -} + fu.dri = intel_batchbuffer_flush( intel->batch ); + if (fu.dri) + iws->pws->fence_reference(iws->pws, fence, fu.pipe); -static void intel_i915_batch_finish( struct i915_winsys *sws ) -{ - struct intel_context *intel = intel_i915_winsys(sws)->intel; - intel_batchbuffer_finish( intel->batch ); +// if (0) intel_i915_batch_wait_idle( sws ); } @@ -145,7 +150,7 @@ intel_create_i915simple( struct intel_context *intel, iws->winsys.batch_dword = intel_i915_batch_dword; iws->winsys.batch_reloc = intel_i915_batch_reloc; iws->winsys.batch_flush = intel_i915_batch_flush; - iws->winsys.batch_finish = intel_i915_batch_finish; + iws->pws = winsys; iws->intel = intel; screen = i915_create_screen(winsys, intel->intelScreen->deviceID); diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 7baaae295c5..c930a1d1963 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -570,6 +570,33 @@ xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) } +/* + * Fence functions - basically nothing to do, as we don't create any actual + * fence objects. + */ + +static void +xm_fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ +} + + +static int +xm_fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + +static int +xm_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + /** * Return pointer to a pipe_winsys object. @@ -603,6 +630,10 @@ xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis) ws->base.surface_alloc_storage = xm_surface_alloc_storage; ws->base.surface_release = xm_surface_release; + ws->fence_reference = xm_fence_reference; + ws->fence_signalled = xm_fence_signalled; + ws->fence_finish = xm_fence_finish; + ws->base.flush_frontbuffer = xm_flush_frontbuffer; ws->base.printf = xm_printf; ws->base.get_name = xm_get_name; diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c index f1fddc4e026..a623d0bcc06 100644 --- a/src/mesa/state_tracker/st_cb_accum.c +++ b/src/mesa/state_tracker/st_cb_accum.c @@ -214,7 +214,7 @@ st_Accum(GLcontext *ctx, GLenum op, GLfloat value) const GLint height = ctx->DrawBuffer->_Ymax - ypos; /* make sure color bufs aren't cached */ - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE); + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); switch (op) { case GL_ADD: diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 026f015fd85..43cc21d1fb4 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -737,7 +737,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, GLint skipPixels; ubyte *stmap; - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE); + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); /* map the stencil buffer */ stmap = pipe_surface_map(ps); @@ -952,7 +952,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, enum pipe_format srcFormat, texFormat; /* make sure rendering has completed */ - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE); + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); st_validate_state(st); diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 5384252a8e5..ec7788923a3 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -366,7 +366,7 @@ st_finish_render_texture(GLcontext *ctx, assert(strb); - ctx->st->pipe->flush(ctx->st->pipe, PIPE_FLUSH_RENDER_CACHE); + ctx->st->pipe->flush(ctx->st->pipe, PIPE_FLUSH_RENDER_CACHE, NULL); /* printf("FINISH RENDER TO TEXTURE surf=%p\n", strb->surface); diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c index dbec993f1ba..a536a059bd5 100644 --- a/src/mesa/state_tracker/st_cb_flush.c +++ b/src/mesa/state_tracker/st_cb_flush.c @@ -43,19 +43,21 @@ #include "pipe/p_winsys.h" -void st_flush( struct st_context *st, uint pipeFlushFlags ) +void st_flush( struct st_context *st, uint pipeFlushFlags, + struct pipe_fence_handle **fence ) { FLUSH_VERTICES(st->ctx, 0); - st->pipe->flush( st->pipe, pipeFlushFlags ); + st->pipe->flush( st->pipe, pipeFlushFlags, fence ); } -static void st_gl_flush( struct st_context *st, uint pipeFlushFlags ) +static void st_gl_flush( struct st_context *st, uint pipeFlushFlags, + struct pipe_fence_handle **fence ) { GLframebuffer *fb = st->ctx->DrawBuffer; - FLUSH_VERTICES(st->ctx, 0); + st_flush( st, pipeFlushFlags, fence ); if (!fb) return; @@ -80,15 +82,6 @@ static void st_gl_flush( struct st_context *st, uint pipeFlushFlags ) = st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); struct pipe_surface *front_surf = strb->surface; - /* If we aren't rendering to the frontbuffer, this is a noop. - * This should be uncontroversial for glFlush, though people may - * feel more strongly about glFinish. - * - * Additionally, need to make sure that the frontbuffer_dirty - * flag really gets set on frontbuffer rendering. - */ - st->pipe->flush( st->pipe, pipeFlushFlags ); - /* Hook for copying "fake" frontbuffer if necessary: */ st->pipe->winsys->flush_frontbuffer( st->pipe->winsys, front_surf, @@ -103,7 +96,18 @@ static void st_gl_flush( struct st_context *st, uint pipeFlushFlags ) */ static void st_glFlush(GLcontext *ctx) { - st_gl_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE); + st_gl_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); +} + + +void st_finish( struct st_context *st ) +{ + struct pipe_fence_handle *fence; + + st_gl_flush(st, PIPE_FLUSH_RENDER_CACHE, &fence); + + st->pipe->winsys->fence_finish(st->pipe->winsys, fence, 0); + st->pipe->winsys->fence_reference(st->pipe->winsys, &fence, NULL); } @@ -112,7 +116,7 @@ static void st_glFlush(GLcontext *ctx) */ static void st_glFinish(GLcontext *ctx) { - st_gl_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_WAIT); + st_finish( ctx->st ); } diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 4cf9adcd28a..e9fcdf69a14 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -160,7 +160,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, return; /* make sure rendering has completed */ - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE); + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); if (format == GL_STENCIL_INDEX) { st_read_stencil_pixels(ctx, x, y, width, height, type, pack, dest); diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index d46a9178b19..075e9d1bd68 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -186,7 +186,8 @@ st_notify_swapbuffers(struct st_framebuffer *stfb) if (ctx && ctx->DrawBuffer == &stfb->Base) { st_flush( ctx->st, - PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_SWAPBUFFERS); + PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_SWAPBUFFERS, + NULL ); } } diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h index 3c397b126a9..9d88ce9764d 100644 --- a/src/mesa/state_tracker/st_public.h +++ b/src/mesa/state_tracker/st_public.h @@ -45,6 +45,7 @@ struct st_context; struct st_framebuffer; struct pipe_context; +struct pipe_fence_handle; struct pipe_surface; @@ -78,7 +79,9 @@ void st_make_current(struct st_context *st, struct st_framebuffer *draw, struct st_framebuffer *read); -void st_flush( struct st_context *st, uint pipeFlushFlags ); +void st_flush( struct st_context *st, uint pipeFlushFlags, + struct pipe_fence_handle **fence ); +void st_finish( struct st_context *st ); void st_notify_swapbuffers(struct st_framebuffer *stfb); void st_notify_swapbuffers_complete(struct st_framebuffer *stfb); -- cgit v1.2.3 From 0dd596fbc7f88b88467529a7f176aca70d70f731 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 7 Apr 2008 14:53:49 -0600 Subject: gallium: accum buffer fixes If the driver can't create a PIPE_FORMAT_R16G16B16A16_SNORM surface, create an accum surface using a shallower format and taller height. Since only the accum buffer code accesses the surface the actual format doesn't really matter, just that there's enough memory. --- src/mesa/state_tracker/st_cb_accum.c | 61 +++++++++++++++++++++++++++++---- src/mesa/state_tracker/st_cb_fbo.c | 29 ++++++++++++++-- src/mesa/state_tracker/st_cb_fbo.h | 3 ++ src/mesa/state_tracker/st_framebuffer.c | 2 +- 4 files changed, 84 insertions(+), 11 deletions(-) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c index a623d0bcc06..35352351d5a 100644 --- a/src/mesa/state_tracker/st_cb_accum.c +++ b/src/mesa/state_tracker/st_cb_accum.c @@ -56,6 +56,51 @@ */ +/** + * Wrapper for pipe_get_tile_rgba(). Do format/cpp override to make the + * tile util function think the surface is 16bit/channel, even if it's not. + * See also: st_renderbuffer_alloc_storage() + */ +static void +acc_get_tile_rgba(struct pipe_context *pipe, struct pipe_surface *acc_ps, + uint x, uint y, uint w, uint h, float *p) +{ + const enum pipe_format f = acc_ps->format; + const int cpp = acc_ps->cpp; + + acc_ps->format = DEFAULT_ACCUM_PIPE_FORMAT; + acc_ps->cpp = 8; + + pipe_get_tile_rgba(pipe, acc_ps, x, y, w, h, p); + + acc_ps->format = f; + acc_ps->cpp = cpp; +} + + +/** + * Wrapper for pipe_put_tile_rgba(). Do format/cpp override to make the + * tile util function think the surface is 16bit/channel, even if it's not. + * See also: st_renderbuffer_alloc_storage() + */ +static void +acc_put_tile_rgba(struct pipe_context *pipe, struct pipe_surface *acc_ps, + uint x, uint y, uint w, uint h, const float *p) +{ + enum pipe_format f = acc_ps->format; + const int cpp = acc_ps->cpp; + + acc_ps->format = DEFAULT_ACCUM_PIPE_FORMAT; + acc_ps->cpp = 8; + + pipe_put_tile_rgba(pipe, acc_ps, x, y, w, h, p); + + acc_ps->format = f; + acc_ps->cpp = cpp; +} + + + void st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) { @@ -80,7 +125,9 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) accBuf[i*4+3] = a; } - pipe_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf); + acc_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf); + + free(accBuf); } @@ -95,13 +142,13 @@ accum_mad(struct pipe_context *pipe, GLfloat scale, GLfloat bias, accBuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); - pipe_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf); + acc_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf); for (i = 0; i < 4 * width * height; i++) { accBuf[i] = accBuf[i] * scale + bias; } - pipe_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf); + acc_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf); free(accBuf); } @@ -120,13 +167,13 @@ accum_accum(struct pipe_context *pipe, GLfloat value, accBuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); pipe_get_tile_rgba(pipe, color_ps, xpos, ypos, width, height, colorBuf); - pipe_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf); + acc_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf); for (i = 0; i < 4 * width * height; i++) { accBuf[i] = accBuf[i] + colorBuf[i] * value; } - pipe_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf); + acc_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf); free(colorBuf); free(accBuf); @@ -150,7 +197,7 @@ accum_load(struct pipe_context *pipe, GLfloat value, buf[i] = buf[i] * value; } - pipe_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, buf); + acc_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, buf); free(buf); } @@ -169,7 +216,7 @@ accum_return(GLcontext *ctx, GLfloat value, abuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); - pipe_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, abuf); + acc_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, abuf); if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3]) { cbuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index e55281a4308..b1a56f3ca63 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -127,14 +127,37 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, pipeFormat, flags); if (ret || !strb->surface->buffer) { - return GL_FALSE; /* out of memory, try s/w buffer? */ + if (pipeFormat == DEFAULT_ACCUM_PIPE_FORMAT) { + /* Accum buffer. Try a different surface format. Since accum + * buffers are s/w only for now, the surface pixel format doesn't + * really matter, only that the buffer is large enough. + */ + int sz, mult; + enum pipe_format accum_format; + + /* allocate a buffer of (typically) double height to get 64bpp */ + accum_format = st_choose_renderbuffer_format(pipe, GL_RGBA); + sz = pf_get_size(accum_format); + mult = pf_get_size(DEFAULT_ACCUM_PIPE_FORMAT) / sz; + + ret = pipe->winsys->surface_alloc_storage(pipe->winsys, + strb->surface, + width, height * mult, + accum_format, flags); + if (ret) + return GL_FALSE; /* we've _really_ failed */ + + } + else { + return GL_FALSE; /* out of memory, try s/w buffer? */ + } } ASSERT(strb->surface->buffer); ASSERT(strb->surface->format); ASSERT(strb->surface->cpp); ASSERT(strb->surface->width == width); - ASSERT(strb->surface->height == height); + /*ASSERT(strb->surface->height == height);*/ ASSERT(strb->surface->pitch); strb->Base.Width = width; @@ -252,7 +275,7 @@ st_new_renderbuffer_fb(enum pipe_format format) strb->Base.InternalFormat = GL_STENCIL_INDEX8_EXT; strb->Base._BaseFormat = GL_STENCIL_INDEX; break; - case PIPE_FORMAT_R16G16B16A16_SNORM: + case DEFAULT_ACCUM_PIPE_FORMAT: /*PIPE_FORMAT_R16G16B16A16_SNORM*/ strb->Base.InternalFormat = GL_RGBA16; strb->Base._BaseFormat = GL_RGBA; break; diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h index 21e531d1d06..c1aa14f9b22 100644 --- a/src/mesa/state_tracker/st_cb_fbo.h +++ b/src/mesa/state_tracker/st_cb_fbo.h @@ -30,6 +30,9 @@ #define ST_CB_FBO_H +#define DEFAULT_ACCUM_PIPE_FORMAT PIPE_FORMAT_R16G16B16A16_SNORM + + /** * Derived renderbuffer class. Just need to add a pointer to the diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 075e9d1bd68..ea09d9234cd 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -107,7 +107,7 @@ st_create_framebuffer( const __GLcontextModes *visual, if (visual->accumRedBits > 0) { /* 16-bit/channel accum */ struct gl_renderbuffer *accumRb - = st_new_renderbuffer_fb(PIPE_FORMAT_R16G16B16A16_SNORM); + = st_new_renderbuffer_fb(DEFAULT_ACCUM_PIPE_FORMAT); _mesa_add_renderbuffer(&stfb->Base, BUFFER_ACCUM, accumRb); } -- cgit v1.2.3 From 311e40268414649f047ee177ba22a17a2d437843 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 9 Apr 2008 18:39:51 -0600 Subject: gallium: more elaborate tracking of front color buffer state This fixes the case where the app calls SwapBuffers then calls glReadPixels to read the front color buffer. We now keep track of when the front buffer is a _logically_ copy of the back buffer (after SwapBuffers) and read from the back color buffer instead of the front. --- src/mesa/state_tracker/st_atom_framebuffer.c | 8 +++++++ src/mesa/state_tracker/st_cb_drawpixels.c | 2 +- src/mesa/state_tracker/st_cb_flush.c | 27 ++++------------------- src/mesa/state_tracker/st_cb_readpixels.c | 33 ++++++++++++++++++++++++++-- src/mesa/state_tracker/st_cb_readpixels.h | 3 +++ src/mesa/state_tracker/st_context.h | 9 +++++--- src/mesa/state_tracker/st_framebuffer.c | 1 + 7 files changed, 54 insertions(+), 29 deletions(-) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c index 02573af8f0a..8a95096ec9a 100644 --- a/src/mesa/state_tracker/st_atom_framebuffer.c +++ b/src/mesa/state_tracker/st_atom_framebuffer.c @@ -81,6 +81,14 @@ update_framebuffer_state( struct st_context *st ) } cso_set_framebuffer(st->cso_context, framebuffer); + + if (fb->_ColorDrawBufferMask[0] & BUFFER_BIT_FRONT_LEFT) { + if (st->frontbuffer_status == FRONT_STATUS_COPY_OF_BACK) { + /* XXX copy back buf to front? */ + } + /* we're assuming we'll really draw to the front buffer */ + st->frontbuffer_status = FRONT_STATUS_DIRTY; + } } diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index b1affc4a915..5f8c90cbba4 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -961,7 +961,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, } if (type == GL_COLOR) { - rbRead = st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer); + rbRead = st_get_color_read_renderbuffer(ctx); color = NULL; stfp = combined_drawpix_fragment_program(ctx); stvp = st_make_passthrough_vertex_shader(ctx->st, GL_FALSE); diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c index 1bcd1b4cd98..1b3402cee24 100644 --- a/src/mesa/state_tracker/st_cb_flush.c +++ b/src/mesa/state_tracker/st_cb_flush.c @@ -44,30 +44,10 @@ #include "pipe/p_winsys.h" -static GLboolean +static INLINE GLboolean is_front_buffer_dirty(struct st_context *st) { - GLframebuffer *fb = st->ctx->DrawBuffer; - - if (!fb) - return GL_FALSE; - - /* XXX: temporary hack. This flag should only be set if we do any - * rendering to the front buffer. - * - * Further more, the scissor rectangle could be tracked to - * construct a dirty region of the front buffer, to avoid - * situations where it must be copied repeatedly. - * - * In the extreme case, some kind of timer could be set up to allow - * coalescing of multiple flushes to the frontbuffer, which can be - * quite a performance drain if there are a sufficient number of - * them. - */ - st->flags.frontbuffer_dirty - = (fb->_ColorDrawBufferMask[0] & BUFFER_BIT_FRONT_LEFT); - - return st->flags.frontbuffer_dirty; + return st->frontbuffer_status == FRONT_STATUS_DIRTY; } @@ -86,7 +66,8 @@ display_front_buffer(struct st_context *st) */ st->pipe->winsys->flush_frontbuffer( st->pipe->winsys, front_surf, st->pipe->priv ); - st->flags.frontbuffer_dirty = 0; + + st->frontbuffer_status = FRONT_STATUS_UNDEFINED; } diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 2bcc8c99fb7..29a06ffaa90 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -128,6 +128,34 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, } +/** + * Return renderbuffer to use for reading color pixels for glRead/CopyPixel + * commands. + * Special care is needed for the front buffer. + */ +struct st_renderbuffer * +st_get_color_read_renderbuffer(GLcontext *ctx) +{ + struct gl_framebuffer *fb = ctx->ReadBuffer; + struct st_renderbuffer *strb = + st_renderbuffer(fb->_ColorReadBuffer); + struct st_renderbuffer *front = + st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + + if (strb == front + && ctx->st->frontbuffer_status == FRONT_STATUS_COPY_OF_BACK) { + /* reading from front color buffer, which is a logical copy of the + * back color buffer. + */ + struct st_renderbuffer *back = + st_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer); + strb = back; + } + + return strb; +} + + /** * Do glReadPixels by getting rows from the framebuffer surface with * get_tile(). Convert to requested format/type with Mesa image routines. @@ -173,12 +201,13 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, strb = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer); } else { - strb = st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer); + /* Read color buffer */ + strb = st_get_color_read_renderbuffer(ctx); } + if (!strb) return; - if (format == GL_RGBA && type == GL_FLOAT) { /* write tile(row) directly into user's buffer */ df = (GLfloat *) _mesa_image_address2d(&clippedPacking, dest, width, diff --git a/src/mesa/state_tracker/st_cb_readpixels.h b/src/mesa/state_tracker/st_cb_readpixels.h index 79acdad88e1..9e151be51fb 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.h +++ b/src/mesa/state_tracker/st_cb_readpixels.h @@ -29,6 +29,9 @@ #ifndef ST_CB_READPIXELS_H #define ST_CB_READPIXELS_H +extern struct st_renderbuffer * +st_get_color_read_renderbuffer(GLcontext *ctx); + extern void st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum type, diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 212687cf4ab..d89e54c43c1 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -45,6 +45,11 @@ struct blit_state; struct bitmap_cache; +#define FRONT_STATUS_UNDEFINED 0 +#define FRONT_STATUS_DIRTY 1 +#define FRONT_STATUS_COPY_OF_BACK 2 + + #define ST_NEW_MESA 0x1 /* Mesa state has changed */ #define ST_NEW_FRAGMENT_PROGRAM 0x2 #define ST_NEW_VERTEX_PROGRAM 0x4 @@ -104,9 +109,7 @@ struct st_context struct gl_fragment_program *fragment_program; } cb; - struct { - GLuint frontbuffer_dirty:1; - } flags; + GLuint frontbuffer_status; /**< one of FRONT_STATUS_ */ char vendor[100]; char renderer[100]; diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index ea09d9234cd..47466c97d81 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -188,6 +188,7 @@ st_notify_swapbuffers(struct st_framebuffer *stfb) st_flush( ctx->st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_SWAPBUFFERS, NULL ); + ctx->st->frontbuffer_status = FRONT_STATUS_COPY_OF_BACK; } } -- cgit v1.2.3 From 8cad3189d3346bce3eee1976f1b5cf32da9dd9a7 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 9 Jun 2008 14:56:29 -0600 Subject: gallium: include scissor.h --- src/mesa/state_tracker/st_context.c | 1 + src/mesa/state_tracker/st_framebuffer.c | 1 + 2 files changed, 2 insertions(+) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 4081722bc71..e20e0c08cbd 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -30,6 +30,7 @@ #include "main/extensions.h" #include "main/matrix.h" #include "main/buffers.h" +#include "main/scissor.h" #include "vbo/vbo.h" #include "shader/shader_api.h" #include "st_public.h" diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 47466c97d81..7099d78eb8c 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -32,6 +32,7 @@ #include "main/framebuffer.h" #include "main/matrix.h" #include "main/renderbuffer.h" +#include "main/scissor.h" #include "st_public.h" #include "st_context.h" #include "st_cb_fbo.h" -- cgit v1.2.3 From 9a2c70f0754b275e7ec370bbbff3d81b48bfd476 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 18 Jun 2008 10:20:13 -0600 Subject: gallium: added new st_set_framebuffer_surface() This allows the winsys to explicitly specify gallium surfaces for a framebuffer object. --- src/mesa/state_tracker/st_framebuffer.c | 56 +++++++++++++++++++++++++++++++++ src/mesa/state_tracker/st_public.h | 3 ++ 2 files changed, 59 insertions(+) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 7099d78eb8c..7e6db467576 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -38,6 +38,7 @@ #include "st_cb_fbo.h" #include "pipe/p_defines.h" #include "pipe/p_context.h" +#include "pipe/p_inlines.h" struct st_framebuffer * @@ -154,6 +155,61 @@ void st_unreference_framebuffer( struct st_framebuffer **stfb ) +/** + * Set/replace a framebuffer surface. + * The user of the state tracker can use this instead of + * st_resize_framebuffer() to provide new surfaces when a window is resized. + */ +void +st_set_framebuffer_surface(struct st_framebuffer *stfb, + uint surfIndex, struct pipe_surface *surf) +{ + static const GLuint invalid_size = 9999999; + struct st_renderbuffer *strb; + GLuint width, height, i; + + assert(surfIndex < BUFFER_COUNT); + + strb = st_renderbuffer(stfb->Base.Attachment[surfIndex].Renderbuffer); + assert(strb); + + /* replace the renderbuffer's surface/texture pointers */ + pipe_surface_reference( &strb->surface, surf ); + pipe_texture_reference( &strb->texture, surf->texture ); + + /* update renderbuffer's width/height */ + strb->Base.Width = surf->width; + strb->Base.Height = surf->height; + + /* Try to update the framebuffer's width/height from the renderbuffer + * sizes. Before we start drawing, all the rbs _should_ be the same size. + */ + width = height = invalid_size; + for (i = 0; i < BUFFER_COUNT; i++) { + if (stfb->Base.Attachment[i].Renderbuffer) { + if (width == invalid_size) { + width = stfb->Base.Attachment[i].Renderbuffer->Width; + height = stfb->Base.Attachment[i].Renderbuffer->Height; + } + else if (width != stfb->Base.Attachment[i].Renderbuffer->Width || + height != stfb->Base.Attachment[i].Renderbuffer->Height) { + /* inconsistant renderbuffer sizes, bail out */ + return; + } + } + } + + if (width != invalid_size) { + /* OK, the renderbuffers are of a consistant size, so update the + * parent framebuffer's size. + */ + stfb->Base.Width = width; + stfb->Base.Height = height; + } +} + + + /** * Return the pipe_surface for the given renderbuffer. */ diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h index a0dab33257f..b99984215f7 100644 --- a/src/mesa/state_tracker/st_public.h +++ b/src/mesa/state_tracker/st_public.h @@ -68,6 +68,9 @@ struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual, void st_resize_framebuffer( struct st_framebuffer *stfb, uint width, uint height ); +void st_set_framebuffer_surface(struct st_framebuffer *stfb, + uint surfIndex, struct pipe_surface *surf); + struct pipe_surface *st_get_framebuffer_surface(struct st_framebuffer *stfb, uint surfIndex); -- cgit v1.2.3 From 52501801c7107614387717e7b97e66a667f9e5b8 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 23 Jun 2008 15:54:25 +0200 Subject: gallium: Add accessor functions to get textures from a st_framebuffer --- src/mesa/state_tracker/st_framebuffer.c | 16 ++++++++++++++++ src/mesa/state_tracker/st_public.h | 3 +++ 2 files changed, 19 insertions(+) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 7e6db467576..1b6e68c2a11 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -230,6 +230,22 @@ st_get_framebuffer_surface(struct st_framebuffer *stfb, uint surfIndex) return NULL; } +struct pipe_texture * +st_get_framebuffer_texture(struct st_framebuffer *stfb, uint surfIndex) +{ + struct st_renderbuffer *strb; + + assert(surfIndex <= ST_SURFACE_DEPTH); + + /* sanity checks, ST tokens should match Mesa tokens */ + assert(ST_SURFACE_FRONT_LEFT == BUFFER_FRONT_LEFT); + assert(ST_SURFACE_BACK_RIGHT == BUFFER_BACK_RIGHT); + + strb = st_renderbuffer(stfb->Base.Attachment[surfIndex].Renderbuffer); + if (strb) + return strb->texture; + return NULL; +} /** * This function is to be called prior to SwapBuffers on the given diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h index b99984215f7..ca4e9577b1b 100644 --- a/src/mesa/state_tracker/st_public.h +++ b/src/mesa/state_tracker/st_public.h @@ -74,6 +74,9 @@ void st_set_framebuffer_surface(struct st_framebuffer *stfb, struct pipe_surface *st_get_framebuffer_surface(struct st_framebuffer *stfb, uint surfIndex); +struct pipe_texture *st_get_framebuffer_texture(struct st_framebuffer *stfb, + uint surfIndex); + void *st_framebuffer_private( struct st_framebuffer *stfb ); void st_unreference_framebuffer( struct st_framebuffer **stfb ); -- cgit v1.2.3 From 429a08384c2ea66d446e46beb28e33ee3b764d52 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Fri, 27 Jun 2008 16:02:43 +0200 Subject: gallium: handle msaa --- src/gallium/include/pipe/p_state.h | 6 +- src/gallium/winsys/dri/intel/intel_screen.c | 6 +- src/mesa/drivers/dri/common/utils.c | 97 ++++++++++++++++------------- src/mesa/drivers/dri/common/utils.h | 3 +- src/mesa/main/mtypes.h | 1 + src/mesa/state_tracker/st_cb_fbo.c | 4 +- src/mesa/state_tracker/st_cb_fbo.h | 2 +- src/mesa/state_tracker/st_framebuffer.c | 18 +++--- 8 files changed, 77 insertions(+), 60 deletions(-) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 2992e2f3b30..55467969361 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -276,7 +276,7 @@ struct pipe_surface unsigned layout; /**< PIPE_SURFACE_LAYOUT_x */ unsigned offset; /**< offset from start of buffer, in bytes */ unsigned refcount; - unsigned usage; /**< PIPE_BUFFER_USAGE_* */ + unsigned usage; /**< PIPE_BUFFER_USAGE_* */ struct pipe_winsys *winsys; /**< winsys which owns/created the surface */ @@ -311,7 +311,9 @@ struct pipe_texture unsigned last_level:8; /**< Index of last mipmap level present/defined */ unsigned compressed:1; - + + unsigned nr_samples:8; /**< for multisampled surfaces, nr of samples */ + unsigned tex_usage; /* PIPE_TEXTURE_USAGE_* */ /* These are also refcounted: diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 89de188ada8..cfecebdb8c7 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -483,11 +483,13 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits, uint8_t depth_bits_array[3]; uint8_t stencil_bits_array[3]; + uint8_t msaa_samples_array[1]; depth_bits_array[0] = 0; depth_bits_array[1] = depth_bits; depth_bits_array[2] = depth_bits; + msaa_samples_array[0] = 0; /* Just like with the accumulation buffer, always provide some modes * with a stencil buffer. It will be a sw fallback, but some apps won't @@ -521,7 +523,7 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits, if (!driFillInModes(&m, fb_format, fb_type, depth_bits_array, stencil_bits_array, depth_buffer_factor, back_buffer_modes, - back_buffer_factor, GLX_TRUE_COLOR)) { + back_buffer_factor, msaa_samples_array, 1, GLX_TRUE_COLOR)) { fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__); return NULL; @@ -529,7 +531,7 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits, if (!driFillInModes(&m, fb_format, fb_type, depth_bits_array, stencil_bits_array, depth_buffer_factor, back_buffer_modes, - back_buffer_factor, GLX_DIRECT_COLOR)) { + back_buffer_factor, msaa_samples_array, 1, GLX_DIRECT_COLOR)) { fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__); return NULL; diff --git a/src/mesa/drivers/dri/common/utils.c b/src/mesa/drivers/dri/common/utils.c index 94db3199287..3cf2146dceb 100644 --- a/src/mesa/drivers/dri/common/utils.c +++ b/src/mesa/drivers/dri/common/utils.c @@ -521,6 +521,9 @@ GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer, * \c GLX_SWAP_UNDEFINED_OML. See the * GLX_OML_swap_method extension spec for more details. * \param num_db_modes Number of entries in \c db_modes. + * \param msaa_samples Array of msaa sample count. 0 represents a visual + * without a multisample buffer. + * \param num_msaa_modes Number of entries in \c msaa_samples. * \param visType GLX visual type. Usually either \c GLX_TRUE_COLOR or * \c GLX_DIRECT_COLOR. * @@ -542,6 +545,7 @@ driFillInModes( __GLcontextModes ** ptr_to_modes, const uint8_t * depth_bits, const uint8_t * stencil_bits, unsigned num_depth_stencil_bits, const GLenum * db_modes, unsigned num_db_modes, + const u_int8_t * msaa_samples, unsigned num_msaa_modes, int visType ) { static const uint8_t bits_table[3][4] = { @@ -607,9 +611,7 @@ driFillInModes( __GLcontextModes ** ptr_to_modes, const uint32_t * masks; const int index = fb_type & 0x07; __GLcontextModes * modes = *ptr_to_modes; - unsigned i; - unsigned j; - unsigned k; + unsigned i, j, k, h; if ( bytes_per_pixel[ index ] == 0 ) { @@ -659,49 +661,54 @@ driFillInModes( __GLcontextModes ** ptr_to_modes, for ( k = 0 ; k < num_depth_stencil_bits ; k++ ) { for ( i = 0 ; i < num_db_modes ; i++ ) { - for ( j = 0 ; j < 2 ; j++ ) { - - modes->redBits = bits[0]; - modes->greenBits = bits[1]; - modes->blueBits = bits[2]; - modes->alphaBits = bits[3]; - modes->redMask = masks[0]; - modes->greenMask = masks[1]; - modes->blueMask = masks[2]; - modes->alphaMask = masks[3]; - modes->rgbBits = modes->redBits + modes->greenBits - + modes->blueBits + modes->alphaBits; - - modes->accumRedBits = 16 * j; - modes->accumGreenBits = 16 * j; - modes->accumBlueBits = 16 * j; - modes->accumAlphaBits = (masks[3] != 0) ? 16 * j : 0; - modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG; - - modes->stencilBits = stencil_bits[k]; - modes->depthBits = depth_bits[k]; - - modes->visualType = visType; - modes->renderType = GLX_RGBA_BIT; - modes->drawableType = GLX_WINDOW_BIT; - modes->rgbMode = GL_TRUE; - - if ( db_modes[i] == GLX_NONE ) { - modes->doubleBufferMode = GL_FALSE; + for ( h = 0 ; h < num_msaa_modes; h++ ) { + for ( j = 0 ; j < 2 ; j++ ) { + + modes->redBits = bits[0]; + modes->greenBits = bits[1]; + modes->blueBits = bits[2]; + modes->alphaBits = bits[3]; + modes->redMask = masks[0]; + modes->greenMask = masks[1]; + modes->blueMask = masks[2]; + modes->alphaMask = masks[3]; + modes->rgbBits = modes->redBits + modes->greenBits + + modes->blueBits + modes->alphaBits; + + modes->accumRedBits = 16 * j; + modes->accumGreenBits = 16 * j; + modes->accumBlueBits = 16 * j; + modes->accumAlphaBits = (masks[3] != 0) ? 16 * j : 0; + modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG; + + modes->stencilBits = stencil_bits[k]; + modes->depthBits = depth_bits[k]; + + modes->visualType = visType; + modes->renderType = GLX_RGBA_BIT; + modes->drawableType = GLX_WINDOW_BIT; + modes->rgbMode = GL_TRUE; + + if ( db_modes[i] == GLX_NONE ) { + modes->doubleBufferMode = GL_FALSE; + } + else { + modes->doubleBufferMode = GL_TRUE; + modes->swapMethod = db_modes[i]; + } + + modes->samples = msaa_samples[h]; + modes->sampleBuffers = modes->samples ? 1 : 0; + + modes->haveAccumBuffer = ((modes->accumRedBits + + modes->accumGreenBits + + modes->accumBlueBits + + modes->accumAlphaBits) > 0); + modes->haveDepthBuffer = (modes->depthBits > 0); + modes->haveStencilBuffer = (modes->stencilBits > 0); + + modes = modes->next; } - else { - modes->doubleBufferMode = GL_TRUE; - modes->swapMethod = db_modes[i]; - } - - modes->haveAccumBuffer = ((modes->accumRedBits + - modes->accumGreenBits + - modes->accumBlueBits + - modes->accumAlphaBits) > 0); - modes->haveDepthBuffer = (modes->depthBits > 0); - modes->haveStencilBuffer = (modes->stencilBits > 0); - - modes = modes->next; } } } diff --git a/src/mesa/drivers/dri/common/utils.h b/src/mesa/drivers/dri/common/utils.h index 1067d0a8bfd..20940c21b4e 100644 --- a/src/mesa/drivers/dri/common/utils.h +++ b/src/mesa/drivers/dri/common/utils.h @@ -115,6 +115,7 @@ extern GLboolean driFillInModes( __GLcontextModes ** modes, GLenum fb_format, GLenum fb_type, const uint8_t * depth_bits, const uint8_t * stencil_bits, unsigned num_depth_stencil_bits, - const GLenum * db_modes, unsigned num_db_modes, int visType ); + const GLenum * db_modes, unsigned num_db_modes, + const u_int8_t * msaa_samples, unsigned num_msaa_modes, int visType ); #endif /* DRI_DEBUG_H */ diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index dceb7611f25..0a065541e1f 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2269,6 +2269,7 @@ struct gl_renderbuffer GLubyte IndexBits; GLubyte DepthBits; GLubyte StencilBits; + GLubyte Samples; /**< Number of samples - 0 if not multisampled */ GLvoid *Data; /**< This may not be used by some kinds of RBs */ /* Used to wrap one renderbuffer around another: */ diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 1067caf9b37..7245798d0da 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -118,6 +118,7 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, template.height[0] = height; template.depth[0] = 1; template.last_level = 0; + template.nr_samples = rb->Samples; if (pf_is_depth_stencil(template.format)) { template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL; @@ -249,7 +250,7 @@ st_new_renderbuffer(GLcontext *ctx, GLuint name) * renderbuffer). The window system code determines the format. */ struct gl_renderbuffer * -st_new_renderbuffer_fb(enum pipe_format format) +st_new_renderbuffer_fb(enum pipe_format format, int samples) { struct st_renderbuffer *strb; @@ -261,6 +262,7 @@ st_new_renderbuffer_fb(enum pipe_format format) _mesa_init_renderbuffer(&strb->Base, 0); strb->Base.ClassID = 0x4242; /* just a unique value */ + strb->Base.Samples = samples; strb->format = format; switch (format) { diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h index 87b0734a0c8..ff56001a4e1 100644 --- a/src/mesa/state_tracker/st_cb_fbo.h +++ b/src/mesa/state_tracker/st_cb_fbo.h @@ -58,7 +58,7 @@ st_renderbuffer(struct gl_renderbuffer *rb) extern struct gl_renderbuffer * -st_new_renderbuffer_fb(enum pipe_format format); +st_new_renderbuffer_fb(enum pipe_format format, int samples); extern void st_init_fbo_functions(struct dd_function_table *functions); diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 1b6e68c2a11..1994a1c8260 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -51,27 +51,29 @@ st_create_framebuffer( const __GLcontextModes *visual, { struct st_framebuffer *stfb = CALLOC_STRUCT(st_framebuffer); if (stfb) { + int samples = 0; _mesa_initialize_framebuffer(&stfb->Base, visual); + if (visual->sampleBuffers) samples = visual->samples; { /* fake frontbuffer */ /* XXX allocation should only happen in the unusual case it's actually needed */ struct gl_renderbuffer *rb - = st_new_renderbuffer_fb(colorFormat); + = st_new_renderbuffer_fb(colorFormat, samples); _mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb); } if (visual->doubleBufferMode) { struct gl_renderbuffer *rb - = st_new_renderbuffer_fb(colorFormat); + = st_new_renderbuffer_fb(colorFormat, samples); _mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb); } if (visual->depthBits == 24 && visual->stencilBits == 8) { /* combined depth/stencil buffer */ struct gl_renderbuffer *depthStencilRb - = st_new_renderbuffer_fb(depthFormat); + = st_new_renderbuffer_fb(depthFormat, samples); /* note: bind RB to two attachment points */ _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthStencilRb); _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, depthStencilRb); @@ -82,26 +84,26 @@ st_create_framebuffer( const __GLcontextModes *visual, if (visual->depthBits == 32) { /* 32-bit depth buffer */ struct gl_renderbuffer *depthRb - = st_new_renderbuffer_fb(depthFormat); + = st_new_renderbuffer_fb(depthFormat, samples); _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); } else if (visual->depthBits == 24) { /* 24-bit depth buffer, ignore stencil bits */ struct gl_renderbuffer *depthRb - = st_new_renderbuffer_fb(depthFormat); + = st_new_renderbuffer_fb(depthFormat, samples); _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); } else if (visual->depthBits > 0) { /* 16-bit depth buffer */ struct gl_renderbuffer *depthRb - = st_new_renderbuffer_fb(depthFormat); + = st_new_renderbuffer_fb(depthFormat, samples); _mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb); } if (visual->stencilBits > 0) { /* 8-bit stencil */ struct gl_renderbuffer *stencilRb - = st_new_renderbuffer_fb(stencilFormat); + = st_new_renderbuffer_fb(stencilFormat, samples); _mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, stencilRb); } } @@ -109,7 +111,7 @@ st_create_framebuffer( const __GLcontextModes *visual, if (visual->accumRedBits > 0) { /* 16-bit/channel accum */ struct gl_renderbuffer *accumRb - = st_new_renderbuffer_fb(DEFAULT_ACCUM_PIPE_FORMAT); + = st_new_renderbuffer_fb(DEFAULT_ACCUM_PIPE_FORMAT, 0); /* XXX accum isn't multisampled right? */ _mesa_add_renderbuffer(&stfb->Base, BUFFER_ACCUM, accumRb); } -- cgit v1.2.3 From 7467a943fc7aeca050014424d5bb2e3ca30c1a04 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Sun, 20 Jul 2008 10:49:48 +0200 Subject: add env var to override msaa visual selection --- src/mesa/state_tracker/st_framebuffer.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 1994a1c8260..039a9cfe899 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -52,8 +52,12 @@ st_create_framebuffer( const __GLcontextModes *visual, struct st_framebuffer *stfb = CALLOC_STRUCT(st_framebuffer); if (stfb) { int samples = 0; + const char *msaa_override = _mesa_getenv("__GL_FSAA_MODE"); _mesa_initialize_framebuffer(&stfb->Base, visual); if (visual->sampleBuffers) samples = visual->samples; + if (msaa_override) { + samples = _mesa_atoi(msaa_override); + } { /* fake frontbuffer */ -- cgit v1.2.3 From 2f34c851c01321b177bc3074755e97af270ec994 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Thu, 14 Aug 2008 11:40:33 +0100 Subject: mesa: Issue PIPE_FLUSH_FRAME in glSwapBuffers/glFlush/glFinish. --- src/mesa/state_tracker/st_cb_flush.c | 2 +- src/mesa/state_tracker/st_framebuffer.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/mesa/state_tracker/st_framebuffer.c') diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c index 5e866b0d413..d8f9537d2de 100644 --- a/src/mesa/state_tracker/st_cb_flush.c +++ b/src/mesa/state_tracker/st_cb_flush.c @@ -91,7 +91,7 @@ void st_finish( struct st_context *st ) { struct pipe_fence_handle *fence = NULL; - st_flush(st, PIPE_FLUSH_RENDER_CACHE, &fence); + st_flush(st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, &fence); st->pipe->winsys->fence_finish(st->pipe->winsys, fence, 0); st->pipe->winsys->fence_reference(st->pipe->winsys, &fence, NULL); diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 039a9cfe899..4012cf73e57 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -265,7 +265,9 @@ st_notify_swapbuffers(struct st_framebuffer *stfb) if (ctx && ctx->DrawBuffer == &stfb->Base) { st_flush( ctx->st, - PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_SWAPBUFFERS, + PIPE_FLUSH_RENDER_CACHE | + PIPE_FLUSH_SWAPBUFFERS | + PIPE_FLUSH_FRAME, NULL ); ctx->st->frontbuffer_status = FRONT_STATUS_COPY_OF_BACK; } -- cgit v1.2.3