diff options
| author | Brian Paul <brianp@vmware.com> | 2009-05-13 10:28:00 -0600 | 
|---|---|---|
| committer | Brian Paul <brianp@vmware.com> | 2009-05-13 10:28:00 -0600 | 
| commit | 2e4e34689022ecfcc7dc107427db90cc52a94d63 (patch) | |
| tree | ba4dce792b03c7a3e51b7bfb951603064ed91431 | |
| parent | 3e74faa02948624cfbaf1f03854f27e0c9130759 (diff) | |
intel: create a private gl_array_object for intel_clear_tris(), fix bug 21638
gl_array_object encapsulates a set of vertex arrays (see the
GL_APPLE_vertex_array_object extension).
Create a private gl_array_object for drawing the quad for intel_clear_tris()
so we don't have to worry about the user's vertex array state.
This fixes the no-op glClear bug #21638 and removes the need to call
_mesa_PushClientAttrib() and _mesa_PopClientAttrib().
| -rw-r--r-- | src/mesa/drivers/dri/intel/intel_clear.c | 93 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/intel/intel_context.c | 3 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/intel/intel_context.h | 8 | 
3 files changed, 75 insertions, 29 deletions
| diff --git a/src/mesa/drivers/dri/intel/intel_clear.c b/src/mesa/drivers/dri/intel/intel_clear.c index aed95c7c56..eb0d890f47 100644 --- a/src/mesa/drivers/dri/intel/intel_clear.c +++ b/src/mesa/drivers/dri/intel/intel_clear.c @@ -30,6 +30,7 @@  #include "main/enums.h"  #include "main/image.h"  #include "main/mtypes.h" +#include "main/arrayobj.h"  #include "main/attrib.h"  #include "main/blend.h"  #include "main/bufferobj.h" @@ -66,6 +67,45 @@  			      BUFFER_BIT_COLOR6 |			\  			      BUFFER_BIT_COLOR7) + +/** + * Per-context one-time init of things for intl_clear_tris(). + * Basically set up a private array object for vertex/color arrays. + */ +static void +init_clear(GLcontext *ctx) +{ +   struct intel_context *intel = intel_context(ctx); +   struct gl_array_object *arraySave = NULL; +   const GLuint arrayBuffer = ctx->Array.ArrayBufferObj->Name; +   const GLuint elementBuffer = ctx->Array.ElementArrayBufferObj->Name; + +   /* create new array object */ +   intel->clear.arrayObj = _mesa_new_array_object(ctx, ~0); + +   /* save current array object, bind new one */ +   _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj); +   _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, intel->clear.arrayObj); + +   /* one-time setup of vertex arrays (pos, color) */ +   _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); +   _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); +   _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), intel->clear.color); +   _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), intel->clear.vertices); +   _mesa_Enable(GL_COLOR_ARRAY); +   _mesa_Enable(GL_VERTEX_ARRAY); + +   /* restore original array object */ +   _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave); +   _mesa_reference_array_object(ctx, &arraySave, NULL); + +   /* restore original buffer objects */ +   _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, arrayBuffer); +   _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, elementBuffer); +} + + +  /**   * Perform glClear where mask contains only color, depth, and/or stencil.   * @@ -78,14 +118,16 @@ void  intel_clear_tris(GLcontext *ctx, GLbitfield mask)  {     struct intel_context *intel = intel_context(ctx); -   GLfloat vertices[4][3]; -   GLfloat color[4][4];     GLfloat dst_z;     struct gl_framebuffer *fb = ctx->DrawBuffer;     int i;     GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE;     GLuint saved_shader_program = 0;     unsigned int saved_active_texture; +   struct gl_array_object *arraySave = NULL; + +   if (!intel->clear.arrayObj) +      init_clear(ctx);     assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH |  		    BUFFER_BIT_STENCIL)) == 0); @@ -98,7 +140,6 @@ intel_clear_tris(GLcontext *ctx, GLbitfield mask)  		    GL_STENCIL_BUFFER_BIT |  		    GL_TRANSFORM_BIT |  		    GL_CURRENT_BIT); -   _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);     saved_active_texture = ctx->Texture.CurrentUnit;     /* Disable existing GL state we don't want to apply to a clear. */ @@ -149,18 +190,14 @@ intel_clear_tris(GLcontext *ctx, GLbitfield mask)        }     } -#if FEATURE_ARB_vertex_buffer_object -   _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); -   _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); -#endif +   /* save current array object, bind our private one */ +   _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj); +   _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, intel->clear.arrayObj);     intel_meta_set_passthrough_transform(intel);     for (i = 0; i < 4; i++) { -      color[i][0] = ctx->Color.ClearColor[0]; -      color[i][1] = ctx->Color.ClearColor[1]; -      color[i][2] = ctx->Color.ClearColor[2]; -      color[i][3] = ctx->Color.ClearColor[3]; +      COPY_4FV(intel->clear.color[i], ctx->Color.ClearColor);     }     /* convert clear Z from [0,1] to NDC coord in [-1,1] */ @@ -169,23 +206,18 @@ intel_clear_tris(GLcontext *ctx, GLbitfield mask)     /* Prepare the vertices, which are the same regardless of which buffer we're      * drawing to.      */ -   vertices[0][0] = fb->_Xmin; -   vertices[0][1] = fb->_Ymin; -   vertices[0][2] = dst_z; -   vertices[1][0] = fb->_Xmax; -   vertices[1][1] = fb->_Ymin; -   vertices[1][2] = dst_z; -   vertices[2][0] = fb->_Xmax; -   vertices[2][1] = fb->_Ymax; -   vertices[2][2] = dst_z; -   vertices[3][0] = fb->_Xmin; -   vertices[3][1] = fb->_Ymax; -   vertices[3][2] = dst_z; - -   _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &color); -   _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), &vertices); -   _mesa_Enable(GL_COLOR_ARRAY); -   _mesa_Enable(GL_VERTEX_ARRAY); +   intel->clear.vertices[0][0] = fb->_Xmin; +   intel->clear.vertices[0][1] = fb->_Ymin; +   intel->clear.vertices[0][2] = dst_z; +   intel->clear.vertices[1][0] = fb->_Xmax; +   intel->clear.vertices[1][1] = fb->_Ymin; +   intel->clear.vertices[1][2] = dst_z; +   intel->clear.vertices[2][0] = fb->_Xmax; +   intel->clear.vertices[2][1] = fb->_Ymax; +   intel->clear.vertices[2][2] = dst_z; +   intel->clear.vertices[3][0] = fb->_Xmin; +   intel->clear.vertices[3][1] = fb->_Ymax; +   intel->clear.vertices[3][2] = dst_z;     while (mask != 0) {        GLuint this_mask = 0; @@ -246,8 +278,11 @@ intel_clear_tris(GLcontext *ctx, GLbitfield mask)     if (saved_shader_program)        _mesa_UseProgramObjectARB(saved_shader_program); -   _mesa_PopClientAttrib();     _mesa_PopAttrib(); + +   /* restore current array object */ +   _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave); +   _mesa_reference_array_object(ctx, &arraySave, NULL);  }  static const char *buffer_names[] = { diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index a6d8729d8f..07d53aad23 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -28,6 +28,7 @@  #include "main/glheader.h"  #include "main/context.h" +#include "main/arrayobj.h"  #include "main/extensions.h"  #include "main/framebuffer.h"  #include "main/imports.h" @@ -755,6 +756,8 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv)        INTEL_FIREVERTICES(intel); +      _mesa_delete_array_object(&intel->ctx, intel->clear.arrayObj); +        intel->vtbl.destroy(intel);        release_texture_heaps = (intel->ctx.Shared->RefCount == 1); diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h index d798225ddd..f45e24ca3a 100644 --- a/src/mesa/drivers/dri/intel/intel_context.h +++ b/src/mesa/drivers/dri/intel/intel_context.h @@ -215,6 +215,14 @@ struct intel_context     GLuint ClearColor565;     GLuint ClearColor8888; +   /* info for intel_clear_tris() */ +   struct +   { +      struct gl_array_object *arrayObj; +      GLfloat vertices[4][3]; +      GLfloat color[4][4]; +   } clear; +     /* Offsets of fields within the current vertex:      */     GLuint coloroffset; | 
