From afa04785fade4ed032a621db13e0a03505afa7ee Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Fri, 18 Mar 2016 11:11:24 +0100 Subject: [PATCH] nvc0: add preliminary support for images This implements set_shader_images() and resource invalidation for images. As OpenGL requires at least 8 images, we are going to expose this minimum value even if this might be raised for Kepler, but this limit is mainly for Fermi because the hardware only accepts 8 images. Based on original patch by Ilia Mirkin. Signed-off-by: Samuel Pitoiset Reviewed-by: Ilia Mirkin --- .../drivers/nouveau/nvc0/nvc0_context.c | 17 ++++++ .../drivers/nouveau/nvc0/nvc0_context.h | 4 ++ .../drivers/nouveau/nvc0/nvc0_screen.h | 1 + src/gallium/drivers/nouveau/nvc0/nvc0_state.c | 53 ++++++++++++++++++- .../nouveau/nvc0/nvc0_state_validate.c | 1 + 5 files changed, 74 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c index fcb8289beda..9e8fd6bbb8d 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c @@ -301,6 +301,23 @@ nvc0_invalidate_resource_storage(struct nouveau_context *ctx, } } } + + for (s = 0; s < 6; ++s) { + for (i = 0; i < NVC0_MAX_IMAGES; ++i) { + if (nvc0->images[s][i].resource == res) { + nvc0->images_dirty[s] |= 1 << i; + if (unlikely(s == 5)) { + nvc0->dirty_cp |= NVC0_NEW_CP_SURFACES; + nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_SUF); + } else { + nvc0->dirty_3d |= NVC0_NEW_3D_SURFACES; + nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_SUF); + } + } + if (!--ref) + return ref; + } + } } return ref; diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h index 91dffa116e1..617f4c2ecc3 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h @@ -237,6 +237,10 @@ struct nvc0_context { uint32_t buffers_dirty[6]; uint32_t buffers_valid[6]; + struct pipe_image_view images[6][NVC0_MAX_IMAGES]; + uint16_t images_dirty[6]; + uint16_t images_valid[6]; + struct util_dynarray global_residents; }; diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h index 0f782207f13..750bba01e73 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h @@ -23,6 +23,7 @@ #define NVC0_MAX_BUFFERS 32 +#define NVC0_MAX_IMAGES 8 struct nvc0_context; diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c index a100fc4c478..e437a6479a0 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c @@ -1231,11 +1231,60 @@ nvc0_set_compute_resources(struct pipe_context *pipe, nvc0_context(pipe)->dirty_cp |= NVC0_NEW_CP_SURFACES; } +static void +nvc0_bind_images_range(struct nvc0_context *nvc0, const unsigned s, + unsigned start, unsigned nr, + struct pipe_image_view *pimages) +{ + const unsigned end = start + nr; + const unsigned mask = ((1 << nr) - 1) << start; + unsigned i; + + assert(s < 6); + + if (pimages) { + for (i = start; i < end; ++i) { + const unsigned p = i - start; + if (pimages[p].resource) + nvc0->images_valid[s] |= (1 << i); + else + nvc0->images_valid[s] &= ~(1 << i); + + nvc0->images[s][i].format = pimages[p].format; + nvc0->images[s][i].access = pimages[p].access; + if (pimages[p].resource->target == PIPE_BUFFER) + nvc0->images[s][i].u.buf = pimages[p].u.buf; + else + nvc0->images[s][i].u.tex = pimages[p].u.tex; + + pipe_resource_reference( + &nvc0->images[s][i].resource, pimages[p].resource); + } + } else { + for (i = start; i < end; ++i) + pipe_resource_reference(&nvc0->images[s][i].resource, NULL); + nvc0->images_valid[s] &= ~mask; + } + nvc0->images_dirty[s] |= mask; + + if (s == 5) + nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_SUF); + else + nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_SUF); +} + static void nvc0_set_shader_images(struct pipe_context *pipe, unsigned shader, - unsigned start_slot, unsigned count, - struct pipe_image_view *views) + unsigned start, unsigned nr, + struct pipe_image_view *images) { + const unsigned s = nvc0_shader_stage(shader); + nvc0_bind_images_range(nvc0_context(pipe), s, start, nr, images); + + if (s == 5) + nvc0_context(pipe)->dirty_cp |= NVC0_NEW_CP_SURFACES; + else + nvc0_context(pipe)->dirty_3d |= NVC0_NEW_3D_SURFACES; } static void diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c index d0d9315dd2b..b57db469109 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c @@ -665,6 +665,7 @@ nvc0_switch_pipe_context(struct nvc0_context *ctx_to) ctx_to->textures_dirty[s] = ~0; ctx_to->constbuf_dirty[s] = (1 << NVC0_MAX_PIPE_CONSTBUFS) - 1; ctx_to->buffers_dirty[s] = ~0; + ctx_to->images_dirty[s] = ~0; } /* Reset tfb as the shader that owns it may have been deleted. */ -- 2.30.2