On Wed, Feb 21, 2018 at 10:30 AM, Thierry Reding <thierry.red...@gmail.com> wrote: > From: Thierry Reding <tred...@nvidia.com> > > This adds support for framebuffer modifiers to Nouveau. This will be > used by the Tegra driver to share metadata about the format of buffers > (such as the tiling mode or compression). > > Signed-off-by: Thierry Reding <tred...@nvidia.com> > --- > src/gallium/drivers/nouveau/Android.mk | 3 + > src/gallium/drivers/nouveau/Makefile.am | 1 + > src/gallium/drivers/nouveau/nouveau_buffer.c | 3 +- > src/gallium/drivers/nouveau/nouveau_buffer.h | 3 +- > src/gallium/drivers/nouveau/nouveau_screen.c | 14 +++++ > src/gallium/drivers/nouveau/nv30/nv30_resource.c | 6 +- > src/gallium/drivers/nouveau/nv50/nv50_resource.c | 5 +- > src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c | 8 ++- > src/gallium/drivers/nouveau/nvc0/nvc0_resource.c | 80 > +++++++++++++++++++++++- > src/gallium/drivers/nouveau/nvc0/nvc0_resource.h | 5 +- > 10 files changed, 120 insertions(+), 8 deletions(-) > > diff --git a/src/gallium/drivers/nouveau/Android.mk > b/src/gallium/drivers/nouveau/Android.mk > index 2de22e73ec18..a446774a86e8 100644 > --- a/src/gallium/drivers/nouveau/Android.mk > +++ b/src/gallium/drivers/nouveau/Android.mk > @@ -36,6 +36,9 @@ LOCAL_SRC_FILES := \ > $(NVC0_CODEGEN_SOURCES) \ > $(NVC0_C_SOURCES) > > +LOCAL_C_INCLUDES := \ > + $(MESA_TOP)/include/drm-uapi > + > LOCAL_SHARED_LIBRARIES := libdrm_nouveau > LOCAL_MODULE := libmesa_pipe_nouveau > > diff --git a/src/gallium/drivers/nouveau/Makefile.am > b/src/gallium/drivers/nouveau/Makefile.am > index 91547178e397..f6126b544811 100644 > --- a/src/gallium/drivers/nouveau/Makefile.am > +++ b/src/gallium/drivers/nouveau/Makefile.am > @@ -24,6 +24,7 @@ include Makefile.sources > include $(top_srcdir)/src/gallium/Automake.inc > > AM_CPPFLAGS = \ > + -I$(top_srcdir)/include/drm-uapi \ > $(GALLIUM_DRIVER_CFLAGS) \ > $(LIBDRM_CFLAGS) \ > $(NOUVEAU_CFLAGS) > diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c > b/src/gallium/drivers/nouveau/nouveau_buffer.c > index 2c604419ce05..73afff961115 100644 > --- a/src/gallium/drivers/nouveau/nouveau_buffer.c > +++ b/src/gallium/drivers/nouveau/nouveau_buffer.c > @@ -636,7 +636,8 @@ const struct u_resource_vtbl nouveau_buffer_vtbl = > > struct pipe_resource * > nouveau_buffer_create(struct pipe_screen *pscreen, > - const struct pipe_resource *templ) > + const struct pipe_resource *templ, > + const uint64_t *modifiers, unsigned int count) > { > struct nouveau_screen *screen = nouveau_screen(pscreen); > struct nv04_resource *buffer; > diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.h > b/src/gallium/drivers/nouveau/nouveau_buffer.h > index 3a33fae9ce2f..466f8cc2b466 100644 > --- a/src/gallium/drivers/nouveau/nouveau_buffer.h > +++ b/src/gallium/drivers/nouveau/nouveau_buffer.h > @@ -89,7 +89,8 @@ nouveau_resource_mapped_by_gpu(struct pipe_resource > *resource) > > struct pipe_resource * > nouveau_buffer_create(struct pipe_screen *pscreen, > - const struct pipe_resource *templ); > + const struct pipe_resource *templ, > + const uint64_t *modifiers, unsigned int count); > > struct pipe_resource * > nouveau_user_buffer_create(struct pipe_screen *screen, void *ptr, > diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c > b/src/gallium/drivers/nouveau/nouveau_screen.c > index c144b39b2dd2..d651cc7f4b8c 100644 > --- a/src/gallium/drivers/nouveau/nouveau_screen.c > +++ b/src/gallium/drivers/nouveau/nouveau_screen.c > @@ -1,3 +1,5 @@ > +#include <drm_fourcc.h> > + > #include "pipe/p_defines.h" > #include "pipe/p_screen.h" > #include "pipe/p_state.h" > @@ -23,6 +25,8 @@ > #include "nouveau_mm.h" > #include "nouveau_buffer.h" > > +#include "nvc0/nvc0_resource.h" > + > /* XXX this should go away */ > #include "state_tracker/drm_driver.h" > > @@ -124,6 +128,15 @@ nouveau_screen_bo_from_handle(struct pipe_screen > *pscreen, > return bo; > } > > +static uint64_t nouveau_bo_get_modifier(struct nouveau_bo *bo) > +{ > + struct nouveau_device *dev = bo->device; > + > + if (dev->chipset >= 0xc0) > + return nvc0_bo_get_modifier(bo); > + > + return DRM_FORMAT_MOD_INVALID; > +} > > bool > nouveau_screen_bo_get_handle(struct pipe_screen *pscreen, > @@ -131,6 +144,7 @@ nouveau_screen_bo_get_handle(struct pipe_screen *pscreen, > unsigned stride, > struct winsys_handle *whandle) > { > + whandle->modifier = nouveau_bo_get_modifier(bo); > whandle->stride = stride; > > if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) { > diff --git a/src/gallium/drivers/nouveau/nv30/nv30_resource.c > b/src/gallium/drivers/nouveau/nv30/nv30_resource.c > index ff34f6e5f9fa..38d2b2e41c30 100644 > --- a/src/gallium/drivers/nouveau/nv30/nv30_resource.c > +++ b/src/gallium/drivers/nouveau/nv30/nv30_resource.c > @@ -23,6 +23,8 @@ > * > */ > > +#include <drm_fourcc.h> > + > #include "util/u_format.h" > #include "util/u_inlines.h" > > @@ -51,9 +53,11 @@ static struct pipe_resource * > nv30_resource_create(struct pipe_screen *pscreen, > const struct pipe_resource *tmpl) > { > + const uint64_t modifier = DRM_FORMAT_MOD_INVALID; > + > switch (tmpl->target) { > case PIPE_BUFFER: > - return nouveau_buffer_create(pscreen, tmpl); > + return nouveau_buffer_create(pscreen, tmpl, &modifier, 1); > default: > return nv30_miptree_create(pscreen, tmpl); > } > diff --git a/src/gallium/drivers/nouveau/nv50/nv50_resource.c > b/src/gallium/drivers/nouveau/nv50/nv50_resource.c > index aed8c6241d4b..37592ad66349 100644 > --- a/src/gallium/drivers/nouveau/nv50/nv50_resource.c > +++ b/src/gallium/drivers/nouveau/nv50/nv50_resource.c > @@ -1,3 +1,4 @@ > +#include <drm_fourcc.h> > > #include "pipe/p_context.h" > #include "util/u_inlines.h" > @@ -11,9 +12,11 @@ static struct pipe_resource * > nv50_resource_create(struct pipe_screen *screen, > const struct pipe_resource *templ) > { > + const uint64_t modifier = DRM_FORMAT_MOD_INVALID; > + > switch (templ->target) { > case PIPE_BUFFER: > - return nouveau_buffer_create(screen, templ); > + return nouveau_buffer_create(screen, templ, &modifier, 1); > default: > return nv50_miptree_create(screen, templ); > } > diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c > b/src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c > index 27674f72a7c0..627d6b7346c3 100644 > --- a/src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c > +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_miptree.c > @@ -20,6 +20,8 @@ > * OTHER DEALINGS IN THE SOFTWARE. > */ > > +#include <drm_fourcc.h> > + > #include "pipe/p_state.h" > #include "pipe/p_defines.h" > #include "util/u_inlines.h" > @@ -244,7 +246,8 @@ const struct u_resource_vtbl nvc0_miptree_vtbl = > > struct pipe_resource * > nvc0_miptree_create(struct pipe_screen *pscreen, > - const struct pipe_resource *templ) > + const struct pipe_resource *templ, > + const uint64_t *modifiers, unsigned int count) > { > struct nouveau_device *dev = nouveau_screen(pscreen)->device; > struct nouveau_drm *drm = nouveau_screen(pscreen)->drm; > @@ -277,6 +280,9 @@ nvc0_miptree_create(struct pipe_screen *pscreen, > } > } > > + if (count == 1 && modifiers[0] == DRM_FORMAT_MOD_LINEAR) > + pt->flags |= NOUVEAU_RESOURCE_FLAG_LINEAR; > + > if (pt->bind & PIPE_BIND_LINEAR) > pt->flags |= NOUVEAU_RESOURCE_FLAG_LINEAR; > > diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c > b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c > index 9bafe3d835db..c409dce7f31f 100644 > --- a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c > +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c > @@ -1,3 +1,4 @@ > +#include <drm_fourcc.h> > > #include "pipe/p_context.h" > #include "nvc0/nvc0_resource.h" > @@ -7,15 +8,38 @@ > static struct pipe_resource * > nvc0_resource_create(struct pipe_screen *screen, > const struct pipe_resource *templ) > +{ > + const uint64_t modifier = DRM_FORMAT_MOD_INVALID; > + > + switch (templ->target) { > + case PIPE_BUFFER: > + return nouveau_buffer_create(screen, templ, &modifier, 1); > + default: > + return nvc0_miptree_create(screen, templ, &modifier, 1); > + } > +} > + > +static struct pipe_resource * > +nvc0_resource_create_with_modifiers(struct pipe_screen *screen, > + const struct pipe_resource *templ, > + const uint64_t *modifiers, int count) > { > switch (templ->target) { > case PIPE_BUFFER: > - return nouveau_buffer_create(screen, templ); > + return nouveau_buffer_create(screen, templ, modifiers, count); > default: > - return nvc0_miptree_create(screen, templ); > + return nvc0_miptree_create(screen, templ, modifiers, count); > } > } > > +static void > +nvc0_query_dmabuf_modifiers(struct pipe_screen *screen, > + enum pipe_format format, int max, > + uint64_t *modifiers, unsigned int *external_only, > + int *count) > +{ > +} > + > static struct pipe_resource * > nvc0_resource_from_handle(struct pipe_screen * screen, > const struct pipe_resource *templ, > @@ -60,7 +84,59 @@ void > nvc0_screen_init_resource_functions(struct pipe_screen *pscreen) > { > pscreen->resource_create = nvc0_resource_create; > + pscreen->resource_create_with_modifiers = > nvc0_resource_create_with_modifiers; > + pscreen->query_dmabuf_modifiers = nvc0_query_dmabuf_modifiers; > pscreen->resource_from_handle = nvc0_resource_from_handle; > pscreen->resource_get_handle = u_resource_get_handle_vtbl; > pscreen->resource_destroy = u_resource_destroy_vtbl; > } > + > +uint64_t nvc0_bo_get_modifier(struct nouveau_bo *bo) > +{ > + union nouveau_bo_config *config = &bo->config; > + uint64_t modifier = DRM_FORMAT_MOD_INVALID; > + > + switch (config->nvc0.memtype) { > + case 0x00: > + modifier = DRM_FORMAT_MOD_LINEAR; > + break; > + > + case 0xfe: > + switch (NVC0_TILE_MODE_Y(config->nvc0.tile_mode)) {
Presumably only if it's not a 3d layout? Not sure how to get that from the bo. > + case 0: > + modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_ONE_GOB; > + break; > + > + case 1: > + modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_TWO_GOB; > + break; > + > + case 2: > + modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_FOUR_GOB; > + break; > + > + case 3: > + modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_EIGHT_GOB; > + break; > + > + case 4: > + modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_SIXTEEN_GOB; > + break; > + > + case 5: > + modifier = DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_THIRTYTWO_GOB; > + break; > + > + default: > + modifier = DRM_FORMAT_MOD_INVALID; > + break; > + } > + break; > + > + default: > + modifier = DRM_FORMAT_MOD_INVALID; > + break; > + } > + > + return modifier; > +} > diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.h > b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.h > index c68a50948360..78247748c141 100644 > --- a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.h > +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.h > @@ -35,7 +35,8 @@ nvc0_screen_init_resource_functions(struct pipe_screen > *pscreen); > */ > struct pipe_resource * > nvc0_miptree_create(struct pipe_screen *pscreen, > - const struct pipe_resource *tmp); > + const struct pipe_resource *tmp, > + const uint64_t *modifiers, unsigned int count); > > const struct u_resource_vtbl nvc0_miptree_vtbl; > > @@ -58,4 +59,6 @@ void > nvc0_miptree_transfer_unmap(struct pipe_context *pcontext, > struct pipe_transfer *ptx); > > +uint64_t nvc0_bo_get_modifier(struct nouveau_bo *bo); > + > #endif > -- > 2.16.2 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev