mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 22:00:13 +01:00
radv: Fix descriptors for cube images with VK_IMAGE_USAGE_STORAGE_BIT
If a cube image has VK_IMAGE_USAGE_STORAGE_BIT set, the type in an image
view's descriptor was set to a 2D array (and a few other fields adjusted
accordingly). This is correct when the image view is actually bound as a
storage image, but not when bound as a sampled image. In that case the
type should be set as a cube.
Fix by generating 2 sets of descriptors at view creation time for both
storage and non-storage usage, and then choose between them based on
descriptor type when writing descriptor sets.
v2: Generate storage descriptors for images with TRANSFER_DST, since
those may be used as storage images internally.
Signed-off-by: Alex Smith <asmith@feralinteractive.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
This commit is contained in:
parent
4d5c0c189d
commit
0e1886efb9
3 changed files with 74 additions and 29 deletions
|
|
@ -602,11 +602,18 @@ write_image_descriptor(struct radv_device *device,
|
||||||
struct radv_cmd_buffer *cmd_buffer,
|
struct radv_cmd_buffer *cmd_buffer,
|
||||||
unsigned *dst,
|
unsigned *dst,
|
||||||
struct radeon_winsys_bo **buffer_list,
|
struct radeon_winsys_bo **buffer_list,
|
||||||
|
VkDescriptorType descriptor_type,
|
||||||
const VkDescriptorImageInfo *image_info)
|
const VkDescriptorImageInfo *image_info)
|
||||||
{
|
{
|
||||||
RADV_FROM_HANDLE(radv_image_view, iview, image_info->imageView);
|
RADV_FROM_HANDLE(radv_image_view, iview, image_info->imageView);
|
||||||
memcpy(dst, iview->descriptor, 8 * 4);
|
|
||||||
memcpy(dst + 8, iview->fmask_descriptor, 8 * 4);
|
if (descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) {
|
||||||
|
memcpy(dst, iview->storage_descriptor, 8 * 4);
|
||||||
|
memcpy(dst + 8, iview->storage_fmask_descriptor, 8 * 4);
|
||||||
|
} else {
|
||||||
|
memcpy(dst, iview->descriptor, 8 * 4);
|
||||||
|
memcpy(dst + 8, iview->fmask_descriptor, 8 * 4);
|
||||||
|
}
|
||||||
|
|
||||||
if (cmd_buffer)
|
if (cmd_buffer)
|
||||||
device->ws->cs_add_buffer(cmd_buffer->cs, iview->bo, 7);
|
device->ws->cs_add_buffer(cmd_buffer->cs, iview->bo, 7);
|
||||||
|
|
@ -619,12 +626,13 @@ write_combined_image_sampler_descriptor(struct radv_device *device,
|
||||||
struct radv_cmd_buffer *cmd_buffer,
|
struct radv_cmd_buffer *cmd_buffer,
|
||||||
unsigned *dst,
|
unsigned *dst,
|
||||||
struct radeon_winsys_bo **buffer_list,
|
struct radeon_winsys_bo **buffer_list,
|
||||||
|
VkDescriptorType descriptor_type,
|
||||||
const VkDescriptorImageInfo *image_info,
|
const VkDescriptorImageInfo *image_info,
|
||||||
bool has_sampler)
|
bool has_sampler)
|
||||||
{
|
{
|
||||||
RADV_FROM_HANDLE(radv_sampler, sampler, image_info->sampler);
|
RADV_FROM_HANDLE(radv_sampler, sampler, image_info->sampler);
|
||||||
|
|
||||||
write_image_descriptor(device, cmd_buffer, dst, buffer_list, image_info);
|
write_image_descriptor(device, cmd_buffer, dst, buffer_list, descriptor_type, image_info);
|
||||||
/* copy over sampler state */
|
/* copy over sampler state */
|
||||||
if (has_sampler)
|
if (has_sampler)
|
||||||
memcpy(dst + 16, sampler->state, 16);
|
memcpy(dst + 16, sampler->state, 16);
|
||||||
|
|
@ -695,10 +703,12 @@ void radv_update_descriptor_sets(
|
||||||
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
||||||
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
|
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
|
||||||
write_image_descriptor(device, cmd_buffer, ptr, buffer_list,
|
write_image_descriptor(device, cmd_buffer, ptr, buffer_list,
|
||||||
|
writeset->descriptorType,
|
||||||
writeset->pImageInfo + j);
|
writeset->pImageInfo + j);
|
||||||
break;
|
break;
|
||||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
||||||
write_combined_image_sampler_descriptor(device, cmd_buffer, ptr, buffer_list,
|
write_combined_image_sampler_descriptor(device, cmd_buffer, ptr, buffer_list,
|
||||||
|
writeset->descriptorType,
|
||||||
writeset->pImageInfo + j,
|
writeset->pImageInfo + j,
|
||||||
!binding_layout->immutable_samplers_offset);
|
!binding_layout->immutable_samplers_offset);
|
||||||
if (copy_immutable_samplers) {
|
if (copy_immutable_samplers) {
|
||||||
|
|
@ -865,10 +875,12 @@ void radv_update_descriptor_set_with_template(struct radv_device *device,
|
||||||
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
||||||
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
|
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
|
||||||
write_image_descriptor(device, cmd_buffer, pDst, buffer_list,
|
write_image_descriptor(device, cmd_buffer, pDst, buffer_list,
|
||||||
|
templ->entry[i].descriptor_type,
|
||||||
(struct VkDescriptorImageInfo *) pSrc);
|
(struct VkDescriptorImageInfo *) pSrc);
|
||||||
break;
|
break;
|
||||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
||||||
write_combined_image_sampler_descriptor(device, cmd_buffer, pDst, buffer_list,
|
write_combined_image_sampler_descriptor(device, cmd_buffer, pDst, buffer_list,
|
||||||
|
templ->entry[i].descriptor_type,
|
||||||
(struct VkDescriptorImageInfo *) pSrc,
|
(struct VkDescriptorImageInfo *) pSrc,
|
||||||
templ->entry[i].has_sampler);
|
templ->entry[i].has_sampler);
|
||||||
if (templ->entry[i].immutable_samplers)
|
if (templ->entry[i].immutable_samplers)
|
||||||
|
|
|
||||||
|
|
@ -325,7 +325,7 @@ static unsigned gfx9_border_color_swizzle(const unsigned char swizzle[4])
|
||||||
static void
|
static void
|
||||||
si_make_texture_descriptor(struct radv_device *device,
|
si_make_texture_descriptor(struct radv_device *device,
|
||||||
struct radv_image *image,
|
struct radv_image *image,
|
||||||
bool sampler,
|
bool is_storage_image,
|
||||||
VkImageViewType view_type,
|
VkImageViewType view_type,
|
||||||
VkFormat vk_format,
|
VkFormat vk_format,
|
||||||
const VkComponentMapping *mapping,
|
const VkComponentMapping *mapping,
|
||||||
|
|
@ -362,7 +362,7 @@ si_make_texture_descriptor(struct radv_device *device,
|
||||||
}
|
}
|
||||||
|
|
||||||
type = radv_tex_dim(image->type, view_type, image->info.array_size, image->info.samples,
|
type = radv_tex_dim(image->type, view_type, image->info.array_size, image->info.samples,
|
||||||
(image->usage & VK_IMAGE_USAGE_STORAGE_BIT));
|
is_storage_image);
|
||||||
if (type == V_008F1C_SQ_RSRC_IMG_1D_ARRAY) {
|
if (type == V_008F1C_SQ_RSRC_IMG_1D_ARRAY) {
|
||||||
height = 1;
|
height = 1;
|
||||||
depth = image->info.array_size;
|
depth = image->info.array_size;
|
||||||
|
|
@ -526,7 +526,7 @@ radv_query_opaque_metadata(struct radv_device *device,
|
||||||
md->metadata[1] = si_get_bo_metadata_word1(device);
|
md->metadata[1] = si_get_bo_metadata_word1(device);
|
||||||
|
|
||||||
|
|
||||||
si_make_texture_descriptor(device, image, true,
|
si_make_texture_descriptor(device, image, false,
|
||||||
(VkImageViewType)image->type, image->vk_format,
|
(VkImageViewType)image->type, image->vk_format,
|
||||||
&fixedmapping, 0, image->info.levels - 1, 0,
|
&fixedmapping, 0, image->info.levels - 1, 0,
|
||||||
image->info.array_size,
|
image->info.array_size,
|
||||||
|
|
@ -834,6 +834,50 @@ radv_image_create(VkDevice _device,
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
radv_image_view_make_descriptor(struct radv_image_view *iview,
|
||||||
|
struct radv_device *device,
|
||||||
|
const VkImageViewCreateInfo* pCreateInfo,
|
||||||
|
bool is_storage_image)
|
||||||
|
{
|
||||||
|
RADV_FROM_HANDLE(radv_image, image, pCreateInfo->image);
|
||||||
|
const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
|
||||||
|
bool is_stencil = iview->aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||||
|
uint32_t blk_w;
|
||||||
|
uint32_t *descriptor;
|
||||||
|
uint32_t *fmask_descriptor;
|
||||||
|
|
||||||
|
if (is_storage_image) {
|
||||||
|
descriptor = iview->storage_descriptor;
|
||||||
|
fmask_descriptor = iview->storage_fmask_descriptor;
|
||||||
|
} else {
|
||||||
|
descriptor = iview->descriptor;
|
||||||
|
fmask_descriptor = iview->fmask_descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(image->surface.blk_w % vk_format_get_blockwidth(image->vk_format) == 0);
|
||||||
|
blk_w = image->surface.blk_w / vk_format_get_blockwidth(image->vk_format) * vk_format_get_blockwidth(iview->vk_format);
|
||||||
|
|
||||||
|
si_make_texture_descriptor(device, image, is_storage_image,
|
||||||
|
iview->type,
|
||||||
|
iview->vk_format,
|
||||||
|
&pCreateInfo->components,
|
||||||
|
0, radv_get_levelCount(image, range) - 1,
|
||||||
|
range->baseArrayLayer,
|
||||||
|
range->baseArrayLayer + radv_get_layerCount(image, range) - 1,
|
||||||
|
iview->extent.width,
|
||||||
|
iview->extent.height,
|
||||||
|
iview->extent.depth,
|
||||||
|
descriptor,
|
||||||
|
fmask_descriptor);
|
||||||
|
si_set_mutable_tex_desc_fields(device, image,
|
||||||
|
is_stencil ? &image->surface.u.legacy.stencil_level[range->baseMipLevel]
|
||||||
|
: &image->surface.u.legacy.level[range->baseMipLevel],
|
||||||
|
range->baseMipLevel,
|
||||||
|
range->baseMipLevel,
|
||||||
|
blk_w, is_stencil, descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
radv_image_view_init(struct radv_image_view *iview,
|
radv_image_view_init(struct radv_image_view *iview,
|
||||||
struct radv_device *device,
|
struct radv_device *device,
|
||||||
|
|
@ -841,8 +885,7 @@ radv_image_view_init(struct radv_image_view *iview,
|
||||||
{
|
{
|
||||||
RADV_FROM_HANDLE(radv_image, image, pCreateInfo->image);
|
RADV_FROM_HANDLE(radv_image, image, pCreateInfo->image);
|
||||||
const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
|
const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
|
||||||
uint32_t blk_w;
|
|
||||||
bool is_stencil = false;
|
|
||||||
switch (image->type) {
|
switch (image->type) {
|
||||||
case VK_IMAGE_TYPE_1D:
|
case VK_IMAGE_TYPE_1D:
|
||||||
case VK_IMAGE_TYPE_2D:
|
case VK_IMAGE_TYPE_2D:
|
||||||
|
|
@ -862,7 +905,6 @@ radv_image_view_init(struct radv_image_view *iview,
|
||||||
iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask;
|
iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask;
|
||||||
|
|
||||||
if (iview->aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) {
|
if (iview->aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) {
|
||||||
is_stencil = true;
|
|
||||||
iview->vk_format = vk_format_stencil_only(iview->vk_format);
|
iview->vk_format = vk_format_stencil_only(iview->vk_format);
|
||||||
} else if (iview->aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT) {
|
} else if (iview->aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT) {
|
||||||
iview->vk_format = vk_format_depth_only(iview->vk_format);
|
iview->vk_format = vk_format_depth_only(iview->vk_format);
|
||||||
|
|
@ -879,30 +921,15 @@ radv_image_view_init(struct radv_image_view *iview,
|
||||||
iview->extent.height = round_up_u32(iview->extent.height * vk_format_get_blockheight(iview->vk_format),
|
iview->extent.height = round_up_u32(iview->extent.height * vk_format_get_blockheight(iview->vk_format),
|
||||||
vk_format_get_blockheight(image->vk_format));
|
vk_format_get_blockheight(image->vk_format));
|
||||||
|
|
||||||
assert(image->surface.blk_w % vk_format_get_blockwidth(image->vk_format) == 0);
|
|
||||||
blk_w = image->surface.blk_w / vk_format_get_blockwidth(image->vk_format) * vk_format_get_blockwidth(iview->vk_format);
|
|
||||||
iview->base_layer = range->baseArrayLayer;
|
iview->base_layer = range->baseArrayLayer;
|
||||||
iview->layer_count = radv_get_layerCount(image, range);
|
iview->layer_count = radv_get_layerCount(image, range);
|
||||||
iview->base_mip = range->baseMipLevel;
|
iview->base_mip = range->baseMipLevel;
|
||||||
|
|
||||||
si_make_texture_descriptor(device, image, false,
|
radv_image_view_make_descriptor(iview, device, pCreateInfo, false);
|
||||||
iview->type,
|
|
||||||
iview->vk_format,
|
/* For transfers we may use the image as a storage image. */
|
||||||
&pCreateInfo->components,
|
if (image->usage & (VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT))
|
||||||
0, radv_get_levelCount(image, range) - 1,
|
radv_image_view_make_descriptor(iview, device, pCreateInfo, true);
|
||||||
range->baseArrayLayer,
|
|
||||||
range->baseArrayLayer + radv_get_layerCount(image, range) - 1,
|
|
||||||
iview->extent.width,
|
|
||||||
iview->extent.height,
|
|
||||||
iview->extent.depth,
|
|
||||||
iview->descriptor,
|
|
||||||
iview->fmask_descriptor);
|
|
||||||
si_set_mutable_tex_desc_fields(device, image,
|
|
||||||
is_stencil ? &image->surface.u.legacy.stencil_level[range->baseMipLevel]
|
|
||||||
: &image->surface.u.legacy.level[range->baseMipLevel],
|
|
||||||
range->baseMipLevel,
|
|
||||||
range->baseMipLevel,
|
|
||||||
blk_w, is_stencil, iview->descriptor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool radv_layout_has_htile(const struct radv_image *image,
|
bool radv_layout_has_htile(const struct radv_image *image,
|
||||||
|
|
|
||||||
|
|
@ -1276,6 +1276,12 @@ struct radv_image_view {
|
||||||
|
|
||||||
uint32_t descriptor[8];
|
uint32_t descriptor[8];
|
||||||
uint32_t fmask_descriptor[8];
|
uint32_t fmask_descriptor[8];
|
||||||
|
|
||||||
|
/* Descriptor for use as a storage image as opposed to a sampled image.
|
||||||
|
* This has a few differences for cube maps (e.g. type).
|
||||||
|
*/
|
||||||
|
uint32_t storage_descriptor[8];
|
||||||
|
uint32_t storage_fmask_descriptor[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct radv_image_create_info {
|
struct radv_image_create_info {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue