Ilia Mirkin
2015-Sep-17 18:00 UTC
[Nouveau] [PATCH v2] nv50, nvc0: detect underlying resource changes and update tic
When updating texture buffers, we might end up replacing the whole buffer. Check that the tic address matches the resource address, and if not, update the tic and reupload it. This fixes: arb_direct_state_access-texture-buffer arb_texture_buffer_object-data-sync Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu> Cc: "11.0" <mesa-stable at lists.freedesktop.org> --- v1 -> v2: take the sampler view's first_element into account, unbreaks ranges src/gallium/drivers/nouveau/nv50/nv50_tex.c | 21 +++++++++++++++++++++ src/gallium/drivers/nouveau/nvc0/nvc0_tex.c | 22 ++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/src/gallium/drivers/nouveau/nv50/nv50_tex.c b/src/gallium/drivers/nouveau/nv50/nv50_tex.c index fc6374d..6083ea9 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_tex.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_tex.c @@ -221,6 +221,26 @@ nv50_create_texture_view(struct pipe_context *pipe, return &view->pipe; } +static void +nv50_update_tic(struct nv50_context *nv50, struct nv50_tic_entry *tic, + struct nv04_resource *res) +{ + uint64_t address = res->address; + if (res->base.target != PIPE_BUFFER) + return; + address += tic->pipe.u.buf.first_element * + util_format_get_blocksize(tic->pipe.format); + if (tic->tic[1] == (uint32_t)address && + (tic->tic[2] & 0xff) == address >> 32) + return; + + nv50_screen_tic_unlock(nv50->screen, tic); + tic->id = -1; + tic->tic[1] = address; + tic->tic[2] &= 0xffffff00; + tic->tic[2] |= address >> 32; +} + static bool nv50_validate_tic(struct nv50_context *nv50, int s) { @@ -240,6 +260,7 @@ nv50_validate_tic(struct nv50_context *nv50, int s) continue; } res = &nv50_miptree(tic->pipe.texture)->base; + nv50_update_tic(nv50, tic, res); if (tic->id < 0) { tic->id = nv50_screen_tic_alloc(nv50->screen, tic); diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c b/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c index d19082e..2dd100f 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c @@ -226,6 +226,26 @@ nvc0_create_texture_view(struct pipe_context *pipe, return &view->pipe; } +static void +nvc0_update_tic(struct nvc0_context *nvc0, struct nv50_tic_entry *tic, + struct nv04_resource *res) +{ + uint64_t address = res->address; + if (res->base.target != PIPE_BUFFER) + return; + address += tic->pipe.u.buf.first_element * + util_format_get_blocksize(tic->pipe.format); + if (tic->tic[1] == (uint32_t)address && + (tic->tic[2] & 0xff) == address >> 32) + return; + + nvc0_screen_tic_unlock(nvc0->screen, tic); + tic->id = -1; + tic->tic[1] = address; + tic->tic[2] &= 0xffffff00; + tic->tic[2] |= address >> 32; +} + static bool nvc0_validate_tic(struct nvc0_context *nvc0, int s) { @@ -247,6 +267,7 @@ nvc0_validate_tic(struct nvc0_context *nvc0, int s) continue; } res = nv04_resource(tic->pipe.texture); + nvc0_update_tic(nvc0, tic, res); if (tic->id < 0) { tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic); @@ -313,6 +334,7 @@ nve4_validate_tic(struct nvc0_context *nvc0, unsigned s) continue; } res = nv04_resource(tic->pipe.texture); + nvc0_update_tic(nvc0, tic, res); if (tic->id < 0) { tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic); -- 2.4.6