From ae261614c64f1be32952ddbd23ba9ec0200cadbf Mon Sep 17 00:00:00 2001 From: hyzboy Date: Tue, 9 Apr 2019 02:02:43 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=B0=81=E8=A3=85Vulkan?= =?UTF-8?q?=E7=9A=84Instance,PhysicalDevice,Device,CommandBuffer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example/Vulkan/CMakeLists.txt | 5 +- example/Vulkan/VK.h | 9 ++++ example/Vulkan/VKCommandBuffer.cpp | 9 ++++ example/Vulkan/VKCommandBuffer.h | 19 +++++++ example/Vulkan/VKDevice.cpp | 53 +++++++++++++++++++ example/Vulkan/VKDevice.h | 27 ++++++++++ example/Vulkan/VKInstance.cpp | 19 +++++++ example/Vulkan/VKInstance.h | 11 ++-- example/Vulkan/VKPhysicalDevice.cpp | 82 +++++++++++++++++++++++++++++ example/Vulkan/VKPhysicalDevice.h | 34 ++++++++++++ example/Vulkan/main.cpp | 19 ++++++- 11 files changed, 280 insertions(+), 7 deletions(-) create mode 100644 example/Vulkan/VK.h create mode 100644 example/Vulkan/VKCommandBuffer.cpp create mode 100644 example/Vulkan/VKCommandBuffer.h create mode 100644 example/Vulkan/VKDevice.cpp create mode 100644 example/Vulkan/VKDevice.h create mode 100644 example/Vulkan/VKPhysicalDevice.cpp create mode 100644 example/Vulkan/VKPhysicalDevice.h diff --git a/example/Vulkan/CMakeLists.txt b/example/Vulkan/CMakeLists.txt index bee6fa13..511c0547 100644 --- a/example/Vulkan/CMakeLists.txt +++ b/example/Vulkan/CMakeLists.txt @@ -1,4 +1,7 @@ add_executable(VulkanTest main.cpp - VKInstance.cpp) + VKInstance.cpp + VKPhysicalDevice.cpp + VKDevice.cpp + VKCommandBuffer.cpp) target_link_libraries(VulkanTest PRIVATE ${ULRE} ${VULKAN_LIB}) diff --git a/example/Vulkan/VK.h b/example/Vulkan/VK.h new file mode 100644 index 00000000..4eab5f90 --- /dev/null +++ b/example/Vulkan/VK.h @@ -0,0 +1,9 @@ +#ifndef HGL_GRAPH_VULKAN_INCLUDE +#define HGL_GRAPH_VULKAN_INCLUDE + +#include + +#define VK_NAMESPACE_BEGIN namespace hgl{namespace graph{namespace vulkan{ +#define VK_NAMESPACE_END }}} + +#endif//HGL_GRAPH_VULKAN_INCLUDE diff --git a/example/Vulkan/VKCommandBuffer.cpp b/example/Vulkan/VKCommandBuffer.cpp new file mode 100644 index 00000000..f04d5dc8 --- /dev/null +++ b/example/Vulkan/VKCommandBuffer.cpp @@ -0,0 +1,9 @@ +#include"VKCommandBuffer.h" + +VK_NAMESPACE_BEGIN +CommandBuffer::~CommandBuffer() +{ + VkCommandBuffer cmd_bufs[1] = {buf}; + vkFreeCommandBuffers(device, pool, 1, cmd_bufs); +} +VK_NAMESPACE_END diff --git a/example/Vulkan/VKCommandBuffer.h b/example/Vulkan/VKCommandBuffer.h new file mode 100644 index 00000000..37bba7f6 --- /dev/null +++ b/example/Vulkan/VKCommandBuffer.h @@ -0,0 +1,19 @@ +#ifndef HGL_GRAPH_VULKAN_COMMAND_BUFFER_INCLUDE +#define HGL_GRAPH_VULKAN_COMMAND_BUFFER_INCLUDE + +#include"VK.h" + +VK_NAMESPACE_BEGIN + class CommandBuffer + { + VkDevice device; + VkCommandPool pool; + VkCommandBuffer buf; + + public: + + CommandBuffer(VkDevice dev,VkCommandPool cp,VkCommandBuffer cb){device=dev;pool=cp;buf=cb;} + ~CommandBuffer(); + };//class CommandBuffer +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_COMMAND_BUFFER_INCLUDE diff --git a/example/Vulkan/VKDevice.cpp b/example/Vulkan/VKDevice.cpp new file mode 100644 index 00000000..5d7025d9 --- /dev/null +++ b/example/Vulkan/VKDevice.cpp @@ -0,0 +1,53 @@ +#include"VKDevice.h" +#include"VKCommandBuffer.h" + +VK_NAMESPACE_BEGIN +Device::Device(VkDevice dev,int family_index) +{ + device=dev; + + cmd_pool=nullptr; + + if(!device) + return; + + { + VkCommandPoolCreateInfo cmd_pool_info = {}; + + cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + cmd_pool_info.pNext = NULL; + cmd_pool_info.queueFamilyIndex = family_index; + cmd_pool_info.flags = 0; + + VkResult res = vkCreateCommandPool(device, &cmd_pool_info, nullptr, &cmd_pool); + } +} + +Device::~Device() +{ + vkDestroyCommandPool(device,cmd_pool,nullptr); + vkDestroyDevice(device,nullptr); +} + +CommandBuffer *Device::CreateCommandBuffer() +{ + if(!cmd_pool) + return(nullptr); + + VkCommandBufferAllocateInfo cmd = {}; + cmd.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + cmd.pNext = nullptr; + cmd.commandPool = cmd_pool; + cmd.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + cmd.commandBufferCount = 1; + + VkCommandBuffer cmd_buf; + + VkResult res = vkAllocateCommandBuffers(device, &cmd, &cmd_buf); + + if(res!=VK_SUCCESS) + return(nullptr); + + return(new CommandBuffer(device,cmd_pool,cmd_buf)); +} +VK_NAMESPACE_END diff --git a/example/Vulkan/VKDevice.h b/example/Vulkan/VKDevice.h new file mode 100644 index 00000000..0693008a --- /dev/null +++ b/example/Vulkan/VKDevice.h @@ -0,0 +1,27 @@ +#ifndef HGL_GRAPH_VULKAN_DEVICE_INCLUDE +#define HGL_GRAPH_VULKAN_DEVICE_INCLUDE + +#include"VK.h" + +VK_NAMESPACE_BEGIN + + class CommandBuffer; + + /** + * Vulkan设备对象封装 + */ + class Device + { + VkDevice device; + VkCommandPool cmd_pool; ///<命令池,用于创建命令缓冲区。由于不知道创建多个是否有好处,所以暂时设计为一个设备只有一个。 + + public: + + Device(VkDevice,int); + virtual ~Device(); + + CommandBuffer *CreateCommandBuffer(); + };//class Device +VK_NAMESPACE_END + +#endif//HGL_GRAPH_VULKAN_DEVICE_INCLUDE diff --git a/example/Vulkan/VKInstance.cpp b/example/Vulkan/VKInstance.cpp index a569a326..d3571a4c 100644 --- a/example/Vulkan/VKInstance.cpp +++ b/example/Vulkan/VKInstance.cpp @@ -29,6 +29,8 @@ Instance::Instance(const UTF8String &an) Instance::~Instance() { + physical_devices.Clear(); + if(inst) vkDestroyInstance(inst,nullptr); } @@ -46,6 +48,23 @@ bool Instance::Init() return(false); } + { + uint32_t gpu_count = 1; + res = vkEnumeratePhysicalDevices(inst, &gpu_count, nullptr); + + if(res!=VK_SUCCESS) + return(false); + + VkPhysicalDevice *pd_list=new VkPhysicalDevice[gpu_count]; + physical_devices.SetCount(gpu_count); + vkEnumeratePhysicalDevices(inst, &gpu_count, pd_list); + + for(uint32_t i=0;i -#include - -#define VK_NAMESPACE_BEGIN namespace hgl{namespace graph{namespace vulkan{ -#define VK_NAMESPACE_END }}} +#include +#include"VK.h" +#include"VKPhysicalDevice.h" VK_NAMESPACE_BEGIN class Instance @@ -15,6 +14,8 @@ VK_NAMESPACE_BEGIN VkInstance inst; + ObjectList physical_devices; + private: UTF8String app_name; @@ -25,6 +26,8 @@ VK_NAMESPACE_BEGIN virtual ~Instance(); virtual bool Init(); + + const ObjectList & GetDeviceList()const{return physical_devices;} };//class Instance VK_NAMESPACE_END #endif//HGL_GRAPH_VULKAN_INSTANCE_INCLUDE diff --git a/example/Vulkan/VKPhysicalDevice.cpp b/example/Vulkan/VKPhysicalDevice.cpp new file mode 100644 index 00000000..36875a38 --- /dev/null +++ b/example/Vulkan/VKPhysicalDevice.cpp @@ -0,0 +1,82 @@ +#include"VKPhysicalDevice.h" +#include"VKDevice.h" + +VK_NAMESPACE_BEGIN + +PhysicalDevice::PhysicalDevice(VkPhysicalDevice pd) +{ + physical_device=pd; + + if(!pd)return; + + vkGetPhysicalDeviceFeatures(physical_device,&features); + vkGetPhysicalDeviceProperties(physical_device,&properties); + vkGetPhysicalDeviceMemoryProperties(physical_device,&memory_properties); + + { + uint32_t family_count; + vkGetPhysicalDeviceQueueFamilyProperties(physical_device,&family_count,nullptr); + family_properties.SetCount(family_count); + vkGetPhysicalDeviceQueueFamilyProperties(physical_device,&family_count,family_properties.GetData()); + } +} + +PhysicalDevice::~PhysicalDevice() +{ +} + +int PhysicalDevice::QueueFamilyProperties(VkQueueFlags flag) const +{ + const int count=family_properties.GetCount(); + + if(count<=0) + return(-1); + + VkQueueFamilyProperties *fp=family_properties.GetData(); + for(int i=0;iqueueFlags&flag) + return i; + + ++fp; + } + + return -1; +} + +Device *PhysicalDevice::CreateGraphicsDevice() const +{ + const int index=QueueFamilyProperties(VK_QUEUE_GRAPHICS_BIT); + + if(index==-1) + return(nullptr); + + float queue_priorities[1] = {0.0}; + + VkDeviceQueueCreateInfo queue_info; + queue_info.queueFamilyIndex=index; + queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queue_info.pNext = nullptr; + queue_info.queueCount = 1; + queue_info.pQueuePriorities = queue_priorities; + + VkDeviceCreateInfo create_info = {}; + create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + create_info.pNext = nullptr; + create_info.queueCreateInfoCount = 1; + create_info.pQueueCreateInfos = &queue_info; + create_info.enabledExtensionCount = 0; + create_info.ppEnabledExtensionNames = nullptr; + create_info.enabledLayerCount = 0; + create_info.ppEnabledLayerNames = nullptr; + create_info.pEnabledFeatures = nullptr; + + VkDevice device; + VkResult res = vkCreateDevice(physical_device, &create_info, nullptr, &device); + if(res != VK_SUCCESS) + return(nullptr); + + return(new Device(device,index)); +} + +VK_NAMESPACE_END diff --git a/example/Vulkan/VKPhysicalDevice.h b/example/Vulkan/VKPhysicalDevice.h new file mode 100644 index 00000000..ad6e1b1d --- /dev/null +++ b/example/Vulkan/VKPhysicalDevice.h @@ -0,0 +1,34 @@ +#ifndef HGL_GRAPH_VULKAN_PHYSICAL_DEVICE_INCLUDE +#define HGL_GRAPH_VULKAN_PHYSICAL_DEVICE_INCLUDE + +#include"VK.h" +#include + +VK_NAMESPACE_BEGIN + + class Device; + + /** + * Vulkan物理设备对象封装
+ * 注:这个设备可能是图形设备,也可能是计算设备等,我们暂时只支持图形设备 + */ + class PhysicalDevice + { + VkPhysicalDevice physical_device; + + VkPhysicalDeviceFeatures features; + VkPhysicalDeviceProperties properties; + VkPhysicalDeviceMemoryProperties memory_properties; + + List family_properties; + int QueueFamilyProperties(VkQueueFlags) const; + + public: + + PhysicalDevice(VkPhysicalDevice pd); + ~PhysicalDevice(); + + Device *CreateGraphicsDevice()const; ///<创建一个图形设备 + };//class PhysicalDevice +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_PHYSICAL_DEVICE_INCLUDE diff --git a/example/Vulkan/main.cpp b/example/Vulkan/main.cpp index 672967fd..b34ff73c 100644 --- a/example/Vulkan/main.cpp +++ b/example/Vulkan/main.cpp @@ -1,4 +1,7 @@ -#include"VKInstance.h" +#include"VK.h" +#include"VKInstance.h" +#include"VKDevice.h" +#include"VKCommandBuffer.h" int main(int,char **) { @@ -7,7 +10,19 @@ int main(int,char **) vulkan::Instance inst("Test"); - inst.Init(); + if(!inst.Init()) + return(-1); + + const ObjectList &device_list=inst.GetDeviceList(); + + vulkan::PhysicalDevice *pd=device_list[0]; + + vulkan::Device *dev=pd->CreateGraphicsDevice(); + + vulkan::CommandBuffer *cmd_buf=dev->CreateCommandBuffer(); + + delete cmd_buf; + delete dev; return 0; }