libretro: disable layered rendering where not supported

I suspect this causes some pretty weird rendering issues on older
hardware but it's better than outright crashing. Need to look into how
to do this better.
This commit is contained in:
Eric Warmenhoven 2025-08-03 11:57:28 -04:00
parent bcd1522c5a
commit 3a0a25e474
No known key found for this signature in database
3 changed files with 35 additions and 5 deletions

View file

@ -217,17 +217,39 @@ void LibRetroVKInstance::DetectDeviceCapabilities() {
// Query extended features if available
vk::PhysicalDeviceFeatures2 features2;
vk::PhysicalDeviceTimelineSemaphoreFeatures timeline_features;
vk::PhysicalDeviceVulkan12Features vulkan12_features;
// Chain the feature structures
void* pNext = nullptr;
// Check for layered rendering support on MoltenVK (maps to shaderOutputLayer)
if (driver_id == vk::DriverIdKHR::eMoltenvk) {
vulkan12_features.pNext = pNext;
pNext = &vulkan12_features;
}
if (timeline_semaphores) {
features2.pNext = &timeline_features;
timeline_features.pNext = nullptr;
timeline_features.pNext = pNext;
pNext = &timeline_features;
}
features2.pNext = pNext;
try {
physical_device.getFeatures2(&features2);
if (timeline_semaphores) {
timeline_semaphores = timeline_features.timelineSemaphore;
}
// Check layered rendering support on MoltenVK
// MoltenVK maps _metalFeatures.layeredRendering to _vulkan12FeaturesNoExt.shaderOutputLayer
if (driver_id == vk::DriverIdKHR::eMoltenvk) {
if (!vulkan12_features.shaderOutputLayer) {
LOG_INFO(Render_Vulkan,
"Disabling layered rendering (shaderOutputLayer not supported by device)");
layered_rendering_supported = false;
}
}
} catch (const vk::SystemError& e) {
LOG_WARNING(Render_Vulkan, "Failed to query extended features: {}", e.what());
}

View file

@ -250,6 +250,11 @@ public:
return features.shaderSampledImageArrayDynamicIndexing;
}
/// Returns true if layered rendering (array attachments) is supported
bool IsLayeredRenderingSupported() const {
return layered_rendering_supported;
}
/// Returns the minimum vertex stride alignment
u32 GetMinVertexStrideAlignment() const {
return min_vertex_stride_alignment;
@ -324,6 +329,7 @@ protected:
bool shader_stencil_export{};
bool external_memory_host{};
u64 min_imported_host_pointer_alignment{};
bool layered_rendering_supported{true};
bool tooling_info{};
bool debug_utils_supported{};
bool has_nsight_graphics{};

View file

@ -146,7 +146,10 @@ Handle MakeHandle(const Instance* instance, u32 width, u32 height, u32 levels, T
vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags flags,
vk::ImageAspectFlags aspect, bool need_format_list,
std::string_view debug_name = {}) {
const u32 layers = type == TextureType::CubeMap ? 6 : 1;
// On tvOS/iOS, fall back to 2D textures when layered rendering isn't supported
const bool is_cube_map =
type == TextureType::CubeMap && instance->IsLayeredRenderingSupported();
const u32 layers = is_cube_map ? 6 : 1;
const std::array format_list = {
vk::Format::eR8G8B8A8Unorm,
@ -192,8 +195,7 @@ Handle MakeHandle(const Instance* instance, u32 width, u32 height, u32 levels, T
const vk::Image image{unsafe_image};
const vk::ImageViewCreateInfo view_info = {
.image = image,
.viewType =
type == TextureType::CubeMap ? vk::ImageViewType::eCube : vk::ImageViewType::e2D,
.viewType = is_cube_map ? vk::ImageViewType::eCube : vk::ImageViewType::e2D,
.format = format,
.subresourceRange{
.aspectMask = aspect,