mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-01 06:50:22 +01:00
lavapipe: Implement VK_EXT_image_2d_view_of_3d with sparse textures
The following things needed to be fixed: - lp_build_tiled_sample_offset has to use the block size of the underlying 3D texture. Remaining calculations use the dimensions of the view since the z-coordinate is undefined and has to be ignored. - The layer offset must be calculated using llvmpipe_get_texel_offset. Fixes:d747c4a("lavapipe: Implement sparse buffers and images") Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com> Reviewed-by: Dave Airlie <airlied@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31038> (cherry picked from commit1ad1b356fc)
This commit is contained in:
parent
97570a038d
commit
412fbc16ed
5 changed files with 48 additions and 9 deletions
|
|
@ -3234,7 +3234,7 @@
|
|||
"description": "lavapipe: Implement VK_EXT_image_2d_view_of_3d with sparse textures",
|
||||
"nominated": true,
|
||||
"nomination_type": 1,
|
||||
"resolution": 0,
|
||||
"resolution": 1,
|
||||
"main_sha": null,
|
||||
"because_sha": "d747c4a8746834d3c9a6fbd7b455b7ce9441fb38",
|
||||
"notes": null
|
||||
|
|
|
|||
|
|
@ -123,6 +123,8 @@ lp_sampler_static_texture_state(struct lp_static_texture_state *state,
|
|||
else
|
||||
state->target = view->target;
|
||||
|
||||
state->res_target = texture->target;
|
||||
|
||||
state->pot_width = util_is_power_of_two_or_zero(texture->width0);
|
||||
state->pot_height = util_is_power_of_two_or_zero(texture->height0);
|
||||
state->pot_depth = util_is_power_of_two_or_zero(texture->depth0);
|
||||
|
|
@ -166,13 +168,17 @@ lp_sampler_static_texture_state_image(struct lp_static_texture_state *state,
|
|||
assert(state->swizzle_a < PIPE_SWIZZLE_NONE);
|
||||
|
||||
state->target = resource->target;
|
||||
state->res_target = resource->target;
|
||||
state->pot_width = util_is_power_of_two_or_zero(resource->width0);
|
||||
state->pot_height = util_is_power_of_two_or_zero(resource->height0);
|
||||
state->pot_depth = util_is_power_of_two_or_zero(resource->depth0);
|
||||
state->level_zero_only = view->u.tex.level == 0;
|
||||
state->tiled = !!(resource->flags & PIPE_RESOURCE_FLAG_SPARSE);
|
||||
if (state->tiled)
|
||||
if (state->tiled) {
|
||||
state->tiled_samples = resource->nr_samples;
|
||||
if (view->u.tex.is_2d_view_of_3d)
|
||||
state->target = PIPE_TEXTURE_2D;
|
||||
}
|
||||
|
||||
/*
|
||||
* the layer / element / level parameters are all either dynamic
|
||||
|
|
@ -2222,6 +2228,21 @@ lp_build_tiled_sample_offset(struct lp_build_context *bld,
|
|||
|
||||
assert(static_texture_state->tiled);
|
||||
|
||||
uint32_t res_dimensions = 1;
|
||||
switch (static_texture_state->res_target) {
|
||||
case PIPE_TEXTURE_2D:
|
||||
case PIPE_TEXTURE_CUBE:
|
||||
case PIPE_TEXTURE_RECT:
|
||||
case PIPE_TEXTURE_2D_ARRAY:
|
||||
res_dimensions = 2;
|
||||
break;
|
||||
case PIPE_TEXTURE_3D:
|
||||
res_dimensions = 3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t dimensions = 1;
|
||||
switch (static_texture_state->target) {
|
||||
case PIPE_TEXTURE_2D:
|
||||
|
|
@ -2244,9 +2265,9 @@ lp_build_tiled_sample_offset(struct lp_build_context *bld,
|
|||
};
|
||||
|
||||
uint32_t sparse_tile_size[3] = {
|
||||
util_format_get_tilesize(format, dimensions, static_texture_state->tiled_samples, 0) * block_size[0],
|
||||
util_format_get_tilesize(format, dimensions, static_texture_state->tiled_samples, 1) * block_size[1],
|
||||
util_format_get_tilesize(format, dimensions, static_texture_state->tiled_samples, 2) * block_size[2],
|
||||
util_format_get_tilesize(format, res_dimensions, static_texture_state->tiled_samples, 0) * block_size[0],
|
||||
util_format_get_tilesize(format, res_dimensions, static_texture_state->tiled_samples, 1) * block_size[1],
|
||||
util_format_get_tilesize(format, res_dimensions, static_texture_state->tiled_samples, 2) * block_size[2],
|
||||
};
|
||||
|
||||
LLVMValueRef sparse_tile_size_log2[3] = {
|
||||
|
|
|
|||
|
|
@ -197,6 +197,7 @@ struct lp_static_texture_state
|
|||
|
||||
/* pipe_texture's state */
|
||||
enum pipe_texture_target target:5; /**< PIPE_TEXTURE_* */
|
||||
enum pipe_texture_target res_target:5;
|
||||
unsigned pot_width:1; /**< is the width a power of two? */
|
||||
unsigned pot_height:1;
|
||||
unsigned pot_depth:1;
|
||||
|
|
|
|||
|
|
@ -418,11 +418,13 @@ lp_jit_texture_from_pipe(struct lp_jit_texture *jit, const struct pipe_sampler_v
|
|||
}
|
||||
}
|
||||
|
||||
bool is_2d_view_of_3d = res->target == PIPE_TEXTURE_3D && view->target == PIPE_TEXTURE_2D;
|
||||
|
||||
if (res->target == PIPE_TEXTURE_1D_ARRAY ||
|
||||
res->target == PIPE_TEXTURE_2D_ARRAY ||
|
||||
res->target == PIPE_TEXTURE_CUBE ||
|
||||
res->target == PIPE_TEXTURE_CUBE_ARRAY ||
|
||||
(res->target == PIPE_TEXTURE_3D && view->target == PIPE_TEXTURE_2D)) {
|
||||
is_2d_view_of_3d) {
|
||||
/*
|
||||
* For array textures, we don't have first_layer, instead
|
||||
* adjust last_layer (stored as depth) plus the mip level
|
||||
|
|
@ -432,8 +434,13 @@ lp_jit_texture_from_pipe(struct lp_jit_texture *jit, const struct pipe_sampler_v
|
|||
*/
|
||||
jit->depth = view->u.tex.last_layer - view->u.tex.first_layer + 1;
|
||||
for (unsigned j = first_level; j <= last_level; j++) {
|
||||
jit->mip_offsets[j] += view->u.tex.first_layer *
|
||||
lp_tex->img_stride[j];
|
||||
if (is_2d_view_of_3d && (res->flags & PIPE_RESOURCE_FLAG_SPARSE)) {
|
||||
jit->mip_offsets[j] = llvmpipe_get_texel_offset(
|
||||
view->texture, j, 0, 0, view->u.tex.first_layer);
|
||||
} else {
|
||||
jit->mip_offsets[j] += view->u.tex.first_layer *
|
||||
lp_tex->img_stride[j];
|
||||
}
|
||||
}
|
||||
if (view->target == PIPE_TEXTURE_CUBE ||
|
||||
view->target == PIPE_TEXTURE_CUBE_ARRAY) {
|
||||
|
|
@ -580,7 +587,14 @@ lp_jit_image_from_pipe(struct lp_jit_image *jit, const struct pipe_image_view *v
|
|||
* XXX For mip levels, could do something similar.
|
||||
*/
|
||||
jit->depth = view->u.tex.last_layer - view->u.tex.first_layer + 1;
|
||||
mip_offset += view->u.tex.first_layer * lp_res->img_stride[view->u.tex.level];
|
||||
|
||||
if (res->target == PIPE_TEXTURE_3D && view->u.tex.first_layer != 0 &&
|
||||
(res->flags & PIPE_RESOURCE_FLAG_SPARSE)) {
|
||||
mip_offset = llvmpipe_get_texel_offset(
|
||||
res, view->u.tex.level, 0, 0, view->u.tex.first_layer);
|
||||
} else {
|
||||
mip_offset += view->u.tex.first_layer * lp_res->img_stride[view->u.tex.level];
|
||||
}
|
||||
} else
|
||||
jit->depth = u_minify(jit->depth, view->u.tex.level);
|
||||
|
||||
|
|
|
|||
|
|
@ -327,6 +327,9 @@ lvp_create_imageview(const struct lvp_image_view *iv, VkFormat plane_format, uns
|
|||
} else {
|
||||
view.u.tex.first_layer = iv->vk.base_array_layer,
|
||||
view.u.tex.last_layer = iv->vk.base_array_layer + iv->vk.layer_count - 1;
|
||||
|
||||
if (view.resource->target == PIPE_TEXTURE_3D)
|
||||
view.u.tex.is_2d_view_of_3d = true;
|
||||
}
|
||||
view.u.tex.level = iv->vk.base_mip_level;
|
||||
return view;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue