freedreno/a6xx: cl_khr_image2d_from_buffer support

This allows sampling from a buffer as if it was a simple (single
level/layer, linear) 2d image/texture.  Add a helper to convert
struct pipe_image_view to an apprpriate fdl_layout and wire it up
in the image view and tex view paths.

Can be tested with cl cts:

 ./test_image_streams 2D read CL_RG CL_SIGNED_INT16 CL_FILTER_NEAREST CL_ADDRESS_CLAMP_TO_EDGE UNNORMALIZED

(for ex)

Signed-off-by: Rob Clark <rob.clark@oss.qualcomm.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35447>
This commit is contained in:
Rob Clark
2025-06-10 15:03:21 -07:00
committed by Marge Bot
parent 095e136f8b
commit 8eb2540b78
5 changed files with 95 additions and 3 deletions
+1 -1
View File
@@ -767,7 +767,7 @@ Rusticl OpenCL 2.0 -- all DONE:
Pipes not started
Extended 2D images creation in progress
- CL_ABGR DONE
- cl_khr_image2d_from_buffer DONE (iris, llvmpipe)
- cl_khr_image2d_from_buffer DONE (freedreno, iris, llvmpipe)
- cl_khr_depth_images DONE
- from sRGB images in progress
clCreateSamplerWithProperties DONE
@@ -46,7 +46,36 @@ static void
fd6_image_descriptor(struct fd_context *ctx, const struct pipe_image_view *buf,
uint32_t *descriptor)
{
if (buf->resource->target == PIPE_BUFFER) {
if (buf->access & PIPE_IMAGE_ACCESS_TEX2D_FROM_BUFFER) {
struct fdl_view_args args = {
.chip = ctx->screen->gen,
.iova = rsc_iova(buf->resource, 0),
.base_miplevel = 0,
.level_count = 1,
.base_array_layer = 0,
.layer_count = 1,
.swiz = {PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z,
PIPE_SWIZZLE_W},
.format = buf->format,
.type = FDL_VIEW_TYPE_2D,
.chroma_offsets = {FDL_CHROMA_LOCATION_COSITED_EVEN,
FDL_CHROMA_LOCATION_COSITED_EVEN},
};
struct fdl_layout layout;
const struct fdl_layout *layouts = &layout;
fd6_layout_tex2d_from_buf(&layout, ctx->screen->info, buf->format,
&buf->u.tex2d_from_buf);
struct fdl6_view view;
fdl6_view_init(&view, &layouts, &args,
ctx->screen->info->a6xx.has_z24uint_s8uint);
memcpy(descriptor, view.storage_descriptor, sizeof(view.storage_descriptor));
} else if (buf->resource->target == PIPE_BUFFER) {
uint32_t size = fd_clamp_buffer_size(buf->format, buf->u.buf.size,
A4XX_MAX_TEXEL_BUFFER_ELEMENTS_UINT);
@@ -442,7 +442,37 @@ fd6_sampler_view_update(struct fd_context *ctx,
so->ptr1 = rsc;
if (cso->target == PIPE_BUFFER) {
if (cso->is_tex2d_from_buf) {
struct fdl_view_args args = {
.chip = ctx->screen->gen,
/* Using relocs for addresses still */
.iova = 0,
.base_miplevel = 0,
.level_count = 1,
.base_array_layer = 0,
.layer_count = 1,
.swiz = {cso->swizzle_r, cso->swizzle_g, cso->swizzle_b,
cso->swizzle_a},
.format = format,
.type = FDL_VIEW_TYPE_2D,
.chroma_offsets = {FDL_CHROMA_LOCATION_COSITED_EVEN,
FDL_CHROMA_LOCATION_COSITED_EVEN},
};
struct fdl_layout layout;
const struct fdl_layout *layouts = &layout;
fd6_layout_tex2d_from_buf(&layout, ctx->screen->info, format,
&cso->u.tex2d_from_buf);
struct fdl6_view view;
fdl6_view_init(&view, &layouts, &args,
ctx->screen->info->a6xx.has_z24uint_s8uint);
memcpy(so->descriptor, view.descriptor, sizeof(so->descriptor));
} else if (cso->target == PIPE_BUFFER) {
uint8_t swiz[4] = {cso->swizzle_r, cso->swizzle_g, cso->swizzle_b,
cso->swizzle_a};
@@ -112,6 +112,34 @@ struct fd6_texture_state {
struct fd6_texture_state *
fd6_texture_state(struct fd_context *ctx, enum pipe_shader_type type) assert_dt;
static inline void
fd6_layout_tex2d_from_buf(struct fdl_layout *layout,
const struct fd_dev_info *info,
enum pipe_format format,
const struct pipe_tex2d_from_buf *tex2d_from_buf)
{
unsigned block_size = util_format_get_blocksize(format);
struct fdl_explicit_layout explicit_layout = {
.offset = tex2d_from_buf->offset * block_size,
.pitch = tex2d_from_buf->row_stride * block_size,
};
*layout = (struct fdl_layout) {
.ubwc = false,
.tile_all = false,
.tile_mode = TILE6_LINEAR,
};
ASSERTED bool ret = fdl6_layout(layout, info, format, 1,
tex2d_from_buf->width,
tex2d_from_buf->height,
1, 1, 1, false, false,
false, &explicit_layout);
assert(ret);
}
ENDC;
#endif /* FD6_TEXTURE_H_ */
@@ -512,6 +512,11 @@ fd_init_screen_caps(struct fd_screen *screen)
caps->shader_buffer_offset_alignment =
is_a6xx(screen) ? 64 : (is_a5xx(screen) || is_a4xx(screen) ? 4 : 0);
if (is_a6xx(screen)) {
caps->linear_image_pitch_alignment = 64;
caps->linear_image_base_address_alignment = 64;
}
caps->max_texture_gather_components =
is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen) ? 4 : 0;