Archived
1
Fork 0

Remove dynamic data system, replace it on the renderer level

This commit is contained in:
redstrate 2021-02-17 08:51:47 -05:00
parent 97adca57d8
commit 1a324e61af
7 changed files with 166 additions and 166 deletions

View file

@ -104,8 +104,10 @@ void draw_renderer() {
auto targets = engine->get_renderer()->get_all_render_targets(); auto targets = engine->get_renderer()->get_all_render_targets();
for(auto target : targets) { for(auto target : targets) {
ImGui::Text("Frame %i", target->current_frame);
ImGui::Text("%i %i", target->extent.width, target->extent.height); ImGui::Text("%i %i", target->extent.width, target->extent.height);
ImGui::Image(target->offscreenColorTexture, ImVec2(100, 100)); ImGui::Image(target->offscreenColorTexture, ImVec2(100, 100));
ImGui::Separator();
} }
ImGui::Text("Performance"); ImGui::Text("Performance");

View file

@ -15,6 +15,29 @@
#include "gfx.hpp" #include "gfx.hpp"
#include "gfx_vulkan_constants.hpp" #include "gfx_vulkan_constants.hpp"
struct NativeSurface {
int identifier = -1;
void* windowNativeHandle;
uint32_t surfaceWidth = -1, surfaceHeight = -1;
std::vector<VkSemaphore> imageAvailableSemaphores;
std::vector<VkSemaphore> renderFinishedSemaphores;
std::vector<VkFence> inFlightFences;
size_t currentFrame = 0;
VkSurfaceKHR surface = VK_NULL_HANDLE;
VkSwapchainKHR swapchain = VK_NULL_HANDLE;
VkExtent2D swapchainExtent = {};
std::vector<VkImage> swapchainImages;
std::vector<VkImageView> swapchainImageViews;
VkRenderPass swapchainRenderPass = VK_NULL_HANDLE;
std::vector<VkFramebuffer> swapchainFramebuffers;
};
class GFXVulkanPipeline; class GFXVulkanPipeline;
class GFXVulkan : public GFX { class GFXVulkan : public GFX {
@ -64,9 +87,9 @@ public:
private: private:
void createInstance(std::vector<const char*> layers, std::vector<const char*> extensions); void createInstance(std::vector<const char*> layers, std::vector<const char*> extensions);
void createLogicalDevice(std::vector<const char*> extensions); void createLogicalDevice(std::vector<const char*> extensions);
void createSwapchain(VkSwapchainKHR oldSwapchain = VK_NULL_HANDLE); void createSwapchain(NativeSurface* native_surface, VkSwapchainKHR oldSwapchain = VK_NULL_HANDLE);
void createDescriptorPool(); void createDescriptorPool();
void createSyncPrimitives(); void createSyncPrimitives(NativeSurface* native_surface);
// dynamic descriptor sets // dynamic descriptor sets
void resetDescriptorState(); void resetDescriptorState();
@ -92,23 +115,7 @@ private:
VkDescriptorPool descriptorPool = VK_NULL_HANDLE; VkDescriptorPool descriptorPool = VK_NULL_HANDLE;
uint32_t surfaceWidth = -1, surfaceHeight = -1; std::vector<NativeSurface*> native_surfaces;
std::vector<VkSemaphore> imageAvailableSemaphores;
std::vector<VkSemaphore> renderFinishedSemaphores;
std::vector<VkFence> inFlightFences;
size_t currentFrame = 0;
VkSurfaceKHR surface = VK_NULL_HANDLE;
VkSwapchainKHR swapchain = VK_NULL_HANDLE;
VkExtent2D swapchainExtent = {};
std::vector<VkImage> swapchainImages;
std::vector<VkImageView> swapchainImageViews;
VkRenderPass swapchainRenderPass = VK_NULL_HANDLE;
std::vector<VkFramebuffer> swapchainFramebuffers;
std::vector<VkCommandBuffer> commandBuffers; std::vector<VkCommandBuffer> commandBuffers;

View file

@ -18,8 +18,6 @@
#include "utility.hpp" #include "utility.hpp"
#include "gfx_vulkan_commandbuffer.hpp" #include "gfx_vulkan_commandbuffer.hpp"
void* windowNativeHandle;
VkFormat toVkFormat(GFXPixelFormat format) { VkFormat toVkFormat(GFXPixelFormat format) {
switch (format) { switch (format) {
case GFXPixelFormat::R_32F: case GFXPixelFormat::R_32F:
@ -201,7 +199,6 @@ bool GFXVulkan::initialize(const GFXCreateInfo& info) {
createInstance({}, enabledExtensions); createInstance({}, enabledExtensions);
createLogicalDevice({ VK_KHR_SWAPCHAIN_EXTENSION_NAME }); createLogicalDevice({ VK_KHR_SWAPCHAIN_EXTENSION_NAME });
createDescriptorPool(); createDescriptorPool();
createSyncPrimitives();
return true; return true;
} }
@ -209,26 +206,35 @@ bool GFXVulkan::initialize(const GFXCreateInfo& info) {
void GFXVulkan::initialize_view(void* native_handle, const int identifier, const uint32_t width, const uint32_t height) { void GFXVulkan::initialize_view(void* native_handle, const int identifier, const uint32_t width, const uint32_t height) {
vkDeviceWaitIdle(device); vkDeviceWaitIdle(device);
surfaceWidth = width; NativeSurface* surface = new NativeSurface();
surfaceHeight = height; surface->identifier = identifier;
surface->surfaceWidth = width;
surface->surfaceHeight = height;
surface->windowNativeHandle = native_handle;
windowNativeHandle = native_handle; createSwapchain(surface);
createSyncPrimitives(surface);
createSwapchain(); native_surfaces.push_back(surface);
} }
void GFXVulkan::recreate_view(const int identifier, const uint32_t width, const uint32_t height) { void GFXVulkan::recreate_view(const int identifier, const uint32_t width, const uint32_t height) {
vkDeviceWaitIdle(device); vkDeviceWaitIdle(device);
surfaceWidth = width; NativeSurface* found_surface = nullptr;
surfaceHeight = height; for(auto surface : native_surfaces) {
if(surface->identifier == identifier)
found_surface = surface;
}
createSwapchain(swapchain); found_surface->surfaceWidth = width;
found_surface->surfaceHeight = height;
createSwapchain(found_surface, found_surface->swapchain);
} }
GFXBuffer* GFXVulkan::create_buffer(void *data, const GFXSize size, const bool dynamic_data, const GFXBufferUsage usage) { GFXBuffer* GFXVulkan::create_buffer(void *data, const GFXSize size, const bool dynamic_data, const GFXBufferUsage usage) {
GFXVulkanBuffer* buffer = new GFXVulkanBuffer(); GFXVulkanBuffer* buffer = new GFXVulkanBuffer();
buffer->is_dynamic_data = dynamic_data;
vkDeviceWaitIdle(device); vkDeviceWaitIdle(device);
@ -248,50 +254,28 @@ GFXBuffer* GFXVulkan::create_buffer(void *data, const GFXSize size, const bool d
bufferInfo.usage = bufferUsage; bufferInfo.usage = bufferUsage;
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
if(dynamic_data) { vkCreateBuffer(device, &bufferInfo, nullptr, &buffer->handle);
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
vkCreateBuffer(device, &bufferInfo, nullptr, &buffer->data[i].handle);
} else {
vkCreateBuffer(device, &bufferInfo, nullptr, &buffer->data[0].handle);
}
buffer->size = size; buffer->size = size;
// allocate memory // allocate memory
VkMemoryRequirements memRequirements; VkMemoryRequirements memRequirements;
vkGetBufferMemoryRequirements(device, buffer->data[0].handle, &memRequirements); vkGetBufferMemoryRequirements(device, buffer->handle, &memRequirements);
VkMemoryAllocateInfo allocInfo = {}; VkMemoryAllocateInfo allocInfo = {};
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocInfo.allocationSize = memRequirements.size; allocInfo.allocationSize = memRequirements.size;
allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
if(dynamic_data) { vkAllocateMemory(device, &allocInfo, nullptr, &buffer->memory);
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
vkAllocateMemory(device, &allocInfo, nullptr, &buffer->data[i].memory);
vkBindBufferMemory(device, buffer->data[i].handle, buffer->data[i].memory, 0); vkBindBufferMemory(device, buffer->handle, buffer->memory, 0);
}
} else {
vkAllocateMemory(device, &allocInfo, nullptr, &buffer->data[0].memory);
vkBindBufferMemory(device, buffer->data[0].handle, buffer->data[0].memory, 0);
}
if (data != nullptr) { if (data != nullptr) {
if(dynamic_data) { void* mapped_data;
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { vkMapMemory(device, buffer->memory, 0, size, 0, &mapped_data);
void* mapped_data; memcpy(mapped_data, data, size);
vkMapMemory(device, buffer->data[i].memory, 0, size, 0, &mapped_data); vkUnmapMemory(device, buffer->memory);
memcpy(mapped_data, data, size);
vkUnmapMemory(device, buffer->data[i].memory);
}
} else {
void* mapped_data;
vkMapMemory(device, buffer->data[0].memory, 0, size, 0, &mapped_data);
memcpy(mapped_data, data, size);
vkUnmapMemory(device, buffer->data[0].memory);
}
} }
return buffer; return buffer;
@ -301,23 +285,30 @@ void GFXVulkan::copy_buffer(GFXBuffer* buffer, void* data, GFXSize offset, GFXSi
GFXVulkanBuffer* vulkanBuffer = (GFXVulkanBuffer*)buffer; GFXVulkanBuffer* vulkanBuffer = (GFXVulkanBuffer*)buffer;
void* mapped_data; void* mapped_data;
vkMapMemory(device, vulkanBuffer->get(currentFrame).memory, offset, vulkanBuffer->size - offset, 0, &mapped_data); vkMapMemory(device, vulkanBuffer->memory, offset, vulkanBuffer->size - offset, 0, &mapped_data);
memcpy(mapped_data, data, size); memcpy(mapped_data, data, size);
vkUnmapMemory(device, vulkanBuffer->get(currentFrame).memory);
VkMappedMemoryRange range = {};
range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
range.memory = vulkanBuffer->memory;
range.size = VK_WHOLE_SIZE;
vkFlushMappedMemoryRanges(device, 1, &range);
vkUnmapMemory(device, vulkanBuffer->memory);
} }
void* GFXVulkan::get_buffer_contents(GFXBuffer* buffer) { void* GFXVulkan::get_buffer_contents(GFXBuffer* buffer) {
GFXVulkanBuffer* vulkanBuffer = (GFXVulkanBuffer*)buffer; GFXVulkanBuffer* vulkanBuffer = (GFXVulkanBuffer*)buffer;
void* mapped_data; void* mapped_data;
vkMapMemory(device, vulkanBuffer->get(currentFrame).memory, 0, vulkanBuffer->size, 0, &mapped_data); vkMapMemory(device, vulkanBuffer->memory, 0, vulkanBuffer->size, 0, &mapped_data);
return mapped_data; return mapped_data;
} }
void GFXVulkan::release_buffer_contents(GFXBuffer* buffer, void* handle) { void GFXVulkan::release_buffer_contents(GFXBuffer* buffer, void* handle) {
GFXVulkanBuffer* vulkanBuffer = (GFXVulkanBuffer*)buffer; GFXVulkanBuffer* vulkanBuffer = (GFXVulkanBuffer*)buffer;
vkUnmapMemory(device, vulkanBuffer->get(currentFrame).memory); vkUnmapMemory(device, vulkanBuffer->memory);
} }
GFXTexture* GFXVulkan::create_texture(const GFXTextureCreateInfo& info) { GFXTexture* GFXVulkan::create_texture(const GFXTextureCreateInfo& info) {
@ -547,7 +538,7 @@ void GFXVulkan::copy_texture(GFXTexture* from, GFXBuffer* to) {
1 1
}; };
vkCmdCopyImageToBuffer(commandBuffer, vulkanTexture->handle, vulkanTexture->layout, vulkanBuffer->get(0).handle, 1, &region); vkCmdCopyImageToBuffer(commandBuffer, vulkanTexture->handle, vulkanTexture->layout, vulkanBuffer->handle, 1, &region);
endSingleTimeCommands(commandBuffer); endSingleTimeCommands(commandBuffer);
} }
@ -974,7 +965,7 @@ GFXPipeline* GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreate
pipelineInfo.renderPass = ((GFXVulkanRenderPass*)info.render_pass)->handle; pipelineInfo.renderPass = ((GFXVulkanRenderPass*)info.render_pass)->handle;
} }
else { else {
pipelineInfo.renderPass = swapchainRenderPass; pipelineInfo.renderPass = native_surfaces[0]->swapchainRenderPass;
} }
if (info.render_pass != nullptr && ((GFXVulkanRenderPass*)info.render_pass)->hasDepthAttachment) if (info.render_pass != nullptr && ((GFXVulkanRenderPass*)info.render_pass)->hasDepthAttachment)
@ -1015,11 +1006,17 @@ GFXCommandBuffer* GFXVulkan::acquire_command_buffer(bool for_presentation_use) {
} }
void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) { void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) {
uint32_t imageIndex = 0; NativeSurface* current_surface = nullptr;
if(identifier != -1) { for(auto surface : native_surfaces) {
vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, std::numeric_limits<uint64_t>::max()); if(surface->identifier == identifier)
current_surface = surface;
}
VkResult result = vkAcquireNextImageKHR(device, swapchain, std::numeric_limits<uint64_t>::max(), imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex); uint32_t imageIndex = 0;
if(identifier != -1 && current_surface != nullptr) {
vkWaitForFences(device, 1, &current_surface->inFlightFences[current_surface->currentFrame], VK_TRUE, std::numeric_limits<uint64_t>::max());
VkResult result = vkAcquireNextImageKHR(device, current_surface->swapchain, std::numeric_limits<uint64_t>::max(), current_surface->imageAvailableSemaphores[current_surface->currentFrame], VK_NULL_HANDLE, &imageIndex);
if (result == VK_ERROR_OUT_OF_DATE_KHR) if (result == VK_ERROR_OUT_OF_DATE_KHR)
return; return;
} }
@ -1030,7 +1027,7 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) {
if(cmdbuf->handle != VK_NULL_HANDLE) if(cmdbuf->handle != VK_NULL_HANDLE)
cmd = cmdbuf->handle; cmd = cmdbuf->handle;
else else
cmd = commandBuffers[currentFrame]; cmd = commandBuffers[current_surface-> currentFrame];
VkCommandBufferBeginInfo beginInfo = {}; VkCommandBufferBeginInfo beginInfo = {};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
@ -1076,7 +1073,7 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) {
currentRenderPass = renderPass->handle; currentRenderPass = renderPass->handle;
} }
else { else {
currentRenderPass = swapchainRenderPass; currentRenderPass = current_surface->swapchainRenderPass;
} }
VkRenderPassBeginInfo renderPassInfo = {}; VkRenderPassBeginInfo renderPassInfo = {};
@ -1101,19 +1098,19 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) {
vkCmdSetScissor(cmd, 0, 1, &scissor); vkCmdSetScissor(cmd, 0, 1, &scissor);
} }
else { else {
renderPassInfo.framebuffer = swapchainFramebuffers[imageIndex]; renderPassInfo.framebuffer = current_surface->swapchainFramebuffers[imageIndex];
VkViewport viewport = {}; VkViewport viewport = {};
viewport.y = static_cast<float>(surfaceHeight); viewport.y = static_cast<float>(current_surface->surfaceHeight);
viewport.width = static_cast<float>(surfaceWidth); viewport.width = static_cast<float>(current_surface->surfaceWidth);
viewport.height = -static_cast<float>(surfaceHeight); viewport.height = -static_cast<float>(current_surface->surfaceHeight);
viewport.maxDepth = 1.0f; viewport.maxDepth = 1.0f;
vkCmdSetViewport(cmd, 0, 1, &viewport); vkCmdSetViewport(cmd, 0, 1, &viewport);
VkRect2D scissor = {}; VkRect2D scissor = {};
scissor.extent.width = surfaceWidth; scissor.extent.width = current_surface->surfaceWidth;
scissor.extent.height = surfaceHeight; scissor.extent.height = current_surface->surfaceHeight;
vkCmdSetScissor(cmd, 0, 1, &scissor); vkCmdSetScissor(cmd, 0, 1, &scissor);
} }
@ -1158,7 +1155,7 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) {
break; break;
case GFXCommandType::SetVertexBuffer: case GFXCommandType::SetVertexBuffer:
{ {
VkBuffer buffer = ((GFXVulkanBuffer*)command.data.set_vertex_buffer.buffer)->get(currentFrame).handle; VkBuffer buffer = ((GFXVulkanBuffer*)command.data.set_vertex_buffer.buffer)->handle;
VkDeviceSize offset = command.data.set_vertex_buffer.offset; VkDeviceSize offset = command.data.set_vertex_buffer.offset;
vkCmdBindVertexBuffers(cmd, command.data.set_vertex_buffer.index, 1, &buffer, &offset); vkCmdBindVertexBuffers(cmd, command.data.set_vertex_buffer.index, 1, &buffer, &offset);
} }
@ -1169,7 +1166,7 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) {
if (command.data.set_index_buffer.index_type == IndexType::UINT16) if (command.data.set_index_buffer.index_type == IndexType::UINT16)
indexType = VK_INDEX_TYPE_UINT16; indexType = VK_INDEX_TYPE_UINT16;
vkCmdBindIndexBuffer(cmd, ((GFXVulkanBuffer*)command.data.set_index_buffer.buffer)->get(currentFrame).handle, 0, indexType); vkCmdBindIndexBuffer(cmd, ((GFXVulkanBuffer*)command.data.set_index_buffer.buffer)->handle, 0, indexType);
currentIndexType = indexType; currentIndexType = indexType;
} }
@ -1272,7 +1269,7 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) {
VkSubmitInfo submitInfo = {}; VkSubmitInfo submitInfo = {};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
VkSemaphore waitSemaphores[] = { imageAvailableSemaphores[currentFrame] }; VkSemaphore waitSemaphores[] = { current_surface->imageAvailableSemaphores[current_surface->currentFrame] };
VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
submitInfo.waitSemaphoreCount = 1; submitInfo.waitSemaphoreCount = 1;
submitInfo.pWaitSemaphores = waitSemaphores; submitInfo.pWaitSemaphores = waitSemaphores;
@ -1280,13 +1277,13 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) {
submitInfo.commandBufferCount = 1; submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &cmd; submitInfo.pCommandBuffers = &cmd;
VkSemaphore signalSemaphores[] = { renderFinishedSemaphores[currentFrame] }; VkSemaphore signalSemaphores[] = { current_surface->renderFinishedSemaphores[current_surface->currentFrame] };
submitInfo.signalSemaphoreCount = 1; submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = signalSemaphores; submitInfo.pSignalSemaphores = signalSemaphores;
vkResetFences(device, 1, &inFlightFences[currentFrame]); vkResetFences(device, 1, &current_surface->inFlightFences[current_surface->currentFrame]);
if(vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[currentFrame]) != VK_SUCCESS) if(vkQueueSubmit(graphicsQueue, 1, &submitInfo, current_surface->inFlightFences[current_surface->currentFrame]) != VK_SUCCESS)
return; return;
// present // present
@ -1295,14 +1292,14 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) {
presentInfo.waitSemaphoreCount = 1; presentInfo.waitSemaphoreCount = 1;
presentInfo.pWaitSemaphores = signalSemaphores; presentInfo.pWaitSemaphores = signalSemaphores;
VkSwapchainKHR swapChains[] = { swapchain }; VkSwapchainKHR swapChains[] = { current_surface->swapchain };
presentInfo.swapchainCount = 1; presentInfo.swapchainCount = 1;
presentInfo.pSwapchains = swapChains; presentInfo.pSwapchains = swapChains;
presentInfo.pImageIndices = &imageIndex; presentInfo.pImageIndices = &imageIndex;
vkQueuePresentKHR(presentQueue, &presentInfo); vkQueuePresentKHR(presentQueue, &presentInfo);
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT; current_surface->currentFrame = (current_surface->currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
} }
} }
@ -1429,59 +1426,59 @@ void GFXVulkan::createLogicalDevice(std::vector<const char*> extensions) {
vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool); vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool);
} }
void GFXVulkan::createSwapchain(VkSwapchainKHR oldSwapchain) { void GFXVulkan::createSwapchain(NativeSurface* native_surface, VkSwapchainKHR oldSwapchain) {
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
// create win32 surface // create win32 surface
if(surface == VK_NULL_HANDLE) if(native_surface->surface == VK_NULL_HANDLE)
{ {
VkWin32SurfaceCreateInfoKHR createInfo = {}; VkWin32SurfaceCreateInfoKHR createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
createInfo.hwnd = (HWND)windowNativeHandle; createInfo.hwnd = (HWND)native_surface->windowNativeHandle;
createInfo.hinstance = GetModuleHandle(nullptr); createInfo.hinstance = GetModuleHandle(nullptr);
vkCreateWin32SurfaceKHR(instance, &createInfo, nullptr, &surface); vkCreateWin32SurfaceKHR(instance, &createInfo, nullptr, &native_surface->surface);
} }
#else #else
if(surface == VK_NULL_HANDLE) { if(native_surface->surface == VK_NULL_HANDLE) {
struct WindowConnection { struct WindowConnection {
xcb_connection_t* connection; xcb_connection_t* connection;
xcb_window_t window; xcb_window_t window;
}; };
WindowConnection* wincon = reinterpret_cast<WindowConnection*>(windowNativeHandle); WindowConnection* wincon = reinterpret_cast<WindowConnection*>(native_surface->windowNativeHandle);
VkXcbSurfaceCreateInfoKHR createInfo = {}; VkXcbSurfaceCreateInfoKHR createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
createInfo.window = wincon->window; createInfo.window = wincon->window;
createInfo.connection = wincon->connection; createInfo.connection = wincon->connection;
vkCreateXcbSurfaceKHR(instance, &createInfo, nullptr, &surface); vkCreateXcbSurfaceKHR(instance, &createInfo, nullptr, &native_surface->surface);
} }
#endif #endif
// TODO: fix this pls // TODO: fix this pls
VkBool32 supported; VkBool32 supported;
vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, 0, surface, &supported); vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, 0, native_surface->surface, &supported);
// query swapchain support // query swapchain support
VkSurfaceCapabilitiesKHR capabilities; VkSurfaceCapabilitiesKHR capabilities;
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &capabilities); vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, native_surface->surface, &capabilities);
std::vector<VkSurfaceFormatKHR> formats; std::vector<VkSurfaceFormatKHR> formats;
uint32_t formatCount; uint32_t formatCount;
vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, nullptr); vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, native_surface->surface, &formatCount, nullptr);
formats.resize(formatCount); formats.resize(formatCount);
vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, formats.data()); vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, native_surface->surface, &formatCount, formats.data());
std::vector<VkPresentModeKHR> presentModes; std::vector<VkPresentModeKHR> presentModes;
uint32_t presentModeCount; uint32_t presentModeCount;
vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, nullptr); vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, native_surface->surface, &presentModeCount, nullptr);
presentModes.resize(presentModeCount); presentModes.resize(presentModeCount);
vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, presentModes.data()); vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, native_surface->surface, &presentModeCount, presentModes.data());
// choosing swapchain features // choosing swapchain features
VkSurfaceFormatKHR swapchainSurfaceFormat = formats[0]; VkSurfaceFormatKHR swapchainSurfaceFormat = formats[0];
@ -1506,12 +1503,12 @@ void GFXVulkan::createSwapchain(VkSwapchainKHR oldSwapchain) {
// create swapchain // create swapchain
VkSwapchainCreateInfoKHR createInfo = {}; VkSwapchainCreateInfoKHR createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
createInfo.surface = surface; createInfo.surface = native_surface->surface;
createInfo.minImageCount = imageCount; createInfo.minImageCount = imageCount;
createInfo.imageFormat = swapchainSurfaceFormat.format; createInfo.imageFormat = swapchainSurfaceFormat.format;
createInfo.imageColorSpace = swapchainSurfaceFormat.colorSpace; createInfo.imageColorSpace = swapchainSurfaceFormat.colorSpace;
createInfo.imageExtent.width = surfaceWidth; createInfo.imageExtent.width = native_surface->surfaceWidth;
createInfo.imageExtent.height = surfaceHeight; createInfo.imageExtent.height = native_surface->surfaceHeight;
createInfo.imageArrayLayers = 1; createInfo.imageArrayLayers = 1;
createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
@ -1521,27 +1518,27 @@ void GFXVulkan::createSwapchain(VkSwapchainKHR oldSwapchain) {
createInfo.clipped = VK_TRUE; createInfo.clipped = VK_TRUE;
createInfo.oldSwapchain = oldSwapchain; createInfo.oldSwapchain = oldSwapchain;
vkCreateSwapchainKHR(device, &createInfo, nullptr, &swapchain); vkCreateSwapchainKHR(device, &createInfo, nullptr, &native_surface->swapchain);
if (oldSwapchain != VK_NULL_HANDLE) { if (oldSwapchain != VK_NULL_HANDLE) {
vkDestroySwapchainKHR(device, oldSwapchain, nullptr); vkDestroySwapchainKHR(device, oldSwapchain, nullptr);
} }
swapchainExtent.width = surfaceWidth; native_surface->swapchainExtent.width = native_surface->surfaceWidth;
swapchainExtent.height = surfaceHeight; native_surface->swapchainExtent.height = native_surface->surfaceHeight;
// get swapchain images // get swapchain images
vkGetSwapchainImagesKHR(device, swapchain, &imageCount, nullptr); vkGetSwapchainImagesKHR(device, native_surface->swapchain, &imageCount, nullptr);
swapchainImages.resize(imageCount); native_surface->swapchainImages.resize(imageCount);
vkGetSwapchainImagesKHR(device, swapchain, &imageCount, swapchainImages.data()); vkGetSwapchainImagesKHR(device, native_surface->swapchain, &imageCount, native_surface->swapchainImages.data());
// create swapchain image views // create swapchain image views
swapchainImageViews.resize(swapchainImages.size()); native_surface->swapchainImageViews.resize(native_surface->swapchainImages.size());
for (size_t i = 0; i < swapchainImages.size(); i++) { for (size_t i = 0; i < native_surface->swapchainImages.size(); i++) {
VkImageViewCreateInfo createInfo = {}; VkImageViewCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
createInfo.image = swapchainImages[i]; createInfo.image = native_surface->swapchainImages[i];
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
createInfo.format = swapchainSurfaceFormat.format; createInfo.format = swapchainSurfaceFormat.format;
createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
@ -1554,7 +1551,7 @@ void GFXVulkan::createSwapchain(VkSwapchainKHR oldSwapchain) {
createInfo.subresourceRange.baseArrayLayer = 0; createInfo.subresourceRange.baseArrayLayer = 0;
createInfo.subresourceRange.layerCount = 1; createInfo.subresourceRange.layerCount = 1;
vkCreateImageView(device, &createInfo, nullptr, &swapchainImageViews[i]); vkCreateImageView(device, &createInfo, nullptr, &native_surface->swapchainImageViews[i]);
} }
// create render pass // create render pass
@ -1595,26 +1592,26 @@ void GFXVulkan::createSwapchain(VkSwapchainKHR oldSwapchain) {
renderPassInfo.dependencyCount = 1; renderPassInfo.dependencyCount = 1;
renderPassInfo.pDependencies = &dependency; renderPassInfo.pDependencies = &dependency;
vkCreateRenderPass(device, &renderPassInfo, nullptr, &swapchainRenderPass); vkCreateRenderPass(device, &renderPassInfo, nullptr, &native_surface->swapchainRenderPass);
// create swapchain framebuffers // create swapchain framebuffers
swapchainFramebuffers.resize(swapchainImageViews.size()); native_surface->swapchainFramebuffers.resize(native_surface->swapchainImageViews.size());
for (size_t i = 0; i < swapchainImageViews.size(); i++) { for (size_t i = 0; i < native_surface->swapchainImageViews.size(); i++) {
VkImageView attachments[] = { VkImageView attachments[] = {
swapchainImageViews[i] native_surface->swapchainImageViews[i]
}; };
VkFramebufferCreateInfo framebufferInfo = {}; VkFramebufferCreateInfo framebufferInfo = {};
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferInfo.renderPass = swapchainRenderPass; framebufferInfo.renderPass = native_surface->swapchainRenderPass;
framebufferInfo.attachmentCount = 1; framebufferInfo.attachmentCount = 1;
framebufferInfo.pAttachments = attachments; framebufferInfo.pAttachments = attachments;
framebufferInfo.width = surfaceWidth; framebufferInfo.width = native_surface->surfaceWidth;
framebufferInfo.height = surfaceHeight; framebufferInfo.height = native_surface->surfaceHeight;
framebufferInfo.layers = 1; framebufferInfo.layers = 1;
vkCreateFramebuffer(device, &framebufferInfo, nullptr, &swapchainFramebuffers[i]); vkCreateFramebuffer(device, &framebufferInfo, nullptr, &native_surface->swapchainFramebuffers[i]);
} }
// allocate command buffers // allocate command buffers
@ -1648,10 +1645,10 @@ void GFXVulkan::createDescriptorPool() {
vkCreateDescriptorPool(device, &poolInfo, nullptr, &descriptorPool); vkCreateDescriptorPool(device, &poolInfo, nullptr, &descriptorPool);
} }
void GFXVulkan::createSyncPrimitives() { void GFXVulkan::createSyncPrimitives(NativeSurface* native_surface) {
imageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT); native_surface->imageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
renderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT); native_surface->renderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
inFlightFences.resize(MAX_FRAMES_IN_FLIGHT); native_surface->inFlightFences.resize(MAX_FRAMES_IN_FLIGHT);
VkSemaphoreCreateInfo semaphoreInfo = {}; VkSemaphoreCreateInfo semaphoreInfo = {};
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
@ -1661,9 +1658,9 @@ void GFXVulkan::createSyncPrimitives() {
fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
vkCreateSemaphore(device, &semaphoreInfo, nullptr, &imageAvailableSemaphores[i]); vkCreateSemaphore(device, &semaphoreInfo, nullptr, &native_surface->imageAvailableSemaphores[i]);
vkCreateSemaphore(device, &semaphoreInfo, nullptr, &renderFinishedSemaphores[i]); vkCreateSemaphore(device, &semaphoreInfo, nullptr, &native_surface->renderFinishedSemaphores[i]);
vkCreateFence(device, &fenceCreateInfo, nullptr, &inFlightFences[i]); vkCreateFence(device, &fenceCreateInfo, nullptr, &native_surface->inFlightFences[i]);
} }
} }
@ -1706,7 +1703,7 @@ void GFXVulkan::cacheDescriptorState(GFXVulkanPipeline* pipeline, VkDescriptorSe
GFXVulkanBuffer* vulkanBuffer = (GFXVulkanBuffer*)buffer.buffer; GFXVulkanBuffer* vulkanBuffer = (GFXVulkanBuffer*)buffer.buffer;
VkDescriptorBufferInfo bufferInfo = {}; VkDescriptorBufferInfo bufferInfo = {};
bufferInfo.buffer = vulkanBuffer->get(currentFrame).handle; // will this break? bufferInfo.buffer = vulkanBuffer->handle; // will this break?
bufferInfo.offset = buffer.offset; bufferInfo.offset = buffer.offset;
bufferInfo.range = buffer.size; bufferInfo.range = buffer.size;

View file

@ -7,20 +7,9 @@
class GFXVulkanBuffer : public GFXBuffer { class GFXVulkanBuffer : public GFXBuffer {
public: public:
bool is_dynamic_data = false; VkBuffer handle;
VkDeviceMemory memory;
struct Data {
VkBuffer handle;
VkDeviceMemory memory;
} data[MAX_FRAMES_IN_FLIGHT];
Data get(int frameIndex) {
if(is_dynamic_data) {
return data[frameIndex];
} else {
return data[0];
}
}
VkDeviceSize size; VkDeviceSize size;
uint32_t frame_index = 0;
}; };

View file

@ -7,6 +7,8 @@ class GFXTexture;
class GFXFramebuffer; class GFXFramebuffer;
class GFXBuffer; class GFXBuffer;
constexpr int RT_MAX_FRAMES_IN_FLIGHT = 3;
class RenderTarget { class RenderTarget {
public: public:
prism::Extent extent; prism::Extent extent;
@ -33,9 +35,11 @@ public:
GFXFramebuffer* blend_framebuffer = nullptr; GFXFramebuffer* blend_framebuffer = nullptr;
// imgui // imgui
GFXBuffer* vertex_buffer = nullptr; GFXBuffer* vertex_buffer[RT_MAX_FRAMES_IN_FLIGHT] = {};
int current_vertex_size = 0; int current_vertex_size[RT_MAX_FRAMES_IN_FLIGHT] = {};
GFXBuffer* index_buffer = nullptr; GFXBuffer* index_buffer[RT_MAX_FRAMES_IN_FLIGHT] = {};
int current_index_size = 0; int current_index_size[RT_MAX_FRAMES_IN_FLIGHT] = {};
uint32_t current_frame = 0;
}; };

View file

@ -88,21 +88,20 @@ void ImGuiPass::render_post(GFXCommandBuffer* command_buffer, RenderTarget& targ
if(draw_data == nullptr) if(draw_data == nullptr)
return; return;
if(draw_data->TotalIdxCount == 0 || draw_data->TotalVtxCount == 0)
return;
const int framebuffer_width = static_cast<int>(draw_data->DisplaySize.x * draw_data->FramebufferScale.x); const int framebuffer_width = static_cast<int>(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
const int framebuffer_height = static_cast<int>(draw_data->DisplaySize.y * draw_data->FramebufferScale.y); const int framebuffer_height = static_cast<int>(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
Expects(framebuffer_width > 0); if (framebuffer_width <= 0 || framebuffer_height <= 0)
Expects(framebuffer_height > 0); return;
update_buffers(target, *draw_data);
command_buffer->set_graphics_pipeline(pipeline); command_buffer->set_graphics_pipeline(pipeline);
command_buffer->set_vertex_buffer(target.vertex_buffer, 0, 0); if(draw_data->TotalVtxCount > 0) {
command_buffer->set_index_buffer(target.index_buffer, IndexType::UINT16); update_buffers(target, *draw_data);
command_buffer->set_vertex_buffer(target.vertex_buffer[target.current_frame], 0, 0);
command_buffer->set_index_buffer(target.index_buffer[target.current_frame], IndexType::UINT16);
}
const Matrix4x4 projection = transform::orthographic(draw_data->DisplayPos.x, const Matrix4x4 projection = transform::orthographic(draw_data->DisplayPos.x,
draw_data->DisplayPos.x + draw_data->DisplaySize.x, draw_data->DisplayPos.x + draw_data->DisplaySize.x,
@ -146,6 +145,8 @@ void ImGuiPass::render_post(GFXCommandBuffer* command_buffer, RenderTarget& targ
index_offset += cmd_list->IdxBuffer.Size; index_offset += cmd_list->IdxBuffer.Size;
vertex_offset += cmd_list->VtxBuffer.Size; vertex_offset += cmd_list->VtxBuffer.Size;
} }
target.current_frame = (target.current_frame + 1) % RT_MAX_FRAMES_IN_FLIGHT;
} }
void ImGuiPass::load_font(const std::string_view filename) { void ImGuiPass::load_font(const std::string_view filename) {
@ -196,14 +197,14 @@ void ImGuiPass::update_buffers(RenderTarget& target, const ImDrawData& draw_data
Expects(new_vertex_size > 0); Expects(new_vertex_size > 0);
Expects(new_index_size > 0); Expects(new_index_size > 0);
if(target.vertex_buffer == nullptr || target.current_vertex_size < new_vertex_size) { if(target.vertex_buffer[target.current_frame] == nullptr || target.current_vertex_size[target.current_frame] < new_vertex_size) {
target.vertex_buffer = engine->get_gfx()->create_buffer(nullptr, new_vertex_size, true, GFXBufferUsage::Vertex); target.vertex_buffer[target.current_frame] = engine->get_gfx()->create_buffer(nullptr, new_vertex_size, true, GFXBufferUsage::Vertex);
target.current_vertex_size = new_vertex_size; target.current_vertex_size[target.current_frame] = new_vertex_size;
} }
if(target.index_buffer == nullptr || target.current_index_size < new_index_size) { if(target.index_buffer[target.current_frame] == nullptr || target.current_index_size[target.current_frame] < new_index_size) {
target.index_buffer = engine->get_gfx()->create_buffer(nullptr, new_index_size, true, GFXBufferUsage::Index); target.index_buffer[target.current_frame] = engine->get_gfx()->create_buffer(nullptr, new_index_size, true, GFXBufferUsage::Index);
target.current_index_size = new_index_size; target.current_index_size[target.current_frame] = new_index_size;
} }
int vertex_offset = 0; int vertex_offset = 0;
@ -211,8 +212,8 @@ void ImGuiPass::update_buffers(RenderTarget& target, const ImDrawData& draw_data
for(int i = 0; i < draw_data.CmdListsCount; i++) { for(int i = 0; i < draw_data.CmdListsCount; i++) {
const ImDrawList* cmd_list = draw_data.CmdLists[i]; const ImDrawList* cmd_list = draw_data.CmdLists[i];
engine->get_gfx()->copy_buffer(target.vertex_buffer, cmd_list->VtxBuffer.Data, vertex_offset, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert)); engine->get_gfx()->copy_buffer(target.vertex_buffer[target.current_frame], cmd_list->VtxBuffer.Data, vertex_offset, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
engine->get_gfx()->copy_buffer(target.index_buffer, cmd_list->IdxBuffer.Data, index_offset, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); engine->get_gfx()->copy_buffer(target.index_buffer[target.current_frame], cmd_list->IdxBuffer.Data, index_offset, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
vertex_offset += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert); vertex_offset += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert);
index_offset += cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx); index_offset += cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx);