summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/pipebuffer
diff options
context:
space:
mode:
authorJosé Fonseca <[email protected]>2008-04-22 19:47:02 +0900
committerJosé Fonseca <[email protected]>2008-04-22 19:47:12 +0900
commitb4b3a73bdf68adc1d9fbadac913aa6cf60d648d5 (patch)
tree3e16f4205fe5144645626d6be187ac6985c64f18 /src/gallium/auxiliary/pipebuffer
parent57987ea67320e79e4c2d7e66388806148ece09b5 (diff)
pipebuffer: Temporarily allow simultaneous CPU writes.
Also, fast path for re-fencing the same buffer multiple times with the same fence.
Diffstat (limited to 'src/gallium/auxiliary/pipebuffer')
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
index 65b6584003a..27032b0c4c0 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
@@ -215,15 +215,21 @@ fenced_buffer_serialize(struct fenced_buffer *fenced_buf, unsigned flags)
struct fenced_buffer_list *fenced_list = fenced_buf->list;
struct pipe_winsys *winsys = fenced_list->winsys;
+ /* Allow concurrent reads */
if(((fenced_buf->flags | flags) & PIPE_BUFFER_USAGE_WRITE) == 0)
return PIPE_OK;
+ /* Wait for the CPU to finish */
if(fenced_buf->mapcount) {
- /* FIXME */
+ /* FIXME: Use thread conditions variables to signal when mapcount
+ * reaches zero */
debug_warning("attemp to write concurrently to buffer");
+ /* XXX: we must not fail here in order to support texture mipmap generation
return PIPE_ERROR_RETRY;
+ */
}
+ /* Wait for the GPU to finish */
if(fenced_buf->fence) {
if(winsys->fence_finish(winsys, fenced_buf->fence, 0) != 0)
return PIPE_ERROR_RETRY;
@@ -353,6 +359,16 @@ buffer_fence(struct pb_buffer *buf,
/* FIXME: receive this as a parameter */
unsigned flags = fence ? PIPE_BUFFER_USAGE_GPU_READ_WRITE : 0;
+ if(fence == fenced_buf->fence) {
+ /* Handle the same fence case specially, not only because it is a fast
+ * path, but mostly to avoid serializing two writes with the same fence,
+ * as that would bring the hardware down to synchronous operation without
+ * any benefit.
+ */
+ fenced_buf->flags |= flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE;
+ return;
+ }
+
if(fenced_buffer_serialize(fenced_buf, flags) != PIPE_OK) {
/* FIXME: propagate error */
(void)0;