2016-08-13 12:57:50 +00:00
|
|
|
// Copyright 2016 Dolphin Emulator Project
|
2021-07-05 01:22:19 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2016-08-13 12:57:50 +00:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <memory>
|
2019-10-02 11:27:32 +00:00
|
|
|
#include <optional>
|
2019-09-30 15:07:36 +00:00
|
|
|
#include <string>
|
2016-08-13 12:57:50 +00:00
|
|
|
#include <vector>
|
|
|
|
|
2016-10-01 03:07:50 +00:00
|
|
|
#include "Common/CommonTypes.h"
|
2018-10-24 04:47:48 +00:00
|
|
|
#include "Common/WindowSystemInfo.h"
|
2016-08-13 12:57:50 +00:00
|
|
|
#include "VideoBackends/Vulkan/Constants.h"
|
|
|
|
#include "VideoCommon/VideoConfig.h"
|
|
|
|
|
|
|
|
namespace Vulkan
|
|
|
|
{
|
|
|
|
class VulkanContext
|
|
|
|
{
|
|
|
|
public:
|
2024-09-04 04:24:05 +00:00
|
|
|
struct PhysicalDeviceInfo
|
|
|
|
{
|
|
|
|
PhysicalDeviceInfo(const PhysicalDeviceInfo&) = default;
|
|
|
|
explicit PhysicalDeviceInfo(VkPhysicalDevice device);
|
|
|
|
VkPhysicalDeviceFeatures features() const;
|
|
|
|
|
|
|
|
char deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE];
|
|
|
|
u8 pipelineCacheUUID[VK_UUID_SIZE];
|
|
|
|
u32 apiVersion;
|
|
|
|
u32 driverVersion;
|
|
|
|
u32 vendorID;
|
|
|
|
u32 deviceID;
|
|
|
|
VkDeviceSize minUniformBufferOffsetAlignment;
|
|
|
|
VkDeviceSize bufferImageGranularity;
|
|
|
|
u32 maxTexelBufferElements;
|
|
|
|
u32 maxImageDimension2D;
|
|
|
|
VkSampleCountFlags framebufferColorSampleCounts;
|
|
|
|
VkSampleCountFlags framebufferDepthSampleCounts;
|
|
|
|
float pointSizeRange[2];
|
|
|
|
float maxSamplerAnisotropy;
|
|
|
|
u32 subgroupSize = 1;
|
2024-09-04 04:55:27 +00:00
|
|
|
VkDriverId driverID = static_cast<VkDriverId>(0);
|
2024-09-04 04:24:05 +00:00
|
|
|
bool dualSrcBlend;
|
|
|
|
bool geometryShader;
|
|
|
|
bool samplerAnisotropy;
|
|
|
|
bool logicOp;
|
|
|
|
bool fragmentStoresAndAtomics;
|
|
|
|
bool sampleRateShading;
|
|
|
|
bool largePoints;
|
|
|
|
bool shaderStorageImageMultisample;
|
|
|
|
bool shaderTessellationAndGeometryPointSize;
|
|
|
|
bool occlusionQueryPrecise;
|
|
|
|
bool shaderClipDistance;
|
|
|
|
bool depthClamp;
|
|
|
|
bool textureCompressionBC;
|
|
|
|
bool shaderSubgroupOperations = false;
|
|
|
|
};
|
|
|
|
|
2016-08-13 12:57:50 +00:00
|
|
|
VulkanContext(VkInstance instance, VkPhysicalDevice physical_device);
|
|
|
|
~VulkanContext();
|
|
|
|
|
|
|
|
// Determines if the Vulkan validation layer is available on the system.
|
|
|
|
static bool CheckValidationLayerAvailablility();
|
|
|
|
|
|
|
|
// Helper method to create a Vulkan instance.
|
2022-10-27 19:25:32 +00:00
|
|
|
static VkInstance CreateVulkanInstance(WindowSystemType wstype, bool enable_debug_utils,
|
2022-10-07 21:36:16 +00:00
|
|
|
bool enable_validation_layer, u32* out_vk_api_version);
|
2016-08-13 12:57:50 +00:00
|
|
|
|
|
|
|
// Returns a list of Vulkan-compatible GPUs.
|
|
|
|
using GPUList = std::vector<VkPhysicalDevice>;
|
|
|
|
static GPUList EnumerateGPUs(VkInstance instance);
|
|
|
|
|
|
|
|
// Populates backend/video config.
|
|
|
|
// These are public so that the backend info can be populated without creating a context.
|
|
|
|
static void PopulateBackendInfo(VideoConfig* config);
|
|
|
|
static void PopulateBackendInfoAdapters(VideoConfig* config, const GPUList& gpu_list);
|
|
|
|
static void PopulateBackendInfoFeatures(VideoConfig* config, VkPhysicalDevice gpu,
|
2024-09-04 04:24:05 +00:00
|
|
|
const PhysicalDeviceInfo& info);
|
2016-08-13 12:57:50 +00:00
|
|
|
static void PopulateBackendInfoMultisampleModes(VideoConfig* config, VkPhysicalDevice gpu,
|
2024-09-04 04:24:05 +00:00
|
|
|
const PhysicalDeviceInfo& info);
|
2016-08-13 12:57:50 +00:00
|
|
|
|
|
|
|
// Creates a Vulkan device context.
|
|
|
|
// This assumes that PopulateBackendInfo and PopulateBackendInfoAdapters has already
|
|
|
|
// been called for the specified VideoConfig.
|
|
|
|
static std::unique_ptr<VulkanContext> Create(VkInstance instance, VkPhysicalDevice gpu,
|
2022-10-27 19:25:32 +00:00
|
|
|
VkSurfaceKHR surface, bool enable_debug_utils,
|
2022-10-07 21:36:16 +00:00
|
|
|
bool enable_validation_layer, u32 api_version);
|
2016-08-13 12:57:50 +00:00
|
|
|
|
|
|
|
// Enable/disable debug message runtime.
|
2022-10-27 19:25:32 +00:00
|
|
|
bool EnableDebugUtils();
|
|
|
|
void DisableDebugUtils();
|
2016-08-13 12:57:50 +00:00
|
|
|
|
|
|
|
// Global state accessors
|
|
|
|
VkInstance GetVulkanInstance() const { return m_instance; }
|
|
|
|
VkPhysicalDevice GetPhysicalDevice() const { return m_physical_device; }
|
|
|
|
VkDevice GetDevice() const { return m_device; }
|
|
|
|
VkQueue GetGraphicsQueue() const { return m_graphics_queue; }
|
|
|
|
u32 GetGraphicsQueueFamilyIndex() const { return m_graphics_queue_family_index; }
|
2017-09-04 21:35:53 +00:00
|
|
|
VkQueue GetPresentQueue() const { return m_present_queue; }
|
|
|
|
u32 GetPresentQueueFamilyIndex() const { return m_present_queue_family_index; }
|
2016-08-13 12:57:50 +00:00
|
|
|
const VkQueueFamilyProperties& GetGraphicsQueueProperties() const
|
|
|
|
{
|
|
|
|
return m_graphics_queue_properties;
|
|
|
|
}
|
2024-09-04 04:24:05 +00:00
|
|
|
const PhysicalDeviceInfo& GetDeviceInfo() const { return m_device_info; }
|
2016-08-13 12:57:50 +00:00
|
|
|
// Support bits
|
2024-09-04 04:24:05 +00:00
|
|
|
bool SupportsAnisotropicFiltering() const { return m_device_info.samplerAnisotropy; }
|
|
|
|
bool SupportsPreciseOcclusionQueries() const { return m_device_info.occlusionQueryPrecise; }
|
|
|
|
u32 GetShaderSubgroupSize() const { return m_device_info.subgroupSize; }
|
|
|
|
bool SupportsShaderSubgroupOperations() const { return m_device_info.shaderSubgroupOperations; }
|
2018-08-29 03:12:19 +00:00
|
|
|
|
2016-08-13 12:57:50 +00:00
|
|
|
// Helpers for getting constants
|
|
|
|
VkDeviceSize GetUniformBufferAlignment() const
|
|
|
|
{
|
2024-09-04 04:24:05 +00:00
|
|
|
return m_device_info.minUniformBufferOffsetAlignment;
|
2016-08-13 12:57:50 +00:00
|
|
|
}
|
2024-09-04 04:24:05 +00:00
|
|
|
VkDeviceSize GetBufferImageGranularity() const { return m_device_info.bufferImageGranularity; }
|
|
|
|
float GetMaxSamplerAnisotropy() const { return m_device_info.maxSamplerAnisotropy; }
|
2016-08-13 12:57:50 +00:00
|
|
|
|
2019-09-30 15:07:36 +00:00
|
|
|
// Returns true if the specified extension is supported and enabled.
|
|
|
|
bool SupportsDeviceExtension(const char* name) const;
|
|
|
|
|
2019-09-30 15:10:08 +00:00
|
|
|
// Returns true if exclusive fullscreen is supported for the given surface.
|
|
|
|
bool SupportsExclusiveFullscreen(const WindowSystemInfo& wsi, VkSurfaceKHR surface);
|
|
|
|
|
2022-10-07 21:36:16 +00:00
|
|
|
VmaAllocator GetMemoryAllocator() const { return m_allocator; }
|
|
|
|
|
2019-09-30 15:10:08 +00:00
|
|
|
#ifdef WIN32
|
|
|
|
// Returns the platform-specific exclusive fullscreen structure.
|
|
|
|
VkSurfaceFullScreenExclusiveWin32InfoEXT
|
|
|
|
GetPlatformExclusiveFullscreenInfo(const WindowSystemInfo& wsi);
|
|
|
|
#endif
|
|
|
|
|
2016-08-13 12:57:50 +00:00
|
|
|
private:
|
2019-09-30 15:07:36 +00:00
|
|
|
static bool SelectInstanceExtensions(std::vector<const char*>* extension_list,
|
2022-10-27 19:25:32 +00:00
|
|
|
WindowSystemType wstype, bool enable_debug_utils,
|
|
|
|
bool validation_layer_enabled);
|
2019-09-30 15:07:36 +00:00
|
|
|
bool SelectDeviceExtensions(bool enable_surface);
|
2024-09-04 04:24:05 +00:00
|
|
|
void WarnMissingDeviceFeatures();
|
2016-08-13 12:57:50 +00:00
|
|
|
bool CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer);
|
2017-09-19 11:11:33 +00:00
|
|
|
void InitDriverDetails();
|
2022-10-07 21:36:16 +00:00
|
|
|
bool CreateAllocator(u32 vk_api_version);
|
2016-08-13 12:57:50 +00:00
|
|
|
|
|
|
|
VkInstance m_instance = VK_NULL_HANDLE;
|
|
|
|
VkPhysicalDevice m_physical_device = VK_NULL_HANDLE;
|
|
|
|
VkDevice m_device = VK_NULL_HANDLE;
|
2022-10-07 21:36:16 +00:00
|
|
|
VmaAllocator m_allocator = VK_NULL_HANDLE;
|
2016-08-13 12:57:50 +00:00
|
|
|
|
|
|
|
VkQueue m_graphics_queue = VK_NULL_HANDLE;
|
|
|
|
u32 m_graphics_queue_family_index = 0;
|
2017-09-04 21:35:53 +00:00
|
|
|
VkQueue m_present_queue = VK_NULL_HANDLE;
|
|
|
|
u32 m_present_queue_family_index = 0;
|
2016-08-13 12:57:50 +00:00
|
|
|
VkQueueFamilyProperties m_graphics_queue_properties = {};
|
|
|
|
|
2022-10-27 19:25:32 +00:00
|
|
|
VkDebugUtilsMessengerEXT m_debug_utils_messenger = VK_NULL_HANDLE;
|
2016-08-13 12:57:50 +00:00
|
|
|
|
2024-09-04 04:24:05 +00:00
|
|
|
PhysicalDeviceInfo m_device_info;
|
2019-09-30 15:07:36 +00:00
|
|
|
|
|
|
|
std::vector<std::string> m_device_extensions;
|
2016-08-13 12:57:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
extern std::unique_ptr<VulkanContext> g_vulkan_context;
|
|
|
|
|
|
|
|
} // namespace Vulkan
|