[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