mirror of
https://github.com/yuzu-emu/yuzu.git
synced 2024-07-04 23:31:19 +01:00
vk_device: Use Vulkan 1.0 properly
Enable the required capabilities to use Vulkan 1.0 without validation errors and disable those that are not compatible with it.
This commit is contained in:
parent
29a0ca2391
commit
c5a78f4480
5 changed files with 66 additions and 52 deletions
|
@ -92,9 +92,9 @@ Common::DynamicLibrary OpenVulkanLibrary() {
|
||||||
return library;
|
return library;
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::Instance CreateInstance(Common::DynamicLibrary& library, vk::InstanceDispatch& dld,
|
std::pair<vk::Instance, u32> CreateInstance(
|
||||||
WindowSystemType window_type = WindowSystemType::Headless,
|
Common::DynamicLibrary& library, vk::InstanceDispatch& dld,
|
||||||
bool enable_layers = false) {
|
WindowSystemType window_type = WindowSystemType::Headless, bool enable_layers = false) {
|
||||||
if (!library.IsOpen()) {
|
if (!library.IsOpen()) {
|
||||||
LOG_ERROR(Render_Vulkan, "Vulkan library not available");
|
LOG_ERROR(Render_Vulkan, "Vulkan library not available");
|
||||||
return {};
|
return {};
|
||||||
|
@ -191,7 +191,7 @@ vk::Instance CreateInstance(Common::DynamicLibrary& library, vk::InstanceDispatc
|
||||||
if (!vk::Load(*instance, dld)) {
|
if (!vk::Load(*instance, dld)) {
|
||||||
LOG_ERROR(Render_Vulkan, "Failed to load Vulkan instance function pointers");
|
LOG_ERROR(Render_Vulkan, "Failed to load Vulkan instance function pointers");
|
||||||
}
|
}
|
||||||
return instance;
|
return std::make_pair(std::move(instance), version);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetReadableVersion(u32 version) {
|
std::string GetReadableVersion(u32 version) {
|
||||||
|
@ -289,8 +289,8 @@ bool RendererVulkan::TryPresent(int /*timeout_ms*/) {
|
||||||
|
|
||||||
bool RendererVulkan::Init() {
|
bool RendererVulkan::Init() {
|
||||||
library = OpenVulkanLibrary();
|
library = OpenVulkanLibrary();
|
||||||
instance = CreateInstance(library, dld, render_window.GetWindowInfo().type,
|
std::tie(instance, instance_version) = CreateInstance(
|
||||||
Settings::values.renderer_debug);
|
library, dld, render_window.GetWindowInfo().type, Settings::values.renderer_debug);
|
||||||
if (!instance || !CreateDebugCallback() || !CreateSurface() || !PickDevices()) {
|
if (!instance || !CreateDebugCallback() || !CreateSurface() || !PickDevices()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -423,7 +423,8 @@ bool RendererVulkan::PickDevices() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
device = std::make_unique<VKDevice>(*instance, physical_device, *surface, dld);
|
device =
|
||||||
|
std::make_unique<VKDevice>(*instance, instance_version, physical_device, *surface, dld);
|
||||||
return device->Create();
|
return device->Create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,7 +434,7 @@ void RendererVulkan::Report() const {
|
||||||
const std::string driver_version = GetDriverVersion(*device);
|
const std::string driver_version = GetDriverVersion(*device);
|
||||||
const std::string driver_name = fmt::format("{} {}", vendor_name, driver_version);
|
const std::string driver_name = fmt::format("{} {}", vendor_name, driver_version);
|
||||||
|
|
||||||
const std::string api_version = GetReadableVersion(device->GetApiVersion());
|
const std::string api_version = GetReadableVersion(device->ApiVersion());
|
||||||
|
|
||||||
const std::string extensions = BuildCommaSeparatedExtensions(device->GetAvailableExtensions());
|
const std::string extensions = BuildCommaSeparatedExtensions(device->GetAvailableExtensions());
|
||||||
|
|
||||||
|
@ -453,7 +454,7 @@ void RendererVulkan::Report() const {
|
||||||
std::vector<std::string> RendererVulkan::EnumerateDevices() {
|
std::vector<std::string> RendererVulkan::EnumerateDevices() {
|
||||||
vk::InstanceDispatch dld;
|
vk::InstanceDispatch dld;
|
||||||
Common::DynamicLibrary library = OpenVulkanLibrary();
|
Common::DynamicLibrary library = OpenVulkanLibrary();
|
||||||
vk::Instance instance = CreateInstance(library, dld);
|
vk::Instance instance = CreateInstance(library, dld).first;
|
||||||
if (!instance) {
|
if (!instance) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,8 @@ private:
|
||||||
vk::InstanceDispatch dld;
|
vk::InstanceDispatch dld;
|
||||||
|
|
||||||
vk::Instance instance;
|
vk::Instance instance;
|
||||||
|
u32 instance_version{};
|
||||||
|
|
||||||
vk::SurfaceKHR surface;
|
vk::SurfaceKHR surface;
|
||||||
|
|
||||||
VKScreenInfo screen_info;
|
VKScreenInfo screen_info;
|
||||||
|
|
|
@ -38,6 +38,9 @@ constexpr std::array Depth16UnormS8_UINT{
|
||||||
|
|
||||||
constexpr std::array REQUIRED_EXTENSIONS{
|
constexpr std::array REQUIRED_EXTENSIONS{
|
||||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
||||||
|
VK_KHR_MAINTENANCE1_EXTENSION_NAME,
|
||||||
|
VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME,
|
||||||
|
VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME,
|
||||||
VK_KHR_16BIT_STORAGE_EXTENSION_NAME,
|
VK_KHR_16BIT_STORAGE_EXTENSION_NAME,
|
||||||
VK_KHR_8BIT_STORAGE_EXTENSION_NAME,
|
VK_KHR_8BIT_STORAGE_EXTENSION_NAME,
|
||||||
VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME,
|
VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME,
|
||||||
|
@ -171,10 +174,10 @@ std::unordered_map<VkFormat, VkFormatProperties> GetFormatProperties(
|
||||||
|
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
VKDevice::VKDevice(VkInstance instance, vk::PhysicalDevice physical, VkSurfaceKHR surface,
|
VKDevice::VKDevice(VkInstance instance_, u32 instance_version_, vk::PhysicalDevice physical_,
|
||||||
const vk::InstanceDispatch& dld)
|
VkSurfaceKHR surface, const vk::InstanceDispatch& dld_)
|
||||||
: dld{dld}, physical{physical}, properties{physical.GetProperties()},
|
: dld{dld_}, physical{physical_}, properties{physical.GetProperties()},
|
||||||
format_properties{GetFormatProperties(physical, dld)} {
|
instance_version{instance_version_}, format_properties{GetFormatProperties(physical, dld)} {
|
||||||
SetupFamilies(surface);
|
SetupFamilies(surface);
|
||||||
SetupFeatures();
|
SetupFeatures();
|
||||||
}
|
}
|
||||||
|
@ -565,8 +568,16 @@ bool VKDevice::IsSuitable(vk::PhysicalDevice physical, VkSurfaceKHR surface) {
|
||||||
|
|
||||||
std::vector<const char*> VKDevice::LoadExtensions() {
|
std::vector<const char*> VKDevice::LoadExtensions() {
|
||||||
std::vector<const char*> extensions;
|
std::vector<const char*> extensions;
|
||||||
const auto Test = [&](const VkExtensionProperties& extension,
|
extensions.reserve(7 + REQUIRED_EXTENSIONS.size());
|
||||||
std::optional<std::reference_wrapper<bool>> status, const char* name,
|
extensions.insert(extensions.begin(), REQUIRED_EXTENSIONS.begin(), REQUIRED_EXTENSIONS.end());
|
||||||
|
|
||||||
|
bool has_khr_shader_float16_int8{};
|
||||||
|
bool has_ext_subgroup_size_control{};
|
||||||
|
bool has_ext_transform_feedback{};
|
||||||
|
bool has_ext_custom_border_color{};
|
||||||
|
bool has_ext_extended_dynamic_state{};
|
||||||
|
for (const VkExtensionProperties& extension : physical.EnumerateDeviceExtensionProperties()) {
|
||||||
|
const auto test = [&](std::optional<std::reference_wrapper<bool>> status, const char* name,
|
||||||
bool push) {
|
bool push) {
|
||||||
if (extension.extensionName != std::string_view(name)) {
|
if (extension.extensionName != std::string_view(name)) {
|
||||||
return;
|
return;
|
||||||
|
@ -578,37 +589,23 @@ std::vector<const char*> VKDevice::LoadExtensions() {
|
||||||
status->get() = true;
|
status->get() = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
test(nv_viewport_swizzle, VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME, true);
|
||||||
extensions.reserve(7 + REQUIRED_EXTENSIONS.size());
|
test(khr_uniform_buffer_standard_layout,
|
||||||
extensions.insert(extensions.begin(), REQUIRED_EXTENSIONS.begin(), REQUIRED_EXTENSIONS.end());
|
|
||||||
|
|
||||||
bool has_khr_shader_float16_int8{};
|
|
||||||
bool has_ext_subgroup_size_control{};
|
|
||||||
bool has_ext_transform_feedback{};
|
|
||||||
bool has_ext_custom_border_color{};
|
|
||||||
bool has_ext_extended_dynamic_state{};
|
|
||||||
for (const auto& extension : physical.EnumerateDeviceExtensionProperties()) {
|
|
||||||
Test(extension, nv_viewport_swizzle, VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME, true);
|
|
||||||
Test(extension, khr_uniform_buffer_standard_layout,
|
|
||||||
VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, true);
|
VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, true);
|
||||||
Test(extension, has_khr_shader_float16_int8, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME,
|
test(has_khr_shader_float16_int8, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, false);
|
||||||
false);
|
test(ext_depth_range_unrestricted, VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME, true);
|
||||||
Test(extension, ext_depth_range_unrestricted,
|
test(ext_index_type_uint8, VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME, true);
|
||||||
VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME, true);
|
test(ext_shader_viewport_index_layer, VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME,
|
||||||
Test(extension, ext_index_type_uint8, VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME, true);
|
true);
|
||||||
Test(extension, ext_shader_viewport_index_layer,
|
test(has_ext_transform_feedback, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, false);
|
||||||
VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME, true);
|
test(has_ext_custom_border_color, VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, false);
|
||||||
Test(extension, has_ext_subgroup_size_control, VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME,
|
test(has_ext_extended_dynamic_state, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, false);
|
||||||
false);
|
if (instance_version >= VK_API_VERSION_1_1) {
|
||||||
Test(extension, has_ext_transform_feedback, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME,
|
test(has_ext_subgroup_size_control, VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME, false);
|
||||||
false);
|
}
|
||||||
Test(extension, has_ext_custom_border_color, VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME,
|
|
||||||
false);
|
|
||||||
Test(extension, has_ext_extended_dynamic_state,
|
|
||||||
VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, false);
|
|
||||||
if (Settings::values.renderer_debug) {
|
if (Settings::values.renderer_debug) {
|
||||||
Test(extension, nv_device_diagnostics_config,
|
test(nv_device_diagnostics_config, VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME,
|
||||||
VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME, true);
|
true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,8 @@ const u32 GuestWarpSize = 32;
|
||||||
/// Handles data specific to a physical device.
|
/// Handles data specific to a physical device.
|
||||||
class VKDevice final {
|
class VKDevice final {
|
||||||
public:
|
public:
|
||||||
explicit VKDevice(VkInstance instance, vk::PhysicalDevice physical, VkSurfaceKHR surface,
|
explicit VKDevice(VkInstance instance, u32 instance_version, vk::PhysicalDevice physical,
|
||||||
const vk::InstanceDispatch& dld);
|
VkSurfaceKHR surface, const vk::InstanceDispatch& dld);
|
||||||
~VKDevice();
|
~VKDevice();
|
||||||
|
|
||||||
/// Initializes the device. Returns true on success.
|
/// Initializes the device. Returns true on success.
|
||||||
|
@ -82,8 +82,13 @@ public:
|
||||||
return present_family;
|
return present_family;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the current instance Vulkan API version in Vulkan-formatted version numbers.
|
||||||
|
u32 InstanceApiVersion() const {
|
||||||
|
return instance_version;
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the current Vulkan API version provided in Vulkan-formatted version numbers.
|
/// Returns the current Vulkan API version provided in Vulkan-formatted version numbers.
|
||||||
u32 GetApiVersion() const {
|
u32 ApiVersion() const {
|
||||||
return properties.apiVersion;
|
return properties.apiVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,6 +244,7 @@ private:
|
||||||
vk::Device logical; ///< Logical device.
|
vk::Device logical; ///< Logical device.
|
||||||
vk::Queue graphics_queue; ///< Main graphics queue.
|
vk::Queue graphics_queue; ///< Main graphics queue.
|
||||||
vk::Queue present_queue; ///< Main present queue.
|
vk::Queue present_queue; ///< Main present queue.
|
||||||
|
u32 instance_version{}; ///< Vulkan onstance version.
|
||||||
u32 graphics_family{}; ///< Main graphics queue family index.
|
u32 graphics_family{}; ///< Main graphics queue family index.
|
||||||
u32 present_family{}; ///< Main present queue family index.
|
u32 present_family{}; ///< Main present queue family index.
|
||||||
VkDriverIdKHR driver_id{}; ///< Driver ID.
|
VkDriverIdKHR driver_id{}; ///< Driver ID.
|
||||||
|
|
|
@ -272,12 +272,19 @@ bool IsPrecise(Operation operand) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 ShaderVersion(const VKDevice& device) {
|
||||||
|
if (device.InstanceApiVersion() < VK_API_VERSION_1_1) {
|
||||||
|
return 0x00010000;
|
||||||
|
}
|
||||||
|
return 0x00010300;
|
||||||
|
}
|
||||||
|
|
||||||
class SPIRVDecompiler final : public Sirit::Module {
|
class SPIRVDecompiler final : public Sirit::Module {
|
||||||
public:
|
public:
|
||||||
explicit SPIRVDecompiler(const VKDevice& device, const ShaderIR& ir, ShaderType stage,
|
explicit SPIRVDecompiler(const VKDevice& device, const ShaderIR& ir, ShaderType stage,
|
||||||
const Registry& registry, const Specialization& specialization)
|
const Registry& registry, const Specialization& specialization)
|
||||||
: Module(0x00010300), device{device}, ir{ir}, stage{stage}, header{ir.GetHeader()},
|
: Module(ShaderVersion(device)), device{device}, ir{ir}, stage{stage},
|
||||||
registry{registry}, specialization{specialization} {
|
header{ir.GetHeader()}, registry{registry}, specialization{specialization} {
|
||||||
if (stage != ShaderType::Compute) {
|
if (stage != ShaderType::Compute) {
|
||||||
transform_feedback = BuildTransformFeedback(registry.GetGraphicsInfo());
|
transform_feedback = BuildTransformFeedback(registry.GetGraphicsInfo());
|
||||||
}
|
}
|
||||||
|
@ -293,6 +300,7 @@ public:
|
||||||
AddCapability(spv::Capability::DrawParameters);
|
AddCapability(spv::Capability::DrawParameters);
|
||||||
AddCapability(spv::Capability::SubgroupBallotKHR);
|
AddCapability(spv::Capability::SubgroupBallotKHR);
|
||||||
AddCapability(spv::Capability::SubgroupVoteKHR);
|
AddCapability(spv::Capability::SubgroupVoteKHR);
|
||||||
|
AddExtension("SPV_KHR_16bit_storage");
|
||||||
AddExtension("SPV_KHR_shader_ballot");
|
AddExtension("SPV_KHR_shader_ballot");
|
||||||
AddExtension("SPV_KHR_subgroup_vote");
|
AddExtension("SPV_KHR_subgroup_vote");
|
||||||
AddExtension("SPV_KHR_storage_buffer_storage_class");
|
AddExtension("SPV_KHR_storage_buffer_storage_class");
|
||||||
|
|
Loading…
Reference in a new issue