#include "brw_structs.h"
#include "intel_decode.h"
-#define USE_MALLOC_BUFFER 1
#define ALWAYS_EMIT_MI_FLUSH 1
enum pipe_error
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;
}
{
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);
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;
}
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 );
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
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;
+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,
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 )
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;
}
*/
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.
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)
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);
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)
{
buf->modified = 0;
- /* Consider dumping new buffer contents here.
+ /* Consider dumping new buffer contents here, using the
+ * flush-range info to minimize verbosity.
*/
}
}
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;