llvmpipe: Fix array mismatch when accessing shader images
The compiled image function is derived from the image view, which is supposed to match what is declared in the shader, however we did fixups for array targets that only had one layer, since pipe_shader_image actually doesn't have a target (derived from the resource instead). But this is not correct at least for vulkan, since then the layer coord is completely ignored, so we never got OOB behavior wrt the layer coord. Use single_layer_view field in pipe_shader_image to denote non-array targets (the GL state tracker uses this in a similar way already, although llvmpipe ignored it). Reviewed-by: Konstantin Seurer <konstantin.seurer@gmail.com> Reviewed-by: Brian Paul <brian.paul@broadcom.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36304>
This commit is contained in:
committed by
Marge Bot
parent
5291eb9cd2
commit
5385624c6d
@@ -126,7 +126,20 @@ llvmpipe_create_image_handle(struct pipe_context *pctx, const struct pipe_image_
|
||||
state.static_state.pot_height = false;
|
||||
state.static_state.pot_depth = false;
|
||||
|
||||
if (view->u.tex.first_layer == view->u.tex.last_layer) {
|
||||
/*
|
||||
* Rely on single_layer_view to distinguish array and non-array targets,
|
||||
* since there's no target field in pipe_image_view, and there can
|
||||
* be mismatch between resource and view.
|
||||
* We cannot unconditionally demote array to non-array targets if there's
|
||||
* only one layer, since we'd then ignore the layer coord completely and
|
||||
* OOB behavior would be wrong.
|
||||
*
|
||||
* XXX shouldn't we do this in lp_sampler_static_texture_state_image()
|
||||
* in the first place (there's more callers)?
|
||||
*/
|
||||
if (view->resource && llvmpipe_resource_is_texture(view->resource) &&
|
||||
view->u.tex.single_layer_view &&
|
||||
view->u.tex.first_layer == view->u.tex.last_layer) {
|
||||
if (state.static_state.target == PIPE_TEXTURE_1D_ARRAY)
|
||||
state.static_state.target = PIPE_TEXTURE_1D;
|
||||
else if (state.static_state.target == PIPE_TEXTURE_2D_ARRAY ||
|
||||
|
||||
@@ -337,6 +337,26 @@ lvp_create_imageview(const struct lvp_image_view *iv, VkFormat plane_format, uns
|
||||
if (view.resource->target == PIPE_TEXTURE_3D)
|
||||
view.u.tex.is_2d_view_of_3d = true;
|
||||
}
|
||||
|
||||
if (iv->vk.view_type == VK_IMAGE_VIEW_TYPE_1D ||
|
||||
iv->vk.view_type == VK_IMAGE_VIEW_TYPE_2D) {
|
||||
/*
|
||||
* There's no target field in pipe_image_view, but
|
||||
* there's a single_layer_view which the mesa state tracker
|
||||
* uses for a similar purpose, although not exactly the same,
|
||||
* here we just use it to indicate the view is of a non-array
|
||||
* type.
|
||||
* Note that the layered-ness must match between shader dcl
|
||||
* and view (but not between view and resource).
|
||||
* We ignore VK_IMAGE_VIEW_TYPE_CUBE here, should be fine
|
||||
* since there's no difference in accessing cube and cube arrays
|
||||
* (as layer and face combine into one var), and for size queries
|
||||
* we fix up targets separately (always using array types).
|
||||
*/
|
||||
assert(view.u.tex.first_layer == view.u.tex.last_layer);
|
||||
view.u.tex.single_layer_view = 1;
|
||||
}
|
||||
|
||||
view.u.tex.level = iv->vk.base_mip_level;
|
||||
return view;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user