llvmpipe: Ensure the context is flushed before modifying textures.
This commit is contained in:
parent
3abc7b985c
commit
bf40c34663
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -28,10 +28,22 @@
|
|||
#ifndef LP_FLUSH_H
|
||||
#define LP_FLUSH_H
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
|
||||
struct pipe_context;
|
||||
struct pipe_fence_handle;
|
||||
|
||||
void llvmpipe_flush(struct pipe_context *pipe, unsigned flags,
|
||||
struct pipe_fence_handle **fence);
|
||||
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "util/u_rect.h"
|
||||
#include "lp_context.h"
|
||||
#include "lp_flush.h"
|
||||
#include "lp_surface.h"
|
||||
|
||||
|
||||
|
@ -36,6 +37,20 @@ lp_surface_copy(struct pipe_context *pipe,
|
|||
struct pipe_surface *src, unsigned srcx, unsigned srcy,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
llvmpipe_flush_texture(pipe,
|
||||
dest->texture, dest->face, dest->level,
|
||||
0, /* flush_flags */
|
||||
FALSE, /* read_only */
|
||||
FALSE, /* cpu_access */
|
||||
FALSE); /* do_not_flush */
|
||||
|
||||
llvmpipe_flush_texture(pipe,
|
||||
src->texture, src->face, src->level,
|
||||
0, /* flush_flags */
|
||||
TRUE, /* read_only */
|
||||
FALSE, /* cpu_access */
|
||||
FALSE); /* do_not_flush */
|
||||
|
||||
util_surface_copy(pipe, FALSE,
|
||||
dest, destx, desty,
|
||||
src, srcx, srcy,
|
||||
|
|
|
@ -371,6 +371,16 @@ llvmpipe_transfer_map( struct pipe_context *pipe,
|
|||
lpt = llvmpipe_texture(transfer->texture);
|
||||
format = lpt->base.format;
|
||||
|
||||
/*
|
||||
* Transfers, like other pipe operations, must happen in order, so flush the
|
||||
* context if necessary.
|
||||
*/
|
||||
llvmpipe_flush_texture(pipe,
|
||||
transfer->texture, transfer->face, transfer->level,
|
||||
0, /* flush_flags */
|
||||
!(transfer->usage & PIPE_TRANSFER_WRITE), /* read_only */
|
||||
TRUE, /* cpu_access */
|
||||
FALSE); /* do_not_flush */
|
||||
|
||||
map = llvmpipe_texture_map(transfer->texture,
|
||||
transfer->face, transfer->level, transfer->zslice);
|
||||
|
|
Loading…
Reference in New Issue