On 02/10/2018 06:41 PM, Ilia Mirkin wrote:
On Sat, Feb 10, 2018 at 12:37 PM, Samuel Pitoiset
<samuel.pitoi...@gmail.com> wrote:


On 02/10/2018 06:12 AM, Ilia Mirkin wrote:

Signed-off-by: Ilia Mirkin <imir...@alum.mit.edu>
---

Tested on GM107 with DOW3 and DiRT Rally (in bindless mode). Seems to
work about as well as on Kepler, except I got a few ltc errors in DiRT
Rally. Unclear if it's related to this patch though. Could be a missing
flush somewhere.

   docs/relnotes/18.1.0.html                          |  1 +
   .../nouveau/codegen/nv50_ir_lowering_nvc0.cpp      | 32 ++++++--
   src/gallium/drivers/nouveau/nvc0/nvc0_screen.c     |  3 +-
   src/gallium/drivers/nouveau/nvc0/nvc0_tex.c        | 96
+++++++++++++++++++++-
   4 files changed, 118 insertions(+), 14 deletions(-)

diff --git a/docs/relnotes/18.1.0.html b/docs/relnotes/18.1.0.html
index b8a0cd0d02c..93cf1f2b4ff 100644
--- a/docs/relnotes/18.1.0.html
+++ b/docs/relnotes/18.1.0.html
@@ -44,6 +44,7 @@ Note: some of the new features are only available with
certain drivers.
   </p>
     <ul>
+<li>GL_ARB_bindless_texture on nvc0/maxwell+</li>
   <li>GL_EXT_semaphore on radeonsi</li>
   <li>GL_EXT_semaphore_fd on radeonsi</li>
   </ul>
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
index ddcae1e5a51..65c5bd7810b 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
@@ -2400,6 +2400,7 @@
NVC0LoweringPass::processSurfaceCoordsGM107(TexInstruction *su)
      const int dim = su->tex.target.getDim();
      const int arg = dim + (su->tex.target.isArray() ||
su->tex.target.isCube());
      Value *ind = su->getIndirectR();
+   Value *handle;
      int pos = 0;
        bld.setPosition(su, false);
@@ -2416,7 +2417,16 @@
NVC0LoweringPass::processSurfaceCoordsGM107(TexInstruction *su)
         assert(pos == 0);
         break;
      }
-   su->setSrc(arg + pos, loadTexHandle(ind, slot + 32));
+   if (su->tex.bindless)
+      handle = ind;
+   else
+      handle = loadTexHandle(ind, slot + 32);
+   su->setSrc(arg + pos, handle);
+
+   // The address check doesn't make sense here. The format check could
make
+   // sense but it's a bit of a pain.
+   if (su->tex.bindless)
+      return;
        // prevent read fault when the image is not actually bound
      CmpInstruction *pred =
@@ -2450,18 +2460,22 @@
NVC0LoweringPass::handleSurfaceOpGM107(TexInstruction *su)
         Value *def = su->getDef(0);
           su->op = OP_SUREDB;
-      su->setDef(0, bld.getSSA());
   -      bld.setPosition(su, true);
+      // There may not be a predicate in the bindless case.
+      if (su->getPredicate()) {
+         su->setDef(0, bld.getSSA());
   -      // make sure to initialize dst value when the atomic operation is
not
-      // performed
-      Instruction *mov = bld.mkMov(bld.getSSA(), bld.loadImm(NULL, 0));
+         bld.setPosition(su, true);
   -      assert(su->cc == CC_NOT_P);
-      mov->setPredicate(CC_P, su->getPredicate());
+         // make sure to initialize dst value when the atomic operation
is not
+         // performed
+         Instruction *mov = bld.mkMov(bld.getSSA(), bld.loadImm(NULL,
0));
+
+         assert(su->cc == CC_NOT_P);
+         mov->setPredicate(CC_P, su->getPredicate());
   -      bld.mkOp2(OP_UNION, TYPE_U32, def, su->getDef(0),
mov->getDef(0));
+         bld.mkOp2(OP_UNION, TYPE_U32, def, su->getDef(0),
mov->getDef(0));
+      }
      }
   }
   diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
index 7ba8086a533..b3d7768aed7 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
@@ -266,9 +266,8 @@ nvc0_screen_get_param(struct pipe_screen *pscreen,
enum pipe_cap param)
         return class_3d >= GM200_3D_CLASS;
      case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
      case PIPE_CAP_TGSI_BALLOT:
-      return class_3d >= NVE4_3D_CLASS;
      case PIPE_CAP_BINDLESS_TEXTURE:
-      return class_3d >= NVE4_3D_CLASS && class_3d < GM107_3D_CLASS;
+      return class_3d >= NVE4_3D_CLASS;
        /* unsupported caps */
      case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c
b/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c
index 9e391fe1acf..ce58cced916 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c
@@ -1386,15 +1386,105 @@ nve4_make_image_handle_resident(struct
pipe_context *pipe, uint64_t handle,
      }
   }
   +static uint64_t
+gm107_create_image_handle(struct pipe_context *pipe,
+                          const struct pipe_image_view *view)
+{
+   /* GM107+ use TIC handles to reference images. As such, image handles
are
+    * just the TIC id.
+    */
+   struct nvc0_context *nvc0 = nvc0_context(pipe);
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
+   struct pipe_sampler_view *sview =
+      gm107_create_texture_view_from_image(pipe, view);
+   struct nv50_tic_entry *tic = nv50_tic_entry(sview);
+
+   if (tic == NULL)
+      goto fail;
+
+   tic->bindless = 1;
+   tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic);
+   if (tic->id < 0)
+      goto fail;
+
+   nve4_p2mf_push_linear(&nvc0->base, nvc0->screen->txc, tic->id * 32,
+                         NV_VRAM_DOMAIN(&nvc0->screen->base), 32,
+                         tic->tic);
+
+   IMMED_NVC0(push, NVC0_3D(TIC_FLUSH), 0);
+
+   nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);
+
+   return 0x100000000ULL | tic->id;
+
+fail:
+   if (tic)
+      FREE(tic);


Do we really need the conditional here, I don't think but your call.

FREE(null)? I guess that's OK. I can drop the conditional.



+   return 0;
+}
+
+static void
+gm107_delete_image_handle(struct pipe_context *pipe, uint64_t handle)
+{
+   struct nvc0_context *nvc0 = nvc0_context(pipe);
+   int tic = handle & NVE4_TIC_ENTRY_INVALID;
+   struct nv50_tic_entry *entry = nvc0->screen->tic.entries[tic];
+   struct pipe_sampler_view *view = &entry->pipe;
+   assert(entry->bindless == 1);
+   assert(!view_bound(nvc0, view));
+   entry->bindless = 0;
+   nvc0_screen_tic_unlock(nvc0->screen, entry);
+   pipe_sampler_view_reference(&view, NULL);
+}
+
+static void
+gm107_make_image_handle_resident(struct pipe_context *pipe, uint64_t
handle,
+                                 unsigned access, bool resident)
+{
+   struct nvc0_context *nvc0 = nvc0_context(pipe);
+
+   if (resident) {
+      struct nvc0_resident *res = calloc(1, sizeof(struct
nvc0_resident));
+      struct nv50_tic_entry *tic =
+         nvc0->screen->tic.entries[handle & NVE4_TIC_ENTRY_INVALID];
+      assert(tic);
+      assert(tic->bindless);
+
+      res->handle = handle;
+      res->buf = nv04_resource(tic->pipe.texture);
+      res->flags = (access & 3) << 8;


(access & 3) looks useless, gallium should correctly set that flag, maybe
add an assertion instead?

Yeah, but tomorrow someone will add another flag we don't care about
but that will mess this up. It's converting from one set of flags to
another, so I want to be conservative.

Good point!



Nice work, looks good to me!

Thanks!



+      if (res->buf->base.target == PIPE_BUFFER &&
+          access & PIPE_IMAGE_ACCESS_WRITE)
+         util_range_add(&res->buf->valid_buffer_range,
+                        tic->pipe.u.buf.offset,
+                        tic->pipe.u.buf.offset + tic->pipe.u.buf.size);
+      list_add(&res->list, &nvc0->img_head);
+   } else {
+      list_for_each_entry_safe(struct nvc0_resident, pos,
&nvc0->img_head, list) {
+         if (pos->handle == handle) {
+            list_del(&pos->list);
+            free(pos);
+            break;
+         }
+      }
+   }
+}
+
   void
   nvc0_init_bindless_functions(struct pipe_context *pipe) {
      pipe->create_texture_handle = nve4_create_texture_handle;
      pipe->delete_texture_handle = nve4_delete_texture_handle;
      pipe->make_texture_handle_resident =
nve4_make_texture_handle_resident;
   -   pipe->create_image_handle = nve4_create_image_handle;
-   pipe->delete_image_handle = nve4_delete_image_handle;
-   pipe->make_image_handle_resident = nve4_make_image_handle_resident;
+   if (nvc0_context(pipe)->screen->base.class_3d < GM107_3D_CLASS) {
+      pipe->create_image_handle = nve4_create_image_handle;
+      pipe->delete_image_handle = nve4_delete_image_handle;
+      pipe->make_image_handle_resident = nve4_make_image_handle_resident;
+   } else {
+      pipe->create_image_handle = gm107_create_image_handle;
+      pipe->delete_image_handle = gm107_delete_image_handle;
+      pipe->make_image_handle_resident =
gm107_make_image_handle_resident;
+   }
   }

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to