2019-04-30 16:42:59 +08:00
|
|
|
|
#include<hgl/graph/vulkan/VKDevice.h>
|
2019-04-16 02:21:35 +08:00
|
|
|
|
#include<hgl/type/Pair.h>
|
2019-04-30 16:42:59 +08:00
|
|
|
|
#include<hgl/graph/vulkan/VKImageView.h>
|
|
|
|
|
#include<hgl/graph/vulkan/VKCommandBuffer.h>
|
|
|
|
|
//#include<hgl/graph/vulkan/VKDescriptorSet.h>
|
|
|
|
|
#include<hgl/graph/vulkan/VKRenderPass.h>
|
|
|
|
|
#include<hgl/graph/vulkan/VKFramebuffer.h>
|
|
|
|
|
#include<hgl/graph/vulkan/VKShaderModuleManage.h>
|
|
|
|
|
#include<hgl/graph/vulkan/VKDescriptorSets.h>
|
2019-04-10 21:54:39 +08:00
|
|
|
|
|
|
|
|
|
VK_NAMESPACE_BEGIN
|
2019-05-07 12:46:25 +08:00
|
|
|
|
bool ResizeRenderDevice(DeviceAttribute *attr,uint width,uint height);
|
|
|
|
|
|
2019-04-19 20:10:59 +08:00
|
|
|
|
Device::Device(DeviceAttribute *da)
|
|
|
|
|
{
|
|
|
|
|
attr=da;
|
2019-05-05 14:22:58 +08:00
|
|
|
|
|
2019-04-20 16:12:22 +08:00
|
|
|
|
current_frame=0;
|
|
|
|
|
|
2019-06-26 11:26:38 +08:00
|
|
|
|
texture_fence=this->CreateFence(false);
|
2019-05-20 13:50:11 +08:00
|
|
|
|
|
2019-06-15 23:52:10 +08:00
|
|
|
|
hgl_zero(texture_submit_info);
|
|
|
|
|
texture_submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
2019-04-23 00:02:59 +08:00
|
|
|
|
|
2019-06-14 10:32:43 +08:00
|
|
|
|
main_rp=nullptr;
|
|
|
|
|
texture_cmd_buf=nullptr;
|
2019-06-15 23:52:10 +08:00
|
|
|
|
|
|
|
|
|
pipe_stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
|
|
|
|
|
|
|
|
|
present_complete_semaphore =this->CreateSem();
|
|
|
|
|
render_complete_semaphore =this->CreateSem();
|
|
|
|
|
|
2019-06-20 21:41:40 +08:00
|
|
|
|
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
|
|
|
|
submit_info.pNext = nullptr;
|
|
|
|
|
submit_info.waitSemaphoreCount = 1;
|
|
|
|
|
submit_info.pWaitSemaphores = *present_complete_semaphore;
|
|
|
|
|
submit_info.pWaitDstStageMask = &pipe_stage_flags;
|
|
|
|
|
submit_info.signalSemaphoreCount = 1;
|
|
|
|
|
submit_info.pSignalSemaphores = *render_complete_semaphore;
|
2019-06-15 23:52:10 +08:00
|
|
|
|
|
|
|
|
|
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
|
|
|
|
present_info.pNext = nullptr;
|
|
|
|
|
present_info.waitSemaphoreCount = 1;
|
|
|
|
|
present_info.pWaitSemaphores = *render_complete_semaphore;
|
2019-06-20 21:41:40 +08:00
|
|
|
|
present_info.swapchainCount = 1;
|
|
|
|
|
present_info.pResults = nullptr;
|
2019-06-15 23:52:10 +08:00
|
|
|
|
|
2019-06-14 10:32:43 +08:00
|
|
|
|
RecreateDevice();
|
2019-04-19 20:10:59 +08:00
|
|
|
|
}
|
2019-04-27 21:49:22 +08:00
|
|
|
|
|
2019-04-18 22:24:39 +08:00
|
|
|
|
Device::~Device()
|
|
|
|
|
{
|
2019-06-16 00:08:42 +08:00
|
|
|
|
fence_list.Clear();
|
2019-06-15 22:02:20 +08:00
|
|
|
|
render_frame.Clear();
|
2019-04-23 00:02:59 +08:00
|
|
|
|
|
2019-06-15 23:52:10 +08:00
|
|
|
|
delete present_complete_semaphore;
|
|
|
|
|
delete render_complete_semaphore;
|
|
|
|
|
|
2019-04-23 00:02:59 +08:00
|
|
|
|
delete main_rp;
|
|
|
|
|
|
2019-05-21 00:22:18 +08:00
|
|
|
|
delete texture_cmd_buf;
|
2019-05-20 13:50:11 +08:00
|
|
|
|
delete texture_fence;
|
2019-04-20 16:12:22 +08:00
|
|
|
|
|
2019-04-18 22:24:39 +08:00
|
|
|
|
delete attr;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-14 10:32:43 +08:00
|
|
|
|
void Device::RecreateDevice()
|
2019-05-07 12:46:25 +08:00
|
|
|
|
{
|
2019-06-16 00:08:42 +08:00
|
|
|
|
fence_list.Clear();
|
2019-06-15 22:02:20 +08:00
|
|
|
|
render_frame.Clear();
|
2019-06-16 00:08:42 +08:00
|
|
|
|
|
2019-06-14 10:32:43 +08:00
|
|
|
|
if(main_rp)delete main_rp;
|
|
|
|
|
if(texture_cmd_buf)delete texture_cmd_buf;
|
|
|
|
|
|
2019-06-15 23:52:10 +08:00
|
|
|
|
present_info.pSwapchains=&attr->swap_chain;
|
2019-06-14 10:32:43 +08:00
|
|
|
|
|
|
|
|
|
main_rp=CreateRenderPass(attr->sc_image_views[0]->GetFormat(),attr->depth.view->GetFormat());
|
2019-06-15 22:02:20 +08:00
|
|
|
|
|
2019-06-16 00:08:42 +08:00
|
|
|
|
swap_chain_count=attr->sc_image_views.GetCount();
|
2019-05-07 12:46:25 +08:00
|
|
|
|
|
2019-06-16 00:08:42 +08:00
|
|
|
|
for(uint i=0;i<swap_chain_count;i++)
|
2019-06-15 22:02:20 +08:00
|
|
|
|
{
|
2019-06-16 00:08:42 +08:00
|
|
|
|
render_frame.Add(vulkan::CreateFramebuffer(this,main_rp,attr->sc_image_views[i],attr->depth.view));
|
2019-06-26 11:26:38 +08:00
|
|
|
|
fence_list.Add(this->CreateFence(true));
|
2019-06-15 22:02:20 +08:00
|
|
|
|
}
|
2019-06-14 10:32:43 +08:00
|
|
|
|
|
|
|
|
|
texture_cmd_buf=CreateCommandBuffer();
|
2019-06-16 02:58:12 +08:00
|
|
|
|
|
|
|
|
|
current_frame=0;
|
2019-06-16 00:08:42 +08:00
|
|
|
|
current_fence=0;
|
2019-05-07 12:46:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Device::Resize(uint width,uint height)
|
|
|
|
|
{
|
|
|
|
|
if(!ResizeRenderDevice(attr,width,height))
|
|
|
|
|
return(false);
|
|
|
|
|
|
2019-06-14 10:32:43 +08:00
|
|
|
|
RecreateDevice();
|
2019-05-07 12:46:25 +08:00
|
|
|
|
return(true);
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-18 16:06:44 +08:00
|
|
|
|
CommandBuffer *Device::CreateCommandBuffer()
|
2019-04-10 21:54:39 +08:00
|
|
|
|
{
|
2019-04-18 22:24:39 +08:00
|
|
|
|
if(!attr->cmd_pool)
|
2019-04-10 21:54:39 +08:00
|
|
|
|
return(nullptr);
|
|
|
|
|
|
2019-06-20 21:41:40 +08:00
|
|
|
|
VkCommandBufferAllocateInfo cmd;
|
|
|
|
|
cmd.sType =VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
|
|
|
|
cmd.pNext =nullptr;
|
|
|
|
|
cmd.commandPool =attr->cmd_pool;
|
|
|
|
|
cmd.level =VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
|
|
|
|
cmd.commandBufferCount =1;
|
2019-04-10 21:54:39 +08:00
|
|
|
|
|
|
|
|
|
VkCommandBuffer cmd_buf;
|
|
|
|
|
|
2019-04-18 22:24:39 +08:00
|
|
|
|
VkResult res=vkAllocateCommandBuffers(attr->device,&cmd,&cmd_buf);
|
2019-04-10 21:54:39 +08:00
|
|
|
|
|
|
|
|
|
if(res!=VK_SUCCESS)
|
|
|
|
|
return(nullptr);
|
|
|
|
|
|
2019-04-20 02:28:57 +08:00
|
|
|
|
return(new CommandBuffer(attr->device,attr->swapchain_extent,attr->cmd_pool,cmd_buf));
|
2019-04-10 21:54:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-06-26 11:26:38 +08:00
|
|
|
|
/**
|
|
|
|
|
* 创建栅栏
|
|
|
|
|
* @param create_signaled 是否创建初始信号
|
|
|
|
|
*/
|
|
|
|
|
Fence *Device::CreateFence(bool create_signaled)
|
2019-04-19 19:58:01 +08:00
|
|
|
|
{
|
|
|
|
|
VkFenceCreateInfo fenceInfo;
|
|
|
|
|
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
|
|
|
|
fenceInfo.pNext = nullptr;
|
2019-06-26 11:26:38 +08:00
|
|
|
|
fenceInfo.flags = create_signaled?VK_FENCE_CREATE_SIGNALED_BIT:0;
|
2019-04-19 19:58:01 +08:00
|
|
|
|
|
2019-04-20 16:12:22 +08:00
|
|
|
|
VkFence fence;
|
2019-04-19 19:58:01 +08:00
|
|
|
|
|
2019-04-20 16:12:22 +08:00
|
|
|
|
if(vkCreateFence(attr->device, &fenceInfo, nullptr, &fence)!=VK_SUCCESS)
|
2019-04-19 19:58:01 +08:00
|
|
|
|
return(nullptr);
|
|
|
|
|
|
2019-04-20 16:12:22 +08:00
|
|
|
|
return(new Fence(attr->device,fence));
|
2019-04-19 19:58:01 +08:00
|
|
|
|
}
|
2019-04-19 20:04:08 +08:00
|
|
|
|
|
|
|
|
|
Semaphore *Device::CreateSem()
|
|
|
|
|
{
|
|
|
|
|
VkSemaphoreCreateInfo SemaphoreCreateInfo;
|
|
|
|
|
SemaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
|
|
|
|
SemaphoreCreateInfo.pNext = nullptr;
|
|
|
|
|
SemaphoreCreateInfo.flags = 0;
|
|
|
|
|
|
|
|
|
|
VkSemaphore sem;
|
|
|
|
|
if(vkCreateSemaphore(attr->device, &SemaphoreCreateInfo, nullptr, &sem)!=VK_SUCCESS)
|
|
|
|
|
return(nullptr);
|
|
|
|
|
|
|
|
|
|
return(new Semaphore(attr->device,sem));
|
|
|
|
|
}
|
2019-04-19 20:10:59 +08:00
|
|
|
|
|
2019-04-28 16:06:53 +08:00
|
|
|
|
ShaderModuleManage *Device::CreateShaderModuleManage()
|
|
|
|
|
{
|
|
|
|
|
return(new ShaderModuleManage(this));
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-18 00:48:05 +08:00
|
|
|
|
bool Device::Wait(bool wait_all,uint64_t time_out)
|
|
|
|
|
{
|
|
|
|
|
VkFence fence=*fence_list[current_fence];
|
|
|
|
|
|
|
|
|
|
VkResult result;
|
|
|
|
|
|
|
|
|
|
result=vkWaitForFences(attr->device,1,&fence,wait_all,time_out);
|
|
|
|
|
result=vkResetFences(attr->device,1,&fence);
|
|
|
|
|
|
|
|
|
|
return(true);
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-19 20:10:59 +08:00
|
|
|
|
bool Device::AcquireNextImage()
|
|
|
|
|
{
|
2019-06-15 23:52:10 +08:00
|
|
|
|
return(vkAcquireNextImageKHR(attr->device,attr->swap_chain,UINT64_MAX,*present_complete_semaphore,VK_NULL_HANDLE,¤t_frame)==VK_SUCCESS);
|
2019-04-19 20:10:59 +08:00
|
|
|
|
}
|
2019-04-19 20:23:14 +08:00
|
|
|
|
|
2019-05-20 13:50:11 +08:00
|
|
|
|
bool Device::SubmitDraw(const VkCommandBuffer *cmd_bufs,const uint32_t count)
|
2019-04-19 20:23:14 +08:00
|
|
|
|
{
|
2019-05-20 13:50:11 +08:00
|
|
|
|
if(!cmd_bufs||count<=0)
|
2019-04-19 20:23:14 +08:00
|
|
|
|
return(false);
|
|
|
|
|
|
2019-05-05 11:54:49 +08:00
|
|
|
|
submit_info.commandBufferCount = count;
|
|
|
|
|
submit_info.pCommandBuffers = cmd_bufs;
|
2019-06-17 21:59:54 +08:00
|
|
|
|
|
2019-06-16 00:08:42 +08:00
|
|
|
|
VkFence fence=*fence_list[current_fence];
|
2019-04-20 16:12:22 +08:00
|
|
|
|
|
2019-06-15 23:52:10 +08:00
|
|
|
|
VkResult result=vkQueueSubmit(attr->graphics_queue,1,&submit_info,fence);
|
2019-06-26 11:26:38 +08:00
|
|
|
|
|
2019-06-17 21:59:54 +08:00
|
|
|
|
if(++current_fence==swap_chain_count)
|
|
|
|
|
current_fence=0;
|
|
|
|
|
|
2019-06-26 11:26:38 +08:00
|
|
|
|
//不在这里立即等待fence完成,是因为有可能queue submit需要久一点工作时间,我们这个时间可以去干别的。等在AcquireNextImage时再去等待fence,而且是另一帧的fence。这样有利于异步处理
|
|
|
|
|
|
2019-06-18 00:48:05 +08:00
|
|
|
|
return(result==VK_SUCCESS);
|
2019-04-19 20:23:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Device::QueuePresent()
|
|
|
|
|
{
|
2019-06-15 23:52:10 +08:00
|
|
|
|
present_info.pImageIndices=¤t_frame;
|
2019-06-15 22:02:20 +08:00
|
|
|
|
|
2019-06-18 14:58:00 +08:00
|
|
|
|
VkResult result=vkQueuePresentKHR(attr->graphics_queue,&present_info);
|
|
|
|
|
|
|
|
|
|
if (!((result == VK_SUCCESS) || (result == VK_SUBOPTIMAL_KHR)))
|
|
|
|
|
{
|
|
|
|
|
if (result == VK_ERROR_OUT_OF_DATE_KHR) {
|
|
|
|
|
// Swap chain is no longer compatible with the surface and needs to be recreated
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result=vkQueueWaitIdle(attr->graphics_queue);
|
|
|
|
|
|
|
|
|
|
if(result!=VK_SUCCESS)
|
2019-06-15 23:52:10 +08:00
|
|
|
|
return(false);
|
2019-04-19 20:23:14 +08:00
|
|
|
|
|
2019-06-15 23:52:10 +08:00
|
|
|
|
return(true);
|
2019-04-19 20:23:14 +08:00
|
|
|
|
}
|
2019-04-10 21:54:39 +08:00
|
|
|
|
VK_NAMESPACE_END
|