diff options
18 files changed, 684 insertions, 871 deletions
| diff --git a/src/mesa/drivers/dri/Makefile.template b/src/mesa/drivers/dri/Makefile.template index bd38e3be47..18dbeba24a 100644 --- a/src/mesa/drivers/dri/Makefile.template +++ b/src/mesa/drivers/dri/Makefile.template @@ -11,7 +11,8 @@ COMMON_GALLIUM_SOURCES = \  COMMON_SOURCES = $(COMMON_GALLIUM_SOURCES) \          ../../common/driverfuncs.c \          ../common/texmem.c \ -        ../common/drirenderbuffer.c +        ../common/drirenderbuffer.c \ +	../common/dri_metaops.c  ifeq ($(WINDOW_SYSTEM),dri)  WINOBJ= diff --git a/src/mesa/drivers/dri/common/dri_metaops.c b/src/mesa/drivers/dri/common/dri_metaops.c new file mode 100644 index 0000000000..fe183c2e87 --- /dev/null +++ b/src/mesa/drivers/dri/common/dri_metaops.c @@ -0,0 +1,541 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009 Intel Corporation. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "main/arrayobj.h" +#include "main/attrib.h" +#include "main/blend.h" +#include "main/bufferobj.h" +#include "main/buffers.h" +#include "main/depth.h" +#include "main/enable.h" +#include "main/matrix.h" +#include "main/macros.h" +#include "main/polygon.h" +#include "main/shaders.h" +#include "main/stencil.h" +#include "main/texstate.h" +#include "main/varray.h" +#include "main/viewport.h" +#include "shader/arbprogram.h" +#include "shader/program.h" +#include "dri_metaops.h" + +void +meta_set_passthrough_transform(struct dri_metaops *meta) +{ +   GLcontext *ctx = meta->ctx; + +   meta->saved_vp_x = ctx->Viewport.X; +   meta->saved_vp_y = ctx->Viewport.Y; +   meta->saved_vp_width = ctx->Viewport.Width; +   meta->saved_vp_height = ctx->Viewport.Height; +   meta->saved_matrix_mode = ctx->Transform.MatrixMode; + +   meta->internal_viewport_call = GL_TRUE; +   _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height); +   meta->internal_viewport_call = GL_FALSE; + +   _mesa_MatrixMode(GL_PROJECTION); +   _mesa_PushMatrix(); +   _mesa_LoadIdentity(); +   _mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1); + +   _mesa_MatrixMode(GL_MODELVIEW); +   _mesa_PushMatrix(); +   _mesa_LoadIdentity(); +} + +void +meta_restore_transform(struct dri_metaops *meta) +{ +   _mesa_MatrixMode(GL_PROJECTION); +   _mesa_PopMatrix(); +   _mesa_MatrixMode(GL_MODELVIEW); +   _mesa_PopMatrix(); + +   _mesa_MatrixMode(meta->saved_matrix_mode); + +   meta->internal_viewport_call = GL_TRUE; +   _mesa_Viewport(meta->saved_vp_x, meta->saved_vp_y, +		  meta->saved_vp_width, meta->saved_vp_height); +   meta->internal_viewport_call = GL_FALSE; +} + + +/** + * Set up a vertex program to pass through the position and first texcoord + * for pixel path. + */ +void +meta_set_passthrough_vertex_program(struct dri_metaops *meta) +{ +   GLcontext *ctx = meta->ctx; +   static const char *vp = +      "!!ARBvp1.0\n" +      "TEMP vertexClip;\n" +      "DP4 vertexClip.x, state.matrix.mvp.row[0], vertex.position;\n" +      "DP4 vertexClip.y, state.matrix.mvp.row[1], vertex.position;\n" +      "DP4 vertexClip.z, state.matrix.mvp.row[2], vertex.position;\n" +      "DP4 vertexClip.w, state.matrix.mvp.row[3], vertex.position;\n" +      "MOV result.position, vertexClip;\n" +      "MOV result.texcoord[0], vertex.texcoord[0];\n" +      "MOV result.color, vertex.color;\n" +      "END\n"; + +   assert(meta->saved_vp == NULL); + +   _mesa_reference_vertprog(ctx, &meta->saved_vp, +			    ctx->VertexProgram.Current); +   if (meta->passthrough_vp == NULL) { +      GLuint prog_name; +      _mesa_GenPrograms(1, &prog_name); +      _mesa_BindProgram(GL_VERTEX_PROGRAM_ARB, prog_name); +      _mesa_ProgramStringARB(GL_VERTEX_PROGRAM_ARB, +			     GL_PROGRAM_FORMAT_ASCII_ARB, +			     strlen(vp), (const GLubyte *)vp); +      _mesa_reference_vertprog(ctx, &meta->passthrough_vp, +			       ctx->VertexProgram.Current); +      _mesa_DeletePrograms(1, &prog_name); +   } + +   FLUSH_VERTICES(ctx, _NEW_PROGRAM); +   _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, +			    meta->passthrough_vp); +   ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, +			   &meta->passthrough_vp->Base); + +   meta->saved_vp_enable = ctx->VertexProgram.Enabled; +   _mesa_Enable(GL_VERTEX_PROGRAM_ARB); +} + +/** + * Restores the previous vertex program after + * meta_set_passthrough_vertex_program() + */ +void +meta_restore_vertex_program(struct dri_metaops *meta) +{ +   GLcontext *ctx = meta->ctx; + +   FLUSH_VERTICES(ctx, _NEW_PROGRAM); +   _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, +			    meta->saved_vp); +   _mesa_reference_vertprog(ctx, &meta->saved_vp, NULL); +   ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, +			   &ctx->VertexProgram.Current->Base); + +   if (!meta->saved_vp_enable) +      _mesa_Disable(GL_VERTEX_PROGRAM_ARB); +} + +/** + * Binds the given program string to GL_FRAGMENT_PROGRAM_ARB, caching the + * program object. + */ +void +meta_set_fragment_program(struct dri_metaops *meta, +			  struct gl_fragment_program **prog, +			  const char *prog_string) +{ +   GLcontext *ctx = meta->ctx; +   assert(meta->saved_fp == NULL); + +   _mesa_reference_fragprog(ctx, &meta->saved_fp, +			    ctx->FragmentProgram.Current); +   if (*prog == NULL) { +      GLuint prog_name; +      _mesa_GenPrograms(1, &prog_name); +      _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, prog_name); +      _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, +			     GL_PROGRAM_FORMAT_ASCII_ARB, +			     strlen(prog_string), (const GLubyte *)prog_string); +      _mesa_reference_fragprog(ctx, prog, ctx->FragmentProgram.Current); +      /* Note that DeletePrograms unbinds the program on us */ +      _mesa_DeletePrograms(1, &prog_name); +   } + +   FLUSH_VERTICES(ctx, _NEW_PROGRAM); +   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, *prog); +   ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, &((*prog)->Base)); + +   meta->saved_fp_enable = ctx->FragmentProgram.Enabled; +   _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); +} + +/** + * Restores the previous fragment program after + * meta_set_fragment_program() + */ +void +meta_restore_fragment_program(struct dri_metaops *meta) +{ +   GLcontext *ctx = meta->ctx; + +   FLUSH_VERTICES(ctx, _NEW_PROGRAM); +   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, +			    meta->saved_fp); +   _mesa_reference_fragprog(ctx, &meta->saved_fp, NULL); +   ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, +			   &ctx->FragmentProgram.Current->Base); + +   if (!meta->saved_fp_enable) +      _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); +} + +static const float default_texcoords[4][2] = { { 0.0, 0.0 }, +					       { 1.0, 0.0 }, +					       { 1.0, 1.0 }, +					       { 0.0, 1.0 } }; + +void +meta_set_default_texrect(struct dri_metaops *meta) +{ +   GLcontext *ctx = meta->ctx; +   struct gl_client_array *old_texcoord_array; + +   meta->saved_active_texture = ctx->Texture.CurrentUnit; +   if (meta->saved_array_vbo == NULL) { +      _mesa_reference_buffer_object(ctx, &meta->saved_array_vbo, +				    ctx->Array.ArrayBufferObj); +   } + +   old_texcoord_array = &ctx->Array.ArrayObj->TexCoord[0]; +   meta->saved_texcoord_type = old_texcoord_array->Type; +   meta->saved_texcoord_size = old_texcoord_array->Size; +   meta->saved_texcoord_stride = old_texcoord_array->Stride; +   meta->saved_texcoord_enable = old_texcoord_array->Enabled; +   meta->saved_texcoord_ptr = old_texcoord_array->Ptr; +   _mesa_reference_buffer_object(ctx, &meta->saved_texcoord_vbo, +				 old_texcoord_array->BufferObj); + +   _mesa_ClientActiveTextureARB(GL_TEXTURE0); + +   if (meta->texcoord_vbo == NULL) { +      GLuint vbo_name; + +      _mesa_GenBuffersARB(1, &vbo_name); +      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_name); +      _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(default_texcoords), +			  default_texcoords, GL_STATIC_DRAW_ARB); +      _mesa_reference_buffer_object(ctx, &meta->texcoord_vbo, +				    ctx->Array.ArrayBufferObj); +   } else { +      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, +			  meta->texcoord_vbo->Name); +   } +   _mesa_TexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), NULL); + +   _mesa_Enable(GL_TEXTURE_COORD_ARRAY); +} + +void +meta_restore_texcoords(struct dri_metaops *meta) +{ +   GLcontext *ctx = meta->ctx; + +   /* Restore the old TexCoordPointer */ +   if (meta->saved_texcoord_vbo) { +      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, +			  meta->saved_texcoord_vbo->Name); +      _mesa_reference_buffer_object(ctx, &meta->saved_texcoord_vbo, NULL); +   } else { +      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); +   } + +   _mesa_TexCoordPointer(meta->saved_texcoord_size, +			 meta->saved_texcoord_type, +			 meta->saved_texcoord_stride, +			 meta->saved_texcoord_ptr); +   if (!meta->saved_texcoord_enable) +      _mesa_Disable(GL_TEXTURE_COORD_ARRAY); + +   _mesa_ClientActiveTextureARB(GL_TEXTURE0 + +				meta->saved_active_texture); + +   if (meta->saved_array_vbo) { +      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, +			  meta->saved_array_vbo->Name); +      _mesa_reference_buffer_object(ctx, &meta->saved_array_vbo, NULL); +   } else { +      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); +   } +} + + +/** + * Perform glClear where mask contains only color, depth, and/or stencil. + * + * The implementation is based on calling into Mesa to set GL state and + * performing normal triangle rendering.  The intent of this path is to + * have as generic a path as possible, so that any driver could make use of + * it. + */ + +/** + * Per-context one-time init of things for intl_clear_tris(). + * Basically set up a private array object for vertex/color arrays. + */ +static void +meta_init_clear(struct dri_metaops *meta) +{ +   GLcontext *ctx = meta->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 */ +   meta->clear.arrayObj = _mesa_new_array_object(ctx, ~0); + +   /* save current array object, bind new one */ +   _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj); +   ctx->NewState |= _NEW_ARRAY; +   ctx->Array.NewState |= _NEW_ARRAY_ALL; +   _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, meta->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), meta->clear.color); +   _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), meta->clear.vertices); +   _mesa_Enable(GL_COLOR_ARRAY); +   _mesa_Enable(GL_VERTEX_ARRAY); + +   /* restore original array object */ +   ctx->NewState |= _NEW_ARRAY; +   ctx->Array.NewState |= _NEW_ARRAY_ALL; +   _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. + * + * The implementation is based on calling into Mesa to set GL state and + * performing normal triangle rendering.  The intent of this path is to + * have as generic a path as possible, so that any driver could make use of + * it. + */ +void +meta_clear_tris(struct dri_metaops *meta, GLbitfield mask) +{ +   GLcontext *ctx = meta->ctx; +   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 (!meta->clear.arrayObj) +      meta_init_clear(meta); + +   assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH | +		    BUFFER_BIT_STENCIL)) == 0); + +   _mesa_PushAttrib(GL_COLOR_BUFFER_BIT | +		    GL_DEPTH_BUFFER_BIT | +		    GL_ENABLE_BIT | +		    GL_POLYGON_BIT | +		    GL_STENCIL_BUFFER_BIT | +		    GL_TRANSFORM_BIT | +		    GL_CURRENT_BIT | +		    GL_VIEWPORT_BIT); +   saved_active_texture = ctx->Texture.CurrentUnit; + +   /* Disable existing GL state we don't want to apply to a clear. */ +   _mesa_Disable(GL_ALPHA_TEST); +   _mesa_Disable(GL_BLEND); +   _mesa_Disable(GL_CULL_FACE); +   _mesa_Disable(GL_FOG); +   _mesa_Disable(GL_POLYGON_SMOOTH); +   _mesa_Disable(GL_POLYGON_STIPPLE); +   _mesa_Disable(GL_POLYGON_OFFSET_FILL); +   _mesa_Disable(GL_LIGHTING); +   _mesa_Disable(GL_CLIP_PLANE0); +   _mesa_Disable(GL_CLIP_PLANE1); +   _mesa_Disable(GL_CLIP_PLANE2); +   _mesa_Disable(GL_CLIP_PLANE3); +   _mesa_Disable(GL_CLIP_PLANE4); +   _mesa_Disable(GL_CLIP_PLANE5); +   _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL); +   if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) { +      saved_fp_enable = GL_TRUE; +      _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); +   } +   if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) { +      saved_vp_enable = GL_TRUE; +      _mesa_Disable(GL_VERTEX_PROGRAM_ARB); +   } +   if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) { +      saved_shader_program = ctx->Shader.CurrentProgram->Name; +      _mesa_UseProgramObjectARB(0); +   } + +   if (ctx->Texture._EnabledUnits != 0) { +      int i; + +      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { +	 _mesa_ActiveTextureARB(GL_TEXTURE0 + i); +	 _mesa_Disable(GL_TEXTURE_1D); +	 _mesa_Disable(GL_TEXTURE_2D); +	 _mesa_Disable(GL_TEXTURE_3D); +	 if (ctx->Extensions.ARB_texture_cube_map) +	    _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB); +	 if (ctx->Extensions.NV_texture_rectangle) +	    _mesa_Disable(GL_TEXTURE_RECTANGLE_NV); +	 if (ctx->Extensions.MESA_texture_array) { +	    _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT); +	    _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT); +	 } +      } +   } + +   /* save current array object, bind our private one */ +   _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj); +   ctx->NewState |= _NEW_ARRAY; +   ctx->Array.NewState |= _NEW_ARRAY_ALL; +   _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, meta->clear.arrayObj); + +   meta_set_passthrough_transform(meta); + +   for (i = 0; i < 4; i++) { +      COPY_4FV(meta->clear.color[i], ctx->Color.ClearColor); +   } + +   /* convert clear Z from [0,1] to NDC coord in [-1,1] */ +   dst_z = -1.0 + 2.0 * ctx->Depth.Clear; + +   /* The ClearDepth value is unaffected by DepthRange, so do a default +    * mapping. +    */ +   _mesa_DepthRange(0.0, 1.0); + +   /* Prepare the vertices, which are the same regardless of which buffer we're +    * drawing to. +    */ +   meta->clear.vertices[0][0] = fb->_Xmin; +   meta->clear.vertices[0][1] = fb->_Ymin; +   meta->clear.vertices[0][2] = dst_z; +   meta->clear.vertices[1][0] = fb->_Xmax; +   meta->clear.vertices[1][1] = fb->_Ymin; +   meta->clear.vertices[1][2] = dst_z; +   meta->clear.vertices[2][0] = fb->_Xmax; +   meta->clear.vertices[2][1] = fb->_Ymax; +   meta->clear.vertices[2][2] = dst_z; +   meta->clear.vertices[3][0] = fb->_Xmin; +   meta->clear.vertices[3][1] = fb->_Ymax; +   meta->clear.vertices[3][2] = dst_z; + +   while (mask != 0) { +      GLuint this_mask = 0; +      GLuint color_bit; + +      color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS); +      if (color_bit != 0) +	 this_mask |= (1 << (color_bit - 1)); + +      /* Clear depth/stencil in the same pass as color. */ +      this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)); + +      /* Select the current color buffer and use the color write mask if +       * we have one, otherwise don't write any color channels. +       */ +      if (this_mask & BUFFER_BIT_FRONT_LEFT) +	 _mesa_DrawBuffer(GL_FRONT_LEFT); +      else if (this_mask & BUFFER_BIT_BACK_LEFT) +	 _mesa_DrawBuffer(GL_BACK_LEFT); +      else if (color_bit != 0) +	 _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0 + +			  (color_bit - BUFFER_COLOR0 - 1)); +      else +	 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + +      /* Control writing of the depth clear value to depth. */ +      if (this_mask & BUFFER_BIT_DEPTH) { +	 _mesa_DepthFunc(GL_ALWAYS); +	 _mesa_Enable(GL_DEPTH_TEST); +      } else { +	 _mesa_Disable(GL_DEPTH_TEST); +	 _mesa_DepthMask(GL_FALSE); +      } + +      /* Control writing of the stencil clear value to stencil. */ +      if (this_mask & BUFFER_BIT_STENCIL) { +	 _mesa_Enable(GL_STENCIL_TEST); +	 _mesa_StencilOpSeparate(GL_FRONT_AND_BACK, +				 GL_REPLACE, GL_REPLACE, GL_REPLACE); +	 _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, +				   ctx->Stencil.Clear & 0x7fffffff, +				   ctx->Stencil.WriteMask[0]); +      } else { +	 _mesa_Disable(GL_STENCIL_TEST); +      } + +      _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); + +      mask &= ~this_mask; +   } + +   meta_restore_transform(meta); + +   _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture); +   if (saved_fp_enable) +      _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); +   if (saved_vp_enable) +      _mesa_Enable(GL_VERTEX_PROGRAM_ARB); + +   if (saved_shader_program) +      _mesa_UseProgramObjectARB(saved_shader_program); + +   _mesa_PopAttrib(); + +   /* restore current array object */ +   ctx->NewState |= _NEW_ARRAY; +   ctx->Array.NewState |= _NEW_ARRAY_ALL; +   _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave); +   _mesa_reference_array_object(ctx, &arraySave, NULL); +} + +void meta_init_metaops(GLcontext *ctx, struct dri_metaops *meta) +{ +   meta->ctx = ctx; +} + +void meta_destroy_metaops(struct dri_metaops *meta) +{ +  if (meta->clear.arrayObj) +    _mesa_delete_array_object(meta->ctx, meta->clear.arrayObj); + +} diff --git a/src/mesa/drivers/dri/common/dri_metaops.h b/src/mesa/drivers/dri/common/dri_metaops.h new file mode 100644 index 0000000000..bb4079d535 --- /dev/null +++ b/src/mesa/drivers/dri/common/dri_metaops.h @@ -0,0 +1,99 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009 Intel Corporation. + * 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 DRI_METAOPS_H +#define DRI_METAOPS_H + +#define TRI_CLEAR_COLOR_BITS (BUFFER_BIT_BACK_LEFT |			\ +			      BUFFER_BIT_FRONT_LEFT |			\ +			      BUFFER_BIT_COLOR0 |			\ +			      BUFFER_BIT_COLOR1 |			\ +			      BUFFER_BIT_COLOR2 |			\ +			      BUFFER_BIT_COLOR3 |			\ +			      BUFFER_BIT_COLOR4 |			\ +			      BUFFER_BIT_COLOR5 |			\ +			      BUFFER_BIT_COLOR6 |			\ +			      BUFFER_BIT_COLOR7) + +struct dri_meta_clear { +    struct gl_array_object *arrayObj; +    GLfloat vertices[4][3]; +    GLfloat color[4][4]; +}; + +struct dri_metaops { +    GLcontext *ctx; +    GLboolean internal_viewport_call; +    struct gl_fragment_program *bitmap_fp; +    struct gl_vertex_program *passthrough_vp; +    struct gl_buffer_object *texcoord_vbo; +     +    struct gl_fragment_program *saved_fp; +    GLboolean saved_fp_enable; +    struct gl_vertex_program *saved_vp; +    GLboolean saved_vp_enable; + +    struct gl_fragment_program *tex2d_fp; +     +    GLboolean saved_texcoord_enable; +    struct gl_buffer_object *saved_array_vbo, *saved_texcoord_vbo; +    GLenum saved_texcoord_type; +    GLsizei saved_texcoord_size, saved_texcoord_stride; +    const void *saved_texcoord_ptr; +    int saved_active_texture; + +    GLint saved_vp_x, saved_vp_y; +    GLsizei saved_vp_width, saved_vp_height; +    GLenum saved_matrix_mode; +     +    struct dri_meta_clear clear; +}; + + +void meta_set_passthrough_transform(struct dri_metaops *meta); + +void meta_restore_transform(struct dri_metaops *meta); + +void meta_set_passthrough_vertex_program(struct dri_metaops *meta); + +void meta_restore_vertex_program(struct dri_metaops *meta); + +void meta_set_fragment_program(struct dri_metaops *meta, +			  struct gl_fragment_program **prog, +			  const char *prog_string); + +void meta_restore_fragment_program(struct dri_metaops *meta); + +void meta_set_default_texrect(struct dri_metaops *meta); + +void meta_restore_texcoords(struct dri_metaops *meta); +void meta_clear_tris(struct dri_metaops *meta, GLbitfield mask); + +void meta_init_metaops(GLcontext *ctx, struct dri_metaops *meta); +void meta_destroy_metaops(struct dri_metaops *meta); +#endif + diff --git a/src/mesa/drivers/dri/intel/intel_clear.c b/src/mesa/drivers/dri/intel/intel_clear.c index 13b433dd17..cfddabd318 100644 --- a/src/mesa/drivers/dri/intel/intel_clear.c +++ b/src/mesa/drivers/dri/intel/intel_clear.c @@ -57,250 +57,6 @@  #define FILE_DEBUG_FLAG DEBUG_BLIT -#define TRI_CLEAR_COLOR_BITS (BUFFER_BIT_BACK_LEFT |			\ -			      BUFFER_BIT_FRONT_LEFT |			\ -			      BUFFER_BIT_COLOR0 |			\ -			      BUFFER_BIT_COLOR1 |			\ -			      BUFFER_BIT_COLOR2 |			\ -			      BUFFER_BIT_COLOR3 |			\ -			      BUFFER_BIT_COLOR4 |			\ -			      BUFFER_BIT_COLOR5 |			\ -			      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); -   ctx->NewState |= _NEW_ARRAY; -   ctx->Array.NewState |= _NEW_ARRAY_ALL; -   _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 */ -   ctx->NewState |= _NEW_ARRAY; -   ctx->Array.NewState |= _NEW_ARRAY_ALL; -   _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. - * - * The implementation is based on calling into Mesa to set GL state and - * performing normal triangle rendering.  The intent of this path is to - * have as generic a path as possible, so that any driver could make use of - * it. - */ -void -intel_clear_tris(GLcontext *ctx, GLbitfield mask) -{ -   struct intel_context *intel = intel_context(ctx); -   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); - -   _mesa_PushAttrib(GL_COLOR_BUFFER_BIT | -		    GL_DEPTH_BUFFER_BIT | -		    GL_ENABLE_BIT | -		    GL_POLYGON_BIT | -		    GL_STENCIL_BUFFER_BIT | -		    GL_TRANSFORM_BIT | -		    GL_CURRENT_BIT | -		    GL_VIEWPORT_BIT); -   saved_active_texture = ctx->Texture.CurrentUnit; - -   /* Disable existing GL state we don't want to apply to a clear. */ -   _mesa_Disable(GL_ALPHA_TEST); -   _mesa_Disable(GL_BLEND); -   _mesa_Disable(GL_CULL_FACE); -   _mesa_Disable(GL_FOG); -   _mesa_Disable(GL_POLYGON_SMOOTH); -   _mesa_Disable(GL_POLYGON_STIPPLE); -   _mesa_Disable(GL_POLYGON_OFFSET_FILL); -   _mesa_Disable(GL_LIGHTING); -   _mesa_Disable(GL_CLIP_PLANE0); -   _mesa_Disable(GL_CLIP_PLANE1); -   _mesa_Disable(GL_CLIP_PLANE2); -   _mesa_Disable(GL_CLIP_PLANE3); -   _mesa_Disable(GL_CLIP_PLANE4); -   _mesa_Disable(GL_CLIP_PLANE5); -   _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL); -   if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) { -      saved_fp_enable = GL_TRUE; -      _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); -   } -   if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) { -      saved_vp_enable = GL_TRUE; -      _mesa_Disable(GL_VERTEX_PROGRAM_ARB); -   } -   if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) { -      saved_shader_program = ctx->Shader.CurrentProgram->Name; -      _mesa_UseProgramObjectARB(0); -   } - -   if (ctx->Texture._EnabledUnits != 0) { -      int i; - -      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { -	 _mesa_ActiveTextureARB(GL_TEXTURE0 + i); -	 _mesa_Disable(GL_TEXTURE_1D); -	 _mesa_Disable(GL_TEXTURE_2D); -	 _mesa_Disable(GL_TEXTURE_3D); -	 if (ctx->Extensions.ARB_texture_cube_map) -	    _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB); -	 if (ctx->Extensions.NV_texture_rectangle) -	    _mesa_Disable(GL_TEXTURE_RECTANGLE_NV); -	 if (ctx->Extensions.MESA_texture_array) { -	    _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT); -	    _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT); -	 } -      } -   } - -   /* save current array object, bind our private one */ -   _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj); -   ctx->NewState |= _NEW_ARRAY; -   ctx->Array.NewState |= _NEW_ARRAY_ALL; -   _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, intel->clear.arrayObj); - -   intel_meta_set_passthrough_transform(intel); - -   for (i = 0; i < 4; i++) { -      COPY_4FV(intel->clear.color[i], ctx->Color.ClearColor); -   } - -   /* convert clear Z from [0,1] to NDC coord in [-1,1] */ -   dst_z = -1.0 + 2.0 * ctx->Depth.Clear; - -   /* The ClearDepth value is unaffected by DepthRange, so do a default -    * mapping. -    */ -   _mesa_DepthRange(0.0, 1.0); - -   /* Prepare the vertices, which are the same regardless of which buffer we're -    * drawing to. -    */ -   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; -      GLuint color_bit; - -      color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS); -      if (color_bit != 0) -	 this_mask |= (1 << (color_bit - 1)); - -      /* Clear depth/stencil in the same pass as color. */ -      this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)); - -      /* Select the current color buffer and use the color write mask if -       * we have one, otherwise don't write any color channels. -       */ -      if (this_mask & BUFFER_BIT_FRONT_LEFT) -	 _mesa_DrawBuffer(GL_FRONT_LEFT); -      else if (this_mask & BUFFER_BIT_BACK_LEFT) -	 _mesa_DrawBuffer(GL_BACK_LEFT); -      else if (color_bit != 0) -	 _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0 + -			  (color_bit - BUFFER_COLOR0 - 1)); -      else -	 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - -      /* Control writing of the depth clear value to depth. */ -      if (this_mask & BUFFER_BIT_DEPTH) { -	 _mesa_DepthFunc(GL_ALWAYS); -	 _mesa_Enable(GL_DEPTH_TEST); -      } else { -	 _mesa_Disable(GL_DEPTH_TEST); -	 _mesa_DepthMask(GL_FALSE); -      } - -      /* Control writing of the stencil clear value to stencil. */ -      if (this_mask & BUFFER_BIT_STENCIL) { -	 _mesa_Enable(GL_STENCIL_TEST); -	 _mesa_StencilOpSeparate(GL_FRONT_AND_BACK, -				 GL_REPLACE, GL_REPLACE, GL_REPLACE); -	 _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, -				   ctx->Stencil.Clear, -				   ctx->Stencil.WriteMask[0]); -      } else { -	 _mesa_Disable(GL_STENCIL_TEST); -      } - -      _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - -      mask &= ~this_mask; -   } - -   intel_meta_restore_transform(intel); - -   _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture); -   if (saved_fp_enable) -      _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); -   if (saved_vp_enable) -      _mesa_Enable(GL_VERTEX_PROGRAM_ARB); - -   if (saved_shader_program) -      _mesa_UseProgramObjectARB(saved_shader_program); - -   _mesa_PopAttrib(); - -   /* restore current array object */ -   ctx->NewState |= _NEW_ARRAY; -   ctx->Array.NewState |= _NEW_ARRAY_ALL; -   _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave); -   _mesa_reference_array_object(ctx, &arraySave, NULL); -} -  static const char *buffer_names[] = {     [BUFFER_FRONT_LEFT] = "front",     [BUFFER_BACK_LEFT] = "back", @@ -326,6 +82,7 @@ static const char *buffer_names[] = {  static void  intelClear(GLcontext *ctx, GLbitfield mask)  { +   struct intel_context *intel = intel_context(ctx);     const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask);     GLbitfield tri_mask = 0;     GLbitfield blit_mask = 0; @@ -425,7 +182,7 @@ intelClear(GLcontext *ctx, GLbitfield mask)  	 }  	 DBG("\n");        } -      intel_clear_tris(ctx, tri_mask); +      meta_clear_tris(&intel->meta, tri_mask);     }     if (swrast_mask) { diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index edf422c1bd..4abb525f78 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -404,7 +404,7 @@ intel_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)      if (!driContext->driScreenPriv->dri2.enabled)  	return; -    if (!intel->internal_viewport_call && ctx->DrawBuffer->Name == 0) { +    if (!intel->meta.internal_viewport_call && ctx->DrawBuffer->Name == 0) {         /* If we're rendering to the fake front buffer, make sure all the pending  	* drawing has landed on the real front buffer.  Otherwise when we  	* eventually get to DRI2GetBuffersWithFormat the stale real front @@ -672,6 +672,7 @@ intelInitContext(struct intel_context *intel,      */     _mesa_init_point(ctx); +   meta_init_metaops(ctx, &intel->meta);     ctx->Const.MaxColorAttachments = 4;  /* XXX FBO: review this */     if (IS_965(intelScreen->deviceID)) {        if (MAX_WIDTH > 8192) @@ -794,8 +795,7 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv)        INTEL_FIREVERTICES(intel); -      if (intel->clear.arrayObj) -         _mesa_delete_array_object(&intel->ctx, intel->clear.arrayObj); +      meta_destroy_metaops(&intel->meta);        intel->vtbl.destroy(intel); diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h index 6761193f8c..08bea88c95 100644 --- a/src/mesa/drivers/dri/intel/intel_context.h +++ b/src/mesa/drivers/dri/intel/intel_context.h @@ -33,6 +33,7 @@  #include "main/mtypes.h"  #include "main/mm.h"  #include "texmem.h" +#include "dri_metaops.h"  #include "drm.h"  #include "intel_bufmgr.h" @@ -157,29 +158,7 @@ struct intel_context        void (*debug_batch)(struct intel_context *intel);     } vtbl; -   struct { -      struct gl_fragment_program *bitmap_fp; -      struct gl_vertex_program *passthrough_vp; -      struct gl_buffer_object *texcoord_vbo; - -      struct gl_fragment_program *saved_fp; -      GLboolean saved_fp_enable; -      struct gl_vertex_program *saved_vp; -      GLboolean saved_vp_enable; - -      struct gl_fragment_program *tex2d_fp; - -      GLboolean saved_texcoord_enable; -      struct gl_buffer_object *saved_array_vbo, *saved_texcoord_vbo; -      GLenum saved_texcoord_type; -      GLsizei saved_texcoord_size, saved_texcoord_stride; -      const void *saved_texcoord_ptr; -      int saved_active_texture; - -      GLint saved_vp_x, saved_vp_y; -      GLsizei saved_vp_width, saved_vp_height; -      GLenum saved_matrix_mode; -   } meta; +   struct dri_metaops meta;     GLint refcount;     GLuint Fallback; @@ -191,7 +170,6 @@ struct intel_context     struct intel_region *front_region;     struct intel_region *back_region;     struct intel_region *depth_region; -   GLboolean internal_viewport_call;     /**      * This value indicates that the kernel memory manager is being used @@ -224,13 +202,6 @@ 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:      */ diff --git a/src/mesa/drivers/dri/intel/intel_generatemipmap.c b/src/mesa/drivers/dri/intel/intel_generatemipmap.c index b00f8019dd..fe986092db 100644 --- a/src/mesa/drivers/dri/intel/intel_generatemipmap.c +++ b/src/mesa/drivers/dri/intel/intel_generatemipmap.c @@ -88,7 +88,7 @@ intel_generate_mipmap_level(GLcontext *ctx, GLuint tex_name,     if (status != GL_FRAMEBUFFER_COMPLETE_EXT)        return GL_FALSE; -   intel_meta_set_passthrough_transform(intel); +   meta_set_passthrough_transform(&intel->meta);     /* XXX: Doing it right would involve setting up the transformation to do      * 0-1 mapping or something, and not changing the vertex data. @@ -104,12 +104,12 @@ intel_generate_mipmap_level(GLcontext *ctx, GLuint tex_name,     _mesa_VertexPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &vertices);     _mesa_Enable(GL_VERTEX_ARRAY); -   intel_meta_set_default_texrect(intel); +   meta_set_default_texrect(&intel->meta);     _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); -   intel_meta_restore_texcoords(intel); -   intel_meta_restore_transform(intel); +   meta_restore_texcoords(&intel->meta); +   meta_restore_transform(&intel->meta);     return GL_TRUE;  } @@ -153,9 +153,9 @@ intel_generate_mipmap_2d(GLcontext *ctx,     _mesa_GenFramebuffersEXT(1, &fb_name);     _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb_name); -   intel_meta_set_fragment_program(intel, &intel->meta.tex2d_fp, -				   intel_fp_tex2d); -   intel_meta_set_passthrough_vertex_program(intel); +   meta_set_fragment_program(&intel->meta, &intel->meta.tex2d_fp, +			     intel_fp_tex2d); +   meta_set_passthrough_vertex_program(&intel->meta);     max_levels = _mesa_max_texture_levels(ctx, texObj->Target);     start_level = texObj->BaseLevel; @@ -202,8 +202,8 @@ intel_generate_mipmap_2d(GLcontext *ctx,     success = GL_TRUE;  fail: -   intel_meta_restore_fragment_program(intel); -   intel_meta_restore_vertex_program(intel); +   meta_restore_fragment_program(&intel->meta); +   meta_restore_vertex_program(&intel->meta);     _mesa_DeleteFramebuffersEXT(1, &fb_name);     _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture); diff --git a/src/mesa/drivers/dri/intel/intel_pixel.c b/src/mesa/drivers/dri/intel/intel_pixel.c index da9ccb23f1..a300141655 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel.c +++ b/src/mesa/drivers/dri/intel/intel_pixel.c @@ -177,246 +177,6 @@ intel_check_blit_format(struct intel_region * region,  }  void -intel_meta_set_passthrough_transform(struct intel_context *intel) -{ -   GLcontext *ctx = &intel->ctx; - -   intel->meta.saved_vp_x = ctx->Viewport.X; -   intel->meta.saved_vp_y = ctx->Viewport.Y; -   intel->meta.saved_vp_width = ctx->Viewport.Width; -   intel->meta.saved_vp_height = ctx->Viewport.Height; -   intel->meta.saved_matrix_mode = ctx->Transform.MatrixMode; - -   intel->internal_viewport_call = GL_TRUE; -   _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height); -   intel->internal_viewport_call = GL_FALSE; - -   _mesa_MatrixMode(GL_PROJECTION); -   _mesa_PushMatrix(); -   _mesa_LoadIdentity(); -   _mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1); - -   _mesa_MatrixMode(GL_MODELVIEW); -   _mesa_PushMatrix(); -   _mesa_LoadIdentity(); -} - -void -intel_meta_restore_transform(struct intel_context *intel) -{ -   _mesa_MatrixMode(GL_PROJECTION); -   _mesa_PopMatrix(); -   _mesa_MatrixMode(GL_MODELVIEW); -   _mesa_PopMatrix(); - -   _mesa_MatrixMode(intel->meta.saved_matrix_mode); - -   intel->internal_viewport_call = GL_TRUE; -   _mesa_Viewport(intel->meta.saved_vp_x, intel->meta.saved_vp_y, -		  intel->meta.saved_vp_width, intel->meta.saved_vp_height); -   intel->internal_viewport_call = GL_FALSE; -} - -/** - * Set up a vertex program to pass through the position and first texcoord - * for pixel path. - */ -void -intel_meta_set_passthrough_vertex_program(struct intel_context *intel) -{ -   GLcontext *ctx = &intel->ctx; -   static const char *vp = -      "!!ARBvp1.0\n" -      "TEMP vertexClip;\n" -      "DP4 vertexClip.x, state.matrix.mvp.row[0], vertex.position;\n" -      "DP4 vertexClip.y, state.matrix.mvp.row[1], vertex.position;\n" -      "DP4 vertexClip.z, state.matrix.mvp.row[2], vertex.position;\n" -      "DP4 vertexClip.w, state.matrix.mvp.row[3], vertex.position;\n" -      "MOV result.position, vertexClip;\n" -      "MOV result.texcoord[0], vertex.texcoord[0];\n" -      "MOV result.color, vertex.color;\n" -      "END\n"; - -   assert(intel->meta.saved_vp == NULL); - -   _mesa_reference_vertprog(ctx, &intel->meta.saved_vp, -			    ctx->VertexProgram.Current); -   if (intel->meta.passthrough_vp == NULL) { -      GLuint prog_name; -      _mesa_GenPrograms(1, &prog_name); -      _mesa_BindProgram(GL_VERTEX_PROGRAM_ARB, prog_name); -      _mesa_ProgramStringARB(GL_VERTEX_PROGRAM_ARB, -			     GL_PROGRAM_FORMAT_ASCII_ARB, -			     strlen(vp), (const GLubyte *)vp); -      _mesa_reference_vertprog(ctx, &intel->meta.passthrough_vp, -			       ctx->VertexProgram.Current); -      _mesa_DeletePrograms(1, &prog_name); -   } - -   FLUSH_VERTICES(ctx, _NEW_PROGRAM); -   _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, -			    intel->meta.passthrough_vp); -   ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, -			   &intel->meta.passthrough_vp->Base); - -   intel->meta.saved_vp_enable = ctx->VertexProgram.Enabled; -   _mesa_Enable(GL_VERTEX_PROGRAM_ARB); -} - -/** - * Restores the previous vertex program after - * intel_meta_set_passthrough_vertex_program() - */ -void -intel_meta_restore_vertex_program(struct intel_context *intel) -{ -   GLcontext *ctx = &intel->ctx; - -   FLUSH_VERTICES(ctx, _NEW_PROGRAM); -   _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, -			    intel->meta.saved_vp); -   _mesa_reference_vertprog(ctx, &intel->meta.saved_vp, NULL); -   ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, -			   &ctx->VertexProgram.Current->Base); - -   if (!intel->meta.saved_vp_enable) -      _mesa_Disable(GL_VERTEX_PROGRAM_ARB); -} - -/** - * Binds the given program string to GL_FRAGMENT_PROGRAM_ARB, caching the - * program object. - */ -void -intel_meta_set_fragment_program(struct intel_context *intel, -				struct gl_fragment_program **prog, -				const char *prog_string) -{ -   GLcontext *ctx = &intel->ctx; -   assert(intel->meta.saved_fp == NULL); - -   _mesa_reference_fragprog(ctx, &intel->meta.saved_fp, -			    ctx->FragmentProgram.Current); -   if (*prog == NULL) { -      GLuint prog_name; -      _mesa_GenPrograms(1, &prog_name); -      _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, prog_name); -      _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, -			     GL_PROGRAM_FORMAT_ASCII_ARB, -			     strlen(prog_string), (const GLubyte *)prog_string); -      _mesa_reference_fragprog(ctx, prog, ctx->FragmentProgram.Current); -      /* Note that DeletePrograms unbinds the program on us */ -      _mesa_DeletePrograms(1, &prog_name); -   } - -   FLUSH_VERTICES(ctx, _NEW_PROGRAM); -   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, *prog); -   ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, &((*prog)->Base)); - -   intel->meta.saved_fp_enable = ctx->FragmentProgram.Enabled; -   _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); -} - -/** - * Restores the previous fragment program after - * intel_meta_set_fragment_program() - */ -void -intel_meta_restore_fragment_program(struct intel_context *intel) -{ -   GLcontext *ctx = &intel->ctx; - -   FLUSH_VERTICES(ctx, _NEW_PROGRAM); -   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, -			    intel->meta.saved_fp); -   _mesa_reference_fragprog(ctx, &intel->meta.saved_fp, NULL); -   ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, -			   &ctx->FragmentProgram.Current->Base); - -   if (!intel->meta.saved_fp_enable) -      _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); -} - -static const float default_texcoords[4][2] = { { 0.0, 0.0 }, -					       { 1.0, 0.0 }, -					       { 1.0, 1.0 }, -					       { 0.0, 1.0 } }; - -void -intel_meta_set_default_texrect(struct intel_context *intel) -{ -   GLcontext *ctx = &intel->ctx; -   struct gl_client_array *old_texcoord_array; - -   intel->meta.saved_active_texture = ctx->Texture.CurrentUnit; -   if (intel->meta.saved_array_vbo == NULL) { -      _mesa_reference_buffer_object(ctx, &intel->meta.saved_array_vbo, -				    ctx->Array.ArrayBufferObj); -   } - -   old_texcoord_array = &ctx->Array.ArrayObj->TexCoord[0]; -   intel->meta.saved_texcoord_type = old_texcoord_array->Type; -   intel->meta.saved_texcoord_size = old_texcoord_array->Size; -   intel->meta.saved_texcoord_stride = old_texcoord_array->Stride; -   intel->meta.saved_texcoord_enable = old_texcoord_array->Enabled; -   intel->meta.saved_texcoord_ptr = old_texcoord_array->Ptr; -   _mesa_reference_buffer_object(ctx, &intel->meta.saved_texcoord_vbo, -				 old_texcoord_array->BufferObj); - -   _mesa_ClientActiveTextureARB(GL_TEXTURE0); - -   if (intel->meta.texcoord_vbo == NULL) { -      GLuint vbo_name; - -      _mesa_GenBuffersARB(1, &vbo_name); -      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_name); -      _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(default_texcoords), -			  default_texcoords, GL_STATIC_DRAW_ARB); -      _mesa_reference_buffer_object(ctx, &intel->meta.texcoord_vbo, -				    ctx->Array.ArrayBufferObj); -   } else { -      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, -			  intel->meta.texcoord_vbo->Name); -   } -   _mesa_TexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), NULL); - -   _mesa_Enable(GL_TEXTURE_COORD_ARRAY); -} - -void -intel_meta_restore_texcoords(struct intel_context *intel) -{ -   GLcontext *ctx = &intel->ctx; - -   /* Restore the old TexCoordPointer */ -   if (intel->meta.saved_texcoord_vbo) { -      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, -			  intel->meta.saved_texcoord_vbo->Name); -      _mesa_reference_buffer_object(ctx, &intel->meta.saved_texcoord_vbo, NULL); -   } else { -      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); -   } - -   _mesa_TexCoordPointer(intel->meta.saved_texcoord_size, -			 intel->meta.saved_texcoord_type, -			 intel->meta.saved_texcoord_stride, -			 intel->meta.saved_texcoord_ptr); -   if (!intel->meta.saved_texcoord_enable) -      _mesa_Disable(GL_TEXTURE_COORD_ARRAY); - -   _mesa_ClientActiveTextureARB(GL_TEXTURE0 + -				intel->meta.saved_active_texture); - -   if (intel->meta.saved_array_vbo) { -      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, -			  intel->meta.saved_array_vbo->Name); -      _mesa_reference_buffer_object(ctx, &intel->meta.saved_array_vbo, NULL); -   } else { -      _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); -   } -} - -void  intelInitPixelFuncs(struct dd_function_table *functions)  {     functions->Accum = _swrast_Accum; @@ -428,14 +188,3 @@ intelInitPixelFuncs(struct dd_function_table *functions)     functions->ReadPixels = intelReadPixels;  } -void -intel_free_pixel_state(struct intel_context *intel) -{ -   GLcontext *ctx = &intel->ctx; - -   _mesa_reference_vertprog(ctx, &intel->meta.passthrough_vp, NULL); -   _mesa_reference_fragprog(ctx, &intel->meta.bitmap_fp, NULL); -   _mesa_reference_fragprog(ctx, &intel->meta.tex2d_fp, NULL); -   _mesa_reference_buffer_object(ctx, &intel->meta.texcoord_vbo, NULL); -} - diff --git a/src/mesa/drivers/dri/intel/intel_pixel.h b/src/mesa/drivers/dri/intel/intel_pixel.h index 6acf0813c8..96a6dd17b2 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel.h +++ b/src/mesa/drivers/dri/intel/intel_pixel.h @@ -31,19 +31,6 @@  #include "main/mtypes.h"  void intelInitPixelFuncs(struct dd_function_table *functions); -void intel_meta_set_passthrough_transform(struct intel_context *intel); -void intel_meta_restore_transform(struct intel_context *intel); -void intel_meta_set_passthrough_vertex_program(struct intel_context *intel); -void intel_meta_restore_vertex_program(struct intel_context *intel); -void intel_meta_set_fragment_program(struct intel_context *intel, -				     struct gl_fragment_program **prog, -				     const char *prog_string); -void intel_meta_restore_fragment_program(struct intel_context *intel); -void intel_free_pixel_state(struct intel_context *intel); -void intel_meta_set_default_texrect(struct intel_context *intel); -void intel_meta_set_default_texrect(struct intel_context *intel); -void intel_meta_restore_texcoords(struct intel_context *intel); -  GLboolean intel_check_blit_fragment_ops(GLcontext * ctx,  					GLboolean src_alpha_is_one); @@ -79,6 +66,4 @@ void intelBitmap(GLcontext * ctx,  		 const struct gl_pixelstore_attrib *unpack,  		 const GLubyte * pixels); -void intel_clear_tris(GLcontext *ctx, GLbitfield mask); -  #endif diff --git a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c index ebba6aafad..540e7620a9 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c @@ -476,11 +476,11 @@ intel_texture_bitmap(GLcontext * ctx,  		    GL_ALPHA, GL_UNSIGNED_BYTE, a8_bitmap);     _mesa_free(a8_bitmap); -   intel_meta_set_fragment_program(intel, &intel->meta.bitmap_fp, fp); +   meta_set_fragment_program(&intel->meta, &intel->meta.bitmap_fp, fp);     _mesa_ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0,  				     ctx->Current.RasterColor); -   intel_meta_set_passthrough_vertex_program(intel); -   intel_meta_set_passthrough_transform(intel); +   meta_set_passthrough_vertex_program(&intel->meta); +   meta_set_passthrough_transform(&intel->meta);     /* convert rasterpos Z from [0,1] to NDC coord in [-1,1] */     dst_z = -1.0 + 2.0 * ctx->Current.RasterPos[2]; @@ -507,13 +507,13 @@ intel_texture_bitmap(GLcontext * ctx,     _mesa_VertexPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &vertices);     _mesa_Enable(GL_VERTEX_ARRAY); -   intel_meta_set_default_texrect(intel); +   meta_set_default_texrect(&intel->meta);     _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); -   intel_meta_restore_texcoords(intel); -   intel_meta_restore_transform(intel); -   intel_meta_restore_fragment_program(intel); -   intel_meta_restore_vertex_program(intel); +   meta_restore_texcoords(&intel->meta); +   meta_restore_transform(&intel->meta); +   meta_restore_fragment_program(&intel->meta); +   meta_restore_vertex_program(&intel->meta);     _mesa_PopClientAttrib();     _mesa_Disable(GL_TEXTURE_2D); /* asserted that it was disabled at entry */ diff --git a/src/mesa/drivers/dri/intel/intel_pixel_draw.c b/src/mesa/drivers/dri/intel/intel_pixel_draw.c index dfc9e1539f..a6b6824164 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_draw.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_draw.c @@ -150,7 +150,7 @@ intel_texture_drawpixels(GLcontext * ctx,     _mesa_TexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format,  		    type, pixels); -   intel_meta_set_passthrough_transform(intel); +   meta_set_passthrough_transform(&intel->meta);     /* convert rasterpos Z from [0,1] to NDC coord in [-1,1] */     z = -1.0 + 2.0 * ctx->Current.RasterPos[2]; @@ -182,12 +182,12 @@ intel_texture_drawpixels(GLcontext * ctx,     _mesa_VertexPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &vertices);     _mesa_Enable(GL_VERTEX_ARRAY); -   intel_meta_set_default_texrect(intel); +   meta_set_default_texrect(&intel->meta);     _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); -   intel_meta_restore_texcoords(intel); -   intel_meta_restore_transform(intel); +   meta_restore_texcoords(&intel->meta); +   meta_restore_transform(&intel->meta);     _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture);     _mesa_PopClientAttrib(); @@ -352,7 +352,7 @@ intel_stencil_drawpixels(GLcontext * ctx,     ctx->Unpack = old_unpack;     _mesa_free(stencil_pixels); -   intel_meta_set_passthrough_transform(intel); +   meta_set_passthrough_transform(&intel->meta);     /* Since we're rendering to the framebuffer as if it was an FBO,      * if it's the window system we have to flip the coordinates. @@ -375,12 +375,12 @@ intel_stencil_drawpixels(GLcontext * ctx,     _mesa_VertexPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &vertices);     _mesa_Enable(GL_VERTEX_ARRAY); -   intel_meta_set_default_texrect(intel); +   meta_set_default_texrect(&intel->meta);     _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); -   intel_meta_restore_texcoords(intel); -   intel_meta_restore_transform(intel); +   meta_restore_texcoords(&intel->meta); +   meta_restore_transform(&intel->meta);     _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture);     _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, old_fb_name); diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c index 6560efdca3..4dbda39eb9 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.c +++ b/src/mesa/drivers/dri/r200/r200_ioctl.c @@ -58,11 +58,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  #define R200_TIMEOUT             512  #define R200_IDLE_RETRY           16 -static void r200UserClear(GLcontext *ctx, GLuint mask) -{ -   radeon_clear_tris(ctx, mask); -} -  static void r200KernelClear(GLcontext *ctx, GLuint flags)  {     r200ContextPtr rmesa = R200_CONTEXT(ctx); @@ -253,7 +248,7 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask )     }     if (rmesa->radeon.radeonScreen->kernel_mm) -      r200UserClear(ctx, orig_mask); +      radeonUserClear(ctx, orig_mask);     else {        r200KernelClear(ctx, flags);        rmesa->radeon.hw.all_dirty = GL_TRUE; diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c index 4e913dba29..ddabd53992 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.c +++ b/src/mesa/drivers/dri/r300/r300_ioctl.c @@ -68,11 +68,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  static void r300EmitClearState(GLcontext * ctx); -static void r300UserClear(GLcontext *ctx, GLuint mask) -{ -	radeon_clear_tris(ctx, mask); -} -  static void r300ClearBuffer(r300ContextPtr r300, int flags,  			    struct radeon_renderbuffer *rrb,  			    struct radeon_renderbuffer *rrbd) @@ -680,7 +675,7 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask)  	ret = 0;  	if (tri_mask) {  		if (r300->radeon.radeonScreen->kernel_mm) -			r300UserClear(ctx, tri_mask); +			radeonUserClear(ctx, tri_mask);  		else {  			/* if kernel clear fails due to size restraints fallback */  			ret = r300KernelClear(ctx, tri_mask); diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c index 0a8d8b03e8..3bf42e9bb0 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.c +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -877,7 +877,7 @@ void radeon_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei he  	if (!driContext->driScreenPriv->dri2.enabled)  		return; -	if (!radeon->internal_viewport_call && ctx->DrawBuffer->Name == 0) { +	if (!radeon->meta.internal_viewport_call && ctx->DrawBuffer->Name == 0) {  		if (radeon->is_front_buffer_rendering) {  			radeonFlush(ctx);  		} @@ -1258,254 +1258,8 @@ void rcommonBeginBatch(radeonContextPtr rmesa, int n,  } - - -static void -radeon_meta_set_passthrough_transform(radeonContextPtr radeon) -{ -   GLcontext *ctx = radeon->glCtx; - -   radeon->meta.saved_vp_x = ctx->Viewport.X; -   radeon->meta.saved_vp_y = ctx->Viewport.Y; -   radeon->meta.saved_vp_width = ctx->Viewport.Width; -   radeon->meta.saved_vp_height = ctx->Viewport.Height; -   radeon->meta.saved_matrix_mode = ctx->Transform.MatrixMode; - -   radeon->internal_viewport_call = GL_TRUE; -   _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height); -   radeon->internal_viewport_call = GL_FALSE; - -   _mesa_MatrixMode(GL_PROJECTION); -   _mesa_PushMatrix(); -   _mesa_LoadIdentity(); -   _mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1); - -   _mesa_MatrixMode(GL_MODELVIEW); -   _mesa_PushMatrix(); -   _mesa_LoadIdentity(); -} - -static void -radeon_meta_restore_transform(radeonContextPtr radeon) -{ -   _mesa_MatrixMode(GL_PROJECTION); -   _mesa_PopMatrix(); -   _mesa_MatrixMode(GL_MODELVIEW); -   _mesa_PopMatrix(); - -   _mesa_MatrixMode(radeon->meta.saved_matrix_mode); - -   radeon->internal_viewport_call = GL_TRUE; -   _mesa_Viewport(radeon->meta.saved_vp_x, radeon->meta.saved_vp_y, -		  radeon->meta.saved_vp_width, radeon->meta.saved_vp_height); -   radeon->internal_viewport_call = GL_FALSE; -} - - -/** - * Perform glClear where mask contains only color, depth, and/or stencil. - * - * The implementation is based on calling into Mesa to set GL state and - * performing normal triangle rendering.  The intent of this path is to - * have as generic a path as possible, so that any driver could make use of - * it. - */ - -static void radeon_clear_init(GLcontext *ctx) -{ -    radeonContextPtr rmesa = RADEON_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 */ -    rmesa->clear.arrayObj = _mesa_new_array_object(ctx, ~0); -    _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj); -    _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, rmesa->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), rmesa->clear.color); -    _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), rmesa->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); -} - - -void radeon_clear_tris(GLcontext *ctx, GLbitfield mask) +void radeonUserClear(GLcontext *ctx, GLuint mask)  {     radeonContextPtr rmesa = RADEON_CONTEXT(ctx); -   GLfloat dst_z; -   struct gl_framebuffer *fb = ctx->DrawBuffer; -   int i; -   GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE; -   GLboolean saved_shader_program = 0; -   unsigned int saved_active_texture; -   struct gl_array_object *arraySave = NULL; - -   if (!rmesa->clear.arrayObj) -       radeon_clear_init(ctx); - -   assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH | -		    BUFFER_BIT_STENCIL)) == 0); - -   _mesa_PushAttrib(GL_COLOR_BUFFER_BIT | -		    GL_DEPTH_BUFFER_BIT | -		    GL_ENABLE_BIT | -		    GL_POLYGON_BIT | -		    GL_STENCIL_BUFFER_BIT | -		    GL_TRANSFORM_BIT | -		    GL_CURRENT_BIT); -   saved_active_texture = ctx->Texture.CurrentUnit; - -  /* Disable existing GL state we don't want to apply to a clear. */ -   _mesa_Disable(GL_ALPHA_TEST); -   _mesa_Disable(GL_BLEND); -   _mesa_Disable(GL_CULL_FACE); -   _mesa_Disable(GL_FOG); -   _mesa_Disable(GL_POLYGON_SMOOTH); -   _mesa_Disable(GL_POLYGON_STIPPLE); -   _mesa_Disable(GL_POLYGON_OFFSET_FILL); -   _mesa_Disable(GL_LIGHTING); -   _mesa_Disable(GL_CLIP_PLANE0); -   _mesa_Disable(GL_CLIP_PLANE1); -   _mesa_Disable(GL_CLIP_PLANE2); -   _mesa_Disable(GL_CLIP_PLANE3); -   _mesa_Disable(GL_CLIP_PLANE4); -   _mesa_Disable(GL_CLIP_PLANE5); -   _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL); -   if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) { -      saved_fp_enable = GL_TRUE; -      _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); -   } -   if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) { -      saved_vp_enable = GL_TRUE; -      _mesa_Disable(GL_VERTEX_PROGRAM_ARB); -   } -   if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) { -      saved_shader_program = ctx->Shader.CurrentProgram->Name; -      _mesa_UseProgramObjectARB(0); -   } - -   if (ctx->Texture._EnabledUnits != 0) { -      int i; - -      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { -	 _mesa_ActiveTextureARB(GL_TEXTURE0 + i); -	 _mesa_Disable(GL_TEXTURE_1D); -	 _mesa_Disable(GL_TEXTURE_2D); -	 _mesa_Disable(GL_TEXTURE_3D); -	 if (ctx->Extensions.ARB_texture_cube_map) -	    _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB); -	 if (ctx->Extensions.NV_texture_rectangle) -	    _mesa_Disable(GL_TEXTURE_RECTANGLE_NV); -	 if (ctx->Extensions.MESA_texture_array) { -	    _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT); -	    _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT); -	 } -      } -   } - -   /* 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, rmesa->clear.arrayObj); - -   radeon_meta_set_passthrough_transform(rmesa); - -   for (i = 0; i < 4; i++) { -      COPY_4FV(rmesa->clear.color[i], ctx->Color.ClearColor); -   } - -   /* convert clear Z from [0,1] to NDC coord in [-1,1] */ - -   dst_z = -1.0 + 2.0 * ctx->Depth.Clear; -   /* Prepare the vertices, which are the same regardless of which buffer we're -    * drawing to. -    */ -   rmesa->clear.vertices[0][0] = fb->_Xmin; -   rmesa->clear.vertices[0][1] = fb->_Ymin; -   rmesa->clear.vertices[0][2] = dst_z; -   rmesa->clear.vertices[1][0] = fb->_Xmax; -   rmesa->clear.vertices[1][1] = fb->_Ymin; -   rmesa->clear.vertices[1][2] = dst_z; -   rmesa->clear.vertices[2][0] = fb->_Xmax; -   rmesa->clear.vertices[2][1] = fb->_Ymax; -   rmesa->clear.vertices[2][2] = dst_z; -   rmesa->clear.vertices[3][0] = fb->_Xmin; -   rmesa->clear.vertices[3][1] = fb->_Ymax; -   rmesa->clear.vertices[3][2] = dst_z; - -   while (mask != 0) { -      GLuint this_mask = 0; -      GLuint color_bit; - -      color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS); -      if (color_bit != 0) -	 this_mask |= (1 << (color_bit - 1)); - -      /* Clear depth/stencil in the same pass as color. */ -      this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)); - -      /* Select the current color buffer and use the color write mask if -       * we have one, otherwise don't write any color channels. -       */ -      if (this_mask & BUFFER_BIT_FRONT_LEFT) -	 _mesa_DrawBuffer(GL_FRONT_LEFT); -      else if (this_mask & BUFFER_BIT_BACK_LEFT) -	 _mesa_DrawBuffer(GL_BACK_LEFT); -      else if (color_bit != 0) -	 _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0 + -			  (color_bit - BUFFER_COLOR0 - 1)); -      else -	 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - -      /* Control writing of the depth clear value to depth. */ -      if (this_mask & BUFFER_BIT_DEPTH) { -	 _mesa_DepthFunc(GL_ALWAYS); -	 _mesa_DepthMask(GL_TRUE); -	 _mesa_Enable(GL_DEPTH_TEST); -      } else { -	 _mesa_Disable(GL_DEPTH_TEST); -	 _mesa_DepthMask(GL_FALSE); -      } - -      /* Control writing of the stencil clear value to stencil. */ -      if (this_mask & BUFFER_BIT_STENCIL) { -	 _mesa_Enable(GL_STENCIL_TEST); -	 _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); -	 _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, (GLint)ctx->Stencil.Clear, -				   ctx->Stencil.WriteMask[0]); -      } else { -	 _mesa_Disable(GL_STENCIL_TEST); -      } - -      _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - -      mask &= ~this_mask; -   } - -   radeon_meta_restore_transform(rmesa); - -   _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture); -   if (saved_fp_enable) -      _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); -   if (saved_vp_enable) -      _mesa_Enable(GL_VERTEX_PROGRAM_ARB); - -   if (saved_shader_program) -      _mesa_UseProgramObjectARB(saved_shader_program); - -   _mesa_PopAttrib(); -     /* restore current array object */ -   _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave); -   _mesa_reference_array_object(ctx, &arraySave, NULL); +   meta_clear_tris(&rmesa->meta, mask);  } diff --git a/src/mesa/drivers/dri/radeon/radeon_common.h b/src/mesa/drivers/dri/radeon/radeon_common.h index ba6c7c5773..cebae18b2d 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.h +++ b/src/mesa/drivers/dri/radeon/radeon_common.h @@ -5,18 +5,7 @@  #include "radeon_dma.h"  #include "radeon_texture.h" - -#define TRI_CLEAR_COLOR_BITS (BUFFER_BIT_BACK_LEFT |			\ -			      BUFFER_BIT_FRONT_LEFT |			\ -			      BUFFER_BIT_COLOR0 |			\ -			      BUFFER_BIT_COLOR1 |			\ -			      BUFFER_BIT_COLOR2 |			\ -			      BUFFER_BIT_COLOR3 |			\ -			      BUFFER_BIT_COLOR4 |			\ -			      BUFFER_BIT_COLOR5 |			\ -			      BUFFER_BIT_COLOR6 |			\ -			      BUFFER_BIT_COLOR7) - +void radeonUserClear(GLcontext *ctx, GLuint mask);  void radeonRecalcScissorRects(radeonContextPtr radeon);  void radeonSetCliprects(radeonContextPtr radeon);  void radeonUpdateScissor( GLcontext *ctx ); diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c index 828d6477f0..9add50b4cc 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c @@ -184,6 +184,7 @@ GLboolean radeonInitContext(radeonContextPtr radeon,  	ctx = radeon->glCtx;  	driContextPriv->driverPrivate = radeon; +	meta_init_metaops(ctx, &radeon->meta);  	/* DRI fields */  	radeon->dri.context = driContextPriv;  	radeon->dri.screen = sPriv; @@ -264,7 +265,7 @@ void radeonDestroyContext(__DRIcontextPrivate *driContextPriv )  		}  		radeonReleaseArrays(radeon->glCtx, ~0); - +		meta_destroy_metaops(&radeon->meta);  		if (radeon->vtbl.free_context)  			radeon->vtbl.free_context(radeon->glCtx);  		_swsetup_DestroyContext( radeon->glCtx ); diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h index 036d2658d9..07ac85fb52 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h @@ -13,6 +13,7 @@  #include "dri_util.h"  #include "tnl/t_vertex.h" +#include "dri_metaops.h"  struct radeon_context;  #include "radeon_bocs_wrapper.h" @@ -476,27 +477,7 @@ struct radeon_context {      */     GLboolean is_front_buffer_reading; -   /* info for radeon_clear_tris() */ -   struct { -      struct gl_array_object *arrayObj; -      GLfloat vertices[4][3]; -      GLfloat color[4][4]; -   } clear; -   GLboolean internal_viewport_call; - -  struct { -      struct gl_fragment_program *bitmap_fp; -      struct gl_vertex_program *passthrough_vp; - -      struct gl_fragment_program *saved_fp; -      GLboolean saved_fp_enable; -      struct gl_vertex_program *saved_vp; -      GLboolean saved_vp_enable; - -      GLint saved_vp_x, saved_vp_y; -      GLsizei saved_vp_width, saved_vp_height; -      GLenum saved_matrix_mode; -   } meta; +   struct dri_metaops meta;     struct {  	   void (*get_lock)(radeonContextPtr radeon); diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c index 01c45df2df..a5e4df7941 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c @@ -445,11 +445,6 @@ void radeonEmitAOS( r100ContextPtr rmesa,   */  #define RADEON_MAX_CLEARS	256 -static void radeonUserClear(GLcontext *ctx, GLuint mask) -{ -   radeon_clear_tris(ctx, mask); -} -  static void radeonKernelClear(GLcontext *ctx, GLuint flags)  {       r100ContextPtr rmesa = R100_CONTEXT(ctx); | 
