pvr: cube map tex state packing fixes

A VK_ERROR_FORMAT_NOT_SUPPORTED error was being returned when setting up the
image view tex state for images with the VK_IMAGE_USAGE_STORAGE_BIT and/or
VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT bit(s) set due to missing handling in
pvr_pack_tex_state(). Resolve this by handling these cases, while taking the
opportunity to simplify how the tex type is determined when packing
TEXSTATE_IMAGE_WORD0.

It was also found that the depth field in TEXSTATE_IMAGE_WORD1 was being set up
incorrectly, as it was relying on the image depth being 0 for 1D and 2D images,
but the image depth will always be 1 in these cases.

Partial fix for dEQP-VK.image.qualifiers.volatile.cube.r32f. This now goes from
failing to seg faulting when VK_FORMAT_R32_SFLOAT is added to the format table,
as the test is now getting further.

Signed-off-by: Frank Binns <frank.binns@imgtec.com>
Reviewed-by: Rajnesh Kanwal <rajnesh.kanwal@imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18320>
This commit is contained in:
Frank Binns 2022-08-23 11:55:33 +01:00
parent 3436438dd0
commit fdf85f10a1
4 changed files with 78 additions and 28 deletions

View file

@ -1388,7 +1388,6 @@ static VkResult pvr_device_init_compute_idfwdf_state(struct pvr_device *device)
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.mem_layout = PVR_MEMLAYOUT_LINEAR,
.flags = PVR_TEXFLAGS_INDEX_LOOKUP,
/* TODO: Is this correct? Is it 2D, 3D, or 2D_ARRAY? */
.type = VK_IMAGE_VIEW_TYPE_2D,
.extent = { .width = 4, .height = 2, .depth = 0 },
.mip_levels = 1,

View file

@ -163,6 +163,12 @@ pvr_get_image_format_properties(struct pvr_physical_device *pdevice,
return VK_SUCCESS;
}
/* FIXME: Should this be returning VK_ERROR_FORMAT_NOT_SUPPORTED when tiling is
* linear and the image type is 3D or flags contains
* VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT? This should avoid well behaved apps
* attempting to create invalid image views, as pvr_pack_tex_state() will return
* VK_ERROR_FORMAT_NOT_SUPPORTED in these cases.
*/
VkResult pvr_GetPhysicalDeviceImageFormatProperties2(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo,

View file

@ -309,10 +309,11 @@ VkResult pvr_CreateImageView(VkDevice _device,
goto err_vk_image_view_destroy;
/* Create an additional texture state for cube type if storage
* usage flat is set.
* usage flag is set.
*/
if (info.is_cube && image->vk.usage & VK_IMAGE_USAGE_STORAGE_BIT) {
info.tex_state_type = PVR_TEXTURE_STATE_STORAGE;
result = pvr_pack_tex_state(device,
&info,
iview->texture_state[info.tex_state_type]);
@ -335,6 +336,13 @@ VkResult pvr_CreateImageView(VkDevice _device,
info.base_level = 0;
info.tex_state_type = PVR_TEXTURE_STATE_ATTACHMENT;
if (iview->vk.image->image_type == VK_IMAGE_TYPE_3D &&
iview->vk.view_type == VK_IMAGE_VIEW_TYPE_2D) {
info.type = VK_IMAGE_VIEW_TYPE_3D;
} else {
info.type = iview->vk.view_type;
}
result = pvr_pack_tex_state(device,
&info,
iview->texture_state[info.tex_state_type]);
@ -408,6 +416,7 @@ VkResult pvr_CreateBufferView(VkDevice _device,
info.addr = PVR_DEV_ADDR_OFFSET(buffer->dev_addr, pCreateInfo->offset);
info.mem_layout = PVR_MEMLAYOUT_LINEAR;
info.is_cube = false;
info.type = VK_IMAGE_VIEW_TYPE_2D;
info.tex_state_type = PVR_TEXTURE_STATE_SAMPLE;
info.format = bview->format;
info.flags = PVR_TEXFLAGS_INDEX_LOOKUP;

View file

@ -68,29 +68,66 @@ pvr_pack_tex_state(struct pvr_device *device,
uint64_t state[static const ROGUE_NUM_TEXSTATE_IMAGE_WORDS])
{
const struct pvr_device_info *dev_info = &device->pdevice->dev_info;
uint32_t texture_type;
enum pvr_memlayout mem_layout;
VkImageViewType iview_type;
if (info->type == VK_IMAGE_VIEW_TYPE_1D &&
info->mem_layout == PVR_MEMLAYOUT_LINEAR) {
/* Change the memory layout to twiddled as there isn't a TEXSTATE_TEXTYPE
* for 1D linear and 1D twiddled is equivalent.
*/
mem_layout = PVR_MEMLAYOUT_TWIDDLED;
} else {
mem_layout = info->mem_layout;
}
if (info->is_cube && info->tex_state_type != PVR_TEXTURE_STATE_SAMPLE)
iview_type = VK_IMAGE_VIEW_TYPE_2D;
else
iview_type = info->type;
pvr_csb_pack (&state[0], TEXSTATE_IMAGE_WORD0, word0) {
/* Determine texture type */
if (info->is_cube && info->tex_state_type == PVR_TEXTURE_STATE_SAMPLE) {
word0.textype = texture_type = PVRX(TEXSTATE_TEXTYPE_CUBE);
} else if (info->mem_layout == PVR_MEMLAYOUT_TWIDDLED ||
info->mem_layout == PVR_MEMLAYOUT_3DTWIDDLED) {
if (info->type == VK_IMAGE_VIEW_TYPE_3D) {
word0.textype = texture_type = PVRX(TEXSTATE_TEXTYPE_3D);
} else if (info->type == VK_IMAGE_VIEW_TYPE_1D ||
info->type == VK_IMAGE_VIEW_TYPE_1D_ARRAY) {
word0.textype = texture_type = PVRX(TEXSTATE_TEXTYPE_1D);
} else if (info->type == VK_IMAGE_VIEW_TYPE_2D ||
info->type == VK_IMAGE_VIEW_TYPE_2D_ARRAY) {
word0.textype = texture_type = PVRX(TEXSTATE_TEXTYPE_2D);
} else {
if (mem_layout == PVR_MEMLAYOUT_LINEAR) {
switch (iview_type) {
case VK_IMAGE_VIEW_TYPE_2D:
case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
word0.textype = PVRX(TEXSTATE_TEXTYPE_STRIDE);
break;
default:
return vk_error(device, VK_ERROR_FORMAT_NOT_SUPPORTED);
}
} else if (mem_layout == PVR_MEMLAYOUT_TWIDDLED) {
switch (iview_type) {
case VK_IMAGE_VIEW_TYPE_1D:
case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
word0.textype = PVRX(TEXSTATE_TEXTYPE_1D);
break;
case VK_IMAGE_VIEW_TYPE_2D:
case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
word0.textype = PVRX(TEXSTATE_TEXTYPE_2D);
break;
case VK_IMAGE_VIEW_TYPE_CUBE:
case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
word0.textype = PVRX(TEXSTATE_TEXTYPE_CUBE);
break;
default:
return vk_error(device, VK_ERROR_FORMAT_NOT_SUPPORTED);
}
} else if (mem_layout == PVR_MEMLAYOUT_3DTWIDDLED) {
switch (iview_type) {
case VK_IMAGE_VIEW_TYPE_3D:
word0.textype = PVRX(TEXSTATE_TEXTYPE_3D);
break;
default:
return vk_error(device, VK_ERROR_FORMAT_NOT_SUPPORTED);
}
} else if (info->mem_layout == PVR_MEMLAYOUT_LINEAR) {
word0.textype = texture_type = PVRX(TEXSTATE_TEXTYPE_STRIDE);
} else {
return vk_error(device, VK_ERROR_FORMAT_NOT_SUPPORTED);
unreachable("Unknown memory layout");
}
word0.texformat = pvr_get_tex_format(info->format);
@ -128,13 +165,12 @@ pvr_pack_tex_state(struct pvr_device *device,
}
word0.width = info->extent.width - 1;
if (info->type != VK_IMAGE_VIEW_TYPE_1D &&
info->type != VK_IMAGE_VIEW_TYPE_1D_ARRAY)
if (iview_type != VK_IMAGE_VIEW_TYPE_1D &&
iview_type != VK_IMAGE_VIEW_TYPE_1D_ARRAY)
word0.height = info->extent.height - 1;
}
/* Texture type specific stuff (word 1) */
if (texture_type == PVRX(TEXSTATE_TEXTYPE_STRIDE)) {
if (mem_layout == PVR_MEMLAYOUT_LINEAR) {
pvr_csb_pack (&state[1], TEXSTATE_STRIDE_IMAGE_WORD1, word1) {
assert(info->stride > 0U);
word1.stride = info->stride - 1U;
@ -167,13 +203,13 @@ pvr_pack_tex_state(struct pvr_device *device,
word1.mipmaps_present = info->mipmaps_present;
word1.baselevel = info->base_level;
if (info->extent.depth > 0) {
word1.depth = info->extent.depth - 1;
if (iview_type == VK_IMAGE_VIEW_TYPE_3D) {
if (info->extent.depth > 0)
word1.depth = info->extent.depth - 1;
} else if (PVR_HAS_FEATURE(dev_info, tpu_array_textures)) {
uint32_t array_layers = info->array_size;
if (info->type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY &&
info->tex_state_type == PVR_TEXTURE_STATE_SAMPLE)
if (iview_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
array_layers /= 6;
word1.depth = array_layers - 1;