Get batchbuffers working natively again. This code still

relies over-heavily on the DRI lock to protect offsets in the
command stream from changing before being queued on the ring,
and should be viewed as being a pretty temporary mechanism
before a more robust alternative is implemented, most likely
based on a batchbuffer relocation list that will be used
to patch prebuilt batchbuffers after validation takes place.
This commit is contained in:
Keith Whitwell 2006-02-01 15:54:42 +00:00
parent 2fd2910010
commit a97a1439ae
19 changed files with 174 additions and 124 deletions

View file

@ -29,7 +29,6 @@ DRIVER_SOURCES = \
intel_context.c \
intel_ioctl.c \
intel_pixel.c \
intel_render.c \
intel_screen.c \
intel_span.c \
intel_state.c \
@ -37,6 +36,7 @@ DRIVER_SOURCES = \
DISABLED = \
intel_render.c \
i830_context.c \
i830_metaops.c \
i830_state.c \

View file

@ -137,7 +137,7 @@ int bmValidateBufferList( struct bufmgr *,
struct bm_buffer_list *,
unsigned flags );
void bmFenceBufferList( struct bufmgr *,
unsigned bmFenceBufferList( struct bufmgr *,
struct bm_buffer_list * );
void bmFreeBufferList( struct bm_buffer_list * );

View file

@ -166,6 +166,7 @@ static int bmAllocMem( struct bufmgr *bm,
if (buf->block)
buf->block->buf = buf;
assert(buf->block);
return buf->block != NULL;
}
@ -255,6 +256,8 @@ static int move_buffers( struct bufmgr *bm,
if (flags & BM_NO_UPLOAD)
goto cleanup;
assert(!buffers[i]->mapped);
DBG("try to move buffer %d size 0x%x to pools 0x%x\n",
buffers[i]->id, buffers[i]->size, flags & BM_MEM_MASK);
@ -308,7 +311,7 @@ static int move_buffers( struct bufmgr *bm,
free_block(bm, newMem[i]);
}
DBG("%s - fail\n", __FUNCTION__);
_mesa_printf("%s - fail\n", __FUNCTION__);
return 0;
}
@ -538,6 +541,8 @@ void bmBufferData(struct bufmgr *bm,
DBG("bmBufferData %d sz 0x%x data: %p\n", buffer, size, data);
assert(!buf->mapped);
if (buf->block) {
if ((buf->block->mem_type != BM_MEM_LOCAL && !bmTestFence(bm, buf->block->fence)) ||
(buf->size && buf->size != size) ||
@ -699,6 +704,7 @@ int bmValidateBufferList( struct bufmgr *bm,
if (!delayed_free(bm) &&
!evict_lru(bm, flags))
return 0;
exit(1);
}
@ -706,7 +712,8 @@ int bmValidateBufferList( struct bufmgr *bm,
DBG("%d: buf %d ofs 0x%x\n",
i, bufs[i]->id, bufs[i]->block->mem->ofs);
list->elem[i].offset_return[0] = bufs[i]->block->mem->ofs;
if (list->elem[i].offset_return)
list->elem[i].offset_return[0] = bufs[i]->block->mem->ofs;
if (list->elem[i].memtype_return)
list->elem[i].memtype_return[0] = bufs[i]->block->mem_type;
@ -724,7 +731,7 @@ int bmValidateBufferList( struct bufmgr *bm,
* The buffer manager knows how to emit and test fences directly
* through the drm and without callbacks or whatever into the driver.
*/
void bmFenceBufferList( struct bufmgr *bm, struct bm_buffer_list *list )
unsigned bmFenceBufferList( struct bufmgr *bm, struct bm_buffer_list *list )
{
DBG("%s (%d bufs)\n", __FUNCTION__, list->nr);
@ -741,7 +748,11 @@ void bmFenceBufferList( struct bufmgr *bm, struct bm_buffer_list *list )
move_to_head(&buf->block->pool->lru, buf->block);
buf->block->fence = fence;
}
return fence;
}
else
return 0;
}
@ -761,6 +772,9 @@ unsigned bmSetFence( struct bufmgr *bm )
int bmTestFence( struct bufmgr *bm, unsigned fence )
{
/* if (fence % 1024 == 0) */
/* _mesa_printf("%d %d\n", fence, bm->intel->sarea->last_dispatch); */
return fence <= bm->intel->sarea->last_dispatch;
}

View file

@ -442,7 +442,7 @@ i830TryTextureReadPixels( GLcontext *ctx,
int textureFormat;
GLenum glTextureFormat;
int src_offset = i830->meta.Buffer[I830_DESTREG_CBUFADDR2];
int destOffset = intelAgpOffsetFromVirtual( &i830->intel, pixels);
int destOffset = 0;
int destFormat, depthFormat, destPitch;
drm_clip_rect_t tmp;
@ -596,7 +596,7 @@ i830TryTextureDrawPixels( GLcontext *ctx,
int textureFormat;
GLenum glTextureFormat;
int dst_offset = i830->meta.Buffer[I830_DESTREG_CBUFADDR2];
int src_offset = intelAgpOffsetFromVirtual( intel, pixels );
int src_offset = 0;
if (INTEL_DEBUG & DEBUG_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);

View file

@ -109,7 +109,7 @@ GLboolean i915CreateContext( const __GLcontextModes *mesaVis,
if (!i915) return GL_FALSE;
_mesa_printf( "\ntexmem branch\n\n");
_mesa_printf( "\ntexmem branch (i915)\n\n");
i915InitVtbl( i915 );
@ -167,6 +167,7 @@ GLboolean i915CreateContext( const __GLcontextModes *mesaVis,
intelScreen->depth.pitch,
intelScreen->height);
intelInitBatchBuffer(intel);
/* Advertise the full hardware capabilities. The new memory
* manager should cope much better with overload situations:

View file

@ -43,6 +43,7 @@
#define I915_UPLOAD_PROGRAM 0x8
#define I915_UPLOAD_CONSTANTS 0x10
#define I915_UPLOAD_FOG 0x20
#define I915_UPLOAD_INVARIENT 0x40
#define I915_UPLOAD_TEX(i) (0x00010000<<(i))
#define I915_UPLOAD_TEX_ALL (0x00ff0000)
#define I915_UPLOAD_TEX_0_SHIFT 16

View file

@ -237,6 +237,11 @@ static void i915_emit_state( intelContextPtr intel )
if (VERBOSE)
fprintf(stderr, "%s dirty: %x\n", __FUNCTION__, dirty);
if (dirty & I915_UPLOAD_INVARIENT) {
if (VERBOSE) fprintf(stderr, "I915_UPLOAD_INVARIENT:\n");
i915_emit_invarient_state( intel );
}
if (dirty & I915_UPLOAD_CTX) {
if (VERBOSE) fprintf(stderr, "I915_UPLOAD_CTX:\n");
emit( i915, state->Ctx, sizeof(state->Ctx) );

View file

@ -37,6 +37,7 @@
#include "intel_batchbuffer.h"
#include "intel_context.h"
#include "bufmgr.h"
@ -59,6 +60,9 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
intelFlush( &intel->ctx );
LOCK_HARDWARE( intel );
intelInstallBatchBuffer(intel);
intelValidateBuffers( intel );
{
intelScreenPrivate *intelScreen = intel->intelScreen;
__DRIdrawablePrivate *dPriv = intel->driDrawable;
@ -117,6 +121,8 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
}
}
intelFlushBatchLocked( intel, GL_TRUE, GL_TRUE, GL_TRUE );
assert(intel->buffer_list == NULL);
UNLOCK_HARDWARE( intel );
}
@ -273,6 +279,8 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all,
intelFlush( &intel->ctx );
LOCK_HARDWARE( intel );
intelInstallBatchBuffer(intel);
intelValidateBuffers( intel );
{
/* flip top to bottom */
cy = intel->driDrawable->h-cy1-ch;
@ -362,60 +370,72 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all,
void intelDestroyBatchBuffer( GLcontext *ctx )
void intelDestroyBatchBuffer( struct intel_context *intel )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
if (intel->alloc.ptr) {
intelFreeAGP( intel, intel->alloc.ptr );
intel->alloc.ptr = 0;
}
}
void intelInitBatchBuffer( GLcontext *ctx )
void intelInstallBatchBuffer( struct intel_context *intel )
{
intelContextPtr intel = INTEL_CONTEXT(ctx);
assert(!intel->batch.ptr);
/* AGP allocation won't work:
intel->alloc.current++;
intel->alloc.current %= INTEL_ALLOC_NR;
DBG("%s: %d\n", __FUNCTION__, intel->alloc.current);
intel->batch.size = INTEL_ALLOC_SIZE;
intel->batch.space = intel->batch.size;
intel->batch.start_offset = 0;
intel->batch.ptr = bmMapBuffer( intel->bm,
intel->alloc.buffer[intel->alloc.current],
BM_WRITE | BM_MEM_AGP );
assert(!intel->buffer_list);
intel->buffer_list = bmNewBufferList();
/* Add the batchbuffer
*/
if (1 || !intel->intelScreen->allow_batchbuffer || getenv("INTEL_NO_BATCH")) {
intel->alloc.size = 8 * 1024;
intel->alloc.ptr = malloc( intel->alloc.size );
intel->alloc.offset = 0;
}
else {
switch (intel->intelScreen->deviceID) {
case PCI_CHIP_I865_G:
/* HW bug? Seems to crash if batchbuffer crosses 4k boundary.
*/
intel->alloc.size = 8 * 1024;
break;
default:
/* This is the smallest amount of memory the kernel deals with.
* We'd ideally like to make this smaller.
*/
intel->alloc.size = 1 << intel->intelScreen->logTextureGranularity;
break;
bmAddBuffer(intel->buffer_list,
intel->alloc.buffer[intel->alloc.current],
BM_READ,
NULL,
&intel->batch.start_offset);
if (0) {
static int foo;
if (foo++ > 10) {
_mesa_printf("foo\n");
exit(1);
}
intel->alloc.ptr = intelAllocateAGP( intel, intel->alloc.size );
if (intel->alloc.ptr)
intel->alloc.offset =
intelAgpOffsetFromVirtual( intel, intel->alloc.ptr );
}
if (!intel->alloc.ptr) {
FALLBACK(intel, INTEL_FALLBACK_NO_BATCHBUFFER, 1);
}
else {
intel->prim.flush = 0;
intel->vtbl.emit_invarient_state( intel );
/* Make sure this gets to the hardware, even if we have no cliprects:
*/
LOCK_HARDWARE( intel );
intelFlushBatchLocked( intel, GL_TRUE, GL_FALSE, GL_TRUE );
UNLOCK_HARDWARE( intel );
}
}
void intelInitBatchBuffer( struct intel_context *intel )
{
GLint i;
_mesa_printf("%s: %d\n", __FUNCTION__, intel->alloc.current);
bmGenBuffers(intel->bm,
INTEL_ALLOC_NR,
intel->alloc.buffer);
for (i = 0; i < INTEL_ALLOC_NR; i++)
bmBufferData(intel->bm,
intel->alloc.buffer[i],
INTEL_ALLOC_SIZE,
NULL,
BM_MEM_AGP);
}
void intelValidateBuffers( struct intel_context *intel )
{
if (!bmValidateBufferList(intel->bm, intel->buffer_list, BM_MEM_AGP))
assert(0);
}

View file

@ -42,6 +42,7 @@ do { \
if (VERBOSE) fprintf(stderr, \
"BEGIN_BATCH(%d) in %s, %d dwords free\n", \
(n), __FUNCTION__, intel->batch.space/4); \
assert(intel->locked); \
if (intel->batch.space < (n)*4) \
intelFlushBatch(intel, GL_TRUE); \
batch_ptr = intel->batch.ptr; \
@ -62,8 +63,11 @@ do { \
assert(intel->batch.space >= 0); \
} while(0)
extern void intelInitBatchBuffer( GLcontext *ctx );
extern void intelDestroyBatchBuffer( GLcontext *ctx );
extern void intelInitBatchBuffer( struct intel_context *intel );
extern void intelDestroyBatchBuffer( struct intel_context *intel );
void intelInstallBatchBuffer( struct intel_context *intel );
extern void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim );
extern void intelWrapInlinePrimitive( intelContextPtr intel );
@ -97,5 +101,6 @@ extern void intelEmitFillBlitLocked( intelContextPtr intel,
GLuint *intelExtendInlinePrimitive( intelContextPtr intel,
GLuint dwords );
void intelValidateBuffers( struct intel_context *intel );
#endif

View file

View file

@ -389,7 +389,7 @@ GLboolean intelInitContext( intelContextPtr intel,
/* DRI_TEXMGR_DO_TEXTURE_RECT ); */
intel->prim.flush = intelInitBatchBuffer;
intel->prim.flush = NULL;
intel->prim.primitive = ~0;
@ -433,7 +433,7 @@ void intelDestroyContext(__DRIcontextPrivate *driContextPriv)
_swrast_DestroyContext (&intel->ctx);
intel->Fallback = 0; /* don't call _swrast_Flush later */
intelDestroyBatchBuffer(&intel->ctx);
intelDestroyBatchBuffer(intel);
if ( release_texture_heaps ) {
@ -581,6 +581,13 @@ void intelGetLock( intelContextPtr intel, GLuint flags )
__DRIscreenPrivate *sPriv = intel->driScreen;
drmI830Sarea * sarea = intel->sarea;
int me = intel->hHWContext;
static int foo = 0;
/* _mesa_printf("%s\n", __FUNCTION__); */
/* if (foo++ > 1) { */
/* _mesa_printf("%s - foo\n", __FUNCTION__); */
/* abort(); */
/* } */
drmGetLock(intel->driFd, intel->hHWContext, flags);

View file

@ -146,6 +146,8 @@ struct intel_context
GLuint Fallback;
GLuint NewGLState;
GLuint last_fence;
struct {
GLuint start_offset;
GLint size;
@ -153,15 +155,16 @@ struct intel_context
GLubyte *ptr;
} batch;
#define INTEL_ALLOC_NR 64
#define INTEL_ALLOC_SIZE 4096
struct {
void *ptr;
GLint size;
GLuint offset;
GLuint active_buf;
GLuint irq_emitted;
GLuint buffer[INTEL_ALLOC_NR];
GLuint current;
} alloc;
struct {
GLuint id;
GLuint primitive;
GLubyte *start_ptr;
void (*flush)( GLcontext * );
@ -211,11 +214,12 @@ struct intel_context
GLenum render_primitive;
GLenum reduced_primitive;
GLuint vertex_size;
char *verts; /* points to tnl->clipspace.vertex_buf */
GLubyte *verts; /* points to tnl->clipspace.vertex_buf */
struct intel_region *front_region;
struct intel_region *back_region;
struct intel_region *draw_region;
struct intel_region *depth_region;

View file

@ -46,11 +46,6 @@ extern void intelRefillBatchLocked( intelContextPtr intel, GLboolean allow_unloc
extern void intelFinish( GLcontext *ctx );
extern void intelFlush( GLcontext *ctx );
extern void *intelAllocateAGP( intelContextPtr intel, GLsizei size );
extern void intelFreeAGP( intelContextPtr intel, void *pointer );
extern GLuint intelAgpOffsetFromVirtual( intelContextPtr intel, const GLvoid *p );
void intelWaitIrq( intelContextPtr intel, int seq );
int intelEmitIrqLocked( intelContextPtr intel );

View file

@ -180,7 +180,7 @@ intelTryReadPixels( GLcontext *ctx,
int nbox = dPriv->numClipRects;
int src_offset = intel->drawOffset;
int src_pitch = intel->intelScreen->front.pitch;
int dst_offset = intelAgpOffsetFromVirtual( intel, pixels);
int dst_offset = 0;
drm_clip_rect_t *box = dPriv->pClipRects;
int i;
@ -261,7 +261,7 @@ static void do_draw_pix( GLcontext *ctx,
drm_clip_rect_t *box = dPriv->pClipRects;
int nbox = dPriv->numClipRects;
int i;
int src_offset = intelAgpOffsetFromVirtual( intel, pixels);
int src_offset = 0;
int src_pitch = pitch;
if (INTEL_DEBUG & DEBUG_PIXEL)
@ -504,6 +504,7 @@ static GLboolean intelTryCopyPixels( GLcontext *ctx,
intelFlush( &intel->ctx );
LOCK_HARDWARE( intel );
intelInstallBatchBuffer( intel );
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
drm_clip_rect_t *box = dPriv->pClipRects;
@ -513,7 +514,6 @@ static GLboolean intelTryCopyPixels( GLcontext *ctx,
GLuint dst_offset = 0;
GLuint src_offset = 0;
GLuint i;
struct bm_buffer_list *list = bmNewBufferList();
#if 0
dsty -= height; /* cope with pixel zoom */
@ -547,9 +547,12 @@ static GLboolean intelTryCopyPixels( GLcontext *ctx,
dsty += dPriv->y;
bmAddBuffer(list, dst->buffer, BM_WRITE, NULL, &dst_offset);
bmAddBuffer(list, src->buffer, BM_READ, NULL, &src_offset);
if (!bmValidateBufferList(intel->bm, list, BM_NO_EVICT|BM_NO_UPLOAD|BM_MEM_AGP))
bmAddBuffer(intel->buffer_list, dst->buffer, BM_NO_EVICT|BM_NO_UPLOAD|BM_WRITE,
NULL, &dst_offset);
bmAddBuffer(intel->buffer_list, src->buffer, BM_NO_EVICT|BM_NO_UPLOAD|BM_READ,
NULL, &src_offset);
if (!bmValidateBufferList(intel->bm, intel->buffer_list, BM_MEM_AGP))
goto out;
/* Could do slightly more clipping: Eg, take the intersection of
@ -583,15 +586,9 @@ static GLboolean intelTryCopyPixels( GLcontext *ctx,
bx, by, /* dstx, dsty */
bw, bh );
}
intelFlushBatchLocked( intel, GL_TRUE, GL_FALSE, GL_FALSE);
bmFenceBufferList(intel->bm, list);
out:
bmFreeBufferList(list);
}
out:
intelFlushBatchLocked( intel, GL_TRUE, GL_FALSE, GL_FALSE);
UNLOCK_HARDWARE( intel );
return GL_TRUE;
}

View file

@ -166,7 +166,7 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
intelScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset;
if (0) intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv);
if (1) intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv);
intelScreen->drmMinor = sPriv->drmMinor;

View file

@ -192,10 +192,17 @@ static void intelDrawBuffer(GLcontext *ctx, GLenum mode )
intelSetFrontClipRects( intel );
/* if (intel->draw_region) */
/* intel_region_release(intel, intel->draw_region); */
if (front) {
intel->drawOffset = screen->front.offset;
/* intel->draw_region = intel_region_reference(intel->front_region); */
intel->draw_region = intel->front_region;
} else {
intel->drawOffset = screen->back.offset;
/* intel->draw_region = intel_region_reference(intel->back_region); */
intel->draw_region = intel->back_region;
}
intel->vtbl.set_draw_offset( intel, intel->drawOffset );

View file

@ -111,4 +111,12 @@ GLboolean intel_prevalidate_buffers( struct intel_context *intel );
GLboolean intel_validate_buffers( struct intel_context *intel );
void intel_fence_buffers( struct intel_context *intel );
void intel_tex_map_images( struct intel_context *intel,
struct intel_texture_object *intelObj );
void intel_tex_unmap_images( struct intel_context *intel,
struct intel_texture_object *intelObj );
#endif

View file

@ -105,9 +105,9 @@ static GLboolean do_copy_texsubimage( struct intel_context *intel,
LOCK_HARDWARE(intel);
intelInstallBatchBuffer(intel);
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
struct bm_buffer_list *list = bmNewBufferList();
GLuint image_offset = intel_miptree_image_offset(intelImage->mt,
intelImage->face,
intelImage->level);
@ -131,9 +131,15 @@ static GLboolean do_copy_texsubimage( struct intel_context *intel,
y += dPriv->y;
bmAddBuffer(list, intelImage->mt->region->buffer, BM_WRITE, NULL, &dst_offset);
bmAddBuffer(list, src->buffer, BM_READ, NULL, &src_offset);
if (!bmValidateBufferList(intel->bm, list, BM_MEM_AGP)) {
bmAddBuffer(intel->buffer_list,
intelImage->mt->region->buffer,
BM_WRITE, NULL, &dst_offset);
bmAddBuffer(intel->buffer_list,
src->buffer,
BM_READ, NULL, &src_offset);
if (!bmValidateBufferList(intel->bm, intel->buffer_list, BM_MEM_AGP)) {
ret = GL_FALSE;
goto out;
}
@ -146,12 +152,8 @@ static GLboolean do_copy_texsubimage( struct intel_context *intel,
x, y,
dstx, dsty,
width, height );
intelFlushBatchLocked( intel, GL_TRUE, GL_FALSE, GL_FALSE);
bmFenceBufferList(intel->bm, list);
out:
bmFreeBufferList(list);
intelFlushBatchLocked( intel, GL_TRUE, GL_FALSE, GL_FALSE);
}

View file

@ -87,12 +87,6 @@ static void intel_flush_inline_primitive( GLcontext *ctx )
intel->prim.primitive = ~0;
intel->prim.start_ptr = 0;
intel->prim.flush = 0;
intelFlushBatch(intel, GL_TRUE);
intel_fence_buffers(intel);
UNLOCK_HARDWARE(intel);
}
@ -101,30 +95,7 @@ static void intel_flush_inline_primitive( GLcontext *ctx )
void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim )
{
BATCH_LOCALS;
if (0)
fprintf(stderr, "%s %x\n", __FUNCTION__, prim);
/* Finish any in-progress primitive:
*/
INTEL_FIREVERTICES( intel );
LOCK_HARDWARE(intel);
intel_validate_buffers( intel );
intel->vtbl.emit_state( intel );
/* Make sure there is some space in this buffer:
*/
if (intel->vertex_size * 10 * sizeof(GLuint) >= intel->batch.space)
intelFlushBatch(intel, GL_TRUE);
if (((int)intel->batch.ptr) & 0x4) {
BEGIN_BATCH(1);
OUT_BATCH(0);
ADVANCE_BATCH();
}
/* Emit a slot which will be filled with the inline primitive
* command later.
*/
@ -146,6 +117,9 @@ void intelWrapInlinePrimitive( intelContextPtr intel )
intel_flush_inline_primitive( &intel->ctx );
intelFlushBatch(intel, GL_TRUE);
intelInstallBatchBuffer( intel );
intel_validate_buffers( intel );
intel->vtbl.emit_state( intel );
intelStartInlinePrimitive( intel, prim );
}
@ -859,7 +833,14 @@ static void intelRunPipeline( GLcontext *ctx )
static void intelRenderStart( GLcontext *ctx )
{
INTEL_CONTEXT(ctx)->vtbl.render_start( INTEL_CONTEXT(ctx) );
struct intel_context *intel = intel_context(ctx);
intel->vtbl.render_start( INTEL_CONTEXT(ctx) );
LOCK_HARDWARE(intel);
intelInstallBatchBuffer( intel );
intel_validate_buffers( intel );
intel->vtbl.emit_state( intel );
}
static void intelRenderFinish( GLcontext *ctx )
@ -871,6 +852,9 @@ static void intelRenderFinish( GLcontext *ctx )
if (intel->prim.flush)
intel->prim.flush(ctx);
intelFlushBatch(intel, GL_TRUE);
UNLOCK_HARDWARE(intel);
}