mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 13:10:10 +01:00
radv: Deal with Android external formats.
To abstract things a bit, this adds a helper function in radv_android.c. However, this means we have to link in radv_android.c on non-android as well, which means some scaffolding changes. Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
This commit is contained in:
parent
041fc7beb8
commit
adad61239c
5 changed files with 76 additions and 39 deletions
|
|
@ -67,6 +67,7 @@ libradv_files = files(
|
|||
'winsys/amdgpu/radv_amdgpu_winsys.c',
|
||||
'winsys/amdgpu/radv_amdgpu_winsys.h',
|
||||
'winsys/amdgpu/radv_amdgpu_winsys_public.h',
|
||||
'radv_android.c',
|
||||
'radv_cmd_buffer.c',
|
||||
'radv_cs.h',
|
||||
'radv_debug.c',
|
||||
|
|
@ -143,7 +144,6 @@ if with_platform_android
|
|||
radv_flags += [
|
||||
'-DVK_USE_PLATFORM_ANDROID_KHR'
|
||||
]
|
||||
libradv_files += files('radv_android.c')
|
||||
endif
|
||||
|
||||
libvulkan_radeon = shared_library(
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <hardware/gralloc.h>
|
||||
#include <hardware/hardware.h>
|
||||
#include <hardware/hwvulkan.h>
|
||||
|
|
@ -28,10 +29,13 @@
|
|||
#include <vulkan/vk_android_native_buffer.h>
|
||||
#include <vulkan/vk_icd.h>
|
||||
#include <libsync.h>
|
||||
#endif
|
||||
|
||||
#include "radv_private.h"
|
||||
#include "vk_util.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
|
||||
static int radv_hal_open(const struct hw_module_t* mod, const char* id, struct hw_device_t** dev);
|
||||
static int radv_hal_close(struct hw_device_t *dev);
|
||||
|
||||
|
|
@ -374,6 +378,7 @@ radv_QueueSignalReleaseImageANDROID(
|
|||
}
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
|
||||
|
||||
|
|
@ -579,3 +584,18 @@ radv_GetMemoryAndroidHardwareBufferANDROID(
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
VkFormat
|
||||
radv_select_android_external_format(const void *next, VkFormat default_format)
|
||||
{
|
||||
#if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
|
||||
const VkExternalFormatANDROID *android_format =
|
||||
vk_find_struct_const(next, EXTERNAL_FORMAT_ANDROID);
|
||||
|
||||
if (android_format && android_format->externalFormat) {
|
||||
return (VkFormat)android_format->externalFormat;
|
||||
}
|
||||
#endif
|
||||
|
||||
return default_format;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1104,6 +1104,7 @@ void radv_GetPhysicalDeviceFormatProperties2(
|
|||
|
||||
static VkResult radv_get_image_format_properties(struct radv_physical_device *physical_device,
|
||||
const VkPhysicalDeviceImageFormatInfo2 *info,
|
||||
VkFormat format,
|
||||
VkImageFormatProperties *pImageFormatProperties)
|
||||
|
||||
{
|
||||
|
|
@ -1113,10 +1114,10 @@ static VkResult radv_get_image_format_properties(struct radv_physical_device *ph
|
|||
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;
|
||||
|
|
@ -1129,7 +1130,7 @@ static VkResult radv_get_image_format_properties(struct radv_physical_device *ph
|
|||
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) {
|
||||
|
|
@ -1179,9 +1180,9 @@ static VkResult radv_get_image_format_properties(struct radv_physical_device *ph
|
|||
}
|
||||
|
||||
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.
|
||||
|
|
@ -1196,8 +1197,8 @@ static VkResult radv_get_image_format_properties(struct radv_physical_device *ph
|
|||
/* 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))) {
|
||||
|
|
@ -1293,7 +1294,7 @@ VkResult radv_GetPhysicalDeviceImageFormatProperties(
|
|||
.flags = createFlags,
|
||||
};
|
||||
|
||||
return radv_get_image_format_properties(physical_device, &info,
|
||||
return radv_get_image_format_properties(physical_device, &info, format,
|
||||
pImageFormatProperties);
|
||||
}
|
||||
|
||||
|
|
@ -1348,8 +1349,9 @@ VkResult radv_GetPhysicalDeviceImageFormatProperties2(
|
|||
struct VkAndroidHardwareBufferUsageANDROID *android_usage = NULL;
|
||||
VkSamplerYcbcrConversionImageFormatProperties *ycbcr_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;
|
||||
|
|
@ -1416,7 +1418,7 @@ VkResult radv_GetPhysicalDeviceImageFormatProperties2(
|
|||
}
|
||||
|
||||
if (ycbcr_props) {
|
||||
ycbcr_props->combinedImageSamplerDescriptorCount = vk_format_get_plane_count(base_info->format);
|
||||
ycbcr_props->combinedImageSamplerDescriptorCount = vk_format_get_plane_count(format);
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
|
|
|||
|
|
@ -36,15 +36,16 @@
|
|||
|
||||
static unsigned
|
||||
radv_choose_tiling(struct radv_device *device,
|
||||
const VkImageCreateInfo *pCreateInfo)
|
||||
const VkImageCreateInfo *pCreateInfo,
|
||||
VkFormat format)
|
||||
{
|
||||
if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) {
|
||||
assert(pCreateInfo->samples <= 1);
|
||||
return RADEON_SURF_MODE_LINEAR_ALIGNED;
|
||||
}
|
||||
|
||||
if (!vk_format_is_compressed(pCreateInfo->format) &&
|
||||
!vk_format_is_depth_or_stencil(pCreateInfo->format)
|
||||
if (!vk_format_is_compressed(format) &&
|
||||
!vk_format_is_depth_or_stencil(format)
|
||||
&& device->physical_device->rad_info.chip_class <= GFX8) {
|
||||
/* this causes hangs in some VK CTS tests on GFX9. */
|
||||
/* Textures with a very small height are recommended to be linear. */
|
||||
|
|
@ -64,7 +65,8 @@ radv_choose_tiling(struct radv_device *device,
|
|||
|
||||
static bool
|
||||
radv_use_tc_compat_htile_for_image(struct radv_device *device,
|
||||
const VkImageCreateInfo *pCreateInfo)
|
||||
const VkImageCreateInfo *pCreateInfo,
|
||||
VkFormat format)
|
||||
{
|
||||
/* TC-compat HTILE is only available for GFX8+. */
|
||||
if (device->physical_device->rad_info.chip_class < GFX8)
|
||||
|
|
@ -84,8 +86,8 @@ radv_use_tc_compat_htile_for_image(struct radv_device *device,
|
|||
* tests - disable for now. On GFX10 D32_SFLOAT is affected as well.
|
||||
*/
|
||||
if (pCreateInfo->samples >= 2 &&
|
||||
(pCreateInfo->format == VK_FORMAT_D32_SFLOAT_S8_UINT ||
|
||||
(pCreateInfo->format == VK_FORMAT_D32_SFLOAT &&
|
||||
(format == VK_FORMAT_D32_SFLOAT_S8_UINT ||
|
||||
(format == VK_FORMAT_D32_SFLOAT &&
|
||||
device->physical_device->rad_info.chip_class == GFX10)))
|
||||
return false;
|
||||
|
||||
|
|
@ -93,9 +95,9 @@ radv_use_tc_compat_htile_for_image(struct radv_device *device,
|
|||
* supports 32-bit. Though, it's possible to enable TC-compat for
|
||||
* 16-bit depth surfaces if no Z planes are compressed.
|
||||
*/
|
||||
if (pCreateInfo->format != VK_FORMAT_D32_SFLOAT_S8_UINT &&
|
||||
pCreateInfo->format != VK_FORMAT_D32_SFLOAT &&
|
||||
pCreateInfo->format != VK_FORMAT_D16_UNORM)
|
||||
if (format != VK_FORMAT_D32_SFLOAT_S8_UINT &&
|
||||
format != VK_FORMAT_D32_SFLOAT &&
|
||||
format != VK_FORMAT_D16_UNORM)
|
||||
return false;
|
||||
|
||||
if (pCreateInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) {
|
||||
|
|
@ -113,7 +115,7 @@ radv_use_tc_compat_htile_for_image(struct radv_device *device,
|
|||
if (format_list->pViewFormats[i] == VK_FORMAT_UNDEFINED)
|
||||
continue;
|
||||
|
||||
if (pCreateInfo->format != format_list->pViewFormats[i])
|
||||
if (format != format_list->pViewFormats[i])
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -143,7 +145,8 @@ radv_surface_has_scanout(struct radv_device *device, const struct radv_image_cre
|
|||
static bool
|
||||
radv_use_dcc_for_image(struct radv_device *device,
|
||||
const struct radv_image *image,
|
||||
const VkImageCreateInfo *pCreateInfo)
|
||||
const VkImageCreateInfo *pCreateInfo,
|
||||
VkFormat format)
|
||||
{
|
||||
bool dcc_compatible_formats;
|
||||
bool blendable;
|
||||
|
|
@ -166,8 +169,8 @@ radv_use_dcc_for_image(struct radv_device *device,
|
|||
if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR)
|
||||
return false;
|
||||
|
||||
if (vk_format_is_subsampled(pCreateInfo->format) ||
|
||||
vk_format_get_plane_count(pCreateInfo->format) > 1)
|
||||
if (vk_format_is_subsampled(format) ||
|
||||
vk_format_get_plane_count(format) > 1)
|
||||
return false;
|
||||
|
||||
/* TODO: Enable DCC for mipmaps on GFX9+. */
|
||||
|
|
@ -189,7 +192,7 @@ radv_use_dcc_for_image(struct radv_device *device,
|
|||
|
||||
/* Determine if the formats are DCC compatible. */
|
||||
dcc_compatible_formats =
|
||||
radv_is_colorbuffer_format_supported(pCreateInfo->format,
|
||||
radv_is_colorbuffer_format_supported(format,
|
||||
&blendable);
|
||||
|
||||
if (pCreateInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) {
|
||||
|
|
@ -206,7 +209,7 @@ radv_use_dcc_for_image(struct radv_device *device,
|
|||
if (format_list->pViewFormats[i] == VK_FORMAT_UNDEFINED)
|
||||
continue;
|
||||
|
||||
if (!radv_dcc_formats_compatible(pCreateInfo->format,
|
||||
if (!radv_dcc_formats_compatible(format,
|
||||
format_list->pViewFormats[i]))
|
||||
dcc_compatible_formats = false;
|
||||
}
|
||||
|
|
@ -389,10 +392,11 @@ radv_init_surface(struct radv_device *device,
|
|||
const struct radv_image *image,
|
||||
struct radeon_surf *surface,
|
||||
unsigned plane_id,
|
||||
const VkImageCreateInfo *pCreateInfo)
|
||||
const VkImageCreateInfo *pCreateInfo,
|
||||
VkFormat image_format)
|
||||
{
|
||||
unsigned array_mode = radv_choose_tiling(device, pCreateInfo);
|
||||
VkFormat format = vk_format_get_plane_format(pCreateInfo->format, plane_id);
|
||||
unsigned array_mode = radv_choose_tiling(device, pCreateInfo, image_format);
|
||||
VkFormat format = vk_format_get_plane_format(image_format, plane_id);
|
||||
const struct vk_format_description *desc = vk_format_description(format);
|
||||
bool is_depth, is_stencil;
|
||||
|
||||
|
|
@ -432,7 +436,7 @@ radv_init_surface(struct radv_device *device,
|
|||
|
||||
if (is_depth) {
|
||||
surface->flags |= RADEON_SURF_ZBUFFER;
|
||||
if (radv_use_tc_compat_htile_for_image(device, pCreateInfo))
|
||||
if (radv_use_tc_compat_htile_for_image(device, pCreateInfo, image_format))
|
||||
surface->flags |= RADEON_SURF_TC_COMPATIBLE_HTILE;
|
||||
}
|
||||
|
||||
|
|
@ -441,13 +445,13 @@ radv_init_surface(struct radv_device *device,
|
|||
|
||||
if (device->physical_device->rad_info.chip_class >= GFX9 &&
|
||||
pCreateInfo->imageType == VK_IMAGE_TYPE_3D &&
|
||||
vk_format_get_blocksizebits(pCreateInfo->format) == 128 &&
|
||||
vk_format_is_compressed(pCreateInfo->format))
|
||||
vk_format_get_blocksizebits(image_format) == 128 &&
|
||||
vk_format_is_compressed(image_format))
|
||||
surface->flags |= RADEON_SURF_NO_RENDER_TARGET;
|
||||
|
||||
surface->flags |= RADEON_SURF_OPTIMIZE_FOR_SPACE;
|
||||
|
||||
if (!radv_use_dcc_for_image(device, image, pCreateInfo))
|
||||
if (!radv_use_dcc_for_image(device, image, pCreateInfo, image_format))
|
||||
surface->flags |= RADEON_SURF_DISABLE_DCC;
|
||||
|
||||
return 0;
|
||||
|
|
@ -1439,9 +1443,11 @@ radv_image_create(VkDevice _device,
|
|||
RADV_FROM_HANDLE(radv_device, device, _device);
|
||||
const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
|
||||
struct radv_image *image = NULL;
|
||||
VkFormat format = radv_select_android_external_format(pCreateInfo->pNext,
|
||||
pCreateInfo->format);
|
||||
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
|
||||
|
||||
const unsigned plane_count = vk_format_get_plane_count(pCreateInfo->format);
|
||||
const unsigned plane_count = vk_format_get_plane_count(format);
|
||||
const size_t image_struct_size = sizeof(*image) + sizeof(struct radv_image_plane) * plane_count;
|
||||
|
||||
radv_assert(pCreateInfo->mipLevels > 0);
|
||||
|
|
@ -1464,9 +1470,9 @@ radv_image_create(VkDevice _device,
|
|||
image->info.storage_samples = pCreateInfo->samples;
|
||||
image->info.array_size = pCreateInfo->arrayLayers;
|
||||
image->info.levels = pCreateInfo->mipLevels;
|
||||
image->info.num_channels = vk_format_get_nr_components(pCreateInfo->format);
|
||||
image->info.num_channels = vk_format_get_nr_components(format);
|
||||
|
||||
image->vk_format = pCreateInfo->format;
|
||||
image->vk_format = format;
|
||||
image->tiling = pCreateInfo->tiling;
|
||||
image->usage = pCreateInfo->usage;
|
||||
image->flags = pCreateInfo->flags;
|
||||
|
|
@ -1484,12 +1490,12 @@ radv_image_create(VkDevice _device,
|
|||
|
||||
image->shareable = vk_find_struct_const(pCreateInfo->pNext,
|
||||
EXTERNAL_MEMORY_IMAGE_CREATE_INFO) != NULL;
|
||||
if (!vk_format_is_depth_or_stencil(pCreateInfo->format) && !image->shareable) {
|
||||
if (!vk_format_is_depth_or_stencil(format) && !image->shareable) {
|
||||
image->info.surf_index = &device->image_mrt_offset_counter;
|
||||
}
|
||||
|
||||
for (unsigned plane = 0; plane < image->plane_count; ++plane) {
|
||||
radv_init_surface(device, image, &image->planes[plane].surface, plane, pCreateInfo);
|
||||
radv_init_surface(device, image, &image->planes[plane].surface, plane, pCreateInfo, format);
|
||||
}
|
||||
|
||||
ASSERTED VkResult result = radv_image_create_layout(device, *create_info, image);
|
||||
|
|
@ -1632,8 +1638,14 @@ radv_image_view_init(struct radv_image_view *iview,
|
|||
iview->plane_id = radv_plane_from_aspect(pCreateInfo->subresourceRange.aspectMask);
|
||||
iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask;
|
||||
iview->multiple_planes = vk_format_get_plane_count(image->vk_format) > 1 && iview->aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
|
||||
iview->vk_format = pCreateInfo->format;
|
||||
|
||||
/* If the image has an Android external format, pCreateInfo->format will be
|
||||
* VK_FORMAT_UNDEFINED. */
|
||||
if (iview->vk_format == VK_FORMAT_UNDEFINED)
|
||||
iview->vk_format = image->vk_format;
|
||||
|
||||
if (iview->aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) {
|
||||
iview->vk_format = vk_format_stencil_only(iview->vk_format);
|
||||
} else if (iview->aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT) {
|
||||
|
|
|
|||
|
|
@ -1928,6 +1928,9 @@ uint64_t
|
|||
radv_ahb_usage_from_vk_usage(const VkImageCreateFlags vk_create,
|
||||
const VkImageUsageFlags vk_usage);
|
||||
|
||||
VkFormat
|
||||
radv_select_android_external_format(const void *next, VkFormat default_format);
|
||||
|
||||
|
||||
struct radv_image_view_extra_create_info {
|
||||
bool disable_compression;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue