mirror of
https://github.com/stenzek/duckstation.git
synced 2025-07-14 06:00:09 +00:00
GPUDevice: Backport driver type detection
This commit is contained in:
parent
1e930c4063
commit
ef26d5cb74
@ -122,14 +122,16 @@ bool D3D11Device::CreateDeviceAndMainSwapChain(std::string_view adapter, Feature
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
ComPtr<IDXGIDevice> dxgi_device;
|
ComPtr<IDXGIDevice> dxgi_device;
|
||||||
|
GPUDriverType driver_type = GPUDriverType::Unknown;
|
||||||
if (SUCCEEDED(m_device.As(&dxgi_device)) &&
|
if (SUCCEEDED(m_device.As(&dxgi_device)) &&
|
||||||
SUCCEEDED(dxgi_device->GetParent(IID_PPV_ARGS(dxgi_adapter.GetAddressOf()))))
|
SUCCEEDED(dxgi_device->GetParent(IID_PPV_ARGS(dxgi_adapter.GetAddressOf()))))
|
||||||
INFO_LOG("D3D Adapter: {}", D3DCommon::GetAdapterName(dxgi_adapter.Get()));
|
INFO_LOG("D3D Adapter: {}", D3DCommon::GetAdapterName(dxgi_adapter.Get(), &driver_type));
|
||||||
else
|
else
|
||||||
ERROR_LOG("Failed to obtain D3D adapter name.");
|
ERROR_LOG("Failed to obtain D3D adapter name.");
|
||||||
INFO_LOG("Max device feature level: {}",
|
INFO_LOG("Max device feature level: {}",
|
||||||
D3DCommon::GetFeatureLevelString(D3DCommon::GetRenderAPIVersionForFeatureLevel(m_max_feature_level)));
|
D3DCommon::GetFeatureLevelString(D3DCommon::GetRenderAPIVersionForFeatureLevel(m_max_feature_level)));
|
||||||
|
|
||||||
|
SetDriverType(driver_type);
|
||||||
SetFeatures(disabled_features);
|
SetFeatures(disabled_features);
|
||||||
|
|
||||||
if (!wi.IsSurfaceless())
|
if (!wi.IsSurfaceless())
|
||||||
@ -170,7 +172,7 @@ void D3D11Device::SetFeatures(FeatureMask disabled_features)
|
|||||||
m_device->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, multisamples, &num_quality_levels)) &&
|
m_device->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, multisamples, &num_quality_levels)) &&
|
||||||
num_quality_levels > 0)
|
num_quality_levels > 0)
|
||||||
{
|
{
|
||||||
m_max_multisamples = multisamples;
|
m_max_multisamples = static_cast<u16>(multisamples);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,6 +263,11 @@ bool D3D12Device::CreateDeviceAndMainSwapChain(std::string_view adapter, Feature
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GPUDriverType driver_type = GPUDriverType::Unknown;
|
||||||
|
if (std::string adapter_name = D3DCommon::GetAdapterName(m_adapter.Get(), &driver_type); adapter_name.empty())
|
||||||
|
INFO_LOG("D3D Adapter: {}", adapter_name);
|
||||||
|
SetDriverType(driver_type);
|
||||||
|
|
||||||
const D3D12_COMMAND_QUEUE_DESC queue_desc = {D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL,
|
const D3D12_COMMAND_QUEUE_DESC queue_desc = {D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL,
|
||||||
D3D12_COMMAND_QUEUE_FLAG_NONE, 0u};
|
D3D12_COMMAND_QUEUE_FLAG_NONE, 0u};
|
||||||
hr = m_device->CreateCommandQueue(&queue_desc, IID_PPV_ARGS(&m_command_queue));
|
hr = m_device->CreateCommandQueue(&queue_desc, IID_PPV_ARGS(&m_command_queue));
|
||||||
@ -1349,7 +1354,7 @@ void D3D12Device::SetFeatures(D3D_FEATURE_LEVEL feature_level, FeatureMask disab
|
|||||||
if (SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &fd, sizeof(fd))) &&
|
if (SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &fd, sizeof(fd))) &&
|
||||||
fd.NumQualityLevels > 0)
|
fd.NumQualityLevels > 0)
|
||||||
{
|
{
|
||||||
m_max_multisamples = multisamples;
|
m_max_multisamples = static_cast<u16>(multisamples);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ GPUDevice::AdapterInfoList D3DCommon::GetAdapterInfoList()
|
|||||||
// Unfortunately we can't get any properties such as feature level without creating the device.
|
// Unfortunately we can't get any properties such as feature level without creating the device.
|
||||||
// So just assume a max of the D3D11 max across the board.
|
// So just assume a max of the D3D11 max across the board.
|
||||||
GPUDevice::AdapterInfo ai;
|
GPUDevice::AdapterInfo ai;
|
||||||
ai.name = FixupDuplicateAdapterNames(adapters, GetAdapterName(adapter.Get()));
|
ai.name = FixupDuplicateAdapterNames(adapters, GetAdapterName(adapter.Get(), &ai.driver_type));
|
||||||
ai.max_texture_size = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
ai.max_texture_size = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
||||||
ai.max_multisamples = 8;
|
ai.max_multisamples = 8;
|
||||||
ai.supports_sample_shading = true;
|
ai.supports_sample_shading = true;
|
||||||
@ -352,7 +352,7 @@ Microsoft::WRL::ComPtr<IDXGIAdapter1> D3DCommon::GetChosenOrFirstAdapter(IDXGIFa
|
|||||||
return adapter;
|
return adapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string D3DCommon::GetAdapterName(IDXGIAdapter1* adapter)
|
std::string D3DCommon::GetAdapterName(IDXGIAdapter1* adapter, GPUDriverType* out_driver_type)
|
||||||
{
|
{
|
||||||
std::string ret;
|
std::string ret;
|
||||||
|
|
||||||
@ -361,10 +361,14 @@ std::string D3DCommon::GetAdapterName(IDXGIAdapter1* adapter)
|
|||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
ret = StringUtil::WideStringToUTF8String(desc.Description);
|
ret = StringUtil::WideStringToUTF8String(desc.Description);
|
||||||
|
if (out_driver_type)
|
||||||
|
*out_driver_type = GPUDevice::GuessDriverType(desc.VendorId, {}, ret);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ERROR_LOG("IDXGIAdapter1::GetDesc() returned {:08X}", static_cast<unsigned>(hr));
|
ERROR_LOG("IDXGIAdapter1::GetDesc() returned {:08X}", static_cast<unsigned>(hr));
|
||||||
|
if (out_driver_type)
|
||||||
|
*out_driver_type = GPUDriverType::Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret.empty())
|
if (ret.empty())
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
class Error;
|
class Error;
|
||||||
|
|
||||||
|
enum class GPUDriverType : u16;
|
||||||
|
|
||||||
struct IDXGIFactory5;
|
struct IDXGIFactory5;
|
||||||
struct IDXGIAdapter;
|
struct IDXGIAdapter;
|
||||||
struct IDXGIAdapter1;
|
struct IDXGIAdapter1;
|
||||||
@ -57,7 +59,7 @@ Microsoft::WRL::ComPtr<IDXGIAdapter1> GetFirstAdapter(IDXGIFactory5* factory);
|
|||||||
Microsoft::WRL::ComPtr<IDXGIAdapter1> GetChosenOrFirstAdapter(IDXGIFactory5* factory, std::string_view name);
|
Microsoft::WRL::ComPtr<IDXGIAdapter1> GetChosenOrFirstAdapter(IDXGIFactory5* factory, std::string_view name);
|
||||||
|
|
||||||
// returns a utf-8 string of the specified adapter's name
|
// returns a utf-8 string of the specified adapter's name
|
||||||
std::string GetAdapterName(IDXGIAdapter1* adapter);
|
std::string GetAdapterName(IDXGIAdapter1* adapter, GPUDriverType* out_driver_type = nullptr);
|
||||||
|
|
||||||
// returns the driver version from the registry as a string
|
// returns the driver version from the registry as a string
|
||||||
std::string GetDriverVersionFromLUID(const LUID& luid);
|
std::string GetDriverVersionFromLUID(const LUID& luid);
|
||||||
|
@ -1203,6 +1203,97 @@ void GPUDevice::ResetStatistics()
|
|||||||
s_stats = {};
|
s_stats = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GPUDriverType GPUDevice::GuessDriverType(u32 pci_vendor_id, std::string_view vendor_name, std::string_view adapter_name)
|
||||||
|
{
|
||||||
|
#define ACHECK(name) (adapter_name.find(name) != std::string_view::npos)
|
||||||
|
#define VCHECK(name) (vendor_name.find(name) != std::string_view::npos)
|
||||||
|
#define MESA_CHECK (ACHECK("Mesa") || VCHECK("Mesa"))
|
||||||
|
|
||||||
|
if (pci_vendor_id == 0x1002 || pci_vendor_id == 0x1022 || VCHECK("Advanced Micro Devices") ||
|
||||||
|
VCHECK("ATI Technologies Inc.") || VCHECK("ATI"))
|
||||||
|
{
|
||||||
|
INFO_LOG("AMD GPU detected.");
|
||||||
|
return MESA_CHECK ? GPUDriverType::AMDMesa : GPUDriverType::AMDProprietary;
|
||||||
|
}
|
||||||
|
else if (pci_vendor_id == 0x10DE || VCHECK("NVIDIA Corporation"))
|
||||||
|
{
|
||||||
|
INFO_LOG("NVIDIA GPU detected.");
|
||||||
|
return MESA_CHECK ? GPUDriverType::NVIDIAMesa : GPUDriverType::NVIDIAProprietary;
|
||||||
|
}
|
||||||
|
else if (pci_vendor_id == 0x8086 || VCHECK("Intel"))
|
||||||
|
{
|
||||||
|
INFO_LOG("Intel GPU detected.");
|
||||||
|
return MESA_CHECK ? GPUDriverType::IntelMesa : GPUDriverType::IntelProprietary;
|
||||||
|
}
|
||||||
|
else if (pci_vendor_id == 0x5143 || VCHECK("ARM") || ACHECK("Adreno"))
|
||||||
|
{
|
||||||
|
INFO_LOG("Qualcomm GPU detected.");
|
||||||
|
return MESA_CHECK ? GPUDriverType::QualcommMesa : GPUDriverType::QualcommProprietary;
|
||||||
|
}
|
||||||
|
else if (pci_vendor_id == 0x13B5 || VCHECK("ARM") || ACHECK("Mali"))
|
||||||
|
{
|
||||||
|
INFO_LOG("ARM GPU detected.");
|
||||||
|
return MESA_CHECK ? GPUDriverType::ARMMesa : GPUDriverType::ARMProprietary;
|
||||||
|
}
|
||||||
|
else if (pci_vendor_id == 0x1010 || VCHECK("Imagination Technologies") || ACHECK("PowerVR"))
|
||||||
|
{
|
||||||
|
INFO_LOG("Imagination GPU detected.");
|
||||||
|
return MESA_CHECK ? GPUDriverType::ImaginationMesa : GPUDriverType::ImaginationProprietary;
|
||||||
|
}
|
||||||
|
else if (pci_vendor_id == 0x14E4 || VCHECK("Broadcom") || ACHECK("VideoCore"))
|
||||||
|
{
|
||||||
|
INFO_LOG("Broadcom GPU detected.");
|
||||||
|
return MESA_CHECK ? GPUDriverType::BroadcomMesa : GPUDriverType::BroadcomProprietary;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WARNING_LOG("Unknown GPU vendor with PCI ID 0x{:04X}, adapter='{}', vendor='{}'", pci_vendor_id, adapter_name,
|
||||||
|
vendor_name);
|
||||||
|
return GPUDriverType::Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef MESA_CHECK
|
||||||
|
#undef VCHECK
|
||||||
|
#undef ACHECK
|
||||||
|
}
|
||||||
|
|
||||||
|
void GPUDevice::SetDriverType(GPUDriverType type)
|
||||||
|
{
|
||||||
|
m_driver_type = type;
|
||||||
|
|
||||||
|
#define NTENTRY(n) {GPUDriverType::n, #n}
|
||||||
|
static constexpr const std::pair<GPUDriverType, const char*> name_table[] = {
|
||||||
|
NTENTRY(Unknown),
|
||||||
|
NTENTRY(AMDProprietary),
|
||||||
|
NTENTRY(AMDMesa),
|
||||||
|
NTENTRY(IntelProprietary),
|
||||||
|
NTENTRY(IntelMesa),
|
||||||
|
NTENTRY(NVIDIAProprietary),
|
||||||
|
NTENTRY(NVIDIAMesa),
|
||||||
|
NTENTRY(AppleProprietary),
|
||||||
|
NTENTRY(AppleMesa),
|
||||||
|
NTENTRY(DozenMesa),
|
||||||
|
|
||||||
|
NTENTRY(ImaginationProprietary),
|
||||||
|
NTENTRY(ImaginationMesa),
|
||||||
|
NTENTRY(ARMProprietary),
|
||||||
|
NTENTRY(ARMMesa),
|
||||||
|
NTENTRY(QualcommProprietary),
|
||||||
|
NTENTRY(QualcommMesa),
|
||||||
|
NTENTRY(BroadcomProprietary),
|
||||||
|
NTENTRY(BroadcomMesa),
|
||||||
|
|
||||||
|
NTENTRY(LLVMPipe),
|
||||||
|
NTENTRY(SwiftShader),
|
||||||
|
};
|
||||||
|
#undef NTENTRY
|
||||||
|
|
||||||
|
const auto iter =
|
||||||
|
std::find_if(std::begin(name_table), std::end(name_table), [&type](const auto& it) { return it.first == type; });
|
||||||
|
INFO_LOG("Driver type set to {}.", (iter == std::end(name_table)) ? name_table[0].second : iter->second);
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<GPUDevice> GPUDevice::CreateDeviceForAPI(RenderAPI api)
|
std::unique_ptr<GPUDevice> GPUDevice::CreateDeviceForAPI(RenderAPI api)
|
||||||
{
|
{
|
||||||
switch (api)
|
switch (api)
|
||||||
|
@ -139,6 +139,36 @@ enum class GPUShaderLanguage : u8
|
|||||||
Count
|
Count
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class GPUDriverType : u16
|
||||||
|
{
|
||||||
|
MobileFlag = 0x100,
|
||||||
|
SoftwareFlag = 0x200,
|
||||||
|
|
||||||
|
Unknown = 0,
|
||||||
|
AMDProprietary = 1,
|
||||||
|
AMDMesa = 2,
|
||||||
|
IntelProprietary = 3,
|
||||||
|
IntelMesa = 4,
|
||||||
|
NVIDIAProprietary = 5,
|
||||||
|
NVIDIAMesa = 6,
|
||||||
|
AppleProprietary = 7,
|
||||||
|
AppleMesa = 8,
|
||||||
|
DozenMesa = 9,
|
||||||
|
|
||||||
|
ImaginationProprietary = MobileFlag | 1,
|
||||||
|
ImaginationMesa = MobileFlag | 2,
|
||||||
|
ARMProprietary = MobileFlag | 3,
|
||||||
|
ARMMesa = MobileFlag | 4,
|
||||||
|
QualcommProprietary = MobileFlag | 5,
|
||||||
|
QualcommMesa = MobileFlag | 6,
|
||||||
|
BroadcomProprietary = MobileFlag | 7,
|
||||||
|
BroadcomMesa = MobileFlag | 8,
|
||||||
|
|
||||||
|
LLVMPipe = SoftwareFlag | 1,
|
||||||
|
SwiftShader = SoftwareFlag | 2,
|
||||||
|
};
|
||||||
|
IMPLEMENT_ENUM_CLASS_BITWISE_OPERATORS(GPUDriverType);
|
||||||
|
|
||||||
class GPUShader
|
class GPUShader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -643,6 +673,7 @@ public:
|
|||||||
std::vector<ExclusiveFullscreenMode> fullscreen_modes;
|
std::vector<ExclusiveFullscreenMode> fullscreen_modes;
|
||||||
u32 max_texture_size;
|
u32 max_texture_size;
|
||||||
u32 max_multisamples;
|
u32 max_multisamples;
|
||||||
|
GPUDriverType driver_type;
|
||||||
bool supports_sample_shading;
|
bool supports_sample_shading;
|
||||||
};
|
};
|
||||||
using AdapterInfoList = std::vector<AdapterInfo>;
|
using AdapterInfoList = std::vector<AdapterInfo>;
|
||||||
@ -721,6 +752,9 @@ public:
|
|||||||
(count_z + (local_size_z - 1)) / local_size_z);
|
(count_z + (local_size_z - 1)) / local_size_z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Determines the driver type for a given adapter.
|
||||||
|
static GPUDriverType GuessDriverType(u32 pci_vendor_id, std::string_view vendor_name, std::string_view adapter_name);
|
||||||
|
|
||||||
ALWAYS_INLINE const Features& GetFeatures() const { return m_features; }
|
ALWAYS_INLINE const Features& GetFeatures() const { return m_features; }
|
||||||
ALWAYS_INLINE RenderAPI GetRenderAPI() const { return m_render_api; }
|
ALWAYS_INLINE RenderAPI GetRenderAPI() const { return m_render_api; }
|
||||||
ALWAYS_INLINE u32 GetRenderAPIVersion() const { return m_render_api_version; }
|
ALWAYS_INLINE u32 GetRenderAPIVersion() const { return m_render_api_version; }
|
||||||
@ -926,11 +960,14 @@ protected:
|
|||||||
DynamicHeapArray<u8>* out_binary, Error* error);
|
DynamicHeapArray<u8>* out_binary, Error* error);
|
||||||
static std::optional<DynamicHeapArray<u8>> OptimizeVulkanSpv(const std::span<const u8> spirv, Error* error);
|
static std::optional<DynamicHeapArray<u8>> OptimizeVulkanSpv(const std::span<const u8> spirv, Error* error);
|
||||||
|
|
||||||
|
void SetDriverType(GPUDriverType type);
|
||||||
|
|
||||||
Features m_features = {};
|
Features m_features = {};
|
||||||
RenderAPI m_render_api = RenderAPI::None;
|
RenderAPI m_render_api = RenderAPI::None;
|
||||||
u32 m_render_api_version = 0;
|
u32 m_render_api_version = 0;
|
||||||
u32 m_max_texture_size = 0;
|
u32 m_max_texture_size = 0;
|
||||||
u32 m_max_multisamples = 0;
|
GPUDriverType m_driver_type = GPUDriverType::Unknown;
|
||||||
|
u16 m_max_multisamples = 0;
|
||||||
|
|
||||||
std::unique_ptr<GPUSwapChain> m_main_swap_chain;
|
std::unique_ptr<GPUSwapChain> m_main_swap_chain;
|
||||||
std::unique_ptr<GPUTexture> m_empty_texture;
|
std::unique_ptr<GPUTexture> m_empty_texture;
|
||||||
|
@ -329,8 +329,11 @@ bool MetalDevice::CreateDeviceAndMainSwapChain(std::string_view adapter, Feature
|
|||||||
|
|
||||||
m_device = [device retain];
|
m_device = [device retain];
|
||||||
m_queue = [queue retain];
|
m_queue = [queue retain];
|
||||||
INFO_LOG("Metal Device: {}", [[m_device name] UTF8String]);
|
|
||||||
|
|
||||||
|
const char* device_name = [[m_device name] UTF8String];
|
||||||
|
INFO_LOG("Metal Device: {}", device_name);
|
||||||
|
|
||||||
|
SetDriverType(GuessDriverType(0, {}, device_name));
|
||||||
SetFeatures(disabled_features);
|
SetFeatures(disabled_features);
|
||||||
CreateCommandBuffer();
|
CreateCommandBuffer();
|
||||||
|
|
||||||
@ -2797,11 +2800,13 @@ GPUDevice::AdapterInfoList GPUDevice::WrapGetMetalAdapterList()
|
|||||||
ret.reserve(count);
|
ret.reserve(count);
|
||||||
for (u32 i = 0; i < count; i++)
|
for (u32 i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
|
const char* device_name = [devices[i].name UTF8String];
|
||||||
AdapterInfo ai;
|
AdapterInfo ai;
|
||||||
ai.name = [devices[i].name UTF8String];
|
ai.name = device_name;
|
||||||
ai.max_texture_size = GetMetalMaxTextureSize(devices[i]);
|
ai.max_texture_size = GetMetalMaxTextureSize(devices[i]);
|
||||||
ai.max_multisamples = GetMetalMaxMultisamples(devices[i]);
|
ai.max_multisamples = GetMetalMaxMultisamples(devices[i]);
|
||||||
ai.supports_sample_shading = true;
|
ai.supports_sample_shading = true;
|
||||||
|
ai.driver_type = GuessDriverType(0, {}, device_name);
|
||||||
ret.push_back(std::move(ai));
|
ret.push_back(std::move(ai));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -356,6 +356,8 @@ bool OpenGLDevice::CheckFeatures(FeatureMask disabled_features)
|
|||||||
|
|
||||||
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));
|
||||||
|
|
||||||
if (std::strstr(vendor, "Advanced Micro Devices") || std::strstr(vendor, "ATI Technologies Inc.") ||
|
if (std::strstr(vendor, "Advanced Micro Devices") || std::strstr(vendor, "ATI Technologies Inc.") ||
|
||||||
std::strstr(vendor, "ATI"))
|
std::strstr(vendor, "ATI"))
|
||||||
{
|
{
|
||||||
@ -404,7 +406,7 @@ bool OpenGLDevice::CheckFeatures(FeatureMask disabled_features)
|
|||||||
glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
|
glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
|
||||||
DEV_LOG("GL_MAX_SAMPLES: {}", max_samples);
|
DEV_LOG("GL_MAX_SAMPLES: {}", max_samples);
|
||||||
m_max_texture_size = std::max(1024u, static_cast<u32>(max_texture_size));
|
m_max_texture_size = std::max(1024u, static_cast<u32>(max_texture_size));
|
||||||
m_max_multisamples = std::max(1u, static_cast<u32>(max_samples));
|
m_max_multisamples = static_cast<u16>(std::max(1u, static_cast<u32>(max_samples)));
|
||||||
|
|
||||||
GLint max_dual_source_draw_buffers = 0;
|
GLint max_dual_source_draw_buffers = 0;
|
||||||
glGetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS, &max_dual_source_draw_buffers);
|
glGetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS, &max_dual_source_draw_buffers);
|
||||||
|
@ -351,16 +351,29 @@ VulkanDevice::GPUList VulkanDevice::EnumerateGPUs(VkInstance instance)
|
|||||||
gpus.reserve(physical_devices.size());
|
gpus.reserve(physical_devices.size());
|
||||||
for (VkPhysicalDevice device : physical_devices)
|
for (VkPhysicalDevice device : physical_devices)
|
||||||
{
|
{
|
||||||
VkPhysicalDeviceProperties props = {};
|
VkPhysicalDeviceProperties2 props = {};
|
||||||
vkGetPhysicalDeviceProperties(device, &props);
|
VkPhysicalDeviceDriverProperties driver_props = {};
|
||||||
|
|
||||||
|
if (vkGetPhysicalDeviceProperties2)
|
||||||
|
{
|
||||||
|
driver_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
|
||||||
|
Vulkan::AddPointerToChain(&props, &driver_props);
|
||||||
|
vkGetPhysicalDeviceProperties2(device, &props);
|
||||||
|
}
|
||||||
|
|
||||||
|
// just in case the chained version fails
|
||||||
|
props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
|
||||||
|
vkGetPhysicalDeviceProperties(device, &props.properties);
|
||||||
|
|
||||||
VkPhysicalDeviceFeatures available_features = {};
|
VkPhysicalDeviceFeatures available_features = {};
|
||||||
vkGetPhysicalDeviceFeatures(device, &available_features);
|
vkGetPhysicalDeviceFeatures(device, &available_features);
|
||||||
|
|
||||||
AdapterInfo ai;
|
AdapterInfo ai;
|
||||||
ai.name = props.deviceName;
|
ai.name = props.properties.deviceName;
|
||||||
ai.max_texture_size = std::min(props.limits.maxFramebufferWidth, props.limits.maxImageDimension2D);
|
ai.max_texture_size =
|
||||||
ai.max_multisamples = GetMaxMultisamples(device, props);
|
std::min(props.properties.limits.maxFramebufferWidth, props.properties.limits.maxImageDimension2D);
|
||||||
|
ai.max_multisamples = GetMaxMultisamples(device, props.properties);
|
||||||
|
ai.driver_type = GuessDriverType(props.properties, driver_props);
|
||||||
ai.supports_sample_shading = available_features.sampleRateShading;
|
ai.supports_sample_shading = available_features.sampleRateShading;
|
||||||
|
|
||||||
// handle duplicate adapter names
|
// handle duplicate adapter names
|
||||||
@ -600,6 +613,9 @@ bool VulkanDevice::EnableOptionalDeviceExtensions(VkPhysicalDevice physical_devi
|
|||||||
if (vkGetPhysicalDeviceProperties2 && properties2.pNext)
|
if (vkGetPhysicalDeviceProperties2 && properties2.pNext)
|
||||||
vkGetPhysicalDeviceProperties2(physical_device, &properties2);
|
vkGetPhysicalDeviceProperties2(physical_device, &properties2);
|
||||||
|
|
||||||
|
// set driver type
|
||||||
|
SetDriverType(GuessDriverType(m_device_properties, m_device_driver_properties));
|
||||||
|
|
||||||
// check we actually support enough
|
// check we actually support enough
|
||||||
m_optional_extensions.vk_khr_push_descriptor &= (push_descriptor_properties.maxPushDescriptors >= 1);
|
m_optional_extensions.vk_khr_push_descriptor &= (push_descriptor_properties.maxPushDescriptors >= 1);
|
||||||
|
|
||||||
@ -2501,7 +2517,7 @@ void VulkanDevice::SetFeatures(FeatureMask disabled_features, VkPhysicalDevice p
|
|||||||
(VK_API_VERSION_MINOR(store_api_version) * 10u) + (VK_API_VERSION_PATCH(store_api_version));
|
(VK_API_VERSION_MINOR(store_api_version) * 10u) + (VK_API_VERSION_PATCH(store_api_version));
|
||||||
m_max_texture_size =
|
m_max_texture_size =
|
||||||
std::min(m_device_properties.limits.maxImageDimension2D, m_device_properties.limits.maxFramebufferWidth);
|
std::min(m_device_properties.limits.maxImageDimension2D, m_device_properties.limits.maxFramebufferWidth);
|
||||||
m_max_multisamples = GetMaxMultisamples(physical_device, m_device_properties);
|
m_max_multisamples = static_cast<u16>(GetMaxMultisamples(physical_device, m_device_properties));
|
||||||
|
|
||||||
m_features.dual_source_blend = !(disabled_features & FEATURE_MASK_DUAL_SOURCE_BLEND) && vk_features.dualSrcBlend;
|
m_features.dual_source_blend = !(disabled_features & FEATURE_MASK_DUAL_SOURCE_BLEND) && vk_features.dualSrcBlend;
|
||||||
m_features.framebuffer_fetch =
|
m_features.framebuffer_fetch =
|
||||||
@ -2552,6 +2568,51 @@ void VulkanDevice::SetFeatures(FeatureMask disabled_features, VkPhysicalDevice p
|
|||||||
(!(disabled_features & FEATURE_MASK_COMPRESSED_TEXTURES) && vk_features.textureCompressionBC);
|
(!(disabled_features & FEATURE_MASK_COMPRESSED_TEXTURES) && vk_features.textureCompressionBC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GPUDriverType VulkanDevice::GuessDriverType(const VkPhysicalDeviceProperties& device_properties,
|
||||||
|
const VkPhysicalDeviceDriverProperties& driver_properties)
|
||||||
|
{
|
||||||
|
static constexpr const std::pair<VkDriverId, GPUDriverType> table[] = {
|
||||||
|
{VK_DRIVER_ID_NVIDIA_PROPRIETARY, GPUDriverType::NVIDIAProprietary},
|
||||||
|
{VK_DRIVER_ID_AMD_PROPRIETARY, GPUDriverType::AMDProprietary},
|
||||||
|
{VK_DRIVER_ID_AMD_OPEN_SOURCE, GPUDriverType::AMDProprietary},
|
||||||
|
{VK_DRIVER_ID_MESA_RADV, GPUDriverType::AMDMesa},
|
||||||
|
{VK_DRIVER_ID_NVIDIA_PROPRIETARY, GPUDriverType::NVIDIAProprietary},
|
||||||
|
{VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS, GPUDriverType::IntelProprietary},
|
||||||
|
{VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA, GPUDriverType::IntelMesa},
|
||||||
|
{VK_DRIVER_ID_IMAGINATION_PROPRIETARY, GPUDriverType::ImaginationProprietary},
|
||||||
|
{VK_DRIVER_ID_QUALCOMM_PROPRIETARY, GPUDriverType::QualcommProprietary},
|
||||||
|
{VK_DRIVER_ID_ARM_PROPRIETARY, GPUDriverType::ARMProprietary},
|
||||||
|
{VK_DRIVER_ID_GOOGLE_SWIFTSHADER, GPUDriverType::SwiftShader},
|
||||||
|
{VK_DRIVER_ID_GGP_PROPRIETARY, GPUDriverType::Unknown},
|
||||||
|
{VK_DRIVER_ID_BROADCOM_PROPRIETARY, GPUDriverType::BroadcomProprietary},
|
||||||
|
{VK_DRIVER_ID_MESA_LLVMPIPE, GPUDriverType::LLVMPipe},
|
||||||
|
{VK_DRIVER_ID_MOLTENVK, GPUDriverType::AppleProprietary},
|
||||||
|
{VK_DRIVER_ID_COREAVI_PROPRIETARY, GPUDriverType::Unknown},
|
||||||
|
{VK_DRIVER_ID_JUICE_PROPRIETARY, GPUDriverType::Unknown},
|
||||||
|
{VK_DRIVER_ID_VERISILICON_PROPRIETARY, GPUDriverType::Unknown},
|
||||||
|
{VK_DRIVER_ID_MESA_TURNIP, GPUDriverType::QualcommMesa},
|
||||||
|
{VK_DRIVER_ID_MESA_V3DV, GPUDriverType::BroadcomMesa},
|
||||||
|
{VK_DRIVER_ID_MESA_PANVK, GPUDriverType::ARMMesa},
|
||||||
|
{VK_DRIVER_ID_SAMSUNG_PROPRIETARY, GPUDriverType::AMDProprietary},
|
||||||
|
{VK_DRIVER_ID_MESA_VENUS, GPUDriverType::Unknown},
|
||||||
|
{VK_DRIVER_ID_MESA_DOZEN, GPUDriverType::DozenMesa},
|
||||||
|
{VK_DRIVER_ID_MESA_NVK, GPUDriverType::NVIDIAMesa},
|
||||||
|
{VK_DRIVER_ID_IMAGINATION_OPEN_SOURCE_MESA, GPUDriverType::ImaginationMesa},
|
||||||
|
{VK_DRIVER_ID_MESA_AGXV, GPUDriverType::AppleMesa},
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto iter = std::find_if(std::begin(table), std::end(table), [&driver_properties](const auto& it) {
|
||||||
|
return (driver_properties.driverID == it.first);
|
||||||
|
});
|
||||||
|
if (iter != std::end(table))
|
||||||
|
return iter->second;
|
||||||
|
|
||||||
|
return GPUDevice::GuessDriverType(
|
||||||
|
device_properties.vendorID, {},
|
||||||
|
std::string_view(device_properties.deviceName,
|
||||||
|
StringUtil::Strnlen(device_properties.deviceName, std::size(device_properties.deviceName))));
|
||||||
|
}
|
||||||
|
|
||||||
void VulkanDevice::CopyTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u32 dst_layer, u32 dst_level,
|
void VulkanDevice::CopyTextureRegion(GPUTexture* dst, u32 dst_x, u32 dst_y, u32 dst_layer, u32 dst_level,
|
||||||
GPUTexture* src, u32 src_x, u32 src_y, u32 src_layer, u32 src_level, u32 width,
|
GPUTexture* src, u32 src_x, u32 src_y, u32 src_layer, u32 src_level, u32 width,
|
||||||
u32 height)
|
u32 height)
|
||||||
|
@ -349,6 +349,8 @@ private:
|
|||||||
void SetFeatures(FeatureMask disabled_features, VkPhysicalDevice physical_device,
|
void SetFeatures(FeatureMask disabled_features, VkPhysicalDevice physical_device,
|
||||||
const VkPhysicalDeviceFeatures& vk_features);
|
const VkPhysicalDeviceFeatures& vk_features);
|
||||||
|
|
||||||
|
static GPUDriverType GuessDriverType(const VkPhysicalDeviceProperties& device_properties,
|
||||||
|
const VkPhysicalDeviceDriverProperties& driver_properties);
|
||||||
static u32 GetMaxMultisamples(VkPhysicalDevice physical_device, const VkPhysicalDeviceProperties& properties);
|
static u32 GetMaxMultisamples(VkPhysicalDevice physical_device, const VkPhysicalDeviceProperties& properties);
|
||||||
|
|
||||||
bool CreateAllocator();
|
bool CreateAllocator();
|
||||||
@ -432,7 +434,7 @@ private:
|
|||||||
VkDebugUtilsMessengerEXT m_debug_messenger_callback = VK_NULL_HANDLE;
|
VkDebugUtilsMessengerEXT m_debug_messenger_callback = VK_NULL_HANDLE;
|
||||||
|
|
||||||
VkPhysicalDeviceProperties m_device_properties = {};
|
VkPhysicalDeviceProperties m_device_properties = {};
|
||||||
VkPhysicalDeviceDriverPropertiesKHR m_device_driver_properties = {};
|
VkPhysicalDeviceDriverProperties m_device_driver_properties = {};
|
||||||
OptionalExtensions m_optional_extensions = {};
|
OptionalExtensions m_optional_extensions = {};
|
||||||
std::optional<bool> m_exclusive_fullscreen_control;
|
std::optional<bool> m_exclusive_fullscreen_control;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user