[Mesa-dev] [PATCH 7/7] nvc0: add support for PIPE_CAP_SURFACE_REINTERPRET_BLOCKS

Samuel Pitoiset samuel.pitoiset at gmail.com
Tue Oct 25 19:41:16 UTC 2016


Loosely based on radeonsi, thanks Nicolai!

Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
---
 src/gallium/drivers/nouveau/nv50/nv50_miptree.c  | 13 ++++++++----
 src/gallium/drivers/nouveau/nv50/nv50_resource.h |  3 ++-
 src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c  |  6 ++++--
 src/gallium/drivers/nouveau/nvc0/nvc0_resource.c | 27 +++++++++++++++++++++++-
 src/gallium/drivers/nouveau/nvc0/nvc0_resource.h |  3 ++-
 src/gallium/drivers/nouveau/nvc0/nvc0_screen.c   |  2 +-
 src/gallium/drivers/nouveau/nvc0/nvc0_surface.c  |  7 +++++-
 7 files changed, 50 insertions(+), 11 deletions(-)

diff --git a/src/gallium/drivers/nouveau/nv50/nv50_miptree.c b/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
index f2e304f..8dff9f7 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
@@ -466,7 +466,8 @@ nv50_mt_zslice_offset(const struct nv50_miptree *mt, unsigned l, unsigned z)
 
 struct nv50_surface *
 nv50_surface_from_miptree(struct nv50_miptree *mt,
-                          const struct pipe_surface *templ)
+                          const struct pipe_surface *templ,
+                          unsigned width, unsigned height)
 {
    struct pipe_surface *ps;
    struct nv50_surface *ns = CALLOC_STRUCT(nv50_surface);
@@ -483,8 +484,8 @@ nv50_surface_from_miptree(struct nv50_miptree *mt,
    ps->u.tex.first_layer = templ->u.tex.first_layer;
    ps->u.tex.last_layer = templ->u.tex.last_layer;
 
-   ns->width = u_minify(mt->base.base.width0, ps->u.tex.level);
-   ns->height = u_minify(mt->base.base.height0, ps->u.tex.level);
+   ns->width = width;
+   ns->height = height;
    ns->depth = ps->u.tex.last_layer - ps->u.tex.first_layer + 1;
    ns->offset = mt->level[templ->u.tex.level].offset;
 
@@ -504,7 +505,11 @@ nv50_miptree_surface_new(struct pipe_context *pipe,
                          const struct pipe_surface *templ)
 {
    struct nv50_miptree *mt = nv50_miptree(pt);
-   struct nv50_surface *ns = nv50_surface_from_miptree(mt, templ);
+   unsigned width = u_minify(pt->width0, templ->u.tex.level);
+   unsigned height = u_minify(pt->height0, templ->u.tex.level);
+   struct nv50_surface *ns;
+
+   ns = nv50_surface_from_miptree(mt, templ, width, height);
    if (!ns)
       return NULL;
    ns->base.context = pipe;
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_resource.h b/src/gallium/drivers/nouveau/nv50/nv50_resource.h
index 5d03925..85a1b76 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_resource.h
+++ b/src/gallium/drivers/nouveau/nv50/nv50_resource.h
@@ -141,7 +141,8 @@ nv50_miptree_transfer_unmap(struct pipe_context *pcontext,
 
 struct nv50_surface *
 nv50_surface_from_miptree(struct nv50_miptree *mt,
-                          const struct pipe_surface *templ);
+                          const struct pipe_surface *templ,
+                          unsigned width, unsigned height);
 
 struct pipe_surface *
 nv50_surface_from_buffer(struct pipe_context *pipe,
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c b/src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c
index 27674f7..99c8a06 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c
@@ -351,9 +351,11 @@ nvc0_mt_zslice_offset(const struct nv50_miptree *mt, unsigned l, unsigned z)
 struct pipe_surface *
 nvc0_miptree_surface_new(struct pipe_context *pipe,
                          struct pipe_resource *pt,
-                         const struct pipe_surface *templ)
+                         const struct pipe_surface *templ,
+                         unsigned width, unsigned height)
 {
-   struct nv50_surface *ns = nv50_surface_from_miptree(nv50_miptree(pt), templ);
+   struct nv50_surface *ns =
+      nv50_surface_from_miptree(nv50_miptree(pt), templ, width, height);
    if (!ns)
       return NULL;
    ns->base.context = pipe;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c
index 9bafe3d..2fe491f 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c
@@ -3,6 +3,7 @@
 #include "nvc0/nvc0_resource.h"
 #include "nouveau_screen.h"
 
+#include "util/u_format.h"
 
 static struct pipe_resource *
 nvc0_resource_create(struct pipe_screen *screen,
@@ -38,9 +39,33 @@ nvc0_surface_create(struct pipe_context *pipe,
                     struct pipe_resource *pres,
                     const struct pipe_surface *templ)
 {
+   unsigned level = templ->u.tex.level;
+   unsigned width = u_minify(pres->width0, level);
+   unsigned height = u_minify(pres->height0, level);
+
+   if (pres->target != PIPE_BUFFER && templ->format != pres->format) {
+      const struct util_format_description *tex_desc
+         = util_format_description(pres->format);
+      const struct util_format_description *templ_desc
+         = util_format_description(templ->format);
+
+      assert(tex_desc->block.bits == templ_desc->block.bits);
+
+      /* Adjust size of surface if and only if the block width or
+       * height is changed. */
+      if (tex_desc->block.width != templ_desc->block.width ||
+          tex_desc->block.height != templ_desc->block.height) {
+         unsigned nblks_x = util_format_get_nblocksx(pres->format, width);
+         unsigned nblks_y = util_format_get_nblocksy(pres->format, height);
+
+         width = nblks_x * templ_desc->block.width;
+         height = nblks_y * templ_desc->block.height;
+      }
+   }
+
    if (unlikely(pres->target == PIPE_BUFFER))
       return nv50_surface_from_buffer(pipe, pres, templ);
-   return nvc0_miptree_surface_new(pipe, pres, templ);
+   return nvc0_miptree_surface_new(pipe, pres, templ, width, height);
 }
 
 void
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.h b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.h
index 0d5f026..d59a580 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.h
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.h
@@ -39,7 +39,8 @@ const struct u_resource_vtbl nvc0_miptree_vtbl;
 struct pipe_surface *
 nvc0_miptree_surface_new(struct pipe_context *,
                          struct pipe_resource *,
-                         const struct pipe_surface *templ);
+                         const struct pipe_surface *templ,
+                         unsigned width, unsigned height);
 
 unsigned
 nvc0_mt_zslice_offset(const struct nv50_miptree *, unsigned l, unsigned z);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
index 6361e9e..2036381 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
@@ -242,6 +242,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_TGSI_VOTE:
    case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED:
    case PIPE_CAP_TGSI_ARRAY_COMPONENTS:
+   case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:
       return 1;
    case PIPE_CAP_COMPUTE:
       return (class_3d < GP100_3D_CLASS);
@@ -267,7 +268,6 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
    case PIPE_CAP_GENERATE_MIPMAP:
    case PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY:
-   case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:
    case PIPE_CAP_QUERY_MEMORY_INFO:
    case PIPE_CAP_PCI_GROUP:
    case PIPE_CAP_PCI_BUS:
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
index 0d14058..da47478 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
@@ -927,6 +927,7 @@ nvc0_blit_set_dst(struct nvc0_blitctx *ctx,
    struct nvc0_context *nvc0 = ctx->nvc0;
    struct pipe_context *pipe = &nvc0->base.pipe;
    struct pipe_surface templ;
+   unsigned width, height;
 
    if (util_format_is_depth_or_stencil(format))
       templ.format = nv50_blit_zeta_to_colour_format(format);
@@ -942,7 +943,11 @@ nvc0_blit_set_dst(struct nvc0_blitctx *ctx,
          (res->target == PIPE_TEXTURE_3D ? res->depth0 : res->array_size) - 1;
    }
 
-   nvc0->framebuffer.cbufs[0] = nvc0_miptree_surface_new(pipe, res, &templ);
+   width = u_minify(res->width0, templ.u.tex.level);
+   height = u_minify(res->height0, templ.u.tex.level);
+
+   nvc0->framebuffer.cbufs[0] =
+      nvc0_miptree_surface_new(pipe, res, &templ, width, height);
    nvc0->framebuffer.nr_cbufs = 1;
    nvc0->framebuffer.zsbuf = NULL;
    nvc0->framebuffer.width = nvc0->framebuffer.cbufs[0]->width;
-- 
2.10.1



More information about the mesa-dev mailing list