Ejemplo n.º 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 );
}
Ejemplo n.º 2
0
/* Begin/End
 */
static void r200_Begin( GLenum mode )
{
    GET_CURRENT_CONTEXT(ctx);
    r200ContextPtr rmesa = R200_CONTEXT(ctx);

    if (R200_DEBUG & DEBUG_VFMT)
        fprintf(stderr, "%s( %s )\n", __FUNCTION__,
                _mesa_lookup_enum_by_nr( mode ));

    if (mode > GL_POLYGON) {
        _mesa_error( ctx, GL_INVALID_ENUM, "glBegin" );
        return;
    }

    if (rmesa->vb.prim[0] != GL_POLYGON+1) {
        _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" );
        return;
    }

    if (ctx->NewState)
        _mesa_update_state( ctx );

    if (rmesa->NewGLState)
        r200ValidateState( ctx );

    if (rmesa->vb.recheck)
        r200VtxfmtValidate( ctx );

    if (!rmesa->vb.installed) {
        CALL_Begin(GET_DISPATCH(), (mode));
        return;
    }


    if (rmesa->dma.flush && rmesa->vb.counter < 12) {
        if (R200_DEBUG & DEBUG_VFMT)
            fprintf(stderr, "%s: flush almost-empty buffers\n", __FUNCTION__);
        flush_prims( rmesa );
    }

    /* Need to arrange to save vertices here?  Or always copy from dma (yuk)?
     */
    if (!rmesa->dma.flush) {
        if (rmesa->dma.current.ptr + 12*rmesa->vb.vertex_size*4 >
                rmesa->dma.current.end) {
            R200_NEWPRIM( rmesa );
            r200RefillCurrentDmaRegion( rmesa );
        }

        rmesa->vb.dmaptr = (int *)(rmesa->dma.current.address + rmesa->dma.current.ptr);
        rmesa->vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) /
                            (rmesa->vb.vertex_size * 4);
        rmesa->vb.counter--;
        rmesa->vb.initial_counter = rmesa->vb.counter;
        rmesa->vb.notify = wrap_buffer;
        rmesa->dma.flush = flush_prims;
        ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
    }


    rmesa->vb.prim[0] = mode;
    start_prim( rmesa, mode | PRIM_BEGIN );
}
Ejemplo n.º 3
0
static void wrap_buffer( void )
{
    GET_CURRENT_CONTEXT(ctx);
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    GLfloat tmp[3][R200_MAX_VERTEX_SIZE];
    GLuint i, nrverts;

    if (R200_DEBUG & (DEBUG_VFMT|DEBUG_PRIMS))
        fprintf(stderr, "%s %d\n", __FUNCTION__,
                rmesa->vb.initial_counter - rmesa->vb.counter);

    /* Don't deal with parity.
     */
    if ((((rmesa->vb.initial_counter - rmesa->vb.counter) -
            rmesa->vb.primlist[rmesa->vb.nrprims].start) & 1)) {
        rmesa->vb.counter++;
        rmesa->vb.initial_counter++;
        return;
    }

    /* Copy vertices out of dma:
     */
    if (rmesa->vb.prim[0] == GL_POLYGON+1)
        nrverts = 0;
    else {
        nrverts = copy_dma_verts( rmesa, tmp );

        if (R200_DEBUG & DEBUG_VFMT)
            fprintf(stderr, "%d vertices to copy\n", nrverts);

        /* Finish the prim at this point:
         */
        note_last_prim( rmesa, 0 );
    }

    /* Fire any buffered primitives
     */
    flush_prims( rmesa );

    /* Get new buffer
     */
    r200RefillCurrentDmaRegion( rmesa );

    /* Reset counter, dmaptr
     */
    rmesa->vb.dmaptr = (int *)(rmesa->dma.current.ptr + rmesa->dma.current.address);
    rmesa->vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) /
                        (rmesa->vb.vertex_size * 4);
    rmesa->vb.counter--;
    rmesa->vb.initial_counter = rmesa->vb.counter;
    rmesa->vb.notify = wrap_buffer;

    rmesa->dma.flush = flush_prims;

    /* Restart wrapped primitive:
     */
    if (rmesa->vb.prim[0] != GL_POLYGON+1)
        start_prim( rmesa, rmesa->vb.prim[0] );


    /* Reemit saved vertices
     */
    for (i = 0 ; i < nrverts; i++) {
        if (R200_DEBUG & DEBUG_VERTS) {
            int j;
            fprintf(stderr, "re-emit vertex %d to %p\n", i,
                    (void *)rmesa->vb.dmaptr);
            if (R200_DEBUG & DEBUG_VERBOSE)
                for (j = 0 ; j < rmesa->vb.vertex_size; j++)
                    fprintf(stderr, "\t%08x/%f\n", *(int*)&tmp[i][j], tmp[i][j]);
        }

        memcpy( rmesa->vb.dmaptr, tmp[i], rmesa->vb.vertex_size * 4 );
        rmesa->vb.dmaptr += rmesa->vb.vertex_size;
        rmesa->vb.counter--;
    }
}