diff --git a/src/gallium/auxiliary/util/u_transfer_helper.c b/src/gallium/auxiliary/util/u_transfer_helper.c index 10ee300342446ffc5726564e18979e86d55c5145..6dc8afa63f71aa475955721aa4221821cbc05c72 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); @@ -239,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, @@ -253,7 +264,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)) @@ -513,12 +526,21 @@ 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) { 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); @@ -553,20 +575,17 @@ 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; + helper->interleave_in_place = flags & U_TRANSFER_HELPER_INTERLEAVE_IN_PLACE; return helper; } @@ -584,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, @@ -688,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 d62d8a198483c2363a49ab568ec2dc8afbcb6aad..4b7707f4670878a1a80f360335a2d119d0637b96 100644 --- a/src/gallium/auxiliary/util/u_transfer_helper.h +++ b/src/gallium/auxiliary/util/u_transfer_helper.h @@ -98,6 +98,15 @@ 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), + U_TRANSFER_HELPER_INTERLEAVE_IN_PLACE = (1 << 5), +}; + struct pipe_resource *u_transfer_helper_resource_create( struct pipe_screen *pscreen, const struct pipe_resource *templ); @@ -121,25 +130,12 @@ 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); -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 diff --git a/src/gallium/drivers/asahi/agx_pipe.c b/src/gallium/drivers/asahi/agx_pipe.c index 7f3dd07e498f76d5b29ec17ca4f15138e2924179..389b11f21508fe7d2123398fbd40fa4c1cf65871 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 c35b63079c2bf26ff983442eb10c17c255eca8cf..8e9d7dae09387213c77079a4da99489cc37d796d 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 9b4a136d6abfe76af5e7a212572ce07a5ae8a336..eb189b091e910ace6d0bc3ed1eb121ad7eb84493 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 c5b36176ca795acb672986eb102614694d2c271d..69487876abaacb44bf88edfb0bdaaad7779116f6 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 10c471424f96d66660ad00f8cf2f353c3d1156c8..11fa075ed0042c0a05de08fbd717534021a5ad32 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 b673af74370a79acb030e6709ef31c6d70fe87c4..228e452013529a07b33ec7efc368ec3218fd60be 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 b85983c23f57377f69c413c9091781acb1549757..c97537516767f4c1f3bc9444e5ad114d4e64f045 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 d9b80a5170090be067d32023c6512bb5779480af..ab918a05cce5c39d20ebe41b521e0504ee2deb55 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 b65bbedf0bd490fa04cf135c51f07d7159630b27..588b17f2f31a87c04916ca09db7e2d68fe04b440 100644 --- a/src/gallium/drivers/zink/zink_resource.c +++ b/src/gallium/drivers/zink/zink_resource.c @@ -2266,11 +2266,14 @@ 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->transfer_helper = u_transfer_helper_create(&transfer_vtbl, true, true, false, false, !screen->have_D24_UNORM_S8_UINT); + 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) { pscreen->resource_get_handle = zink_resource_get_handle; @@ -2290,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;