summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nouveau
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2019-02-03 21:55:12 -0500
committerIlia Mirkin <[email protected]>2019-02-06 19:35:57 -0500
commit162352e6711b3ceab114686f7a3248074339e7f7 (patch)
treeb43d8d2b791a984fbb34aa7f902e21979d99f2b2 /src/gallium/drivers/nouveau
parent5de5beedf21306b01730085f8e03d8f424729016 (diff)
nvc0: fix 3d images on kepler
Looks like SUBFM.3D and SUEAU are perfectly capable of dealing with 3d tiling, they just need the correct inputs. Supply them. We also have to deal with the case where a 2d "layer" of a 3d image is bound. In this case, we supply the z coordinate separately to the shader, which has to optionally treat every 2d case as if it could be a slice of a 3d texture. Signed-off-by: Ilia Mirkin <[email protected]> Cc: 19.0 <[email protected]>
Diffstat (limited to 'src/gallium/drivers/nouveau')
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp46
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_tex.c23
2 files changed, 34 insertions, 35 deletions
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 45474f07547..34cb7dc3e4b 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
@@ -1934,7 +1934,8 @@ NVC0LoweringPass::processSurfaceCoordsNVE4(TexInstruction *su)
su->op == OP_SULDB || su->op == OP_SUSTB || su->op == OP_SUREDB;
const int slot = su->tex.r;
const int dim = su->tex.target.getDim();
- const int arg = dim + (su->tex.target.isArray() || su->tex.target.isCube());
+ const bool array = su->tex.target.isArray() || su->tex.target.isCube();
+ const int arg = dim + array;
int c;
Value *zero = bld.mkImm(0);
Value *p1 = NULL;
@@ -1943,6 +1944,7 @@ NVC0LoweringPass::processSurfaceCoordsNVE4(TexInstruction *su)
Value *bf, *eau, *off;
Value *addr, *pred;
Value *ind = su->getIndirectR();
+ Value *y, *z;
off = bld.getScratch(4);
bf = bld.getScratch(4);
@@ -1973,34 +1975,42 @@ NVC0LoweringPass::processSurfaceCoordsNVE4(TexInstruction *su)
for (; c < 3; ++c)
src[c] = zero;
+ if (dim == 2 && !array) {
+ v = loadSuInfo32(ind, slot, NVC0_SU_INFO_UNK1C, su->tex.bindless);
+ src[2] = bld.mkOp2v(OP_SHR, TYPE_U32, bld.getSSA(),
+ v, bld.loadImm(NULL, 16));
+
+ v = loadSuInfo32(ind, slot, NVC0_SU_INFO_DIM(2), su->tex.bindless);
+ bld.mkOp3(OP_SUCLAMP, TYPE_S32, src[2], src[2], v, zero)
+ ->subOp = NV50_IR_SUBOP_SUCLAMP_SD(0, 2);
+ }
+
// set predicate output
if (su->tex.target == TEX_TARGET_BUFFER) {
src[0]->getInsn()->setFlagsDef(1, pred);
} else
- if (su->tex.target.isArray() || su->tex.target.isCube()) {
+ if (array) {
p1 = bld.getSSA(1, FILE_PREDICATE);
src[dim]->getInsn()->setFlagsDef(1, p1);
}
// calculate pixel offset
if (dim == 1) {
+ y = z = zero;
if (su->tex.target != TEX_TARGET_BUFFER)
bld.mkOp2(OP_AND, TYPE_U32, off, src[0], bld.loadImm(NULL, 0xffff));
- } else
- if (dim == 3) {
+ } else {
+ y = src[1];
+ z = src[2];
+
v = loadSuInfo32(ind, slot, NVC0_SU_INFO_UNK1C, su->tex.bindless);
bld.mkOp3(OP_MADSP, TYPE_U32, off, src[2], v, src[1])
- ->subOp = NV50_IR_SUBOP_MADSP(4,2,8); // u16l u16l u16l
+ ->subOp = NV50_IR_SUBOP_MADSP(4,4,8); // u16l u16l u16l
v = loadSuInfo32(ind, slot, NVC0_SU_INFO_PITCH, su->tex.bindless);
bld.mkOp3(OP_MADSP, TYPE_U32, off, off, v, src[0])
- ->subOp = NV50_IR_SUBOP_MADSP(0,2,8); // u32 u16l u16l
- } else {
- assert(dim == 2);
- v = loadSuInfo32(ind, slot, NVC0_SU_INFO_PITCH, su->tex.bindless);
- bld.mkOp3(OP_MADSP, TYPE_U32, off, src[1], v, src[0])
- ->subOp = (su->tex.target.isArray() || su->tex.target.isCube()) ?
- NV50_IR_SUBOP_MADSP_SD : NV50_IR_SUBOP_MADSP(4,2,8); // u16l u16l u16l
+ ->subOp = array ?
+ NV50_IR_SUBOP_MADSP_SD : NV50_IR_SUBOP_MADSP(0,2,8); // u32 u16l u16l
}
// calculate effective address part 1
@@ -2013,19 +2023,15 @@ NVC0LoweringPass::processSurfaceCoordsNVE4(TexInstruction *su)
->subOp = NV50_IR_SUBOP_V1(7,6,8|2);
}
} else {
- Value *y = src[1];
- Value *z = src[2];
uint16_t subOp = 0;
switch (dim) {
case 1:
- y = zero;
- z = zero;
break;
case 2:
- z = off;
- if (!su->tex.target.isArray() && !su->tex.target.isCube()) {
- z = loadSuInfo32(ind, slot, NVC0_SU_INFO_UNK1C, su->tex.bindless);
+ if (array) {
+ z = off;
+ } else {
subOp = NV50_IR_SUBOP_SUBFM_3D;
}
break;
@@ -2048,7 +2054,7 @@ NVC0LoweringPass::processSurfaceCoordsNVE4(TexInstruction *su)
eau = bld.mkOp3v(OP_SUEAU, TYPE_U32, bld.getScratch(4), off, bf, v);
}
// add array layer offset
- if (su->tex.target.isArray() || su->tex.target.isCube()) {
+ if (array) {
v = loadSuInfo32(ind, slot, NVC0_SU_INFO_ARRAY, su->tex.bindless);
if (dim == 1)
bld.mkOp3(OP_MADSP, TYPE_U32, eau, src[1], v, eau)
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c b/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c
index 04f0a0d55da..8820b5aac66 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c
@@ -1051,21 +1051,13 @@ nve4_set_surface_info(struct nouveau_pushbuf *push,
} else {
struct nv50_miptree *mt = nv50_miptree(&res->base);
struct nv50_miptree_level *lvl = &mt->level[view->u.tex.level];
- const unsigned z = view->u.tex.first_layer;
-
- if (z) {
- if (mt->layout_3d) {
- address += nvc0_mt_zslice_offset(mt, view->u.tex.level, z);
- /* doesn't work if z passes z-tile boundary */
- if (depth > 1) {
- pipe_debug_message(&nvc0->base.debug, CONFORMANCE,
- "3D images are not really supported!");
- debug_printf("3D images are not really supported!\n");
- }
- } else {
- address += mt->layer_stride * z;
- }
+ unsigned z = view->u.tex.first_layer;
+
+ if (!mt->layout_3d) {
+ address += mt->layer_stride * z;
+ z = 0;
}
+
address += lvl->offset;
info[0] = address >> 8;
@@ -1080,7 +1072,8 @@ nve4_set_surface_info(struct nouveau_pushbuf *push,
info[6] = depth - 1;
info[6] |= (lvl->tile_mode & 0xf00) << 21;
info[6] |= NVC0_TILE_SHIFT_Z(lvl->tile_mode) << 22;
- info[7] = 0;
+ info[7] = mt->layout_3d ? 1 : 0;
+ info[7] |= z << 16;
info[14] = mt->ms_x;
info[15] = mt->ms_y;
}