nvc0: add support for bindless on maxwell+
authorIlia Mirkin <imirkin@alum.mit.edu>
Sat, 13 Jan 2018 17:32:41 +0000 (12:32 -0500)
committerIlia Mirkin <imirkin@alum.mit.edu>
Sun, 18 Feb 2018 04:41:21 +0000 (23:41 -0500)
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
docs/relnotes/18.1.0.html
src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
src/gallium/drivers/nouveau/nvc0/nvc0_tex.c

index b8a0cd0d02c3d1e621853b33c1e699520fcffe1c..93cf1f2b4ff7f68070bedbb94e992db5e3e05116 100644 (file)
@@ -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>
index e07f57e782ddb8010d14de2f7b4e0a4e4a9fb24b..5e9ffc0d46377ce1f32208101b73cd390320055e 100644 (file)
@@ -2344,6 +2344,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);
@@ -2360,7 +2361,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 =
@@ -2394,18 +2404,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));
 
-      bld.mkOp2(OP_UNION, TYPE_U32, def, su->getDef(0), mov->getDef(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));
+      }
    }
 }
 
index e9072c1ed86eb6a08aa14ecffee2f8fd2ec0645e..2052e84b586dbf1c3c1724634d56be1c2a0995bf 100644 (file)
@@ -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:
index 9e391fe1acf33512229c1b1eae1718ec67a43a5d..0471fffe835946162231437a1399acce08015af9 100644 (file)
@@ -1386,15 +1386,104 @@ 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:
+   FREE(tic);
+   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;
+      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;
+   }
 }