From c5a01854df6602d536eb18c21d4663056f66bee7 Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Tue, 9 Aug 2022 13:22:59 +0200 Subject: [PATCH 1/4] gallium/u_transfer_helper: clean up boolean flags Whenever we add or remove a flag here, we need to update a bunch of drivers in a fragile way. Moving to flags here instead should make this a bit easier to maintain in the future. Reviewed-by: Alyssa Rosenzweig Reviewed-by: Vasily Khoruzhick Reviewed-by: Mike Blumenkrantz Reviewed-by: Juan A. Suarez Reviewed-by: Yonggang Luo Reviewed-by: Kenneth Graunke Part-of: --- src/gallium/auxiliary/util/u_transfer_helper.c | 16 ++++++---------- src/gallium/auxiliary/util/u_transfer_helper.h | 17 +++++++++++------ src/gallium/drivers/asahi/agx_pipe.c | 6 ++++-- src/gallium/drivers/crocus/crocus_resource.c | 10 ++++++++-- .../drivers/freedreno/freedreno_resource.c | 5 ++++- src/gallium/drivers/iris/iris_resource.c | 5 ++++- src/gallium/drivers/lima/lima_resource.c | 4 +--- src/gallium/drivers/panfrost/pan_resource.c | 5 +++-- src/gallium/drivers/v3d/v3d_resource.c | 6 +++--- src/gallium/drivers/vc4/vc4_resource.c | 4 +--- src/gallium/drivers/zink/zink_resource.c | 4 +++- 11 files changed, 48 insertions(+), 34 deletions(-) diff --git a/src/gallium/auxiliary/util/u_transfer_helper.c b/src/gallium/auxiliary/util/u_transfer_helper.c index 10ee30034244..06b9d46c8dcf 100644 --- a/src/gallium/auxiliary/util/u_transfer_helper.c +++ b/src/gallium/auxiliary/util/u_transfer_helper.c @@ -553,20 +553,16 @@ u_transfer_helper_transfer_unmap(struct pipe_context *pctx, struct u_transfer_helper * u_transfer_helper_create(const struct u_transfer_vtbl *vtbl, - bool separate_z32s8, - bool separate_stencil, - bool fake_rgtc, - bool msaa_map, - bool z24_in_z32f) + enum u_transfer_helper_flags flags) { struct u_transfer_helper *helper = calloc(1, sizeof(*helper)); helper->vtbl = vtbl; - helper->separate_z32s8 = separate_z32s8; - helper->separate_stencil = separate_stencil; - helper->fake_rgtc = fake_rgtc; - helper->msaa_map = msaa_map; - helper->z24_in_z32f = z24_in_z32f; + helper->separate_z32s8 = flags & U_TRANSFER_HELPER_SEPARATE_Z32S8; + helper->separate_stencil = flags & U_TRANSFER_HELPER_SEPARATE_STENCIL; + helper->fake_rgtc = flags & U_TRANSFER_HELPER_FAKE_RGTC; + helper->msaa_map = flags & U_TRANSFER_HELPER_MSAA_MAP; + helper->z24_in_z32f = flags & U_TRANSFER_HELPER_Z24_IN_Z32F; return helper; } diff --git a/src/gallium/auxiliary/util/u_transfer_helper.h b/src/gallium/auxiliary/util/u_transfer_helper.h index d62d8a198483..430deffeb04a 100644 --- a/src/gallium/auxiliary/util/u_transfer_helper.h +++ b/src/gallium/auxiliary/util/u_transfer_helper.h @@ -98,6 +98,14 @@ struct u_transfer_vtbl { struct pipe_resource *(*get_stencil)(struct pipe_resource *prsc); }; +enum u_transfer_helper_flags { + U_TRANSFER_HELPER_SEPARATE_Z32S8 = (1 << 0), + U_TRANSFER_HELPER_SEPARATE_STENCIL = (1 << 1), + U_TRANSFER_HELPER_FAKE_RGTC = (1 << 2), + U_TRANSFER_HELPER_MSAA_MAP = (1 << 3), + U_TRANSFER_HELPER_Z24_IN_Z32F = (1 << 4), +}; + struct pipe_resource *u_transfer_helper_resource_create( struct pipe_screen *pscreen, const struct pipe_resource *templ); @@ -121,12 +129,9 @@ void u_transfer_helper_transfer_unmap(struct pipe_context *pctx, struct u_transfer_helper; -struct u_transfer_helper * u_transfer_helper_create(const struct u_transfer_vtbl *vtbl, - bool separate_z32s8, - bool separate_stencil, - bool fake_rgtc, - bool msaa_map, - bool z24_in_z32f); +struct u_transfer_helper * +u_transfer_helper_create(const struct u_transfer_vtbl *vtbl, + enum u_transfer_helper_flags flags); void u_transfer_helper_destroy(struct u_transfer_helper *helper); diff --git a/src/gallium/drivers/asahi/agx_pipe.c b/src/gallium/drivers/asahi/agx_pipe.c index 7f3dd07e498f..389b11f21508 100644 --- a/src/gallium/drivers/asahi/agx_pipe.c +++ b/src/gallium/drivers/asahi/agx_pipe.c @@ -1217,8 +1217,10 @@ agx_screen_create(struct sw_winsys *winsys) screen->resource_create = u_transfer_helper_resource_create; screen->resource_destroy = u_transfer_helper_resource_destroy; screen->transfer_helper = u_transfer_helper_create(&transfer_vtbl, - true, true, false, true, - true); + U_TRANSFER_HELPER_SEPARATE_Z32S8 | + U_TRANSFER_HELPER_SEPARATE_STENCIL | + U_TRANSFER_HELPER_MSAA_MAP | + U_TRANSFER_HELPER_Z24_IN_Z32F); agx_internal_shaders(&agx_screen->dev); diff --git a/src/gallium/drivers/crocus/crocus_resource.c b/src/gallium/drivers/crocus/crocus_resource.c index c35b63079c2b..8e9d7dae0938 100644 --- a/src/gallium/drivers/crocus/crocus_resource.c +++ b/src/gallium/drivers/crocus/crocus_resource.c @@ -2007,9 +2007,15 @@ crocus_init_screen_resource_functions(struct pipe_screen *pscreen) pscreen->resource_destroy = u_transfer_helper_resource_destroy; pscreen->memobj_create_from_handle = crocus_memobj_create_from_handle; pscreen->memobj_destroy = crocus_memobj_destroy; + + enum u_transfer_helper_flags transfer_flags = U_TRANSFER_HELPER_MSAA_MAP; + if (screen->devinfo.ver >= 6) { + transfer_flags |= U_TRANSFER_HELPER_SEPARATE_Z32S8 | + U_TRANSFER_HELPER_SEPARATE_STENCIL; + } + pscreen->transfer_helper = - u_transfer_helper_create(&transfer_vtbl, screen->devinfo.ver >= 6, - screen->devinfo.ver >= 6, false, true, false); + u_transfer_helper_create(&transfer_vtbl, transfer_flags); } void diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c index 9b4a136d6abf..eb189b091e91 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.c +++ b/src/gallium/drivers/freedreno/freedreno_resource.c @@ -1666,7 +1666,10 @@ fd_resource_screen_init(struct pipe_screen *pscreen) pscreen->resource_destroy = u_transfer_helper_resource_destroy; pscreen->transfer_helper = - u_transfer_helper_create(&transfer_vtbl, true, false, fake_rgtc, true, false); + u_transfer_helper_create(&transfer_vtbl, + U_TRANSFER_HELPER_SEPARATE_Z32S8 | + U_TRANSFER_HELPER_MSAA_MAP | + (fake_rgtc ? U_TRANSFER_HELPER_FAKE_RGTC : 0)); if (!screen->layout_resource_for_modifier) screen->layout_resource_for_modifier = fd_layout_resource_for_modifier; diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c index c5b36176ca79..69487876abaa 100644 --- a/src/gallium/drivers/iris/iris_resource.c +++ b/src/gallium/drivers/iris/iris_resource.c @@ -2693,7 +2693,10 @@ iris_init_screen_resource_functions(struct pipe_screen *pscreen) pscreen->memobj_create_from_handle = iris_memobj_create_from_handle; pscreen->memobj_destroy = iris_memobj_destroy; pscreen->transfer_helper = - u_transfer_helper_create(&transfer_vtbl, true, true, false, true, false); + u_transfer_helper_create(&transfer_vtbl, + U_TRANSFER_HELPER_SEPARATE_Z32S8 | + U_TRANSFER_HELPER_SEPARATE_STENCIL | + U_TRANSFER_HELPER_MSAA_MAP); } void diff --git a/src/gallium/drivers/lima/lima_resource.c b/src/gallium/drivers/lima/lima_resource.c index 10c471424f96..11fa075ed004 100644 --- a/src/gallium/drivers/lima/lima_resource.c +++ b/src/gallium/drivers/lima/lima_resource.c @@ -934,9 +934,7 @@ lima_resource_screen_init(struct lima_screen *screen) screen->base.resource_get_param = lima_resource_get_param; screen->base.set_damage_region = lima_resource_set_damage_region; screen->base.transfer_helper = u_transfer_helper_create(&transfer_vtbl, - false, false, - false, true, - false); + U_TRANSFER_HELPER_MSAA_MAP); } void diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c index b673af74370a..228e45201352 100644 --- a/src/gallium/drivers/panfrost/pan_resource.c +++ b/src/gallium/drivers/panfrost/pan_resource.c @@ -1461,8 +1461,9 @@ panfrost_resource_screen_init(struct pipe_screen *pscreen) pscreen->resource_get_handle = panfrost_resource_get_handle; pscreen->resource_get_param = panfrost_resource_get_param; pscreen->transfer_helper = u_transfer_helper_create(&transfer_vtbl, - true, false, - fake_rgtc, true, false); + U_TRANSFER_HELPER_SEPARATE_Z32S8 | + U_TRANSFER_HELPER_MSAA_MAP | + (fake_rgtc ? U_TRANSFER_HELPER_FAKE_RGTC : 0)); } void panfrost_resource_screen_destroy(struct pipe_screen *pscreen) diff --git a/src/gallium/drivers/v3d/v3d_resource.c b/src/gallium/drivers/v3d/v3d_resource.c index b85983c23f57..c97537516767 100644 --- a/src/gallium/drivers/v3d/v3d_resource.c +++ b/src/gallium/drivers/v3d/v3d_resource.c @@ -1178,9 +1178,9 @@ v3d_resource_screen_init(struct pipe_screen *pscreen) pscreen->resource_get_param = v3d_resource_get_param; pscreen->resource_destroy = u_transfer_helper_resource_destroy; pscreen->transfer_helper = u_transfer_helper_create(&transfer_vtbl, - true, false, - true, true, - false); + U_TRANSFER_HELPER_SEPARATE_Z32S8 | + U_TRANSFER_HELPER_FAKE_RGTC | + U_TRANSFER_HELPER_MSAA_MAP); } void diff --git a/src/gallium/drivers/vc4/vc4_resource.c b/src/gallium/drivers/vc4/vc4_resource.c index d9b80a517009..ab918a05cce5 100644 --- a/src/gallium/drivers/vc4/vc4_resource.c +++ b/src/gallium/drivers/vc4/vc4_resource.c @@ -1138,9 +1138,7 @@ vc4_resource_screen_init(struct pipe_screen *pscreen) pscreen->resource_get_param = vc4_resource_get_param; pscreen->resource_destroy = vc4_resource_destroy; pscreen->transfer_helper = u_transfer_helper_create(&transfer_vtbl, - false, false, - false, true, - false); + U_TRANSFER_HELPER_MSAA_MAP); /* Test if the kernel has GET_TILING; it will return -EINVAL if the * ioctl does not exist, but -ENOENT if we pass an impossible handle. diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c index b65bbedf0bd4..a0fd5400632f 100644 --- a/src/gallium/drivers/zink/zink_resource.c +++ b/src/gallium/drivers/zink/zink_resource.c @@ -2270,7 +2270,9 @@ zink_screen_resource_init(struct pipe_screen *pscreen) pscreen->resource_create_with_modifiers = zink_resource_create_with_modifiers; pscreen->resource_create_drawable = zink_resource_create_drawable; pscreen->resource_destroy = zink_resource_destroy; - pscreen->transfer_helper = u_transfer_helper_create(&transfer_vtbl, true, true, false, false, !screen->have_D24_UNORM_S8_UINT); + pscreen->transfer_helper = u_transfer_helper_create(&transfer_vtbl, + U_TRANSFER_HELPER_SEPARATE_Z32S8 | U_TRANSFER_HELPER_SEPARATE_STENCIL | + (!screen->have_D24_UNORM_S8_UINT ? U_TRANSFER_HELPER_Z24_IN_Z32F : 0)); if (screen->info.have_KHR_external_memory_fd || screen->info.have_KHR_external_memory_win32) { pscreen->resource_get_handle = zink_resource_get_handle; -- GitLab From 81a73abc63a34fb1b84379f947605414535ec804 Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Tue, 9 Aug 2022 14:07:03 +0200 Subject: [PATCH 2/4] gallium/u_transfer_helper: add in-place interleave flag This flag should allow Zink to stop using the interleave-specific API, and instead just use the normal/full u_transfer_helper API, and start using some more of these helpers. Reviewed-by: Alyssa Rosenzweig Part-of: --- .../auxiliary/util/u_transfer_helper.c | 20 +++++++++++++++---- .../auxiliary/util/u_transfer_helper.h | 1 + 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/gallium/auxiliary/util/u_transfer_helper.c b/src/gallium/auxiliary/util/u_transfer_helper.c index 06b9d46c8dcf..43e4aba8ada0 100644 --- a/src/gallium/auxiliary/util/u_transfer_helper.c +++ b/src/gallium/auxiliary/util/u_transfer_helper.c @@ -38,11 +38,14 @@ struct u_transfer_helper { bool fake_rgtc; bool msaa_map; bool z24_in_z32f; /* the z24 values are stored in a z32 - translate them. */ + bool interleave_in_place; }; static inline bool need_interleave_path(struct u_transfer_helper *helper, enum pipe_format format) { + if (!helper->interleave_in_place) + return false; if (helper->separate_stencil && util_format_is_depth_and_stencil(format)) return true; if (helper->separate_z32s8 && format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) @@ -103,8 +106,9 @@ u_transfer_helper_resource_create(struct pipe_screen *pscreen, enum pipe_format format = templ->format; struct pipe_resource *prsc; - if ((helper->separate_stencil && util_format_is_depth_and_stencil(format)) || - (format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT && helper->separate_z32s8)) { + if (((helper->separate_stencil && util_format_is_depth_and_stencil(format)) || + (format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT && helper->separate_z32s8)) && + !helper->interleave_in_place) { struct pipe_resource t = *templ; struct pipe_resource *stencil; @@ -151,7 +155,7 @@ u_transfer_helper_resource_destroy(struct pipe_screen *pscreen, { struct u_transfer_helper *helper = pscreen->transfer_helper; - if (helper->vtbl->get_stencil) { + if (helper->vtbl->get_stencil && !helper->interleave_in_place) { struct pipe_resource *stencil = helper->vtbl->get_stencil(prsc); pipe_resource_reference(&stencil, NULL); @@ -253,7 +257,9 @@ u_transfer_helper_transfer_map(struct pipe_context *pctx, unsigned width = box->width; unsigned height = box->height; - if (!handle_transfer(prsc)) + if (need_interleave_path(helper, format)) + return u_transfer_helper_deinterleave_transfer_map(pctx, prsc, level, usage, box, pptrans); + else if (!handle_transfer(prsc)) return helper->vtbl->transfer_map(pctx, prsc, level, usage, box, pptrans); if (helper->msaa_map && (prsc->nr_samples > 1)) @@ -519,6 +525,11 @@ u_transfer_helper_transfer_unmap(struct pipe_context *pctx, { struct u_transfer_helper *helper = pctx->screen->transfer_helper; + if (need_interleave_path(helper, ptrans->resource->format)) { + u_transfer_helper_deinterleave_transfer_unmap(pctx, ptrans); + return; + } + if (handle_transfer(ptrans->resource)) { struct u_transfer *trans = u_transfer(ptrans); @@ -563,6 +574,7 @@ u_transfer_helper_create(const struct u_transfer_vtbl *vtbl, helper->fake_rgtc = flags & U_TRANSFER_HELPER_FAKE_RGTC; helper->msaa_map = flags & U_TRANSFER_HELPER_MSAA_MAP; helper->z24_in_z32f = flags & U_TRANSFER_HELPER_Z24_IN_Z32F; + helper->interleave_in_place = flags & U_TRANSFER_HELPER_INTERLEAVE_IN_PLACE; return helper; } diff --git a/src/gallium/auxiliary/util/u_transfer_helper.h b/src/gallium/auxiliary/util/u_transfer_helper.h index 430deffeb04a..5c851413c5f2 100644 --- a/src/gallium/auxiliary/util/u_transfer_helper.h +++ b/src/gallium/auxiliary/util/u_transfer_helper.h @@ -104,6 +104,7 @@ enum u_transfer_helper_flags { U_TRANSFER_HELPER_FAKE_RGTC = (1 << 2), U_TRANSFER_HELPER_MSAA_MAP = (1 << 3), U_TRANSFER_HELPER_Z24_IN_Z32F = (1 << 4), + U_TRANSFER_HELPER_INTERLEAVE_IN_PLACE = (1 << 5), }; struct pipe_resource *u_transfer_helper_resource_create( -- GitLab From c033a12c525a3eb7a81028d7521dec56728bcb85 Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Tue, 9 Aug 2022 14:11:22 +0200 Subject: [PATCH 3/4] zink: use full transfer-helper api This is going to make it easier to maintain u_transfer_helper in the future. Reviewed-by: Mike Blumenkrantz Part-of: --- src/gallium/drivers/zink/zink_resource.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c index a0fd5400632f..588b17f2f31a 100644 --- a/src/gallium/drivers/zink/zink_resource.c +++ b/src/gallium/drivers/zink/zink_resource.c @@ -2266,12 +2266,13 @@ bool zink_screen_resource_init(struct pipe_screen *pscreen) { struct zink_screen *screen = zink_screen(pscreen); - pscreen->resource_create = zink_resource_create; + pscreen->resource_create = u_transfer_helper_resource_create; pscreen->resource_create_with_modifiers = zink_resource_create_with_modifiers; pscreen->resource_create_drawable = zink_resource_create_drawable; - pscreen->resource_destroy = zink_resource_destroy; + pscreen->resource_destroy = u_transfer_helper_resource_destroy; pscreen->transfer_helper = u_transfer_helper_create(&transfer_vtbl, U_TRANSFER_HELPER_SEPARATE_Z32S8 | U_TRANSFER_HELPER_SEPARATE_STENCIL | + U_TRANSFER_HELPER_INTERLEAVE_IN_PLACE | (!screen->have_D24_UNORM_S8_UINT ? U_TRANSFER_HELPER_Z24_IN_Z32F : 0)); if (screen->info.have_KHR_external_memory_fd || screen->info.have_KHR_external_memory_win32) { @@ -2292,8 +2293,8 @@ zink_context_resource_init(struct pipe_context *pctx) { pctx->buffer_map = zink_buffer_map; pctx->buffer_unmap = zink_buffer_unmap; - pctx->texture_map = u_transfer_helper_deinterleave_transfer_map; - pctx->texture_unmap = u_transfer_helper_deinterleave_transfer_unmap; + pctx->texture_map = u_transfer_helper_transfer_map; + pctx->texture_unmap = u_transfer_helper_transfer_unmap; pctx->transfer_flush_region = u_transfer_helper_transfer_flush_region; pctx->buffer_subdata = zink_buffer_subdata; -- GitLab From 530683096bf3141576790c53aa49a3339fc265f7 Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Tue, 9 Aug 2022 14:11:46 +0200 Subject: [PATCH 4/4] gallium/u_transfer_helper: hide deinterleave helpers There's no more callers of these, so let's make them an implementation detail instead of public API. Reviewed-by: Alyssa Rosenzweig Part-of: --- src/gallium/auxiliary/util/u_transfer_helper.c | 15 +++++++++++++-- src/gallium/auxiliary/util/u_transfer_helper.h | 10 ---------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/gallium/auxiliary/util/u_transfer_helper.c b/src/gallium/auxiliary/util/u_transfer_helper.c index 43e4aba8ada0..6dc8afa63f71 100644 --- a/src/gallium/auxiliary/util/u_transfer_helper.c +++ b/src/gallium/auxiliary/util/u_transfer_helper.c @@ -243,6 +243,13 @@ transfer_map_msaa(struct pipe_context *pctx, return ss_map; } +static void * +u_transfer_helper_deinterleave_transfer_map(struct pipe_context *pctx, + struct pipe_resource *prsc, + unsigned level, unsigned usage, + const struct pipe_box *box, + struct pipe_transfer **pptrans); + void * u_transfer_helper_transfer_map(struct pipe_context *pctx, struct pipe_resource *prsc, @@ -519,6 +526,10 @@ u_transfer_helper_transfer_flush_region(struct pipe_context *pctx, } } +static void +u_transfer_helper_deinterleave_transfer_unmap(struct pipe_context *pctx, + struct pipe_transfer *ptrans); + void u_transfer_helper_transfer_unmap(struct pipe_context *pctx, struct pipe_transfer *ptrans) @@ -592,7 +603,7 @@ u_transfer_helper_destroy(struct u_transfer_helper *helper) * drivers should expect to be passed the same buffer repeatedly with the format changed * to indicate which component is being mapped */ -void * +static void * u_transfer_helper_deinterleave_transfer_map(struct pipe_context *pctx, struct pipe_resource *prsc, unsigned level, unsigned usage, @@ -696,7 +707,7 @@ fail: return NULL; } -void +static void u_transfer_helper_deinterleave_transfer_unmap(struct pipe_context *pctx, struct pipe_transfer *ptrans) { diff --git a/src/gallium/auxiliary/util/u_transfer_helper.h b/src/gallium/auxiliary/util/u_transfer_helper.h index 5c851413c5f2..4b7707f46708 100644 --- a/src/gallium/auxiliary/util/u_transfer_helper.h +++ b/src/gallium/auxiliary/util/u_transfer_helper.h @@ -136,16 +136,6 @@ u_transfer_helper_create(const struct u_transfer_vtbl *vtbl, void u_transfer_helper_destroy(struct u_transfer_helper *helper); -void * -u_transfer_helper_deinterleave_transfer_map(struct pipe_context *pctx, - struct pipe_resource *prsc, - unsigned level, unsigned usage, - const struct pipe_box *box, - struct pipe_transfer **pptrans); - -void -u_transfer_helper_deinterleave_transfer_unmap(struct pipe_context *pctx, - struct pipe_transfer *ptrans); #ifdef __cplusplus } // extern "C" { #endif -- GitLab