Пример #1
0
static void r300DrawPrims(GLcontext *ctx,
			 const struct gl_client_array *arrays[],
			 const struct _mesa_prim *prim,
			 GLuint nr_prims,
			 const struct _mesa_index_buffer *ib,
			 GLboolean index_bounds_valid,
			 GLuint min_index,
			 GLuint max_index)
{
	GLboolean retval;

	/* This check should get folded into just the places that
	 * min/max index are really needed.
	 */
	if (!index_bounds_valid) {
		vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
	}

	if (min_index) {
		radeon_print(RADEON_FALLBACKS, RADEON_IMPORTANT,
				"%s: Rebasing primitives. %p nr_prims %d min_index %u max_index %u\n",
				__func__, prim, nr_prims, min_index, max_index);
		vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib, min_index, max_index, r300DrawPrims );
		return;
	}

	/* Make an attempt at drawing */
	retval = r300TryDrawPrims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);

	/* If failed run tnl pipeline - it should take care of fallbacks */
	if (!retval)
		_tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
}
Пример #2
0
void brw_draw_prims( GLcontext *ctx,
		     const struct gl_client_array *arrays[],
		     const struct _mesa_prim *prim,
		     GLuint nr_prims,
		     const struct _mesa_index_buffer *ib,
		     GLuint min_index,
		     GLuint max_index )
{
   struct intel_context *intel = intel_context(ctx);
   GLboolean retval;

   /* Decide if we want to rebase.  If so we end up recursing once
    * only into this function.
    */
   if (brw_need_rebase( ctx, arrays, ib, min_index )) {
      vbo_rebase_prims( ctx, arrays, 
			prim, nr_prims, 
			ib, min_index, max_index, 
			brw_draw_prims );
      
      return;
   }


   /* Make a first attempt at drawing:
    */
   retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);

   
   /* This looks like out-of-memory but potentially we have
    * situation where there is enough memory but it has become
    * fragmented.  Clear out all heaps and start from scratch by
    * faking a contended lock event:  (done elsewhere)
    */
   if (!retval && !intel->Fallback && bmError(intel)) {
      DBG("retrying\n");
      /* Then try a second time only to upload textures and draw the
       * primitives:
       */
      retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
   }

   /* Otherwise, we really are out of memory.  Pass the drawing
    * command to the software tnl module and which will in turn call
    * swrast to do the drawing.
    */
   if (!retval) {
       _swsetup_Wakeup(ctx);
      _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
   }

   if (intel->aub_file && (INTEL_DEBUG & DEBUG_SYNC)) {
      intelFinish( &intel->ctx );
      intel->aub_wrap = 1;
   }
}
Пример #3
0
void brw_draw_prims( struct gl_context *ctx,
		     const struct _mesa_prim *prim,
		     GLuint nr_prims,
		     const struct _mesa_index_buffer *ib,
		     GLboolean index_bounds_valid,
		     GLuint min_index,
		     GLuint max_index,
		     struct gl_transform_feedback_object *tfb_vertcount )
{
   const struct gl_client_array **arrays = ctx->Array._DrawArrays;
   bool retval;

   if (!_mesa_check_conditional_render(ctx))
      return;

   /* Handle primitive restart if needed */
   if (brw_handle_primitive_restart(ctx, prim, nr_prims, ib)) {
      /* The draw was handled, so we can exit now */
      return;
   }

   if (!vbo_all_varyings_in_vbos(arrays)) {
      if (!index_bounds_valid)
	 vbo_get_minmax_indices(ctx, prim, ib, &min_index, &max_index, nr_prims);

      /* Decide if we want to rebase.  If so we end up recursing once
       * only into this function.
       */
      if (min_index != 0 && !vbo_any_varyings_in_vbos(arrays)) {
	 vbo_rebase_prims(ctx, arrays,
			  prim, nr_prims,
			  ib, min_index, max_index,
			  brw_draw_prims );
	 return;
      }
   }

   /* Make a first attempt at drawing:
    */
   retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);

   /* Otherwise, we really are out of memory.  Pass the drawing
    * command to the software tnl module and which will in turn call
    * swrast to do the drawing.
    */
   if (!retval) {
       _swsetup_Wakeup(ctx);
       _tnl_wakeup(ctx);
      _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
   }

}
Пример #4
0
void brw_draw_prims( struct gl_context *ctx,
		     const struct gl_client_array *arrays[],
		     const struct _mesa_prim *prim,
		     GLuint nr_prims,
		     const struct _mesa_index_buffer *ib,
		     GLboolean index_bounds_valid,
		     GLuint min_index,
		     GLuint max_index )
{
   GLboolean retval;

   if (!_mesa_check_conditional_render(ctx))
      return;

   if (!vbo_all_varyings_in_vbos(arrays)) {
      if (!index_bounds_valid)
	 vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);

      /* Decide if we want to rebase.  If so we end up recursing once
       * only into this function.
       */
      if (min_index != 0 && !vbo_any_varyings_in_vbos(arrays)) {
	 vbo_rebase_prims(ctx, arrays,
			  prim, nr_prims,
			  ib, min_index, max_index,
			  brw_draw_prims );
	 return;
      }
   }

   /* Make a first attempt at drawing:
    */
   retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);

   /* Otherwise, we really are out of memory.  Pass the drawing
    * command to the software tnl module and which will in turn call
    * swrast to do the drawing.
    */
   if (!retval) {
       _swsetup_Wakeup(ctx);
       _tnl_wakeup(ctx);
      _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
   }

}
Пример #5
0
static void evergreenDrawPrims(GLcontext *ctx,
			  const struct gl_client_array *arrays[],
			  const struct _mesa_prim *prim,
			  GLuint nr_prims,
			  const struct _mesa_index_buffer *ib,
			  GLboolean index_bounds_valid,
			  GLuint min_index,
			  GLuint max_index)
{
	GLboolean retval = GL_FALSE;

	context_t *context = EVERGREEN_CONTEXT(ctx);
	radeonContextPtr radeon = &context->radeon;
	radeon_prepare_render(radeon);

	/* This check should get folded into just the places that
	 * min/max index are really needed.
	 */
	if (!vbo_all_varyings_in_vbos(arrays)) {
		if (!index_bounds_valid)
			vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
		/* do we want to rebase, minimizes the 
		 * amount of data to upload? */
		if (min_index) {
			vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib, min_index, max_index, evergreenDrawPrims );
			return;
		}
	}
	/* Make an attempt at drawing */
	retval = evergreenTryDrawPrims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);

	/* If failed run tnl pipeline - it should take care of fallbacks */
	if (!retval) {
		_swsetup_Wakeup(ctx);
		_tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
	}
}
Пример #6
0
void brw_draw_prims( GLcontext *ctx,
		     const struct gl_client_array *arrays[],
		     const struct _mesa_prim *prim,
		     GLuint nr_prims,
		     const struct _mesa_index_buffer *ib,
		     GLuint min_index,
		     GLuint max_index )
{
   GLboolean retval;

   /* Decide if we want to rebase.  If so we end up recursing once
    * only into this function.
    */
   if (brw_need_rebase( ctx, arrays, ib, min_index )) {
      vbo_rebase_prims( ctx, arrays, 
			prim, nr_prims, 
			ib, min_index, max_index, 
			brw_draw_prims );
      
      return;
   }


   /* Make a first attempt at drawing:
    */
   retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);

   /* Otherwise, we really are out of memory.  Pass the drawing
    * command to the software tnl module and which will in turn call
    * swrast to do the drawing.
    */
   if (!retval) {
       _swsetup_Wakeup(ctx);
      _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
   }
}
Пример #7
0
/* This is the main entrypoint into the slimmed-down software tnl
 * module.  In a regular swtnl driver, this can be plugged straight
 * into the vbo->Driver.DrawPrims() callback.
 */
void _tnl_draw_prims( struct gl_context *ctx,
		      const struct gl_client_array *arrays[],
		      const struct _mesa_prim *prim,
		      GLuint nr_prims,
		      const struct _mesa_index_buffer *ib,
		      GLuint min_index,
		      GLuint max_index)
{
   TNLcontext *tnl = TNL_CONTEXT(ctx);
   const GLuint TEST_SPLIT = 0;
   const GLint max = TEST_SPLIT ? 8 : tnl->vb.Size - MAX_CLIPPED_VERTICES;
   GLint max_basevertex = prim->basevertex;
   GLuint i;

   /* Mesa core state should have been validated already */
   assert(ctx->NewState == 0x0);

   if (!_mesa_check_conditional_render(ctx))
      return; /* don't draw */

   for (i = 1; i < nr_prims; i++)
      max_basevertex = MAX2(max_basevertex, prim[i].basevertex);

   if (0)
   {
      printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
      for (i = 0; i < nr_prims; i++)
	 printf("prim %d: %s start %d count %d\n", i, 
		_mesa_lookup_enum_by_nr(prim[i].mode),
		prim[i].start,
		prim[i].count);
   }

   if (min_index) {
      /* We always translate away calls with min_index != 0. 
       */
      vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib, 
			min_index, max_index,
			_tnl_vbo_draw_prims );
      return;
   }
   else if ((GLint)max_index + max_basevertex > max) {
      /* The software TNL pipeline has a fixed amount of storage for
       * vertices and it is necessary to split incoming drawing commands
       * if they exceed that limit.
       */
      struct split_limits limits;
      limits.max_verts = max;
      limits.max_vb_size = ~0;
      limits.max_indices = ~0;

      /* This will split the buffers one way or another and
       * recursively call back into this function.
       */
      vbo_split_prims( ctx, arrays, prim, nr_prims, ib, 
		       0, max_index + prim->basevertex,
		       _tnl_vbo_draw_prims,
		       &limits );
   }
   else {
      /* May need to map a vertex buffer object for every attribute plus
       * one for the index buffer.
       */
      struct gl_buffer_object *bo[VERT_ATTRIB_MAX + 1];
      GLuint nr_bo = 0;
      GLuint inst;

      for (i = 0; i < nr_prims;) {
	 GLuint this_nr_prims;

	 /* Our SW TNL pipeline doesn't handle basevertex yet, so bind_indices
	  * will rebase the elements to the basevertex, and we'll only
	  * emit strings of prims with the same basevertex in one draw call.
	  */
	 for (this_nr_prims = 1; i + this_nr_prims < nr_prims;
	      this_nr_prims++) {
	    if (prim[i].basevertex != prim[i + this_nr_prims].basevertex)
	       break;
	 }

         assert(prim[i].num_instances > 0);

	 /* Binding inputs may imply mapping some vertex buffer objects.
	  * They will need to be unmapped below.
	  */
         for (inst = 0; inst < prim[i].num_instances; inst++) {

            bind_prims(ctx, &prim[i], this_nr_prims);
            bind_inputs(ctx, arrays, max_index + prim[i].basevertex + 1,
                        bo, &nr_bo);
            bind_indices(ctx, ib, bo, &nr_bo);

            tnl->CurInstance = inst;
            TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx);

            unmap_vbos(ctx, bo, nr_bo);
            free_space(ctx);
         }

	 i += this_nr_prims;
      }
   }
}
Пример #8
0
/* This is the main entrypoint into the slimmed-down software tnl
 * module.  In a regular swtnl driver, this can be plugged straight
 * into the vbo->Driver.DrawPrims() callback.
 */
void _tnl_draw_prims( GLcontext *ctx,
		      const struct gl_client_array *arrays[],
		      const struct _mesa_prim *prim,
		      GLuint nr_prims,
		      const struct _mesa_index_buffer *ib,
		      GLuint min_index,
		      GLuint max_index)
{
   TNLcontext *tnl = TNL_CONTEXT(ctx);
   const GLuint TEST_SPLIT = 0;
   const GLint max = TEST_SPLIT ? 8 : tnl->vb.Size - MAX_CLIPPED_VERTICES;

   if (0)
   {
      GLuint i;
      _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
      for (i = 0; i < nr_prims; i++)
	 _mesa_printf("prim %d: %s start %d count %d\n", i, 
		      _mesa_lookup_enum_by_nr(prim[i].mode),
		      prim[i].start,
		      prim[i].count);
   }

   if (min_index) {
      /* We always translate away calls with min_index != 0. 
       */
      vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib, 
			min_index, max_index,
			_tnl_draw_prims );
      return;
   }
   else if (max_index >= max) {
      /* The software TNL pipeline has a fixed amount of storage for
       * vertices and it is necessary to split incoming drawing commands
       * if they exceed that limit.
       */
      struct split_limits limits;
      limits.max_verts = max;
      limits.max_vb_size = ~0;
      limits.max_indices = ~0;

      /* This will split the buffers one way or another and
       * recursively call back into this function.
       */
      vbo_split_prims( ctx, arrays, prim, nr_prims, ib, 
		       0, max_index,
		       _tnl_draw_prims,
		       &limits );
   }
   else {
      /* May need to map a vertex buffer object for every attribute plus
       * one for the index buffer.
       */
      struct gl_buffer_object *bo[VERT_ATTRIB_MAX + 1];
      GLuint nr_bo = 0;

      /* Binding inputs may imply mapping some vertex buffer objects.
       * They will need to be unmapped below.
       */
      bind_inputs(ctx, arrays, max_index+1, bo, &nr_bo);
      bind_indices(ctx, ib, bo, &nr_bo);
      bind_prims(ctx, prim, nr_prims );

      TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx);

      unmap_vbos(ctx, bo, nr_bo);
      free_space(ctx);
   }
}