Example #1
0
/* Allocates a region from rmesa->dma.current.  If there isn't enough
 * space in current, grab a new buffer (and discard what was left of current)
 */
void r200AllocDmaRegion( r200ContextPtr rmesa, 
			   struct r200_dma_region *region,
			   int bytes,
			   int alignment )
{
   if (R200_DEBUG & DEBUG_IOCTL)
      fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);

   if (rmesa->dma.flush)
      rmesa->dma.flush( rmesa );

   if (region->buf)
      r200ReleaseDmaRegion( rmesa, region, __FUNCTION__ );

   alignment--;
   rmesa->dma.current.start = rmesa->dma.current.ptr = 
      (rmesa->dma.current.ptr + alignment) & ~alignment;

   if ( rmesa->dma.current.ptr + bytes > rmesa->dma.current.end ) 
      r200RefillCurrentDmaRegion( rmesa );

   region->start = rmesa->dma.current.start;
   region->ptr = rmesa->dma.current.start;
   region->end = rmesa->dma.current.start + bytes;
   region->address = rmesa->dma.current.address;
   region->buf = rmesa->dma.current.buf;
   region->buf->refcount++;

   rmesa->dma.current.ptr += bytes; /* bug - if alignment > 7 */
   rmesa->dma.current.start = 
      rmesa->dma.current.ptr = (rmesa->dma.current.ptr + 0x7) & ~0x7;  

   assert( rmesa->dma.current.ptr <= rmesa->dma.current.end );
}
Example #2
0
void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs )
{
    GLuint unit;
    r200ContextPtr rmesa = R200_CONTEXT( ctx );

    /*    if (R200_DEBUG & DEBUG_VERTS)  */
    /*       _tnl_print_vert_flags( __FUNCTION__, newinputs ); */

    if (newinputs & VERT_BIT_POS)
        r200ReleaseDmaRegion( rmesa, &rmesa->tcl.obj, __FUNCTION__ );

    if (newinputs & VERT_BIT_NORMAL)
        r200ReleaseDmaRegion( rmesa, &rmesa->tcl.norm, __FUNCTION__ );

    if (newinputs & VERT_BIT_FOG)
        r200ReleaseDmaRegion( rmesa, &rmesa->tcl.fog, __FUNCTION__ );

    if (newinputs & VERT_BIT_COLOR0)
        r200ReleaseDmaRegion( rmesa, &rmesa->tcl.rgba, __FUNCTION__ );

    if (newinputs & VERT_BIT_COLOR1)
        r200ReleaseDmaRegion( rmesa, &rmesa->tcl.spec, __FUNCTION__ );

    for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
        if (newinputs & VERT_BIT_TEX(unit))
            r200ReleaseDmaRegion( rmesa, &rmesa->tcl.tex[unit], __FUNCTION__ );
    }
}
static void transition_to_hwtnl( GLcontext *ctx )
{
   r200ContextPtr rmesa = R200_CONTEXT(ctx);
   TNLcontext *tnl = TNL_CONTEXT(ctx);

   _tnl_need_projected_coords( ctx, GL_FALSE );

   r200UpdateMaterial( ctx );

   tnl->Driver.NotifyMaterialChange = r200UpdateMaterial;

   if ( rmesa->dma.flush )			
      rmesa->dma.flush( rmesa );	

   rmesa->dma.flush = NULL;
   
   if (rmesa->swtcl.indexed_verts.buf) 
      r200ReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts, 
			      __FUNCTION__ );

   R200_STATECHANGE( rmesa, vap );
   rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_TCL_ENABLE;
   rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~R200_VAP_FORCE_W_TO_ONE;

   if (ctx->VertexProgram._Enabled) {
      rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_PROG_VTX_SHADER_ENABLE;
   }

   if ( ((rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] & R200_FOG_USE_MASK)
      == R200_FOG_USE_SPEC_ALPHA) &&
      (ctx->Fog.FogCoordinateSource == GL_FOG_COORD )) {
      R200_STATECHANGE( rmesa, ctx );
      rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~R200_FOG_USE_MASK;
      rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |= R200_FOG_USE_VTX_FOG;
   }

   R200_STATECHANGE( rmesa, vte );
   rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] &= ~(R200_VTX_XY_FMT|R200_VTX_Z_FMT);
   rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] |= R200_VTX_W0_FMT;

   if (R200_DEBUG & DEBUG_FALLBACKS) 
      fprintf(stderr, "R200 end tcl fallback\n");
}
Example #4
0
static void r200UploadRectSubImage( r200ContextPtr rmesa,
				    r200TexObjPtr t, 
				    struct gl_texture_image *texImage,
				    GLint x, GLint y, 
				    GLint width, GLint height )
{
   const struct gl_texture_format *texFormat = texImage->TexFormat;
   int blit_format, dstPitch, done;

   switch ( texFormat->TexelBytes ) {
   case 1:
      blit_format = R200_CP_COLOR_FORMAT_CI8;
      break;
   case 2:
      blit_format = R200_CP_COLOR_FORMAT_RGB565;
      break;
   case 4:
      blit_format = R200_CP_COLOR_FORMAT_ARGB8888;
      break;
   default:
      return;
   }

   t->image[0][0].data = texImage->Data;

   /* Currently don't need to cope with small pitches.
    */
   width = texImage->Width;
   height = texImage->Height;
   dstPitch = t->pp_txpitch + 32;

   if (rmesa->prefer_gart_client_texturing && texImage->IsClientData) {
      /* In this case, could also use GART texturing.  This is
       * currently disabled, but has been tested & works.
       */
      if ( !t->image_override )
         t->pp_txoffset = r200GartOffsetFromVirtual( rmesa, texImage->Data );
      t->pp_txpitch = texImage->RowStride * texFormat->TexelBytes - 32;

      if (R200_DEBUG & DEBUG_TEXTURE)
	 fprintf(stderr, 
		 "Using GART texturing for rectangular client texture\n");

      /* Release FB memory allocated for this image:
       */
      /* FIXME This may not be correct as driSwapOutTextureObject sets
       * FIXME dirty_images.  It may be fine, though.
       */
      if ( t->base.memBlock ) {
	 driSwapOutTextureObject( (driTextureObject *) t );
      }
   }
   else if (texImage->IsClientData) {
      /* Data already in GART memory, with usable pitch.
       */
      GLuint srcPitch;
      srcPitch = texImage->RowStride * texFormat->TexelBytes;
      r200EmitBlit( rmesa, 
		    blit_format, 
		    srcPitch,
		    r200GartOffsetFromVirtual( rmesa, texImage->Data ),   
		    dstPitch, t->bufAddr,
		    0, 0, 
		    0, 0, 
		    width, height );
   }
   else {
      /* Data not in GART memory, or bad pitch.
       */
      for (done = 0; done < height ; ) {
	 struct r200_dma_region region;
	 int lines = MIN2( height - done, RADEON_BUFFER_SIZE / dstPitch );
	 int src_pitch;
	 char *tex;

         src_pitch = texImage->RowStride * texFormat->TexelBytes;

	 tex = (char *)texImage->Data + done * src_pitch;

	 memset(&region, 0, sizeof(region));
	 r200AllocDmaRegion( rmesa, &region, lines * dstPitch, 1024 );

	 /* Copy texdata to dma:
	  */
	 if (0)
	    fprintf(stderr, "%s: src_pitch %d dst_pitch %d\n",
		    __FUNCTION__, src_pitch, dstPitch);

	 if (src_pitch == dstPitch) {
	    memcpy( region.address + region.start, tex, lines * src_pitch );
	 } 
	 else {
	    char *buf = region.address + region.start;
	    int i;
	    for (i = 0 ; i < lines ; i++) {
	       memcpy( buf, tex, src_pitch );
	       buf += dstPitch;
	       tex += src_pitch;
	    }
	 }

	 r200EmitWait( rmesa, RADEON_WAIT_3D );

	 /* Blit to framebuffer
	  */
	 r200EmitBlit( rmesa,
		       blit_format,
		       dstPitch, GET_START( &region ),
		       dstPitch | (t->tile_bits >> 16),
		       t->bufAddr,
		       0, 0,
		       0, done,
		       width, lines );
	 
	 r200EmitWait( rmesa, RADEON_WAIT_2D );

	 r200ReleaseDmaRegion( rmesa, &region, __FUNCTION__ );
	 done += lines;
      }
   }
}
Example #5
0
/* Destroy the Mesa and driver specific context data.
 */
void r200DestroyContext( __DRIcontextPrivate *driContextPriv )
{
   GET_CURRENT_CONTEXT(ctx);
   r200ContextPtr rmesa = (r200ContextPtr) driContextPriv->driverPrivate;
   r200ContextPtr current = ctx ? R200_CONTEXT(ctx) : NULL;

   /* check if we're deleting the currently bound context */
   if (rmesa == current) {
      R200_FIREVERTICES( rmesa );
      _mesa_make_current(NULL, NULL, NULL);
   }

   /* Free r200 context resources */
   assert(rmesa); /* should never be null */
   if ( rmesa ) {
      GLboolean   release_texture_heaps;


      release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1);
      _swsetup_DestroyContext( rmesa->glCtx );
      _tnl_DestroyContext( rmesa->glCtx );
      _vbo_DestroyContext( rmesa->glCtx );
      _swrast_DestroyContext( rmesa->glCtx );

      r200DestroySwtcl( rmesa->glCtx );
      r200ReleaseArrays( rmesa->glCtx, ~0 );

      if (rmesa->dma.current.buf) {
	 r200ReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ );
	 r200FlushCmdBuf( rmesa, __FUNCTION__ );
      }

      if (rmesa->state.scissor.pClipRects) {
	 FREE(rmesa->state.scissor.pClipRects);
	 rmesa->state.scissor.pClipRects = NULL;
      }

      if ( release_texture_heaps ) {
         /* This share group is about to go away, free our private
          * texture object data.
          */
         int i;

         for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) {
	    driDestroyTextureHeap( rmesa->texture_heaps[ i ] );
	    rmesa->texture_heaps[ i ] = NULL;
         }

	 assert( is_empty_list( & rmesa->swapped ) );
      }

      /* free the Mesa context */
      rmesa->glCtx->DriverCtx = NULL;
      _mesa_destroy_context( rmesa->glCtx );

      /* free the option cache */
      driDestroyOptionCache (&rmesa->optionCache);

      FREE( rmesa );
   }
}
Example #6
0
void r200RefillCurrentDmaRegion( r200ContextPtr rmesa )
{
   struct r200_dma_buffer *dmabuf;
   int fd = rmesa->dri.fd;
   int index = 0;
   int size = 0;
   drmDMAReq dma;
   int ret;

   if (R200_DEBUG & (DEBUG_IOCTL|DEBUG_DMA))
      fprintf(stderr, "%s\n", __FUNCTION__);  

   if (rmesa->dma.flush) {
      rmesa->dma.flush( rmesa );
   }

   if (rmesa->dma.current.buf)
      r200ReleaseDmaRegion( rmesa, &rmesa->dma.current, __FUNCTION__ );

   if (rmesa->dma.nr_released_bufs > 4)
      r200FlushCmdBuf( rmesa, __FUNCTION__ );

   dma.context = rmesa->dri.hwContext;
   dma.send_count = 0;
   dma.send_list = NULL;
   dma.send_sizes = NULL;
   dma.flags = 0;
   dma.request_count = 1;
   dma.request_size = RADEON_BUFFER_SIZE;
   dma.request_list = &index;
   dma.request_sizes = &size;
   dma.granted_count = 0;

   LOCK_HARDWARE(rmesa);	/* no need to validate */

   while (1) {
      ret = drmDMA( fd, &dma );
      if (ret == 0)
	 break;
   
      if (rmesa->dma.nr_released_bufs) {
	 r200FlushCmdBufLocked( rmesa, __FUNCTION__ );
      }

      if (rmesa->do_usleeps) {
	 UNLOCK_HARDWARE( rmesa );
	 DO_USLEEP( 1 );
	 LOCK_HARDWARE( rmesa );
      }
   }

   UNLOCK_HARDWARE(rmesa);

   if (R200_DEBUG & DEBUG_DMA)
      fprintf(stderr, "Allocated buffer %d\n", index);

   dmabuf = CALLOC_STRUCT( r200_dma_buffer );
   dmabuf->buf = &rmesa->r200Screen->buffers->list[index];
   dmabuf->refcount = 1;

   rmesa->dma.current.buf = dmabuf;
   rmesa->dma.current.address = dmabuf->buf->address;
   rmesa->dma.current.end = dmabuf->buf->total;
   rmesa->dma.current.start = 0;
   rmesa->dma.current.ptr = 0;
}
Example #7
0
static void flush_prims( r200ContextPtr rmesa )
{
    int i,j;
    struct r200_dma_region tmp = rmesa->dma.current;

    tmp.buf->refcount++;
    tmp.aos_size = rmesa->vb.vertex_size;
    tmp.aos_stride = rmesa->vb.vertex_size;
    tmp.aos_start = GET_START(&tmp);

    rmesa->dma.current.ptr = rmesa->dma.current.start +=
                                 (rmesa->vb.initial_counter - rmesa->vb.counter) *
                                 rmesa->vb.vertex_size * 4;

    rmesa->tcl.vertex_format = rmesa->vb.vtxfmt_0;
    rmesa->tcl.aos_components[0] = &tmp;
    rmesa->tcl.nr_aos_components = 1;
    rmesa->dma.flush = NULL;

    /* Optimize the primitive list:
     */
    if (rmesa->vb.nrprims > 1) {
        for (j = 0, i = 1 ; i < rmesa->vb.nrprims; i++) {
            int pj = rmesa->vb.primlist[j].prim & 0xf;
            int pi = rmesa->vb.primlist[i].prim & 0xf;

            if (pj == pi && discreet_gl_prim[pj] &&
                    rmesa->vb.primlist[i].start == rmesa->vb.primlist[j].end) {
                rmesa->vb.primlist[j].end = rmesa->vb.primlist[i].end;
            }
            else {
                j++;
                if (j != i) rmesa->vb.primlist[j] = rmesa->vb.primlist[i];
            }
        }
        rmesa->vb.nrprims = j+1;
    }

    if (rmesa->vb.vtxfmt_0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] ||
            rmesa->vb.vtxfmt_1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) {
        R200_STATECHANGE( rmesa, vtx );
        rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = rmesa->vb.vtxfmt_0;
        rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = rmesa->vb.vtxfmt_1;
    }


    for (i = 0 ; i < rmesa->vb.nrprims; i++) {
        if (R200_DEBUG & DEBUG_PRIMS)
            fprintf(stderr, "vtxfmt prim %d: %s %d..%d\n", i,
                    _mesa_lookup_enum_by_nr( rmesa->vb.primlist[i].prim &
                                             PRIM_MODE_MASK ),
                    rmesa->vb.primlist[i].start,
                    rmesa->vb.primlist[i].end);

        if (rmesa->vb.primlist[i].start < rmesa->vb.primlist[i].end)
            r200EmitPrimitive( rmesa->glCtx,
                               rmesa->vb.primlist[i].start,
                               rmesa->vb.primlist[i].end,
                               rmesa->vb.primlist[i].prim );
    }

    rmesa->vb.nrprims = 0;
    r200ReleaseDmaRegion( rmesa, &tmp, __FUNCTION__ );
}