gallium: Add util_image_to_sampler_view helper

This helper is useful to implement images. This implementation is based on the
one in Panfrost and extended to handle all pipe_image_views (notably including
tex2d_from_buf which did not exist when the panfrost version was written). It
will be used in both Panfrost and Asahi.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Reviewed-by: Emma Anholt <emma@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23273>
This commit is contained in:
Alyssa Rosenzweig 2023-05-25 17:04:56 -04:00 committed by Marge Bot
parent d261c425ff
commit 07e477bb39
2 changed files with 75 additions and 0 deletions

View file

@ -563,3 +563,75 @@ util_clamp_color(enum pipe_format format,
return clamp_color;
}
/*
* Some hardware does not use a distinct descriptor for images, so it is
* convenient for drivers to reuse their texture descriptor packing for shader
* images. This helper constructs a synthetic, non-reference counted
* pipe_sampler_view corresponding to a given pipe_image_view for drivers'
* internal convenience.
*
* The returned descriptor is "synthetic" in the sense that it is not reference
* counted and the context field is ignored. Otherwise it's complete.
*/
struct pipe_sampler_view
util_image_to_sampler_view(struct pipe_image_view *v)
{
struct pipe_sampler_view out = {
.format = v->format,
.is_tex2d_from_buf = v->access & PIPE_IMAGE_ACCESS_TEX2D_FROM_BUFFER,
.target = v->resource->target,
.swizzle_r = PIPE_SWIZZLE_X,
.swizzle_g = PIPE_SWIZZLE_Y,
.swizzle_b = PIPE_SWIZZLE_Z,
.swizzle_a = PIPE_SWIZZLE_W,
.texture = v->resource,
};
if (out.target == PIPE_BUFFER) {
out.u.buf.offset = v->u.buf.offset;
out.u.buf.size = v->u.buf.size;
} else if (out.is_tex2d_from_buf) {
out.u.tex2d_from_buf.offset = v->u.tex2d_from_buf.offset;
out.u.tex2d_from_buf.row_stride = v->u.tex2d_from_buf.row_stride;
out.u.tex2d_from_buf.width = v->u.tex2d_from_buf.width;
out.u.tex2d_from_buf.height = v->u.tex2d_from_buf.height;
} else {
/* For a single layer view of a multilayer image, we need to swap in the
* non-layered texture target to match the texture instruction.
*/
if (v->u.tex.single_layer_view) {
switch (out.target) {
case PIPE_TEXTURE_1D_ARRAY:
/* A single layer is a 1D image */
out.target = PIPE_TEXTURE_1D;
break;
case PIPE_TEXTURE_3D:
case PIPE_TEXTURE_CUBE:
case PIPE_TEXTURE_2D_ARRAY:
case PIPE_TEXTURE_CUBE_ARRAY:
/* A single layer/face is a 2D image.
*
* Note that OpenGL does not otherwise support 2D views of 3D.
* Drivers that use this helper must support that anyway.
*/
out.target = PIPE_TEXTURE_2D;
break;
default:
/* Other texture targets already only have 1 layer, nothing to do */
break;
}
}
out.u.tex.first_layer = v->u.tex.first_layer;
out.u.tex.last_layer = v->u.tex.last_layer;
/* Single level only */
out.u.tex.first_level = v->u.tex.level;
out.u.tex.last_level = v->u.tex.level;
}
return out;
}

View file

@ -135,6 +135,9 @@ util_init_pipe_vertex_state(struct pipe_screen *screen,
union pipe_color_union util_clamp_color(enum pipe_format format,
const union pipe_color_union *color);
struct pipe_sampler_view
util_image_to_sampler_view(struct pipe_image_view *v);
#ifdef __cplusplus
}
#endif