mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-27 21:20:12 +01:00
pvr: Implement vkGetPhysicalDeviceImageFormatProperties2 API.
Signed-off-by: Rajnesh Kanwal <rajnesh.kanwal@imgtec.com> Reviewed-by: Frank Binns <frank.binns@imgtec.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18487>
This commit is contained in:
parent
1e7a930e10
commit
0265a23172
7 changed files with 227 additions and 22 deletions
|
|
@ -433,7 +433,7 @@ Vulkan 1.1 -- all DONE: anv, lvp, radv, tu, vn
|
|||
VK_KHR_external_semaphore DONE (anv, lvp, radv, tu, v3dv, vn)
|
||||
VK_KHR_external_semaphore_capabilities DONE (anv, lvp, radv, tu, v3dv, vn)
|
||||
VK_KHR_get_memory_requirements2 DONE (anv, lvp, radv, tu, v3dv, vn)
|
||||
VK_KHR_get_physical_device_properties2 DONE (anv, dzn, lvp, panvk, radv, tu, v3dv, vn)
|
||||
VK_KHR_get_physical_device_properties2 DONE (anv, dzn, lvp, panvk, pvr, radv, tu, v3dv, vn)
|
||||
VK_KHR_maintenance1 DONE (anv, lvp, radv, tu, v3dv, vn)
|
||||
VK_KHR_maintenance2 DONE (anv, lvp, radv, tu, v3dv, vn)
|
||||
VK_KHR_maintenance3 DONE (anv, lvp, radv, tu, v3dv, vn)
|
||||
|
|
|
|||
|
|
@ -264,7 +264,9 @@ SOFTWARE.
|
|||
<struct name="IMAGE_WORD0" length="2">
|
||||
<field name="smpcnt" start="62" end="63" type="uint"/>
|
||||
<field name="height" start="48" end="61" type="uint"/>
|
||||
<field name="width" start="34" end="47" type="uint"/>
|
||||
<field name="width" start="34" end="47" type="uint">
|
||||
<define name="MAX_SIZE" value="16383"/>
|
||||
</field>
|
||||
<field name="texformat" start="27" end="33" type="FORMAT"/>
|
||||
<field name="texformat_compressed" start="27" end="33" type="FORMAT_COMPRESSED"/>
|
||||
<field name="minlod" start="17" end="26" type="uint"/>
|
||||
|
|
@ -294,7 +296,9 @@ SOFTWARE.
|
|||
<condition type="endif" check="TPU_IMAGE_STATE_V2"/>
|
||||
<field name="texaddr" start="16" end="53" shift="2" type="address"/>
|
||||
<field name="mipmaps_present" start="15" end="15" type="bool"/>
|
||||
<field name="depth" start="4" end="14" type="uint"/>
|
||||
<field name="depth" start="4" end="14" type="uint">
|
||||
<define name="MAX_SIZE" value="2047"/>
|
||||
</field>
|
||||
<field name="num_mip_levels" start="0" end="3" type="uint"/>
|
||||
</struct>
|
||||
|
||||
|
|
|
|||
|
|
@ -93,8 +93,6 @@
|
|||
/* Number of TEXSTATE_SAMPLER state words that need setting up. */
|
||||
#define ROGUE_NUM_TEXSTATE_SAMPLER_WORDS 2U
|
||||
|
||||
#define ROGUE_MAX_RENDER_TARGETS 2048U
|
||||
|
||||
/* 12 dwords reserved for shared register management. The first dword is the
|
||||
* number of shared register blocks to reload. Should be a multiple of 4 dwords,
|
||||
* size in bytes.
|
||||
|
|
|
|||
|
|
@ -870,9 +870,9 @@ void pvr_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
|
|||
VkPhysicalDeviceLimits limits = {
|
||||
.maxImageDimension1D = max_render_size,
|
||||
.maxImageDimension2D = max_render_size,
|
||||
.maxImageDimension3D = 2U * 1024U,
|
||||
.maxImageDimension3D = PVR_MAX_TEXTURE_EXTENT_Z,
|
||||
.maxImageDimensionCube = max_render_size,
|
||||
.maxImageArrayLayers = 2U * 1024U,
|
||||
.maxImageArrayLayers = PVR_MAX_ARRAY_LAYERS,
|
||||
.maxTexelBufferElements = 64U * 1024U,
|
||||
.maxUniformBufferRange = 128U * 1024U * 1024U,
|
||||
.maxStorageBufferRange = 128U * 1024U * 1024U,
|
||||
|
|
|
|||
|
|
@ -21,44 +21,56 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#include "hwdef/rogue_hw_utils.h"
|
||||
#include "pvr_formats.h"
|
||||
#include "pvr_private.h"
|
||||
#include "util/log.h"
|
||||
#include "util/macros.h"
|
||||
#include "util/u_math.h"
|
||||
#include "vk_enum_to_str.h"
|
||||
#include "vk_format.h"
|
||||
#include "vk_log.h"
|
||||
#include "vk_util.h"
|
||||
|
||||
#define FORMAT(vk, tex_fmt, pack_mode) \
|
||||
[VK_FORMAT_##vk] = { \
|
||||
.vk_format = VK_FORMAT_##vk, \
|
||||
.tex_format = ROGUE_TEXSTATE_FORMAT_##tex_fmt, \
|
||||
.pbe_packmode = ROGUE_PBESTATE_PACKMODE_##pack_mode, \
|
||||
.supported = true, \
|
||||
#define FORMAT(vk, tex_fmt, pack_mode, accum_format) \
|
||||
[VK_FORMAT_##vk] = { \
|
||||
.vk_format = VK_FORMAT_##vk, \
|
||||
.tex_format = ROGUE_TEXSTATE_FORMAT_##tex_fmt, \
|
||||
.pbe_packmode = ROGUE_PBESTATE_PACKMODE_##pack_mode, \
|
||||
.pbe_accum_format = PVR_PBE_ACCUM_FORMAT_##accum_format, \
|
||||
.supported = true, \
|
||||
}
|
||||
|
||||
struct pvr_format {
|
||||
VkFormat vk_format;
|
||||
uint32_t tex_format;
|
||||
uint32_t pbe_packmode;
|
||||
enum pvr_pbe_accum_format pbe_accum_format;
|
||||
bool supported;
|
||||
};
|
||||
|
||||
/* TODO: add all supported core formats */
|
||||
/* TODO: Add all supported core formats. */
|
||||
static const struct pvr_format pvr_format_table[] = {
|
||||
/* VK_FORMAT_R8_UINT = 13. */
|
||||
FORMAT(R8_UINT, U8, U8),
|
||||
FORMAT(R8_UINT, U8, U8, UINT8),
|
||||
/* VK_FORMAT_R8G8B8A8_UNORM = 37. */
|
||||
FORMAT(R8G8B8A8_UNORM, U8U8U8U8, U8U8U8U8, U8),
|
||||
/* VK_FORMAT_B8G8R8A8_UNORM = 44. */
|
||||
FORMAT(B8G8R8A8_UNORM, U8U8U8U8, U8U8U8U8),
|
||||
FORMAT(B8G8R8A8_UNORM, U8U8U8U8, U8U8U8U8, U8),
|
||||
/* VK_FORMAT_R32_UINT = 98. */
|
||||
FORMAT(R32_UINT, U32, U32),
|
||||
FORMAT(R32_UINT, U32, U32, UINT32),
|
||||
/* VK_FORMAT_R32G32B32A32_UINT = 107. */
|
||||
FORMAT(R32G32B32A32_UINT, U32U32U32U32, U32U32U32U32),
|
||||
FORMAT(R32G32B32A32_UINT, U32U32U32U32, U32U32U32U32, UINT32),
|
||||
/* VK_FORMAT_R32G32B32A32_SFLOAT = 109. */
|
||||
FORMAT(R32G32B32A32_SFLOAT, F32F32F32F32, F32F32F32F32),
|
||||
FORMAT(R32G32B32A32_SFLOAT, F32F32F32F32, F32F32F32F32, F32),
|
||||
/* VK_FORMAT_D32_SFLOAT = 126. */
|
||||
FORMAT(D32_SFLOAT, F32, F32),
|
||||
FORMAT(D32_SFLOAT, F32, F32, F16),
|
||||
};
|
||||
|
||||
#undef FORMAT
|
||||
|
|
@ -96,6 +108,15 @@ uint32_t pvr_get_pbe_packmode(VkFormat vk_format)
|
|||
return ROGUE_PBESTATE_PACKMODE_INVALID;
|
||||
}
|
||||
|
||||
uint32_t pvr_get_pbe_accum_format(VkFormat vk_format)
|
||||
{
|
||||
const struct pvr_format *pvr_format = pvr_get_format(vk_format);
|
||||
if (pvr_format)
|
||||
return pvr_format->pbe_accum_format;
|
||||
|
||||
return PVR_PBE_ACCUM_FORMAT_INVALID;
|
||||
}
|
||||
|
||||
static VkFormatFeatureFlags
|
||||
pvr_get_image_format_features(const struct pvr_format *pvr_format,
|
||||
VkImageTiling vk_tiling)
|
||||
|
|
@ -159,8 +180,162 @@ pvr_get_image_format_properties(struct pvr_physical_device *pdevice,
|
|||
const VkPhysicalDeviceImageFormatInfo2 *info,
|
||||
VkImageFormatProperties *pImageFormatProperties)
|
||||
{
|
||||
assert(!"Unimplemented");
|
||||
/* Input attachments aren't rendered but they must have the same size
|
||||
* restrictions as any framebuffer attachment.
|
||||
*/
|
||||
const VkImageUsageFlags render_usage =
|
||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT |
|
||||
VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
|
||||
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
const struct pvr_format *pvr_format = pvr_get_format(info->format);
|
||||
VkFormatFeatureFlags tiling_features;
|
||||
VkResult result;
|
||||
|
||||
if (!pvr_format) {
|
||||
result = vk_error(pdevice, VK_ERROR_FORMAT_NOT_SUPPORTED);
|
||||
goto err_unsupported_format;
|
||||
}
|
||||
|
||||
tiling_features = pvr_get_image_format_features(pvr_format, info->tiling);
|
||||
if (tiling_features == 0) {
|
||||
result = vk_error(pdevice, VK_ERROR_FORMAT_NOT_SUPPORTED);
|
||||
goto err_unsupported_format;
|
||||
}
|
||||
|
||||
/* If VK_IMAGE_CREATE_EXTENDED_USAGE_BIT is set, the driver can't decide if a
|
||||
* specific format isn't supported based on the usage.
|
||||
*/
|
||||
if ((info->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT) == 0 &&
|
||||
info->usage & (VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) &&
|
||||
pvr_format->pbe_accum_format == PVR_PBE_ACCUM_FORMAT_INVALID) {
|
||||
result = vk_error(pdevice, VK_ERROR_FORMAT_NOT_SUPPORTED);
|
||||
goto err_unsupported_format;
|
||||
}
|
||||
|
||||
if (info->type == VK_IMAGE_TYPE_3D) {
|
||||
const VkImageUsageFlags transfer_usage =
|
||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
|
||||
VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
|
||||
|
||||
/* We don't support 3D depth/stencil images. */
|
||||
if (tiling_features & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) {
|
||||
result = vk_error(pdevice, VK_ERROR_FORMAT_NOT_SUPPORTED);
|
||||
goto err_unsupported_format;
|
||||
}
|
||||
|
||||
/* Linear tiled 3D images may only be used for transfer or blit
|
||||
* operations.
|
||||
*/
|
||||
if (info->tiling == VK_IMAGE_TILING_LINEAR &&
|
||||
info->usage & ~transfer_usage) {
|
||||
result = vk_error(pdevice, VK_ERROR_FORMAT_NOT_SUPPORTED);
|
||||
goto err_unsupported_format;
|
||||
}
|
||||
}
|
||||
|
||||
if (info->usage & render_usage) {
|
||||
const uint32_t max_render_size =
|
||||
rogue_get_render_size_max(&pdevice->dev_info);
|
||||
|
||||
pImageFormatProperties->maxExtent.width = max_render_size;
|
||||
pImageFormatProperties->maxExtent.height = max_render_size;
|
||||
pImageFormatProperties->maxExtent.depth = PVR_MAX_TEXTURE_EXTENT_Z;
|
||||
} else {
|
||||
const uint32_t max_texture_extent_xy =
|
||||
PVRX(TEXSTATE_IMAGE_WORD0_WIDTH_MAX_SIZE) + 1U;
|
||||
|
||||
pImageFormatProperties->maxExtent.width = max_texture_extent_xy;
|
||||
pImageFormatProperties->maxExtent.height = max_texture_extent_xy;
|
||||
pImageFormatProperties->maxExtent.depth = PVR_MAX_TEXTURE_EXTENT_Z;
|
||||
}
|
||||
|
||||
if (info->tiling == VK_IMAGE_TILING_LINEAR) {
|
||||
pImageFormatProperties->maxExtent.depth = 1;
|
||||
pImageFormatProperties->maxArrayLayers = 1;
|
||||
pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
|
||||
} else {
|
||||
/* Default value is the minimum value found in all existing cores. */
|
||||
const uint32_t max_multisample =
|
||||
PVR_GET_FEATURE_VALUE(&pdevice->dev_info, max_multisample, 4);
|
||||
|
||||
const uint32_t max_sample_bits = ((max_multisample << 1) - 1);
|
||||
|
||||
pImageFormatProperties->maxArrayLayers = PVR_MAX_ARRAY_LAYERS;
|
||||
pImageFormatProperties->sampleCounts = max_sample_bits;
|
||||
}
|
||||
|
||||
if (!(tiling_features & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT ||
|
||||
tiling_features & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
|
||||
pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
|
||||
}
|
||||
|
||||
switch (info->type) {
|
||||
case VK_IMAGE_TYPE_1D:
|
||||
pImageFormatProperties->maxExtent.height = 1;
|
||||
pImageFormatProperties->maxExtent.depth = 1;
|
||||
pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
|
||||
break;
|
||||
|
||||
case VK_IMAGE_TYPE_2D:
|
||||
pImageFormatProperties->maxExtent.depth = 1;
|
||||
|
||||
/* If a 2D image is created to be used in a cube map, then the sample
|
||||
* count must be restricted to 1 sample.
|
||||
*/
|
||||
if (info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
|
||||
pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
||||
break;
|
||||
|
||||
case VK_IMAGE_TYPE_3D:
|
||||
pImageFormatProperties->maxArrayLayers = 1;
|
||||
pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
|
||||
break;
|
||||
|
||||
default:
|
||||
unreachable("Invalid image type.");
|
||||
}
|
||||
|
||||
/* The spec says maxMipLevels may be 1 when tiling is VK_IMAGE_TILING_LINEAR
|
||||
* or VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, so for simplicity don't
|
||||
* support miplevels for these tilings.
|
||||
*/
|
||||
if (info->tiling == VK_IMAGE_TILING_LINEAR) {
|
||||
pImageFormatProperties->maxMipLevels = 1;
|
||||
} else {
|
||||
const uint32_t max_size = MAX3(pImageFormatProperties->maxExtent.width,
|
||||
pImageFormatProperties->maxExtent.height,
|
||||
pImageFormatProperties->maxExtent.depth);
|
||||
|
||||
pImageFormatProperties->maxMipLevels = util_logbase2(max_size) + 1U;
|
||||
}
|
||||
|
||||
/* Return 2GB (minimum required from spec).
|
||||
*
|
||||
* From the Vulkan spec:
|
||||
*
|
||||
* maxResourceSize is an upper bound on the total image size in bytes,
|
||||
* inclusive of all image subresources. Implementations may have an
|
||||
* address space limit on total size of a resource, which is advertised by
|
||||
* this property. maxResourceSize must be at least 2^31.
|
||||
*/
|
||||
pImageFormatProperties->maxResourceSize = 2ULL * 1024 * 1024 * 1024;
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
||||
err_unsupported_format:
|
||||
/* From the Vulkan 1.0.42 spec:
|
||||
*
|
||||
* If the combination of parameters to
|
||||
* vkGetPhysicalDeviceImageFormatProperties2 is not supported by the
|
||||
* implementation for use in vkCreateImage, then all members of
|
||||
* imageFormatProperties will be filled with zero.
|
||||
*/
|
||||
*pImageFormatProperties = (VkImageFormatProperties){ 0 };
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* FIXME: Should this be returning VK_ERROR_FORMAT_NOT_SUPPORTED when tiling is
|
||||
|
|
|
|||
|
|
@ -28,9 +28,31 @@
|
|||
#include <stdint.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
enum pvr_pbe_accum_format {
|
||||
PVR_PBE_ACCUM_FORMAT_INVALID = 0, /* Explicitly treat 0 as invalid. */
|
||||
PVR_PBE_ACCUM_FORMAT_U8,
|
||||
PVR_PBE_ACCUM_FORMAT_S8,
|
||||
PVR_PBE_ACCUM_FORMAT_U16,
|
||||
PVR_PBE_ACCUM_FORMAT_S16,
|
||||
PVR_PBE_ACCUM_FORMAT_F16,
|
||||
PVR_PBE_ACCUM_FORMAT_F32,
|
||||
PVR_PBE_ACCUM_FORMAT_UINT8,
|
||||
PVR_PBE_ACCUM_FORMAT_UINT16,
|
||||
PVR_PBE_ACCUM_FORMAT_UINT32,
|
||||
PVR_PBE_ACCUM_FORMAT_SINT8,
|
||||
PVR_PBE_ACCUM_FORMAT_SINT16,
|
||||
PVR_PBE_ACCUM_FORMAT_SINT32,
|
||||
/* Formats with medp shader output precision. */
|
||||
PVR_PBE_ACCUM_FORMAT_UINT32_MEDP,
|
||||
PVR_PBE_ACCUM_FORMAT_SINT32_MEDP,
|
||||
PVR_PBE_ACCUM_FORMAT_U1010102,
|
||||
PVR_PBE_ACCUM_FORMAT_U24,
|
||||
};
|
||||
|
||||
const uint8_t *pvr_get_format_swizzle(VkFormat vk_format);
|
||||
uint32_t pvr_get_tex_format(VkFormat vk_format);
|
||||
uint32_t pvr_get_pbe_packmode(VkFormat vk_format);
|
||||
uint32_t pvr_get_pbe_accum_format(VkFormat vk_format);
|
||||
bool pvr_format_is_pbe_downscalable(VkFormat vk_format);
|
||||
|
||||
#endif /* PVR_FORMATS_H */
|
||||
|
|
|
|||
|
|
@ -39,8 +39,14 @@
|
|||
|
||||
#define PVR_MAX_PUSH_CONSTANTS_SIZE 256U
|
||||
|
||||
#define PVR_MAX_TEXTURE_EXTENT_Z \
|
||||
(PVRX(TEXSTATE_IMAGE_WORD1_DEPTH_MAX_SIZE) + 1U)
|
||||
|
||||
#define PVR_MAX_ARRAY_LAYERS (PVRX(TEXSTATE_IMAGE_WORD1_DEPTH_MAX_SIZE) + 1U)
|
||||
|
||||
#define PVR_MAX_DESCRIPTOR_SETS 4U
|
||||
#define PVR_MAX_FRAMEBUFFER_LAYERS ROGUE_MAX_RENDER_TARGETS
|
||||
|
||||
#define PVR_MAX_FRAMEBUFFER_LAYERS PVR_MAX_ARRAY_LAYERS
|
||||
|
||||
/* The limit is somewhat arbitrary, it just translates into more pds code
|
||||
* and larger arrays, 32 appears to be the popular (and highest choice) across
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue