When a buffer was mapped for write and no explicit flush range was provided the existing semantics were that the whole buffer would be flushed, mostly for backwards compatability with non map-buffer-range aware code. However if the buffer was mapped/unmapped with nothing really written -- something that often happens with the vbo -- we were unnecessarily assuming that the whole buffer was written. The new PIPE_BUFFER_USAGE_FLUSH_EXPLICIT flag (based from ARB_map_buffer_range 's GL_MAP_FLUSH_EXPLICIT_BIT flag) allows to clearly distinguish the legacy usage from the nothing written usage.tags/intel_2009q2_rc3
@@ -217,6 +217,7 @@ enum pipe_transfer_usage { | |||
#define PIPE_BUFFER_USAGE_CONSTANT (1 << 7) | |||
#define PIPE_BUFFER_USAGE_DISCARD (1 << 8) | |||
#define PIPE_BUFFER_USAGE_DONTBLOCK (1 << 9) | |||
#define PIPE_BUFFER_USAGE_FLUSH_EXPLICIT (1 << 10) /**< See pipe_screen::buffer_flush_mapped_range */ | |||
/** Pipe driver custom usage flags should be greater or equal to this value */ | |||
#define PIPE_BUFFER_USAGE_CUSTOM (1 << 16) | |||
@@ -117,7 +117,9 @@ pipe_buffer_write(struct pipe_screen *screen, | |||
assert(offset + size <= buf->size); | |||
assert(size); | |||
map = pipe_buffer_map_range(screen, buf, offset, size, PIPE_BUFFER_USAGE_CPU_WRITE); | |||
map = pipe_buffer_map_range(screen, buf, offset, size, | |||
PIPE_BUFFER_USAGE_CPU_WRITE | | |||
PIPE_BUFFER_USAGE_FLUSH_EXPLICIT); | |||
assert(map); | |||
if(map) { | |||
memcpy(map + offset, data, size); |
@@ -221,23 +221,31 @@ struct pipe_screen { | |||
/** | |||
* Notify a range that was actually written into. | |||
* | |||
* Can only be used if the buffer was mapped with the | |||
* PIPE_BUFFER_USAGE_CPU_WRITE and PIPE_BUFFER_USAGE_FLUSH_EXPLICIT flags | |||
* set. | |||
* | |||
* The range is relative to the buffer start, regardless of the range | |||
* specified to buffer_map_range. This is different from the | |||
* ARB_map_buffer_range semantics because we don't forbid multiple mappings | |||
* of the same buffer (yet). | |||
* | |||
* If the buffer was mapped for writing and no buffer_flush_mapped_range | |||
* call was done until the buffer_unmap is called then the pipe driver will | |||
* assumed that the whole buffer was written. This is for backward | |||
* compatibility purposes and may affect performance -- the state tracker | |||
* should always specify exactly what got written while the buffer was | |||
* mapped. | |||
*/ | |||
void (*buffer_flush_mapped_range)( struct pipe_screen *screen, | |||
struct pipe_buffer *buf, | |||
unsigned offset, | |||
unsigned length); | |||
/** | |||
* Unmap buffer. | |||
* | |||
* If the buffer was mapped with PIPE_BUFFER_USAGE_CPU_WRITE flag but not | |||
* PIPE_BUFFER_USAGE_FLUSH_EXPLICIT then the pipe driver will | |||
* assume that the whole buffer was written. This is mostly for backward | |||
* compatibility purposes and may affect performance -- the state tracker | |||
* should always specify exactly what got written while the buffer was | |||
* mapped. | |||
*/ | |||
void (*buffer_unmap)( struct pipe_screen *screen, | |||
struct pipe_buffer *buf ); | |||