新的RenderSurface创建结构,更为合理化。在初始化不成功前不会创建RenderSurface类,以节省内存开销
This commit is contained in:
parent
ef52f5e7b8
commit
4d4e491985
@ -7,8 +7,10 @@ ENDIF()
|
|||||||
|
|
||||||
add_executable(VulkanTest main.cpp
|
add_executable(VulkanTest main.cpp
|
||||||
${RENDER_WINDOW_SOURCE}
|
${RENDER_WINDOW_SOURCE}
|
||||||
VKInstance.cpp
|
VKInstance.cpp
|
||||||
VKCommandBuffer.cpp
|
VKCommandBuffer.cpp
|
||||||
|
RenderSurfaceAttribute.cpp
|
||||||
|
RenderSurfaceCreater.cpp
|
||||||
RenderSurface.cpp)
|
RenderSurface.cpp)
|
||||||
|
|
||||||
target_link_libraries(VulkanTest PRIVATE ${ULRE} ${VULKAN_LIB} ${RENDER_WINDOW_LIBRARY})
|
target_link_libraries(VulkanTest PRIVATE ${ULRE} ${VULKAN_LIB} ${RENDER_WINDOW_LIBRARY})
|
||||||
|
@ -1,189 +1,27 @@
|
|||||||
#include"RenderSurface.h"
|
#include"RenderSurface.h"
|
||||||
|
|
||||||
VK_NAMESPACE_BEGIN
|
VK_NAMESPACE_BEGIN
|
||||||
RenderSurface::RenderSurface(Window *w,VkInstance inst,VkPhysicalDevice pd)
|
|
||||||
{
|
|
||||||
win=w;
|
|
||||||
instance=inst;
|
|
||||||
physical_device=pd;
|
|
||||||
family_index=-1;
|
|
||||||
device=nullptr;
|
|
||||||
cmd_pool=nullptr;
|
|
||||||
|
|
||||||
vkGetPhysicalDeviceFeatures(physical_device,&features);
|
|
||||||
vkGetPhysicalDeviceProperties(physical_device,&properties);
|
|
||||||
vkGetPhysicalDeviceMemoryProperties(physical_device,&memory_properties);
|
|
||||||
|
|
||||||
surface=win->CreateSurface(inst);
|
|
||||||
|
|
||||||
{
|
|
||||||
uint32_t family_count;
|
|
||||||
vkGetPhysicalDeviceQueueFamilyProperties(physical_device,&family_count,nullptr);
|
|
||||||
family_properties.SetCount(family_count);
|
|
||||||
vkGetPhysicalDeviceQueueFamilyProperties(physical_device,&family_count,family_properties.GetData());
|
|
||||||
|
|
||||||
{
|
|
||||||
supports_present.SetCount(family_count);
|
|
||||||
VkBool32 *sp=supports_present.GetData();
|
|
||||||
for(uint32_t i=0; i<family_count; i++)
|
|
||||||
{
|
|
||||||
vkGetPhysicalDeviceSurfaceSupportKHR(physical_device,i,surface,sp);
|
|
||||||
++sp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
uint32_t format_count;
|
|
||||||
if(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device,surface,&format_count,nullptr)==VK_SUCCESS)
|
|
||||||
{
|
|
||||||
surface_formts.SetCount(format_count);
|
|
||||||
|
|
||||||
if(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device,surface,&format_count,surface_formts.GetData())!=VK_SUCCESS)
|
|
||||||
surface_formts.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
uint32_t mode_count;
|
|
||||||
if(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device,surface,&mode_count,nullptr)==VK_SUCCESS)
|
|
||||||
{
|
|
||||||
present_modes.SetCount(mode_count);
|
|
||||||
if(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device,surface,&mode_count,present_modes.GetData())!=VK_SUCCESS)
|
|
||||||
present_modes.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device,surface,&surface_caps);
|
|
||||||
|
|
||||||
VkExtent2D swapchain_extent;
|
|
||||||
if(surface_caps.currentExtent.width==0xFFFFFFFF)
|
|
||||||
{
|
|
||||||
swapchain_extent.width=win->GetWidth();
|
|
||||||
swapchain_extent.height=win->GetHeight();
|
|
||||||
|
|
||||||
if(swapchain_extent.width<surface_caps.minImageExtent.width)swapchain_extent.width=surface_caps.minImageExtent.width;else
|
|
||||||
if(swapchain_extent.width>surface_caps.maxImageExtent.width)swapchain_extent.width=surface_caps.maxImageExtent.width;
|
|
||||||
|
|
||||||
if(swapchain_extent.height<surface_caps.minImageExtent.height)swapchain_extent.height=surface_caps.minImageExtent.height;else
|
|
||||||
if(swapchain_extent.height>surface_caps.maxImageExtent.height)swapchain_extent.height=surface_caps.maxImageExtent.height;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
swapchain_extent=surface_caps.currentExtent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CreateDevice();
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderSurface::~RenderSurface()
|
|
||||||
{
|
|
||||||
if(device)
|
|
||||||
{
|
|
||||||
if(cmd_pool)
|
|
||||||
vkDestroyCommandPool(device,cmd_pool,nullptr);
|
|
||||||
|
|
||||||
vkDestroyDevice(device,nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(surface)
|
|
||||||
vkDestroySurfaceKHR(instance,surface,nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
int RenderSurface::QueueFamilyProperties(VkQueueFlags flag) const
|
|
||||||
{
|
|
||||||
const int count=family_properties.GetCount();
|
|
||||||
|
|
||||||
if(count<=0)
|
|
||||||
return(-1);
|
|
||||||
|
|
||||||
VkBool32*sp=supports_present.GetData();
|
|
||||||
VkQueueFamilyProperties*fp=family_properties.GetData();
|
|
||||||
for(int i=0;i<count;i++)
|
|
||||||
{
|
|
||||||
if((*sp)
|
|
||||||
&&(fp->queueFlags&flag))
|
|
||||||
return i;
|
|
||||||
|
|
||||||
++sp;
|
|
||||||
++fp;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RenderSurface::CreateCommandPool()
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
return(res==VK_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
CommandBuffer *RenderSurface::CreateCommandBuffer()
|
CommandBuffer *RenderSurface::CreateCommandBuffer()
|
||||||
{
|
{
|
||||||
if(!cmd_pool)
|
if(!rsa->cmd_pool)
|
||||||
return(nullptr);
|
return(nullptr);
|
||||||
|
|
||||||
VkCommandBufferAllocateInfo cmd={};
|
VkCommandBufferAllocateInfo cmd={};
|
||||||
cmd.sType=VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
cmd.sType=VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||||
cmd.pNext=nullptr;
|
cmd.pNext=nullptr;
|
||||||
cmd.commandPool=cmd_pool;
|
cmd.commandPool=rsa->cmd_pool;
|
||||||
cmd.level=VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
cmd.level=VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||||
cmd.commandBufferCount=1;
|
cmd.commandBufferCount=1;
|
||||||
|
|
||||||
VkCommandBuffer cmd_buf;
|
VkCommandBuffer cmd_buf;
|
||||||
|
|
||||||
VkResult res=vkAllocateCommandBuffers(device,&cmd,&cmd_buf);
|
VkResult res=vkAllocateCommandBuffers(rsa->device,&cmd,&cmd_buf);
|
||||||
|
|
||||||
if(res!=VK_SUCCESS)
|
if(res!=VK_SUCCESS)
|
||||||
return(nullptr);
|
return(nullptr);
|
||||||
|
|
||||||
return(new CommandBuffer(device,cmd_pool,cmd_buf));
|
return(new CommandBuffer(rsa->device,rsa->cmd_pool,cmd_buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderSurface::CreateDevice()
|
|
||||||
{
|
|
||||||
family_index=QueueFamilyProperties(VK_QUEUE_GRAPHICS_BIT);
|
|
||||||
|
|
||||||
if(family_index==-1)
|
|
||||||
return(false);
|
|
||||||
|
|
||||||
float queue_priorities[1]={0.0};
|
|
||||||
|
|
||||||
VkDeviceQueueCreateInfo queue_info;
|
|
||||||
queue_info.queueFamilyIndex=family_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={};
|
|
||||||
const char *ext_list[1]={VK_KHR_SWAPCHAIN_EXTENSION_NAME};
|
|
||||||
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=1;
|
|
||||||
create_info.ppEnabledExtensionNames=ext_list;
|
|
||||||
create_info.enabledLayerCount=0;
|
|
||||||
create_info.ppEnabledLayerNames=nullptr;
|
|
||||||
create_info.pEnabledFeatures=nullptr;
|
|
||||||
|
|
||||||
VkResult res=vkCreateDevice(physical_device,&create_info,nullptr,&device);
|
|
||||||
|
|
||||||
if(res!=VK_SUCCESS)
|
|
||||||
return(false);
|
|
||||||
|
|
||||||
CreateCommandPool();
|
|
||||||
return(true);
|
|
||||||
}
|
|
||||||
VK_NAMESPACE_END
|
VK_NAMESPACE_END
|
||||||
|
@ -4,49 +4,36 @@
|
|||||||
#include<hgl/type/List.h>
|
#include<hgl/type/List.h>
|
||||||
#include"VK.h"
|
#include"VK.h"
|
||||||
#include"Window.h"
|
#include"Window.h"
|
||||||
|
#include"RenderSurfaceAttribute.h"
|
||||||
#include"VKCommandBuffer.h"
|
#include"VKCommandBuffer.h"
|
||||||
|
|
||||||
VK_NAMESPACE_BEGIN
|
VK_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
using RefRenderSurfaceAttribute=SharedPtr<RenderSurfaceAttribute>;
|
||||||
|
|
||||||
class RenderSurface
|
class RenderSurface
|
||||||
{
|
{
|
||||||
Window *win;
|
RefRenderSurfaceAttribute rsa;
|
||||||
VkInstance instance;
|
|
||||||
VkPhysicalDevice physical_device;
|
|
||||||
VkSurfaceKHR surface;
|
|
||||||
|
|
||||||
VkPhysicalDeviceFeatures features;
|
private:
|
||||||
VkPhysicalDeviceProperties properties;
|
|
||||||
VkPhysicalDeviceMemoryProperties memory_properties;
|
|
||||||
|
|
||||||
List<VkQueueFamilyProperties> family_properties;
|
friend RenderSurface *CreateRenderSuface(VkInstance,VkPhysicalDevice,Window *);
|
||||||
List<VkBool32> supports_present;
|
|
||||||
|
|
||||||
List<VkSurfaceFormatKHR> surface_formts;
|
RenderSurface(RefRenderSurfaceAttribute &ref_rsa)
|
||||||
VkSurfaceCapabilitiesKHR surface_caps;
|
{
|
||||||
List<VkPresentModeKHR> present_modes;
|
rsa=ref_rsa;
|
||||||
|
}
|
||||||
uint32_t family_index;
|
|
||||||
VkDevice device;
|
|
||||||
VkCommandPool cmd_pool; ///<命令池,用于创建命令缓冲区。由于不知道创建多个是否有好处,所以暂时设计为一个设备只有一个。
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
int QueueFamilyProperties(VkQueueFlags) const;
|
|
||||||
|
|
||||||
bool CreateDevice();
|
|
||||||
bool CreateCommandPool();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
RenderSurface(Window *,VkInstance,VkPhysicalDevice);
|
virtual ~RenderSurface()=default;
|
||||||
virtual ~RenderSurface();
|
|
||||||
|
|
||||||
VkPhysicalDevice GetPhysicalDevice() { return physical_device; }
|
VkPhysicalDevice GetPhysicalDevice () { return rsa->physical_device; }
|
||||||
VkSurfaceKHR GetSurface() { return surface; }
|
VkSurfaceKHR GetSurface () { return rsa->surface; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CommandBuffer *CreateCommandBuffer();
|
CommandBuffer * CreateCommandBuffer ();
|
||||||
};//class RenderSurface
|
};//class RenderSurface
|
||||||
VK_NAMESPACE_END
|
VK_NAMESPACE_END
|
||||||
#endif//HGL_GRAPH_RENDER_SURFACE_INCLUDE
|
#endif//HGL_GRAPH_RENDER_SURFACE_INCLUDE
|
||||||
|
74
example/Vulkan/RenderSurfaceAttribute.cpp
Normal file
74
example/Vulkan/RenderSurfaceAttribute.cpp
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#include"RenderSurfaceAttribute.h"
|
||||||
|
|
||||||
|
VK_NAMESPACE_BEGIN
|
||||||
|
RenderSurfaceAttribute::RenderSurfaceAttribute(VkInstance inst,VkPhysicalDevice pd,VkSurfaceKHR s)
|
||||||
|
{
|
||||||
|
instance=inst;
|
||||||
|
physical_device=pd;
|
||||||
|
surface=s;
|
||||||
|
|
||||||
|
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device,surface,&surface_caps);
|
||||||
|
|
||||||
|
vkGetPhysicalDeviceFeatures(physical_device,&features);
|
||||||
|
vkGetPhysicalDeviceProperties(physical_device,&properties);
|
||||||
|
vkGetPhysicalDeviceMemoryProperties(physical_device,&memory_properties);
|
||||||
|
|
||||||
|
{
|
||||||
|
uint32_t format_count;
|
||||||
|
if(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device,surface,&format_count,nullptr)==VK_SUCCESS)
|
||||||
|
{
|
||||||
|
surface_formts.SetCount(format_count);
|
||||||
|
|
||||||
|
if(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device,surface,&format_count,surface_formts.GetData())!=VK_SUCCESS)
|
||||||
|
surface_formts.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
uint32_t mode_count;
|
||||||
|
if(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device,surface,&mode_count,nullptr)==VK_SUCCESS)
|
||||||
|
{
|
||||||
|
present_modes.SetCount(mode_count);
|
||||||
|
if(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device,surface,&mode_count,present_modes.GetData())!=VK_SUCCESS)
|
||||||
|
present_modes.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
uint32_t family_count;
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties(physical_device,&family_count,nullptr);
|
||||||
|
family_properties.SetCount(family_count);
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties(physical_device,&family_count,family_properties.GetData());
|
||||||
|
|
||||||
|
VkQueueFamilyProperties *fp=family_properties.GetData();
|
||||||
|
|
||||||
|
supports_present.SetCount(family_count);
|
||||||
|
VkBool32 *sp=supports_present.GetData();
|
||||||
|
for(uint32_t i=0; i<family_count; i++)
|
||||||
|
{
|
||||||
|
vkGetPhysicalDeviceSurfaceSupportKHR(physical_device,i,surface,sp);
|
||||||
|
|
||||||
|
if(family_index==-1)
|
||||||
|
{
|
||||||
|
if(*sp&&(fp->queueFlags&VK_QUEUE_GRAPHICS_BIT))
|
||||||
|
family_index=i;
|
||||||
|
}
|
||||||
|
|
||||||
|
++fp;
|
||||||
|
++sp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderSurfaceAttribute::~RenderSurfaceAttribute()
|
||||||
|
{
|
||||||
|
if(cmd_pool)
|
||||||
|
vkDestroyCommandPool(device,cmd_pool,nullptr);
|
||||||
|
|
||||||
|
if(device)
|
||||||
|
vkDestroyDevice(device,nullptr);
|
||||||
|
|
||||||
|
if(surface)
|
||||||
|
vkDestroySurfaceKHR(instance,surface,nullptr);
|
||||||
|
}
|
||||||
|
VK_NAMESPACE_END
|
34
example/Vulkan/RenderSurfaceAttribute.h
Normal file
34
example/Vulkan/RenderSurfaceAttribute.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include"VK.h"
|
||||||
|
|
||||||
|
VK_NAMESPACE_BEGIN
|
||||||
|
struct RenderSurfaceAttribute
|
||||||
|
{
|
||||||
|
VkInstance instance =nullptr;
|
||||||
|
VkPhysicalDevice physical_device =nullptr;
|
||||||
|
VkSurfaceKHR surface =nullptr;
|
||||||
|
VkSurfaceCapabilitiesKHR surface_caps;
|
||||||
|
VkExtent2D swapchain_extent;
|
||||||
|
|
||||||
|
int family_index =-1;
|
||||||
|
|
||||||
|
List<VkQueueFamilyProperties> family_properties;
|
||||||
|
List<VkBool32> supports_present;
|
||||||
|
|
||||||
|
VkPhysicalDeviceFeatures features;
|
||||||
|
VkPhysicalDeviceProperties properties;
|
||||||
|
VkPhysicalDeviceMemoryProperties memory_properties;
|
||||||
|
|
||||||
|
List<VkSurfaceFormatKHR> surface_formts;
|
||||||
|
List<VkPresentModeKHR> present_modes;
|
||||||
|
|
||||||
|
VkDevice device =nullptr;
|
||||||
|
VkCommandPool cmd_pool =nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
RenderSurfaceAttribute(VkInstance inst,VkPhysicalDevice pd,VkSurfaceKHR s);
|
||||||
|
~RenderSurfaceAttribute();
|
||||||
|
};//class RenderSurfaceAttribute
|
||||||
|
VK_NAMESPACE_END
|
109
example/Vulkan/RenderSurfaceCreater.cpp
Normal file
109
example/Vulkan/RenderSurfaceCreater.cpp
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
#include"RenderSurface.h"
|
||||||
|
#include"VKInstance.h"
|
||||||
|
#include<hgl/type/Smart.h>
|
||||||
|
|
||||||
|
VK_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
VkSurfaceKHR CreateSurface(VkInstance,Window *);
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
VkExtent2D GetSwapchainExtent(VkSurfaceCapabilitiesKHR &surface_caps,int width,int height)
|
||||||
|
{
|
||||||
|
if(surface_caps.currentExtent.width==0xFFFFFFFF)
|
||||||
|
{
|
||||||
|
VkExtent2D swapchain_extent;
|
||||||
|
|
||||||
|
swapchain_extent.width=width;
|
||||||
|
swapchain_extent.height=height;
|
||||||
|
|
||||||
|
if(swapchain_extent.width<surface_caps.minImageExtent.width)swapchain_extent.width=surface_caps.minImageExtent.width;else
|
||||||
|
if(swapchain_extent.width>surface_caps.maxImageExtent.width)swapchain_extent.width=surface_caps.maxImageExtent.width;
|
||||||
|
|
||||||
|
if(swapchain_extent.height<surface_caps.minImageExtent.height)swapchain_extent.height=surface_caps.minImageExtent.height;else
|
||||||
|
if(swapchain_extent.height>surface_caps.maxImageExtent.height)swapchain_extent.height=surface_caps.maxImageExtent.height;
|
||||||
|
|
||||||
|
return swapchain_extent;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return surface_caps.currentExtent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VkDevice CreateDevice(VkInstance instance,VkPhysicalDevice physical_device,int family_index)
|
||||||
|
{
|
||||||
|
float queue_priorities[1]={0.0};
|
||||||
|
|
||||||
|
VkDeviceQueueCreateInfo queue_info;
|
||||||
|
queue_info.queueFamilyIndex=family_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={};
|
||||||
|
const char *ext_list[1]={VK_KHR_SWAPCHAIN_EXTENSION_NAME};
|
||||||
|
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=1;
|
||||||
|
create_info.ppEnabledExtensionNames=ext_list;
|
||||||
|
create_info.enabledLayerCount=0;
|
||||||
|
create_info.ppEnabledLayerNames=nullptr;
|
||||||
|
create_info.pEnabledFeatures=nullptr;
|
||||||
|
|
||||||
|
VkDevice device;
|
||||||
|
|
||||||
|
if(vkCreateDevice(physical_device,&create_info,nullptr,&device)==VK_SUCCESS)
|
||||||
|
return device;
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkCommandPool CreateCommandPool(VkDevice device,int family_index)
|
||||||
|
{
|
||||||
|
VkCommandPoolCreateInfo cmd_pool_info={};
|
||||||
|
|
||||||
|
cmd_pool_info.sType=VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||||
|
cmd_pool_info.pNext=nullptr;
|
||||||
|
cmd_pool_info.queueFamilyIndex=family_index;
|
||||||
|
cmd_pool_info.flags=0;
|
||||||
|
|
||||||
|
VkCommandPool cmd_pool;
|
||||||
|
|
||||||
|
if(vkCreateCommandPool(device,&cmd_pool_info,nullptr,&cmd_pool)==VK_SUCCESS)
|
||||||
|
return cmd_pool;
|
||||||
|
|
||||||
|
return(nullptr);
|
||||||
|
}
|
||||||
|
}//namespace
|
||||||
|
|
||||||
|
RenderSurface *CreateRenderSuface(VkInstance inst,VkPhysicalDevice physical_device,Window *win)
|
||||||
|
{
|
||||||
|
VkSurfaceKHR surface=CreateSurface(inst,win);
|
||||||
|
|
||||||
|
if(!surface)
|
||||||
|
return(nullptr);
|
||||||
|
|
||||||
|
RefRenderSurfaceAttribute rsa=new RenderSurfaceAttribute(inst,physical_device,surface);
|
||||||
|
|
||||||
|
rsa->swapchain_extent=GetSwapchainExtent(rsa->surface_caps,win->GetWidth(),win->GetHeight());
|
||||||
|
|
||||||
|
if(rsa->family_index==-1)
|
||||||
|
return(nullptr);
|
||||||
|
|
||||||
|
rsa->device=CreateDevice(inst,physical_device,rsa->family_index);
|
||||||
|
|
||||||
|
if(!rsa->device)
|
||||||
|
return(nullptr);
|
||||||
|
|
||||||
|
rsa->cmd_pool=CreateCommandPool(rsa->device,rsa->family_index);
|
||||||
|
|
||||||
|
if(!rsa->cmd_pool)
|
||||||
|
return(nullptr);
|
||||||
|
|
||||||
|
return(new RenderSurface(rsa));
|
||||||
|
}
|
||||||
|
VK_NAMESPACE_END
|
@ -1,9 +1,12 @@
|
|||||||
#ifndef HGL_GRAPH_VULKAN_INCLUDE
|
#ifndef HGL_GRAPH_VULKAN_INCLUDE
|
||||||
#define HGL_GRAPH_VULKAN_INCLUDE
|
#define HGL_GRAPH_VULKAN_INCLUDE
|
||||||
|
|
||||||
|
#include<hgl/type/List.h>
|
||||||
#include<vulkan/vulkan.h>
|
#include<vulkan/vulkan.h>
|
||||||
|
|
||||||
#define VK_NAMESPACE_BEGIN namespace hgl{namespace graph{namespace vulkan{
|
#define VK_NAMESPACE_BEGIN namespace hgl{namespace graph{namespace vulkan{
|
||||||
#define VK_NAMESPACE_END }}}
|
#define VK_NAMESPACE_END }}}
|
||||||
|
|
||||||
|
using CharPointerList=hgl::List<const char *>;
|
||||||
|
|
||||||
#endif//HGL_GRAPH_VULKAN_INCLUDE
|
#endif//HGL_GRAPH_VULKAN_INCLUDE
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
#include"VKInstance.h"
|
#include"VKInstance.h"
|
||||||
|
#include"VKSurfaceExtensionName.h"
|
||||||
#include<hgl/type/DataType.h>
|
#include<hgl/type/DataType.h>
|
||||||
|
|
||||||
VK_NAMESPACE_BEGIN
|
VK_NAMESPACE_BEGIN
|
||||||
|
RenderSurface *CreateRenderSuface(VkInstance,VkPhysicalDevice,Window *);
|
||||||
|
|
||||||
Instance::Instance(const UTF8String &an,Window *w)
|
Instance *CreateInstance(const UTF8String &app_name)
|
||||||
{
|
{
|
||||||
win=w;
|
VkApplicationInfo app_info;
|
||||||
app_name=an;
|
VkInstanceCreateInfo inst_info;
|
||||||
|
CharPointerList ext_list;
|
||||||
|
|
||||||
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||||
app_info.pNext = nullptr;
|
app_info.pNext = nullptr;
|
||||||
@ -17,7 +20,7 @@ Instance::Instance(const UTF8String &an,Window *w)
|
|||||||
app_info.apiVersion = VK_API_VERSION_1_0;
|
app_info.apiVersion = VK_API_VERSION_1_0;
|
||||||
|
|
||||||
ext_list.Add(VK_KHR_SURFACE_EXTENSION_NAME);
|
ext_list.Add(VK_KHR_SURFACE_EXTENSION_NAME);
|
||||||
ext_list.Add(win->GetVulkanSurfaceExtname());
|
ext_list.Add(HGL_VK_SURFACE_EXTENSION_NAME); //此宏在CMAKE中定义
|
||||||
|
|
||||||
inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||||
inst_info.pNext = nullptr;
|
inst_info.pNext = nullptr;
|
||||||
@ -28,52 +31,45 @@ Instance::Instance(const UTF8String &an,Window *w)
|
|||||||
inst_info.enabledLayerCount = 0;
|
inst_info.enabledLayerCount = 0;
|
||||||
inst_info.ppEnabledLayerNames = nullptr;
|
inst_info.ppEnabledLayerNames = nullptr;
|
||||||
|
|
||||||
inst=nullptr;
|
VkInstance inst;
|
||||||
|
|
||||||
|
if(vkCreateInstance(&inst_info,nullptr,&inst)==VK_SUCCESS)
|
||||||
|
return(new Instance(inst,ext_list));
|
||||||
|
|
||||||
|
return(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
Instance::Instance(VkInstance i,CharPointerList &el)
|
||||||
|
{
|
||||||
|
inst=i;
|
||||||
|
ext_list=el;
|
||||||
|
|
||||||
|
uint32_t gpu_count = 1;
|
||||||
|
|
||||||
|
if(vkEnumeratePhysicalDevices(inst, &gpu_count, nullptr)==VK_SUCCESS)
|
||||||
|
{
|
||||||
|
physical_devices.SetCount(gpu_count);
|
||||||
|
vkEnumeratePhysicalDevices(inst, &gpu_count,physical_devices.GetData());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Instance::~Instance()
|
Instance::~Instance()
|
||||||
{
|
{
|
||||||
physical_devices.Clear();
|
physical_devices.Clear();
|
||||||
|
|
||||||
if(inst)
|
vkDestroyInstance(inst,nullptr);
|
||||||
vkDestroyInstance(inst,nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Instance::Init()
|
RenderSurface *Instance::CreateSurface(Window *win,int pd_index)
|
||||||
{
|
{
|
||||||
if(inst)
|
if(!win)
|
||||||
return(false);
|
|
||||||
|
|
||||||
VkResult res=vkCreateInstance(&inst_info,nullptr,&inst);
|
|
||||||
|
|
||||||
if(res)
|
|
||||||
{
|
|
||||||
inst=nullptr;
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
uint32_t gpu_count = 1;
|
|
||||||
res = vkEnumeratePhysicalDevices(inst, &gpu_count, nullptr);
|
|
||||||
|
|
||||||
if(res!=VK_SUCCESS)
|
|
||||||
return(false);
|
|
||||||
|
|
||||||
physical_devices.SetCount(gpu_count);
|
|
||||||
vkEnumeratePhysicalDevices(inst, &gpu_count,physical_devices.GetData());
|
|
||||||
}
|
|
||||||
|
|
||||||
return(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderSurface *Instance::CreateRenderSurface(int pd_index)
|
|
||||||
{
|
|
||||||
VkPhysicalDevice pd;
|
|
||||||
|
|
||||||
if(!physical_devices.Get(pd_index,pd))
|
|
||||||
return(nullptr);
|
return(nullptr);
|
||||||
|
|
||||||
return(new RenderSurface(win,inst,pd));
|
VkPhysicalDevice pd=GetDevice(pd_index);
|
||||||
}
|
|
||||||
|
|
||||||
|
if(!pd)
|
||||||
|
return(nullptr);
|
||||||
|
|
||||||
|
return CreateRenderSuface(inst,pd,win);
|
||||||
|
}
|
||||||
VK_NAMESPACE_END
|
VK_NAMESPACE_END
|
||||||
|
@ -4,36 +4,40 @@
|
|||||||
#include<hgl/type/BaseString.h>
|
#include<hgl/type/BaseString.h>
|
||||||
#include<hgl/type/List.h>
|
#include<hgl/type/List.h>
|
||||||
#include"Window.h"
|
#include"Window.h"
|
||||||
|
#include"VK.h"
|
||||||
#include"RenderSurface.h"
|
#include"RenderSurface.h"
|
||||||
|
|
||||||
VK_NAMESPACE_BEGIN
|
VK_NAMESPACE_BEGIN
|
||||||
class Instance
|
class Instance
|
||||||
{
|
{
|
||||||
Window *win;
|
|
||||||
|
|
||||||
List<const char *> ext_list;
|
|
||||||
|
|
||||||
VkApplicationInfo app_info;
|
|
||||||
VkInstanceCreateInfo inst_info;
|
|
||||||
|
|
||||||
VkInstance inst;
|
VkInstance inst;
|
||||||
|
|
||||||
|
CharPointerList ext_list;
|
||||||
|
|
||||||
List<VkPhysicalDevice> physical_devices;
|
List<VkPhysicalDevice> physical_devices;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
UTF8String app_name;
|
friend Instance *CreateInstance(const UTF8String &app_name);
|
||||||
|
|
||||||
|
Instance(VkInstance,CharPointerList &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Instance(const UTF8String &,Window *);
|
|
||||||
virtual ~Instance();
|
virtual ~Instance();
|
||||||
|
|
||||||
virtual bool Init();
|
VkInstance GetVkInstance () {return inst;}
|
||||||
|
|
||||||
const List<VkPhysicalDevice> & GetDeviceList()const{return physical_devices;}
|
const CharPointerList & GetExtList ()const {return ext_list;}
|
||||||
|
const List<VkPhysicalDevice> &GetDeviceList ()const {return physical_devices;}
|
||||||
|
VkPhysicalDevice GetDevice (int index)
|
||||||
|
{
|
||||||
|
return GetObject(physical_devices,index);
|
||||||
|
}
|
||||||
|
|
||||||
RenderSurface *CreateRenderSurface(int pd_index=0);
|
RenderSurface * CreateSurface (Window *,int pd_index=0);
|
||||||
};//class Instance
|
};//class Instance
|
||||||
|
|
||||||
|
Instance *CreateInstance(const UTF8String &); ///<创建一个Vulkan实例
|
||||||
VK_NAMESPACE_END
|
VK_NAMESPACE_END
|
||||||
#endif//HGL_GRAPH_VULKAN_INSTANCE_INCLUDE
|
#endif//HGL_GRAPH_VULKAN_INSTANCE_INCLUDE
|
||||||
|
26
example/Vulkan/VKSurfaceExtensionName.h
Normal file
26
example/Vulkan/VKSurfaceExtensionName.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include"VK.h"
|
||||||
|
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
#include<vulkan/vulkan_android.h>
|
||||||
|
#define HGL_VK_SURFACE_EXTENSION_NAME VK_KHR_ANDROID_SURFACE_EXTENSION_NAME
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
#include<Windows.h>
|
||||||
|
#include<vulkan/vulkan_win32.h>
|
||||||
|
#define HGL_VK_SURFACE_EXTENSION_NAME VK_KHR_WIN32_SURFACE_EXTENSION_NAME
|
||||||
|
#elif defined(VK_USE_PLATFORM_IOS_MVK)
|
||||||
|
#include<vulkan/vulkan_ios.h>
|
||||||
|
#define HGL_VK_SURFACE_EXTENSION_NAME VK_MVK_IOS_SURFACE_EXTENSION_NAME
|
||||||
|
#elif defined(VK_USE_PLATFORM_MACOS_MVK)
|
||||||
|
#include<vulkan/vulkan_macos.h>
|
||||||
|
#define HGL_VK_SURFACE_EXTENSION_NAME VK_MVK_MACOS_SURFACE_EXTENSION_NAME
|
||||||
|
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||||
|
#include<vulkan/vulkan_wayland.h>
|
||||||
|
#define HGL_VK_SURFACE_EXTENSION_NAME VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME
|
||||||
|
#else
|
||||||
|
#include<xcb/xcb.h>
|
||||||
|
#include<xcb/xcb_atom.h>
|
||||||
|
#include<vulkan/vulkan_xcb.h>
|
||||||
|
#define HGL_VK_SURFACE_EXTENSION_NAME VK_KHR_XCB_SURFACE_EXTENSION_NAME
|
||||||
|
#endif
|
@ -12,11 +12,11 @@ namespace hgl
|
|||||||
{
|
{
|
||||||
constexpr wchar_t WIN_CLASS_NAME[] = L"CMGameEngine/ULRE Window Class";
|
constexpr wchar_t WIN_CLASS_NAME[] = L"CMGameEngine/ULRE Window Class";
|
||||||
|
|
||||||
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
Window *win=(Window *)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
|
Window *win=(Window *)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
|
||||||
|
|
||||||
switch (uMsg)
|
switch (uMsg)
|
||||||
{
|
{
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
PostQuitMessage(0);
|
PostQuitMessage(0);
|
||||||
@ -125,11 +125,6 @@ namespace hgl
|
|||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* GetVulkanSurfaceExtname()const
|
|
||||||
{
|
|
||||||
return VK_KHR_WIN32_SURFACE_EXTENSION_NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Create(uint w, uint h) override
|
bool Create(uint w, uint h) override
|
||||||
{
|
{
|
||||||
width = w;
|
width = w;
|
||||||
@ -143,7 +138,7 @@ namespace hgl
|
|||||||
return Create();
|
return Create();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Create(uint, uint, uint)override
|
bool Create(uint, uint, uint)override
|
||||||
{
|
{
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
@ -158,7 +153,7 @@ namespace hgl
|
|||||||
win_hwnd = nullptr;
|
win_hwnd = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Show()override
|
void Show()override
|
||||||
{
|
{
|
||||||
ShowWindow(win_hwnd, SW_SHOW);
|
ShowWindow(win_hwnd, SW_SHOW);
|
||||||
SetForegroundWindow(win_hwnd);
|
SetForegroundWindow(win_hwnd);
|
||||||
@ -167,7 +162,7 @@ namespace hgl
|
|||||||
UpdateWindow(win_hwnd);
|
UpdateWindow(win_hwnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hide()override
|
void Hide()override
|
||||||
{
|
{
|
||||||
ShowWindow(win_hwnd, SW_HIDE);
|
ShowWindow(win_hwnd, SW_HIDE);
|
||||||
UpdateWindow(win_hwnd);
|
UpdateWindow(win_hwnd);
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#define HGL_GRAPH_WINDOW_INCLUDE
|
#define HGL_GRAPH_WINDOW_INCLUDE
|
||||||
|
|
||||||
#include<hgl/type/BaseString.h>
|
#include<hgl/type/BaseString.h>
|
||||||
#include"VK.h"
|
|
||||||
namespace hgl
|
namespace hgl
|
||||||
{
|
{
|
||||||
namespace graph
|
namespace graph
|
||||||
@ -29,16 +28,12 @@ namespace hgl
|
|||||||
}
|
}
|
||||||
virtual ~Window()=default;
|
virtual ~Window()=default;
|
||||||
|
|
||||||
virtual const char *GetVulkanSurfaceExtname()const=0;
|
|
||||||
|
|
||||||
virtual bool Create(uint,uint)=0;
|
virtual bool Create(uint,uint)=0;
|
||||||
virtual bool Create(uint,uint,uint)=0;
|
virtual bool Create(uint,uint,uint)=0;
|
||||||
virtual void Close()=0;
|
virtual void Close()=0;
|
||||||
|
|
||||||
virtual void Show()=0;
|
virtual void Show()=0;
|
||||||
virtual void Hide()=0;
|
virtual void Hide()=0;
|
||||||
|
|
||||||
virtual VkSurfaceKHR CreateSurface(VkInstance)const = 0;
|
|
||||||
};//class Window
|
};//class Window
|
||||||
|
|
||||||
Window *CreateRenderWindow(const OSString &win_name);
|
Window *CreateRenderWindow(const OSString &win_name);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include"Window.h"
|
#include"Window.h"
|
||||||
#include<xcb/xcb.h>
|
#include<xcb/xcb.h>
|
||||||
#include<xcb/xcb_atom.h>
|
#include<xcb/xcb_atom.h>
|
||||||
|
#include"VK.h"
|
||||||
#include<vulkan/vk_sdk_platform.h>
|
#include<vulkan/vk_sdk_platform.h>
|
||||||
#include<vulkan/vulkan.h>
|
#include<vulkan/vulkan.h>
|
||||||
#include<vulkan/vulkan_xcb.h>
|
#include<vulkan/vulkan_xcb.h>
|
||||||
@ -48,11 +49,6 @@ namespace hgl
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *GetVulkanSurfaceExtname()const
|
|
||||||
{
|
|
||||||
return VK_KHR_XCB_SURFACE_EXTENSION_NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Create(uint w,uint h) override
|
bool Create(uint w,uint h) override
|
||||||
{
|
{
|
||||||
if(w<=0||h<=0)return(false);
|
if(w<=0||h<=0)return(false);
|
||||||
@ -111,23 +107,11 @@ namespace hgl
|
|||||||
void Show()override{}
|
void Show()override{}
|
||||||
void Hide()override{}
|
void Hide()override{}
|
||||||
|
|
||||||
VkSurfaceKHR CreateSurface(VkInstance vk_inst)const override
|
public:
|
||||||
{
|
|
||||||
VkXcbSurfaceCreateInfoKHR createInfo = {};
|
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
|
|
||||||
createInfo.pNext = nullptr;
|
|
||||||
createInfo.connection = connection;
|
|
||||||
createInfo.window = window;
|
|
||||||
|
|
||||||
VkSurfaceKHR surface;
|
xcb_connection_t *GetConnection(){return connection;}
|
||||||
|
xcb_window_t GetWindow(){return window;}
|
||||||
|
|
||||||
VkResult res = vkCreateXcbSurfaceKHR(vk_inst, &createInfo, nullptr, &surface);
|
|
||||||
|
|
||||||
if (res != VK_SUCCESS)
|
|
||||||
return(nullptr);
|
|
||||||
|
|
||||||
return(surface);
|
|
||||||
}
|
|
||||||
};//class XCBWindow:public Window
|
};//class XCBWindow:public Window
|
||||||
|
|
||||||
Window *CreateRenderWindow(const UTF8String &win_name)
|
Window *CreateRenderWindow(const UTF8String &win_name)
|
||||||
@ -136,3 +120,25 @@ namespace hgl
|
|||||||
}
|
}
|
||||||
}//namespace graph
|
}//namespace graph
|
||||||
}//namespace hgl
|
}//namespace hgl
|
||||||
|
|
||||||
|
VK_NAMESPACE_BEGIN
|
||||||
|
VkSurfaceKHR CreateSurface(VkInstance vk_inst,Window *win)
|
||||||
|
{
|
||||||
|
XCBWindow *xcb_win=(XCBWindow *)win;
|
||||||
|
|
||||||
|
VkXcbSurfaceCreateInfoKHR createInfo = {};
|
||||||
|
createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
|
||||||
|
createInfo.pNext = nullptr;
|
||||||
|
createInfo.connection = xcb_win->GetConnection();
|
||||||
|
createInfo.window = xcb_win->GetWindow();
|
||||||
|
|
||||||
|
VkSurfaceKHR surface;
|
||||||
|
|
||||||
|
VkResult res = vkCreateXcbSurfaceKHR(vk_inst, &createInfo, nullptr, &surface);
|
||||||
|
|
||||||
|
if (res != VK_SUCCESS)
|
||||||
|
return(nullptr);
|
||||||
|
|
||||||
|
return(surface);
|
||||||
|
}
|
||||||
|
VK_NAMESPACE_END
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include"Window.h"
|
#include"Window.h"
|
||||||
#include"VKInstance.h"
|
#include"VKInstance.h"
|
||||||
|
#include"RenderSurface.h"
|
||||||
|
|
||||||
using namespace hgl;
|
using namespace hgl;
|
||||||
using namespace hgl::graph;
|
using namespace hgl::graph;
|
||||||
@ -10,19 +11,18 @@ int main(int,char **)
|
|||||||
|
|
||||||
win->Create(1280,720);
|
win->Create(1280,720);
|
||||||
|
|
||||||
vulkan::Instance inst(U8_TEXT("VulkanTest"),win);
|
vulkan::Instance *inst=vulkan::CreateInstance(U8_TEXT("VulkanTest"));
|
||||||
|
|
||||||
if(!inst.Init())
|
if(!inst)
|
||||||
{
|
{
|
||||||
delete win;
|
delete win;
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
vulkan::RenderSurface *render=inst.CreateRenderSurface();
|
vulkan::RenderSurface *render=inst->CreateSurface(win);
|
||||||
vulkan::CommandBuffer *cmd_buf=render->CreateCommandBuffer();
|
vulkan::CommandBuffer *cmd_buf=render->CreateCommandBuffer();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
delete cmd_buf;
|
delete cmd_buf;
|
||||||
delete render;
|
delete render;
|
||||||
delete win;
|
delete win;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user