Loosely based on radeonsi, thanks Nicolai! Signed-off-by: Samuel Pitoiset <samuel.pitoi...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev