mirror of
https://github.com/stenzek/duckstation.git
synced 2025-07-19 00:20:12 +00:00
GPUDevice: Use driver type fields
This commit is contained in:
parent
ef26d5cb74
commit
e4e57c674d
@ -347,53 +347,16 @@ bool OpenGLDevice::CheckFeatures(FeatureMask disabled_features)
|
|||||||
glGetIntegerv(GL_MINOR_VERSION, &minor_version);
|
glGetIntegerv(GL_MINOR_VERSION, &minor_version);
|
||||||
m_render_api_version = (static_cast<u32>(major_version) * 100u) + (static_cast<u32>(minor_version) * 10u);
|
m_render_api_version = (static_cast<u32>(major_version) * 100u) + (static_cast<u32>(minor_version) * 10u);
|
||||||
|
|
||||||
bool vendor_id_amd = false;
|
|
||||||
// bool vendor_id_nvidia = false;
|
|
||||||
bool vendor_id_intel = false;
|
|
||||||
bool vendor_id_arm = false;
|
|
||||||
bool vendor_id_qualcomm = false;
|
|
||||||
bool vendor_id_powervr = false;
|
|
||||||
|
|
||||||
const char* vendor = (const char*)glGetString(GL_VENDOR);
|
const char* vendor = (const char*)glGetString(GL_VENDOR);
|
||||||
const char* renderer = (const char*)glGetString(GL_RENDERER);
|
const char* renderer = (const char*)glGetString(GL_RENDERER);
|
||||||
SetDriverType(GuessDriverType(0, vendor, renderer));
|
SetDriverType(GuessDriverType(0, vendor, renderer));
|
||||||
|
|
||||||
if (std::strstr(vendor, "Advanced Micro Devices") || std::strstr(vendor, "ATI Technologies Inc.") ||
|
|
||||||
std::strstr(vendor, "ATI"))
|
|
||||||
{
|
|
||||||
INFO_LOG("AMD GPU detected.");
|
|
||||||
vendor_id_amd = true;
|
|
||||||
}
|
|
||||||
else if (std::strstr(vendor, "NVIDIA Corporation"))
|
|
||||||
{
|
|
||||||
INFO_LOG("NVIDIA GPU detected.");
|
|
||||||
// vendor_id_nvidia = true;
|
|
||||||
}
|
|
||||||
else if (std::strstr(vendor, "Intel"))
|
|
||||||
{
|
|
||||||
INFO_LOG("Intel GPU detected.");
|
|
||||||
vendor_id_intel = true;
|
|
||||||
}
|
|
||||||
else if (std::strstr(vendor, "ARM"))
|
|
||||||
{
|
|
||||||
INFO_LOG("ARM GPU detected.");
|
|
||||||
vendor_id_arm = true;
|
|
||||||
}
|
|
||||||
else if (std::strstr(vendor, "Qualcomm"))
|
|
||||||
{
|
|
||||||
INFO_LOG("Qualcomm GPU detected.");
|
|
||||||
vendor_id_qualcomm = true;
|
|
||||||
}
|
|
||||||
else if (std::strstr(vendor, "Imagination Technologies") || std::strstr(renderer, "PowerVR"))
|
|
||||||
{
|
|
||||||
INFO_LOG("PowerVR GPU detected.");
|
|
||||||
vendor_id_powervr = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't use PBOs when we don't have ARB_buffer_storage, orphaning buffers probably ends up worse than just
|
// Don't use PBOs when we don't have ARB_buffer_storage, orphaning buffers probably ends up worse than just
|
||||||
// using the normal texture update routines and letting the driver take care of it. PBOs are also completely
|
// using the normal texture update routines and letting the driver take care of it. PBOs are also completely
|
||||||
// broken on mobile drivers.
|
// broken on mobile drivers.
|
||||||
const bool is_shitty_mobile_driver = (vendor_id_powervr || vendor_id_qualcomm || vendor_id_arm);
|
const bool is_shitty_mobile_driver =
|
||||||
|
(m_driver_type == GPUDriverType::ARMProprietary || m_driver_type == GPUDriverType::QualcommProprietary ||
|
||||||
|
m_driver_type == GPUDriverType::ImaginationProprietary);
|
||||||
m_disable_pbo =
|
m_disable_pbo =
|
||||||
(!GLAD_GL_VERSION_4_4 && !GLAD_GL_ARB_buffer_storage && !GLAD_GL_EXT_buffer_storage) || is_shitty_mobile_driver;
|
(!GLAD_GL_VERSION_4_4 && !GLAD_GL_ARB_buffer_storage && !GLAD_GL_EXT_buffer_storage) || is_shitty_mobile_driver;
|
||||||
if (m_disable_pbo && !is_shitty_mobile_driver)
|
if (m_disable_pbo && !is_shitty_mobile_driver)
|
||||||
@ -472,14 +435,16 @@ bool OpenGLDevice::CheckFeatures(FeatureMask disabled_features)
|
|||||||
// Sample rate shading is broken on AMD and Intel.
|
// Sample rate shading is broken on AMD and Intel.
|
||||||
// If AMD and Intel can't get it right, I very much doubt broken mobile drivers can.
|
// If AMD and Intel can't get it right, I very much doubt broken mobile drivers can.
|
||||||
m_features.per_sample_shading = (GLAD_GL_VERSION_4_0 || GLAD_GL_ES_VERSION_3_2 || GLAD_GL_ARB_sample_shading) &&
|
m_features.per_sample_shading = (GLAD_GL_VERSION_4_0 || GLAD_GL_ES_VERSION_3_2 || GLAD_GL_ARB_sample_shading) &&
|
||||||
(!vendor_id_amd && !vendor_id_intel && !is_shitty_mobile_driver);
|
(m_driver_type != GPUDriverType::AMDProprietary &&
|
||||||
|
m_driver_type != GPUDriverType::IntelProprietary && !is_shitty_mobile_driver);
|
||||||
|
|
||||||
// noperspective is not supported in GLSL ES.
|
// noperspective is not supported in GLSL ES.
|
||||||
m_features.noperspective_interpolation = !is_gles;
|
m_features.noperspective_interpolation = !is_gles;
|
||||||
|
|
||||||
// glBlitFramebufer with same source/destination should be legal, but on Mali (at least Bifrost) it breaks.
|
// glBlitFramebufer with same source/destination should be legal, but on Mali (at least Bifrost) it breaks.
|
||||||
// So, blit from the shadow texture, like in the other renderers.
|
// So, blit from the shadow texture, like in the other renderers.
|
||||||
m_features.texture_copy_to_self = !vendor_id_arm && !(disabled_features & FEATURE_MASK_TEXTURE_COPY_TO_SELF);
|
m_features.texture_copy_to_self =
|
||||||
|
(m_driver_type != GPUDriverType::ARMProprietary) && !(disabled_features & FEATURE_MASK_TEXTURE_COPY_TO_SELF);
|
||||||
|
|
||||||
m_features.feedback_loops = false;
|
m_features.feedback_loops = false;
|
||||||
|
|
||||||
@ -520,9 +485,10 @@ bool OpenGLDevice::CheckFeatures(FeatureMask disabled_features)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mobile drivers prefer textures to not be updated mid-frame.
|
// Mobile drivers prefer textures to not be updated mid-frame.
|
||||||
m_features.prefer_unused_textures = is_gles || vendor_id_arm || vendor_id_powervr || vendor_id_qualcomm;
|
m_features.prefer_unused_textures =
|
||||||
|
is_gles || ((m_driver_type & GPUDriverType::MobileFlag) == GPUDriverType::MobileFlag);
|
||||||
|
|
||||||
if (vendor_id_intel)
|
if (m_driver_type == GPUDriverType::IntelProprietary)
|
||||||
{
|
{
|
||||||
// Intel drivers corrupt image on readback when syncs are used for downloads.
|
// Intel drivers corrupt image on readback when syncs are used for downloads.
|
||||||
WARNING_LOG("Disabling async downloads with PBOs due to it being broken on Intel drivers.");
|
WARNING_LOG("Disabling async downloads with PBOs due to it being broken on Intel drivers.");
|
||||||
|
@ -623,7 +623,8 @@ bool VulkanDevice::EnableOptionalDeviceExtensions(VkPhysicalDevice physical_devi
|
|||||||
m_optional_extensions.vk_ext_external_memory_host &=
|
m_optional_extensions.vk_ext_external_memory_host &=
|
||||||
(external_memory_host_properties.minImportedHostPointerAlignment <= HOST_PAGE_SIZE);
|
(external_memory_host_properties.minImportedHostPointerAlignment <= HOST_PAGE_SIZE);
|
||||||
|
|
||||||
if (IsBrokenMobileDriver())
|
if (m_driver_type == GPUDriverType::QualcommProprietary || m_driver_type == GPUDriverType::ARMProprietary ||
|
||||||
|
m_driver_type == GPUDriverType::ImaginationProprietary)
|
||||||
{
|
{
|
||||||
// Push descriptor is broken on Adreno v502.. don't want to think about dynamic rendending.
|
// Push descriptor is broken on Adreno v502.. don't want to think about dynamic rendending.
|
||||||
if (m_optional_extensions.vk_khr_dynamic_rendering)
|
if (m_optional_extensions.vk_khr_dynamic_rendering)
|
||||||
@ -639,7 +640,7 @@ bool VulkanDevice::EnableOptionalDeviceExtensions(VkPhysicalDevice physical_devi
|
|||||||
WARNING_LOG("Disabling VK_KHR_push_descriptor on broken mobile driver.");
|
WARNING_LOG("Disabling VK_KHR_push_descriptor on broken mobile driver.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (IsDeviceAMD())
|
else if (m_driver_type == GPUDriverType::AMDProprietary)
|
||||||
{
|
{
|
||||||
// VK_KHR_dynamic_rendering_local_read appears to be broken on RDNA3, like everything else...
|
// VK_KHR_dynamic_rendering_local_read appears to be broken on RDNA3, like everything else...
|
||||||
// Just causes GPU resets when you actually use a feedback loop. Assume Mesa is fine.
|
// Just causes GPU resets when you actually use a feedback loop. Assume Mesa is fine.
|
||||||
@ -1772,41 +1773,6 @@ void VulkanDevice::DisableDebugUtils()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VulkanDevice::IsDeviceNVIDIA() const
|
|
||||||
{
|
|
||||||
return (m_device_properties.vendorID == 0x10DE);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VulkanDevice::IsDeviceAMD() const
|
|
||||||
{
|
|
||||||
return (m_device_properties.vendorID == 0x1002);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VulkanDevice::IsDeviceAdreno() const
|
|
||||||
{
|
|
||||||
// Assume turnip is fine...
|
|
||||||
return ((m_device_properties.vendorID == 0x5143 ||
|
|
||||||
m_device_driver_properties.driverID == VK_DRIVER_ID_QUALCOMM_PROPRIETARY) &&
|
|
||||||
m_device_driver_properties.driverID != VK_DRIVER_ID_MESA_TURNIP);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VulkanDevice::IsDeviceMali() const
|
|
||||||
{
|
|
||||||
return (m_device_properties.vendorID == 0x13B5 ||
|
|
||||||
m_device_driver_properties.driverID == VK_DRIVER_ID_ARM_PROPRIETARY);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VulkanDevice::IsDeviceImgTec() const
|
|
||||||
{
|
|
||||||
return (m_device_properties.vendorID == 0x1010 ||
|
|
||||||
m_device_driver_properties.driverID == VK_DRIVER_ID_IMAGINATION_PROPRIETARY);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VulkanDevice::IsBrokenMobileDriver() const
|
|
||||||
{
|
|
||||||
return (IsDeviceAdreno() || IsDeviceMali() || IsDeviceImgTec());
|
|
||||||
}
|
|
||||||
|
|
||||||
VkRenderPass VulkanDevice::CreateCachedRenderPass(RenderPassCacheKey key)
|
VkRenderPass VulkanDevice::CreateCachedRenderPass(RenderPassCacheKey key)
|
||||||
{
|
{
|
||||||
std::array<VkAttachmentReference, MAX_RENDER_TARGETS> color_references;
|
std::array<VkAttachmentReference, MAX_RENDER_TARGETS> color_references;
|
||||||
@ -2747,7 +2713,7 @@ void VulkanDevice::ClearRenderTarget(GPUTexture* t, u32 c)
|
|||||||
{
|
{
|
||||||
VulkanTexture* T = static_cast<VulkanTexture*>(t);
|
VulkanTexture* T = static_cast<VulkanTexture*>(t);
|
||||||
|
|
||||||
if (IsDeviceNVIDIA())
|
if (m_driver_type == GPUDriverType::NVIDIAProprietary)
|
||||||
{
|
{
|
||||||
EndRenderPass();
|
EndRenderPass();
|
||||||
}
|
}
|
||||||
@ -2775,7 +2741,7 @@ void VulkanDevice::ClearDepth(GPUTexture* t, float d)
|
|||||||
// should be failing. Breaking/restarting the render pass isn't enough to work around the bug,
|
// should be failing. Breaking/restarting the render pass isn't enough to work around the bug,
|
||||||
// it needs an explicit pipeline barrier.
|
// it needs an explicit pipeline barrier.
|
||||||
VulkanTexture* T = static_cast<VulkanTexture*>(t);
|
VulkanTexture* T = static_cast<VulkanTexture*>(t);
|
||||||
if (IsDeviceNVIDIA())
|
if (m_driver_type == GPUDriverType::NVIDIAProprietary)
|
||||||
{
|
{
|
||||||
EndRenderPass();
|
EndRenderPass();
|
||||||
T->TransitionSubresourcesToLayout(GetCurrentCommandBuffer(), 0, 1, 0, 1, T->GetLayout(), T->GetLayout());
|
T->TransitionSubresourcesToLayout(GetCurrentCommandBuffer(), 0, 1, 0, 1, T->GetLayout(), T->GetLayout());
|
||||||
@ -3344,7 +3310,7 @@ void VulkanDevice::BeginRenderPass()
|
|||||||
|
|
||||||
// NVIDIA drivers appear to return random garbage when sampling the RT via a feedback loop, if the load op for
|
// NVIDIA drivers appear to return random garbage when sampling the RT via a feedback loop, if the load op for
|
||||||
// the render pass is CLEAR. Using vkCmdClearAttachments() doesn't work, so we have to clear the image instead.
|
// the render pass is CLEAR. Using vkCmdClearAttachments() doesn't work, so we have to clear the image instead.
|
||||||
if (m_current_render_pass_flags & GPUPipeline::ColorFeedbackLoop && IsDeviceNVIDIA())
|
if (m_current_render_pass_flags & GPUPipeline::ColorFeedbackLoop && m_driver_type == GPUDriverType::NVIDIAProprietary)
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < m_num_current_render_targets; i++)
|
for (u32 i = 0; i < m_num_current_render_targets; i++)
|
||||||
{
|
{
|
||||||
|
@ -325,18 +325,6 @@ private:
|
|||||||
bool EnableDebugUtils();
|
bool EnableDebugUtils();
|
||||||
void DisableDebugUtils();
|
void DisableDebugUtils();
|
||||||
|
|
||||||
/// Returns true if running on an NVIDIA GPU.
|
|
||||||
bool IsDeviceNVIDIA() const;
|
|
||||||
|
|
||||||
/// Returns true if running on an AMD GPU.
|
|
||||||
bool IsDeviceAMD() const;
|
|
||||||
|
|
||||||
// Vendor queries.
|
|
||||||
bool IsDeviceAdreno() const;
|
|
||||||
bool IsDeviceMali() const;
|
|
||||||
bool IsDeviceImgTec() const;
|
|
||||||
bool IsBrokenMobileDriver() const;
|
|
||||||
|
|
||||||
using ExtensionList = std::vector<const char*>;
|
using ExtensionList = std::vector<const char*>;
|
||||||
static bool SelectInstanceExtensions(ExtensionList* extension_list, const WindowInfo& wi, OptionalExtensions* oe,
|
static bool SelectInstanceExtensions(ExtensionList* extension_list, const WindowInfo& wi, OptionalExtensions* oe,
|
||||||
bool enable_debug_utils);
|
bool enable_debug_utils);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user