Пример #1
0
/**
 * 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);
}
Пример #2
0
/**
 * Helper for _mesa_BindVertexArray() and _mesa_BindVertexArrayAPPLE().
 * \param genRequired  specifies behavour when id was not generated with
 *                     glGenVertexArrays().
 */
static void
bind_vertex_array(struct gl_context *ctx, GLuint id, GLboolean genRequired)
{
   struct gl_array_object * const oldObj = ctx->Array.ArrayObj;
   struct gl_array_object *newObj = NULL;
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   ASSERT(oldObj != NULL);

   if ( oldObj->Name == id )
      return;   /* rebinding the same array object- no change */

   /*
    * Get pointer to new array object (newObj)
    */
   if (id == 0) {
      /* The spec says there is no array object named 0, but we use
       * one internally because it simplifies things.
       */
      newObj = ctx->Array.DefaultArrayObj;
   }
   else {
      /* non-default array object */
      newObj = lookup_arrayobj(ctx, id);
      if (!newObj) {
         if (genRequired) {
            _mesa_error(ctx, GL_INVALID_OPERATION, "glBindVertexArray(id)");
            return;
         }

         /* For APPLE version, generate a new array object now */
	 newObj = (*ctx->Driver.NewArrayObject)(ctx, id);
         if (!newObj) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindVertexArrayAPPLE");
            return;
         }

         save_array_object(ctx, newObj);
      }

      if (!newObj->_Used) {
         /* The "Interactions with APPLE_vertex_array_object" section of the
          * GL_ARB_vertex_array_object spec says:
          *
          *     "The first bind call, either BindVertexArray or
          *     BindVertexArrayAPPLE, determines the semantic of the object."
          */
         newObj->ARBsemantics = genRequired;
         newObj->_Used = GL_TRUE;
      }
   }

   ctx->NewState |= _NEW_ARRAY;
   ctx->Array.NewState |= VERT_BIT_ALL;
   _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, newObj);

   /* Pass BindVertexArray call to device driver */
   if (ctx->Driver.BindArrayObject && newObj)
      ctx->Driver.BindArrayObject(ctx, newObj);
}
Пример #3
0
/**
 * Initialize vertex array state for given context.
 */
void 
_mesa_init_varray(struct gl_context *ctx)
{
   ctx->Array.DefaultArrayObj = _mesa_new_array_object(ctx, 0);
   _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj,
                                ctx->Array.DefaultArrayObj);

   ctx->Array.Objects = _mesa_NewHashTable();
}
Пример #4
0
/**
 * Initialize vertex array state for given context.
 */
void 
_mesa_init_varray(struct gl_context *ctx)
{
   ctx->Array.DefaultArrayObj = ctx->Driver.NewArrayObject(ctx, 0);
   _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj,
                                ctx->Array.DefaultArrayObj);
   ctx->Array.ActiveTexture = 0;   /* GL_ARB_multitexture */

   ctx->Array.Objects = _mesa_NewHashTable();
}
Пример #5
0
/**
 * Delete a set of array objects.
 * 
 * \param n      Number of array objects to delete.
 * \param ids    Array of \c n array object IDs.
 */
void GLAPIENTRY
_mesa_DeleteVertexArraysAPPLE(GLsizei n, const GLuint *ids)
{
   GET_CURRENT_CONTEXT(ctx);
   GLsizei i;
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (n < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteVertexArrayAPPLE(n)");
      return;
   }

   for (i = 0; i < n; i++) {
      struct gl_array_object *obj = lookup_arrayobj(ctx, ids[i]);

      if ( obj != NULL ) {
	 ASSERT( obj->Name == ids[i] );

	 /* If the array object is currently bound, the spec says "the binding
	  * for that object reverts to zero and the default vertex array
	  * becomes current."
	  */
	 if ( obj == ctx->Array.ArrayObj ) {
	    CALL_BindVertexArrayAPPLE( ctx->Exec, (0) );
	 }

	 /* The ID is immediately freed for re-use */
	 remove_array_object(ctx, obj);

         /* Unreference the array object. 
          * If refcount hits zero, the object will be deleted.
          */
         _mesa_reference_array_object(ctx, &obj, NULL);
      }
   }
}
Пример #6
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.
 */
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_CURRENT_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, 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;

   /* 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 */
   _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave);
   _mesa_reference_array_object(ctx, &arraySave, NULL);
}