nvc0: add preliminary support for images
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Fri, 18 Mar 2016 10:11:24 +0000 (11:11 +0100)
committerSamuel Pitoiset <samuel.pitoiset@gmail.com>
Tue, 26 Apr 2016 17:47:49 +0000 (19:47 +0200)
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 <samuel.pitoiset@gmail.com>
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/nouveau/nvc0/nvc0_context.c
src/gallium/drivers/nouveau/nvc0/nvc0_context.h
src/gallium/drivers/nouveau/nvc0/nvc0_screen.h
src/gallium/drivers/nouveau/nvc0/nvc0_state.c
src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c

index fcb8289bedadbd6bdb28df87ecfc57000ba2d5a5..9e8fd6bbb8db6a5b665acd3c1c1c7f9dac7303da 100644 (file)
@@ -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;
index 91dffa116e16cd1f9094a19865250e51dd2404bf..617f4c2ecc32304f1367ec59aafc9a9c7ee6ad44 100644 (file)
@@ -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;
 };
 
index 0f782207f13a9b4cb1bd6a9255d3b167ad1dd946..750bba01e734624ad706574e2bfd248e64e5deef 100644 (file)
@@ -23,6 +23,7 @@
 
 #define NVC0_MAX_BUFFERS 32
 
+#define NVC0_MAX_IMAGES 8
 
 struct nvc0_context;
 
index a100fc4c47834ecad8436b5b60ae962641f4866d..e437a6479a008eea829d7983cea2e169bbcd83f3 100644 (file)
@@ -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
index d0d9315dd2bf1f77ef0c6e730f5ba10c8809d05d..b57db469109647509a03b5d217635ba1dc393347 100644 (file)
@@ -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. */