diff --git a/src/gallium/drivers/i965/brw_batchbuffer.c b/src/gallium/drivers/i965/brw_batchbuffer.c index a55be6faab0..d725e8b27e0 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.c +++ b/src/gallium/drivers/i965/brw_batchbuffer.c @@ -35,7 +35,6 @@ #include "brw_structs.h" #include "intel_decode.h" -#define USE_MALLOC_BUFFER 1 #define ALWAYS_EMIT_MI_FLUSH 1 enum pipe_error @@ -50,14 +49,18 @@ brw_batchbuffer_reset(struct brw_batchbuffer *batch) if (ret) return ret; - if (batch->malloc_buffer) - batch->map = batch->malloc_buffer; - else - batch->map = batch->sws->bo_map(batch->buf, - BRW_DATA_BATCH_BUFFER, - GL_TRUE); - batch->size = BRW_BATCH_SIZE; + + /* With map_range semantics, the winsys can decide whether to + * inject a malloc'ed bounce buffer instead of mapping directly. + */ + batch->map = batch->sws->bo_map(batch->buf, + BRW_DATA_BATCH_BUFFER, + 0, batch->size, + GL_TRUE, + GL_TRUE, + GL_TRUE); + batch->ptr = batch->map; return PIPE_OK; } @@ -68,11 +71,6 @@ brw_batchbuffer_alloc(struct brw_winsys_screen *sws, { struct brw_batchbuffer *batch = CALLOC_STRUCT(brw_batchbuffer); - batch->use_malloc_buffer = USE_MALLOC_BUFFER; - if (batch->use_malloc_buffer) { - batch->malloc_buffer = MALLOC(BRW_BATCH_SIZE); - } - batch->sws = sws; batch->chipset = chipset; brw_batchbuffer_reset(batch); @@ -83,11 +81,7 @@ brw_batchbuffer_alloc(struct brw_winsys_screen *sws, void brw_batchbuffer_free(struct brw_batchbuffer *batch) { - if (batch->malloc_buffer) { - FREE(batch->malloc_buffer); - batch->map = NULL; - } - else if (batch->map) { + if (batch->map) { batch->sws->bo_unmap(batch->buf); batch->map = NULL; } @@ -134,18 +128,9 @@ _brw_batchbuffer_flush(struct brw_batchbuffer *batch, batch->ptr += 4; used = batch->ptr - batch->map; - if (batch->use_malloc_buffer) { - batch->sws->bo_subdata(batch->buf, - BRW_DATA_BATCH_BUFFER, - 0, used, - batch->map ); - batch->map = NULL; - } - else { - batch->sws->bo_unmap(batch->buf); - batch->map = NULL; - } - + batch->sws->bo_flush_range(batch->buf, 0, used); + batch->sws->bo_unmap(batch->buf); + batch->map = NULL; batch->ptr = NULL; batch->sws->bo_exec(batch->buf, used ); diff --git a/src/gallium/drivers/i965/brw_batchbuffer.h b/src/gallium/drivers/i965/brw_batchbuffer.h index 288a9d27555..7473f5bea4d 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.h +++ b/src/gallium/drivers/i965/brw_batchbuffer.h @@ -28,15 +28,6 @@ struct brw_batchbuffer { struct brw_winsys_buffer *buf; struct brw_chipset chipset; - /* 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? - */ - boolean use_malloc_buffer; - uint8_t *malloc_buffer; - /** * Values exported to speed up the writing the batchbuffer, * instead of having to go trough a accesor function for diff --git a/src/gallium/drivers/i965/brw_pipe_query.c b/src/gallium/drivers/i965/brw_pipe_query.c index 6a011737879..2eb862635cc 100644 --- a/src/gallium/drivers/i965/brw_pipe_query.c +++ b/src/gallium/drivers/i965/brw_pipe_query.c @@ -63,7 +63,7 @@ brw_query_get_result(struct pipe_context *pipe, if (brw->sws->bo_is_busy(query->bo) && !wait) return FALSE; - map = brw->sws->bo_map(query->bo, BRW_DATA_OTHER, GL_FALSE); + map = bo_map_read(brw->sws, query->bo); if (map == NULL) return FALSE; diff --git a/src/gallium/drivers/i965/brw_screen_buffers.c b/src/gallium/drivers/i965/brw_screen_buffers.c index 7ae386ffb34..d8141a3f5b9 100644 --- a/src/gallium/drivers/i965/brw_screen_buffers.c +++ b/src/gallium/drivers/i965/brw_screen_buffers.c @@ -11,6 +11,29 @@ +static void * +brw_buffer_map_range( struct pipe_screen *screen, + struct pipe_buffer *buffer, + unsigned offset, + unsigned length, + unsigned usage ) +{ + struct brw_screen *bscreen = brw_screen(screen); + struct brw_winsys_screen *sws = bscreen->sws; + struct brw_buffer *buf = brw_buffer( buffer ); + + if (buf->user_buffer) + return buf->user_buffer; + + return sws->bo_map( buf->bo, + BRW_DATA_OTHER, + offset, + length, + (usage & PIPE_BUFFER_USAGE_CPU_WRITE) ? TRUE : FALSE, + (usage & PIPE_BUFFER_USAGE_DISCARD) ? TRUE : FALSE, + (usage & PIPE_BUFFER_USAGE_FLUSH_EXPLICIT) ? TRUE : FALSE); +} + static void * brw_buffer_map( struct pipe_screen *screen, struct pipe_buffer *buffer, @@ -25,9 +48,33 @@ brw_buffer_map( struct pipe_screen *screen, return sws->bo_map( buf->bo, BRW_DATA_OTHER, - (usage & PIPE_BUFFER_USAGE_CPU_WRITE) ? TRUE : FALSE ); + 0, + buf->base.size, + (usage & PIPE_BUFFER_USAGE_CPU_WRITE) ? TRUE : FALSE, + FALSE, + FALSE); } + +static void +brw_buffer_flush_mapped_range( struct pipe_screen *screen, + struct pipe_buffer *buffer, + unsigned offset, + unsigned length ) +{ + struct brw_screen *bscreen = brw_screen(screen); + struct brw_winsys_screen *sws = bscreen->sws; + struct brw_buffer *buf = brw_buffer( buffer ); + + if (buf->user_buffer) + return; + + sws->bo_flush_range( buf->bo, + offset, + length ); +} + + static void brw_buffer_unmap( struct pipe_screen *screen, struct pipe_buffer *buffer ) @@ -148,6 +195,8 @@ void brw_screen_buffer_init(struct brw_screen *brw_screen) brw_screen->base.buffer_create = brw_buffer_create; brw_screen->base.user_buffer_create = brw_user_buffer_create; brw_screen->base.buffer_map = brw_buffer_map; + brw_screen->base.buffer_map_range = brw_buffer_map_range; + brw_screen->base.buffer_flush_mapped_range = brw_buffer_flush_mapped_range; brw_screen->base.buffer_unmap = brw_buffer_unmap; brw_screen->base.buffer_destroy = brw_buffer_destroy; } diff --git a/src/gallium/drivers/i965/brw_winsys.h b/src/gallium/drivers/i965/brw_winsys.h index f4a1e9d8edf..e72b928b064 100644 --- a/src/gallium/drivers/i965/brw_winsys.h +++ b/src/gallium/drivers/i965/brw_winsys.h @@ -169,7 +169,15 @@ struct brw_winsys_screen { */ void *(*bo_map)(struct brw_winsys_buffer *buffer, enum brw_buffer_data_type data_type, - boolean write); + unsigned offset, + unsigned length, + boolean write, + boolean discard, + boolean flush_explicit ); + + void (*bo_flush_range)( struct brw_winsys_buffer *buffer, + unsigned offset, + unsigned length ); /** * Unmap a buffer. @@ -189,6 +197,14 @@ struct brw_winsys_screen { void (*destroy)(struct brw_winsys_screen *iws); }; +static INLINE void * +bo_map_read( struct brw_winsys_screen *sws, struct brw_winsys_buffer *buf ) +{ + return sws->bo_map( buf, + BRW_DATA_OTHER, + 0, buf->size, + FALSE, FALSE, FALSE ); +} static INLINE void bo_reference(struct brw_winsys_buffer **ptr, struct brw_winsys_buffer *buf) diff --git a/src/gallium/winsys/drm/i965/xlib/xlib_i965.c b/src/gallium/winsys/drm/i965/xlib/xlib_i965.c index f46d9961c6e..ab5df56bc05 100644 --- a/src/gallium/winsys/drm/i965/xlib/xlib_i965.c +++ b/src/gallium/winsys/drm/i965/xlib/xlib_i965.c @@ -350,7 +350,11 @@ xlib_brw_check_aperture_space( struct brw_winsys_screen *iws, static void * xlib_brw_bo_map(struct brw_winsys_buffer *buffer, enum brw_buffer_data_type data_type, - boolean write) + unsigned offset, + unsigned length, + boolean write, + boolean discard, + boolean explicit) { struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer); @@ -365,6 +369,15 @@ xlib_brw_bo_map(struct brw_winsys_buffer *buffer, return buf->virtual; } + +static void +xlib_brw_bo_flush_range( struct brw_winsys_buffer *buffer, + unsigned offset, + unsigned length ) +{ +} + + static void xlib_brw_bo_unmap(struct brw_winsys_buffer *buffer) { @@ -380,7 +393,8 @@ xlib_brw_bo_unmap(struct brw_winsys_buffer *buffer) buf->modified = 0; - /* Consider dumping new buffer contents here. + /* Consider dumping new buffer contents here, using the + * flush-range info to minimize verbosity. */ } } @@ -421,6 +435,7 @@ xlib_create_brw_winsys_screen( void ) ws->base.bo_references = xlib_brw_bo_references; ws->base.check_aperture_space = xlib_brw_check_aperture_space; ws->base.bo_map = xlib_brw_bo_map; + ws->base.bo_flush_range = xlib_brw_bo_flush_range; ws->base.bo_unmap = xlib_brw_bo_unmap; ws->base.bo_wait_idle = xlib_brw_bo_wait_idle;