}
}
-static bool radv_is_buffer_format_supported(VkFormat format, bool *scaled)
+bool radv_is_buffer_format_supported(VkFormat format, bool *scaled)
{
const struct vk_format_description *desc = vk_format_description(format);
unsigned data_format, num_format;
num_format = radv_translate_buffer_numformat(desc,
vk_format_get_first_non_void_channel(format));
- *scaled = (num_format == V_008F0C_BUF_NUM_FORMAT_SSCALED) || (num_format == V_008F0C_BUF_NUM_FORMAT_USCALED);
+ if (scaled)
+ *scaled = (num_format == V_008F0C_BUF_NUM_FORMAT_SSCALED) || (num_format == V_008F0C_BUF_NUM_FORMAT_USCALED);
return data_format != V_008F0C_BUF_DATA_FORMAT_INVALID &&
num_format != ~0;
}
/* From the Vulkan spec 1.1.71:
*
* "The following formats must support the
- * VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT feature with
+ * VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT feature with
* VK_IMAGE_TILING_OPTIMAL, if they support
* VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT."
*/
{
return physical_device->rad_info.family == CHIP_VEGA10 ||
physical_device->rad_info.family == CHIP_RAVEN ||
+ physical_device->rad_info.family == CHIP_RAVEN2 ||
physical_device->rad_info.family == CHIP_STONEY;
}
const struct vk_format_description *desc = vk_format_description(format);
bool blendable;
bool scaled = false;
- if (!desc) {
+ /* TODO: implement some software emulation of SUBSAMPLED formats. */
+ if (!desc || desc->layout == VK_FORMAT_LAYOUT_SUBSAMPLED) {
out_properties->linearTilingFeatures = linear;
out_properties->optimalTilingFeatures = tiled;
out_properties->bufferFeatures = buffer;
uint32_t tiling = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
VK_FORMAT_FEATURE_TRANSFER_DST_BIT |
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
+ VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT |
VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT;
/* The subsampled formats have no support for linear filters. */
VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
if (radv_is_filter_minmax_format_supported(format))
- tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT;
+ tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT;
/* Don't support blitting surfaces with depth/stencil. */
if (vk_format_is_depth(format) && vk_format_is_stencil(format))
VK_FORMAT_FEATURE_BLIT_SRC_BIT;
if (radv_is_filter_minmax_format_supported(format))
- tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT;
+ tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT;
if (linear_sampling) {
linear |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
}
- if (format == VK_FORMAT_R32_UINT || format == VK_FORMAT_R32_SINT) {
+ if (format == VK_FORMAT_R32_UINT ||
+ format == VK_FORMAT_R32_SINT ||
+ format == VK_FORMAT_R32_SFLOAT) {
buffer |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
linear |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT;
tiled |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT;
case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
case VK_FORMAT_A2R10G10B10_SINT_PACK32:
case VK_FORMAT_A2B10G10R10_SINT_PACK32:
- if (physical_device->rad_info.chip_class <= VI &&
+ if (physical_device->rad_info.chip_class <= GFX8 &&
physical_device->rad_info.family != CHIP_STONEY) {
buffer &= ~(VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT |
VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT);
break;
}
+ /* addrlib does not support linear compressed textures. */
+ if (vk_format_is_compressed(format))
+ linear = 0;
+
out_properties->linearTilingFeatures = linear;
out_properties->optimalTilingFeatures = tiled;
out_properties->bufferFeatures = buffer;
if (channel->size == 32) {
memcpy(&v, &value->float32[c], 4);
} else if(channel->size == 16) {
- v = util_float_to_half(value->float32[c]);
+ v = util_float_to_half_rtz(value->float32[c]);
} else {
fprintf(stderr, "failed to fast clear for unhandled float size in format %d\n", format);
return false;
static VkResult radv_get_image_format_properties(struct radv_physical_device *physical_device,
const VkPhysicalDeviceImageFormatInfo2 *info,
+ VkFormat format,
VkImageFormatProperties *pImageFormatProperties)
{
uint32_t maxMipLevels;
uint32_t maxArraySize;
VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT;
- const struct vk_format_description *desc = vk_format_description(info->format);
+ const struct vk_format_description *desc = vk_format_description(format);
+ enum chip_class chip_class = physical_device->rad_info.chip_class;
- radv_physical_device_get_format_properties(physical_device, info->format,
+ radv_physical_device_get_format_properties(physical_device, format,
&format_props);
if (info->tiling == VK_IMAGE_TILING_LINEAR) {
format_feature_flags = format_props.linearTilingFeatures;
if (format_feature_flags == 0)
goto unsupported;
- if (info->type != VK_IMAGE_TYPE_2D && vk_format_is_depth_or_stencil(info->format))
+ if (info->type != VK_IMAGE_TYPE_2D && vk_format_is_depth_or_stencil(format))
goto unsupported;
switch (info->type) {
maxExtent.height = 1;
maxExtent.depth = 1;
maxMipLevels = 15; /* log2(maxWidth) + 1 */
- maxArraySize = 2048;
+ maxArraySize = chip_class >= GFX10 ? 8192 : 2048;
break;
case VK_IMAGE_TYPE_2D:
maxExtent.width = 16384;
maxExtent.height = 16384;
maxExtent.depth = 1;
maxMipLevels = 15; /* log2(maxWidth) + 1 */
- maxArraySize = 2048;
+ maxArraySize = chip_class >= GFX10 ? 8192 : 2048;
break;
case VK_IMAGE_TYPE_3D:
- maxExtent.width = 2048;
- maxExtent.height = 2048;
- maxExtent.depth = 2048;
- maxMipLevels = 12; /* log2(maxWidth) + 1 */
+ if (chip_class >= GFX10) {
+ maxExtent.width = 8192;
+ maxExtent.height = 8192;
+ maxExtent.depth = 8192;
+ } else {
+ maxExtent.width = 2048;
+ maxExtent.height = 2048;
+ maxExtent.depth = 2048;
+ }
+ maxMipLevels = util_logbase2(maxExtent.width) + 1;
maxArraySize = 1;
break;
}
}
if (info->tiling == VK_IMAGE_TILING_LINEAR &&
- (info->format == VK_FORMAT_R32G32B32_SFLOAT ||
- info->format == VK_FORMAT_R32G32B32_SINT ||
- info->format == VK_FORMAT_R32G32B32_UINT)) {
+ (format == VK_FORMAT_R32G32B32_SFLOAT ||
+ format == VK_FORMAT_R32G32B32_SINT ||
+ format == VK_FORMAT_R32G32B32_UINT)) {
/* R32G32B32 is a weird format and the driver currently only
* supports the barely minimum.
* TODO: Implement more if we really need to.
/* We can't create 3d compressed 128bpp images that can be rendered to on GFX9 */
if (physical_device->rad_info.chip_class >= GFX9 &&
info->type == VK_IMAGE_TYPE_3D &&
- vk_format_get_blocksizebits(info->format) == 128 &&
- vk_format_is_compressed(info->format) &&
+ vk_format_get_blocksizebits(format) == 128 &&
+ vk_format_is_compressed(format) &&
(info->flags & VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT) &&
((info->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT) ||
(info->usage & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))) {
}
}
+ /* Sparse resources with multi-planar formats are unsupported. */
+ if (info->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) {
+ if (desc->plane_count > 1)
+ goto unsupported;
+ }
+
*pImageFormatProperties = (VkImageFormatProperties) {
.maxExtent = maxExtent,
.maxMipLevels = maxMipLevels,
.flags = createFlags,
};
- return radv_get_image_format_properties(physical_device, &info,
+ return radv_get_image_format_properties(physical_device, &info, format,
pImageFormatProperties);
}
static void
-get_external_image_format_properties(const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo,
+get_external_image_format_properties(struct radv_physical_device *physical_device,
+ const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo,
VkExternalMemoryHandleTypeFlagBits handleType,
- VkExternalMemoryProperties *external_properties)
+ VkExternalMemoryProperties *external_properties,
+ VkImageFormatProperties *format_properties)
{
VkExternalMemoryFeatureFlagBits flags = 0;
VkExternalMemoryHandleTypeFlags export_flags = 0;
VkExternalMemoryHandleTypeFlags compat_flags = 0;
+
+ if (pImageFormatInfo->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)
+ return;
+
switch (handleType) {
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
switch (pImageFormatInfo->type) {
case VK_IMAGE_TYPE_2D:
- flags = VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT|VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT|VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
+ flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT|VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
+ if (pImageFormatInfo->tiling != VK_IMAGE_TILING_LINEAR)
+ flags |= VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT;
+
compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
break;
break;
}
break;
+ case VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID:
+ if (!physical_device->supported_extensions.ANDROID_external_memory_android_hardware_buffer)
+ break;
+
+ if (!radv_android_gralloc_supports_format(pImageFormatInfo->format,
+ pImageFormatInfo->usage))
+ break;
+
+ if (pImageFormatInfo->type != VK_IMAGE_TYPE_2D)
+ break;
+
+ format_properties->maxMipLevels = MIN2(1, format_properties->maxMipLevels);
+ format_properties->maxArrayLayers = MIN2(1, format_properties->maxArrayLayers);
+ format_properties->sampleCounts &= VK_SAMPLE_COUNT_1_BIT;
+
+ flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT|VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
+ if (pImageFormatInfo->tiling != VK_IMAGE_TILING_LINEAR)
+ flags |= VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT;
+
+ compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
+ break;
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice);
const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL;
VkExternalImageFormatProperties *external_props = NULL;
+ struct VkAndroidHardwareBufferUsageANDROID *android_usage = NULL;
VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL;
+ VkTextureLODGatherFormatPropertiesAMD *texture_lod_props = NULL;
VkResult result;
+ VkFormat format = radv_select_android_external_format(base_info->pNext, base_info->format);
- result = radv_get_image_format_properties(physical_device, base_info,
+ result = radv_get_image_format_properties(physical_device, base_info, format,
&base_props->imageFormatProperties);
if (result != VK_SUCCESS)
return result;
case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES:
ycbcr_props = (void *) s;
break;
+ case VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID:
+ android_usage = (void *) s;
+ break;
+ case VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD:
+ texture_lod_props = (void *) s;
+ break;
default:
break;
}
}
+ bool ahb_supported = physical_device->supported_extensions.ANDROID_external_memory_android_hardware_buffer;
+ if (android_usage && ahb_supported) {
+#if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
+ android_usage->androidHardwareBufferUsage =
+ radv_ahb_usage_from_vk_usage(base_info->flags,
+ base_info->usage);
+#endif
+ }
+
/* From the Vulkan 1.0.97 spec:
*
* If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2 will
* present and VkExternalImageFormatProperties will be ignored.
*/
if (external_info && external_info->handleType != 0) {
- switch (external_info->handleType) {
- case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
- case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
- case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
- get_external_image_format_properties(base_info, external_info->handleType,
- &external_props->externalMemoryProperties);
- break;
- default:
+ get_external_image_format_properties(physical_device, base_info, external_info->handleType,
+ &external_props->externalMemoryProperties,
+ &base_props->imageFormatProperties);
+ if (!external_props->externalMemoryProperties.externalMemoryFeatures) {
/* From the Vulkan 1.0.97 spec:
*
* If handleType is not compatible with the [parameters] specified
}
if (ycbcr_props) {
- ycbcr_props->combinedImageSamplerDescriptorCount = vk_format_get_plane_count(base_info->format);
+ ycbcr_props->combinedImageSamplerDescriptorCount = vk_format_get_plane_count(format);
+ }
+
+ if (texture_lod_props) {
+ if (physical_device->rad_info.chip_class >= GFX9) {
+ texture_lod_props->supportsTextureGatherLODBiasAMD = true;
+ } else {
+ texture_lod_props->supportsTextureGatherLODBiasAMD = !vk_format_is_int(format);
+ }
}
return VK_SUCCESS;