diff --git a/config/visual-studio/renderer.vcxproj b/config/visual-studio/renderer.vcxproj index 6fb2731..def2f7f 100644 --- a/config/visual-studio/renderer.vcxproj +++ b/config/visual-studio/renderer.vcxproj @@ -105,7 +105,6 @@ - @@ -132,7 +131,6 @@ - @@ -140,9 +138,7 @@ - - diff --git a/config/visual-studio/renderer.vcxproj.filters b/config/visual-studio/renderer.vcxproj.filters index 62a97b6..4e0a0bc 100644 --- a/config/visual-studio/renderer.vcxproj.filters +++ b/config/visual-studio/renderer.vcxproj.filters @@ -92,12 +92,6 @@ Source Files - - Source Files - - - Source Files - Source Files @@ -157,12 +151,6 @@ Header Files - - Source Files - - - Source Files - Source Files diff --git a/src/engine/platform/win_glimp.c b/src/engine/platform/win_glimp.c index c6e781e..2857f9c 100644 --- a/src/engine/platform/win_glimp.c +++ b/src/engine/platform/win_glimp.c @@ -41,9 +41,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "glw_win.h" #include "win_local.h" -// VULKAN -#include "../../engine/renderer/vk_demo.h" - extern void WG_CheckHardwareGamma( void ); extern void WG_RestoreGamma( void ); @@ -572,7 +569,6 @@ static bool GLW_SetMode(int mode, qboolean fullscreen) { ri.Printf(PRINT_WARNING, "GLW_SetMode: could not create API compare window"); } else { g_wv.hWnd_vulkan = hwnd2; - vulkan_demo = new Vulkan_Demo(glConfig.vidWidth, glConfig.vidHeight); } } } else { // vulkan @@ -581,7 +577,6 @@ static bool GLW_SetMode(int mode, qboolean fullscreen) { DestroyWindow(hwnd); return false; } - vulkan_demo = new Vulkan_Demo(glConfig.vidWidth, glConfig.vidHeight); g_wv.hWnd = hwnd; g_wv.hWnd_vulkan = hwnd; diff --git a/src/engine/renderer/tr_backend.c b/src/engine/renderer/tr_backend.c index 840320f..759fe47 100644 --- a/src/engine/renderer/tr_backend.c +++ b/src/engine/renderer/tr_backend.c @@ -23,7 +23,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // VULKAN #include "vk.h" -#include "vk_demo.h" #include "vk_utils.h" backEndData_t *backEndData[SMP_FRAMES]; @@ -746,23 +745,23 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte * vk_update_cinematic_image(vk_image.image, vk_image.staging_buffer, cols, rows, data); VkDescriptorImageInfo image_info; - image_info.sampler = vulkan_demo->texture_image_sampler; + image_info.sampler = vk.sampler; image_info.imageView = vk_image.image_view; image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - std::array descriptor_writes; - descriptor_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descriptor_writes[0].dstSet = vk_image.descriptor_set; - descriptor_writes[0].dstBinding = 0; - descriptor_writes[0].dstArrayElement = 0; - descriptor_writes[0].descriptorCount = 1; - descriptor_writes[0].pNext = nullptr; - descriptor_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - descriptor_writes[0].pImageInfo = &image_info; - descriptor_writes[0].pBufferInfo = nullptr; - descriptor_writes[0].pTexelBufferView = nullptr; + VkWriteDescriptorSet descriptor_write; + descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptor_write.dstSet = vk_image.descriptor_set; + descriptor_write.dstBinding = 0; + descriptor_write.dstArrayElement = 0; + descriptor_write.descriptorCount = 1; + descriptor_write.pNext = nullptr; + descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + descriptor_write.pImageInfo = &image_info; + descriptor_write.pBufferInfo = nullptr; + descriptor_write.pTexelBufferView = nullptr; - vkUpdateDescriptorSets(vk.device, (uint32_t)descriptor_writes.size(), descriptor_writes.data(), 0, nullptr); + vkUpdateDescriptorSets(vk.device, 1, &descriptor_write, 0, nullptr); } else { if (dirty) { // otherwise, just subimage upload it so that drivers can tell we are going to be changing @@ -1053,49 +1052,7 @@ const void *RB_SwapBuffers( const void *data ) { backEnd.projection2D = qfalse; // VULKAN - extern FILE* vk_log_file; - - if (r_logFile->integer) - fprintf(vk_log_file, "end_frame (vb_size %d, ib_size %d)\n", - vk.xyz_elements * 16 + vk.color_st_elements * 20, - (int)vk.index_buffer_offset); - - vkCmdEndRenderPass(vk.command_buffer); - - VkResult result = vkEndCommandBuffer(vk.command_buffer); - check_vk_result(result, "vkEndCommandBuffer"); - - if (r_logFile->integer) { - fprintf(vk_log_file, "present\n"); - fflush(vk_log_file); - } - - VkPipelineStageFlags wait_dst_stage_mask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - VkSubmitInfo submit_info; - submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submit_info.pNext = nullptr; - submit_info.waitSemaphoreCount = 1; - submit_info.pWaitSemaphores = &vulkan_demo->image_acquired; - submit_info.pWaitDstStageMask = &wait_dst_stage_mask; - submit_info.commandBufferCount = 1; - submit_info.pCommandBuffers = &vk.command_buffer; - submit_info.signalSemaphoreCount = 1; - submit_info.pSignalSemaphores = &vulkan_demo->rendering_finished; - - result = vkQueueSubmit(vk.queue, 1, &submit_info, vulkan_demo->rendering_finished_fence); - check_vk_result(result, "vkQueueSubmit"); - - VkPresentInfoKHR present_info; - present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; - present_info.pNext = nullptr; - present_info.waitSemaphoreCount = 1; - present_info.pWaitSemaphores = &vulkan_demo->rendering_finished; - present_info.swapchainCount = 1; - present_info.pSwapchains = &vk.swapchain; - present_info.pImageIndices = &vulkan_demo->swapchain_image_index; - present_info.pResults = nullptr; - result = vkQueuePresentKHR(vk.queue, &present_info); - check_vk_result(result, "vkQueuePresentKHR"); + vk_end_frame(); return (const void *)(cmd + 1); } diff --git a/src/engine/renderer/tr_image.c b/src/engine/renderer/tr_image.c index 26ef4e1..2f36691 100644 --- a/src/engine/renderer/tr_image.c +++ b/src/engine/renderer/tr_image.c @@ -22,9 +22,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // tr_image.c #include "tr_local.h" -// VULKAN -#include "vk_demo.h" - static void* q3_stbi_malloc(size_t size) { return ri.Malloc((int)size); } @@ -780,7 +777,7 @@ image_t *R_CreateImage( const char *name, const byte *pic, int width, int height // VULKAN Vk_Image& vk_image = tr.vk_resources.images[image->index]; - vk_image.image = vulkan_demo->create_texture(pic, 4, width, height, vk_image.image_view); + vk_image.image = vk_create_texture(pic, 4, width, height, vk_image.image_view); vk_image.descriptor_set = vk_create_descriptor_set(vk_image.image_view); return image; diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index d320946..0d52217 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -951,11 +951,7 @@ extern glconfig_t glConfig; // outside of TR since it shouldn't be cleared duri extern glstate_t glState; // outside of TR since it shouldn't be cleared during ref re-init // VULKAN -extern Vulkan_Instance vk; // same as above - shouldn't be cleared during ref re-init - -// VULKAN -class Vulkan_Demo; -extern Vulkan_Demo* vulkan_demo; +extern Vulkan_Instance vk; // same as above - shouldn't be cleared during ref re-init // diff --git a/src/engine/renderer/tr_main.c b/src/engine/renderer/tr_main.c index ae1e1bc..7e9a7a8 100644 --- a/src/engine/renderer/tr_main.c +++ b/src/engine/renderer/tr_main.c @@ -25,9 +25,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA trGlobals_t tr; -// VULKAN -Vulkan_Demo* vulkan_demo; - static float s_flipMatrix[16] = { // convert from our coordinate system (looking down X) // to OpenGL's coordinate system (looking down -Z) diff --git a/src/engine/renderer/tr_scene.c b/src/engine/renderer/tr_scene.c index a875f26..dc15cfb 100644 --- a/src/engine/renderer/tr_scene.c +++ b/src/engine/renderer/tr_scene.c @@ -22,9 +22,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "tr_local.h" -// VULKAN -#include "vk_demo.h" - int r_firstSceneDrawSurf; int r_numdlights; diff --git a/src/engine/renderer/tr_shade.c b/src/engine/renderer/tr_shade.c index 522fe28..9763078 100644 --- a/src/engine/renderer/tr_shade.c +++ b/src/engine/renderer/tr_shade.c @@ -23,9 +23,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "tr_local.h" -// VULKAN -#include "vk_demo.h" - /* THIS ENTIRE FILE IS BACK END diff --git a/src/engine/renderer/vk.cpp b/src/engine/renderer/vk.cpp index 8d1213f..20d8817 100644 --- a/src/engine/renderer/vk.cpp +++ b/src/engine/renderer/vk.cpp @@ -2,12 +2,12 @@ #include "vk_utils.h" #include "vk_allocator.h" -#include "vk_resource_manager.h" - -#include "vk_demo.h" +#include #include +FILE* vk_log_file; + const int VERTEX_CHUNK_SIZE = 512 * 1024; const int XYZ_SIZE = 4 * VERTEX_CHUNK_SIZE; @@ -327,6 +327,8 @@ static VkRenderPass create_render_pass(VkDevice device, VkFormat color_format, V VkPipeline create_pipeline(const Vk_Pipeline_Desc&); bool vk_initialize(HWND hwnd) { + vk_log_file = fopen("vk_dev.log", "w"); + try { auto& g = vk; @@ -394,7 +396,6 @@ bool vk_initialize(HWND hwnd) { } get_allocator()->initialize(vk.physical_device, vk.device); - get_resource_manager()->initialize(vk.device); { VkFormat depth_format = find_depth_format(vk.physical_device); @@ -412,15 +413,15 @@ bool vk_initialize(HWND hwnd) { vk.render_pass = create_render_pass(vk.device, vk.surface_format.format, depth_format); { - std::array attachments = {VK_NULL_HANDLE, vk.depth_image_view}; + VkImageView attachments[2] = {VK_NULL_HANDLE, vk.depth_image_view}; VkFramebufferCreateInfo desc; desc.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; desc.pNext = nullptr; desc.flags = 0; desc.renderPass = vk.render_pass; - desc.attachmentCount = static_cast(attachments.size()); - desc.pAttachments = attachments.data(); + desc.attachmentCount = 2; + desc.pAttachments = attachments; desc.width = glConfig.vidWidth; desc.height = glConfig.vidHeight; desc.layers = 1; @@ -499,7 +500,7 @@ bool vk_initialize(HWND hwnd) { } // - // Create geometry buffers. + // Geometry buffers. // { VkBufferCreateInfo desc; @@ -548,6 +549,34 @@ bool vk_initialize(HWND hwnd) { vk.index_buffer_ptr = (byte*)data; } + // + // Samplers. + // + { + VkSamplerCreateInfo desc; + desc.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + desc.pNext = nullptr; + desc.flags = 0; + desc.magFilter = VK_FILTER_LINEAR; + desc.minFilter = VK_FILTER_LINEAR; + desc.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; + desc.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; + desc.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; + desc.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; + desc.mipLodBias = 0.0f; + desc.anisotropyEnable = VK_TRUE; + desc.maxAnisotropy = 1; + desc.compareEnable = VK_FALSE; + desc.compareOp = VK_COMPARE_OP_ALWAYS; + desc.minLod = 0.0f; + desc.maxLod = 0.0f; + desc.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK; + desc.unnormalizedCoordinates = VK_FALSE; + + VkResult result = vkCreateSampler(vk.device, &desc, nullptr, &vk.sampler); + check_vk_result(result, "vkCreateSampler"); + } + // // Skybox pipeline. // @@ -561,6 +590,28 @@ bool vk_initialize(HWND hwnd) { vk.skybox_pipeline = create_pipeline(desc); } + // + // Sync primitives. + // + { + VkSemaphoreCreateInfo desc; + desc.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + desc.pNext = nullptr; + desc.flags = 0; + + VkResult result = vkCreateSemaphore(vk.device, &desc, nullptr, &vk.image_acquired); + check_vk_result(result, "vkCreateSemaphore"); + result = vkCreateSemaphore(vk.device, &desc, nullptr, &vk.rendering_finished); + check_vk_result(result, "vkCreateSemaphore"); + + VkFenceCreateInfo fence_desc; + fence_desc.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + fence_desc.pNext = nullptr; + fence_desc.flags = VK_FENCE_CREATE_SIGNALED_BIT; + result = vkCreateFence(vk.device, &fence_desc, nullptr, &vk.rendering_finished_fence); + check_vk_result(result, "vkCreateFence"); + } + } catch (const std::exception&) { return false; } @@ -568,12 +619,13 @@ bool vk_initialize(HWND hwnd) { } void vk_deinitialize() { + fclose(vk_log_file); + vk_log_file = nullptr; + auto& g = vk; - get_resource_manager()->release_resources(); get_allocator()->deallocate_all(); - vkDestroyFence(vk.device, vulkan_demo->rendering_finished_fence, nullptr); vkDestroyImage(vk.device, vk.depth_image, nullptr); vkDestroyImageView(vk.device, vk.depth_image_view, nullptr); @@ -594,7 +646,11 @@ void vk_deinitialize() { vkDestroyPipelineLayout(vk.device, vk.pipeline_layout, nullptr); vkDestroyBuffer(vk.device, vk.vertex_buffer, nullptr); vkDestroyBuffer(vk.device, vk.index_buffer, nullptr); + vkDestroySampler(vk.device, vk.sampler, nullptr); vkDestroyPipeline(vk.device, vk.skybox_pipeline, nullptr); + vkDestroySemaphore(vk.device, vk.image_acquired, nullptr); + vkDestroySemaphore(vk.device, vk.rendering_finished, nullptr); + vkDestroyFence(vk.device, vk.rendering_finished_fence, nullptr); vkDestroySwapchainKHR(g.device, g.swapchain, nullptr); vkDestroyDevice(g.device, nullptr); @@ -604,6 +660,55 @@ void vk_deinitialize() { g = Vulkan_Instance(); } +VkImage vk_create_texture(const uint8_t* pixels, int bytes_per_pixel, int image_width, int image_height, VkImageView& image_view) { + VkImage staging_image = create_staging_texture(image_width, image_height, + bytes_per_pixel == 3 ? VK_FORMAT_R8G8B8_UNORM : VK_FORMAT_R8G8B8A8_UNORM, pixels, bytes_per_pixel); + + Defer_Action destroy_staging_image([&staging_image]() { + vkDestroyImage(vk.device, staging_image, nullptr); + }); + + VkImage texture_image = ::create_texture(image_width, image_height, + bytes_per_pixel == 3 ? VK_FORMAT_R8G8B8_UNORM : VK_FORMAT_R8G8B8A8_UNORM); + + record_and_run_commands(vk.command_pool, vk.queue, + [&texture_image, &staging_image, &image_width, &image_height](VkCommandBuffer command_buffer) { + + record_image_layout_transition(command_buffer, staging_image, VK_FORMAT_R8G8B8A8_UNORM, + VK_ACCESS_HOST_WRITE_BIT, VK_IMAGE_LAYOUT_PREINITIALIZED, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + + record_image_layout_transition(command_buffer, texture_image, VK_FORMAT_R8G8B8A8_UNORM, + 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + + // copy staging image's data to device local image + VkImageSubresourceLayers subresource_layers; + subresource_layers.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + subresource_layers.mipLevel = 0; + subresource_layers.baseArrayLayer = 0; + subresource_layers.layerCount = 1; + + VkImageCopy region; + region.srcSubresource = subresource_layers; + region.srcOffset = {0, 0, 0}; + region.dstSubresource = subresource_layers; + region.dstOffset = {0, 0, 0}; + region.extent.width = image_width; + region.extent.height = image_height; + region.extent.depth = 1; + + vkCmdCopyImage(command_buffer, + staging_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + texture_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, ®ion); + + record_image_layout_transition(command_buffer, texture_image, VK_FORMAT_R8G8B8A8_UNORM, + VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + }); + + image_view = create_image_view(texture_image, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT); + return texture_image; +} + VkImage vk_create_cinematic_image(int width, int height, Vk_Staging_Buffer& staging_buffer) { VkBufferCreateInfo buffer_desc; buffer_desc.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; @@ -723,14 +828,14 @@ static VkPipeline create_pipeline(const Vk_Pipeline_Desc& desc) { else ri.Error(ERR_DROP, "create_pipeline: invalid alpha test state bits\n"); - std::array specialization_entries; + VkSpecializationMapEntry specialization_entries[1]; specialization_entries[0].constantID = 0; specialization_entries[0].offset = offsetof(struct Specialization_Data, alpha_test_func); specialization_entries[0].size = sizeof(int32_t); VkSpecializationInfo specialization_info; - specialization_info.mapEntryCount = uint32_t(specialization_entries.size()); - specialization_info.pMapEntries = specialization_entries.data(); + specialization_info.mapEntryCount = 1; + specialization_info.pMapEntries = specialization_entries; specialization_info.dataSize = sizeof(Specialization_Data); specialization_info.pData = &specialization_data; @@ -1052,23 +1157,23 @@ VkDescriptorSet vk_create_descriptor_set(VkImageView image_view) { check_vk_result(result, "vkAllocateDescriptorSets"); VkDescriptorImageInfo image_info; - image_info.sampler = vulkan_demo->texture_image_sampler; + image_info.sampler = vk.sampler; image_info.imageView = image_view; image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - std::array descriptor_writes; - descriptor_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descriptor_writes[0].dstSet = set; - descriptor_writes[0].dstBinding = 0; - descriptor_writes[0].dstArrayElement = 0; - descriptor_writes[0].descriptorCount = 1; - descriptor_writes[0].pNext = nullptr; - descriptor_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - descriptor_writes[0].pImageInfo = &image_info; - descriptor_writes[0].pBufferInfo = nullptr; - descriptor_writes[0].pTexelBufferView = nullptr; + VkWriteDescriptorSet descriptor_write; + descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptor_write.dstSet = set; + descriptor_write.dstBinding = 0; + descriptor_write.dstArrayElement = 0; + descriptor_write.descriptorCount = 1; + descriptor_write.pNext = nullptr; + descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + descriptor_write.pImageInfo = &image_info; + descriptor_write.pBufferInfo = nullptr; + descriptor_write.pTexelBufferView = nullptr; - vkUpdateDescriptorSets(vk.device, (uint32_t)descriptor_writes.size(), descriptor_writes.data(), 0, nullptr); + vkUpdateDescriptorSets(vk.device, 1, &descriptor_write, 0, nullptr); return set; } @@ -1287,16 +1392,15 @@ void vk_bind_stage_specific_resources(VkPipeline pipeline, bool multitexture, bo } void vk_begin_frame() { - extern FILE* vk_log_file; if (r_logFile->integer) fprintf(vk_log_file, "vk_begin_frame\n"); - VkResult result = vkAcquireNextImageKHR(vk.device, vk.swapchain, UINT64_MAX, vulkan_demo->image_acquired, VK_NULL_HANDLE, &vulkan_demo->swapchain_image_index); + VkResult result = vkAcquireNextImageKHR(vk.device, vk.swapchain, UINT64_MAX, vk.image_acquired, VK_NULL_HANDLE, &vk.swapchain_image_index); check_vk_result(result, "vkAcquireNextImageKHR"); - result = vkWaitForFences(vk.device, 1, &vulkan_demo->rendering_finished_fence, VK_FALSE, 1e9); + result = vkWaitForFences(vk.device, 1, &vk.rendering_finished_fence, VK_FALSE, 1e9); check_vk_result(result, "vkWaitForFences"); - result = vkResetFences(vk.device, 1, &vulkan_demo->rendering_finished_fence); + result = vkResetFences(vk.device, 1, &vk.rendering_finished_fence); check_vk_result(result, "vkResetFences"); VkCommandBufferBeginInfo begin_info; @@ -1317,7 +1421,7 @@ void vk_begin_frame() { render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; render_pass_begin_info.pNext = nullptr; render_pass_begin_info.renderPass = vk.render_pass; - render_pass_begin_info.framebuffer = vk.framebuffers[vulkan_demo->swapchain_image_index]; + render_pass_begin_info.framebuffer = vk.framebuffers[vk.swapchain_image_index]; render_pass_begin_info.renderArea.offset = { 0, 0 }; render_pass_begin_info.renderArea.extent = { (uint32_t)glConfig.vidWidth, (uint32_t)glConfig.vidHeight }; render_pass_begin_info.clearValueCount = 2; @@ -1331,3 +1435,47 @@ void vk_begin_frame() { glState.vk_dirty_attachments = false; } + +void vk_end_frame() { + if (r_logFile->integer) + fprintf(vk_log_file, "end_frame (vb_size %d, ib_size %d)\n", + vk.xyz_elements * 16 + vk.color_st_elements * 20, + (int)vk.index_buffer_offset); + + vkCmdEndRenderPass(vk.command_buffer); + + VkResult result = vkEndCommandBuffer(vk.command_buffer); + check_vk_result(result, "vkEndCommandBuffer"); + + if (r_logFile->integer) { + fprintf(vk_log_file, "present\n"); + fflush(vk_log_file); + } + + VkPipelineStageFlags wait_dst_stage_mask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + VkSubmitInfo submit_info; + submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submit_info.pNext = nullptr; + submit_info.waitSemaphoreCount = 1; + submit_info.pWaitSemaphores = &vk.image_acquired; + submit_info.pWaitDstStageMask = &wait_dst_stage_mask; + submit_info.commandBufferCount = 1; + submit_info.pCommandBuffers = &vk.command_buffer; + submit_info.signalSemaphoreCount = 1; + submit_info.pSignalSemaphores = &vk.rendering_finished; + + result = vkQueueSubmit(vk.queue, 1, &submit_info, vk.rendering_finished_fence); + check_vk_result(result, "vkQueueSubmit"); + + VkPresentInfoKHR present_info; + present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; + present_info.pNext = nullptr; + present_info.waitSemaphoreCount = 1; + present_info.pWaitSemaphores = &vk.rendering_finished; + present_info.swapchainCount = 1; + present_info.pSwapchains = &vk.swapchain; + present_info.pImageIndices = &vk.swapchain_image_index; + present_info.pResults = nullptr; + result = vkQueuePresentKHR(vk.queue, &present_info); + check_vk_result(result, "vkQueuePresentKHR"); +} diff --git a/src/engine/renderer/vk.h b/src/engine/renderer/vk.h index d2348a0..fc8193a 100644 --- a/src/engine/renderer/vk.h +++ b/src/engine/renderer/vk.h @@ -56,6 +56,7 @@ bool vk_initialize(HWND hwnd); void vk_deinitialize(); void vk_destroy_resources(); +VkImage vk_create_texture(const uint8_t* pixels, int bytes_per_pixel, int width, int height, VkImageView& image_view); VkImage vk_create_cinematic_image(int width, int height, Vk_Staging_Buffer& staging_buffer); void vk_update_cinematic_image(VkImage image, const Vk_Staging_Buffer& staging_buffer, int width, int height, const uint8_t* rgba_pixels); VkPipeline vk_find_pipeline(const Vk_Pipeline_Desc& desc); @@ -68,6 +69,7 @@ void vk_bind_resources_shared_between_stages(); void vk_bind_stage_specific_resources(VkPipeline pipeline, bool multitexture, bool sky); void vk_begin_frame(); +void vk_end_frame(); // Shaders. @@ -126,7 +128,15 @@ struct Vulkan_Instance { byte* index_buffer_ptr = nullptr; // pointer to mapped index buffer VkDeviceSize index_buffer_offset = 0; + VkSampler sampler = VK_NULL_HANDLE; + VkPipeline skybox_pipeline = VK_NULL_HANDLE; + + VkSemaphore image_acquired = VK_NULL_HANDLE; + uint32_t swapchain_image_index = -1; + + VkSemaphore rendering_finished = VK_NULL_HANDLE; + VkFence rendering_finished_fence = VK_NULL_HANDLE; }; struct Vulkan_Resources { diff --git a/src/engine/renderer/vk_demo.cpp b/src/engine/renderer/vk_demo.cpp deleted file mode 100644 index 2028573..0000000 --- a/src/engine/renderer/vk_demo.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include "vk_allocator.h" -#include "vk_resource_manager.h" -#include "vk_demo.h" -#include "vk.h" -#include "vk_utils.h" - -#include "stb_image.h" - -#include -#include -#include -#include -#include - -#include "tr_local.h" - -FILE* vk_log_file; - -Vulkan_Demo::Vulkan_Demo(int window_width, int window_height) -: window_width(window_width) -, window_height(window_height) -{ - vk_log_file = fopen("vk_dev.log", "w"); - - image_acquired = get_resource_manager()->create_semaphore(); - rendering_finished = get_resource_manager()->create_semaphore(); - - VkFenceCreateInfo fence_desc; - fence_desc.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; - fence_desc.pNext = nullptr; - fence_desc.flags = VK_FENCE_CREATE_SIGNALED_BIT; - VkResult result = vkCreateFence(vk.device, &fence_desc, nullptr, &rendering_finished_fence); - check_vk_result(result, "vkCreateFence"); - - create_texture_sampler(); -} - -VkImage Vulkan_Demo::create_texture(const uint8_t* pixels, int bytes_per_pixel, int image_width, int image_height, VkImageView& image_view) { - VkImage staging_image = create_staging_texture(image_width, image_height, - bytes_per_pixel == 3 ? VK_FORMAT_R8G8B8_UNORM : VK_FORMAT_R8G8B8A8_UNORM, pixels, bytes_per_pixel); - - Defer_Action destroy_staging_image([this, &staging_image]() { - vkDestroyImage(vk.device, staging_image, nullptr); - }); - - VkImage texture_image = ::create_texture(image_width, image_height, - bytes_per_pixel == 3 ? VK_FORMAT_R8G8B8_UNORM : VK_FORMAT_R8G8B8A8_UNORM); - - record_and_run_commands(vk.command_pool, vk.queue, - [&texture_image, &staging_image, &image_width, &image_height, this](VkCommandBuffer command_buffer) { - - record_image_layout_transition(command_buffer, staging_image, VK_FORMAT_R8G8B8A8_UNORM, - VK_ACCESS_HOST_WRITE_BIT, VK_IMAGE_LAYOUT_PREINITIALIZED, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); - - record_image_layout_transition(command_buffer, texture_image, VK_FORMAT_R8G8B8A8_UNORM, - 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - - // copy staging image's data to device local image - VkImageSubresourceLayers subresource_layers; - subresource_layers.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - subresource_layers.mipLevel = 0; - subresource_layers.baseArrayLayer = 0; - subresource_layers.layerCount = 1; - - VkImageCopy region; - region.srcSubresource = subresource_layers; - region.srcOffset = {0, 0, 0}; - region.dstSubresource = subresource_layers; - region.dstOffset = {0, 0, 0}; - region.extent.width = image_width; - region.extent.height = image_height; - region.extent.depth = 1; - - vkCmdCopyImage(command_buffer, - staging_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - texture_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 1, ®ion); - - record_image_layout_transition(command_buffer, texture_image, VK_FORMAT_R8G8B8A8_UNORM, - VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - }); - - image_view = create_image_view(texture_image, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT); - return texture_image; -} - -void Vulkan_Demo::create_texture_sampler() { - VkSamplerCreateInfo desc; - desc.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - desc.pNext = nullptr; - desc.flags = 0; - desc.magFilter = VK_FILTER_LINEAR; - desc.minFilter = VK_FILTER_LINEAR; - desc.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; - desc.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; - desc.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; - desc.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; - desc.mipLodBias = 0.0f; - desc.anisotropyEnable = VK_TRUE; - desc.maxAnisotropy = 1; - desc.compareEnable = VK_FALSE; - desc.compareOp = VK_COMPARE_OP_ALWAYS; - desc.minLod = 0.0f; - desc.maxLod = 0.0f; - desc.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK; - desc.unnormalizedCoordinates = VK_FALSE; - - texture_image_sampler = get_resource_manager()->create_sampler(desc); -} diff --git a/src/engine/renderer/vk_demo.h b/src/engine/renderer/vk_demo.h deleted file mode 100644 index 87064eb..0000000 --- a/src/engine/renderer/vk_demo.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "vk.h" -#include "tr_local.h" - -class Vulkan_Demo { -public: - Vulkan_Demo(int window_width, int window_height); - -public: - VkImage create_texture(const uint8_t* pixels, int bytes_per_pixel, int width, int height, VkImageView& image_view); - void create_texture_sampler(); - -public: - const int window_width = 0; - const int window_height = 0; - - VkSemaphore image_acquired = VK_NULL_HANDLE; - VkSemaphore rendering_finished = VK_NULL_HANDLE; - VkFence rendering_finished_fence = VK_NULL_HANDLE; - - VkSampler texture_image_sampler = VK_NULL_HANDLE; - - uint32_t swapchain_image_index = -1; -}; diff --git a/src/engine/renderer/vk_resource_manager.cpp b/src/engine/renderer/vk_resource_manager.cpp deleted file mode 100644 index 6c58187..0000000 --- a/src/engine/renderer/vk_resource_manager.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "vk_resource_manager.h" - -static Resource_Manager resource_manager; - -Resource_Manager* get_resource_manager() { - return &resource_manager; -} - -void Resource_Manager::initialize(VkDevice device) { - this->device = device; -} - -void Resource_Manager::release_resources() { - for (auto semaphore : semaphores) { - vkDestroySemaphore(device, semaphore, nullptr); - } - semaphores.clear(); - - for (auto sampler : samplers) { - vkDestroySampler(device, sampler, nullptr); - } - samplers.clear(); -} - -VkSemaphore Resource_Manager::create_semaphore() { - VkSemaphoreCreateInfo desc; - desc.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - desc.pNext = nullptr; - desc.flags = 0; - - VkSemaphore semaphore; - VkResult result = vkCreateSemaphore(device, &desc, nullptr, &semaphore); - check_vk_result(result, "vkCreateSemaphore"); - semaphores.push_back(semaphore); - return semaphore; -} - -VkSampler Resource_Manager::create_sampler(const VkSamplerCreateInfo& desc) { - VkSampler sampler; - VkResult result = vkCreateSampler(device, &desc, nullptr, &sampler); - check_vk_result(result, "vkCreateSampler"); - samplers.push_back(sampler); - return sampler; -} diff --git a/src/engine/renderer/vk_resource_manager.h b/src/engine/renderer/vk_resource_manager.h deleted file mode 100644 index 4d2236b..0000000 --- a/src/engine/renderer/vk_resource_manager.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "vk_utils.h" -#include - -class Resource_Manager { -public: - void initialize(VkDevice device); - void release_resources(); - - VkSemaphore create_semaphore(); - VkSampler create_sampler(const VkSamplerCreateInfo& desc); - -private: - VkDevice device = VK_NULL_HANDLE; - std::vector semaphores; - std::vector samplers; -}; - -Resource_Manager* get_resource_manager(); diff --git a/src/engine/renderer/vk_utils.cpp b/src/engine/renderer/vk_utils.cpp index 742754f..f5b66df 100644 --- a/src/engine/renderer/vk_utils.cpp +++ b/src/engine/renderer/vk_utils.cpp @@ -1,5 +1,4 @@ #include "vk_allocator.h" -#include "vk_resource_manager.h" #include "vk.h" #include "vk_utils.h" #include