summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2015-09-15 01:32:40 -0400
committerIlia Mirkin <[email protected]>2015-09-17 19:50:47 -0400
commit323c91250682ac931941047f282a613c74b1ba26 (patch)
treeb630973ab9b86c7a80a54c1317268837b6e85955
parent8d3b92af21afb58b6a65e18bb05785d7aae72c27 (diff)
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 <[email protected]> Cc: "11.0" <[email protected]>
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_tex.c21
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_tex.c22
2 files changed, 43 insertions, 0 deletions
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_tex.c b/src/gallium/drivers/nouveau/nv50/nv50_tex.c
index fc6374d1b1b..6083ea995c8 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 d19082e0e15..2dd100ffdc7 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);