From 4b87d37e90b6d2d9562a192540833b599bda5a35 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 3 Aug 2007 13:28:35 -0600 Subject: framebuffer object functions --- src/mesa/state_tracker/st_cb_fbo.h | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/mesa/state_tracker/st_cb_fbo.h (limited to 'src/mesa/state_tracker/st_cb_fbo.h') diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h new file mode 100644 index 0000000000..f4fa66df59 --- /dev/null +++ b/src/mesa/state_tracker/st_cb_fbo.h @@ -0,0 +1,38 @@ +/************************************************************************** + * + * Copyright 2007 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. + * + **************************************************************************/ + + +#ifndef ST_CB_FBO_H +#define ST_CB_FBO_H + + +extern void st_init_cb_fbo( struct st_context *st ); + +extern void st_destroy_cb_fbo( struct st_context *st ); + + +#endif /* ST_CB_FBO_H */ -- cgit v1.2.3 From 6da9234fd437f97267e7831f034c78b31156d939 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 6 Aug 2007 20:53:28 +0100 Subject: New st_init_*_functions() to initialize the driver functions table. We need to do these initializations before initializing the Mesa context because context init involves creating texture/program/etc objects. --- src/mesa/state_tracker/st_cb_bufferobjects.c | 18 ++++++++--------- src/mesa/state_tracker/st_cb_bufferobjects.h | 11 +++++------ src/mesa/state_tracker/st_cb_clear.c | 10 +--------- src/mesa/state_tracker/st_cb_clear.h | 5 +++-- src/mesa/state_tracker/st_cb_drawpixels.c | 8 +------- src/mesa/state_tracker/st_cb_drawpixels.h | 4 +--- src/mesa/state_tracker/st_cb_fbo.c | 9 +-------- src/mesa/state_tracker/st_cb_fbo.h | 5 ++--- src/mesa/state_tracker/st_cb_program.c | 29 ++++++++++------------------ src/mesa/state_tracker/st_cb_texture.c | 12 +++--------- src/mesa/state_tracker/st_cb_texture.h | 6 +----- src/mesa/state_tracker/st_context.c | 18 +++++++++++++++++ src/mesa/state_tracker/st_context.h | 7 +++---- src/mesa/state_tracker/st_program.h | 5 +++-- 14 files changed, 60 insertions(+), 87 deletions(-) (limited to 'src/mesa/state_tracker/st_cb_fbo.h') diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index a667b3e775..d020eb2007 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -192,15 +192,13 @@ st_bufferobj_unmap(GLcontext *ctx, void -st_init_cb_bufferobjects( struct st_context *st ) +st_init_bufferobject_functions(struct dd_function_table *functions) { - GLcontext *ctx = st->ctx; - - ctx->Driver.NewBufferObject = st_bufferobj_alloc; - ctx->Driver.DeleteBuffer = st_bufferobj_free; - ctx->Driver.BufferData = st_bufferobj_data; - ctx->Driver.BufferSubData = st_bufferobj_subdata; - ctx->Driver.GetBufferSubData = st_bufferobj_get_subdata; - ctx->Driver.MapBuffer = st_bufferobj_map; - ctx->Driver.UnmapBuffer = st_bufferobj_unmap; + functions->NewBufferObject = st_bufferobj_alloc; + functions->DeleteBuffer = st_bufferobj_free; + functions->BufferData = st_bufferobj_data; + functions->BufferSubData = st_bufferobj_subdata; + functions->GetBufferSubData = st_bufferobj_get_subdata; + functions->MapBuffer = st_bufferobj_map; + functions->UnmapBuffer = st_bufferobj_unmap; } diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.h b/src/mesa/state_tracker/st_cb_bufferobjects.h index 2787411c5f..2090a743e0 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.h +++ b/src/mesa/state_tracker/st_cb_bufferobjects.h @@ -1,4 +1,4 @@ - /************************************************************************** +/************************************************************************** * * Copyright 2005 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. @@ -43,11 +43,6 @@ struct st_buffer_object }; -/* Hook the bufferobject implementation into mesa: - */ -void st_init_cb_bufferobjects( struct st_context *st ); - - /* Are the obj->Name tests necessary? Unfortunately yes, mesa * allocates a couple of gl_buffer_object structs statically, and the * Name == 0 test is the only way to identify them and avoid casting @@ -63,4 +58,8 @@ st_buffer_object(struct gl_buffer_object *obj) } +extern void +st_init_bufferobject_functions(struct dd_function_table *functions); + + #endif diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index c907b0ed22..0ec7784d84 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -418,15 +418,7 @@ static void st_clear(GLcontext *ctx, GLbitfield mask) } -void st_init_cb_clear( struct st_context *st ) +void st_init_clear_functions(struct dd_function_table *functions) { - struct dd_function_table *functions = &st->ctx->Driver; - functions->Clear = st_clear; } - - -void st_destroy_cb_clear( struct st_context *st ) -{ -} - diff --git a/src/mesa/state_tracker/st_cb_clear.h b/src/mesa/state_tracker/st_cb_clear.h index 32086971b5..c715e56bd5 100644 --- a/src/mesa/state_tracker/st_cb_clear.h +++ b/src/mesa/state_tracker/st_cb_clear.h @@ -29,9 +29,10 @@ #ifndef ST_CB_CLEAR_H #define ST_CB_CLEAR_H -extern void st_init_cb_clear( struct st_context *st ); -extern void st_destroy_cb_clear( struct st_context *st ); +extern void +st_init_clear_functions(struct dd_function_table *functions); + #endif /* ST_CB_CLEAR_H */ diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 13f5c5f3c7..92a4e305d1 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -262,14 +262,8 @@ st_drawpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, } -void st_init_cb_drawpixels( struct st_context *st ) +void st_init_drawpixels_functions(struct dd_function_table *functions) { - struct dd_function_table *functions = &st->ctx->Driver; - functions->DrawPixels = st_drawpixels; } - -void st_destroy_cb_drawpixels( struct st_context *st ) -{ -} diff --git a/src/mesa/state_tracker/st_cb_drawpixels.h b/src/mesa/state_tracker/st_cb_drawpixels.h index 8c36aaa931..71ba487020 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.h +++ b/src/mesa/state_tracker/st_cb_drawpixels.h @@ -30,9 +30,7 @@ #define ST_CB_DRAWPIXELS_H -void st_init_cb_drawpixels( struct st_context *st ); - -void st_destroy_cb_drawpixels( struct st_context *st ); +extern void st_init_drawpixels_functions(struct dd_function_table *functions); #endif /* ST_CB_DRAWPIXELS_H */ diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 6b9ae88dbe..d0205fd635 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -322,10 +322,8 @@ st_finish_render_texture(GLcontext *ctx, -void st_init_cb_fbo( struct st_context *st ) +void st_init_fbo_functions(struct dd_function_table *functions) { - struct dd_function_table *functions = &st->ctx->Driver; - functions->NewFramebuffer = st_new_framebuffer; functions->NewRenderbuffer = st_new_renderbuffer; functions->BindFramebuffer = st_bind_framebuffer; @@ -336,8 +334,3 @@ void st_init_cb_fbo( struct st_context *st ) functions->ResizeBuffers = st_resize_buffers; */ } - - -void st_destroy_cb_fbo( struct st_context *st ) -{ -} diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h index f4fa66df59..6142434ec6 100644 --- a/src/mesa/state_tracker/st_cb_fbo.h +++ b/src/mesa/state_tracker/st_cb_fbo.h @@ -30,9 +30,8 @@ #define ST_CB_FBO_H -extern void st_init_cb_fbo( struct st_context *st ); - -extern void st_destroy_cb_fbo( struct st_context *st ); +extern void +st_init_fbo_functions(struct dd_function_table *functions); #endif /* ST_CB_FBO_H */ diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c index 6da2aeb2f2..ed47c12066 100644 --- a/src/mesa/state_tracker/st_cb_program.c +++ b/src/mesa/state_tracker/st_cb_program.c @@ -32,7 +32,6 @@ #include "st_context.h" #include "st_program.h" - #include "glheader.h" #include "macros.h" #include "enums.h" @@ -44,6 +43,11 @@ #include "pipe/tgsi/mesa/tgsi_mesa.h" +/* Counter to track program string changes: + */ +static GLuint program_id = 0; + + static void st_bind_program( GLcontext *ctx, GLenum target, struct gl_program *prog ) @@ -70,7 +74,7 @@ static struct gl_program *st_new_program( GLcontext *ctx, case GL_VERTEX_PROGRAM_ARB: { struct st_vertex_program *prog = CALLOC_STRUCT(st_vertex_program); - prog->id = st->program_id++; + prog->id = program_id++; prog->dirty = 1; return _mesa_init_vertex_program( ctx, @@ -84,7 +88,7 @@ static struct gl_program *st_new_program( GLcontext *ctx, { struct st_fragment_program *prog = CALLOC_STRUCT(st_fragment_program); - prog->id = st->program_id++; + prog->id = program_id++; prog->dirty = 1; return _mesa_init_fragment_program( ctx, @@ -124,7 +128,7 @@ static void st_program_string_notify( GLcontext *ctx, if (prog == &ctx->FragmentProgram._Current->Base) st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM; - p->id = st->program_id++; + p->id = program_id++; p->param_state = p->Base.Base.Parameters->StateFlags; } else if (target == GL_VERTEX_PROGRAM_ARB) { @@ -133,7 +137,7 @@ static void st_program_string_notify( GLcontext *ctx, if (prog == &ctx->VertexProgram._Current->Base) st->dirty.st |= ST_NEW_VERTEX_PROGRAM; - p->id = st->program_id++; + p->id = program_id++; p->param_state = p->Base.Base.Parameters->StateFlags; /* Also tell tnl about it: @@ -144,15 +148,8 @@ static void st_program_string_notify( GLcontext *ctx, -void st_init_cb_program( struct st_context *st ) +void st_init_program_functions(struct dd_function_table *functions) { - struct dd_function_table *functions = &st->ctx->Driver; - - /* Need these flags: - */ - st->ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; - st->ctx->FragmentProgram._UseTexEnvProgram = GL_TRUE; - #if 0 assert(functions->ProgramStringNotify == _tnl_program_string); #endif @@ -162,9 +159,3 @@ void st_init_cb_program( struct st_context *st ) functions->IsProgramNative = st_is_program_native; functions->ProgramStringNotify = st_program_string_notify; } - - -void st_destroy_cb_program( struct st_context *st ) -{ -} - diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index a0245b553f..5872ae3e74 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -1241,7 +1241,7 @@ do_copy_texsubimage(GLcontext *ctx, get_teximage_source(ctx, internalFormat); if (!stImage->mt || !src) { - DBG("%s fail %p %p\n", __FUNCTION__, stImage->mt, src); + DBG("%s fail %p %p\n", __FUNCTION__, (void *) stImage->mt, (void *) src); return GL_FALSE; } @@ -1726,10 +1726,9 @@ st_tex_unmap_images(struct pipe_context *pipe, -void st_init_cb_texture( struct st_context *st ) +void +st_init_texture_functions(struct dd_function_table *functions) { - struct dd_function_table *functions = &st->ctx->Driver; - functions->ChooseTextureFormat = st_ChooseTextureFormat; functions->TexImage1D = st_TexImage1D; functions->TexImage2D = st_TexImage2D; @@ -1756,8 +1755,3 @@ void st_init_cb_texture( struct st_context *st ) functions->TextureMemCpy = do_memcpy; } - - -void st_destroy_cb_texture( struct st_context *st ) -{ -} diff --git a/src/mesa/state_tracker/st_cb_texture.h b/src/mesa/state_tracker/st_cb_texture.h index c474d16465..c732881c39 100644 --- a/src/mesa/state_tracker/st_cb_texture.h +++ b/src/mesa/state_tracker/st_cb_texture.h @@ -9,11 +9,7 @@ st_finalize_mipmap_tree(GLcontext *ctx, extern void -st_init_cb_texture( struct st_context *st ); - - -extern void -st_destroy_cb_texture( struct st_context *st ); +st_init_texture_functions(struct dd_function_table *functions); #endif /* ST_CB_TEXTURE_H */ diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 2b96286770..0ea06c692d 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -28,6 +28,7 @@ #include "imports.h" #include "st_public.h" #include "st_context.h" +#include "st_cb_bufferobjects.h" #include "st_cb_clear.h" #include "st_cb_drawpixels.h" #include "st_cb_texture.h" @@ -61,10 +62,17 @@ struct st_context *st_create_context( GLcontext *ctx, st_init_atoms( st ); st_init_draw( st ); + /* Need these flags: + */ + st->ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; + st->ctx->FragmentProgram._UseTexEnvProgram = GL_TRUE; + +#if 0 st_init_cb_clear( st ); st_init_cb_program( st ); st_init_cb_drawpixels( st ); st_init_cb_texture( st ); +#endif return st; } @@ -75,11 +83,13 @@ void st_destroy_context( struct st_context *st ) st_destroy_atoms( st ); st_destroy_draw( st ); +#if 0 st_destroy_cb_clear( st ); st_destroy_cb_program( st ); st_destroy_cb_drawpixels( st ); /*st_destroy_cb_teximage( st );*/ st_destroy_cb_texture( st ); +#endif st->pipe->destroy( st->pipe ); FREE( st ); @@ -87,3 +97,11 @@ void st_destroy_context( struct st_context *st ) +void st_init_driver_functions(struct dd_function_table *functions) +{ + st_init_bufferobject_functions(functions); + st_init_clear_functions(functions); + st_init_drawpixels_functions(functions); + st_init_program_functions(functions); + st_init_texture_functions(functions); +} diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index ef3cdb3b09..fe73630c75 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -97,10 +97,6 @@ struct st_context struct st_state_flags dirty; - /* Counter to track program string changes: - */ - GLuint program_id; - GLfloat polygon_offset_scale; /* ?? */ }; @@ -113,4 +109,7 @@ static INLINE struct st_context *st_context(GLcontext *ctx) } +extern void st_init_driver_functions(struct dd_function_table *functions); + + #endif diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index f6d5f6d76c..8dcb2ceb48 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -87,8 +87,9 @@ struct st_vertex_program GLuint param_state; }; -void st_init_cb_program( struct st_context *st ); -void st_destroy_cb_program( struct st_context *st ); + +extern void st_init_program_functions(struct dd_function_table *functions); + static inline struct st_fragment_program * st_fragment_program( struct gl_fragment_program *fp ) -- cgit v1.2.3 From 64da7515009f3551796c90acc74eb0a2ffdb68a0 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 9 Aug 2007 12:27:44 -0600 Subject: checkpoint: no longer using intel_fbo.c --- src/mesa/drivers/dri/intel_winsys/Makefile | 4 +- src/mesa/drivers/dri/intel_winsys/intel_buffers.c | 3 +- src/mesa/drivers/dri/intel_winsys/intel_context.c | 54 ++++++++++++ src/mesa/drivers/dri/intel_winsys/intel_fbo.h | 11 ++- src/mesa/drivers/dri/intel_winsys/intel_screen.c | 28 +++--- src/mesa/drivers/dri/intel_winsys/intel_surface.c | 82 +++++++++++++---- src/mesa/state_tracker/st_cb_fbo.c | 102 ++++++++++++++++++---- src/mesa/state_tracker/st_cb_fbo.h | 8 ++ src/mesa/state_tracker/st_context.c | 2 + 9 files changed, 241 insertions(+), 53 deletions(-) (limited to 'src/mesa/state_tracker/st_cb_fbo.h') diff --git a/src/mesa/drivers/dri/intel_winsys/Makefile b/src/mesa/drivers/dri/intel_winsys/Makefile index 8d3d17e13e..32c2c3bb24 100644 --- a/src/mesa/drivers/dri/intel_winsys/Makefile +++ b/src/mesa/drivers/dri/intel_winsys/Makefile @@ -22,10 +22,10 @@ DRIVER_SOURCES = \ intel_ioctl.c \ intel_screen.c \ intel_surface.c \ - intel_fbo.c \ intel_batchpool.c -UNUSED = intel_depthstencil.c +UNUSED = intel_depthstencil.c \ + intel_fbo.c C_SOURCES = \ $(COMMON_SOURCES) \ diff --git a/src/mesa/drivers/dri/intel_winsys/intel_buffers.c b/src/mesa/drivers/dri/intel_winsys/intel_buffers.c index 9266fb62af..d0139d5b2a 100644 --- a/src/mesa/drivers/dri/intel_winsys/intel_buffers.c +++ b/src/mesa/drivers/dri/intel_winsys/intel_buffers.c @@ -96,6 +96,7 @@ intel_intersect_cliprects(drm_clip_rect_t * dst, /** * Return pointer to current color drawing region, or NULL. */ +#if 0 struct pipe_region * intel_drawbuf_region(struct intel_context *intel) { @@ -120,7 +121,7 @@ intel_readbuf_region(struct intel_context *intel) else return NULL; } - +#endif /** * This will be called whenever the currently bound window is moved/resized. diff --git a/src/mesa/drivers/dri/intel_winsys/intel_context.c b/src/mesa/drivers/dri/intel_winsys/intel_context.c index 9defcc1aae..0d83d4efd6 100644 --- a/src/mesa/drivers/dri/intel_winsys/intel_context.c +++ b/src/mesa/drivers/dri/intel_winsys/intel_context.c @@ -360,6 +360,58 @@ intelCreateContext(const __GLcontextModes * mesaVis, _vbo_CreateContext(ctx); _tnl_CreateContext(ctx); + /* + * Pipe-related setup + */ + if (!getenv("INTEL_HW")) { + intel->pipe = intel_create_softpipe( intel ); + intel->pipe->surface_alloc = intel_new_surface; + intel->pipe->supported_formats = intel_supported_formats; + } + else { + switch (intel->intelScreen->deviceID) { + case PCI_CHIP_I945_G: + case PCI_CHIP_I945_GM: + case PCI_CHIP_I945_GME: + case PCI_CHIP_G33_G: + case PCI_CHIP_Q33_G: + case PCI_CHIP_Q35_G: + case PCI_CHIP_I915_G: + case PCI_CHIP_I915_GM: + intel->pipe = intel_create_i915simple( intel ); + break; + default: + _mesa_printf("Unknown PCIID %x in %s, using software driver\n", + intel->intelScreen->deviceID, __FUNCTION__); + + intel->pipe = intel_create_softpipe( intel ); + break; + } + } + + st_create_context( &intel->ctx, intel->pipe ); + + + /* TODO: Push this down into the pipe driver: + */ + switch (intel->intelScreen->deviceID) { + case PCI_CHIP_I945_G: + case PCI_CHIP_I945_GM: + case PCI_CHIP_I945_GME: + case PCI_CHIP_G33_G: + case PCI_CHIP_Q33_G: + case PCI_CHIP_Q35_G: + intel->pipe->mipmap_tree_layout = i945_miptree_layout; + break; + case PCI_CHIP_I915_G: + case PCI_CHIP_I915_GM: + case PCI_CHIP_I830_M: + case PCI_CHIP_I855_GM: + case PCI_CHIP_I865_G: + intel->pipe->mipmap_tree_layout = i915_miptree_layout; + default: + assert(0); /*FIX*/ + } /* @@ -397,7 +449,9 @@ intelCreateContext(const __GLcontextModes * mesaVis, intel->last_swap_fence = NULL; intel->first_swap_fence = NULL; +#if 00 intel_fbo_init(intel); +#endif if (intel->ctx.Mesa_DXTn) { _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc"); diff --git a/src/mesa/drivers/dri/intel_winsys/intel_fbo.h b/src/mesa/drivers/dri/intel_winsys/intel_fbo.h index 578e1013c2..2801c7345d 100644 --- a/src/mesa/drivers/dri/intel_winsys/intel_fbo.h +++ b/src/mesa/drivers/dri/intel_winsys/intel_fbo.h @@ -73,19 +73,26 @@ struct intel_framebuffer * not pointers because in some circumstances a deleted renderbuffer could * result in a dangling pointer here. */ +#if 0 struct intel_renderbuffer { struct gl_renderbuffer Base; }; +#endif - +#if 0 extern struct intel_renderbuffer *intel_new_renderbuffer_fb(GLuint intFormat); +#endif extern void intel_fbo_init(struct intel_context *intel); extern struct pipe_surface * -intel_new_surface(GLuint intFormat); +intel_new_surface(struct pipe_context *pipe, GLuint pipeFormat); + + +extern const GLuint * +intel_supported_formats(struct pipe_context *pipe, GLuint *numFormats); #endif /* INTEL_FBO_H */ diff --git a/src/mesa/drivers/dri/intel_winsys/intel_screen.c b/src/mesa/drivers/dri/intel_winsys/intel_screen.c index 74cd714cf3..e5f7b36527 100644 --- a/src/mesa/drivers/dri/intel_winsys/intel_screen.c +++ b/src/mesa/drivers/dri/intel_winsys/intel_screen.c @@ -302,34 +302,32 @@ intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, /* fake frontbuffer */ /* XXX allocation should only happen in the unusual case it's actually needed */ - struct intel_renderbuffer *irb - = intel_new_renderbuffer_fb(rgbFormat); - _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT, - &irb->Base); + struct gl_renderbuffer *rb + = st_new_renderbuffer_fb(rgbFormat); + _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT, rb); } if (mesaVis->doubleBufferMode) { - struct intel_renderbuffer *irb - = intel_new_renderbuffer_fb(rgbFormat); - _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT, - &irb->Base); + 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 intel_renderbuffer *depthStencilRb - = intel_new_renderbuffer_fb(GL_DEPTH24_STENCIL8_EXT); + 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->Base); + depthStencilRb); _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_STENCIL, - &depthStencilRb->Base); + depthStencilRb); } else if (mesaVis->depthBits == 16) { /* just 16-bit depth buffer, no hw stencil */ - struct intel_renderbuffer *depthRb - = intel_new_renderbuffer_fb(GL_DEPTH_COMPONENT16); - _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH, &depthRb->Base); + struct gl_renderbuffer *depthRb + = st_new_renderbuffer_fb(GL_DEPTH_COMPONENT16); + _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH, depthRb); } diff --git a/src/mesa/drivers/dri/intel_winsys/intel_surface.c b/src/mesa/drivers/dri/intel_winsys/intel_surface.c index d2e2dabade..20b6bda83f 100644 --- a/src/mesa/drivers/dri/intel_winsys/intel_surface.c +++ b/src/mesa/drivers/dri/intel_winsys/intel_surface.c @@ -159,8 +159,43 @@ write_quad_stencil(struct softpipe_surface *sps, } + + +static void +a8r8g8b8_get_tile(struct pipe_surface *ps, + GLuint x, GLuint y, GLuint w, GLuint h, GLfloat *p) +{ + const GLuint *src + = ((const GLuint *) (ps->region->map + ps->offset)) + + y * ps->region->pitch + x; + GLuint i, j; +#if 0 + assert(x + w <= ps->width); + assert(y + h <= ps->height); +#else + /* temp hack */ + if (x + w > ps->width) + w = ps->width - x; + if (y + h > ps->height) + h = ps->height -y; +#endif + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + p[0] = UBYTE_TO_FLOAT((src[j] >> 16) & 0xff); + p[1] = UBYTE_TO_FLOAT((src[j] >> 8) & 0xff); + p[2] = UBYTE_TO_FLOAT((src[j] >> 0) & 0xff); + p[3] = UBYTE_TO_FLOAT((src[j] >> 24) & 0xff); + p += 4; + } + src += ps->region->pitch; + } +} + + + + struct pipe_surface * -intel_new_surface(GLuint intFormat) +intel_new_surface(struct pipe_context *pipe, GLuint pipeFormat) { struct softpipe_surface *sps = CALLOC_STRUCT(softpipe_surface); if (!sps) @@ -168,31 +203,42 @@ intel_new_surface(GLuint intFormat) sps->surface.width = 0; /* set in intel_alloc_renderbuffer_storage() */ sps->surface.height = 0; + sps->surface.refcount = 1; + sps->surface.format = pipeFormat; - if (intFormat == GL_RGBA8) { - sps->surface.format = PIPE_FORMAT_U_A8_R8_G8_B8; + switch (pipeFormat) { + case PIPE_FORMAT_U_A8_R8_G8_B8: sps->read_quad_f_swz = read_quad_f_swz; sps->write_quad_f_swz = write_quad_f_swz; - } - else if (intFormat == GL_RGB5) { - sps->surface.format = PIPE_FORMAT_U_R5_G6_B5; - - } - else if (intFormat == GL_DEPTH_COMPONENT16) { - sps->surface.format = PIPE_FORMAT_U_Z16; - - } - else if (intFormat == GL_DEPTH24_STENCIL8_EXT) { - sps->surface.format = PIPE_FORMAT_S8_Z24; + sps->surface.get_tile = a8r8g8b8_get_tile; + break; + case PIPE_FORMAT_U_R5_G6_B5: + break; + case PIPE_FORMAT_U_Z16: + break; + case PIPE_FORMAT_S8_Z24: sps->read_quad_z = read_quad_z24; sps->write_quad_z = write_quad_z24; sps->read_quad_stencil = read_quad_stencil; sps->write_quad_stencil = write_quad_stencil; - } - else { - /* TBD / unknown */ - + break; } return &sps->surface; } + + + +const GLuint * +intel_supported_formats(struct pipe_context *pipe, GLuint *numFormats) +{ + static const GLuint formats[] = { + PIPE_FORMAT_U_A8_R8_G8_B8, + PIPE_FORMAT_U_R5_G6_B5, + PIPE_FORMAT_S8_Z24, + }; + + *numFormats = sizeof(formats) / sizeof(formats[0]); + return formats; +} + diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index d0205fd635..3cd1fbe851 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -53,7 +53,9 @@ struct st_renderbuffer { struct gl_renderbuffer Base; +#if 0 struct pipe_surface *surface; +#endif }; @@ -93,14 +95,14 @@ pipe_get_format_info(GLuint format) { PIPE_FORMAT_U_R8_G8_B8_A8, /* format */ GL_RGBA, /* base_format */ - 4, 4, 4, 4, 0, 0, /* color bits */ + 8, 8, 8, 8, 0, 0, /* color bits */ 0, 0, /* depth, stencil */ 4 /* size in bytes */ }, { PIPE_FORMAT_U_A8_R8_G8_B8, GL_RGBA, /* base_format */ - 4, 4, 4, 4, 0, 0, /* color bits */ + 8, 8, 8, 8, 0, 0, /* color bits */ 0, 0, /* depth, stencil */ 4 /* size in bytes */ }, @@ -166,29 +168,29 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, cpp = info->size; - if (!strb->surface) { - strb->surface = pipe->surface_alloc(pipe, pipeFormat); - if (!strb->surface) + if (!strb->Base.surface) { + strb->Base.surface = pipe->surface_alloc(pipe, pipeFormat); + if (!strb->Base.surface) return GL_FALSE; } /* free old region */ - if (strb->surface->region) { - pipe->region_release(pipe, &strb->surface->region); + if (strb->Base.surface->region) { + pipe->region_release(pipe, &strb->Base.surface->region); } /* Choose a pitch to match hardware requirements: */ pitch = ((cpp * width + 63) & ~63) / cpp; /* XXX fix: device-specific */ - strb->surface->region = pipe->region_alloc(pipe, cpp, pitch, height); - if (!strb->surface->region) + strb->Base.surface->region = pipe->region_alloc(pipe, cpp, pitch, height); + if (!strb->Base.surface->region) return GL_FALSE; /* out of memory, try s/w buffer? */ - ASSERT(strb->surface->region->buffer); + ASSERT(strb->Base.surface->region->buffer); - strb->Base.Width = strb->surface->width = width; - strb->Base.Height = strb->surface->height = height; + strb->Base.Width = strb->Base.surface->width = width; + strb->Base.Height = strb->Base.surface->height = height; return GL_TRUE; } @@ -204,11 +206,11 @@ st_renderbuffer_delete(struct gl_renderbuffer *rb) struct pipe_context *pipe = ctx->st->pipe; struct st_renderbuffer *strb = st_renderbuffer(rb); ASSERT(strb); - if (strb && strb->surface) { + if (strb && strb->Base.surface) { if (rb->surface->region) { - pipe->region_release(pipe, &strb->surface->region); + pipe->region_release(pipe, &strb->Base.surface->region); } - free(strb->surface); + free(strb->Base.surface); } free(strb); } @@ -257,6 +259,76 @@ st_new_renderbuffer(GLcontext *ctx, GLuint name) return NULL; } + +#if 000 +struct gl_renderbuffer * +st_new_renderbuffer_fb(struct pipe_region *region, GLuint width, GLuint height) +{ + struct st_renderbuffer *strb = CALLOC_STRUCT(st_renderbuffer); + if (!strb) + return; + + _mesa_init_renderbuffer(&strb->Base, name); + strb->Base.Delete = st_renderbuffer_delete; + strb->Base.AllocStorage = st_renderbuffer_alloc_storage; + strb->Base.GetPointer = null_get_pointer; + strb->Base.Width = width; + strb->Base.Heigth = height; + + strb->region = region; + + return &strb->Base; +} + +#else + +struct gl_renderbuffer * +st_new_renderbuffer_fb(GLuint intFormat) +{ + struct st_renderbuffer *irb; + + irb = CALLOC_STRUCT(st_renderbuffer); + if (!irb) { + _mesa_error(NULL, GL_OUT_OF_MEMORY, "creating renderbuffer"); + return NULL; + } + + _mesa_init_renderbuffer(&irb->Base, 0); + irb->Base.ClassID = 0x42; /* XXX temp */ + irb->Base.InternalFormat = intFormat; + + switch (intFormat) { + case GL_RGB5: + case GL_RGBA8: + irb->Base._BaseFormat = GL_RGBA; + break; + case GL_DEPTH_COMPONENT16: + irb->Base._BaseFormat = GL_DEPTH_COMPONENT; + break; + case GL_DEPTH24_STENCIL8_EXT: + irb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT; + break; + default: + _mesa_problem(NULL, + "Unexpected intFormat in st_new_renderbuffer"); + return NULL; + } + + /* st-specific methods */ + irb->Base.Delete = st_renderbuffer_delete; + irb->Base.AllocStorage = st_renderbuffer_alloc_storage; + irb->Base.GetPointer = null_get_pointer; + /* span routines set in alloc_storage function */ + + irb->Base.surface = NULL;/*intel_new_surface(intFormat);*/ + /*irb->Base.surface->rb = irb;*/ + + return &irb->Base; +} +#endif + + + /** * 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 6142434ec6..7f52ab10d7 100644 --- a/src/mesa/state_tracker/st_cb_fbo.h +++ b/src/mesa/state_tracker/st_cb_fbo.h @@ -30,6 +30,14 @@ #define ST_CB_FBO_H +/* +extern struct gl_renderbuffer * +st_new_renderbuffer_fb(struct pipe_region *region, GLuint width, GLuint height); +*/ +extern struct gl_renderbuffer * +st_new_renderbuffer_fb(GLuint intFormat); + + extern void st_init_fbo_functions(struct dd_function_table *functions); diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 0ea06c692d..9f7916e40e 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -31,6 +31,7 @@ #include "st_cb_bufferobjects.h" #include "st_cb_clear.h" #include "st_cb_drawpixels.h" +#include "st_cb_fbo.h" #include "st_cb_texture.h" #include "st_atom.h" #include "st_draw.h" @@ -102,6 +103,7 @@ void st_init_driver_functions(struct dd_function_table *functions) st_init_bufferobject_functions(functions); st_init_clear_functions(functions); st_init_drawpixels_functions(functions); + st_init_fbo_functions(functions); st_init_program_functions(functions); st_init_texture_functions(functions); } -- cgit v1.2.3 From f5713c7d2e7ba8e1170fd9b1dd95379662ab6117 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 9 Aug 2007 12:59:11 -0600 Subject: Checkpoint intel_renderbuffer removal. Remove surface ptr from gl_renderbuffer. Use st_renderbuffer in most places. More clean-up. --- src/mesa/drivers/dri/intel_winsys/intel_blit.c | 14 +++-- src/mesa/main/mtypes.h | 2 - src/mesa/main/renderbuffer.c | 14 ++++- src/mesa/pipe/p_state.h | 2 - src/mesa/state_tracker/st_atom_framebuffer.c | 27 +++++---- src/mesa/state_tracker/st_cb_clear.c | 35 +++++++---- src/mesa/state_tracker/st_cb_fbo.c | 82 +++++++++----------------- src/mesa/state_tracker/st_cb_fbo.h | 23 ++++++-- 8 files changed, 107 insertions(+), 92 deletions(-) (limited to 'src/mesa/state_tracker/st_cb_fbo.h') diff --git a/src/mesa/drivers/dri/intel_winsys/intel_blit.c b/src/mesa/drivers/dri/intel_winsys/intel_blit.c index 48bbbbeac9..aa4135ed2d 100644 --- a/src/mesa/drivers/dri/intel_winsys/intel_blit.c +++ b/src/mesa/drivers/dri/intel_winsys/intel_blit.c @@ -38,6 +38,7 @@ #include "vblank.h" #include "pipe/p_context.h" +#include "state_tracker/st_cb_fbo.h" #define FILE_DEBUG_FLAG DEBUG_BLIT @@ -106,12 +107,17 @@ intelCopyBuffer(__DRIdrawablePrivate * dPriv, const struct pipe_surface *backSurf; const struct pipe_region *backRegion; int srcpitch; + struct st_renderbuffer *strb; /* blit from back color buffer if it exists, else front buffer */ - if (intel_fb->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer) - backSurf = intel_fb->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer->surface; - else - backSurf = intel_fb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer->surface; + strb = st_renderbuffer(intel_fb->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer); + if (strb) { + backSurf = strb->surface; + } + else { + strb = st_renderbuffer(intel_fb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + backSurf = strb->surface; + } backRegion = backSurf->region; srcpitch = backRegion->pitch; diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index d70df5d945..0a64e0c58c 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2269,8 +2269,6 @@ struct gl_renderbuffer GLubyte StencilBits; GLvoid *Data; /**< This may not be used by some kinds of RBs */ - struct pipe_surface *surface; - /* Used to wrap one renderbuffer around another: */ struct gl_renderbuffer *Wrapped; diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c index d89704196a..e7aeea8e3e 100644 --- a/src/mesa/main/renderbuffer.c +++ b/src/mesa/main/renderbuffer.c @@ -1067,9 +1067,11 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, rb->PutMonoValues = put_mono_values_ubyte; rb->StencilBits = 8 * sizeof(GLubyte); pixelSize = sizeof(GLubyte); +#if 0 if (!rb->surface) rb->surface = (struct pipe_surface *) pipe->surface_alloc(pipe, PIPE_FORMAT_U_S8); +#endif break; case GL_STENCIL_INDEX16_EXT: rb->_ActualFormat = GL_STENCIL_INDEX16_EXT; @@ -1100,9 +1102,11 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, rb->PutValues = put_values_ushort; rb->PutMonoValues = put_mono_values_ushort; rb->DepthBits = 8 * sizeof(GLushort); +#if 0 if (!rb->surface) rb->surface = (struct pipe_surface *) pipe->surface_alloc(pipe, PIPE_FORMAT_U_Z16); +#endif pixelSize = sizeof(GLushort); break; case GL_DEPTH_COMPONENT24: @@ -1125,9 +1129,11 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, rb->_ActualFormat = GL_DEPTH_COMPONENT32; rb->DepthBits = 32; } +#if 0 if (!rb->surface) rb->surface = (struct pipe_surface *) pipe->surface_alloc(pipe, PIPE_FORMAT_U_Z32); +#endif pixelSize = sizeof(GLuint); break; case GL_DEPTH_STENCIL_EXT: @@ -1145,9 +1151,11 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, rb->PutMonoValues = put_mono_values_uint; rb->DepthBits = 24; rb->StencilBits = 8; +#if 0 if (!rb->surface) rb->surface = (struct pipe_surface *) pipe->surface_alloc(pipe, PIPE_FORMAT_S8_Z24); +#endif pixelSize = sizeof(GLuint); break; case GL_COLOR_INDEX8_EXT: @@ -1210,7 +1218,7 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, ASSERT(rb->PutMonoValues); /* free old buffer storage */ - if (rb->surface) { + if (0/**rb->surface**/) { /* pipe_surface/region */ } else if (rb->Data) { @@ -1221,8 +1229,9 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, if (width > 0 && height > 0) { /* allocate new buffer storage */ - if (rb->surface) { + if (0/**rb->surface**/) { /* pipe_surface/region */ +#if 0 if (rb->surface->region) { pipe->region_unmap(pipe, rb->surface->region); pipe->region_release(pipe, &rb->surface->region); @@ -1231,6 +1240,7 @@ _mesa_soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, /* XXX probably don't want to really map here */ pipe->region_map(pipe, rb->surface->region); rb->Data = rb->surface->region->map; +#endif } else { /* legacy renderbuffer (this will go away) */ diff --git a/src/mesa/pipe/p_state.h b/src/mesa/pipe/p_state.h index 2dcd2db868..ee29e38a48 100644 --- a/src/mesa/pipe/p_state.h +++ b/src/mesa/pipe/p_state.h @@ -260,8 +260,6 @@ struct pipe_surface GLuint offset; /**< offset from start of region, in bytes */ GLint refcount; - void *rb; /**< Ptr back to renderbuffer (temporary?) */ - /** get block/tile of pixels from surface */ void (*get_tile)(struct pipe_surface *ps, GLuint x, GLuint y, GLuint w, GLuint h, GLfloat *p); diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c index 7edd044ad9..f054eb8f21 100644 --- a/src/mesa/state_tracker/st_atom_framebuffer.c +++ b/src/mesa/state_tracker/st_atom_framebuffer.c @@ -33,6 +33,7 @@ #include "st_context.h" #include "st_atom.h" +#include "st_cb_fbo.h" #include "pipe/p_context.h" @@ -44,7 +45,7 @@ static void update_framebuffer_state( struct st_context *st ) { struct pipe_framebuffer_state framebuffer; - struct gl_renderbuffer *rb; + struct st_renderbuffer *strb; GLuint i; memset(&framebuffer, 0, sizeof(framebuffer)); @@ -54,21 +55,23 @@ update_framebuffer_state( struct st_context *st ) */ framebuffer.num_cbufs = st->ctx->DrawBuffer->_NumColorDrawBuffers[0]; for (i = 0; i < framebuffer.num_cbufs; i++) { - rb = st->ctx->DrawBuffer->_ColorDrawBuffers[0][i]; - assert(rb->surface); - framebuffer.cbufs[i] = rb->surface; + strb = st_renderbuffer(st->ctx->DrawBuffer->_ColorDrawBuffers[0][i]); + assert(strb->surface); + framebuffer.cbufs[i] = strb->surface; } - rb = st->ctx->DrawBuffer->_DepthBuffer; - if (rb) { - assert(rb->Wrapped->surface); - framebuffer.zbuf = rb->Wrapped->surface; + strb = st_renderbuffer(st->ctx->DrawBuffer->_DepthBuffer); + if (strb) { + strb = st_renderbuffer(strb->Base.Wrapped); + assert(strb->surface); + framebuffer.zbuf = strb->surface; } - rb = st->ctx->DrawBuffer->_StencilBuffer; - if (rb) { - assert(rb->Wrapped->surface); - framebuffer.sbuf = rb->Wrapped->surface; + strb = st_renderbuffer(st->ctx->DrawBuffer->_StencilBuffer); + if (strb) { + strb = st_renderbuffer(strb->Base.Wrapped); + assert(strb->surface); + framebuffer.sbuf = strb->surface; } if (memcmp(&framebuffer, &st->state.framebuffer, sizeof(framebuffer)) != 0) { diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index d862f7ba46..4da3a2500d 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -37,6 +37,7 @@ #include "st_atom.h" #include "st_context.h" #include "st_cb_clear.h" +#include "st_cb_fbo.h" #include "st_program.h" #include "st_public.h" #include "pipe/p_context.h" @@ -288,6 +289,8 @@ clear_with_quad(GLcontext *ctx, GLuint x0, GLuint y0, static void clear_color_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) { + struct st_renderbuffer *strb = st_renderbuffer(rb); + if (ctx->Color.ColorMask[0] && ctx->Color.ColorMask[1] && ctx->Color.ColorMask[2] && @@ -296,8 +299,8 @@ clear_color_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) { /* clear whole buffer w/out masking */ GLuint clearValue - = color_value(rb->surface->format, ctx->Color.ClearColor); - ctx->st->pipe->clear(ctx->st->pipe, rb->surface, clearValue); + = color_value(strb->surface->format, ctx->Color.ClearColor); + ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue); } else { /* masking or scissoring */ @@ -314,14 +317,16 @@ clear_color_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) static void clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) { + struct st_renderbuffer *strb = st_renderbuffer(rb); + if (!ctx->Scissor.Enabled) { /* clear whole buffer w/out masking */ GLuint clearValue - = color_value(rb->surface->format, ctx->Accum.ClearColor); + = color_value(strb->surface->format, ctx->Accum.ClearColor); /* Note that clearValue is 32 bits but the accum buffer will * typically be 64bpp... */ - ctx->st->pipe->clear(ctx->st->pipe, rb->surface, clearValue); + ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue); } else { /* scissoring */ @@ -339,11 +344,13 @@ clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) static void clear_depth_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) { + struct st_renderbuffer *strb = st_renderbuffer(rb); + if (!ctx->Scissor.Enabled && - !is_depth_stencil_format(rb->surface->format)) { + !is_depth_stencil_format(strb->surface->format)) { /* clear whole depth buffer w/out masking */ - GLuint clearValue = depth_value(rb->surface->format, ctx->Depth.Clear); - ctx->st->pipe->clear(ctx->st->pipe, rb->surface, clearValue); + GLuint clearValue = depth_value(strb->surface->format, ctx->Depth.Clear); + ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue); } else { /* masking or scissoring or combined z/stencil buffer */ @@ -360,14 +367,15 @@ clear_depth_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) static void clear_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) { + struct st_renderbuffer *strb = st_renderbuffer(rb); const GLuint stencilMax = (1 << rb->StencilBits) - 1; GLboolean maskStencil = ctx->Stencil.WriteMask[0] != stencilMax; if (!maskStencil && !ctx->Scissor.Enabled && - !is_depth_stencil_format(rb->surface->format)) { + !is_depth_stencil_format(strb->surface->format)) { /* clear whole stencil buffer w/out masking */ GLuint clearValue = ctx->Stencil.Clear; - ctx->st->pipe->clear(ctx->st->pipe, rb->surface, clearValue); + ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue); } else { /* masking or scissoring */ @@ -384,16 +392,17 @@ clear_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) static void clear_depth_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) { + struct st_renderbuffer *strb = st_renderbuffer(rb); const GLuint stencilMax = 1 << rb->StencilBits; GLboolean maskStencil = ctx->Stencil.WriteMask[0] != stencilMax; - assert(is_depth_stencil_format(rb->surface->format)); + assert(is_depth_stencil_format(strb->surface->format)); if (!maskStencil && !ctx->Scissor.Enabled) { /* clear whole buffer w/out masking */ - GLuint clearValue = depth_value(rb->surface->format, ctx->Depth.Clear); + GLuint clearValue = depth_value(strb->surface->format, ctx->Depth.Clear); - switch (rb->surface->format) { + switch (strb->surface->format) { case PIPE_FORMAT_S8_Z24: clearValue |= ctx->Stencil.Clear << 24; break; @@ -406,7 +415,7 @@ clear_depth_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) assert(0); } - ctx->st->pipe->clear(ctx->st->pipe, rb->surface, clearValue); + ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue); } else { /* masking or scissoring */ diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 3cd1fbe851..02bdb5aba5 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -46,29 +46,6 @@ #include "st_cb_teximage.h" -/** - * Derived renderbuffer class. Just need to add a pointer to the - * pipe surface. - */ -struct st_renderbuffer -{ - struct gl_renderbuffer Base; -#if 0 - struct pipe_surface *surface; -#endif -}; - - -/** - * Cast wrapper. - */ -static INLINE struct st_renderbuffer * -st_renderbuffer(struct gl_renderbuffer *rb) -{ - return (struct st_renderbuffer *) rb; -} - - struct pipe_format_info { GLuint format; @@ -168,29 +145,29 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, cpp = info->size; - if (!strb->Base.surface) { - strb->Base.surface = pipe->surface_alloc(pipe, pipeFormat); - if (!strb->Base.surface) + if (!strb->surface) { + strb->surface = pipe->surface_alloc(pipe, pipeFormat); + if (!strb->surface) return GL_FALSE; } /* free old region */ - if (strb->Base.surface->region) { - pipe->region_release(pipe, &strb->Base.surface->region); + if (strb->surface->region) { + pipe->region_release(pipe, &strb->surface->region); } /* Choose a pitch to match hardware requirements: */ pitch = ((cpp * width + 63) & ~63) / cpp; /* XXX fix: device-specific */ - strb->Base.surface->region = pipe->region_alloc(pipe, cpp, pitch, height); - if (!strb->Base.surface->region) + strb->surface->region = pipe->region_alloc(pipe, cpp, pitch, height); + if (!strb->surface->region) return GL_FALSE; /* out of memory, try s/w buffer? */ - ASSERT(strb->Base.surface->region->buffer); + ASSERT(strb->surface->region->buffer); - strb->Base.Width = strb->Base.surface->width = width; - strb->Base.Height = strb->Base.surface->height = height; + strb->Base.Width = strb->surface->width = width; + strb->Base.Height = strb->surface->height = height; return GL_TRUE; } @@ -206,11 +183,11 @@ st_renderbuffer_delete(struct gl_renderbuffer *rb) struct pipe_context *pipe = ctx->st->pipe; struct st_renderbuffer *strb = st_renderbuffer(rb); ASSERT(strb); - if (strb && strb->Base.surface) { - if (rb->surface->region) { - pipe->region_release(pipe, &strb->Base.surface->region); + if (strb && strb->surface) { + if (strb->surface->region) { + pipe->region_release(pipe, &strb->surface->region); } - free(strb->Base.surface); + free(strb->surface); } free(strb); } @@ -285,28 +262,28 @@ st_new_renderbuffer_fb(struct pipe_region *region, GLuint width, GLuint height) struct gl_renderbuffer * st_new_renderbuffer_fb(GLuint intFormat) { - struct st_renderbuffer *irb; + struct st_renderbuffer *strb; - irb = CALLOC_STRUCT(st_renderbuffer); - if (!irb) { + strb = CALLOC_STRUCT(st_renderbuffer); + if (!strb) { _mesa_error(NULL, GL_OUT_OF_MEMORY, "creating renderbuffer"); return NULL; } - _mesa_init_renderbuffer(&irb->Base, 0); - irb->Base.ClassID = 0x42; /* XXX temp */ - irb->Base.InternalFormat = intFormat; + _mesa_init_renderbuffer(&strb->Base, 0); + strb->Base.ClassID = 0x42; /* XXX temp */ + strb->Base.InternalFormat = intFormat; switch (intFormat) { case GL_RGB5: case GL_RGBA8: - irb->Base._BaseFormat = GL_RGBA; + strb->Base._BaseFormat = GL_RGBA; break; case GL_DEPTH_COMPONENT16: - irb->Base._BaseFormat = GL_DEPTH_COMPONENT; + strb->Base._BaseFormat = GL_DEPTH_COMPONENT; break; case GL_DEPTH24_STENCIL8_EXT: - irb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT; + strb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT; break; default: _mesa_problem(NULL, @@ -315,15 +292,14 @@ st_new_renderbuffer_fb(GLuint intFormat) } /* st-specific methods */ - irb->Base.Delete = st_renderbuffer_delete; - irb->Base.AllocStorage = st_renderbuffer_alloc_storage; - irb->Base.GetPointer = null_get_pointer; - /* span routines set in alloc_storage function */ + strb->Base.Delete = st_renderbuffer_delete; + strb->Base.AllocStorage = st_renderbuffer_alloc_storage; + strb->Base.GetPointer = null_get_pointer; - irb->Base.surface = NULL;/*intel_new_surface(intFormat);*/ - /*irb->Base.surface->rb = irb;*/ + /* surface is allocate in alloc_renderbuffer_storage() */ + strb->surface = NULL; - return &irb->Base; + return &strb->Base; } #endif diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h index 7f52ab10d7..b2e7ba810c 100644 --- a/src/mesa/state_tracker/st_cb_fbo.h +++ b/src/mesa/state_tracker/st_cb_fbo.h @@ -30,10 +30,25 @@ #define ST_CB_FBO_H -/* -extern struct gl_renderbuffer * -st_new_renderbuffer_fb(struct pipe_region *region, GLuint width, GLuint height); -*/ + +/** + * Derived renderbuffer class. Just need to add a pointer to the + * pipe surface. + */ +struct st_renderbuffer +{ + struct gl_renderbuffer Base; + struct pipe_surface *surface; +}; + + +static INLINE struct st_renderbuffer * +st_renderbuffer(struct gl_renderbuffer *rb) +{ + return (struct st_renderbuffer *) rb; +} + + extern struct gl_renderbuffer * st_new_renderbuffer_fb(GLuint intFormat); -- cgit v1.2.3 From 6883930f61c67924789f2c7cbc274627407cc784 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 9 Aug 2007 22:56:21 +0100 Subject: init strb->Base.DataType appropriately, clean-ups --- src/mesa/state_tracker/st_cb_fbo.c | 14 ++++++++++++-- src/mesa/state_tracker/st_cb_fbo.h | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'src/mesa/state_tracker/st_cb_fbo.h') diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 15816bee9e..67e239fd6d 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -135,8 +135,15 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, if (!info) return GL_FALSE; + switch (pipeFormat) { + case PIPE_FORMAT_S8_Z24: + strb->Base.DataType = GL_UNSIGNED_INT; + break; + default: + strb->Base.DataType = GL_UNSIGNED_BYTE; /* XXX fix */ + } + strb->Base._ActualFormat = info->base_format; - strb->Base.DataType = GL_UNSIGNED_BYTE; /* XXX fix */ strb->Base.RedBits = info->red_bits; strb->Base.GreenBits = info->green_bits; strb->Base.BlueBits = info->blue_bits; @@ -205,7 +212,9 @@ null_get_pointer(GLcontext * ctx, struct gl_renderbuffer *rb, /* By returning NULL we force all software rendering to go through * the span routines. */ +#if 0 assert(0); /* Should never get called with softpipe */ +#endif return NULL; } @@ -262,7 +271,7 @@ st_new_renderbuffer_fb(struct pipe_region *region, GLuint width, GLuint height) #else struct gl_renderbuffer * -st_new_renderbuffer_fb(GLuint intFormat) +st_new_renderbuffer_fb(GLenum intFormat) { struct st_renderbuffer *strb; @@ -282,6 +291,7 @@ st_new_renderbuffer_fb(GLuint intFormat) strb->Base._BaseFormat = GL_RGBA; break; case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT32: strb->Base._BaseFormat = GL_DEPTH_COMPONENT; break; case GL_DEPTH24_STENCIL8_EXT: diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h index b2e7ba810c..2280441db5 100644 --- a/src/mesa/state_tracker/st_cb_fbo.h +++ b/src/mesa/state_tracker/st_cb_fbo.h @@ -50,7 +50,7 @@ st_renderbuffer(struct gl_renderbuffer *rb) extern struct gl_renderbuffer * -st_new_renderbuffer_fb(GLuint intFormat); +st_new_renderbuffer_fb(GLenum intFormat); extern void -- 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_cb_fbo.h') 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 86ea86a58f..9c643dd0ba 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 b915a67790..f505ff6ae6 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 b3a2122ade..00379fbacf 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 8dce3aba90..d3afef95b4 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 809b165f45..8b8e04c2f9 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 1912e59b9f..cbf64ebb85 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 c347d1c2a3..68f9c39116 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 c0e41dbeec..0179000353 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 36d25a576d..6e9e7e3a24 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 2280441db5..bd85bfc549 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 8d39e1bec6..c292a975f3 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 6ccf5536f9..ebff7c5b91 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 8633f431b2..454306b874 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_cb_fbo.h') diff --git a/src/mesa/drivers/dri/intel_winsys/intel_screen.c b/src/mesa/drivers/dri/intel_winsys/intel_screen.c index 1b520f7135..bce6c5699a 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 1dc494d6ff..c81e0f9c18 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 4021af187c..142074bc65 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 047de412e3..254740ff20 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 bd85bfc549..21e531d1d0 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 287a0054b9..2a23445ca2 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 ebff7c5b91..c9a11de504 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 454306b874..b81a894ef1 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 307635936b..558b20f1e8 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 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_cb_fbo.h') diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c index a623d0bcc0..35352351d5 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 e55281a430..b1a56f3ca6 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 21e531d1d0..c1aa14f9b2 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 075e9d1bd6..ea09d9234c 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 296378b6c8b205048244746e260739448c4ee590 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 6 May 2008 13:47:41 -0600 Subject: gallium: create drawing surfaces as GPU_READ/WRITE only Create different temporary surfaces for CPU_READ/WRITE when needed (such as for glReadPixels, glAccum, some glCopy/DrawPixels, glCopyTexSubImage, etc). --- src/mesa/state_tracker/st_cb_accum.c | 73 ++++++++++++++++++++++--------- src/mesa/state_tracker/st_cb_drawpixels.c | 33 +++++++++++--- src/mesa/state_tracker/st_cb_fbo.c | 25 ++++++----- src/mesa/state_tracker/st_cb_fbo.h | 3 +- src/mesa/state_tracker/st_cb_readpixels.c | 34 +++++++++----- src/mesa/state_tracker/st_cb_texture.c | 10 ++++- 6 files changed, 129 insertions(+), 49 deletions(-) (limited to 'src/mesa/state_tracker/st_cb_fbo.h') diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c index e4ef3e16b7..8098d75e18 100644 --- a/src/mesa/state_tracker/st_cb_accum.c +++ b/src/mesa/state_tracker/st_cb_accum.c @@ -105,7 +105,7 @@ void st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) { struct st_renderbuffer *acc_strb = st_renderbuffer(rb); - struct pipe_surface *acc_ps = acc_strb->surface; + struct pipe_surface *acc_ps; struct pipe_screen *screen = ctx->st->pipe->screen; const GLint xpos = ctx->DrawBuffer->_Xmin; const GLint ypos = ctx->DrawBuffer->_Ymin; @@ -113,6 +113,8 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) const GLint height = ctx->DrawBuffer->_Ymax - ypos; GLvoid *map; + acc_ps = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_WRITE); map = screen->surface_map(screen, acc_ps, PIPE_BUFFER_USAGE_CPU_WRITE); @@ -143,6 +145,7 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) } screen->surface_unmap(screen, acc_ps); + pipe_surface_reference(&acc_ps, NULL); } @@ -185,70 +188,100 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias, static void accum_accum(struct pipe_context *pipe, GLfloat value, GLint xpos, GLint ypos, GLint width, GLint height, - struct pipe_surface *acc_ps, - struct pipe_surface *color_ps) + struct st_renderbuffer *acc_strb, + struct st_renderbuffer *color_strb) { + struct pipe_screen *screen = pipe->screen; + struct pipe_surface *acc_surf, *color_surf; GLfloat *colorBuf, *accBuf; GLint i; + acc_surf = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0, + (PIPE_BUFFER_USAGE_CPU_WRITE | + PIPE_BUFFER_USAGE_CPU_READ)); + + color_surf = screen->get_tex_surface(screen, color_strb->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_READ); + colorBuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); accBuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); - pipe_get_tile_rgba(pipe, color_ps, xpos, ypos, width, height, colorBuf); - acc_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf); + pipe_get_tile_rgba(pipe, color_surf, xpos, ypos, width, height, colorBuf); + acc_get_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, accBuf); for (i = 0; i < 4 * width * height; i++) { accBuf[i] = accBuf[i] + colorBuf[i] * value; } - acc_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, accBuf); + acc_put_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, accBuf); free(colorBuf); free(accBuf); + pipe_surface_reference(&acc_surf, NULL); + pipe_surface_reference(&color_surf, NULL); } static void accum_load(struct pipe_context *pipe, GLfloat value, GLint xpos, GLint ypos, GLint width, GLint height, - struct pipe_surface *acc_ps, - struct pipe_surface *color_ps) + struct st_renderbuffer *acc_strb, + struct st_renderbuffer *color_strb) { + struct pipe_screen *screen = pipe->screen; + struct pipe_surface *acc_surf, *color_surf; GLfloat *buf; GLint i; + acc_surf = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_WRITE); + + color_surf = screen->get_tex_surface(screen, color_strb->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_READ); + buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); - pipe_get_tile_rgba(pipe, color_ps, xpos, ypos, width, height, buf); + pipe_get_tile_rgba(pipe, color_surf, xpos, ypos, width, height, buf); for (i = 0; i < 4 * width * height; i++) { buf[i] = buf[i] * value; } - acc_put_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, buf); + acc_put_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, buf); free(buf); + pipe_surface_reference(&acc_surf, NULL); + pipe_surface_reference(&color_surf, NULL); } static void accum_return(GLcontext *ctx, GLfloat value, GLint xpos, GLint ypos, GLint width, GLint height, - struct pipe_surface *acc_ps, - struct pipe_surface *color_ps) + struct st_renderbuffer *acc_strb, + struct st_renderbuffer *color_strb) { struct pipe_context *pipe = ctx->st->pipe; + struct pipe_screen *screen = pipe->screen; const GLubyte *colormask = ctx->Color.ColorMask; + struct pipe_surface *acc_surf, *color_surf; GLfloat *abuf, *cbuf = NULL; GLint i, ch; abuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); - acc_get_tile_rgba(pipe, acc_ps, xpos, ypos, width, height, abuf); + acc_surf = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_READ); + + color_surf = screen->get_tex_surface(screen, color_strb->texture, 0, 0, 0, + (PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE)); + + acc_get_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, abuf); if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3]) { cbuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); - pipe_get_tile_rgba(pipe, color_ps, xpos, ypos, width, height, cbuf); + pipe_get_tile_rgba(pipe, color_surf, xpos, ypos, width, height, cbuf); } for (i = 0; i < width * height; i++) { @@ -263,11 +296,13 @@ accum_return(GLcontext *ctx, GLfloat value, } } - pipe_put_tile_rgba(pipe, color_ps, xpos, ypos, width, height, abuf); + pipe_put_tile_rgba(pipe, color_surf, xpos, ypos, width, height, abuf); free(abuf); if (cbuf) free(cbuf); + pipe_surface_reference(&acc_surf, NULL); + pipe_surface_reference(&color_surf, NULL); } @@ -280,8 +315,6 @@ st_Accum(GLcontext *ctx, GLenum op, GLfloat value) = st_renderbuffer(ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer); struct st_renderbuffer *color_strb = st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer); - struct pipe_surface *acc_ps = acc_strb->surface; - struct pipe_surface *color_ps = color_strb->surface; const GLint xpos = ctx->DrawBuffer->_Xmin; const GLint ypos = ctx->DrawBuffer->_Ymin; @@ -304,14 +337,14 @@ st_Accum(GLcontext *ctx, GLenum op, GLfloat value) break; case GL_ACCUM: if (value != 0.0F) { - accum_accum(pipe, value, xpos, ypos, width, height, acc_ps, color_ps); + accum_accum(pipe, value, xpos, ypos, width, height, acc_strb, color_strb); } break; case GL_LOAD: - accum_load(pipe, value, xpos, ypos, width, height, acc_ps, color_ps); + accum_load(pipe, value, xpos, ypos, width, height, acc_strb, color_strb); break; case GL_RETURN: - accum_return(ctx, value, xpos, ypos, width, height, acc_ps, color_ps); + accum_return(ctx, value, xpos, ypos, width, height, acc_strb, color_strb); break; default: assert(0); diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 6ec3c343cd..c967c989de 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -734,13 +734,19 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, struct st_context *st = ctx->st; struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; - struct pipe_surface *ps = st->state.framebuffer.zsbuf; + struct st_renderbuffer *strb; + struct pipe_surface *ps; const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0; GLint skipPixels; ubyte *stmap; pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); + strb = st_renderbuffer(ctx->DrawBuffer-> + Attachment[BUFFER_STENCIL].Renderbuffer); + ps = screen->get_tex_surface(screen, strb->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_WRITE); + /* map the stencil buffer */ stmap = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE); @@ -801,6 +807,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, /* unmap the stencil buffer */ screen->surface_unmap(screen, ps); + pipe_surface_reference(&ps, NULL); } @@ -874,7 +881,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, { struct st_renderbuffer *rbDraw = st_renderbuffer(ctx->DrawBuffer->_StencilBuffer); struct pipe_screen *screen = ctx->st->pipe->screen; - struct pipe_surface *psDraw = rbDraw->surface; + struct pipe_surface *psDraw; ubyte *drawMap; ubyte *buffer; int i; @@ -889,6 +896,9 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, st_read_stencil_pixels(ctx, srcx, srcy, width, height, GL_UNSIGNED_BYTE, &ctx->DefaultPacking, buffer); + psDraw = screen->get_tex_surface(screen, rbDraw->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_WRITE); + /* map the stencil buffer */ drawMap = screen->surface_map(screen, psDraw, PIPE_BUFFER_USAGE_CPU_WRITE); @@ -931,6 +941,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, /* unmap the stencil buffer */ screen->surface_unmap(screen, psDraw); + pipe_surface_reference(&psDraw, NULL); } @@ -945,7 +956,6 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, struct st_renderbuffer *rbRead; struct st_vertex_program *stvp; struct st_fragment_program *stfp; - struct pipe_surface *psRead; struct pipe_surface *psTex; struct pipe_texture *pt; GLfloat *color; @@ -976,8 +986,12 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, stvp = st_make_passthrough_vertex_shader(ctx->st, GL_TRUE); } +#if 0 psRead = rbRead->surface; srcFormat = psRead->format; +#else + srcFormat = rbRead->texture->format; +#endif if (screen->is_format_supported(screen, srcFormat, PIPE_TEXTURE)) { texFormat = srcFormat; @@ -1005,18 +1019,26 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, } if (srcFormat == texFormat) { + /* copy source framebuffer surface into mipmap/texture */ + struct pipe_surface *psRead = screen->get_tex_surface(screen, + rbRead->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_READ); psTex = screen->get_tex_surface(screen, pt, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE ); - - /* copy source framebuffer surface into mipmap/texture */ pipe->surface_copy(pipe, FALSE, psTex, /* dest */ 0, 0, /* destx/y */ psRead, srcx, srcy, width, height); + pipe_surface_reference(&psRead, NULL); } else { + /* CPU-based fallback/conversion */ + struct pipe_surface *psRead = screen->get_tex_surface(screen, + rbRead->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_READ); + psTex = screen->get_tex_surface(screen, pt, 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE ); @@ -1036,6 +1058,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, pipe_put_tile_z(pipe, psTex, 0, 0, width, height, buf); free(buf); } + pipe_surface_reference(&psRead, NULL); } pipe_surface_reference(&psTex, NULL); diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index e0578f0b4d..747d4905e6 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -95,7 +95,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); - struct pipe_texture template, *texture; + struct pipe_texture template; unsigned surface_usage; /* Free the old surface (and texture if we hold the last @@ -136,12 +136,14 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, /* Probably need dedicated flags for surface usage too: */ surface_usage = (PIPE_BUFFER_USAGE_GPU_READ | - PIPE_BUFFER_USAGE_GPU_WRITE | + PIPE_BUFFER_USAGE_GPU_WRITE); +#if 0 PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE); +#endif - texture = pipe->screen->texture_create( pipe->screen, - &template ); + strb->texture = pipe->screen->texture_create( pipe->screen, + &template ); /* Special path for accum buffers. * @@ -149,7 +151,7 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, * only for now, the surface pixel format doesn't really matter, * only that the buffer is large enough. */ - if (!texture && template.format == DEFAULT_ACCUM_PIPE_FORMAT) + if (!strb->texture && template.format == DEFAULT_ACCUM_PIPE_FORMAT) { /* Actually, just setting this usage value should be sufficient * to tell the driver to go ahead and allocate the buffer, even @@ -159,21 +161,19 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, surface_usage = (PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE); - texture = pipe->screen->texture_create( pipe->screen, - &template ); + strb->texture = pipe->screen->texture_create( pipe->screen, + &template ); } - if (!texture) + if (!strb->texture) return FALSE; strb->surface = pipe->screen->get_tex_surface( pipe->screen, - texture, + strb->texture, 0, 0, 0, surface_usage ); - pipe_texture_reference( &texture, NULL ); - assert(strb->surface->buffer); assert(strb->surface->format); assert(strb->surface->cpp); @@ -195,6 +195,7 @@ st_renderbuffer_delete(struct gl_renderbuffer *rb) struct st_renderbuffer *strb = st_renderbuffer(rb); ASSERT(strb); pipe_surface_reference(&strb->surface, NULL); + pipe_texture_reference(&strb->texture, NULL); free(strb); } @@ -380,6 +381,8 @@ st_render_texture(GLcontext *ctx, rb->Width = pt->width[att->TextureLevel]; rb->Height = pt->height[att->TextureLevel]; + pipe_texture_reference( &strb->texture, pt ); + /* the renderbuffer's surface is inside the texture */ strb->surface = screen->get_tex_surface(screen, pt, att->CubeMapFace, diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h index c1aa14f9b2..f9cec91314 100644 --- a/src/mesa/state_tracker/st_cb_fbo.h +++ b/src/mesa/state_tracker/st_cb_fbo.h @@ -41,7 +41,8 @@ struct st_renderbuffer { struct gl_renderbuffer Base; - struct pipe_surface *surface; + struct pipe_texture *texture; + struct pipe_surface *surface; /* temporary view into texture */ enum pipe_format format; /** preferred format, or PIPE_FORMAT_NONE */ }; diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index e242195e7a..0b2b9d544d 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -63,10 +63,14 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, struct gl_framebuffer *fb = ctx->ReadBuffer; struct pipe_screen *screen = ctx->st->pipe->screen; struct st_renderbuffer *strb = st_renderbuffer(fb->_StencilBuffer); - struct pipe_surface *ps = strb->surface; + struct pipe_surface *ps; ubyte *stmap; GLint j; + /* Create a CPU-READ surface/view into the renderbuffer's texture */ + ps = screen->get_tex_surface(screen, strb->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_READ); + /* map the stencil buffer */ stmap = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ); @@ -126,6 +130,7 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, /* unmap the stencil buffer */ screen->surface_unmap(screen, ps); + pipe_surface_reference(&ps, NULL); } @@ -169,12 +174,14 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLvoid *dest) { struct pipe_context *pipe = ctx->st->pipe; + struct pipe_screen *screen = pipe->screen; GLfloat temp[MAX_WIDTH][4]; const GLbitfield transferOps = ctx->_ImageTransferState; GLint i, yStep, dfStride; GLfloat *df; struct st_renderbuffer *strb; struct gl_pixelstore_attrib clippedPacking = *pack; + struct pipe_surface *surf; /* XXX convolution not done yet */ assert((transferOps & IMAGE_CONVOLUTION_BIT) == 0); @@ -230,6 +237,10 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, yStep = 1; } + /* Create a CPU-READ surface/view into the renderbuffer's texture */ + surf = screen->get_tex_surface(screen, strb->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_READ); + /* * Copy pixels from pipe_surface to user memory */ @@ -241,15 +252,14 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, const GLint dstStride = _mesa_image_row_stride(&clippedPacking, width, format, type); - if (strb->surface->format == PIPE_FORMAT_S8Z24_UNORM || - strb->surface->format == PIPE_FORMAT_X8Z24_UNORM) { + if (surf->format == PIPE_FORMAT_S8Z24_UNORM || + surf->format == PIPE_FORMAT_X8Z24_UNORM) { if (format == GL_DEPTH_COMPONENT) { for (i = 0; i < height; i++) { GLuint ztemp[MAX_WIDTH], j; GLfloat zfloat[MAX_WIDTH]; const double scale = 1.0 / ((1 << 24) - 1); - pipe_get_tile_raw(pipe, strb->surface, x, y, - width, 1, ztemp, 0); + pipe_get_tile_raw(pipe, surf, x, y, width, 1, ztemp, 0); y += yStep; for (j = 0; j < width; j++) { zfloat[j] = (float) (scale * (ztemp[j] & 0xffffff)); @@ -263,18 +273,18 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, /* untested, but simple: */ assert(format == GL_DEPTH_STENCIL_EXT); for (i = 0; i < height; i++) { - pipe_get_tile_raw(pipe, strb->surface, x, y, width, 1, dst, 0); + pipe_get_tile_raw(pipe, surf, x, y, width, 1, dst, 0); y += yStep; dst += dstStride; } } } - else if (strb->surface->format == PIPE_FORMAT_Z16_UNORM) { + else if (surf->format == PIPE_FORMAT_Z16_UNORM) { for (i = 0; i < height; i++) { GLushort ztemp[MAX_WIDTH], j; GLfloat zfloat[MAX_WIDTH]; const double scale = 1.0 / 0xffff; - pipe_get_tile_raw(pipe, strb->surface, x, y, width, 1, ztemp, 0); + pipe_get_tile_raw(pipe, surf, x, y, width, 1, ztemp, 0); y += yStep; for (j = 0; j < width; j++) { zfloat[j] = (float) (scale * ztemp[j]); @@ -284,12 +294,12 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, dst += dstStride; } } - else if (strb->surface->format == PIPE_FORMAT_Z32_UNORM) { + else if (surf->format == PIPE_FORMAT_Z32_UNORM) { for (i = 0; i < height; i++) { GLuint ztemp[MAX_WIDTH], j; GLfloat zfloat[MAX_WIDTH]; const double scale = 1.0 / 0xffffffff; - pipe_get_tile_raw(pipe, strb->surface, x, y, width, 1, ztemp, 0); + pipe_get_tile_raw(pipe, surf, x, y, width, 1, ztemp, 0); y += yStep; for (j = 0; j < width; j++) { zfloat[j] = (float) (scale * ztemp[j]); @@ -303,7 +313,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, /* RGBA format */ /* Do a row at a time to flip image data vertically */ for (i = 0; i < height; i++) { - pipe_get_tile_rgba(pipe, strb->surface, x, y, width, 1, df); + pipe_get_tile_rgba(pipe, surf, x, y, width, 1, df); y += yStep; df += dfStride; if (!dfStride) { @@ -315,6 +325,8 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, } } + pipe_surface_reference(&surf, NULL); + _mesa_unmap_readpix_pbo(ctx, &clippedPacking); } diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index f6f833a0db..828b2340f2 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -306,6 +306,11 @@ guess_and_alloc_texture(struct st_context *st, depth <<= 1; } + if (width == 0 || height == 0 || depth == 0) { + /* no texture needed */ + return; + } + /* Guess a reasonable value for lastLevel. This is probably going * to be wrong fairly often and might mean that we have to look at * resizable buffers, or require that buffers implement lazy @@ -1059,6 +1064,8 @@ fallback_copy_texsubimage(GLcontext *ctx, } src_surf = strb->surface; + src_surf = screen->get_tex_surface(screen, strb->texture, face, level, destZ, + PIPE_BUFFER_USAGE_CPU_READ); dest_surf = screen->get_tex_surface(screen, pt, face, level, destZ, PIPE_BUFFER_USAGE_CPU_WRITE); @@ -1097,6 +1104,7 @@ fallback_copy_texsubimage(GLcontext *ctx, } screen->tex_surface_release(screen, &dest_surf); + screen->tex_surface_release(screen, &src_surf); } @@ -1164,7 +1172,7 @@ do_copy_texsubimage(GLcontext *ctx, stImage->level, destZ, PIPE_BUFFER_USAGE_CPU_WRITE); - if (ctx->_ImageTransferState == 0x0 && + if (0&& ctx->_ImageTransferState == 0x0 && strb->surface->buffer && dest_surface->buffer) { /* do blit-style copy */ -- cgit v1.2.3 From 1a82d9648b3db780e58e4966924157542d148c58 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 7 May 2008 16:44:33 -0600 Subject: gallium: fix some render to texture bugs Before, we were sometimes rendering into a stale texture because st_finalize_texture() would discard the old texture and create a new one. Moved st_update_framebuffer atom after texture validation so that we can create a new renderbuffer surface if the texture changes. Also, split texture validation into two parts: finalize_textures and update_textures. Do finalize_textures first to avoid getting into the situtation where we're doing a pipe->surface_copy() mid-way through state validation. Some debug code still in place, but disabled... --- src/mesa/state_tracker/st_atom.c | 3 +- src/mesa/state_tracker/st_atom.h | 1 + src/mesa/state_tracker/st_atom_framebuffer.c | 60 ++++++++++++++++++++- src/mesa/state_tracker/st_atom_shader.c | 26 ++++++++- src/mesa/state_tracker/st_atom_texture.c | 80 +++++++++++++++++----------- src/mesa/state_tracker/st_cb_fbo.c | 34 +++++++++--- src/mesa/state_tracker/st_cb_fbo.h | 3 ++ src/mesa/state_tracker/st_cb_readpixels.c | 2 + src/mesa/state_tracker/st_cb_texture.c | 1 + src/mesa/state_tracker/st_context.h | 3 ++ src/mesa/state_tracker/st_texture.c | 16 ++++++ 11 files changed, 189 insertions(+), 40 deletions(-) (limited to 'src/mesa/state_tracker/st_cb_fbo.h') diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c index 18063adc79..ecfd117918 100644 --- a/src/mesa/state_tracker/st_atom.c +++ b/src/mesa/state_tracker/st_atom.c @@ -45,10 +45,10 @@ */ static const struct st_tracked_state *atoms[] = { - &st_update_framebuffer, &st_update_depth_stencil_alpha, &st_update_clip, + &st_finalize_textures, &st_update_shader, &st_update_rasterizer, @@ -58,6 +58,7 @@ static const struct st_tracked_state *atoms[] = &st_update_blend, &st_update_sampler, &st_update_texture, + &st_update_framebuffer, &st_update_vs_constants, &st_update_fs_constants, &st_update_pixel_transfer diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h index c6c6eba812..c7cffd85c8 100644 --- a/src/mesa/state_tracker/st_atom.h +++ b/src/mesa/state_tracker/st_atom.h @@ -55,6 +55,7 @@ extern const struct st_tracked_state st_update_scissor; extern const struct st_tracked_state st_update_blend; extern const struct st_tracked_state st_update_sampler; extern const struct st_tracked_state st_update_texture; +extern const struct st_tracked_state st_finalize_textures; extern const struct st_tracked_state st_update_fs_constants; extern const struct st_tracked_state st_update_vs_constants; extern const struct st_tracked_state st_update_pixel_transfer; diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c index 0a6974d8a7..c9a30e44b2 100644 --- a/src/mesa/state_tracker/st_atom_framebuffer.c +++ b/src/mesa/state_tracker/st_atom_framebuffer.c @@ -34,13 +34,60 @@ #include "st_context.h" #include "st_atom.h" #include "st_cb_fbo.h" +#include "st_texture.h" #include "pipe/p_context.h" +#include "pipe/p_inlines.h" #include "cso_cache/cso_context.h" + +/** + * When doing GL render to texture, we have to be sure that finalize_texture() + * didn't yank out the pipe_texture that we earlier created a surface for. + * Check for that here and create a new surface if needed. + */ +static void +update_renderbuffer_surface(struct st_context *st, + struct st_renderbuffer *strb) +{ + struct pipe_screen *screen = st->pipe->screen; + struct pipe_texture *texture = strb->rtt->pt; + int rtt_width = strb->Base.Width; + int rtt_height = strb->Base.Height; + + if (!strb->surface || + strb->surface->texture != texture || + strb->surface->width != rtt_width || + strb->surface->height != rtt_height) { + int level; + /* find matching mipmap level size */ + for (level = 0; level <= texture->last_level; level++) { + if (texture->width[level] == rtt_width && + texture->height[level] == rtt_height) { + + pipe_surface_reference(&strb->surface, NULL); + + strb->surface = screen->get_tex_surface(screen, + texture, + strb->rtt_face, + level, + strb->rtt_slice, + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_GPU_WRITE); +#if 0 + printf("-- alloc new surface %d x %d into tex %p\n", + strb->surface->width, strb->surface->height, + texture); +#endif + break; + } + } + } +} + + /** * Update framebuffer state (color, depth, stencil, etc. buffers) - * XXX someday: separate draw/read buffers. */ static void update_framebuffer_state( struct st_context *st ) @@ -55,6 +102,8 @@ update_framebuffer_state( struct st_context *st ) framebuffer->width = fb->Width; framebuffer->height = fb->Height; + /*printf("------ fb size %d x %d\n", fb->Width, fb->Height);*/ + /* Examine Mesa's ctx->DrawBuffer->_ColorDrawBuffers state * to determine which surfaces to draw to */ @@ -62,6 +111,13 @@ update_framebuffer_state( struct st_context *st ) for (j = 0; j < MAX_DRAW_BUFFERS; j++) { for (i = 0; i < fb->_NumColorDrawBuffers[j]; i++) { strb = st_renderbuffer(fb->_ColorDrawBuffers[j][i]); + + /*printf("--------- framebuffer surface rtt %p\n", strb->rtt);*/ + if (strb->rtt) { + /* rendering to a GL texture, may have to update surface */ + update_renderbuffer_surface(st, strb); + } + assert(strb->surface); framebuffer->cbufs[framebuffer->num_cbufs] = strb->surface; framebuffer->num_cbufs++; @@ -99,7 +155,7 @@ const struct st_tracked_state st_update_framebuffer = { "st_update_framebuffer", /* name */ { /* dirty */ _NEW_BUFFERS, /* mesa */ - 0, /* st */ + ST_NEW_FRAMEBUFFER, /* st */ }, update_framebuffer_state /* update */ }; diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c index 7745591afb..8839ab380f 100644 --- a/src/mesa/state_tracker/st_atom_shader.c +++ b/src/mesa/state_tracker/st_atom_shader.c @@ -44,6 +44,8 @@ #include "pipe/p_context.h" #include "pipe/p_shader_tokens.h" +#include "util/u_simple_shaders.h" + #include "cso_cache/cso_context.h" #include "st_context.h" @@ -252,6 +254,20 @@ st_free_translated_vertex_programs(struct st_context *st, } +static void * +get_passthrough_fs(struct st_context *st) +{ + struct pipe_shader_state shader; + + if (!st->passthrough_fs) { + st->passthrough_fs = + util_make_fragment_passthrough_shader(st->pipe, &shader); + free((void *) shader.tokens); + } + + return st->passthrough_fs; +} + static void update_linkage( struct st_context *st ) @@ -277,7 +293,15 @@ update_linkage( struct st_context *st ) st_reference_fragprog(st, &st->fp, stfp); cso_set_vertex_shader_handle(st->cso_context, stvp->driver_shader); - cso_set_fragment_shader_handle(st->cso_context, stfp->driver_shader); + + if (st->missing_textures) { + /* use a pass-through frag shader that uses no textures */ + void *fs = get_passthrough_fs(st); + cso_set_fragment_shader_handle(st->cso_context, fs); + } + else { + cso_set_fragment_shader_handle(st->cso_context, stfp->driver_shader); + } st->vertex_result_to_slot = xvp->output_to_slot; } diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index 767654f3d0..1ec671ed48 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -39,34 +39,13 @@ #include "pipe/p_context.h" #include "pipe/p_inlines.h" #include "cso_cache/cso_context.h" -#include "util/u_simple_shaders.h" -static void * -get_passthrough_fs(struct st_context *st) -{ - struct pipe_shader_state shader; - - if (!st->passthrough_fs) { - st->passthrough_fs = - util_make_fragment_passthrough_shader(st->pipe, &shader); - free((void *) shader.tokens); - } - - return st->passthrough_fs; -} - - -/** - * XXX This needs some work yet.... - * Need to "upload" texture images at appropriate times. - */ static void update_textures(struct st_context *st) { struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current; GLuint su; - GLboolean missing_textures = GL_FALSE; st->state.num_textures = 0; @@ -85,13 +64,11 @@ update_textures(struct st_context *st) retval = st_finalize_texture(st->ctx, st->pipe, texObj, &flush); if (!retval) { /* out of mem */ - missing_textures = GL_TRUE; + /* missing texture */ continue; } st->state.num_textures = su + 1; - - stObj->teximage_realloc = TRUE; } pt = st_get_stobj_texture(stObj); @@ -103,12 +80,6 @@ update_textures(struct st_context *st) cso_set_sampler_textures(st->cso_context, st->state.num_textures, st->state.sampler_texture); - - if (missing_textures) { - /* use a pass-through frag shader that uses no textures */ - void *fs = get_passthrough_fs(st); - cso_set_fragment_shader_handle(st->cso_context, fs); - } } @@ -120,3 +91,52 @@ const struct st_tracked_state st_update_texture = { }, update_textures /* update */ }; + + + + +static void +finalize_textures(struct st_context *st) +{ + struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current; + const GLboolean prev_missing_textures = st->missing_textures; + GLuint su; + + st->missing_textures = GL_FALSE; + + for (su = 0; su < st->ctx->Const.MaxTextureCoordUnits; su++) { + if (fprog->Base.SamplersUsed & (1 << su)) { + const GLuint texUnit = fprog->Base.SamplerUnits[su]; + struct gl_texture_object *texObj + = st->ctx->Texture.Unit[texUnit]._Current; + struct st_texture_object *stObj = st_texture_object(texObj); + + if (texObj) { + GLboolean flush, retval; + + retval = st_finalize_texture(st->ctx, st->pipe, texObj, &flush); + if (!retval) { + /* out of mem */ + st->missing_textures = GL_TRUE; + continue; + } + + stObj->teximage_realloc = TRUE; + } + } + } + + if (prev_missing_textures != st->missing_textures) + st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM; +} + + + +const struct st_tracked_state st_finalize_textures = { + "st_finalize_textures", /* name */ + { /* dirty */ + _NEW_TEXTURE, /* mesa */ + 0, /* st */ + }, + finalize_textures /* update */ +}; diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 747d4905e6..2368c31f4b 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -358,6 +358,10 @@ st_render_texture(GLcontext *ctx, struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; struct pipe_texture *pt; + struct st_texture_object *stObj; + const struct gl_texture_image *texImage = + att->Texture->Image[att->CubeMapFace][att->TextureLevel]; + assert(!att->Renderbuffer); @@ -374,27 +378,42 @@ st_render_texture(GLcontext *ctx, strb = st_renderbuffer(rb); /* get the texture for the texture object */ + stObj = st_texture_object(att->Texture); + + /* point renderbuffer at texobject */ + strb->rtt = stObj; + strb->rtt_level = att->TextureLevel; + strb->rtt_face = att->CubeMapFace; + strb->rtt_slice = att->Zoffset; + + rb->Width = texImage->Width2; + rb->Height = texImage->Height2; + /*printf("***** render to texture level %d: %d x %d\n", att->TextureLevel, rb->Width, rb->Height);*/ + pt = st_get_texobj_texture(att->Texture); assert(pt); - assert(pt->width[att->TextureLevel]); - - rb->Width = pt->width[att->TextureLevel]; - rb->Height = pt->height[att->TextureLevel]; + /*printf("***** pipe texture %d x %d\n", pt->width[0], pt->height[0]);*/ pipe_texture_reference( &strb->texture, pt ); + pipe_surface_reference(&strb->surface, NULL); + +#if 0 /* the renderbuffer's surface is inside the texture */ strb->surface = screen->get_tex_surface(screen, pt, att->CubeMapFace, - att->TextureLevel, + att->TextureLevel /*- att->Texture->BaseLevel*/, att->Zoffset, PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE); + printf("***** surface size: %d x %d\n", strb->surface->width, strb->surface->height); + assert(strb->surface); assert(screen->is_format_supported(screen, strb->surface->format, PIPE_TEXTURE)); assert(screen->is_format_supported(screen, strb->surface->format, PIPE_SURFACE)); init_renderbuffer_bits(strb, pt->format); +#endif /* printf("RENDER TO TEXTURE obj=%p pt=%p surf=%p %d x %d\n", @@ -424,7 +443,10 @@ st_finish_render_texture(GLcontext *ctx, ctx->st->pipe->flush(ctx->st->pipe, PIPE_FLUSH_RENDER_CACHE, NULL); - screen->tex_surface_release( screen, &strb->surface ); + if (strb->surface) + screen->tex_surface_release( screen, &strb->surface ); + + strb->rtt = NULL; /* printf("FINISH RENDER TO TEXTURE surf=%p\n", strb->surface); diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h index f9cec91314..87b0734a0c 100644 --- a/src/mesa/state_tracker/st_cb_fbo.h +++ b/src/mesa/state_tracker/st_cb_fbo.h @@ -44,6 +44,9 @@ struct st_renderbuffer struct pipe_texture *texture; struct pipe_surface *surface; /* temporary view into texture */ enum pipe_format format; /** preferred format, or PIPE_FORMAT_NONE */ + + struct st_texture_object *rtt; /**< GL render to texture's texture */ + int rtt_level, rtt_face, rtt_slice; }; diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 0b2b9d544d..3615fafc0a 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -183,6 +183,8 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, struct gl_pixelstore_attrib clippedPacking = *pack; struct pipe_surface *surf; + assert(ctx->ReadBuffer->Width > 0); + /* XXX convolution not done yet */ assert((transferOps & IMAGE_CONVOLUTION_BIT) == 0); diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 3206215b2e..3468b5f2a1 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -1496,6 +1496,7 @@ st_finalize_texture(GLcontext *ctx, stObj->pt->cpp != cpp || stObj->pt->compressed != firstImage->base.IsCompressed) { pipe_texture_release(&stObj->pt); + ctx->st->dirty.st |= ST_NEW_FRAMEBUFFER; } } diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 1ca779d0a9..69be4ebdd0 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -53,6 +53,7 @@ struct bitmap_cache; #define ST_NEW_MESA 0x1 /* Mesa state has changed */ #define ST_NEW_FRAGMENT_PROGRAM 0x2 #define ST_NEW_VERTEX_PROGRAM 0x4 +#define ST_NEW_FRAMEBUFFER 0x8 struct st_state_flags { @@ -121,6 +122,8 @@ struct st_context struct st_state_flags dirty; + GLboolean missing_textures; + GLfloat polygon_offset_scale; /* ?? */ /** Mapping from VERT_RESULT_x to post-transformed vertex slot */ diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index 2b3742d4e5..d0f56c9717 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -315,6 +315,22 @@ st_texture_image_copy(struct pipe_context *pipe, assert(src->width[srcLevel] == width); assert(src->height[srcLevel] == height); +#if 0 + { + src_surface = screen->get_tex_surface(screen, src, face, srcLevel, i, + PIPE_BUFFER_USAGE_CPU_READ); + ubyte *map = screen->surface_map(screen, src_surface, PIPE_BUFFER_USAGE_CPU_READ); + map += src_surface->width * src_surface->height * 4 / 2; + printf("%s center pixel: %d %d %d %d (pt %p[%d] -> %p[%d])\n", + __FUNCTION__, + map[0], map[1], map[2], map[3], + src, srcLevel, dst, dstLevel); + + screen->surface_unmap(screen, src_surface); + pipe_surface_reference(&src_surface, NULL); + } +#endif + dst_surface = screen->get_tex_surface(screen, dst, face, dstLevel, i, PIPE_BUFFER_USAGE_GPU_WRITE); -- 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_cb_fbo.h') diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 2992e2f3b3..5546796936 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 89de188ada..cfecebdb8c 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 94db319928..3cf2146dce 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 1067d0a8bf..20940c21b4 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 dceb7611f2..0a065541e1 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 1067caf9b3..7245798d0d 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 87b0734a0c..ff56001a4e 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 1b6e68c2a1..1994a1c826 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