nvc0: fix up image support for allowing multiple samples
authorIlia Mirkin <imirkin@alum.mit.edu>
Wed, 29 Jun 2016 04:08:01 +0000 (00:08 -0400)
committerIlia Mirkin <imirkin@alum.mit.edu>
Sat, 2 Jul 2016 03:01:02 +0000 (23:01 -0400)
Basically we just have to scale up the coordinates and then add the
relevant sample offset. The code to handle this was already largely
present from Christoph's earlier attempts to pipe images through back in
the dark ages, this just hooks it all up.

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
src/gallium/drivers/nouveau/nvc0/nvc0_compute.c
src/gallium/drivers/nouveau/nvc0/nvc0_context.h
src/gallium/drivers/nouveau/nvc0/nvc0_program.c
src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
src/gallium/drivers/nouveau/nvc0/nvc0_tex.c

index ed3249e67b195167926ab25d452f3411c45521fd..41dc18f8859419692e31821c2d84253da5b0fb14 100644 (file)
@@ -2388,6 +2388,9 @@ Converter::getImageCoords(std::vector<Value *> &coords, int r, int s)
 
    for (int c = 0; c < arg; ++c)
       coords.push_back(fetchSrc(s, c));
+
+   if (t.isMS())
+      coords.push_back(fetchSrc(s, 3));
 }
 
 // For raw loads, granularity is 4 byte.
index 67bd73bc8c711cf7436d6dd4668294fc110b877d..0558ae0e7c0e8f7a09dc8969ca09360cc05257e1 100644 (file)
@@ -1569,44 +1569,51 @@ static inline uint16_t getSuClampSubOp(const TexInstruction *su, int c)
 bool
 NVC0LoweringPass::handleSUQ(TexInstruction *suq)
 {
+   int mask = suq->tex.mask;
    int dim = suq->tex.target.getDim();
    int arg = dim + (suq->tex.target.isArray() || suq->tex.target.isCube());
-   uint8_t s = prog->driver->io.auxCBSlot;
    Value *ind = suq->getIndirectR();
    uint32_t base;
-   int c;
-
-   base = prog->driver->io.suInfoBase + suq->tex.r * NVE4_SU_INFO__STRIDE;
+   int c, d;
 
-   if (ind)
-      ind = bld.mkOp2v(OP_SHL, TYPE_U32, bld.getScratch(),
+   if (ind) {
+      ind = bld.mkOp2v(OP_ADD, TYPE_U32, bld.getSSA(),
+                       ind, bld.mkImm(suq->tex.r));
+      ind = bld.mkOp2v(OP_AND, TYPE_U32, bld.getSSA(),
+                       ind, bld.mkImm(7));
+      ind = bld.mkOp2v(OP_SHL, TYPE_U32, bld.getSSA(),
                        ind, bld.mkImm(6));
+      base = 0;
+   } else {
+      base = suq->tex.r * NVE4_SU_INFO__STRIDE;
+   }
 
-   for (c = 0; c < arg; ++c) {
-      if (suq->defExists(c)) {
-         int offset;
+   for (c = 0, d = 0; c < 3; ++c, mask >>= 1) {
+      if (c >= arg || !(mask & 1))
+         continue;
 
-         if (c == 1 && suq->tex.target == TEX_TARGET_1D_ARRAY) {
-            offset = base + NVE4_SU_INFO_SIZE(2);
-         } else {
-            offset = base + NVE4_SU_INFO_SIZE(c);
-         }
-         bld.mkLoad(TYPE_U32, suq->getDef(c),
-                    bld.mkSymbol(FILE_MEMORY_CONST, s, TYPE_U32, offset), ind);
-      }
-   }
+      int offset;
 
-   if (suq->tex.target.isCube()) {
-      if (suq->defExists(2)) {
-         bld.mkOp2(OP_DIV, TYPE_U32, suq->getDef(2), suq->getDef(2),
-                   bld.loadImm(NULL, 6));
+      if (c == 1 && suq->tex.target == TEX_TARGET_1D_ARRAY) {
+         offset = NVE4_SU_INFO_SIZE(2);
+      } else {
+         offset = NVE4_SU_INFO_SIZE(c);
       }
+      bld.mkMov(suq->getDef(d++), loadSuInfo32(ind, base + offset));
+      if (c == 2 && suq->tex.target.isCube())
+         bld.mkOp2(OP_DIV, TYPE_U32, suq->getDef(d - 1), suq->getDef(d - 1),
+                   bld.loadImm(NULL, 6));
    }
 
-   if (suq->defExists(3)) {
-      // .w contains the number of samples for multi-sampled images but we
-      // don't support them for now.
-      bld.mkMov(suq->getDef(3), bld.loadImm(NULL, 1));
+   if (mask & 1) {
+      if (suq->tex.target.isMS()) {
+         Value *ms_x = loadSuInfo32(ind, base + NVE4_SU_INFO_MS(0));
+         Value *ms_y = loadSuInfo32(ind, base + NVE4_SU_INFO_MS(1));
+         Value *ms = bld.mkOp2v(OP_ADD, TYPE_U32, bld.getScratch(), ms_x, ms_y);
+         bld.mkOp2(OP_SHL, TYPE_U32, suq->getDef(d++), bld.loadImm(NULL, 1), ms);
+      } else {
+         bld.mkMov(suq->getDef(d++), bld.loadImm(NULL, 1));
+      }
    }
 
    bld.remove(suq);
@@ -1616,7 +1623,7 @@ NVC0LoweringPass::handleSUQ(TexInstruction *suq)
 void
 NVC0LoweringPass::adjustCoordinatesMS(TexInstruction *tex)
 {
-   const uint16_t base = tex->tex.r * NVE4_SU_INFO__STRIDE;
+   uint16_t base;
    const int arg = tex->tex.target.getArgCount();
 
    if (tex->tex.target == TEX_TARGET_2D_MS)
@@ -1632,13 +1639,18 @@ NVC0LoweringPass::adjustCoordinatesMS(TexInstruction *tex)
    Value *s = tex->getSrc(arg - 1);
 
    Value *tx = bld.getSSA(), *ty = bld.getSSA(), *ts = bld.getSSA();
-   Value *ind = NULL;
+   Value *ind = tex->getIndirectR();
 
-   if (tex->tex.rIndirectSrc >= 0) {
-      assert(tex->tex.r == 0);
-      // FIXME: out of bounds
+   if (ind) {
+      ind = bld.mkOp2v(OP_ADD, TYPE_U32, bld.getSSA(),
+                       ind, bld.mkImm(tex->tex.r));
+      ind = bld.mkOp2v(OP_AND, TYPE_U32, bld.getSSA(),
+                       ind, bld.mkImm(7));
       ind = bld.mkOp2v(OP_SHL, TYPE_U32, bld.getSSA(),
-                       tex->getIndirectR(), bld.mkImm(6));
+                       ind, bld.mkImm(6));
+      base = 0;
+   } else {
+      base = tex->tex.r * NVE4_SU_INFO__STRIDE;
    }
 
    Value *ms_x = loadSuInfo32(ind, base + NVE4_SU_INFO_MS(0));
@@ -2044,6 +2056,10 @@ NVC0LoweringPass::processSurfaceCoordsNVC0(TexInstruction *su)
    Value *v;
    Value *ind = NULL;
 
+   bld.setPosition(su, false);
+
+   adjustCoordinatesMS(su);
+
    if (su->tex.rIndirectSrc >= 0) {
       ind = su->getIndirectR();
       if (su->tex.r > 0) {
index 59bbe1efe106f9197e72e90392fbfc8b5a487a61..66cae1916e1aad789d92dd8f5a81c49ed373a9d8 100644 (file)
@@ -113,6 +113,30 @@ nvc0_screen_compute_setup(struct nvc0_screen *screen,
    PUSH_DATA (push, screen->txc->offset + 65536);
    PUSH_DATA (push, NVC0_TSC_MAX_ENTRIES - 1);
 
+   /* MS sample coordinate offsets */
+   BEGIN_NVC0(push, NVC0_CP(CB_SIZE), 3);
+   PUSH_DATA (push, 2048);
+   PUSH_DATAh(push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(5));
+   PUSH_DATA (push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(5));
+   BEGIN_1IC0(push, NVC0_CP(CB_POS), 1 + 2 * 8);
+   PUSH_DATA (push, NVC0_CB_AUX_MS_INFO);
+   PUSH_DATA (push, 0); /* 0 */
+   PUSH_DATA (push, 0);
+   PUSH_DATA (push, 1); /* 1 */
+   PUSH_DATA (push, 0);
+   PUSH_DATA (push, 0); /* 2 */
+   PUSH_DATA (push, 1);
+   PUSH_DATA (push, 1); /* 3 */
+   PUSH_DATA (push, 1);
+   PUSH_DATA (push, 2); /* 4 */
+   PUSH_DATA (push, 0);
+   PUSH_DATA (push, 3); /* 5 */
+   PUSH_DATA (push, 0);
+   PUSH_DATA (push, 2); /* 6 */
+   PUSH_DATA (push, 1);
+   PUSH_DATA (push, 3); /* 7 */
+   PUSH_DATA (push, 1);
+
    return 0;
 }
 
index fe9f9f56e0aed89e27039d6b8add90916df62c70..098d2a1add0b241e22c171c0fc3745ad7f364e99 100644 (file)
 #define NVC0_CB_AUX_TEX_INFO(i)     0x020 + (i) * 4
 #define NVC0_CB_AUX_TEX_SIZE        (32 * 4)
 /* 8 sets of 32-bits coordinate offsets */
-#define NVC0_CB_AUX_MS_INFO         0x0a0 /* CP */
+#define NVC0_CB_AUX_MS_INFO         0x0a0
 #define NVC0_CB_AUX_MS_SIZE         (8 * 2 * 4)
 /* block/grid size, at 3 32-bits integers each and gridid */
 #define NVC0_CB_AUX_GRID_INFO       0x0e0 /* CP */
index aba95114eb733e63f0c2d3b02f8abf164ec932c2..d75b702c809dae39d74895aa03f3951188899dcb 100644 (file)
@@ -555,29 +555,25 @@ nvc0_program_translate(struct nvc0_program *prog, uint16_t chipset,
 
    info->io.genUserClip = prog->vp.num_ucps;
    info->io.auxCBSlot = 15;
+   info->io.msInfoCBSlot = 15;
    info->io.ucpBase = NVC0_CB_AUX_UCP_INFO;
    info->io.drawInfoBase = NVC0_CB_AUX_DRAW_INFO;
+   info->io.msInfoBase = NVC0_CB_AUX_MS_INFO;
+   info->io.bufInfoBase = NVC0_CB_AUX_BUF_INFO(0);
+   info->io.suInfoBase = NVC0_CB_AUX_SU_INFO(0);
+   if (chipset >= NVISA_GK104_CHIPSET) {
+      info->io.texBindBase = NVC0_CB_AUX_TEX_INFO(0);
+   }
 
    if (prog->type == PIPE_SHADER_COMPUTE) {
       if (chipset >= NVISA_GK104_CHIPSET) {
          info->io.auxCBSlot = 7;
-         info->io.texBindBase = NVC0_CB_AUX_TEX_INFO(0);
+         info->io.msInfoCBSlot = 7;
          info->prop.cp.gridInfoBase = NVC0_CB_AUX_GRID_INFO;
          info->io.uboInfoBase = NVC0_CB_AUX_UBO_INFO(0);
       }
-      info->io.msInfoCBSlot = 0;
-      info->io.msInfoBase = NVC0_CB_AUX_MS_INFO;
-      info->io.bufInfoBase = NVC0_CB_AUX_BUF_INFO(0);
-      info->io.suInfoBase = NVC0_CB_AUX_SU_INFO(0);
    } else {
-      if (chipset >= NVISA_GK104_CHIPSET) {
-         info->io.texBindBase = NVC0_CB_AUX_TEX_INFO(0);
-      }
       info->io.sampleInfoBase = NVC0_CB_AUX_SAMPLE_INFO;
-      info->io.bufInfoBase = NVC0_CB_AUX_BUF_INFO(0);
-      info->io.suInfoBase = NVC0_CB_AUX_SU_INFO(0);
-      info->io.msInfoCBSlot = 15;
-      info->io.msInfoBase = 0; /* TODO */
    }
 
    info->assignSlots = nvc0_program_assign_varying_slots;
index abcbfbfbac467f08215e6e4d3ad3d1a088e31283..e0bfd3b41444ec114b1333da29d7835372b99111 100644 (file)
@@ -975,6 +975,26 @@ nvc0_screen_create(struct nouveau_device *dev)
          BEGIN_NVC0(push, NVC0_3D(TEX_LIMITS(i)), 1);
          PUSH_DATA (push, 0x54);
       }
+
+      /* MS sample coordinate offsets: these do not work with _ALT modes ! */
+      BEGIN_1IC0(push, NVC0_3D(CB_POS), 1 + 2 * 8);
+      PUSH_DATA (push, NVC0_CB_AUX_MS_INFO);
+      PUSH_DATA (push, 0); /* 0 */
+      PUSH_DATA (push, 0);
+      PUSH_DATA (push, 1); /* 1 */
+      PUSH_DATA (push, 0);
+      PUSH_DATA (push, 0); /* 2 */
+      PUSH_DATA (push, 1);
+      PUSH_DATA (push, 1); /* 3 */
+      PUSH_DATA (push, 1);
+      PUSH_DATA (push, 2); /* 4 */
+      PUSH_DATA (push, 0);
+      PUSH_DATA (push, 3); /* 5 */
+      PUSH_DATA (push, 0);
+      PUSH_DATA (push, 2); /* 6 */
+      PUSH_DATA (push, 1);
+      PUSH_DATA (push, 3); /* 7 */
+      PUSH_DATA (push, 1);
    }
    BEGIN_NVC0(push, NVC0_3D(LINKED_TSC), 1);
    PUSH_DATA (push, 0);
index 1a5d8ecbf16f9936ce667fbd16e9f9707b46cc1e..21d8e9d6797ebadd6643a737d2c65c7f111fe610 100644 (file)
@@ -928,11 +928,11 @@ nve4_set_surface_info(struct nouveau_pushbuf *push,
       address += lvl->offset;
 
       info[0]  = address >> 8;
-      info[2]  = width - 1;
+      info[2]  = (width << mt->ms_x) - 1;
       /* NOTE: this is really important: */
       info[2] |= (0xff & nve4_su_format_aux_map[view->format]) << 22;
       info[3]  = (0x88 << 24) | (lvl->pitch / 64);
-      info[4]  = height - 1;
+      info[4]  = (height << mt->ms_y) - 1;
       info[4] |= (lvl->tile_mode & 0x0f0) << 25;
       info[4] |= NVC0_TILE_SHIFT_Y(lvl->tile_mode) << 22;
       info[5]  = mt->layer_stride >> 8;
@@ -1051,8 +1051,8 @@ nvc0_validate_suf(struct nvc0_context *nvc0, int s)
 
             PUSH_DATAh(push, address);
             PUSH_DATA (push, address);
-            PUSH_DATA (push, width);
-            PUSH_DATA (push, height);
+            PUSH_DATA (push, width << mt->ms_x);
+            PUSH_DATA (push, height << mt->ms_y);
             PUSH_DATA (push, rt);
             PUSH_DATA (push, lvl->tile_mode & 0xff); /* mask out z-tiling */
          }