From 7843243deedd66b0c94c8874e732ed7e8c6617ff Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 07:58:25 -0600 Subject: st: also check _NEW_PROGRAM flag for vertex shader constant buffers This is a follow-on to commit c1a3b852807fb160f0cd246c1364b7336b4b947e. Note that (at this time) wherever _NEW_PROGRAM_CONSTANTS is set we're still setting _NEW_PROGRAM so this won't really make any difference (for now). --- src/mesa/state_tracker/st_atom_constbuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c index 77ecd0719e..3ba7b26928 100644 --- a/src/mesa/state_tracker/st_atom_constbuf.c +++ b/src/mesa/state_tracker/st_atom_constbuf.c @@ -105,7 +105,7 @@ static void update_vs_constants(struct st_context *st ) const struct st_tracked_state st_update_vs_constants = { "st_update_vs_constants", /* name */ { /* dirty */ - _NEW_PROGRAM_CONSTANTS, + (_NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS), /* mesa */ ST_NEW_VERTEX_PROGRAM, /* st */ }, update_vs_constants /* update */ -- cgit v1.2.3 From 984f2bb629bb742c6d11d4c8434a2cb32a5b8b75 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 15:10:36 -0600 Subject: st: comments, license, copyright --- src/mesa/state_tracker/st_inlines.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_inlines.h b/src/mesa/state_tracker/st_inlines.h index 0322d5dfa6..a41cfeb96f 100644 --- a/src/mesa/state_tracker/st_inlines.h +++ b/src/mesa/state_tracker/st_inlines.h @@ -1,3 +1,35 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * 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 VMWARE 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. + * + **************************************************************************/ + +/** + * Functions for checking if buffers/textures are referenced when we need + * to read/write from/to them. Flush when needed. + */ + #ifndef ST_INLINES_H #define ST_INLINES_H -- cgit v1.2.3 From 5ed7764fd6354da8e2be15d6fb724c2d6be9be4a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 27 Apr 2009 14:42:23 +0100 Subject: mesa/st: fix incorrect face, level in compress_with_blit We were incorrectly applying the destination texture face and level when requesting a transfer to the temporary texture, which has only one face and level. This would obviously cause problems uploading to compressed cube and mipmap textures. --- src/mesa/state_tracker/st_cb_texture.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index c3e990e077..aeb75117ec 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -418,7 +418,6 @@ compress_with_blit(GLcontext * ctx, const GLuint dstImageOffsets[1] = {0}; struct st_texture_image *stImage = st_texture_image(texImage); struct pipe_screen *screen = ctx->st->pipe->screen; - const GLuint face = _mesa_tex_target_to_face(target); const struct gl_texture_format *mesa_format; struct pipe_texture templ; struct pipe_texture *src_tex; @@ -467,7 +466,7 @@ compress_with_blit(GLcontext * ctx, /* Put user's tex data into the temporary texture */ tex_xfer = st_cond_flush_get_tex_transfer(st_context(ctx), src_tex, - face, level, 0, + 0, 0, 0, /* face, level are zero */ PIPE_TRANSFER_WRITE, 0, 0, width, height); /* x, y, w, h */ map = screen->transfer_map(screen, tex_xfer); -- cgit v1.2.3 From 3d2bba0d10d59a9c2d6d09c5dc3fabe148d5e0d7 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 28 Apr 2009 14:12:39 +0200 Subject: st: Add an st_get_current() function. Signed-off-by: Thomas Hellstrom --- src/mesa/state_tracker/st_context.c | 6 ++++++ src/mesa/state_tracker/st_public.h | 2 ++ 2 files changed, 8 insertions(+) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index b27274725f..92a630eff9 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -279,6 +279,12 @@ void st_make_current(struct st_context *st, } } +struct st_context *st_get_current(void) +{ + GET_CURRENT_CONTEXT(ctx); + + return (ctx == NULL) ? NULL : ctx->st; +} void st_copy_context_state(struct st_context *dst, struct st_context *src, diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h index 030314372f..290b8a974e 100644 --- a/src/mesa/state_tracker/st_public.h +++ b/src/mesa/state_tracker/st_public.h @@ -95,6 +95,8 @@ void st_make_current(struct st_context *st, struct st_framebuffer *draw, struct st_framebuffer *read); +struct st_context *st_get_current(void); + void st_flush( struct st_context *st, uint pipeFlushFlags, struct pipe_fence_handle **fence ); void st_finish( struct st_context *st ); -- cgit v1.2.3 From afd16512bc354cf1a7220cb9bf3ce445503c7af4 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 27 Apr 2009 18:56:26 +0100 Subject: mesa/st: workaround for crashes in st_copy_texsubimage Proper fix for this hasn't been identified, but avoid crashing. --- src/mesa/state_tracker/st_cb_texture.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index aeb75117ec..b7b791d9a4 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -51,6 +51,7 @@ #include "state_tracker/st_texture.h" #include "state_tracker/st_gen_mipmap.h" #include "state_tracker/st_inlines.h" +#include "state_tracker/st_atom.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" @@ -1317,6 +1318,10 @@ st_copy_texsubimage(GLcontext *ctx, /* any rendering in progress must complete before we grab the fb image */ st_finish(ctx->st); + /* make sure finalize_textures has been called? + */ + if (0) st_validate_state(ctx->st); + /* determine if copying depth or color data */ if (texBaseFormat == GL_DEPTH_COMPONENT || texBaseFormat == GL_DEPTH24_STENCIL8) { @@ -1330,6 +1335,11 @@ st_copy_texsubimage(GLcontext *ctx, strb = st_renderbuffer(fb->_ColorReadBuffer); } + if (!strb || !strb->surface || !stImage->pt) { + debug_printf("%s: null strb or stImage\n", __FUNCTION__); + return; + } + assert(strb); assert(strb->surface); assert(stImage->pt); -- cgit v1.2.3 From afc0c59dbd7f89d914763fd78701461f22c00450 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 27 Apr 2009 15:33:44 +0100 Subject: mesa/st: translate VERT_ATTRIB_GENERIC8..15 in st_translate_vertex_program It seems quake4 can hit these attributes sometimes. --- src/mesa/state_tracker/st_program.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 2795570cf1..6ec633c0b4 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -169,6 +169,14 @@ st_translate_vertex_program(struct st_context *st, case VERT_ATTRIB_GENERIC5: case VERT_ATTRIB_GENERIC6: case VERT_ATTRIB_GENERIC7: + case VERT_ATTRIB_GENERIC8: + case VERT_ATTRIB_GENERIC9: + case VERT_ATTRIB_GENERIC10: + case VERT_ATTRIB_GENERIC11: + case VERT_ATTRIB_GENERIC12: + case VERT_ATTRIB_GENERIC13: + case VERT_ATTRIB_GENERIC14: + case VERT_ATTRIB_GENERIC15: assert(attr < VERT_ATTRIB_MAX); vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; vs_input_semantic_index[slot] = num_generic++; -- cgit v1.2.3 From 106f2b031cbb83a54fa2949cb07357ecea68b92a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 28 Apr 2009 14:51:11 +0100 Subject: mesa/st: remove duplicate offset calculation --- src/mesa/state_tracker/st_atom_rasterizer.c | 17 +---------------- src/mesa/state_tracker/st_context.h | 2 -- 2 files changed, 1 insertion(+), 18 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c index 61687fbc3e..4e70510c0c 100644 --- a/src/mesa/state_tracker/st_atom_rasterizer.c +++ b/src/mesa/state_tracker/st_atom_rasterizer.c @@ -180,22 +180,7 @@ static void update_raster_state( struct st_context *st ) if (ctx->Polygon.StippleFlag) raster->poly_stipple_enable = 1; - - - /* _NEW_BUFFERS, _NEW_POLYGON - */ - if (raster->fill_cw != PIPE_POLYGON_MODE_FILL || - raster->fill_ccw != PIPE_POLYGON_MODE_FILL) - { - GLfloat mrd = (ctx->DrawBuffer ? - ctx->DrawBuffer->_MRD : - 1.0f); - - raster->offset_units = ctx->Polygon.OffsetFactor * mrd; - raster->offset_scale = (ctx->Polygon.OffsetUnits * mrd * - st->polygon_offset_scale); - } - + /* _NEW_POINT */ raster->point_size = ctx->Point.Size; diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index f840579a40..6ffed56d9a 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -120,8 +120,6 @@ struct st_context GLboolean missing_textures; - GLfloat polygon_offset_scale; /* ?? */ - /** Mapping from VERT_RESULT_x to post-transformed vertex slot */ const GLuint *vertex_result_to_slot; -- cgit v1.2.3 From 801a33ae44355b89cebed47e9e48e39545522f6e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 28 Apr 2009 17:50:19 +0100 Subject: mesa/st: protect internal flushes with FLUSH_CURRENT Already doing this for driver.flush() --- src/mesa/state_tracker/st_cb_flush.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c index 7d7d3823c9..fbaffd154f 100644 --- a/src/mesa/state_tracker/st_cb_flush.c +++ b/src/mesa/state_tracker/st_cb_flush.c @@ -82,7 +82,7 @@ display_front_buffer(struct st_context *st) void st_flush( struct st_context *st, uint pipeFlushFlags, struct pipe_fence_handle **fence ) { - FLUSH_VERTICES(st->ctx, 0); + FLUSH_CURRENT(st->ctx, 0); /* Release any vertex buffers that might potentially be accessed in * successive frames: -- cgit v1.2.3 From cd6734288ddc15a778def9578e128184b3f6bdea Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 10:15:21 -0600 Subject: st: when double buffered, only create front color buffer on demand Before we always created the front color buffer, even if was never used. This can save some memory. --- src/mesa/state_tracker/st_cb_fbo.c | 101 ++++++++++++++++++++++++++++++++ src/mesa/state_tracker/st_framebuffer.c | 16 ++--- 2 files changed, 109 insertions(+), 8 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 1590f275e2..0b88d9bf7e 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -452,6 +452,104 @@ st_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) } +/** + * Check if we're drawing into, or read from, a front color buffer. If the + * front buffer is missing, create it now. + * + * The back color buffer must exist since we'll use its format/samples info + * for creating the front buffer. + * + * \param frontIndex either BUFFER_FRONT_LEFT or BUFFER_FRONT_RIGHT + * \param backIndex either BUFFER_BACK_LEFT or BUFFER_BACK_RIGHT + */ +static void +check_create_front_buffer(GLcontext *ctx, struct gl_framebuffer *fb, + gl_buffer_index frontIndex, + gl_buffer_index backIndex) +{ + if (fb->Attachment[frontIndex].Renderbuffer == NULL) { + GLboolean create = GL_FALSE; + + /* check if drawing to or reading from front buffer */ + if (fb->_ColorReadBufferIndex == frontIndex) { + create = GL_TRUE; + } + else { + GLuint b; + for (b = 0; b < fb->_NumColorDrawBuffers; b++) { + if (fb->_ColorDrawBufferIndexes[b] == frontIndex) { + create = GL_TRUE; + break; + } + } + } + + if (create) { + struct st_renderbuffer *back; + struct gl_renderbuffer *front; + enum pipe_format colorFormat; + uint samples; + + if (0) + _mesa_debug(ctx, "Allocate new front buffer"); + + /* get back renderbuffer info */ + back = st_renderbuffer(fb->Attachment[backIndex].Renderbuffer); + colorFormat = back->format; + samples = back->Base.NumSamples; + + /* create front renderbuffer */ + front = st_new_renderbuffer_fb(colorFormat, samples); + _mesa_add_renderbuffer(fb, frontIndex, front); + + /* alloc texture/surface for new front buffer */ + front->AllocStorage(ctx, front, front->InternalFormat, + fb->Width, fb->Height); + } + } +} + + +/** + * If front left/right color buffers are missing, create them now. + */ +static void +check_create_front_buffers(GLcontext *ctx, struct gl_framebuffer *fb) +{ + /* check if we need to create the front left buffer now */ + check_create_front_buffer(ctx, fb, BUFFER_FRONT_LEFT, BUFFER_BACK_LEFT); + + if (fb->Visual.stereoMode) { + check_create_front_buffer(ctx, fb, BUFFER_FRONT_RIGHT, BUFFER_BACK_RIGHT); + } + + st_invalidate_state(ctx, _NEW_BUFFERS); +} + + +/** + * Called via glDrawBuffer. + */ +static void +st_DrawBuffers(GLcontext *ctx, GLsizei count, const GLenum *buffers) +{ + (void) count; + (void) buffers; + check_create_front_buffers(ctx, ctx->DrawBuffer); +} + + +/** + * Called via glReadBuffer. + */ +static void +st_ReadBuffer(GLcontext *ctx, GLenum buffer) +{ + (void) buffer; + check_create_front_buffers(ctx, ctx->ReadBuffer); +} + + void st_init_fbo_functions(struct dd_function_table *functions) { functions->NewFramebuffer = st_new_framebuffer; @@ -464,4 +562,7 @@ void st_init_fbo_functions(struct dd_function_table *functions) /* no longer needed by core Mesa, drivers handle resizes... functions->ResizeBuffers = st_resize_buffers; */ + + functions->DrawBuffers = st_DrawBuffers; + functions->ReadBuffer = st_ReadBuffer; } diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index daaad65cca..6ad64739bd 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -58,19 +58,19 @@ st_create_framebuffer( const __GLcontextModes *visual, _mesa_initialize_framebuffer(&stfb->Base, visual); - { - /* fake frontbuffer */ - /* XXX allocation should only happen in the unusual case - it's actually needed */ + if (visual->doubleBufferMode) { struct gl_renderbuffer *rb = st_new_renderbuffer_fb(colorFormat, samples); - _mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb); } - - if (visual->doubleBufferMode) { + else { + /* Only allocate front buffer right now if we're single buffered. + * If double-buffered, allocate front buffer on demand later. + * See check_create_front_buffers(). + */ struct gl_renderbuffer *rb = st_new_renderbuffer_fb(colorFormat, samples); - _mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb); } if (depthFormat == stencilFormat && depthFormat != PIPE_FORMAT_NONE) { -- cgit v1.2.3 From 3534539557350f4a63c6e8b3a48fbc8cacffe199 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 10:50:04 -0600 Subject: set: new st_swapbuffers() which does a true front/back buffer swap The pointers to the front/back renderbuffers are exchanged. This new function isn't actually used yet... --- src/mesa/state_tracker/st_framebuffer.c | 79 +++++++++++++++++++++++++++++++++ src/mesa/state_tracker/st_public.h | 4 ++ 2 files changed, 83 insertions(+) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 6ad64739bd..07ccaa6aab 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -293,6 +293,85 @@ st_notify_swapbuffers(struct st_framebuffer *stfb) } +/** + * Swap the front/back color buffers. Exchange the front/back pointers + * and update some derived state. + * No need to call st_notify_swapbuffers() first. + * This is effectively a no-op for single-buffered framebuffers. + * \param front_left returns pointer to front-left renderbuffer after swap + * \param front_right returns pointer to front-right renderbuffer after swap + */ +void +st_swapbuffers(struct st_framebuffer *stfb, + struct pipe_surface **front_left, + struct pipe_surface **front_right) +{ + struct gl_framebuffer *fb = &stfb->Base; + + GET_CURRENT_CONTEXT(ctx); + + if (ctx && ctx->DrawBuffer == &stfb->Base) { + st_flush( ctx->st, + PIPE_FLUSH_RENDER_CACHE | + PIPE_FLUSH_SWAPBUFFERS | + PIPE_FLUSH_FRAME, + NULL ); + } + + /* swap left buffers */ + if (fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer && + fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer) { + struct gl_renderbuffer *rbTemp; + rbTemp = fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer = + fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer = rbTemp; + if (front_left) { + struct st_renderbuffer *strb = + st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + *front_left = strb->surface; + } + } + else { + /* no front buffer, display the back buffer */ + if (front_left) { + struct st_renderbuffer *strb = + st_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer); + *front_left = strb->surface; + } + } + + /* swap right buffers (for stereo) */ + if (fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer && + fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer) { + struct gl_renderbuffer *rbTemp; + rbTemp = fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer; + fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer = + fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer; + fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer = rbTemp; + if (front_right) { + struct st_renderbuffer *strb = + st_renderbuffer(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer); + *front_right = strb->surface; + } + } + else { + /* no front right buffer, display back right buffer (if exists) */ + if (front_right) { + struct st_renderbuffer *strb = + st_renderbuffer(fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer); + *front_right = strb ? strb->surface : NULL; + } + } + + /* Update the _ColorDrawBuffers[] array and _ColorReadBuffer pointer */ + _mesa_update_framebuffer(ctx); + + /* Make sure we draw into the new back surface */ + st_invalidate_state(ctx, _NEW_BUFFERS); +} + + void *st_framebuffer_private( struct st_framebuffer *stfb ) { return stfb->Private; diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h index 290b8a974e..174fbc6394 100644 --- a/src/mesa/state_tracker/st_public.h +++ b/src/mesa/state_tracker/st_public.h @@ -103,6 +103,10 @@ void st_finish( struct st_context *st ); void st_notify_swapbuffers(struct st_framebuffer *stfb); +void st_swapbuffers(struct st_framebuffer *stfb, + struct pipe_surface **front_left, + struct pipe_surface **front_right); + int st_set_teximage(struct pipe_texture *pt, int target); /** Redirect rendering into stfb's surface to a texture image */ -- cgit v1.2.3 From b85b315ebbe25efbd118887bdc87a562d4334fcc Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 12:25:42 -0600 Subject: st: added st_renderbuffer::defined flag Indicates whether there's defined image contents, or garbage/don't care. This is set when we draw into a renderbuffer and cleared when we resize/ reallocate a renderbuffer or do a buffer swap (back buffer becomes undefined). We use this to determine whether the front color buffer has been drawn to, and whether to display its contents upon glFlush/Finish(), when the new st_swapbuffers() function is used. --- src/mesa/state_tracker/st_atom_framebuffer.c | 1 + src/mesa/state_tracker/st_cb_fbo.c | 2 ++ src/mesa/state_tracker/st_cb_fbo.h | 1 + src/mesa/state_tracker/st_cb_flush.c | 11 ++++++++++- src/mesa/state_tracker/st_context.h | 3 ++- src/mesa/state_tracker/st_framebuffer.c | 12 ++++++++++++ 6 files changed, 28 insertions(+), 2 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c index df0f0931ea..f23186c73d 100644 --- a/src/mesa/state_tracker/st_atom_framebuffer.c +++ b/src/mesa/state_tracker/st_atom_framebuffer.c @@ -123,6 +123,7 @@ update_framebuffer_state( struct st_context *st ) framebuffer->cbufs[framebuffer->nr_cbufs] = strb->surface; framebuffer->nr_cbufs++; } + strb->defined = GL_TRUE; /* we'll be drawing something */ } } diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 0b88d9bf7e..fe9befaa2c 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -125,6 +125,8 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, strb->Base.Height = height; init_renderbuffer_bits(strb, template.format); + strb->defined = GL_FALSE; /* undefined contents now */ + /* Probably need dedicated flags for surface usage too: */ surface_usage = (PIPE_BUFFER_USAGE_GPU_READ | diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h index 44fa9fe9a4..fd77d0a95b 100644 --- a/src/mesa/state_tracker/st_cb_fbo.h +++ b/src/mesa/state_tracker/st_cb_fbo.h @@ -44,6 +44,7 @@ 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 */ + GLboolean defined; /**< defined contents? */ 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_flush.c b/src/mesa/state_tracker/st_cb_flush.c index fbaffd154f..8ceeeabcd3 100644 --- a/src/mesa/state_tracker/st_cb_flush.c +++ b/src/mesa/state_tracker/st_cb_flush.c @@ -47,10 +47,19 @@ #include "util/u_blit.h" +/** Check if we have a front color buffer and if it's been drawn to. */ static INLINE GLboolean is_front_buffer_dirty(struct st_context *st) { - return st->frontbuffer_status == FRONT_STATUS_DIRTY; + if (st->frontbuffer_status == FRONT_STATUS_DIRTY) { + return GL_TRUE; + } + else { + GLframebuffer *fb = st->ctx->DrawBuffer; + struct st_renderbuffer *strb + = st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + return strb && strb->defined; + } } diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 6ffed56d9a..18adb35e87 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -45,6 +45,7 @@ struct blit_state; struct bitmap_cache; +/** XXX we'd like to get rid of these */ #define FRONT_STATUS_UNDEFINED 0 #define FRONT_STATUS_DIRTY 1 #define FRONT_STATUS_COPY_OF_BACK 2 @@ -111,7 +112,7 @@ struct st_context struct gl_fragment_program *fragment_program; } cb; - GLuint frontbuffer_status; /**< one of FRONT_STATUS_ */ + GLuint frontbuffer_status; /**< one of FRONT_STATUS_ (XXX to be removed) */ char vendor[100]; char renderer[100]; diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 07ccaa6aab..639373fff7 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -331,6 +331,12 @@ st_swapbuffers(struct st_framebuffer *stfb, st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); *front_left = strb->surface; } + /* mark back buffer contents as undefined */ + { + struct st_renderbuffer *back = + st_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer); + back->defined = GL_FALSE; + } } else { /* no front buffer, display the back buffer */ @@ -354,6 +360,12 @@ st_swapbuffers(struct st_framebuffer *stfb, st_renderbuffer(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer); *front_right = strb->surface; } + /* mark back buffer contents as undefined */ + { + struct st_renderbuffer *back = + st_renderbuffer(fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer); + back->defined = GL_FALSE; + } } else { /* no front right buffer, display back right buffer (if exists) */ -- cgit v1.2.3 From 3f52a853f795d7432b181de81da6f0c4cf1cc202 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 12:48:46 -0600 Subject: st: when creating an on-demand front color buffer, init to back buffer image When we create a new front color buffer (user called glDrawBuffer(GL_FRONT)) initialize it to the contents of the back buffer. Any previous call to SwapBuffers() would have done that in effect, so make it reality. --- src/mesa/state_tracker/st_cb_fbo.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index fe9befaa2c..9ae4208a18 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -454,6 +454,31 @@ st_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) } +/** + * Copy back color buffer to front color buffer. + */ +static void +copy_back_to_front(struct st_context *st, + struct gl_framebuffer *fb, + gl_buffer_index frontIndex, + gl_buffer_index backIndex) + +{ + struct st_framebuffer *stfb = (struct st_framebuffer *) fb; + struct pipe_surface *surf_front, *surf_back; + + (void) st_get_framebuffer_surface(stfb, frontIndex, &surf_front); + (void) st_get_framebuffer_surface(stfb, backIndex, &surf_back); + + if (surf_front && surf_back) { + st->pipe->surface_copy(st->pipe, + surf_front, 0, 0, /* dest */ + surf_back, 0, 0, /* src */ + fb->Width, fb->Height); + } +} + + /** * Check if we're drawing into, or read from, a front color buffer. If the * front buffer is missing, create it now. @@ -493,7 +518,7 @@ check_create_front_buffer(GLcontext *ctx, struct gl_framebuffer *fb, uint samples; if (0) - _mesa_debug(ctx, "Allocate new front buffer"); + _mesa_debug(ctx, "Allocate new front buffer\n"); /* get back renderbuffer info */ back = st_renderbuffer(fb->Attachment[backIndex].Renderbuffer); @@ -507,6 +532,11 @@ check_create_front_buffer(GLcontext *ctx, struct gl_framebuffer *fb, /* alloc texture/surface for new front buffer */ front->AllocStorage(ctx, front, front->InternalFormat, fb->Width, fb->Height); + + /* initialize the front color buffer contents by copying + * the back buffer. + */ + copy_back_to_front(ctx->st, fb, frontIndex, backIndex); } } } -- cgit v1.2.3 From 602833b107cdf3d70117dbd0970c7d574fb55f3b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 16:44:04 -0600 Subject: st: if st_swapbuffers() is called for single-buffered visual don't crash Furthermore, return pointer(s) to the front color buffer(s). --- src/mesa/state_tracker/st_framebuffer.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 639373fff7..ef800291cc 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -297,7 +297,10 @@ st_notify_swapbuffers(struct st_framebuffer *stfb) * Swap the front/back color buffers. Exchange the front/back pointers * and update some derived state. * No need to call st_notify_swapbuffers() first. - * This is effectively a no-op for single-buffered framebuffers. + * + * For a single-buffered framebuffer, no swap occurs, but we still return + * the pointer(s) to the front color buffer(s). + * * \param front_left returns pointer to front-left renderbuffer after swap * \param front_right returns pointer to front-right renderbuffer after swap */ @@ -318,6 +321,21 @@ st_swapbuffers(struct st_framebuffer *stfb, NULL ); } + if (!fb->Visual.doubleBufferMode) { + /* single buffer mode - return pointers to front surfaces */ + if (front_left) { + struct st_renderbuffer *strb = + st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + *front_left = strb->surface; + } + if (front_right) { + struct st_renderbuffer *strb = + st_renderbuffer(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer); + *front_right = strb ? strb->surface : NULL; + } + return; + } + /* swap left buffers */ if (fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer && fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer) { -- cgit v1.2.3 From 0a56a4968786bd93d9117af2a0a3bda13ea71c4d Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 18:17:34 -0600 Subject: st: create renderbuffer's pipe_surface in st_render_texture() Previously we created the pipe_surface during framebuffer validation. But if we did a glCopyTex[Sub]Image() before anything else we wouldn't yet have the surface. This fixes that. --- src/mesa/state_tracker/st_cb_fbo.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 1590f275e2..e003b6db5c 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -343,6 +343,7 @@ st_render_texture(GLcontext *ctx, struct gl_framebuffer *fb, struct gl_renderbuffer_attachment *att) { + struct pipe_screen *screen = ctx->st->pipe->screen; struct st_renderbuffer *strb; struct gl_renderbuffer *rb; struct pipe_texture *pt = st_get_texobj_texture(att->Texture); @@ -365,6 +366,8 @@ st_render_texture(GLcontext *ctx, rb->AllocStorage = NULL; /* should not get called */ strb = st_renderbuffer(rb); + assert(strb->Base.RefCount > 0); + /* get the texture for the texture object */ stObj = st_texture_object(att->Texture); @@ -384,7 +387,14 @@ st_render_texture(GLcontext *ctx, pipe_surface_reference(&strb->surface, NULL); - /* the new surface will be created during framebuffer validation */ + /* new surface for rendering into the texture */ + strb->surface = screen->get_tex_surface(screen, + strb->texture, + strb->rtt_face, + strb->rtt_level, + strb->rtt_slice, + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_GPU_WRITE); init_renderbuffer_bits(strb, pt->format); -- cgit v1.2.3 From 113403ef51e2ec764db061aabf569d6f1a1a3ef0 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 5 May 2009 12:12:28 +0100 Subject: mesa: more complete fix for transform_invarient glitches Add a new flag mvp_with_dp4 in the context, and use that to switch both ffvertex.c and programopt.c vertex transformation code to either DP4 or MUL/MAD implementations. --- src/mesa/main/context.c | 13 ++++ src/mesa/main/context.h | 4 ++ src/mesa/main/ffvertex_prog.c | 16 +++-- src/mesa/main/mtypes.h | 6 ++ src/mesa/shader/programopt.c | 119 +++++++++++++++++++++++++++++++++++- src/mesa/state_tracker/st_context.c | 6 ++ 6 files changed, 153 insertions(+), 11 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 016284de9a..d780f91f04 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1522,4 +1522,17 @@ _mesa_Flush(void) } +/** + * Set mvp_with_dp4 flag. If a driver has a preference for DP4 over + * MUL/MAD, or vice versa, call this function to register that. + * Otherwise we default to MUL/MAD. + */ +void +_mesa_set_mvp_with_dp4( GLcontext *ctx, + GLboolean flag ) +{ + ctx->mvp_with_dp4 = flag; +} + + /*@}*/ diff --git a/src/mesa/main/context.h b/src/mesa/main/context.h index ecc1cec779..5b57d88029 100644 --- a/src/mesa/main/context.h +++ b/src/mesa/main/context.h @@ -151,6 +151,10 @@ extern struct _glapi_table * _mesa_get_dispatch(GLcontext *ctx); +void +_mesa_set_mvp_with_dp4( GLcontext *ctx, + GLboolean flag ); + /** \name Miscellaneous */ /*@{*/ diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c index 82e1c4af66..43325b1352 100644 --- a/src/mesa/main/ffvertex_prog.c +++ b/src/mesa/main/ffvertex_prog.c @@ -315,12 +315,6 @@ static void make_state_key( GLcontext *ctx, struct state_key *key ) */ #define DISASSEM 0 -/* Should be tunable by the driver - do we want to do matrix - * multiplications with DP4's or with MUL/MAD's? SSE works better - * with the latter, drivers may differ. - */ -#define PREFER_DP4 1 - /* Use uregs to represent registers internally, translate to Mesa's * expected formats on emit. @@ -348,6 +342,7 @@ struct tnl_program { const struct state_key *state; struct gl_vertex_program *program; GLint max_inst; /** number of instructions allocated for program */ + GLboolean mvp_with_dp4; GLuint temp_in_use; GLuint temp_reserved; @@ -775,7 +770,7 @@ static struct ureg get_eye_position( struct tnl_program *p ) p->eye_position = reserve_temp(p); - if (PREFER_DP4) { + if (p->mvp_with_dp4) { register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3, 0, modelview ); @@ -881,7 +876,7 @@ static void build_hpos( struct tnl_program *p ) struct ureg hpos = register_output( p, VERT_RESULT_HPOS ); struct ureg mvp[4]; - if (PREFER_DP4) { + if (p->mvp_with_dp4) { register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3, 0, mvp ); emit_matrix_transform_vec4( p, hpos, mvp, pos ); @@ -1574,7 +1569,7 @@ static void build_texture_transform( struct tnl_program *p ) struct ureg in = (!is_undef(out_texgen) ? out_texgen : register_input(p, VERT_ATTRIB_TEX0+i)); - if (PREFER_DP4) { + if (p->mvp_with_dp4) { register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3, 0, texmat ); emit_matrix_transform_vec4( p, out, texmat, in ); @@ -1708,6 +1703,7 @@ static void build_tnl_program( struct tnl_program *p ) static void create_new_program( const struct state_key *key, struct gl_vertex_program *program, + GLboolean mvp_with_dp4, GLuint max_temps) { struct tnl_program p; @@ -1721,6 +1717,7 @@ create_new_program( const struct state_key *key, p.transformed_normal = undef; p.identity = undef; p.temp_in_use = 0; + p.mvp_with_dp4 = mvp_with_dp4; if (max_temps >= sizeof(int) * 8) p.temp_reserved = 0; @@ -1776,6 +1773,7 @@ _mesa_get_fixed_func_vertex_program(GLcontext *ctx) return NULL; create_new_program( &key, prog, + ctx->mvp_with_dp4, ctx->Const.VertexProgram.MaxTemps ); #if 0 diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index cf71077728..587dc80146 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2980,6 +2980,12 @@ struct __GLcontextRec /** software compression/decompression supported or not */ GLboolean Mesa_DXTn; + /** + * Use dp4 (rather than mul/mad) instructions for position + * transformation? + */ + GLboolean mvp_with_dp4; + /** Core tnl module support */ struct gl_tnl_module TnlModule; diff --git a/src/mesa/shader/programopt.c b/src/mesa/shader/programopt.c index ecd98dc85c..f70c75cec8 100644 --- a/src/mesa/shader/programopt.c +++ b/src/mesa/shader/programopt.c @@ -45,8 +45,8 @@ * into a vertex program. * May be used to implement the position_invariant option. */ -void -_mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) +static void +_mesa_insert_mvp_dp4_code(GLcontext *ctx, struct gl_vertex_program *vprog) { struct prog_instruction *newInst; const GLuint origLen = vprog->Base.NumInstructions; @@ -113,6 +113,121 @@ _mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) } +static void +_mesa_insert_mvp_mad_code(GLcontext *ctx, struct gl_vertex_program *vprog) +{ + struct prog_instruction *newInst; + const GLuint origLen = vprog->Base.NumInstructions; + const GLuint newLen = origLen + 4; + GLuint hposTemp; + GLuint i; + + /* + * Setup state references for the modelview/projection matrix. + * XXX we should check if these state vars are already declared. + */ + static const gl_state_index mvpState[4][STATE_LENGTH] = { + { STATE_MVP_MATRIX, 0, 0, 0, STATE_MATRIX_TRANSPOSE }, + { STATE_MVP_MATRIX, 0, 1, 1, STATE_MATRIX_TRANSPOSE }, + { STATE_MVP_MATRIX, 0, 2, 2, STATE_MATRIX_TRANSPOSE }, + { STATE_MVP_MATRIX, 0, 3, 3, STATE_MATRIX_TRANSPOSE }, + }; + GLint mvpRef[4]; + + for (i = 0; i < 4; i++) { + mvpRef[i] = _mesa_add_state_reference(vprog->Base.Parameters, + mvpState[i]); + } + + /* Alloc storage for new instructions */ + newInst = _mesa_alloc_instructions(newLen); + if (!newInst) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, + "glProgramString(inserting position_invariant code)"); + return; + } + + /* TEMP hposTemp; */ + hposTemp = vprog->Base.NumTemporaries++; + + /* + * Generated instructions: + * emit_op2(p, OPCODE_MUL, tmp, 0, swizzle1(src,X), mat[0]); + * emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Y), mat[1], tmp); + * emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Z), mat[2], tmp); + * emit_op3(p, OPCODE_MAD, dest, 0, swizzle1(src,W), mat[3], tmp); + */ + _mesa_init_instructions(newInst, 4); + + newInst[0].Opcode = OPCODE_MUL; + newInst[0].DstReg.File = PROGRAM_TEMPORARY; + newInst[0].DstReg.Index = hposTemp; + newInst[0].DstReg.WriteMask = WRITEMASK_XYZW; + newInst[0].SrcReg[0].File = PROGRAM_INPUT; + newInst[0].SrcReg[0].Index = VERT_ATTRIB_POS; + newInst[0].SrcReg[0].Swizzle = SWIZZLE_XXXX; + newInst[0].SrcReg[1].File = PROGRAM_STATE_VAR; + newInst[0].SrcReg[1].Index = mvpRef[0]; + newInst[0].SrcReg[1].Swizzle = SWIZZLE_NOOP; + + for (i = 1; i <= 2; i++) { + newInst[i].Opcode = OPCODE_MAD; + newInst[i].DstReg.File = PROGRAM_TEMPORARY; + newInst[i].DstReg.Index = hposTemp; + newInst[i].DstReg.WriteMask = WRITEMASK_XYZW; + newInst[i].SrcReg[0].File = PROGRAM_INPUT; + newInst[i].SrcReg[0].Index = VERT_ATTRIB_POS; + newInst[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(i,i,i,i); + newInst[i].SrcReg[1].File = PROGRAM_STATE_VAR; + newInst[i].SrcReg[1].Index = mvpRef[i]; + newInst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP; + newInst[i].SrcReg[2].File = PROGRAM_TEMPORARY; + newInst[i].SrcReg[2].Index = hposTemp; + newInst[1].SrcReg[2].Swizzle = SWIZZLE_NOOP; + } + + newInst[3].Opcode = OPCODE_MAD; + newInst[3].DstReg.File = PROGRAM_OUTPUT; + newInst[3].DstReg.Index = VERT_RESULT_HPOS; + newInst[3].DstReg.WriteMask = WRITEMASK_XYZW; + newInst[3].SrcReg[0].File = PROGRAM_INPUT; + newInst[3].SrcReg[0].Index = VERT_ATTRIB_POS; + newInst[3].SrcReg[0].Swizzle = SWIZZLE_WWWW; + newInst[3].SrcReg[1].File = PROGRAM_STATE_VAR; + newInst[3].SrcReg[1].Index = mvpRef[3]; + newInst[3].SrcReg[1].Swizzle = SWIZZLE_NOOP; + newInst[3].SrcReg[2].File = PROGRAM_TEMPORARY; + newInst[3].SrcReg[2].Index = hposTemp; + newInst[3].SrcReg[2].Swizzle = SWIZZLE_NOOP; + + + /* Append original instructions after new instructions */ + _mesa_copy_instructions (newInst + 4, vprog->Base.Instructions, origLen); + + /* free old instructions */ + _mesa_free_instructions(vprog->Base.Instructions, origLen); + + /* install new instructions */ + vprog->Base.Instructions = newInst; + vprog->Base.NumInstructions = newLen; + vprog->Base.InputsRead |= VERT_BIT_POS; + vprog->Base.OutputsWritten |= (1 << VERT_RESULT_HPOS); +} + + +void +_mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) +{ + if (ctx->mvp_with_dp4) + _mesa_insert_mvp_dp4_code( ctx, vprog ); + else + _mesa_insert_mvp_mad_code( ctx, vprog ); +} + + + + + /** * Append extra instructions onto the given fragment program to implement diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 92a630eff9..2a1f21c51c 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -177,6 +177,12 @@ struct st_context *st_create_context(struct pipe_context *pipe, ctx = _mesa_create_context(visual, shareCtx, &funcs, NULL); + /* XXX: need a capability bit in gallium to query if the pipe + * driver prefers DP4 or MUL/MAD for vertex transformation. + */ + if (debug_get_bool_option("MESA_MVP_DP4", FALSE)) + _mesa_set_mvp_with_dp4( ctx, GL_TRUE ); + return st_create_context_priv(ctx, pipe); } -- cgit v1.2.3 From 01280cff537544299fe0c5f1a282abde8e69b1f3 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 7 May 2009 11:46:08 +0100 Subject: mesa/st: cope with non-ibo index data in st_draw_feedback.c Previously only non-indexed or indicies-in-a-vbo cases were handled in this code. This change adds the missing regular indices-in-memory case. --- src/mesa/state_tracker/st_draw_feedback.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index e533afd051..32502a9cda 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -196,13 +196,10 @@ st_feedback_draw_vbo(GLcontext *ctx, draw_set_vertex_elements(draw, vp->num_inputs, velements); if (ib) { - unsigned indexSize; struct gl_buffer_object *bufobj = ib->obj; - struct st_buffer_object *stobj = st_buffer_object(bufobj); + unsigned indexSize; void *map; - index_buffer_handle = stobj->buffer; - switch (ib->type) { case GL_UNSIGNED_INT: indexSize = 4; @@ -215,9 +212,19 @@ st_feedback_draw_vbo(GLcontext *ctx, return; } - map = pipe_buffer_map(pipe->screen, index_buffer_handle, - PIPE_BUFFER_USAGE_CPU_READ); - draw_set_mapped_element_buffer(draw, indexSize, map); + if (bufobj && bufobj->Name) { + struct st_buffer_object *stobj = st_buffer_object(bufobj); + + index_buffer_handle = stobj->buffer; + + map = pipe_buffer_map(pipe->screen, index_buffer_handle, + PIPE_BUFFER_USAGE_CPU_READ); + + draw_set_mapped_element_buffer(draw, indexSize, map); + } + else { + draw_set_mapped_element_buffer(draw, indexSize, (void *) ib->ptr); + } } else { /* no index/element buffer */ @@ -252,7 +259,7 @@ st_feedback_draw_vbo(GLcontext *ctx, draw_set_mapped_vertex_buffer(draw, i, NULL); } } - if (ib) { + if (index_buffer_handle) { pipe_buffer_unmap(pipe->screen, index_buffer_handle); draw_set_mapped_element_buffer(draw, 0, NULL); } -- cgit v1.2.3 From 6826bad6a75e78729dd472ea26c87787c90ada4c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 7 May 2009 19:27:30 +0100 Subject: mesa/st: remove redundant call to st_finish in CopyTexSubImage Rendering should already have been flushed, any synchronization will be done by the driver or memory manager. --- src/mesa/state_tracker/st_cb_texture.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index b7b791d9a4..98f109fc65 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -1315,9 +1315,6 @@ st_copy_texsubimage(GLcontext *ctx, GLboolean use_fallback = GL_TRUE; GLboolean matching_base_formats; - /* any rendering in progress must complete before we grab the fb image */ - st_finish(ctx->st); - /* make sure finalize_textures has been called? */ if (0) st_validate_state(ctx->st); -- cgit v1.2.3 From d5c2ad8514ce8064d83febf647c9e726788b7924 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 7 May 2009 19:48:06 +0100 Subject: mesa/st: keep surface_copy arguments positive The src/dest x,y, and w,h arguments of the pipe->surface_copy function are unsigned and the drivers aren't expecting negative (or extremly-large unsigned) values as inputs. Trim the requests at the state-tracker level before passing down. --- src/mesa/state_tracker/st_cb_drawpixels.c | 43 ++++++++++++++++++++++++++++--- src/mesa/state_tracker/st_cb_texture.c | 28 ++++++++++++++++++++ 2 files changed, 68 insertions(+), 3 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 08dc7c930e..89725cfe8d 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -910,6 +910,34 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, st_validate_state(st); + if (srcx < 0) { + width -= -srcx; + dstx += -srcx; + srcx = 0; + } + + if (srcy < 0) { + height -= -srcy; + dsty += -srcy; + srcy = 0; + } + + if (dstx < 0) { + width -= -dstx; + srcx += -dstx; + dstx = 0; + } + + if (dsty < 0) { + height -= -dsty; + srcy += -dsty; + dsty = 0; + } + + if (width < 0 || height < 0) + return; + + if (type == GL_STENCIL) { /* can't use texturing to do stencil */ copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty); @@ -951,15 +979,24 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, } } + if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { + srcy = ctx->DrawBuffer->Height - srcy - height; + + if (srcy < 0) { + height -= -srcy; + srcy = 0; + } + + if (height < 0) + return; + } + pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, texFormat, 0, width, height, 1, PIPE_TEXTURE_USAGE_SAMPLER); if (!pt) return; - if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { - srcy = ctx->DrawBuffer->Height - srcy - height; - } if (srcFormat == texFormat) { /* copy source framebuffer surface into mipmap/texture */ diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 98f109fc65..b182106fd5 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -1337,6 +1337,34 @@ st_copy_texsubimage(GLcontext *ctx, return; } + if (srcX < 0) { + width -= -srcX; + destX += -srcX; + srcX = 0; + } + + if (srcY < 0) { + height -= -srcY; + destY += -srcY; + srcY = 0; + } + + if (destX < 0) { + width -= -destX; + srcX += -destX; + destX = 0; + } + + if (destY < 0) { + height -= -destY; + srcY += -destY; + destY = 0; + } + + if (width < 0 || height < 0) + return; + + assert(strb); assert(strb->surface); assert(stImage->pt); -- cgit v1.2.3