Vulkan: Create device and load all entry points
This commit is contained in:
parent
f40d8c545c
commit
0216233a83
|
@ -49,40 +49,68 @@ namespace vulkan {
|
|||
}
|
||||
|
||||
VulkanFunctions* functions = GetMutableFunctions();
|
||||
VulkanInfo* vulkanInfo = GetMutableInfo();
|
||||
|
||||
if (!functions->LoadGlobalProcs(vulkanLib)) {
|
||||
ASSERT(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!vulkanInfo->GatherGlobalInfo(*this)) {
|
||||
if (!GatherGlobalInfo(*this, &globalInfo)) {
|
||||
ASSERT(false);
|
||||
return;
|
||||
}
|
||||
|
||||
KnownGlobalVulkanExtensions usedGlobals;
|
||||
if (!CreateInstance(&usedGlobals)) {
|
||||
VulkanGlobalKnobs usedGlobalKnobs = {};
|
||||
if (!CreateInstance(&usedGlobalKnobs)) {
|
||||
ASSERT(false);
|
||||
return;
|
||||
}
|
||||
*static_cast<VulkanGlobalKnobs*>(&globalInfo) = usedGlobalKnobs;
|
||||
|
||||
if (!functions->LoadInstanceProcs(instance, usedGlobalKnobs)) {
|
||||
ASSERT(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!functions->LoadInstanceProcs(instance, usedGlobals)) {
|
||||
ASSERT(false);
|
||||
return;
|
||||
}
|
||||
|
||||
vulkanInfo->SetUsedGlobals(usedGlobals);
|
||||
|
||||
if(usedGlobals.debugReport) {
|
||||
if (usedGlobalKnobs.debugReport) {
|
||||
if (!RegisterDebugReport()) {
|
||||
ASSERT(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<VkPhysicalDevice> physicalDevices;
|
||||
if (!GetPhysicalDevices(*this, &physicalDevices) || physicalDevices.empty()) {
|
||||
ASSERT(false);
|
||||
return;
|
||||
}
|
||||
// TODO(cwallez@chromium.org): Choose the physical device based on ???
|
||||
physicalDevice = physicalDevices[0];
|
||||
|
||||
if (!GatherDeviceInfo(*this, physicalDevice, &deviceInfo)) {
|
||||
ASSERT(false);
|
||||
return;
|
||||
}
|
||||
|
||||
VulkanDeviceKnobs usedDeviceKnobs = {};
|
||||
if (!CreateDevice(&usedDeviceKnobs)) {
|
||||
ASSERT(false);
|
||||
return;
|
||||
}
|
||||
*static_cast<VulkanDeviceKnobs*>(&deviceInfo) = usedDeviceKnobs;
|
||||
|
||||
if (!functions->LoadDeviceProcs(vkDevice, usedDeviceKnobs)) {
|
||||
ASSERT(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Device::~Device() {
|
||||
if (vkDevice != VK_NULL_HANDLE) {
|
||||
fn.DestroyDevice(vkDevice, nullptr);
|
||||
vkDevice = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (debugReportCallback != VK_NULL_HANDLE) {
|
||||
fn.DestroyDebugReportCallbackEXT(instance, debugReportCallback, nullptr);
|
||||
debugReportCallback = VK_NULL_HANDLE;
|
||||
|
@ -160,18 +188,22 @@ namespace vulkan {
|
|||
void Device::TickImpl() {
|
||||
}
|
||||
|
||||
bool Device::CreateInstance(KnownGlobalVulkanExtensions* usedGlobals) {
|
||||
VkInstance Device::GetInstance() const {
|
||||
return instance;
|
||||
}
|
||||
|
||||
bool Device::CreateInstance(VulkanGlobalKnobs* usedKnobs) {
|
||||
std::vector<const char*> layersToRequest;
|
||||
std::vector<const char*> extensionsToRequest;
|
||||
|
||||
#if defined(NXT_ENABLE_ASSERTS)
|
||||
if (info.global.standardValidation) {
|
||||
if (globalInfo.standardValidation) {
|
||||
layersToRequest.push_back(kLayerNameLunargStandardValidation);
|
||||
usedGlobals->standardValidation = true;
|
||||
usedKnobs->standardValidation = true;
|
||||
}
|
||||
if (info.global.debugReport) {
|
||||
if (globalInfo.debugReport) {
|
||||
extensionsToRequest.push_back(kExtensionNameExtDebugReport);
|
||||
usedGlobals->debugReport = true;
|
||||
usedKnobs->debugReport = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -201,6 +233,66 @@ namespace vulkan {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Device::CreateDevice(VulkanDeviceKnobs* usedKnobs) {
|
||||
float zero = 0.0f;
|
||||
std::vector<const char*> layersToRequest;
|
||||
std::vector<const char*> extensionsToRequest;
|
||||
std::vector<VkDeviceQueueCreateInfo> queuesToRequest;
|
||||
|
||||
if (deviceInfo.swapchain) {
|
||||
extensionsToRequest.push_back(kExtensionNameKhrSwapchain);
|
||||
usedKnobs->swapchain = true;
|
||||
}
|
||||
|
||||
// Find a universal queue family
|
||||
{
|
||||
constexpr uint32_t kUniversalFlags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT;
|
||||
ssize_t universalQueueFamily = -1;
|
||||
for (size_t i = 0; i < deviceInfo.queueFamilies.size(); ++i) {
|
||||
if ((deviceInfo.queueFamilies[i].queueFlags & kUniversalFlags) == kUniversalFlags) {
|
||||
universalQueueFamily = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (universalQueueFamily == -1) {
|
||||
return false;
|
||||
}
|
||||
queueFamily = static_cast<uint32_t>(universalQueueFamily);
|
||||
}
|
||||
|
||||
// Choose to create a single universal queue
|
||||
{
|
||||
VkDeviceQueueCreateInfo queueCreateInfo;
|
||||
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||
queueCreateInfo.pNext = nullptr;
|
||||
queueCreateInfo.flags = 0;
|
||||
queueCreateInfo.queueFamilyIndex = static_cast<uint32_t>(queueFamily);
|
||||
queueCreateInfo.queueCount = 1;
|
||||
queueCreateInfo.pQueuePriorities = &zero;
|
||||
|
||||
queuesToRequest.push_back(queueCreateInfo);
|
||||
}
|
||||
|
||||
VkDeviceCreateInfo createInfo;
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||
createInfo.pNext = nullptr;
|
||||
createInfo.flags = 0;
|
||||
createInfo.queueCreateInfoCount = static_cast<uint32_t>(queuesToRequest.size());
|
||||
createInfo.pQueueCreateInfos = queuesToRequest.data();
|
||||
createInfo.enabledLayerCount = static_cast<uint32_t>(layersToRequest.size());
|
||||
createInfo.ppEnabledLayerNames = layersToRequest.data();
|
||||
createInfo.enabledExtensionCount = static_cast<uint32_t>(extensionsToRequest.size());
|
||||
createInfo.ppEnabledExtensionNames = extensionsToRequest.data();
|
||||
createInfo.pEnabledFeatures = &usedKnobs->features;
|
||||
|
||||
if (fn.CreateDevice(physicalDevice, &createInfo, nullptr, &vkDevice) != VK_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Device::RegisterDebugReport() {
|
||||
VkDebugReportCallbackCreateInfoEXT createInfo;
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
|
||||
|
@ -234,10 +326,6 @@ namespace vulkan {
|
|||
return const_cast<VulkanFunctions*>(&fn);
|
||||
}
|
||||
|
||||
VulkanInfo* Device::GetMutableInfo() {
|
||||
return const_cast<VulkanInfo*>(&info);
|
||||
}
|
||||
|
||||
// Buffer
|
||||
|
||||
Buffer::Buffer(BufferBuilder* builder)
|
||||
|
|
|
@ -121,13 +121,14 @@ namespace vulkan {
|
|||
|
||||
// Contains all the Vulkan entry points, vkDoFoo is called via device->fn.DoFoo.
|
||||
const VulkanFunctions fn;
|
||||
// All the information queried about this Vulkan system
|
||||
const VulkanInfo info;
|
||||
|
||||
VkInstance GetInstance() const;
|
||||
|
||||
private:
|
||||
bool CreateInstance(KnownGlobalVulkanExtensions* usedGlobals);
|
||||
bool RegisterDebugReport();
|
||||
bool CreateInstance(VulkanGlobalKnobs* usedKnobs);
|
||||
bool CreateDevice(VulkanDeviceKnobs* usedKnobs);
|
||||
|
||||
bool RegisterDebugReport();
|
||||
static VkBool32 OnDebugReportCallback(VkDebugReportFlagsEXT flags,
|
||||
VkDebugReportObjectTypeEXT objectType,
|
||||
uint64_t object,
|
||||
|
@ -140,11 +141,16 @@ namespace vulkan {
|
|||
// To make it easier to use fn it is a public const member. However
|
||||
// the Device is allowed to mutate them through these private methods.
|
||||
VulkanFunctions* GetMutableFunctions();
|
||||
VulkanInfo* GetMutableInfo();
|
||||
|
||||
VulkanGlobalInfo globalInfo;
|
||||
VulkanDeviceInfo deviceInfo;
|
||||
|
||||
DynamicLib vulkanLib;
|
||||
|
||||
VkInstance instance = VK_NULL_HANDLE;
|
||||
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
||||
VkDevice vkDevice = VK_NULL_HANDLE;
|
||||
uint32_t queueFamily = 0;
|
||||
VkDebugReportCallbackEXT debugReportCallback = VK_NULL_HANDLE;
|
||||
};
|
||||
|
||||
|
|
|
@ -32,7 +32,6 @@ namespace vulkan {
|
|||
}
|
||||
|
||||
GET_GLOBAL_PROC(CreateInstance);
|
||||
GET_GLOBAL_PROC(DestroyInstance);
|
||||
GET_GLOBAL_PROC(EnumerateInstanceExtensionProperties);
|
||||
GET_GLOBAL_PROC(EnumerateInstanceLayerProperties);
|
||||
|
||||
|
@ -45,12 +44,16 @@ namespace vulkan {
|
|||
return false; \
|
||||
}
|
||||
|
||||
bool VulkanFunctions::LoadInstanceProcs(VkInstance instance, const KnownGlobalVulkanExtensions& usedGlobals) {
|
||||
bool VulkanFunctions::LoadInstanceProcs(VkInstance instance, const VulkanGlobalKnobs& usedKnobs) {
|
||||
// Load this proc first so that we can destroy the instance even if some other GET_INSTANCE_PROC fails
|
||||
GET_INSTANCE_PROC(DestroyInstance);
|
||||
|
||||
GET_INSTANCE_PROC(CreateDevice);
|
||||
GET_INSTANCE_PROC(DestroyDevice);
|
||||
GET_INSTANCE_PROC(EnumerateDeviceExtensionProperties);
|
||||
GET_INSTANCE_PROC(EnumerateDeviceLayerProperties);
|
||||
GET_INSTANCE_PROC(EnumeratePhysicalDevices);
|
||||
GET_INSTANCE_PROC(GetDeviceProcAddr);
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceFeatures);
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceFormatProperties);
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceImageFormatProperties);
|
||||
|
@ -59,12 +62,158 @@ namespace vulkan {
|
|||
GET_INSTANCE_PROC(GetPhysicalDeviceQueueFamilyProperties);
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceSparseImageFormatProperties);
|
||||
|
||||
if (usedGlobals.debugReport) {
|
||||
if (usedKnobs.debugReport) {
|
||||
GET_INSTANCE_PROC(CreateDebugReportCallbackEXT);
|
||||
GET_INSTANCE_PROC(DebugReportMessageEXT);
|
||||
GET_INSTANCE_PROC(DestroyDebugReportCallbackEXT);
|
||||
}
|
||||
|
||||
if (usedKnobs.surface) {
|
||||
GET_INSTANCE_PROC(DestroySurfaceKHR);
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceSurfaceSupportKHR);
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceSurfaceCapabilitiesKHR);
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceSurfaceFormatsKHR);
|
||||
GET_INSTANCE_PROC(GetPhysicalDeviceSurfacePresentModesKHR);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define GET_DEVICE_PROC(name) \
|
||||
name = reinterpret_cast<decltype(name)>(GetDeviceProcAddr(device, "vk" #name)); \
|
||||
if (name == nullptr) { \
|
||||
return false; \
|
||||
}
|
||||
|
||||
bool VulkanFunctions::LoadDeviceProcs(VkDevice device, const VulkanDeviceKnobs& usedKnobs) {
|
||||
GET_DEVICE_PROC(AllocateCommandBuffers);
|
||||
GET_DEVICE_PROC(AllocateDescriptorSets);
|
||||
GET_DEVICE_PROC(AllocateMemory);
|
||||
GET_DEVICE_PROC(BeginCommandBuffer);
|
||||
GET_DEVICE_PROC(BindBufferMemory);
|
||||
GET_DEVICE_PROC(BindImageMemory);
|
||||
GET_DEVICE_PROC(CmdBeginQuery);
|
||||
GET_DEVICE_PROC(CmdBeginRenderPass);
|
||||
GET_DEVICE_PROC(CmdBindDescriptorSets);
|
||||
GET_DEVICE_PROC(CmdBindIndexBuffer);
|
||||
GET_DEVICE_PROC(CmdBindPipeline);
|
||||
GET_DEVICE_PROC(CmdBindVertexBuffers);
|
||||
GET_DEVICE_PROC(CmdBlitImage);
|
||||
GET_DEVICE_PROC(CmdClearAttachments);
|
||||
GET_DEVICE_PROC(CmdClearColorImage);
|
||||
GET_DEVICE_PROC(CmdClearDepthStencilImage);
|
||||
GET_DEVICE_PROC(CmdCopyBuffer);
|
||||
GET_DEVICE_PROC(CmdCopyBufferToImage);
|
||||
GET_DEVICE_PROC(CmdCopyImage);
|
||||
GET_DEVICE_PROC(CmdCopyImageToBuffer);
|
||||
GET_DEVICE_PROC(CmdCopyQueryPoolResults);
|
||||
GET_DEVICE_PROC(CmdDispatch);
|
||||
GET_DEVICE_PROC(CmdDispatchIndirect);
|
||||
GET_DEVICE_PROC(CmdDraw);
|
||||
GET_DEVICE_PROC(CmdDrawIndexed);
|
||||
GET_DEVICE_PROC(CmdDrawIndexedIndirect);
|
||||
GET_DEVICE_PROC(CmdDrawIndirect);
|
||||
GET_DEVICE_PROC(CmdEndQuery);
|
||||
GET_DEVICE_PROC(CmdEndRenderPass);
|
||||
GET_DEVICE_PROC(CmdExecuteCommands);
|
||||
GET_DEVICE_PROC(CmdFillBuffer);
|
||||
GET_DEVICE_PROC(CmdNextSubpass);
|
||||
GET_DEVICE_PROC(CmdPipelineBarrier);
|
||||
GET_DEVICE_PROC(CmdPushConstants);
|
||||
GET_DEVICE_PROC(CmdResetEvent);
|
||||
GET_DEVICE_PROC(CmdResetQueryPool);
|
||||
GET_DEVICE_PROC(CmdResolveImage);
|
||||
GET_DEVICE_PROC(CmdSetBlendConstants);
|
||||
GET_DEVICE_PROC(CmdSetDepthBias);
|
||||
GET_DEVICE_PROC(CmdSetDepthBounds);
|
||||
GET_DEVICE_PROC(CmdSetEvent);
|
||||
GET_DEVICE_PROC(CmdSetLineWidth);
|
||||
GET_DEVICE_PROC(CmdSetScissor);
|
||||
GET_DEVICE_PROC(CmdSetStencilCompareMask);
|
||||
GET_DEVICE_PROC(CmdSetStencilReference);
|
||||
GET_DEVICE_PROC(CmdSetStencilWriteMask);
|
||||
GET_DEVICE_PROC(CmdSetViewport);
|
||||
GET_DEVICE_PROC(CmdUpdateBuffer);
|
||||
GET_DEVICE_PROC(CmdWaitEvents);
|
||||
GET_DEVICE_PROC(CmdWriteTimestamp);
|
||||
GET_DEVICE_PROC(CreateBuffer);
|
||||
GET_DEVICE_PROC(CreateBufferView);
|
||||
GET_DEVICE_PROC(CreateCommandPool);
|
||||
GET_DEVICE_PROC(CreateComputePipelines);
|
||||
GET_DEVICE_PROC(CreateDescriptorPool);
|
||||
GET_DEVICE_PROC(CreateDescriptorSetLayout);
|
||||
GET_DEVICE_PROC(CreateEvent);
|
||||
GET_DEVICE_PROC(CreateFence);
|
||||
GET_DEVICE_PROC(CreateFramebuffer);
|
||||
GET_DEVICE_PROC(CreateGraphicsPipelines);
|
||||
GET_DEVICE_PROC(CreateImage);
|
||||
GET_DEVICE_PROC(CreateImageView);
|
||||
GET_DEVICE_PROC(CreatePipelineCache);
|
||||
GET_DEVICE_PROC(CreatePipelineLayout);
|
||||
GET_DEVICE_PROC(CreateQueryPool);
|
||||
GET_DEVICE_PROC(CreateRenderPass);
|
||||
GET_DEVICE_PROC(CreateSampler);
|
||||
GET_DEVICE_PROC(CreateSemaphore);
|
||||
GET_DEVICE_PROC(CreateShaderModule);
|
||||
GET_DEVICE_PROC(DestroyBuffer);
|
||||
GET_DEVICE_PROC(DestroyBufferView);
|
||||
GET_DEVICE_PROC(DestroyCommandPool);
|
||||
GET_DEVICE_PROC(DestroyDescriptorPool);
|
||||
GET_DEVICE_PROC(DestroyDescriptorSetLayout);
|
||||
GET_DEVICE_PROC(DestroyEvent);
|
||||
GET_DEVICE_PROC(DestroyFence);
|
||||
GET_DEVICE_PROC(DestroyFramebuffer);
|
||||
GET_DEVICE_PROC(DestroyImage);
|
||||
GET_DEVICE_PROC(DestroyImageView);
|
||||
GET_DEVICE_PROC(DestroyPipeline);
|
||||
GET_DEVICE_PROC(DestroyPipelineCache);
|
||||
GET_DEVICE_PROC(DestroyPipelineLayout);
|
||||
GET_DEVICE_PROC(DestroyQueryPool);
|
||||
GET_DEVICE_PROC(DestroyRenderPass);
|
||||
GET_DEVICE_PROC(DestroySampler);
|
||||
GET_DEVICE_PROC(DestroySemaphore);
|
||||
GET_DEVICE_PROC(DestroyShaderModule);
|
||||
GET_DEVICE_PROC(DeviceWaitIdle);
|
||||
GET_DEVICE_PROC(EndCommandBuffer);
|
||||
GET_DEVICE_PROC(FlushMappedMemoryRanges);
|
||||
GET_DEVICE_PROC(FreeCommandBuffers);
|
||||
GET_DEVICE_PROC(FreeDescriptorSets);
|
||||
GET_DEVICE_PROC(FreeMemory);
|
||||
GET_DEVICE_PROC(GetBufferMemoryRequirements);
|
||||
GET_DEVICE_PROC(GetDeviceMemoryCommitment);
|
||||
GET_DEVICE_PROC(GetDeviceQueue);
|
||||
GET_DEVICE_PROC(GetEventStatus);
|
||||
GET_DEVICE_PROC(GetFenceStatus);
|
||||
GET_DEVICE_PROC(GetImageMemoryRequirements);
|
||||
GET_DEVICE_PROC(GetImageSparseMemoryRequirements);
|
||||
GET_DEVICE_PROC(GetImageSubresourceLayout);
|
||||
GET_DEVICE_PROC(GetPipelineCacheData);
|
||||
GET_DEVICE_PROC(GetQueryPoolResults);
|
||||
GET_DEVICE_PROC(GetRenderAreaGranularity);
|
||||
GET_DEVICE_PROC(InvalidateMappedMemoryRanges);
|
||||
GET_DEVICE_PROC(MapMemory);
|
||||
GET_DEVICE_PROC(MergePipelineCaches);
|
||||
GET_DEVICE_PROC(QueueBindSparse);
|
||||
GET_DEVICE_PROC(QueueSubmit);
|
||||
GET_DEVICE_PROC(QueueWaitIdle);
|
||||
GET_DEVICE_PROC(ResetCommandBuffer);
|
||||
GET_DEVICE_PROC(ResetCommandPool);
|
||||
GET_DEVICE_PROC(ResetDescriptorPool);
|
||||
GET_DEVICE_PROC(ResetEvent);
|
||||
GET_DEVICE_PROC(ResetFences);
|
||||
GET_DEVICE_PROC(SetEvent);
|
||||
GET_DEVICE_PROC(UnmapMemory);
|
||||
GET_DEVICE_PROC(UpdateDescriptorSets);
|
||||
GET_DEVICE_PROC(WaitForFences);
|
||||
|
||||
if (usedKnobs.swapchain) {
|
||||
GET_DEVICE_PROC(CreateSwapchainKHR);
|
||||
GET_DEVICE_PROC(DestroySwapchainKHR);
|
||||
GET_DEVICE_PROC(GetSwapchainImagesKHR);
|
||||
GET_DEVICE_PROC(AcquireNextImageKHR);
|
||||
GET_DEVICE_PROC(QueuePresentKHR);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,18 +22,21 @@ class DynamicLib;
|
|||
namespace backend {
|
||||
namespace vulkan {
|
||||
|
||||
struct KnownGlobalVulkanExtensions;
|
||||
struct VulkanGlobalKnobs;
|
||||
struct VulkanDeviceKnobs;
|
||||
|
||||
// Stores the Vulkan entry points. Also loads them from the dynamic library
|
||||
// and the vkGet*ProcAddress entry points.
|
||||
struct VulkanFunctions {
|
||||
bool LoadGlobalProcs(const DynamicLib& vulkanLib);
|
||||
bool LoadInstanceProcs(VkInstance instance, const KnownGlobalVulkanExtensions& usedGlobals);
|
||||
bool LoadInstanceProcs(VkInstance instance, const VulkanGlobalKnobs& usedGlobals);
|
||||
bool LoadDeviceProcs(VkDevice device, const VulkanDeviceKnobs& usedKnobs);
|
||||
|
||||
// ---------- Global procs
|
||||
|
||||
// Initial proc from which we can get all the others
|
||||
PFN_vkGetInstanceProcAddr GetInstanceProcAddr = nullptr;
|
||||
|
||||
// Global procs, can be used without an instance
|
||||
PFN_vkCreateInstance CreateInstance = nullptr;
|
||||
PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties = nullptr;
|
||||
PFN_vkEnumerateInstanceLayerProperties EnumerateInstanceLayerProperties = nullptr;
|
||||
|
@ -41,11 +44,14 @@ namespace vulkan {
|
|||
// before querying the instance procs in case we need to error out during initialization.
|
||||
PFN_vkDestroyInstance DestroyInstance = nullptr;
|
||||
|
||||
// Instance procs
|
||||
// ---------- Instance procs
|
||||
|
||||
// Core Vulkan 1.0
|
||||
PFN_vkCreateDevice CreateDevice = nullptr;
|
||||
PFN_vkEnumerateDeviceExtensionProperties EnumerateDeviceExtensionProperties = nullptr;
|
||||
PFN_vkEnumerateDeviceLayerProperties EnumerateDeviceLayerProperties = nullptr;
|
||||
PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices = nullptr;
|
||||
PFN_vkGetDeviceProcAddr GetDeviceProcAddr = nullptr;
|
||||
PFN_vkGetPhysicalDeviceFeatures GetPhysicalDeviceFeatures = nullptr;
|
||||
PFN_vkGetPhysicalDeviceFormatProperties GetPhysicalDeviceFormatProperties = nullptr;
|
||||
PFN_vkGetPhysicalDeviceImageFormatProperties GetPhysicalDeviceImageFormatProperties = nullptr;
|
||||
|
@ -61,8 +67,144 @@ namespace vulkan {
|
|||
PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT = nullptr;
|
||||
PFN_vkDebugReportMessageEXT DebugReportMessageEXT = nullptr;
|
||||
PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallbackEXT = nullptr;
|
||||
};
|
||||
|
||||
// VK_KHR_surface
|
||||
PFN_vkDestroySurfaceKHR DestroySurfaceKHR = nullptr;
|
||||
PFN_vkGetPhysicalDeviceSurfaceSupportKHR GetPhysicalDeviceSurfaceSupportKHR = nullptr;
|
||||
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR GetPhysicalDeviceSurfaceCapabilitiesKHR = nullptr;
|
||||
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR GetPhysicalDeviceSurfaceFormatsKHR = nullptr;
|
||||
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR GetPhysicalDeviceSurfacePresentModesKHR = nullptr;
|
||||
|
||||
// ---------- Device procs
|
||||
|
||||
// Core Vulkan 1.0
|
||||
PFN_vkAllocateCommandBuffers AllocateCommandBuffers = nullptr;
|
||||
PFN_vkAllocateDescriptorSets AllocateDescriptorSets = nullptr;
|
||||
PFN_vkAllocateMemory AllocateMemory = nullptr;
|
||||
PFN_vkBeginCommandBuffer BeginCommandBuffer = nullptr;
|
||||
PFN_vkBindBufferMemory BindBufferMemory = nullptr;
|
||||
PFN_vkBindImageMemory BindImageMemory = nullptr;
|
||||
PFN_vkCmdBeginQuery CmdBeginQuery = nullptr;
|
||||
PFN_vkCmdBeginRenderPass CmdBeginRenderPass = nullptr;
|
||||
PFN_vkCmdBindDescriptorSets CmdBindDescriptorSets = nullptr;
|
||||
PFN_vkCmdBindIndexBuffer CmdBindIndexBuffer = nullptr;
|
||||
PFN_vkCmdBindPipeline CmdBindPipeline = nullptr;
|
||||
PFN_vkCmdBindVertexBuffers CmdBindVertexBuffers = nullptr;
|
||||
PFN_vkCmdBlitImage CmdBlitImage = nullptr;
|
||||
PFN_vkCmdClearAttachments CmdClearAttachments = nullptr;
|
||||
PFN_vkCmdClearColorImage CmdClearColorImage = nullptr;
|
||||
PFN_vkCmdClearDepthStencilImage CmdClearDepthStencilImage = nullptr;
|
||||
PFN_vkCmdCopyBuffer CmdCopyBuffer = nullptr;
|
||||
PFN_vkCmdCopyBufferToImage CmdCopyBufferToImage = nullptr;
|
||||
PFN_vkCmdCopyImage CmdCopyImage = nullptr;
|
||||
PFN_vkCmdCopyImageToBuffer CmdCopyImageToBuffer = nullptr;
|
||||
PFN_vkCmdCopyQueryPoolResults CmdCopyQueryPoolResults = nullptr;
|
||||
PFN_vkCmdDispatch CmdDispatch = nullptr;
|
||||
PFN_vkCmdDispatchIndirect CmdDispatchIndirect = nullptr;
|
||||
PFN_vkCmdDraw CmdDraw = nullptr;
|
||||
PFN_vkCmdDrawIndexed CmdDrawIndexed = nullptr;
|
||||
PFN_vkCmdDrawIndexedIndirect CmdDrawIndexedIndirect = nullptr;
|
||||
PFN_vkCmdDrawIndirect CmdDrawIndirect = nullptr;
|
||||
PFN_vkCmdEndQuery CmdEndQuery = nullptr;
|
||||
PFN_vkCmdEndRenderPass CmdEndRenderPass = nullptr;
|
||||
PFN_vkCmdExecuteCommands CmdExecuteCommands = nullptr;
|
||||
PFN_vkCmdFillBuffer CmdFillBuffer = nullptr;
|
||||
PFN_vkCmdNextSubpass CmdNextSubpass = nullptr;
|
||||
PFN_vkCmdPipelineBarrier CmdPipelineBarrier = nullptr;
|
||||
PFN_vkCmdPushConstants CmdPushConstants = nullptr;
|
||||
PFN_vkCmdResetEvent CmdResetEvent = nullptr;
|
||||
PFN_vkCmdResetQueryPool CmdResetQueryPool = nullptr;
|
||||
PFN_vkCmdResolveImage CmdResolveImage = nullptr;
|
||||
PFN_vkCmdSetBlendConstants CmdSetBlendConstants = nullptr;
|
||||
PFN_vkCmdSetDepthBias CmdSetDepthBias = nullptr;
|
||||
PFN_vkCmdSetDepthBounds CmdSetDepthBounds = nullptr;
|
||||
PFN_vkCmdSetEvent CmdSetEvent = nullptr;
|
||||
PFN_vkCmdSetLineWidth CmdSetLineWidth = nullptr;
|
||||
PFN_vkCmdSetScissor CmdSetScissor = nullptr;
|
||||
PFN_vkCmdSetStencilCompareMask CmdSetStencilCompareMask = nullptr;
|
||||
PFN_vkCmdSetStencilReference CmdSetStencilReference = nullptr;
|
||||
PFN_vkCmdSetStencilWriteMask CmdSetStencilWriteMask = nullptr;
|
||||
PFN_vkCmdSetViewport CmdSetViewport = nullptr;
|
||||
PFN_vkCmdUpdateBuffer CmdUpdateBuffer = nullptr;
|
||||
PFN_vkCmdWaitEvents CmdWaitEvents = nullptr;
|
||||
PFN_vkCmdWriteTimestamp CmdWriteTimestamp = nullptr;
|
||||
PFN_vkCreateBuffer CreateBuffer = nullptr;
|
||||
PFN_vkCreateBufferView CreateBufferView = nullptr;
|
||||
PFN_vkCreateCommandPool CreateCommandPool = nullptr;
|
||||
PFN_vkCreateComputePipelines CreateComputePipelines = nullptr;
|
||||
PFN_vkCreateDescriptorPool CreateDescriptorPool = nullptr;
|
||||
PFN_vkCreateDescriptorSetLayout CreateDescriptorSetLayout = nullptr;
|
||||
PFN_vkCreateEvent CreateEvent = nullptr;
|
||||
PFN_vkCreateFence CreateFence = nullptr;
|
||||
PFN_vkCreateFramebuffer CreateFramebuffer = nullptr;
|
||||
PFN_vkCreateGraphicsPipelines CreateGraphicsPipelines = nullptr;
|
||||
PFN_vkCreateImage CreateImage = nullptr;
|
||||
PFN_vkCreateImageView CreateImageView = nullptr;
|
||||
PFN_vkCreatePipelineCache CreatePipelineCache = nullptr;
|
||||
PFN_vkCreatePipelineLayout CreatePipelineLayout = nullptr;
|
||||
PFN_vkCreateQueryPool CreateQueryPool = nullptr;
|
||||
PFN_vkCreateRenderPass CreateRenderPass = nullptr;
|
||||
PFN_vkCreateSampler CreateSampler = nullptr;
|
||||
PFN_vkCreateSemaphore CreateSemaphore = nullptr;
|
||||
PFN_vkCreateShaderModule CreateShaderModule = nullptr;
|
||||
PFN_vkDestroyBuffer DestroyBuffer = nullptr;
|
||||
PFN_vkDestroyBufferView DestroyBufferView = nullptr;
|
||||
PFN_vkDestroyCommandPool DestroyCommandPool = nullptr;
|
||||
PFN_vkDestroyDescriptorPool DestroyDescriptorPool = nullptr;
|
||||
PFN_vkDestroyDescriptorSetLayout DestroyDescriptorSetLayout = nullptr;
|
||||
PFN_vkDestroyEvent DestroyEvent = nullptr;
|
||||
PFN_vkDestroyFence DestroyFence = nullptr;
|
||||
PFN_vkDestroyFramebuffer DestroyFramebuffer = nullptr;
|
||||
PFN_vkDestroyImage DestroyImage = nullptr;
|
||||
PFN_vkDestroyImageView DestroyImageView = nullptr;
|
||||
PFN_vkDestroyPipeline DestroyPipeline = nullptr;
|
||||
PFN_vkDestroyPipelineCache DestroyPipelineCache = nullptr;
|
||||
PFN_vkDestroyPipelineLayout DestroyPipelineLayout = nullptr;
|
||||
PFN_vkDestroyQueryPool DestroyQueryPool = nullptr;
|
||||
PFN_vkDestroyRenderPass DestroyRenderPass = nullptr;
|
||||
PFN_vkDestroySampler DestroySampler = nullptr;
|
||||
PFN_vkDestroySemaphore DestroySemaphore = nullptr;
|
||||
PFN_vkDestroyShaderModule DestroyShaderModule = nullptr;
|
||||
PFN_vkDeviceWaitIdle DeviceWaitIdle = nullptr;
|
||||
PFN_vkEndCommandBuffer EndCommandBuffer = nullptr;
|
||||
PFN_vkFlushMappedMemoryRanges FlushMappedMemoryRanges = nullptr;
|
||||
PFN_vkFreeCommandBuffers FreeCommandBuffers = nullptr;
|
||||
PFN_vkFreeDescriptorSets FreeDescriptorSets = nullptr;
|
||||
PFN_vkFreeMemory FreeMemory = nullptr;
|
||||
PFN_vkGetBufferMemoryRequirements GetBufferMemoryRequirements = nullptr;
|
||||
PFN_vkGetDeviceMemoryCommitment GetDeviceMemoryCommitment = nullptr;
|
||||
PFN_vkGetDeviceQueue GetDeviceQueue = nullptr;
|
||||
PFN_vkGetEventStatus GetEventStatus = nullptr;
|
||||
PFN_vkGetFenceStatus GetFenceStatus = nullptr;
|
||||
PFN_vkGetImageMemoryRequirements GetImageMemoryRequirements = nullptr;
|
||||
PFN_vkGetImageSparseMemoryRequirements GetImageSparseMemoryRequirements = nullptr;
|
||||
PFN_vkGetImageSubresourceLayout GetImageSubresourceLayout = nullptr;
|
||||
PFN_vkGetPipelineCacheData GetPipelineCacheData = nullptr;
|
||||
PFN_vkGetQueryPoolResults GetQueryPoolResults = nullptr;
|
||||
PFN_vkGetRenderAreaGranularity GetRenderAreaGranularity = nullptr;
|
||||
PFN_vkInvalidateMappedMemoryRanges InvalidateMappedMemoryRanges = nullptr;
|
||||
PFN_vkMapMemory MapMemory = nullptr;
|
||||
PFN_vkMergePipelineCaches MergePipelineCaches = nullptr;
|
||||
PFN_vkQueueBindSparse QueueBindSparse = nullptr;
|
||||
PFN_vkQueueSubmit QueueSubmit = nullptr;
|
||||
PFN_vkQueueWaitIdle QueueWaitIdle = nullptr;
|
||||
PFN_vkResetCommandBuffer ResetCommandBuffer = nullptr;
|
||||
PFN_vkResetCommandPool ResetCommandPool = nullptr;
|
||||
PFN_vkResetDescriptorPool ResetDescriptorPool = nullptr;
|
||||
PFN_vkResetEvent ResetEvent = nullptr;
|
||||
PFN_vkResetFences ResetFences = nullptr;
|
||||
PFN_vkSetEvent SetEvent = nullptr;
|
||||
PFN_vkUnmapMemory UnmapMemory = nullptr;
|
||||
PFN_vkUpdateDescriptorSets UpdateDescriptorSets = nullptr;
|
||||
PFN_vkWaitForFences WaitForFences = nullptr;
|
||||
|
||||
// VK_KHR_swapchain
|
||||
PFN_vkCreateSwapchainKHR CreateSwapchainKHR = nullptr;
|
||||
PFN_vkDestroySwapchainKHR DestroySwapchainKHR = nullptr;
|
||||
PFN_vkGetSwapchainImagesKHR GetSwapchainImagesKHR = nullptr;
|
||||
PFN_vkAcquireNextImageKHR AcquireNextImageKHR = nullptr;
|
||||
PFN_vkQueuePresentKHR QueuePresentKHR = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,8 +34,10 @@ namespace vulkan {
|
|||
const char kLayerNameLunargStandardValidation[] = "VK_LAYER_LUNARG_standard_validation";
|
||||
|
||||
const char kExtensionNameExtDebugReport[] = "VK_EXT_debug_report";
|
||||
const char kExtensionNameKhrSurface[] = "VK_KHR_surface";
|
||||
const char kExtensionNameKhrSwapchain[] = "VK_KHR_swapchain";
|
||||
|
||||
bool VulkanInfo::GatherGlobalInfo(const Device& device) {
|
||||
bool GatherGlobalInfo(const Device& device, VulkanGlobalInfo* info) {
|
||||
// Gather the info about the instance layers
|
||||
{
|
||||
uint32_t count = 0;
|
||||
|
@ -47,15 +49,15 @@ namespace vulkan {
|
|||
return false;
|
||||
}
|
||||
|
||||
global.layers.resize(count);
|
||||
result = device.fn.EnumerateInstanceLayerProperties(&count, global.layers.data());
|
||||
info->layers.resize(count);
|
||||
result = device.fn.EnumerateInstanceLayerProperties(&count, info->layers.data());
|
||||
if (result != VK_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto& layer : global.layers) {
|
||||
for (const auto& layer : info->layers) {
|
||||
if (IsLayerName(layer, kLayerNameLunargStandardValidation)) {
|
||||
global.standardValidation = true;
|
||||
info->standardValidation = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,15 +70,18 @@ namespace vulkan {
|
|||
return false;
|
||||
}
|
||||
|
||||
global.extensions.resize(count);
|
||||
result = device.fn.EnumerateInstanceExtensionProperties(nullptr, &count, global.extensions.data());
|
||||
info->extensions.resize(count);
|
||||
result = device.fn.EnumerateInstanceExtensionProperties(nullptr, &count, info->extensions.data());
|
||||
if (result != VK_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto& extension : global.extensions) {
|
||||
for (const auto& extension : info->extensions) {
|
||||
if (IsExtensionName(extension, kExtensionNameExtDebugReport)) {
|
||||
global.debugReport = true;
|
||||
info->debugReport = true;
|
||||
}
|
||||
if (IsExtensionName(extension, kExtensionNameKhrSurface)) {
|
||||
info->surface = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -86,8 +91,87 @@ namespace vulkan {
|
|||
return true;
|
||||
}
|
||||
|
||||
void VulkanInfo::SetUsedGlobals(const KnownGlobalVulkanExtensions& usedGlobals) {
|
||||
*static_cast<KnownGlobalVulkanExtensions*>(&global) = usedGlobals;
|
||||
bool GetPhysicalDevices(const Device& device, std::vector<VkPhysicalDevice>* physicalDevices) {
|
||||
VkInstance instance = device.GetInstance();
|
||||
|
||||
uint32_t count = 0;
|
||||
VkResult result = device.fn.EnumeratePhysicalDevices(instance, &count, nullptr);
|
||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
physicalDevices->resize(count);
|
||||
result = device.fn.EnumeratePhysicalDevices(instance, &count, physicalDevices->data());
|
||||
if (result != VK_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GatherDeviceInfo(const Device& device, VkPhysicalDevice physicalDevice, VulkanDeviceInfo* info) {
|
||||
// Gather general info about the device
|
||||
device.fn.GetPhysicalDeviceProperties(physicalDevice, &info->properties);
|
||||
device.fn.GetPhysicalDeviceFeatures(physicalDevice, &info->features);
|
||||
|
||||
// Gather info about device memory.
|
||||
{
|
||||
VkPhysicalDeviceMemoryProperties memory;
|
||||
device.fn.GetPhysicalDeviceMemoryProperties(physicalDevice, &memory);
|
||||
|
||||
info->memoryTypes.assign(memory.memoryTypes, memory.memoryTypes + memory.memoryTypeCount);
|
||||
info->memoryHeaps.assign(memory.memoryHeaps, memory.memoryHeaps + memory.memoryHeapCount);
|
||||
}
|
||||
|
||||
// Gather info about device queue families
|
||||
{
|
||||
uint32_t count = 0;
|
||||
device.fn.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count, nullptr);
|
||||
|
||||
info->queueFamilies.resize(count);
|
||||
device.fn.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, &count, info->queueFamilies.data());
|
||||
}
|
||||
|
||||
// Gather the info about the device layers
|
||||
{
|
||||
uint32_t count = 0;
|
||||
VkResult result = device.fn.EnumerateDeviceLayerProperties(physicalDevice, &count, nullptr);
|
||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
info->layers.resize(count);
|
||||
result = device.fn.EnumerateDeviceLayerProperties(physicalDevice, &count, info->layers.data());
|
||||
if (result != VK_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Gather the info about the device extensions
|
||||
{
|
||||
uint32_t count = 0;
|
||||
VkResult result = device.fn.EnumerateDeviceExtensionProperties(physicalDevice, nullptr, &count, nullptr);
|
||||
if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
info->extensions.resize(count);
|
||||
result = device.fn.EnumerateDeviceExtensionProperties(physicalDevice, nullptr, &count, info->extensions.data());
|
||||
if (result != VK_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto& extension : info->extensions) {
|
||||
if (IsExtensionName(extension, kExtensionNameKhrSwapchain)) {
|
||||
info->swapchain = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(cwallez@chromium.org): gather info about formats
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,29 +27,48 @@ namespace vulkan {
|
|||
extern const char kLayerNameLunargStandardValidation[];
|
||||
|
||||
extern const char kExtensionNameExtDebugReport[];
|
||||
extern const char kExtensionNameKhrSurface[];
|
||||
extern const char kExtensionNameKhrSwapchain[];
|
||||
|
||||
struct KnownGlobalVulkanExtensions {
|
||||
// Global information - gathered before the instance is created
|
||||
struct VulkanGlobalKnobs {
|
||||
// Layers
|
||||
bool standardValidation = false;
|
||||
|
||||
// Extensions
|
||||
bool debugReport = false;
|
||||
bool surface = false;
|
||||
};
|
||||
|
||||
// Stores the information about the Vulkan system that are required to use Vulkan.
|
||||
// Also does the querying of the information.
|
||||
struct VulkanInfo {
|
||||
// Global information - gathered before the instance is created
|
||||
struct : KnownGlobalVulkanExtensions {
|
||||
struct VulkanGlobalInfo : VulkanGlobalKnobs {
|
||||
std::vector<VkLayerProperties> layers;
|
||||
std::vector<VkExtensionProperties> extensions;
|
||||
// TODO(cwallez@chromium.org): layer instance extensions
|
||||
} global;
|
||||
|
||||
bool GatherGlobalInfo(const Device& device);
|
||||
void SetUsedGlobals(const KnownGlobalVulkanExtensions& usedGlobals);
|
||||
};
|
||||
|
||||
// Device information - gathered before the device is created.
|
||||
struct VulkanDeviceKnobs {
|
||||
VkPhysicalDeviceFeatures features;
|
||||
|
||||
// Extensions
|
||||
bool swapchain = false;
|
||||
};
|
||||
|
||||
struct VulkanDeviceInfo : VulkanDeviceKnobs {
|
||||
VkPhysicalDeviceProperties properties;
|
||||
std::vector<VkQueueFamilyProperties> queueFamilies;
|
||||
|
||||
std::vector<VkMemoryType> memoryTypes;
|
||||
std::vector<VkMemoryHeap> memoryHeaps;
|
||||
|
||||
std::vector<VkLayerProperties> layers;
|
||||
std::vector<VkExtensionProperties> extensions;
|
||||
// TODO(cwallez@chromium.org): layer instance extensions
|
||||
};
|
||||
|
||||
bool GatherGlobalInfo(const Device& device, VulkanGlobalInfo* info);
|
||||
bool GetPhysicalDevices(const Device& device, std::vector<VkPhysicalDevice>* physicalDevices);
|
||||
bool GatherDeviceInfo(const Device& device, VkPhysicalDevice physicalDevice, VulkanDeviceInfo* info);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue