*
**************************************************************************/
+#include "util/u_memory.h"
+
+#include "pipe/p_error.h"
+
#include "brw_batchbuffer.h"
-#include "brw_decode.h"
+//#include "brw_decode.h"
#include "brw_reg.h"
#include "brw_winsys.h"
+#include "brw_debug.h"
+#include "brw_structs.h"
+#define BATCH_SIZE (32*1024)
+#define USE_LOCAL_BUFFER 1
+#define ALWAYS_EMIT_MI_FLUSH 1
void
brw_batchbuffer_reset(struct brw_batchbuffer *batch)
{
- struct intel_context *intel = batch->intel;
-
if (batch->buf != NULL) {
- brw->sws->bo_unreference(batch->buf);
+ batch->sws->bo_unreference(batch->buf);
batch->buf = NULL;
}
- if (!batch->buffer && intel->ttm == GL_TRUE)
- batch->buffer = malloc (intel->maxBatchSize);
+ if (USE_LOCAL_BUFFER && !batch->buffer)
+ batch->buffer = MALLOC(BATCH_SIZE);
batch->buf = batch->sws->bo_alloc(batch->sws,
BRW_BUFFER_TYPE_BATCH,
- intel->maxBatchSize, 4096);
+ BATCH_SIZE, 4096);
if (batch->buffer)
batch->map = batch->buffer;
- else {
- batch->sws->bo_map(batch->buf, GL_TRUE);
- batch->map = batch->buf->virtual;
- }
- batch->size = intel->maxBatchSize;
+ else
+ batch->map = batch->sws->bo_map(batch->buf, GL_TRUE);
+
+ batch->size = BATCH_SIZE;
batch->ptr = batch->map;
- batch->dirty_state = ~0;
- batch->cliprect_mode = IGNORE_CLIPRECTS;
}
struct brw_batchbuffer *
brw_batchbuffer_free(struct brw_batchbuffer *batch)
{
if (batch->map) {
- dri_bo_unmap(batch->buf);
+ batch->sws->bo_unmap(batch->buf);
batch->map = NULL;
}
- brw->sws->bo_unreference(batch->buf);
+
+ batch->sws->bo_unreference(batch->buf);
batch->buf = NULL;
+
+ FREE(batch->buffer);
FREE(batch);
}
void
-_brw_batchbuffer_flush(struct brw_batchbuffer *batch, const char *file,
- int line)
+_brw_batchbuffer_flush(struct brw_batchbuffer *batch,
+ const char *file,
+ int line)
{
- struct intel_context *intel = batch->intel;
GLuint used = batch->ptr - batch->map;
if (used == 0)
return;
- if (intel->first_post_swapbuffers_batch == NULL) {
- intel->first_post_swapbuffers_batch = intel->batch->buf;
- batch->sws->bo_reference(intel->first_post_swapbuffers_batch);
- }
-
- if (intel->first_post_swapbuffers_batch == NULL) {
- intel->first_post_swapbuffers_batch = intel->batch->buf;
- batch->sws->bo_reference(intel->first_post_swapbuffers_batch);
- }
-
+ /* Post-swap throttling done by the state tracker.
+ */
if (BRW_DEBUG & DEBUG_BATCH)
- debug_printf("%s:%d: Batchbuffer flush with %db used\n", file, line,
- used);
+ debug_printf("%s:%d: Batchbuffer flush with %db used\n",
+ file, line, used);
-#if 0
- if (intel->always_flush_cache || 1) {
- *(GLuint *) (batch->ptr) = ((CMD_MI_FLUSH << 16) | BRW_FLUSH_STATE_CACHE);
+ if (ALWAYS_EMIT_MI_FLUSH) {
+ *(GLuint *) (batch->ptr) = ((MI_FLUSH << 16) | BRW_FLUSH_STATE_CACHE);
batch->ptr += 4;
used = batch->ptr - batch->map;
}
-#endif
-
- /* Round batchbuffer usage to 2 DWORDs. */
+ /* Round batchbuffer usage to 2 DWORDs.
+ */
if ((used & 4) == 0) {
*(GLuint *) (batch->ptr) = 0; /* noop */
batch->ptr += 4;
used = batch->ptr - batch->map;
}
- /* Mark the end of the buffer. */
- *(GLuint *) (batch->ptr) = MI_BATCH_BUFFER_END; /* noop */
+ /* Mark the end of the buffer.
+ */
+ *(GLuint *) (batch->ptr) = MI_BATCH_BUFFER_END;
batch->ptr += 4;
used = batch->ptr - batch->map;
batch->sws->bo_unmap(batch->buf);
-
batch->map = NULL;
batch->ptr = NULL;
batch->sws->bo_exec(batch->buf, used, NULL, 0, 0 );
-
+
+#if 0
if (BRW_DEBUG & DEBUG_BATCH) {
void *ptr = batch->sws->bo_map(batch->buf, GL_FALSE);
intel_decode(ptr,
used / 4,
batch->buf->offset,
- batch->chipset);
+ batch->chipset.pci_id);
batch->sws->bo_unmap(batch->buf);
}
+#endif
if (BRW_DEBUG & DEBUG_SYNC) {
/* Abuse map/unmap to achieve wait-for-fence.
if (ret)
return ret;
- __memcpy(batch->ptr, data, bytes);
+ memcpy(batch->ptr, data, bytes);
batch->ptr += bytes;
return 0;
}
REFERENCES_CLIPRECTS
};
+
+
+
+struct brw_batchbuffer {
+
+ struct brw_winsys_screen *sws;
+ struct brw_winsys_buffer *buf;
+
+ /* Main-memory copy of the batch-buffer, built up incrementally &
+ * then copied as one to the true buffer.
+ *
+ * XXX: is this still necessary?
+ * XXX: if so, can this be hidden inside the GEM-specific winsys code?
+ */
+ uint8_t *buffer;
+
+ /**
+ * Values exported to speed up the writing the batchbuffer,
+ * instead of having to go trough a accesor function for
+ * each dword written.
+ */
+ /*{@*/
+ uint8_t *map;
+ uint8_t *ptr;
+ size_t size;
+ struct {
+ uint8_t *end_ptr;
+ } emit;
+
+
+ size_t relocs;
+ size_t max_relocs;
+ /*@}*/
+};
+
+struct brw_batchbuffer *brw_batchbuffer_alloc( struct brw_winsys_screen *sws );
+
void brw_batchbuffer_free(struct brw_batchbuffer *batch);
void _brw_batchbuffer_flush(struct brw_batchbuffer *batch,
/* Here are the crusty old macros, to be removed:
*/
#define BEGIN_BATCH(n, cliprect_mode) do { \
- brw_batchbuffer_require_space(brw->batch, (n)*4); \
-} while (0)
+ brw_batchbuffer_require_space(brw->batch, (n)*4); \
+ } while (0)
#define OUT_BATCH(d) brw_batchbuffer_emit_dword(brw->batch, d)
#define OUT_RELOC(buf, read_domains, write_domain, delta) do { \
- assert((unsigned) (delta) < buf->size); \
- brw_batchbuffer_emit_reloc(brw->batch, buf, \
- read_domains, write_domain, delta); \
-} while (0)
+ assert((unsigned) (delta) < buf->size); \
+ brw_batchbuffer_emit_reloc(brw->batch, buf, \
+ read_domains, write_domain, delta); \
+ } while (0)
#ifdef DEBUG
#define ADVANCE_BATCH() do { \
- unsigned int _n = brw->batch->ptr - brw->batch->emit.end_ptr; \
- if (_n != 0) { \
- debug_printf("%s: %d too many bytes emitted to batch\n", __FUNCTION__, _n); \
- abort(); \
- } \
- brw->batch->emit.end_ptr = NULL; \
-} while(0)
+ unsigned int _n = brw->batch->ptr - brw->batch->emit.end_ptr; \
+ if (_n != 0) { \
+ debug_printf("%s: %d too many bytes emitted to batch\n", \
+ __FUNCTION__, _n); \
+ abort(); \
+ } \
+ brw->batch->emit.end_ptr = NULL; \
+ } while(0)
#else
#define ADVANCE_BATCH()
#endif
BRW_BUFFER_TYPE_STATE_CACHE,
};
-
-/* AKA winsys context:
- */
-struct brw_batchbuffer {
-
- struct brw_winsys *iws;
- struct brw_winsys_buffer *buf;
-
- /**
- * Values exported to speed up the writing the batchbuffer,
- * instead of having to go trough a accesor function for
- * each dword written.
- */
- /*{@*/
- uint8_t *map;
- uint8_t *ptr;
- size_t size;
- struct {
- uint8_t *end_ptr;
- } emit;
-
-
- size_t relocs;
- size_t max_relocs;
- /*@}*/
-};
-
struct brw_winsys_screen {
- /**
- * Batchbuffer functions.
- */
- /*@{*/
- /**
- * Create a new batchbuffer.
- */
- struct brw_batchbuffer *(*batchbuffer_create)(struct brw_winsys_screen *iws);
-
- /**
- * Emit a relocation to a buffer.
- * Target position in batchbuffer is the same as ptr.
- */
- int (*batchbuffer_reloc)(struct brw_batchbuffer *batch,
- unsigned offset,
- struct brw_winsys_buffer *reloc,
- unsigned pre_add,
- enum brw_buffer_usage usage);
-
- /**
- * Flush a bufferbatch.
- */
- void (*batchbuffer_flush)(struct brw_batchbuffer *batch,
- struct pipe_fence_handle **fence);
-
- /**
- * Destroy a batchbuffer.
- */
- void (*batchbuffer_destroy)(struct brw_batchbuffer *batch);
- /*@}*/
-
/**
* Buffer functions.
*/
void (*bo_reference)( struct brw_winsys_buffer *buffer );
void (*bo_unreference)( struct brw_winsys_buffer *buffer );
- void (*bo_emit_reloc)( struct brw_winsys_buffer *buffer,
- unsigned domain,
- unsigned a,
- unsigned b,
- unsigned offset,
- struct brw_winsys_buffer *b2);
+
+ /* XXX: parameter names!!
+ */
+ int (*bo_emit_reloc)( struct brw_winsys_buffer *buffer,
+ unsigned domain,
+ unsigned a,
+ unsigned b,
+ unsigned offset,
+ struct brw_winsys_buffer *b2);
+
+ int (*bo_exec)( struct brw_winsys_buffer *buffer,
+ unsigned bytes_used,
+ void *foo,
+ int a,
+ int b );
void (*bo_subdata)(struct brw_winsys_buffer *buffer,
size_t offset,
/*@}*/
- /**
- * Fence functions.
- */
- /*@{*/
- /**
- * Reference fence and set ptr to fence.
- */
- void (*fence_reference)(struct brw_winsys *iws,
- struct pipe_fence_handle **ptr,
- struct pipe_fence_handle *fence);
-
- /**
- * Check if a fence has finished.
- */
- int (*fence_signalled)(struct brw_winsys *iws,
- struct pipe_fence_handle *fence);
-
- /**
- * Wait on a fence to finish.
- */
- int (*fence_finish)(struct brw_winsys *iws,
- struct pipe_fence_handle *fence);
- /*@}*/
/**