diff options
author | José Fonseca <[email protected]> | 2010-03-13 16:13:26 +0000 |
---|---|---|
committer | José Fonseca <[email protected]> | 2010-03-13 16:13:26 +0000 |
commit | bf40c346637325862d6d9cdbc9838c5726abc0c0 (patch) | |
tree | 319879161ef4693a983a05c6381bf4fd41fc801e /src/gallium/drivers/llvmpipe/lp_flush.c | |
parent | 3abc7b985ce0787c5103d1a86bd0ba07b127a82f (diff) |
llvmpipe: Ensure the context is flushed before modifying textures.
Diffstat (limited to 'src/gallium/drivers/llvmpipe/lp_flush.c')
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_flush.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c index 1b4e8899359..636d72a9bb8 100644 --- a/src/gallium/drivers/llvmpipe/lp_flush.c +++ b/src/gallium/drivers/llvmpipe/lp_flush.c @@ -92,3 +92,68 @@ llvmpipe_flush( struct pipe_context *pipe, #endif } + +/** + * Flush context if necessary. + * + * TODO: move this logic to an auxiliary library? + * + * FIXME: We must implement DISCARD/DONTBLOCK/UNSYNCHRONIZED/etc for + * textures to avoid blocking. + */ +boolean +llvmpipe_flush_texture(struct pipe_context *pipe, + struct pipe_texture *texture, + unsigned face, + unsigned level, + unsigned flush_flags, + boolean read_only, + boolean cpu_access, + boolean do_not_flush) +{ + struct pipe_fence_handle *last_fence = NULL; + unsigned referenced; + + referenced = pipe->is_texture_referenced(pipe, texture, face, level); + + if ((referenced & PIPE_REFERENCED_FOR_WRITE) || + ((referenced & PIPE_REFERENCED_FOR_READ) && !read_only)) { + + if (do_not_flush) + return FALSE; + + /* + * TODO: The semantics of these flush flags are too obtuse. They should + * disappear and the pipe driver should just ensure that all visible + * side-effects happen when they need to happen. + */ + if (referenced & PIPE_REFERENCED_FOR_WRITE) + flush_flags |= PIPE_FLUSH_RENDER_CACHE; + + if (referenced & PIPE_REFERENCED_FOR_READ) + flush_flags |= PIPE_FLUSH_TEXTURE_CACHE; + + if (cpu_access) { + /* + * Flush and wait. + */ + + struct pipe_fence_handle *fence = NULL; + + pipe->flush(pipe, flush_flags, &fence); + + if (last_fence) { + pipe->screen->fence_finish(pipe->screen, fence, 0); + pipe->screen->fence_reference(pipe->screen, &fence, NULL); + } + } else { + /* + * Just flush. + */ + + pipe->flush(pipe, flush_flags, NULL); + } + } + + return TRUE; +} |