mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-15 09:27:00 +00:00
Examples: Vulkan: Various tweak. Misc refactor into per-frame data. Duplicate buffer creation code moved to CreateOrResizeBuffer().
This commit is contained in:
parent
9da475e4e8
commit
e927a6ac4a
@ -32,28 +32,32 @@ static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE;
|
|||||||
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
|
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
|
||||||
static void (*g_CheckVkResult)(VkResult err) = NULL;
|
static void (*g_CheckVkResult)(VkResult err) = NULL;
|
||||||
|
|
||||||
static VkCommandBuffer g_CommandBuffer = VK_NULL_HANDLE;
|
|
||||||
static VkDeviceSize g_BufferMemoryAlignment = 256;
|
static VkDeviceSize g_BufferMemoryAlignment = 256;
|
||||||
static VkPipelineCreateFlags g_PipelineCreateFlags = 0;
|
static VkPipelineCreateFlags g_PipelineCreateFlags = 0;
|
||||||
static int g_FrameIndex = 0;
|
|
||||||
|
|
||||||
static VkDescriptorSetLayout g_DescriptorSetLayout = VK_NULL_HANDLE;
|
static VkDescriptorSetLayout g_DescriptorSetLayout = VK_NULL_HANDLE;
|
||||||
static VkPipelineLayout g_PipelineLayout = VK_NULL_HANDLE;
|
static VkPipelineLayout g_PipelineLayout = VK_NULL_HANDLE;
|
||||||
static VkDescriptorSet g_DescriptorSet = VK_NULL_HANDLE;
|
static VkDescriptorSet g_DescriptorSet = VK_NULL_HANDLE;
|
||||||
static VkPipeline g_Pipeline = VK_NULL_HANDLE;
|
static VkPipeline g_Pipeline = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
// Frame data
|
||||||
|
struct FrameDataForRender
|
||||||
|
{
|
||||||
|
VkDeviceMemory VertexBufferMemory;
|
||||||
|
VkDeviceMemory IndexBufferMemory;
|
||||||
|
VkDeviceSize VertexBufferSize;
|
||||||
|
VkDeviceSize IndexBufferSize;
|
||||||
|
VkBuffer VertexBuffer;
|
||||||
|
VkBuffer IndexBuffer;
|
||||||
|
};
|
||||||
|
static int g_FrameIndex = 0;
|
||||||
|
static FrameDataForRender g_FramesDataBuffers[IMGUI_VK_QUEUED_FRAMES];
|
||||||
|
|
||||||
|
// Font data
|
||||||
static VkSampler g_FontSampler = VK_NULL_HANDLE;
|
static VkSampler g_FontSampler = VK_NULL_HANDLE;
|
||||||
static VkDeviceMemory g_FontMemory = VK_NULL_HANDLE;
|
static VkDeviceMemory g_FontMemory = VK_NULL_HANDLE;
|
||||||
static VkImage g_FontImage = VK_NULL_HANDLE;
|
static VkImage g_FontImage = VK_NULL_HANDLE;
|
||||||
static VkImageView g_FontView = VK_NULL_HANDLE;
|
static VkImageView g_FontView = VK_NULL_HANDLE;
|
||||||
|
|
||||||
static VkDeviceMemory g_VertexBufferMemory[IMGUI_VK_QUEUED_FRAMES] = {};
|
|
||||||
static VkDeviceMemory g_IndexBufferMemory[IMGUI_VK_QUEUED_FRAMES] = {};
|
|
||||||
static VkDeviceSize g_VertexBufferSize[IMGUI_VK_QUEUED_FRAMES] = {};
|
|
||||||
static VkDeviceSize g_IndexBufferSize[IMGUI_VK_QUEUED_FRAMES] = {};
|
|
||||||
static VkBuffer g_VertexBuffer[IMGUI_VK_QUEUED_FRAMES] = {};
|
|
||||||
static VkBuffer g_IndexBuffer[IMGUI_VK_QUEUED_FRAMES] = {};
|
|
||||||
|
|
||||||
static VkDeviceMemory g_UploadBufferMemory = VK_NULL_HANDLE;
|
static VkDeviceMemory g_UploadBufferMemory = VK_NULL_HANDLE;
|
||||||
static VkBuffer g_UploadBuffer = VK_NULL_HANDLE;
|
static VkBuffer g_UploadBuffer = VK_NULL_HANDLE;
|
||||||
|
|
||||||
@ -61,6 +65,8 @@ static VkBuffer g_UploadBuffer = VK_NULL_HANDLE;
|
|||||||
static void ImGui_ImplVulkan_InitPlatformInterface();
|
static void ImGui_ImplVulkan_InitPlatformInterface();
|
||||||
static void ImGui_ImplVulkan_ShutdownPlatformInterface();
|
static void ImGui_ImplVulkan_ShutdownPlatformInterface();
|
||||||
|
|
||||||
|
// glsl_shader.vert, compiled with:
|
||||||
|
// # glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert
|
||||||
static uint32_t __glsl_shader_vert_spv[] =
|
static uint32_t __glsl_shader_vert_spv[] =
|
||||||
{
|
{
|
||||||
0x07230203,0x00010000,0x00080001,0x0000002e,0x00000000,0x00020011,0x00000001,0x0006000b,
|
0x07230203,0x00010000,0x00080001,0x0000002e,0x00000000,0x00020011,0x00000001,0x0006000b,
|
||||||
@ -106,6 +112,8 @@ static uint32_t __glsl_shader_vert_spv[] =
|
|||||||
0x0000002d,0x0000002c,0x000100fd,0x00010038
|
0x0000002d,0x0000002c,0x000100fd,0x00010038
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// glsl_shader.frag, compiled with:
|
||||||
|
// # glslangValidator -V -x -o glsl_shader.frag.u32 glsl_shader.frag
|
||||||
static uint32_t __glsl_shader_frag_spv[] =
|
static uint32_t __glsl_shader_frag_spv[] =
|
||||||
{
|
{
|
||||||
0x07230203,0x00010000,0x00080001,0x0000001e,0x00000000,0x00020011,0x00000001,0x0006000b,
|
0x07230203,0x00010000,0x00080001,0x0000001e,0x00000000,0x00020011,0x00000001,0x0006000b,
|
||||||
@ -151,81 +159,63 @@ static void ImGui_ImplVulkan_VkResult(VkResult err)
|
|||||||
g_CheckVkResult(err);
|
g_CheckVkResult(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory, VkDeviceSize& p_buffer_size, size_t new_size, VkBufferUsageFlagBits usage)
|
||||||
|
{
|
||||||
|
VkResult err;
|
||||||
|
if (buffer != NULL)
|
||||||
|
vkDestroyBuffer(g_Device, buffer, g_Allocator);
|
||||||
|
if (buffer_memory)
|
||||||
|
vkFreeMemory(g_Device, buffer_memory, g_Allocator);
|
||||||
|
|
||||||
|
VkDeviceSize vertex_buffer_size_aligned = ((new_size - 1) / g_BufferMemoryAlignment + 1) * g_BufferMemoryAlignment;
|
||||||
|
VkBufferCreateInfo buffer_info = {};
|
||||||
|
buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||||
|
buffer_info.size = vertex_buffer_size_aligned;
|
||||||
|
buffer_info.usage = usage;
|
||||||
|
buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
err = vkCreateBuffer(g_Device, &buffer_info, g_Allocator, &buffer);
|
||||||
|
ImGui_ImplVulkan_VkResult(err);
|
||||||
|
|
||||||
|
VkMemoryRequirements req;
|
||||||
|
vkGetBufferMemoryRequirements(g_Device, buffer, &req);
|
||||||
|
g_BufferMemoryAlignment = (g_BufferMemoryAlignment > req.alignment) ? g_BufferMemoryAlignment : req.alignment;
|
||||||
|
VkMemoryAllocateInfo alloc_info = {};
|
||||||
|
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||||
|
alloc_info.allocationSize = req.size;
|
||||||
|
alloc_info.memoryTypeIndex = ImGui_ImplVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits);
|
||||||
|
err = vkAllocateMemory(g_Device, &alloc_info, g_Allocator, &buffer_memory);
|
||||||
|
ImGui_ImplVulkan_VkResult(err);
|
||||||
|
|
||||||
|
err = vkBindBufferMemory(g_Device, buffer, buffer_memory, 0);
|
||||||
|
ImGui_ImplVulkan_VkResult(err);
|
||||||
|
p_buffer_size = new_size;
|
||||||
|
}
|
||||||
|
|
||||||
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
|
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
|
||||||
void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data)
|
void ImGui_ImplVulkan_RenderDrawData(VkCommandBuffer command_buffer, ImDrawData* draw_data)
|
||||||
{
|
{
|
||||||
VkResult err;
|
VkResult err;
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
if (draw_data->TotalVtxCount == 0)
|
if (draw_data->TotalVtxCount == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Create the Vertex Buffer:
|
FrameDataForRender* fd = &g_FramesDataBuffers[g_FrameIndex];
|
||||||
size_t vertex_size = draw_data->TotalVtxCount * sizeof(ImDrawVert);
|
|
||||||
if (!g_VertexBuffer[g_FrameIndex] || g_VertexBufferSize[g_FrameIndex] < vertex_size)
|
|
||||||
{
|
|
||||||
if (g_VertexBuffer[g_FrameIndex])
|
|
||||||
vkDestroyBuffer(g_Device, g_VertexBuffer[g_FrameIndex], g_Allocator);
|
|
||||||
if (g_VertexBufferMemory[g_FrameIndex])
|
|
||||||
vkFreeMemory(g_Device, g_VertexBufferMemory[g_FrameIndex], g_Allocator);
|
|
||||||
VkDeviceSize vertex_buffer_size = ((vertex_size-1) / g_BufferMemoryAlignment+1) * g_BufferMemoryAlignment;
|
|
||||||
VkBufferCreateInfo buffer_info = {};
|
|
||||||
buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
|
||||||
buffer_info.size = vertex_buffer_size;
|
|
||||||
buffer_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
|
|
||||||
buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
|
||||||
err = vkCreateBuffer(g_Device, &buffer_info, g_Allocator, &g_VertexBuffer[g_FrameIndex]);
|
|
||||||
ImGui_ImplVulkan_VkResult(err);
|
|
||||||
VkMemoryRequirements req;
|
|
||||||
vkGetBufferMemoryRequirements(g_Device, g_VertexBuffer[g_FrameIndex], &req);
|
|
||||||
g_BufferMemoryAlignment = (g_BufferMemoryAlignment > req.alignment) ? g_BufferMemoryAlignment : req.alignment;
|
|
||||||
VkMemoryAllocateInfo alloc_info = {};
|
|
||||||
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
|
||||||
alloc_info.allocationSize = req.size;
|
|
||||||
alloc_info.memoryTypeIndex = ImGui_ImplVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits);
|
|
||||||
err = vkAllocateMemory(g_Device, &alloc_info, g_Allocator, &g_VertexBufferMemory[g_FrameIndex]);
|
|
||||||
ImGui_ImplVulkan_VkResult(err);
|
|
||||||
err = vkBindBufferMemory(g_Device, g_VertexBuffer[g_FrameIndex], g_VertexBufferMemory[g_FrameIndex], 0);
|
|
||||||
ImGui_ImplVulkan_VkResult(err);
|
|
||||||
g_VertexBufferSize[g_FrameIndex] = vertex_buffer_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the Index Buffer:
|
// Create the Vertex and Index buffers:
|
||||||
|
size_t vertex_size = draw_data->TotalVtxCount * sizeof(ImDrawVert);
|
||||||
size_t index_size = draw_data->TotalIdxCount * sizeof(ImDrawIdx);
|
size_t index_size = draw_data->TotalIdxCount * sizeof(ImDrawIdx);
|
||||||
if (!g_IndexBuffer[g_FrameIndex] || g_IndexBufferSize[g_FrameIndex] < index_size)
|
if (!fd->VertexBuffer || fd->VertexBufferSize < vertex_size)
|
||||||
{
|
CreateOrResizeBuffer(fd->VertexBuffer, fd->VertexBufferMemory, fd->VertexBufferSize, vertex_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
|
||||||
if (g_IndexBuffer[g_FrameIndex])
|
if (!fd->IndexBuffer || fd->IndexBufferSize < index_size)
|
||||||
vkDestroyBuffer(g_Device, g_IndexBuffer[g_FrameIndex], g_Allocator);
|
CreateOrResizeBuffer(fd->IndexBuffer, fd->IndexBufferMemory, fd->IndexBufferSize, index_size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
|
||||||
if (g_IndexBufferMemory[g_FrameIndex])
|
|
||||||
vkFreeMemory(g_Device, g_IndexBufferMemory[g_FrameIndex], g_Allocator);
|
|
||||||
VkDeviceSize index_buffer_size = ((index_size-1) / g_BufferMemoryAlignment+1) * g_BufferMemoryAlignment;
|
|
||||||
VkBufferCreateInfo buffer_info = {};
|
|
||||||
buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
|
||||||
buffer_info.size = index_buffer_size;
|
|
||||||
buffer_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
|
|
||||||
buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
|
||||||
err = vkCreateBuffer(g_Device, &buffer_info, g_Allocator, &g_IndexBuffer[g_FrameIndex]);
|
|
||||||
ImGui_ImplVulkan_VkResult(err);
|
|
||||||
VkMemoryRequirements req;
|
|
||||||
vkGetBufferMemoryRequirements(g_Device, g_IndexBuffer[g_FrameIndex], &req);
|
|
||||||
g_BufferMemoryAlignment = (g_BufferMemoryAlignment > req.alignment) ? g_BufferMemoryAlignment : req.alignment;
|
|
||||||
VkMemoryAllocateInfo alloc_info = {};
|
|
||||||
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
|
||||||
alloc_info.allocationSize = req.size;
|
|
||||||
alloc_info.memoryTypeIndex = ImGui_ImplVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits);
|
|
||||||
err = vkAllocateMemory(g_Device, &alloc_info, g_Allocator, &g_IndexBufferMemory[g_FrameIndex]);
|
|
||||||
ImGui_ImplVulkan_VkResult(err);
|
|
||||||
err = vkBindBufferMemory(g_Device, g_IndexBuffer[g_FrameIndex], g_IndexBufferMemory[g_FrameIndex], 0);
|
|
||||||
ImGui_ImplVulkan_VkResult(err);
|
|
||||||
g_IndexBufferSize[g_FrameIndex] = index_buffer_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Upload Vertex and index Data:
|
// Upload Vertex and index Data:
|
||||||
{
|
{
|
||||||
ImDrawVert* vtx_dst;
|
ImDrawVert* vtx_dst;
|
||||||
ImDrawIdx* idx_dst;
|
ImDrawIdx* idx_dst;
|
||||||
err = vkMapMemory(g_Device, g_VertexBufferMemory[g_FrameIndex], 0, vertex_size, 0, (void**)(&vtx_dst));
|
err = vkMapMemory(g_Device, fd->VertexBufferMemory, 0, vertex_size, 0, (void**)(&vtx_dst));
|
||||||
ImGui_ImplVulkan_VkResult(err);
|
ImGui_ImplVulkan_VkResult(err);
|
||||||
err = vkMapMemory(g_Device, g_IndexBufferMemory[g_FrameIndex], 0, index_size, 0, (void**)(&idx_dst));
|
err = vkMapMemory(g_Device, fd->IndexBufferMemory, 0, index_size, 0, (void**)(&idx_dst));
|
||||||
ImGui_ImplVulkan_VkResult(err);
|
ImGui_ImplVulkan_VkResult(err);
|
||||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||||
{
|
{
|
||||||
@ -237,30 +227,30 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data)
|
|||||||
}
|
}
|
||||||
VkMappedMemoryRange range[2] = {};
|
VkMappedMemoryRange range[2] = {};
|
||||||
range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
|
range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
|
||||||
range[0].memory = g_VertexBufferMemory[g_FrameIndex];
|
range[0].memory = fd->VertexBufferMemory;
|
||||||
range[0].size = VK_WHOLE_SIZE;
|
range[0].size = VK_WHOLE_SIZE;
|
||||||
range[1].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
|
range[1].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
|
||||||
range[1].memory = g_IndexBufferMemory[g_FrameIndex];
|
range[1].memory = fd->IndexBufferMemory;
|
||||||
range[1].size = VK_WHOLE_SIZE;
|
range[1].size = VK_WHOLE_SIZE;
|
||||||
err = vkFlushMappedMemoryRanges(g_Device, 2, range);
|
err = vkFlushMappedMemoryRanges(g_Device, 2, range);
|
||||||
ImGui_ImplVulkan_VkResult(err);
|
ImGui_ImplVulkan_VkResult(err);
|
||||||
vkUnmapMemory(g_Device, g_VertexBufferMemory[g_FrameIndex]);
|
vkUnmapMemory(g_Device, fd->VertexBufferMemory);
|
||||||
vkUnmapMemory(g_Device, g_IndexBufferMemory[g_FrameIndex]);
|
vkUnmapMemory(g_Device, fd->IndexBufferMemory);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind pipeline and descriptor sets:
|
// Bind pipeline and descriptor sets:
|
||||||
{
|
{
|
||||||
vkCmdBindPipeline(g_CommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_Pipeline);
|
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_Pipeline);
|
||||||
VkDescriptorSet desc_set[1] = { g_DescriptorSet };
|
VkDescriptorSet desc_set[1] = { g_DescriptorSet };
|
||||||
vkCmdBindDescriptorSets(g_CommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_PipelineLayout, 0, 1, desc_set, 0, NULL);
|
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_PipelineLayout, 0, 1, desc_set, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind Vertex And Index Buffer:
|
// Bind Vertex And Index Buffer:
|
||||||
{
|
{
|
||||||
VkBuffer vertex_buffers[1] = {g_VertexBuffer[g_FrameIndex]};
|
VkBuffer vertex_buffers[1] = { fd->VertexBuffer };
|
||||||
VkDeviceSize vertex_offset[1] = { 0 };
|
VkDeviceSize vertex_offset[1] = { 0 };
|
||||||
vkCmdBindVertexBuffers(g_CommandBuffer, 0, 1, vertex_buffers, vertex_offset);
|
vkCmdBindVertexBuffers(command_buffer, 0, 1, vertex_buffers, vertex_offset);
|
||||||
vkCmdBindIndexBuffer(g_CommandBuffer, g_IndexBuffer[g_FrameIndex], 0, VK_INDEX_TYPE_UINT16);
|
vkCmdBindIndexBuffer(command_buffer, fd->IndexBuffer, 0, VK_INDEX_TYPE_UINT16);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup viewport:
|
// Setup viewport:
|
||||||
@ -272,7 +262,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data)
|
|||||||
viewport.height = io.DisplaySize.y;
|
viewport.height = io.DisplaySize.y;
|
||||||
viewport.minDepth = 0.0f;
|
viewport.minDepth = 0.0f;
|
||||||
viewport.maxDepth = 1.0f;
|
viewport.maxDepth = 1.0f;
|
||||||
vkCmdSetViewport(g_CommandBuffer, 0, 1, &viewport);
|
vkCmdSetViewport(command_buffer, 0, 1, &viewport);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup scale and translation:
|
// Setup scale and translation:
|
||||||
@ -284,8 +274,8 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data)
|
|||||||
float translate[2];
|
float translate[2];
|
||||||
translate[0] = -1.0f - io.DisplayPos.x * scale[0];
|
translate[0] = -1.0f - io.DisplayPos.x * scale[0];
|
||||||
translate[1] = -1.0f - io.DisplayPos.y * scale[1];
|
translate[1] = -1.0f - io.DisplayPos.y * scale[1];
|
||||||
vkCmdPushConstants(g_CommandBuffer, g_PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, sizeof(float) * 0, sizeof(float) * 2, scale);
|
vkCmdPushConstants(command_buffer, g_PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, sizeof(float) * 0, sizeof(float) * 2, scale);
|
||||||
vkCmdPushConstants(g_CommandBuffer, g_PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, sizeof(float) * 2, sizeof(float) * 2, translate);
|
vkCmdPushConstants(command_buffer, g_PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, sizeof(float) * 2, sizeof(float) * 2, translate);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the command lists:
|
// Render the command lists:
|
||||||
@ -310,10 +300,10 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data)
|
|||||||
scissor.offset.y = (int32_t)(pcmd->ClipRect.y - io.DisplayPos.y) > 0 ? (int32_t)(pcmd->ClipRect.y - io.DisplayPos.y) : 0;
|
scissor.offset.y = (int32_t)(pcmd->ClipRect.y - io.DisplayPos.y) > 0 ? (int32_t)(pcmd->ClipRect.y - io.DisplayPos.y) : 0;
|
||||||
scissor.extent.width = (uint32_t)(pcmd->ClipRect.z - pcmd->ClipRect.x);
|
scissor.extent.width = (uint32_t)(pcmd->ClipRect.z - pcmd->ClipRect.x);
|
||||||
scissor.extent.height = (uint32_t)(pcmd->ClipRect.w - pcmd->ClipRect.y + 1); // FIXME: Why +1 here?
|
scissor.extent.height = (uint32_t)(pcmd->ClipRect.w - pcmd->ClipRect.y + 1); // FIXME: Why +1 here?
|
||||||
vkCmdSetScissor(g_CommandBuffer, 0, 1, &scissor);
|
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
vkCmdDrawIndexed(g_CommandBuffer, pcmd->ElemCount, 1, idx_offset, vtx_offset, 0);
|
vkCmdDrawIndexed(command_buffer, pcmd->ElemCount, 1, idx_offset, vtx_offset, 0);
|
||||||
}
|
}
|
||||||
idx_offset += pcmd->ElemCount;
|
idx_offset += pcmd->ElemCount;
|
||||||
}
|
}
|
||||||
@ -540,6 +530,7 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
|
|||||||
|
|
||||||
if (!g_PipelineLayout)
|
if (!g_PipelineLayout)
|
||||||
{
|
{
|
||||||
|
// Constants: we are using 'vec2 offset' and 'vec2 scale' instead of a full 3d projection matrix
|
||||||
VkPushConstantRange push_constants[1] = {};
|
VkPushConstantRange push_constants[1] = {};
|
||||||
push_constants[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
push_constants[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||||
push_constants[0].offset = sizeof(float) * 0;
|
push_constants[0].offset = sizeof(float) * 0;
|
||||||
@ -573,15 +564,15 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
|
|||||||
attribute_desc[0].location = 0;
|
attribute_desc[0].location = 0;
|
||||||
attribute_desc[0].binding = binding_desc[0].binding;
|
attribute_desc[0].binding = binding_desc[0].binding;
|
||||||
attribute_desc[0].format = VK_FORMAT_R32G32_SFLOAT;
|
attribute_desc[0].format = VK_FORMAT_R32G32_SFLOAT;
|
||||||
attribute_desc[0].offset = (size_t)(&((ImDrawVert*)0)->pos);
|
attribute_desc[0].offset = IM_OFFSETOF(ImDrawVert, pos);
|
||||||
attribute_desc[1].location = 1;
|
attribute_desc[1].location = 1;
|
||||||
attribute_desc[1].binding = binding_desc[0].binding;
|
attribute_desc[1].binding = binding_desc[0].binding;
|
||||||
attribute_desc[1].format = VK_FORMAT_R32G32_SFLOAT;
|
attribute_desc[1].format = VK_FORMAT_R32G32_SFLOAT;
|
||||||
attribute_desc[1].offset = (size_t)(&((ImDrawVert*)0)->uv);
|
attribute_desc[1].offset = IM_OFFSETOF(ImDrawVert, uv);
|
||||||
attribute_desc[2].location = 2;
|
attribute_desc[2].location = 2;
|
||||||
attribute_desc[2].binding = binding_desc[0].binding;
|
attribute_desc[2].binding = binding_desc[0].binding;
|
||||||
attribute_desc[2].format = VK_FORMAT_R8G8B8A8_UNORM;
|
attribute_desc[2].format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||||
attribute_desc[2].offset = (size_t)(&((ImDrawVert*)0)->col);
|
attribute_desc[2].offset = IM_OFFSETOF(ImDrawVert, col);
|
||||||
|
|
||||||
VkPipelineVertexInputStateCreateInfo vertex_info = {};
|
VkPipelineVertexInputStateCreateInfo vertex_info = {};
|
||||||
vertex_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
vertex_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||||
@ -678,10 +669,11 @@ void ImGui_ImplVulkan_InvalidateDeviceObjects()
|
|||||||
|
|
||||||
for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++)
|
for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++)
|
||||||
{
|
{
|
||||||
if (g_VertexBuffer[i]) { vkDestroyBuffer(g_Device, g_VertexBuffer[i], g_Allocator); g_VertexBuffer[i] = VK_NULL_HANDLE; }
|
FrameDataForRender* fd = &g_FramesDataBuffers[i];
|
||||||
if (g_VertexBufferMemory[i]) { vkFreeMemory(g_Device, g_VertexBufferMemory[i], g_Allocator); g_VertexBufferMemory[i] = VK_NULL_HANDLE; }
|
if (fd->VertexBuffer) { vkDestroyBuffer (g_Device, fd->VertexBuffer, g_Allocator); fd->VertexBuffer = VK_NULL_HANDLE; }
|
||||||
if (g_IndexBuffer[i]) { vkDestroyBuffer(g_Device, g_IndexBuffer[i], g_Allocator); g_IndexBuffer[i] = VK_NULL_HANDLE; }
|
if (fd->VertexBufferMemory) { vkFreeMemory (g_Device, fd->VertexBufferMemory, g_Allocator); fd->VertexBufferMemory = VK_NULL_HANDLE; }
|
||||||
if (g_IndexBufferMemory[i]) { vkFreeMemory(g_Device, g_IndexBufferMemory[i], g_Allocator); g_IndexBufferMemory[i] = VK_NULL_HANDLE; }
|
if (fd->IndexBuffer) { vkDestroyBuffer (g_Device, fd->IndexBuffer, g_Allocator); fd->IndexBuffer = VK_NULL_HANDLE; }
|
||||||
|
if (fd->IndexBufferMemory) { vkFreeMemory (g_Device, fd->IndexBufferMemory, g_Allocator); fd->IndexBufferMemory = VK_NULL_HANDLE; }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_FontView) { vkDestroyImageView(g_Device, g_FontView, g_Allocator); g_FontView = VK_NULL_HANDLE; }
|
if (g_FontView) { vkDestroyImageView(g_Device, g_FontView, g_Allocator); g_FontView = VK_NULL_HANDLE; }
|
||||||
@ -723,10 +715,8 @@ void ImGui_ImplVulkan_NewFrame()
|
|||||||
|
|
||||||
void ImGui_ImplVulkan_Render(VkCommandBuffer command_buffer)
|
void ImGui_ImplVulkan_Render(VkCommandBuffer command_buffer)
|
||||||
{
|
{
|
||||||
g_CommandBuffer = command_buffer;
|
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData());
|
ImGui_ImplVulkan_RenderDrawData(command_buffer, ImGui::GetDrawData());
|
||||||
g_CommandBuffer = VK_NULL_HANDLE;
|
|
||||||
g_FrameIndex = (g_FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES;
|
g_FrameIndex = (g_FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ IMGUI_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo *init_data
|
|||||||
IMGUI_API void ImGui_ImplVulkan_Shutdown();
|
IMGUI_API void ImGui_ImplVulkan_Shutdown();
|
||||||
IMGUI_API void ImGui_ImplVulkan_NewFrame();
|
IMGUI_API void ImGui_ImplVulkan_NewFrame();
|
||||||
IMGUI_API void ImGui_ImplVulkan_Render(VkCommandBuffer command_buffer);
|
IMGUI_API void ImGui_ImplVulkan_Render(VkCommandBuffer command_buffer);
|
||||||
|
IMGUI_API void ImGui_ImplVulkan_RenderDrawData(VkCommandBuffer command_buffer, ImDrawData* draw_data);
|
||||||
|
|
||||||
// Called by Init/NewFrame/Shutdown
|
// Called by Init/NewFrame/Shutdown
|
||||||
IMGUI_API void ImGui_ImplVulkan_InvalidateFontUploadObjects();
|
IMGUI_API void ImGui_ImplVulkan_InvalidateFontUploadObjects();
|
||||||
|
@ -34,18 +34,22 @@ static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE;
|
|||||||
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
|
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
|
||||||
|
|
||||||
static int fb_width, fb_height;
|
static int fb_width, fb_height;
|
||||||
static uint32_t g_BackbufferIndices[IMGUI_VK_QUEUED_FRAMES]; // keep track of recently rendered swapchain frame indices
|
|
||||||
static uint32_t g_BackBufferCount = 0;
|
static uint32_t g_BackBufferCount = 0;
|
||||||
static VkImage g_BackBuffer[IMGUI_MAX_POSSIBLE_BACK_BUFFERS] = {};
|
static VkImage g_BackBuffer[IMGUI_MAX_POSSIBLE_BACK_BUFFERS] = {};
|
||||||
static VkImageView g_BackBufferView[IMGUI_MAX_POSSIBLE_BACK_BUFFERS] = {};
|
static VkImageView g_BackBufferView[IMGUI_MAX_POSSIBLE_BACK_BUFFERS] = {};
|
||||||
static VkFramebuffer g_Framebuffer[IMGUI_MAX_POSSIBLE_BACK_BUFFERS] = {};
|
static VkFramebuffer g_Framebuffer[IMGUI_MAX_POSSIBLE_BACK_BUFFERS] = {};
|
||||||
|
|
||||||
|
struct FrameData
|
||||||
|
{
|
||||||
|
uint32_t BackbufferIndex; // keep track of recently rendered swapchain frame indices
|
||||||
|
VkCommandPool CommandPool;
|
||||||
|
VkCommandBuffer CommandBuffer;
|
||||||
|
VkFence Fence;
|
||||||
|
VkSemaphore PresentCompleteSemaphore;
|
||||||
|
VkSemaphore RenderCompleteSemaphore;
|
||||||
|
};
|
||||||
static uint32_t g_FrameIndex = 0;
|
static uint32_t g_FrameIndex = 0;
|
||||||
static VkCommandPool g_CommandPool[IMGUI_VK_QUEUED_FRAMES];
|
static FrameData g_Frames[IMGUI_VK_QUEUED_FRAMES] = {};
|
||||||
static VkCommandBuffer g_CommandBuffer[IMGUI_VK_QUEUED_FRAMES];
|
|
||||||
static VkFence g_Fence[IMGUI_VK_QUEUED_FRAMES];
|
|
||||||
static VkSemaphore g_PresentCompleteSemaphore[IMGUI_VK_QUEUED_FRAMES];
|
|
||||||
static VkSemaphore g_RenderCompleteSemaphore[IMGUI_VK_QUEUED_FRAMES];
|
|
||||||
|
|
||||||
static VkClearValue g_ClearValue = {};
|
static VkClearValue g_ClearValue = {};
|
||||||
|
|
||||||
@ -295,6 +299,7 @@ static void setup_vulkan(SDL_Window* window, const char** extensions, uint32_t e
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Get Surface Format
|
// Get Surface Format
|
||||||
{
|
{
|
||||||
const VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM };
|
const VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM };
|
||||||
@ -347,43 +352,44 @@ static void setup_vulkan(SDL_Window* window, const char** extensions, uint32_t e
|
|||||||
// Create Command Buffers
|
// Create Command Buffers
|
||||||
for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++)
|
for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++)
|
||||||
{
|
{
|
||||||
|
FrameData* fd = &g_Frames[i];
|
||||||
{
|
{
|
||||||
VkCommandPoolCreateInfo info = {};
|
VkCommandPoolCreateInfo info = {};
|
||||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||||
info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
||||||
info.queueFamilyIndex = g_QueueFamily;
|
info.queueFamilyIndex = g_QueueFamily;
|
||||||
err = vkCreateCommandPool(g_Device, &info, g_Allocator, &g_CommandPool[i]);
|
err = vkCreateCommandPool(g_Device, &info, g_Allocator, &fd->CommandPool);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
VkCommandBufferAllocateInfo info = {};
|
VkCommandBufferAllocateInfo info = {};
|
||||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||||
info.commandPool = g_CommandPool[i];
|
info.commandPool = fd->CommandPool;
|
||||||
info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||||
info.commandBufferCount = 1;
|
info.commandBufferCount = 1;
|
||||||
err = vkAllocateCommandBuffers(g_Device, &info, &g_CommandBuffer[i]);
|
err = vkAllocateCommandBuffers(g_Device, &info, &fd->CommandBuffer);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
VkFenceCreateInfo info = {};
|
VkFenceCreateInfo info = {};
|
||||||
info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||||
info.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
info.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||||
err = vkCreateFence(g_Device, &info, g_Allocator, &g_Fence[i]);
|
err = vkCreateFence(g_Device, &info, g_Allocator, &fd->Fence);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
VkSemaphoreCreateInfo info = {};
|
VkSemaphoreCreateInfo info = {};
|
||||||
info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||||
err = vkCreateSemaphore(g_Device, &info, g_Allocator, &g_PresentCompleteSemaphore[i]);
|
err = vkCreateSemaphore(g_Device, &info, g_Allocator, &fd->PresentCompleteSemaphore);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
err = vkCreateSemaphore(g_Device, &info, g_Allocator, &g_RenderCompleteSemaphore[i]);
|
err = vkCreateSemaphore(g_Device, &info, g_Allocator, &fd->RenderCompleteSemaphore);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create Descriptor Pool
|
// Create Descriptor Pool
|
||||||
{
|
{
|
||||||
VkDescriptorPoolSize pool_size[11] =
|
VkDescriptorPoolSize pool_sizes[] =
|
||||||
{
|
{
|
||||||
{ VK_DESCRIPTOR_TYPE_SAMPLER, 1000 },
|
{ VK_DESCRIPTOR_TYPE_SAMPLER, 1000 },
|
||||||
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 },
|
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 },
|
||||||
@ -400,9 +406,9 @@ static void setup_vulkan(SDL_Window* window, const char** extensions, uint32_t e
|
|||||||
VkDescriptorPoolCreateInfo pool_info = {};
|
VkDescriptorPoolCreateInfo pool_info = {};
|
||||||
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||||
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
|
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
|
||||||
pool_info.maxSets = 1000 * 11;
|
pool_info.maxSets = 1000 * IM_ARRAYSIZE(pool_sizes);
|
||||||
pool_info.poolSizeCount = 11;
|
pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes);
|
||||||
pool_info.pPoolSizes = pool_size;
|
pool_info.pPoolSizes = pool_sizes;
|
||||||
err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool);
|
err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
}
|
}
|
||||||
@ -413,11 +419,12 @@ static void cleanup_vulkan()
|
|||||||
vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator);
|
vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator);
|
||||||
for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++)
|
for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++)
|
||||||
{
|
{
|
||||||
vkDestroyFence(g_Device, g_Fence[i], g_Allocator);
|
FrameData* fd = &g_Frames[i];
|
||||||
vkFreeCommandBuffers(g_Device, g_CommandPool[i], 1, &g_CommandBuffer[i]);
|
vkDestroyFence(g_Device, fd->Fence, g_Allocator);
|
||||||
vkDestroyCommandPool(g_Device, g_CommandPool[i], g_Allocator);
|
vkFreeCommandBuffers(g_Device, fd->CommandPool, 1, &fd->CommandBuffer);
|
||||||
vkDestroySemaphore(g_Device, g_PresentCompleteSemaphore[i], g_Allocator);
|
vkDestroyCommandPool(g_Device, fd->CommandPool, g_Allocator);
|
||||||
vkDestroySemaphore(g_Device, g_RenderCompleteSemaphore[i], g_Allocator);
|
vkDestroySemaphore(g_Device, fd->PresentCompleteSemaphore, g_Allocator);
|
||||||
|
vkDestroySemaphore(g_Device, fd->RenderCompleteSemaphore, g_Allocator);
|
||||||
}
|
}
|
||||||
for (uint32_t i = 0; i < g_BackBufferCount; i++)
|
for (uint32_t i = 0; i < g_BackBufferCount; i++)
|
||||||
{
|
{
|
||||||
@ -440,61 +447,63 @@ static void cleanup_vulkan()
|
|||||||
|
|
||||||
static void frame_begin()
|
static void frame_begin()
|
||||||
{
|
{
|
||||||
|
FrameData* fd = &g_Frames[g_FrameIndex];
|
||||||
VkResult err;
|
VkResult err;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
err = vkWaitForFences(g_Device, 1, &g_Fence[g_FrameIndex], VK_TRUE, 100);
|
err = vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, 100);
|
||||||
if (err == VK_SUCCESS) break;
|
if (err == VK_SUCCESS) break;
|
||||||
if (err == VK_TIMEOUT) continue;
|
if (err == VK_TIMEOUT) continue;
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
err = vkAcquireNextImageKHR(g_Device, g_Swapchain, UINT64_MAX, g_PresentCompleteSemaphore[g_FrameIndex], VK_NULL_HANDLE, &g_BackbufferIndices[g_FrameIndex]);
|
err = vkAcquireNextImageKHR(g_Device, g_Swapchain, UINT64_MAX, fd->PresentCompleteSemaphore, VK_NULL_HANDLE, &fd->BackbufferIndex);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
err = vkResetCommandPool(g_Device, g_CommandPool[g_FrameIndex], 0);
|
err = vkResetCommandPool(g_Device, fd->CommandPool, 0);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
VkCommandBufferBeginInfo info = {};
|
VkCommandBufferBeginInfo info = {};
|
||||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||||
err = vkBeginCommandBuffer(g_CommandBuffer[g_FrameIndex], &info);
|
err = vkBeginCommandBuffer(fd->CommandBuffer, &info);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
VkRenderPassBeginInfo info = {};
|
VkRenderPassBeginInfo info = {};
|
||||||
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||||
info.renderPass = g_RenderPass;
|
info.renderPass = g_RenderPass;
|
||||||
info.framebuffer = g_Framebuffer[g_BackbufferIndices[g_FrameIndex]];
|
info.framebuffer = g_Framebuffer[fd->BackbufferIndex];
|
||||||
info.renderArea.extent.width = fb_width;
|
info.renderArea.extent.width = fb_width;
|
||||||
info.renderArea.extent.height = fb_height;
|
info.renderArea.extent.height = fb_height;
|
||||||
info.clearValueCount = 1;
|
info.clearValueCount = 1;
|
||||||
info.pClearValues = &g_ClearValue;
|
info.pClearValues = &g_ClearValue;
|
||||||
vkCmdBeginRenderPass(g_CommandBuffer[g_FrameIndex], &info, VK_SUBPASS_CONTENTS_INLINE);
|
vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void frame_end()
|
static void frame_end()
|
||||||
{
|
{
|
||||||
|
FrameData* fd = &g_Frames[g_FrameIndex];
|
||||||
VkResult err;
|
VkResult err;
|
||||||
vkCmdEndRenderPass(g_CommandBuffer[g_FrameIndex]);
|
vkCmdEndRenderPass(fd->CommandBuffer);
|
||||||
{
|
{
|
||||||
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
VkSubmitInfo info = {};
|
VkSubmitInfo info = {};
|
||||||
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
info.waitSemaphoreCount = 1;
|
info.waitSemaphoreCount = 1;
|
||||||
info.pWaitSemaphores = &g_PresentCompleteSemaphore[g_FrameIndex];
|
info.pWaitSemaphores = &fd->PresentCompleteSemaphore;
|
||||||
info.pWaitDstStageMask = &wait_stage;
|
info.pWaitDstStageMask = &wait_stage;
|
||||||
info.commandBufferCount = 1;
|
info.commandBufferCount = 1;
|
||||||
info.pCommandBuffers = &g_CommandBuffer[g_FrameIndex];
|
info.pCommandBuffers = &fd->CommandBuffer;
|
||||||
info.signalSemaphoreCount = 1;
|
info.signalSemaphoreCount = 1;
|
||||||
info.pSignalSemaphores = &g_RenderCompleteSemaphore[g_FrameIndex];
|
info.pSignalSemaphores = &fd->RenderCompleteSemaphore;
|
||||||
|
|
||||||
err = vkEndCommandBuffer(g_CommandBuffer[g_FrameIndex]);
|
err = vkEndCommandBuffer(fd->CommandBuffer);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
err = vkResetFences(g_Device, 1, &g_Fence[g_FrameIndex]);
|
err = vkResetFences(g_Device, 1, &fd->Fence);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
err = vkQueueSubmit(g_Queue, 1, &info, g_Fence[g_FrameIndex]);
|
err = vkQueueSubmit(g_Queue, 1, &info, fd->Fence);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -509,15 +518,14 @@ static void frame_present()
|
|||||||
uint32_t PresentIndex = g_FrameIndex;
|
uint32_t PresentIndex = g_FrameIndex;
|
||||||
#endif // IMGUI_UNLIMITED_FRAME_RATE
|
#endif // IMGUI_UNLIMITED_FRAME_RATE
|
||||||
|
|
||||||
VkSwapchainKHR swapchains[1] = { g_Swapchain };
|
FrameData* fd = &g_Frames[PresentIndex];
|
||||||
uint32_t indices[1] = { g_BackbufferIndices[PresentIndex] };
|
|
||||||
VkPresentInfoKHR info = {};
|
VkPresentInfoKHR info = {};
|
||||||
info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||||
info.waitSemaphoreCount = 1;
|
info.waitSemaphoreCount = 1;
|
||||||
info.pWaitSemaphores = &g_RenderCompleteSemaphore[PresentIndex];
|
info.pWaitSemaphores = &fd->RenderCompleteSemaphore;
|
||||||
info.swapchainCount = 1;
|
info.swapchainCount = 1;
|
||||||
info.pSwapchains = swapchains;
|
info.pSwapchains = &g_Swapchain;
|
||||||
info.pImageIndices = indices;
|
info.pImageIndices = &fd->BackbufferIndex;
|
||||||
err = vkQueuePresentKHR(g_Queue, &info);
|
err = vkQueuePresentKHR(g_Queue, &info);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
|
|
||||||
@ -584,22 +592,26 @@ int main(int, char**)
|
|||||||
|
|
||||||
// Upload Fonts
|
// Upload Fonts
|
||||||
{
|
{
|
||||||
|
// Use any command queue
|
||||||
|
VkCommandPool command_pool = g_Frames[g_FrameIndex].CommandPool;
|
||||||
|
VkCommandBuffer command_buffer = g_Frames[g_FrameIndex].CommandBuffer;
|
||||||
|
|
||||||
VkResult err;
|
VkResult err;
|
||||||
err = vkResetCommandPool(g_Device, g_CommandPool[g_FrameIndex], 0);
|
err = vkResetCommandPool(g_Device, command_pool, 0);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
VkCommandBufferBeginInfo begin_info = {};
|
VkCommandBufferBeginInfo begin_info = {};
|
||||||
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||||
err = vkBeginCommandBuffer(g_CommandBuffer[g_FrameIndex], &begin_info);
|
err = vkBeginCommandBuffer(command_buffer, &begin_info);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
|
|
||||||
ImGui_ImplVulkan_CreateFontsTexture(g_CommandBuffer[g_FrameIndex]);
|
ImGui_ImplVulkan_CreateFontsTexture(command_buffer);
|
||||||
|
|
||||||
VkSubmitInfo end_info = {};
|
VkSubmitInfo end_info = {};
|
||||||
end_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
end_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
end_info.commandBufferCount = 1;
|
end_info.commandBufferCount = 1;
|
||||||
end_info.pCommandBuffers = &g_CommandBuffer[g_FrameIndex];
|
end_info.pCommandBuffers = &command_buffer;
|
||||||
err = vkEndCommandBuffer(g_CommandBuffer[g_FrameIndex]);
|
err = vkEndCommandBuffer(command_buffer);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
err = vkQueueSubmit(g_Queue, 1, &end_info, VK_NULL_HANDLE);
|
err = vkQueueSubmit(g_Queue, 1, &end_info, VK_NULL_HANDLE);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
@ -620,7 +632,7 @@ int main(int, char**)
|
|||||||
ImGui_ImplVulkan_NewFrame();
|
ImGui_ImplVulkan_NewFrame();
|
||||||
ImGui_ImplSDL2_NewFrame(window);
|
ImGui_ImplSDL2_NewFrame(window);
|
||||||
frame_begin();
|
frame_begin();
|
||||||
ImGui_ImplVulkan_Render(g_CommandBuffer[g_FrameIndex]);
|
ImGui_ImplVulkan_Render(g_Frames[g_FrameIndex].CommandBuffer);
|
||||||
frame_end();
|
frame_end();
|
||||||
g_FrameIndex = (g_FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES;
|
g_FrameIndex = (g_FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES;
|
||||||
#endif // IMGUI_UNLIMITED_FRAME_RATE
|
#endif // IMGUI_UNLIMITED_FRAME_RATE
|
||||||
@ -685,7 +697,7 @@ int main(int, char**)
|
|||||||
// Rendering
|
// Rendering
|
||||||
memcpy(&g_ClearValue.color.float32[0], &clear_color, 4 * sizeof(float));
|
memcpy(&g_ClearValue.color.float32[0], &clear_color, 4 * sizeof(float));
|
||||||
frame_begin();
|
frame_begin();
|
||||||
ImGui_ImplVulkan_Render(g_CommandBuffer[g_FrameIndex]);
|
ImGui_ImplVulkan_Render(g_Frames[g_FrameIndex].CommandBuffer);
|
||||||
frame_end();
|
frame_end();
|
||||||
frame_present();
|
frame_present();
|
||||||
}
|
}
|
||||||
|
@ -37,18 +37,22 @@ static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE;
|
|||||||
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
|
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
|
||||||
|
|
||||||
static int fb_width, fb_height;
|
static int fb_width, fb_height;
|
||||||
static uint32_t g_BackbufferIndices[IMGUI_VK_QUEUED_FRAMES]; // keep track of recently rendered swapchain frame indices
|
|
||||||
static uint32_t g_BackBufferCount = 0;
|
static uint32_t g_BackBufferCount = 0;
|
||||||
static VkImage g_BackBuffer[IMGUI_MAX_POSSIBLE_BACK_BUFFERS] = {};
|
static VkImage g_BackBuffer[IMGUI_MAX_POSSIBLE_BACK_BUFFERS] = {};
|
||||||
static VkImageView g_BackBufferView[IMGUI_MAX_POSSIBLE_BACK_BUFFERS] = {};
|
static VkImageView g_BackBufferView[IMGUI_MAX_POSSIBLE_BACK_BUFFERS] = {};
|
||||||
static VkFramebuffer g_Framebuffer[IMGUI_MAX_POSSIBLE_BACK_BUFFERS] = {};
|
static VkFramebuffer g_Framebuffer[IMGUI_MAX_POSSIBLE_BACK_BUFFERS] = {};
|
||||||
|
|
||||||
|
struct FrameData
|
||||||
|
{
|
||||||
|
uint32_t BackbufferIndex; // keep track of recently rendered swapchain frame indices
|
||||||
|
VkCommandPool CommandPool;
|
||||||
|
VkCommandBuffer CommandBuffer;
|
||||||
|
VkFence Fence;
|
||||||
|
VkSemaphore PresentCompleteSemaphore;
|
||||||
|
VkSemaphore RenderCompleteSemaphore;
|
||||||
|
};
|
||||||
static uint32_t g_FrameIndex = 0;
|
static uint32_t g_FrameIndex = 0;
|
||||||
static VkCommandPool g_CommandPool[IMGUI_VK_QUEUED_FRAMES];
|
static FrameData g_Frames[IMGUI_VK_QUEUED_FRAMES] = {};
|
||||||
static VkCommandBuffer g_CommandBuffer[IMGUI_VK_QUEUED_FRAMES];
|
|
||||||
static VkFence g_Fence[IMGUI_VK_QUEUED_FRAMES];
|
|
||||||
static VkSemaphore g_PresentCompleteSemaphore[IMGUI_VK_QUEUED_FRAMES];
|
|
||||||
static VkSemaphore g_RenderCompleteSemaphore[IMGUI_VK_QUEUED_FRAMES];
|
|
||||||
|
|
||||||
static VkClearValue g_ClearValue = {};
|
static VkClearValue g_ClearValue = {};
|
||||||
|
|
||||||
@ -353,43 +357,44 @@ static void setup_vulkan(GLFWwindow* window, const char** extensions, uint32_t e
|
|||||||
// Create Command Buffers
|
// Create Command Buffers
|
||||||
for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++)
|
for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++)
|
||||||
{
|
{
|
||||||
|
FrameData* fd = &g_Frames[i];
|
||||||
{
|
{
|
||||||
VkCommandPoolCreateInfo info = {};
|
VkCommandPoolCreateInfo info = {};
|
||||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||||
info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
||||||
info.queueFamilyIndex = g_QueueFamily;
|
info.queueFamilyIndex = g_QueueFamily;
|
||||||
err = vkCreateCommandPool(g_Device, &info, g_Allocator, &g_CommandPool[i]);
|
err = vkCreateCommandPool(g_Device, &info, g_Allocator, &fd->CommandPool);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
VkCommandBufferAllocateInfo info = {};
|
VkCommandBufferAllocateInfo info = {};
|
||||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||||
info.commandPool = g_CommandPool[i];
|
info.commandPool = fd->CommandPool;
|
||||||
info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||||
info.commandBufferCount = 1;
|
info.commandBufferCount = 1;
|
||||||
err = vkAllocateCommandBuffers(g_Device, &info, &g_CommandBuffer[i]);
|
err = vkAllocateCommandBuffers(g_Device, &info, &fd->CommandBuffer);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
VkFenceCreateInfo info = {};
|
VkFenceCreateInfo info = {};
|
||||||
info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||||
info.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
info.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||||
err = vkCreateFence(g_Device, &info, g_Allocator, &g_Fence[i]);
|
err = vkCreateFence(g_Device, &info, g_Allocator, &fd->Fence);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
VkSemaphoreCreateInfo info = {};
|
VkSemaphoreCreateInfo info = {};
|
||||||
info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||||
err = vkCreateSemaphore(g_Device, &info, g_Allocator, &g_PresentCompleteSemaphore[i]);
|
err = vkCreateSemaphore(g_Device, &info, g_Allocator, &fd->PresentCompleteSemaphore);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
err = vkCreateSemaphore(g_Device, &info, g_Allocator, &g_RenderCompleteSemaphore[i]);
|
err = vkCreateSemaphore(g_Device, &info, g_Allocator, &fd->RenderCompleteSemaphore);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create Descriptor Pool
|
// Create Descriptor Pool
|
||||||
{
|
{
|
||||||
VkDescriptorPoolSize pool_size[11] =
|
VkDescriptorPoolSize pool_sizes[] =
|
||||||
{
|
{
|
||||||
{ VK_DESCRIPTOR_TYPE_SAMPLER, 1000 },
|
{ VK_DESCRIPTOR_TYPE_SAMPLER, 1000 },
|
||||||
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 },
|
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 },
|
||||||
@ -406,9 +411,9 @@ static void setup_vulkan(GLFWwindow* window, const char** extensions, uint32_t e
|
|||||||
VkDescriptorPoolCreateInfo pool_info = {};
|
VkDescriptorPoolCreateInfo pool_info = {};
|
||||||
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||||
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
|
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
|
||||||
pool_info.maxSets = 1000 * 11;
|
pool_info.maxSets = 1000 * IM_ARRAYSIZE(pool_sizes);
|
||||||
pool_info.poolSizeCount = 11;
|
pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes);
|
||||||
pool_info.pPoolSizes = pool_size;
|
pool_info.pPoolSizes = pool_sizes;
|
||||||
err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool);
|
err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
}
|
}
|
||||||
@ -419,11 +424,12 @@ static void cleanup_vulkan()
|
|||||||
vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator);
|
vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator);
|
||||||
for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++)
|
for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++)
|
||||||
{
|
{
|
||||||
vkDestroyFence(g_Device, g_Fence[i], g_Allocator);
|
FrameData* fd = &g_Frames[i];
|
||||||
vkFreeCommandBuffers(g_Device, g_CommandPool[i], 1, &g_CommandBuffer[i]);
|
vkDestroyFence(g_Device, fd->Fence, g_Allocator);
|
||||||
vkDestroyCommandPool(g_Device, g_CommandPool[i], g_Allocator);
|
vkFreeCommandBuffers(g_Device, fd->CommandPool, 1, &fd->CommandBuffer);
|
||||||
vkDestroySemaphore(g_Device, g_PresentCompleteSemaphore[i], g_Allocator);
|
vkDestroyCommandPool(g_Device, fd->CommandPool, g_Allocator);
|
||||||
vkDestroySemaphore(g_Device, g_RenderCompleteSemaphore[i], g_Allocator);
|
vkDestroySemaphore(g_Device, fd->PresentCompleteSemaphore, g_Allocator);
|
||||||
|
vkDestroySemaphore(g_Device, fd->RenderCompleteSemaphore, g_Allocator);
|
||||||
}
|
}
|
||||||
for (uint32_t i = 0; i < g_BackBufferCount; i++)
|
for (uint32_t i = 0; i < g_BackBufferCount; i++)
|
||||||
{
|
{
|
||||||
@ -446,61 +452,63 @@ static void cleanup_vulkan()
|
|||||||
|
|
||||||
static void frame_begin()
|
static void frame_begin()
|
||||||
{
|
{
|
||||||
|
FrameData* fd = &g_Frames[g_FrameIndex];
|
||||||
VkResult err;
|
VkResult err;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
err = vkWaitForFences(g_Device, 1, &g_Fence[g_FrameIndex], VK_TRUE, 100);
|
err = vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, 100);
|
||||||
if (err == VK_SUCCESS) break;
|
if (err == VK_SUCCESS) break;
|
||||||
if (err == VK_TIMEOUT) continue;
|
if (err == VK_TIMEOUT) continue;
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
err = vkAcquireNextImageKHR(g_Device, g_Swapchain, UINT64_MAX, g_PresentCompleteSemaphore[g_FrameIndex], VK_NULL_HANDLE, &g_BackbufferIndices[g_FrameIndex]);
|
err = vkAcquireNextImageKHR(g_Device, g_Swapchain, UINT64_MAX, fd->PresentCompleteSemaphore, VK_NULL_HANDLE, &fd->BackbufferIndex);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
err = vkResetCommandPool(g_Device, g_CommandPool[g_FrameIndex], 0);
|
err = vkResetCommandPool(g_Device, fd->CommandPool, 0);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
VkCommandBufferBeginInfo info = {};
|
VkCommandBufferBeginInfo info = {};
|
||||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||||
err = vkBeginCommandBuffer(g_CommandBuffer[g_FrameIndex], &info);
|
err = vkBeginCommandBuffer(fd->CommandBuffer, &info);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
VkRenderPassBeginInfo info = {};
|
VkRenderPassBeginInfo info = {};
|
||||||
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||||
info.renderPass = g_RenderPass;
|
info.renderPass = g_RenderPass;
|
||||||
info.framebuffer = g_Framebuffer[g_BackbufferIndices[g_FrameIndex]];
|
info.framebuffer = g_Framebuffer[fd->BackbufferIndex];
|
||||||
info.renderArea.extent.width = fb_width;
|
info.renderArea.extent.width = fb_width;
|
||||||
info.renderArea.extent.height = fb_height;
|
info.renderArea.extent.height = fb_height;
|
||||||
info.clearValueCount = 1;
|
info.clearValueCount = 1;
|
||||||
info.pClearValues = &g_ClearValue;
|
info.pClearValues = &g_ClearValue;
|
||||||
vkCmdBeginRenderPass(g_CommandBuffer[g_FrameIndex], &info, VK_SUBPASS_CONTENTS_INLINE);
|
vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void frame_end()
|
static void frame_end()
|
||||||
{
|
{
|
||||||
|
FrameData* fd = &g_Frames[g_FrameIndex];
|
||||||
VkResult err;
|
VkResult err;
|
||||||
vkCmdEndRenderPass(g_CommandBuffer[g_FrameIndex]);
|
vkCmdEndRenderPass(fd->CommandBuffer);
|
||||||
{
|
{
|
||||||
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
VkSubmitInfo info = {};
|
VkSubmitInfo info = {};
|
||||||
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
info.waitSemaphoreCount = 1;
|
info.waitSemaphoreCount = 1;
|
||||||
info.pWaitSemaphores = &g_PresentCompleteSemaphore[g_FrameIndex];
|
info.pWaitSemaphores = &fd->PresentCompleteSemaphore;
|
||||||
info.pWaitDstStageMask = &wait_stage;
|
info.pWaitDstStageMask = &wait_stage;
|
||||||
info.commandBufferCount = 1;
|
info.commandBufferCount = 1;
|
||||||
info.pCommandBuffers = &g_CommandBuffer[g_FrameIndex];
|
info.pCommandBuffers = &fd->CommandBuffer;
|
||||||
info.signalSemaphoreCount = 1;
|
info.signalSemaphoreCount = 1;
|
||||||
info.pSignalSemaphores = &g_RenderCompleteSemaphore[g_FrameIndex];
|
info.pSignalSemaphores = &fd->RenderCompleteSemaphore;
|
||||||
|
|
||||||
err = vkEndCommandBuffer(g_CommandBuffer[g_FrameIndex]);
|
err = vkEndCommandBuffer(fd->CommandBuffer);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
err = vkResetFences(g_Device, 1, &g_Fence[g_FrameIndex]);
|
err = vkResetFences(g_Device, 1, &fd->Fence);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
err = vkQueueSubmit(g_Queue, 1, &info, g_Fence[g_FrameIndex]);
|
err = vkQueueSubmit(g_Queue, 1, &info, fd->Fence);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -515,15 +523,14 @@ static void frame_present()
|
|||||||
uint32_t PresentIndex = g_FrameIndex;
|
uint32_t PresentIndex = g_FrameIndex;
|
||||||
#endif // IMGUI_UNLIMITED_FRAME_RATE
|
#endif // IMGUI_UNLIMITED_FRAME_RATE
|
||||||
|
|
||||||
VkSwapchainKHR swapchains[1] = { g_Swapchain };
|
FrameData* fd = &g_Frames[PresentIndex];
|
||||||
uint32_t indices[1] = { g_BackbufferIndices[PresentIndex] };
|
|
||||||
VkPresentInfoKHR info = {};
|
VkPresentInfoKHR info = {};
|
||||||
info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||||
info.waitSemaphoreCount = 1;
|
info.waitSemaphoreCount = 1;
|
||||||
info.pWaitSemaphores = &g_RenderCompleteSemaphore[PresentIndex];
|
info.pWaitSemaphores = &fd->RenderCompleteSemaphore;
|
||||||
info.swapchainCount = 1;
|
info.swapchainCount = 1;
|
||||||
info.pSwapchains = swapchains;
|
info.pSwapchains = &g_Swapchain;
|
||||||
info.pImageIndices = indices;
|
info.pImageIndices = &fd->BackbufferIndex;
|
||||||
err = vkQueuePresentKHR(g_Queue, &info);
|
err = vkQueuePresentKHR(g_Queue, &info);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
|
|
||||||
@ -595,22 +602,26 @@ int main(int, char**)
|
|||||||
|
|
||||||
// Upload Fonts
|
// Upload Fonts
|
||||||
{
|
{
|
||||||
|
// Use any command queue
|
||||||
|
VkCommandPool command_pool = g_Frames[g_FrameIndex].CommandPool;
|
||||||
|
VkCommandBuffer command_buffer = g_Frames[g_FrameIndex].CommandBuffer;
|
||||||
|
|
||||||
VkResult err;
|
VkResult err;
|
||||||
err = vkResetCommandPool(g_Device, g_CommandPool[g_FrameIndex], 0);
|
err = vkResetCommandPool(g_Device, command_pool, 0);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
VkCommandBufferBeginInfo begin_info = {};
|
VkCommandBufferBeginInfo begin_info = {};
|
||||||
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||||
err = vkBeginCommandBuffer(g_CommandBuffer[g_FrameIndex], &begin_info);
|
err = vkBeginCommandBuffer(command_buffer, &begin_info);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
|
|
||||||
ImGui_ImplVulkan_CreateFontsTexture(g_CommandBuffer[g_FrameIndex]);
|
ImGui_ImplVulkan_CreateFontsTexture(command_buffer);
|
||||||
|
|
||||||
VkSubmitInfo end_info = {};
|
VkSubmitInfo end_info = {};
|
||||||
end_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
end_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
end_info.commandBufferCount = 1;
|
end_info.commandBufferCount = 1;
|
||||||
end_info.pCommandBuffers = &g_CommandBuffer[g_FrameIndex];
|
end_info.pCommandBuffers = &command_buffer;
|
||||||
err = vkEndCommandBuffer(g_CommandBuffer[g_FrameIndex]);
|
err = vkEndCommandBuffer(command_buffer);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
err = vkQueueSubmit(g_Queue, 1, &end_info, VK_NULL_HANDLE);
|
err = vkQueueSubmit(g_Queue, 1, &end_info, VK_NULL_HANDLE);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
@ -631,7 +642,7 @@ int main(int, char**)
|
|||||||
ImGui_ImplVulkan_NewFrame();
|
ImGui_ImplVulkan_NewFrame();
|
||||||
ImGui_ImplGlfw_NewFrame();
|
ImGui_ImplGlfw_NewFrame();
|
||||||
frame_begin();
|
frame_begin();
|
||||||
ImGui_ImplVulkan_Render(g_CommandBuffer[g_FrameIndex]);
|
ImGui_ImplVulkan_Render(g_Frames[g_FrameIndex].CommandBuffer);
|
||||||
frame_end();
|
frame_end();
|
||||||
g_FrameIndex = (g_FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES;
|
g_FrameIndex = (g_FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES;
|
||||||
#endif // IMGUI_UNLIMITED_FRAME_RATE
|
#endif // IMGUI_UNLIMITED_FRAME_RATE
|
||||||
@ -687,7 +698,7 @@ int main(int, char**)
|
|||||||
// Rendering
|
// Rendering
|
||||||
memcpy(&g_ClearValue.color.float32[0], &clear_color, 4 * sizeof(float));
|
memcpy(&g_ClearValue.color.float32[0], &clear_color, 4 * sizeof(float));
|
||||||
frame_begin();
|
frame_begin();
|
||||||
ImGui_ImplVulkan_Render(g_CommandBuffer[g_FrameIndex]);
|
ImGui_ImplVulkan_Render(g_Frames[g_FrameIndex].CommandBuffer);
|
||||||
frame_end();
|
frame_end();
|
||||||
frame_present();
|
frame_present();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user