From f08fd676bf651ba401ca631a22e3586a85f99415 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sat, 13 Jan 2018 12:32:41 -0500 Subject: [PATCH] nvc0: add support for bindless on maxwell+ Signed-off-by: Ilia Mirkin --- docs/relnotes/18.1.0.html | 1 + .../nouveau/codegen/nv50_ir_lowering_nvc0.cpp | 32 +++++-- .../drivers/nouveau/nvc0/nvc0_screen.c | 3 +- src/gallium/drivers/nouveau/nvc0/nvc0_tex.c | 95 ++++++++++++++++++- 4 files changed, 117 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.

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 e07f57e782d..5e9ffc0d463 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp @@ -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)); + } } } diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c index e9072c1ed86..2052e84b586 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..0471fffe835 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c @@ -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; + } } -- 2.30.2