mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 04:38:03 +02:00
r600g,radeonsi: attempt to fix racy multi-context apps calling BufferData
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=75061 v2: minimize the window where cs_buf != new_buf
This commit is contained in:
parent
74d95adea0
commit
e1a9a54464
3 changed files with 18 additions and 14 deletions
|
|
@ -2292,10 +2292,7 @@ static void r600_invalidate_buffer(struct pipe_context *ctx, struct pipe_resourc
|
|||
struct r600_resource *rbuffer = r600_resource(buf);
|
||||
unsigned i, shader, mask, alignment = rbuffer->buf->alignment;
|
||||
|
||||
/* Discard the buffer. */
|
||||
pb_reference(&rbuffer->buf, NULL);
|
||||
|
||||
/* Create a new one in the same pipe_resource. */
|
||||
/* Reallocate the buffer in the same pipe_resource. */
|
||||
r600_init_resource(&rctx->screen->b, rbuffer, rbuffer->b.b.width0,
|
||||
alignment, TRUE);
|
||||
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ bool r600_init_resource(struct r600_common_screen *rscreen,
|
|||
bool use_reusable_pool)
|
||||
{
|
||||
struct r600_texture *rtex = (struct r600_texture*)res;
|
||||
struct pb_buffer *old_buf, *new_buf;
|
||||
|
||||
switch (res->b.b.usage) {
|
||||
case PIPE_USAGE_STAGING:
|
||||
|
|
@ -136,15 +137,23 @@ bool r600_init_resource(struct r600_common_screen *rscreen,
|
|||
res->domains = RADEON_DOMAIN_VRAM;
|
||||
}
|
||||
|
||||
/* Allocate the resource. */
|
||||
res->buf = rscreen->ws->buffer_create(rscreen->ws, size, alignment,
|
||||
use_reusable_pool,
|
||||
res->domains);
|
||||
if (!res->buf) {
|
||||
/* Allocate a new resource. */
|
||||
new_buf = rscreen->ws->buffer_create(rscreen->ws, size, alignment,
|
||||
use_reusable_pool,
|
||||
res->domains);
|
||||
if (!new_buf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
res->cs_buf = rscreen->ws->buffer_get_cs_handle(res->buf);
|
||||
/* Replace the pointer such that if res->buf wasn't NULL, it won't be
|
||||
* NULL. This should prevent crashes with multiple contexts using
|
||||
* the same buffer where one of the contexts invalidates it while
|
||||
* the others are using it. */
|
||||
old_buf = res->buf;
|
||||
res->cs_buf = rscreen->ws->buffer_get_cs_handle(new_buf); /* should be atomic */
|
||||
res->buf = new_buf; /* should be atomic */
|
||||
pb_reference(&old_buf, NULL);
|
||||
|
||||
util_range_set_empty(&res->valid_buffer_range);
|
||||
|
||||
if (rscreen->debug_flags & DBG_VM && res->b.b.target == PIPE_BUFFER) {
|
||||
|
|
@ -363,6 +372,7 @@ struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
|
|||
pipe_reference_init(&rbuffer->b.b.reference, 1);
|
||||
rbuffer->b.b.screen = screen;
|
||||
rbuffer->b.vtbl = &r600_buffer_vtbl;
|
||||
rbuffer->buf = NULL;
|
||||
util_range_init(&rbuffer->valid_buffer_range);
|
||||
|
||||
if (!r600_init_resource(rscreen, rbuffer, templ->width0, alignment, TRUE)) {
|
||||
|
|
|
|||
|
|
@ -723,10 +723,7 @@ static void si_invalidate_buffer(struct pipe_context *ctx, struct pipe_resource
|
|||
unsigned i, shader, alignment = rbuffer->buf->alignment;
|
||||
uint64_t old_va = r600_resource_va(ctx->screen, buf);
|
||||
|
||||
/* Discard the buffer. */
|
||||
pb_reference(&rbuffer->buf, NULL);
|
||||
|
||||
/* Create a new one in the same pipe_resource. */
|
||||
/* Reallocate the buffer in the same pipe_resource. */
|
||||
r600_init_resource(&sctx->screen->b, rbuffer, rbuffer->b.b.width0,
|
||||
alignment, TRUE);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue