i915: Implement and use the reworked batchbuffer code

This commit is contained in:
Jakob Bornecrantz 2008-06-02 17:22:45 +02:00
parent 4ee14279f3
commit 7cc23a9eae
7 changed files with 52 additions and 95 deletions

View file

@ -40,6 +40,7 @@ struct i915_batchbuffer
unsigned char *ptr;
size_t size;
size_t actual_size;
size_t relocs;
size_t max_relocs;
@ -50,39 +51,25 @@ i915_batchbuffer_check( struct i915_batchbuffer *batch,
size_t dwords,
size_t relocs )
{
#if 0 /* To be used */
/** TODO JB: Check relocs */
return dwords * 4 <= batch->size - (batch->ptr - batch->map);
#else
if (batch->winsys->batch_start( batch->winsys, dwords, relocs ))
return 1;
return 0;
#endif
}
static INLINE size_t
i915_batchbuffer_space( struct i915_batchbuffer *batch )
{
#if 0 /* To be used */
return batch->size - (batch->ptr - batch->map);
#else
return 0;
#endif
}
static INLINE void
i915_batchbuffer_dword( struct i915_batchbuffer *batch,
unsigned dword )
{
#if 0 /* To be used */
if (i915_batchbuffer_space(batch) < 4)
return;
*(unsigned *)batch->ptr = dword;
batch->ptr += 4;
#else
batch->winsys->batch_dword( batch->winsys, dword );
#endif
}
static INLINE void
@ -90,14 +77,11 @@ i915_batchbuffer_write( struct i915_batchbuffer *batch,
void *data,
size_t size )
{
#if 0 /* To be used */
if (i915_batchbuffer_space(batch) < size)
return;
memcpy(data, batch->ptr, size);
batch->ptr += size;
#else
#endif
}
static INLINE void
@ -135,4 +119,4 @@ i915_batchbuffer_flush( struct i915_batchbuffer *batch,
i915->hardware_dirty = ~0; \
} while (0)
#endif
#endif

View file

@ -181,7 +181,7 @@ struct pipe_context *i915_create_context( struct pipe_screen *screen,
/* Batch stream debugging is a bit hacked up at the moment:
*/
i915->batch = CALLOC_STRUCT(i915_batchbuffer);
i915->batch = i915_winsys->batch_get(i915_winsys);
i915->batch->winsys = i915_winsys;
return &i915->pipe;

View file

@ -861,8 +861,9 @@ void
i915_dump_batchbuffer( struct i915_context *i915 )
{
struct debug_stream stream;
/* TODO fix me */
unsigned *start = 0;/*i915->batch_start;*/
unsigned *end = i915->winsys->batch_start( i915->winsys, 0, 0 );
unsigned *end = 0;/*i915->winsys->batch_start( i915->winsys, 0, 0 );*/
unsigned long bytes = (unsigned long) (end - start) * 4;
boolean done = FALSE;

View file

@ -55,6 +55,7 @@ extern "C" {
* etc.
*/
struct i915_batchbuffer;
struct pipe_buffer;
struct pipe_fence_handle;
struct pipe_winsys;
@ -75,20 +76,10 @@ struct pipe_screen;
struct i915_winsys {
/**
* Reserve space on batch buffer.
*
* Returns a null pointer if there is insufficient space in the batch buffer
* to hold the requested number of dwords and relocations.
*
* The number of dwords should also include the number of relocations.
* Get the current batch buffer from the winsys.
*/
unsigned *(*batch_start)( struct i915_winsys *sws,
unsigned dwords,
unsigned relocs );
void (*batch_dword)( struct i915_winsys *sws,
unsigned dword );
struct i915_batchbuffer *(*batch_get)( struct i915_winsys *sws );
/**
* Emit a relocation to a buffer.
*
@ -103,7 +94,10 @@ struct i915_winsys {
struct pipe_buffer *buf,
unsigned access_flags,
unsigned delta );
/**
* Flush the batch.
*/
void (*batch_flush)( struct i915_winsys *sws,
struct pipe_fence_handle **fence );
};

View file

@ -65,8 +65,10 @@ intel_batchbuffer_reset(struct intel_batchbuffer *batch)
driBOUnrefUserList(batch->list);
driBOResetList(batch->list);
batch->size = batch->intel->intelScreen->max_batch_size;
driBOData(batch->buffer, batch->size, NULL, NULL, 0);
/* base.size is the size available to the i915simple driver */
batch->base.size = batch->intel->intelScreen->max_batch_size - BATCH_RESERVED;
batch->base.actual_size = batch->intel->intelScreen->max_batch_size;
driBOData(batch->buffer, batch->base.actual_size, NULL, NULL, 0);
/*
* Add the batchbuffer to the validate list.
@ -105,9 +107,9 @@ intel_batchbuffer_reset(struct intel_batchbuffer *batch)
batch->reloc[2] = 0; /* Only a single relocation list. */
batch->reloc[3] = 0; /* Only a single relocation list. */
batch->map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0);
batch->base.map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0);
batch->poolOffset = driBOPoolOffset(batch->buffer);
batch->ptr = batch->map;
batch->base.ptr = batch->base.map;
batch->dirty_state = ~0;
batch->nr_relocs = 0;
batch->flags = 0;
@ -142,9 +144,9 @@ intel_batchbuffer_free(struct intel_batchbuffer *batch)
DRM_FENCE_TYPE_EXE, GL_FALSE);
driFenceUnReference(&batch->last_fence);
}
if (batch->map) {
if (batch->base.map) {
driBOUnmap(batch->buffer);
batch->map = NULL;
batch->base.map = NULL;
}
driBOUnReference(batch->buffer);
driBOFreeList(batch->list);
@ -191,7 +193,7 @@ intel_offset_relocation(struct intel_batchbuffer *batch,
reloc = batch->reloc +
(I915_RELOC_HEADER + batch->nr_relocs * I915_RELOC0_STRIDE);
reloc[0] = ((uint8_t *)batch->ptr - batch->drmBOVirtual);
reloc[0] = ((uint8_t *)batch->base.ptr - batch->drmBOVirtual);
intel_batchbuffer_emit_dword(batch, req->presumed_offset + pre_add);
reloc[1] = pre_add;
reloc[2] = itemLoc;
@ -382,7 +384,7 @@ struct _DriFenceObject *
intel_batchbuffer_flush(struct intel_batchbuffer *batch)
{
struct intel_context *intel = batch->intel;
GLuint used = batch->ptr - batch->map;
GLuint used = batch->base.ptr - batch->base.map;
GLboolean was_locked = intel->locked;
struct _DriFenceObject *fence;
@ -396,32 +398,32 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch)
*/
#if 0 /* ZZZ JB: what should we do here? */
if (used & 4) {
((int *) batch->ptr)[0] = intel->vtbl.flush_cmd();
((int *) batch->ptr)[1] = 0;
((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END;
((int *) batch->base.ptr)[0] = intel->vtbl.flush_cmd();
((int *) batch->base.ptr)[1] = 0;
((int *) batch->base.ptr)[2] = MI_BATCH_BUFFER_END;
used += 12;
}
else {
((int *) batch->ptr)[0] = intel->vtbl.flush_cmd();
((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END;
((int *) batch->base.ptr)[0] = intel->vtbl.flush_cmd();
((int *) batch->base.ptr)[1] = MI_BATCH_BUFFER_END;
used += 8;
}
#else
if (used & 4) {
((int *) batch->ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH;
((int *) batch->ptr)[1] = 0;
((int *) batch->ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END;
((int *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH;
((int *) batch->base.ptr)[1] = 0;
((int *) batch->base.ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END;
used += 12;
}
else {
((int *) batch->ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH;
((int *) batch->ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END;
((int *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH;
((int *) batch->base.ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END;
used += 8;
}
#endif
driBOUnmap(batch->buffer);
batch->ptr = NULL;
batch->map = NULL;
batch->base.ptr = NULL;
batch->base.map = NULL;
/* TODO: Just pass the relocation list and dma buffer up to the
* kernel.
@ -455,6 +457,6 @@ intel_batchbuffer_data(struct intel_batchbuffer *batch,
{
assert((bytes & 3) == 0);
intel_batchbuffer_require_space(batch, bytes, flags);
memcpy(batch->ptr, data, bytes);
batch->ptr += bytes;
memcpy(batch->base.ptr, data, bytes);
batch->base.ptr += bytes;
}

View file

@ -3,6 +3,7 @@
#include "mtypes.h"
#include "ws_dri_bufmgr.h"
#include "i915simple/i915_batch.h"
struct intel_context;
@ -17,7 +18,8 @@ struct intel_context;
struct intel_batchbuffer
{
struct bufmgr *bm;
struct i915_batchbuffer base;
struct intel_context *intel;
struct _DriBufferObject *buffer;
@ -26,15 +28,11 @@ struct intel_batchbuffer
struct _DriBufferList *list;
GLuint list_count;
GLubyte *map;
GLubyte *ptr;
uint32_t *reloc;
GLuint reloc_size;
GLuint nr_relocs;
GLuint size;
GLuint dirty_state;
GLuint id;
@ -83,7 +81,7 @@ intel_offset_relocation(struct intel_batchbuffer *batch,
static INLINE GLuint
intel_batchbuffer_space(struct intel_batchbuffer *batch)
{
return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map);
return (batch->base.size - BATCH_RESERVED) - (batch->base.ptr - batch->base.map);
}
@ -92,8 +90,8 @@ intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword)
{
assert(batch->map);
assert(intel_batchbuffer_space(batch) >= 4);
*(GLuint *) (batch->ptr) = dword;
batch->ptr += 4;
*(GLuint *) (batch->base.ptr) = dword;
batch->base.ptr += 4;
}
static INLINE void
@ -114,20 +112,25 @@ intel_batchbuffer_require_space(struct intel_batchbuffer *batch,
/* Here are the crusty old macros, to be removed:
*/
#undef BATCH_LOCALS
#define BATCH_LOCALS
#undef BEGIN_BATCH
#define BEGIN_BATCH(n, flags) do { \
assert(!intel->prim.flush); \
intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \
} while (0)
#undef OUT_BATCH
#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d)
#undef OUT_RELOC
#define OUT_RELOC(buf,flags,mask,delta) do { \
assert((delta) >= 0); \
intel_offset_relocation(intel->batch, delta, buf, flags, mask); \
} while (0)
#undef ADVANCE_BATCH
#define ADVANCE_BATCH() do { } while(0)

View file

@ -63,28 +63,11 @@ intel_i915_winsys( struct i915_winsys *sws )
/* Simple batchbuffer interface:
*/
static unsigned *intel_i915_batch_start( struct i915_winsys *sws,
unsigned dwords,
unsigned relocs )
static struct i915_batchbuffer*
intel_i915_batch_get( struct i915_winsys *sws )
{
struct intel_context *intel = intel_i915_winsys(sws)->intel;
/* XXX: check relocs.
*/
if (intel_batchbuffer_space( intel->batch ) >= dwords * 4) {
/* XXX: Hmm, the driver can't really do much with this pointer:
*/
return (unsigned *)intel->batch->ptr;
}
else
return NULL;
}
static void intel_i915_batch_dword( struct i915_winsys *sws,
unsigned dword )
{
struct intel_context *intel = intel_i915_winsys(sws)->intel;
intel_batchbuffer_emit_dword( intel->batch, dword );
return &intel->batch->base;
}
static void intel_i915_batch_reloc( struct i915_winsys *sws,
@ -106,22 +89,13 @@ static void intel_i915_batch_reloc( struct i915_winsys *sws,
mask |= DRM_BO_FLAG_READ;
}
#if 0 /* JB old */
intel_batchbuffer_emit_reloc( intel->batch,
dri_bo( buf ),
flags, mask,
delta );
#else /* new */
intel_offset_relocation( intel->batch,
delta,
dri_bo( buf ),
flags,
mask );
#endif
}
static void intel_i915_batch_flush( struct i915_winsys *sws,
struct pipe_fence_handle **fence )
{
@ -166,8 +140,7 @@ intel_create_i915simple( struct intel_context *intel,
/* Fill in this struct with callbacks that i915simple will need to
* communicate with the window system, buffer manager, etc.
*/
iws->winsys.batch_start = intel_i915_batch_start;
iws->winsys.batch_dword = intel_i915_batch_dword;
iws->winsys.batch_get = intel_i915_batch_get;
iws->winsys.batch_reloc = intel_i915_batch_reloc;
iws->winsys.batch_flush = intel_i915_batch_flush;
iws->pws = winsys;