From 2e4e34689022ecfcc7dc107427db90cc52a94d63 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 13 May 2009 10:28:00 -0600 Subject: 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(). --- src/mesa/drivers/dri/intel/intel_clear.c | 93 ++++++++++++++++++++---------- src/mesa/drivers/dri/intel/intel_context.c | 3 + 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 aed95c7c561..eb0d890f477 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 a6d8729d8f3..07d53aad23f 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 d798225ddd9..f45e24ca3a1 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; -- cgit v1.2.3