Vulkan: Create device and load all entry points

This commit is contained in:
Corentin Wallez 2017-11-21 12:52:03 -05:00 committed by Corentin Wallez
parent f40d8c545c
commit 0216233a83
6 changed files with 546 additions and 58 deletions

View File

@ -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)

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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;
};
}
}

View File

@ -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;
}
}
}

View File

@ -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 {
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);
struct VulkanGlobalInfo : VulkanGlobalKnobs {
std::vector<VkLayerProperties> layers;
std::vector<VkExtensionProperties> extensions;
// TODO(cwallez@chromium.org): layer instance extensions
};
// 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);
}
}