diff --git a/src/engine/platform/win_glimp.c b/src/engine/platform/win_glimp.c index c6d7db9..c6e781e 100644 --- a/src/engine/platform/win_glimp.c +++ b/src/engine/platform/win_glimp.c @@ -566,7 +566,7 @@ static bool GLW_SetMode(int mode, qboolean fullscreen) { if (r_renderAPICompareWindow->integer) { HWND hwnd2 = create_api_compare_window(glConfig.vidWidth, glConfig.vidHeight); - if (!initialize_vulkan(hwnd2)) { + if (!vk_initialize(hwnd2)) { ShowWindow(hwnd2, SW_HIDE); DestroyWindow(hwnd2); ri.Printf(PRINT_WARNING, "GLW_SetMode: could not create API compare window"); @@ -576,7 +576,7 @@ static bool GLW_SetMode(int mode, qboolean fullscreen) { } } } else { // vulkan - if (!initialize_vulkan(hwnd)) { + if (!vk_initialize(hwnd)) { ShowWindow(hwnd, SW_HIDE); DestroyWindow(hwnd); return false; diff --git a/src/engine/renderer/tr_backend.c b/src/engine/renderer/tr_backend.c index ff9e8e5..9242883 100644 --- a/src/engine/renderer/tr_backend.c +++ b/src/engine/renderer/tr_backend.c @@ -691,8 +691,8 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte * qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); // VULKAN - vkDestroyImage(get_device(), tr.scratchImage[client]->vk_image, nullptr); - vkDestroyImageView(get_device(), tr.scratchImage[client]->vk_image_view, nullptr); + vkDestroyImage(vk_instance.device, tr.scratchImage[client]->vk_image, nullptr); + vkDestroyImageView(vk_instance.device, tr.scratchImage[client]->vk_image_view, nullptr); tr.scratchImage[client]->vk_image = vk_create_cinematic_image(cols, rows, tr.scratchImage[client]->vk_staging_buffer); tr.scratchImage[client]->vk_image_view = create_image_view(tr.scratchImage[client]->vk_image, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT); vk_update_cinematic_image(tr.scratchImage[client]->vk_image, tr.scratchImage[client]->vk_staging_buffer, cols, rows, data); @@ -714,7 +714,7 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte * descriptor_writes[0].pBufferInfo = nullptr; descriptor_writes[0].pTexelBufferView = nullptr; - vkUpdateDescriptorSets(get_device(), (uint32_t)descriptor_writes.size(), descriptor_writes.data(), 0, nullptr); + vkUpdateDescriptorSets(vk_instance.device, (uint32_t)descriptor_writes.size(), descriptor_writes.data(), 0, nullptr); } else { if (dirty) { // otherwise, just subimage upload it so that drivers can tell we are going to be changing @@ -898,12 +898,12 @@ const void *RB_DrawBuffer( const void *data ) { } // VULKAN - VkResult result = vkAcquireNextImageKHR(get_device(), get_swapchain(), UINT64_MAX, vulkan_demo->image_acquired, VK_NULL_HANDLE, &vulkan_demo->swapchain_image_index); + VkResult result = vkAcquireNextImageKHR(vk_instance.device, vk_instance.swapchain, UINT64_MAX, vulkan_demo->image_acquired, VK_NULL_HANDLE, &vulkan_demo->swapchain_image_index); check_vk_result(result, "vkAcquireNextImageKHR"); - result = vkWaitForFences(get_device(), 1, &vulkan_demo->rendering_finished_fence, VK_FALSE, 1e9); + result = vkWaitForFences(vk_instance.device, 1, &vulkan_demo->rendering_finished_fence, VK_FALSE, 1e9); check_vk_result(result, "vkWaitForFences"); - result = vkResetFences(get_device(), 1, &vulkan_demo->rendering_finished_fence); + result = vkResetFences(vk_instance.device, 1, &vulkan_demo->rendering_finished_fence); check_vk_result(result, "vkResetFences"); VkCommandBufferBeginInfo begin_info; @@ -1051,20 +1051,19 @@ const void *RB_SwapBuffers( const void *data ) { submit_info.signalSemaphoreCount = 1; submit_info.pSignalSemaphores = &vulkan_demo->rendering_finished; - result = vkQueueSubmit(get_queue(), 1, &submit_info, vulkan_demo->rendering_finished_fence); + result = vkQueueSubmit(vk_instance.queue, 1, &submit_info, vulkan_demo->rendering_finished_fence); check_vk_result(result, "vkQueueSubmit"); - VkSwapchainKHR swapchain = get_swapchain(); 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 = &swapchain; + present_info.pSwapchains = &vk_instance.swapchain; present_info.pImageIndices = &vulkan_demo->swapchain_image_index; present_info.pResults = nullptr; - result = vkQueuePresentKHR(get_queue(), &present_info); + result = vkQueuePresentKHR(vk_instance.queue, &present_info); check_vk_result(result, "vkQueuePresentKHR"); return (const void *)(cmd + 1); diff --git a/src/engine/renderer/tr_init.c b/src/engine/renderer/tr_init.c index b40d5e0..37b9b35 100644 --- a/src/engine/renderer/tr_init.c +++ b/src/engine/renderer/tr_init.c @@ -26,6 +26,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA glconfig_t glConfig; glstate_t glState; +// VULKAN +Vulkan_Instance vk_instance; + static void GfxInfo_f( void ); cvar_t *r_renderAPI; @@ -1041,7 +1044,7 @@ void RE_Shutdown( qboolean destroyWindow ) { R_DeleteTextures(); // VULKAN - vk_destroy_pipelines(); + vk_destroy_resources(); } R_DoneFreeType(); diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 9c0ccb0..993f28e 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -55,9 +55,6 @@ long myftol( float f ); // can't be increased without changing bit packing for drawsurfs -// VULKAN -#define MAX_VK_PIPELINES 2048 - typedef struct dlight_s { vec3_t origin; vec3_t color; // range from 0.0 to 1.0, should be color normalized @@ -942,9 +939,7 @@ typedef struct { float fogTable[FOG_TABLE_SIZE]; // VULKAN - int vk_num_pipelines; - Vk_Pipeline_Desc vk_pipeline_desc[MAX_VK_PIPELINES]; - VkPipeline vk_pipelines[MAX_VK_PIPELINES]; + Vulkan_Resources vk; } trGlobals_t; @@ -953,6 +948,9 @@ extern trGlobals_t tr; extern glconfig_t glConfig; // outside of TR since it shouldn't be cleared during ref re-init extern glstate_t glState; // outside of TR since it shouldn't be cleared during ref re-init +// VULKAN +extern Vulkan_Instance vk_instance; // same as above - shouldn't be cleared during ref re-init + // VULKAN class Vulkan_Demo; extern Vulkan_Demo* vulkan_demo; diff --git a/src/engine/renderer/vk.cpp b/src/engine/renderer/vk.cpp index 111b325..365765c 100644 --- a/src/engine/renderer/vk.cpp +++ b/src/engine/renderer/vk.cpp @@ -11,21 +11,6 @@ #include #include -struct Vulkan_Globals { - VkInstance instance = VK_NULL_HANDLE; - VkPhysicalDevice physical_device = VK_NULL_HANDLE; - VkSurfaceKHR surface = VK_NULL_HANDLE; - uint32_t queue_family_index = 0; - VkDevice device = VK_NULL_HANDLE; - VkQueue queue = VK_NULL_HANDLE; - VkSurfaceFormatKHR surface_format = {}; - VkSwapchainKHR swapchain = VK_NULL_HANDLE; - std::vector swapchain_images; - std::vector swapchain_image_views; -}; - -static Vulkan_Globals vulkan_globals; - static const std::vector instance_extensions = { VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME @@ -249,30 +234,31 @@ static VkSwapchainKHR create_swapchain(VkPhysicalDevice physical_device, VkDevic return swapchain; } -bool initialize_vulkan(HWND hwnd) { +bool vk_initialize(HWND hwnd) { try { - auto& g = vulkan_globals; + auto& g = vk_instance; g.instance = create_instance(); g.physical_device = select_physical_device(g.instance); g.surface = create_surface(g.instance, hwnd); + g.surface_format = select_surface_format(g.physical_device, g.surface); + g.queue_family_index = select_queue_family(g.physical_device, g.surface); g.device = create_device(g.physical_device, g.queue_family_index); - vkGetDeviceQueue(g.device, g.queue_family_index, 0, &g.queue); - g.surface_format = select_surface_format(g.physical_device, g.surface); g.swapchain = create_swapchain(g.physical_device, g.device, g.surface, g.surface_format); - uint32_t image_count; - VkResult result = vkGetSwapchainImagesKHR(g.device, g.swapchain, &image_count, nullptr); - check_vk_result(result, "vkGetSwapchainImagesKHR"); - g.swapchain_images.resize(image_count); - result = vkGetSwapchainImagesKHR(g.device, g.swapchain, &image_count, g.swapchain_images.data()); + VkResult result = vkGetSwapchainImagesKHR(g.device, g.swapchain, &vk_instance.swapchain_image_count, nullptr); check_vk_result(result, "vkGetSwapchainImagesKHR"); - g.swapchain_image_views.resize(image_count); - for (std::size_t i = 0; i < image_count; i++) { + if (vk_instance.swapchain_image_count > MAX_SWAPCHAIN_IMAGES) + ri.Error( ERR_FATAL, "initialize_vulkan: swapchain image count (%d) exceeded limit (%d)", vk_instance.swapchain_image_count, MAX_SWAPCHAIN_IMAGES ); + + result = vkGetSwapchainImagesKHR(g.device, g.swapchain, &vk_instance.swapchain_image_count, g.swapchain_images); + check_vk_result(result, "vkGetSwapchainImagesKHR"); + + for (std::size_t i = 0; i < vk_instance.swapchain_image_count; i++) { VkImageViewCreateInfo desc; desc.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; desc.pNext = nullptr; @@ -298,8 +284,8 @@ bool initialize_vulkan(HWND hwnd) { return true; } -void deinitialize_vulkan() { - auto& g = vulkan_globals; +void vk_deinitialize() { + auto& g = vk_instance; for (auto image_view : g.swapchain_image_views) { vkDestroyImageView(g.device, image_view, nullptr); } @@ -307,35 +293,7 @@ void deinitialize_vulkan() { vkDestroyDevice(g.device, nullptr); vkDestroySurfaceKHR(g.instance, g.surface, nullptr); vkDestroyInstance(g.instance, nullptr); - g = Vulkan_Globals(); -} - -VkPhysicalDevice get_physical_device() { - return vulkan_globals.physical_device; -} - -VkDevice get_device() { - return vulkan_globals.device; -} - -uint32_t get_queue_family_index() { - return vulkan_globals.queue_family_index; -} - -VkQueue get_queue() { - return vulkan_globals.queue; -} - -VkSwapchainKHR get_swapchain() { - return vulkan_globals.swapchain; -} - -VkFormat get_swapchain_image_format() { - return vulkan_globals.surface_format.format; -} - -const std::vector& get_swapchain_image_views() { - return vulkan_globals.swapchain_image_views; + g = Vulkan_Instance(); } VkImage vk_create_cinematic_image(int width, int height, Vk_Staging_Buffer& staging_buffer) { @@ -350,11 +308,11 @@ VkImage vk_create_cinematic_image(int width, int height, Vk_Staging_Buffer& stag buffer_desc.pQueueFamilyIndices = nullptr; VkBuffer buffer; - VkResult result = vkCreateBuffer(get_device(), &buffer_desc, nullptr, &buffer); + VkResult result = vkCreateBuffer(vk_instance.device, &buffer_desc, nullptr, &buffer); check_vk_result(result, "vkCreateBuffer"); VkDeviceMemory buffer_memory = get_allocator()->allocate_staging_memory(buffer); - result = vkBindBufferMemory(get_device(), buffer, buffer_memory, 0); + result = vkBindBufferMemory(vk_instance.device, buffer, buffer_memory, 0); check_vk_result(result, "vkBindBufferMemory"); VkImageCreateInfo image_desc; @@ -377,11 +335,11 @@ VkImage vk_create_cinematic_image(int width, int height, Vk_Staging_Buffer& stag image_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; VkImage image; - result = vkCreateImage(get_device(), &image_desc, nullptr, &image); + result = vkCreateImage(vk_instance.device, &image_desc, nullptr, &image); check_vk_result(result, "vkCreateImage"); VkDeviceMemory image_memory = get_allocator()->allocate_memory(image); - result = vkBindImageMemory(get_device(), image, image_memory, 0); + result = vkBindImageMemory(vk_instance.device, image, image_memory, 0); check_vk_result(result, "vkBindImageMemory"); staging_buffer.handle = buffer; @@ -393,12 +351,12 @@ VkImage vk_create_cinematic_image(int width, int height, Vk_Staging_Buffer& stag void vk_update_cinematic_image(VkImage image, const Vk_Staging_Buffer& staging_buffer, int width, int height, const uint8_t* rgba_pixels) { void* buffer_data; - VkResult result = vkMapMemory(get_device(), staging_buffer.memory, staging_buffer.offset, staging_buffer.size, 0, &buffer_data); + VkResult result = vkMapMemory(vk_instance.device, staging_buffer.memory, staging_buffer.offset, staging_buffer.size, 0, &buffer_data); check_vk_result(result, "vkMapMemory"); memcpy(buffer_data, rgba_pixels, staging_buffer.size); - vkUnmapMemory(get_device(), staging_buffer.memory); + vkUnmapMemory(vk_instance.device, staging_buffer.memory); - record_and_run_commands(vulkan_demo->command_pool, get_queue(), + record_and_run_commands(vulkan_demo->command_pool, vk_instance.queue, [&image, &staging_buffer, &width, &height](VkCommandBuffer command_buffer) { record_image_layout_transition(command_buffer, image, VK_FORMAT_R8G8B8A8_UNORM, @@ -686,7 +644,7 @@ static VkPipeline create_pipeline(const Vk_Pipeline_Desc& desc) { create_info.basePipelineIndex = -1; VkPipeline pipeline; - VkResult result = vkCreateGraphicsPipelines(get_device(), VK_NULL_HANDLE, 1, &create_info, nullptr, &pipeline); + VkResult result = vkCreateGraphicsPipelines(vk_instance.device, VK_NULL_HANDLE, 1, &create_info, nullptr, &pipeline); check_vk_result(result, "vkCreateGraphicsPipelines"); return pipeline; } @@ -706,13 +664,13 @@ struct Timer { }; VkPipeline vk_find_pipeline(const Vk_Pipeline_Desc& desc) { - for (int i = 0; i < tr.vk_num_pipelines; i++) { - if (tr.vk_pipeline_desc[i] == desc) { - return tr.vk_pipelines[i]; + for (int i = 0; i < tr.vk.num_pipelines; i++) { + if (tr.vk.pipeline_desc[i] == desc) { + return tr.vk.pipelines[i]; } } - if (tr.vk_num_pipelines == MAX_VK_PIPELINES) { + if (tr.vk.num_pipelines == MAX_VK_PIPELINES) { ri.Error( ERR_DROP, "vk_find_pipeline: MAX_VK_PIPELINES hit\n"); } @@ -720,21 +678,27 @@ VkPipeline vk_find_pipeline(const Vk_Pipeline_Desc& desc) { VkPipeline pipeline = create_pipeline(desc); pipeline_create_time += t.Elapsed_Seconds(); - tr.vk_pipeline_desc[tr.vk_num_pipelines] = desc; - tr.vk_pipelines[tr.vk_num_pipelines] = pipeline; - tr.vk_num_pipelines++; + tr.vk.pipeline_desc[tr.vk.num_pipelines] = desc; + tr.vk.pipelines[tr.vk.num_pipelines] = pipeline; + tr.vk.num_pipelines++; return pipeline; } -void vk_destroy_pipelines() { - for (int i = 0; i < tr.vk_num_pipelines; i++) { - vkDestroyPipeline(get_device(), tr.vk_pipelines[i], nullptr); +static void vk_destroy_pipelines() { + vkDeviceWaitIdle(vk_instance.device); + + for (int i = 0; i < tr.vk.num_pipelines; i++) { + vkDestroyPipeline(vk_instance.device, tr.vk.pipelines[i], nullptr); } - tr.vk_num_pipelines = 0; + tr.vk.num_pipelines = 0; - Com_Memset(tr.vk_pipelines, 0, sizeof(tr.vk_pipelines)); - Com_Memset(tr.vk_pipeline_desc, 0, sizeof(tr.vk_pipeline_desc)); + Com_Memset(tr.vk.pipelines, 0, sizeof(tr.vk.pipelines)); + Com_Memset(tr.vk.pipeline_desc, 0, sizeof(tr.vk.pipeline_desc)); pipeline_create_time = 0.0f; } + +void vk_destroy_resources() { + vk_destroy_pipelines(); +} diff --git a/src/engine/renderer/vk.h b/src/engine/renderer/vk.h index 010b7c4..edec113 100644 --- a/src/engine/renderer/vk.h +++ b/src/engine/renderer/vk.h @@ -8,20 +8,12 @@ #include "vulkan/vulkan.h" #include -#include #include "../../game/q_shared.h" -bool initialize_vulkan(HWND hwnd); -void deinitialize_vulkan(); - -VkPhysicalDevice get_physical_device(); -VkDevice get_device(); -uint32_t get_queue_family_index(); -VkQueue get_queue(); -VkSwapchainKHR get_swapchain(); -VkFormat get_swapchain_image_format(); -const std::vector& get_swapchain_image_views(); +bool vk_initialize(HWND hwnd); +void vk_deinitialize(); +void vk_destroy_resources(); struct Vk_Staging_Buffer { VkBuffer handle = VK_NULL_HANDLE; @@ -56,7 +48,6 @@ struct Vk_Pipeline_Desc { }; VkPipeline vk_find_pipeline(const Vk_Pipeline_Desc& desc); -void vk_destroy_pipelines(); // Vertex formats struct Vk_Vertex { @@ -138,3 +129,30 @@ extern long long multi_texture_add_frag_spv_size; extern unsigned char multi_texture_mul_frag_spv[]; extern long long multi_texture_mul_frag_spv_size; + +// Vulkan specific structures used by the engine. +const int MAX_SWAPCHAIN_IMAGES = 8; + +struct Vulkan_Instance { + VkInstance instance = VK_NULL_HANDLE; + VkPhysicalDevice physical_device = VK_NULL_HANDLE; + VkSurfaceKHR surface = VK_NULL_HANDLE; + VkSurfaceFormatKHR surface_format = {}; + + uint32_t queue_family_index = 0; + VkDevice device = VK_NULL_HANDLE; + VkQueue queue = VK_NULL_HANDLE; + + VkSwapchainKHR swapchain = VK_NULL_HANDLE; + uint32_t swapchain_image_count = 0; + VkImage swapchain_images[MAX_SWAPCHAIN_IMAGES]; + VkImageView swapchain_image_views[MAX_SWAPCHAIN_IMAGES]; +}; + +const int MAX_VK_PIPELINES = 1024; + +struct Vulkan_Resources { + int num_pipelines = 0; + Vk_Pipeline_Desc pipeline_desc[MAX_VK_PIPELINES]; + VkPipeline pipelines[MAX_VK_PIPELINES]; +}; diff --git a/src/engine/renderer/vk_demo.cpp b/src/engine/renderer/vk_demo.cpp index 0092cd5..bb04101 100644 --- a/src/engine/renderer/vk_demo.cpp +++ b/src/engine/renderer/vk_demo.cpp @@ -44,8 +44,8 @@ Vulkan_Demo::Vulkan_Demo(int window_width, int window_height) , window_height(window_height) { logfile = fopen("vk_dev.log", "w"); - get_allocator()->initialize(get_physical_device(), get_device()); - get_resource_manager()->initialize(get_device()); + get_allocator()->initialize(vk_instance.physical_device, vk_instance.device); + get_resource_manager()->initialize(vk_instance.device); create_command_pool(); image_acquired = get_resource_manager()->create_semaphore(); @@ -55,7 +55,7 @@ Vulkan_Demo::Vulkan_Demo(int window_width, int window_height) fence_desc.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fence_desc.pNext = nullptr; fence_desc.flags = VK_FENCE_CREATE_SIGNALED_BIT; - VkResult result = vkCreateFence(get_device(), &fence_desc, nullptr, &rendering_finished_fence); + VkResult result = vkCreateFence(vk_instance.device, &fence_desc, nullptr, &rendering_finished_fence); check_vk_result(result, "vkCreateFence"); create_descriptor_pool(); @@ -79,20 +79,20 @@ Vulkan_Demo::Vulkan_Demo(int window_width, int window_height) alloc_info.commandPool = command_pool; alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; alloc_info.commandBufferCount = 1; - result = vkAllocateCommandBuffers(get_device(), &alloc_info, &command_buffer); + result = vkAllocateCommandBuffers(vk_instance.device, &alloc_info, &command_buffer); check_vk_result(result, "vkAllocateCommandBuffers"); } } Vulkan_Demo::~Vulkan_Demo() { - VkResult result = vkDeviceWaitIdle(get_device()); + VkResult result = vkDeviceWaitIdle(vk_instance.device); if (result < 0) std::cerr << "vkDeviceWaitIdle returned an error code: " + result; get_resource_manager()->release_resources(); get_allocator()->deallocate_all(); - deinitialize_vulkan(); + vk_deinitialize(); } void Vulkan_Demo::create_command_pool() { @@ -100,7 +100,7 @@ void Vulkan_Demo::create_command_pool() { desc.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; desc.pNext = nullptr; desc.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - desc.queueFamilyIndex = get_queue_family_index(); + desc.queueFamilyIndex = vk_instance.queue_family_index; command_pool = get_resource_manager()->create_command_pool(desc); } @@ -128,7 +128,7 @@ void Vulkan_Demo::create_uniform_buffer() { uniform_buffer = create_buffer(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); VkPhysicalDeviceProperties props; - vkGetPhysicalDeviceProperties(get_physical_device(), &props); + vkGetPhysicalDeviceProperties(vk_instance.physical_device, &props); VkDeviceSize offset_align = props.limits.minUniformBufferOffsetAlignment; tess_ubo_offset_step = (uint32_t)((sizeof(Uniform_Buffer_Object) + offset_align - 1) / offset_align * offset_align); } @@ -138,13 +138,13 @@ VkImage Vulkan_Demo::create_texture(const uint8_t* pixels, int bytes_per_pixel, 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(get_device(), staging_image, nullptr); + vkDestroyImage(vk_instance.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(command_pool, get_queue(), + record_and_run_commands(command_pool, vk_instance.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, @@ -206,11 +206,11 @@ void Vulkan_Demo::create_texture_sampler() { } void Vulkan_Demo::create_depth_buffer_resources() { - VkFormat depth_format = find_depth_format(get_physical_device()); + VkFormat depth_format = find_depth_format(vk_instance.physical_device); depth_image = create_depth_attachment_image(window_width, window_height, depth_format); depth_image_view = create_image_view(depth_image, depth_format, VK_IMAGE_ASPECT_DEPTH_BIT); - record_and_run_commands(command_pool, get_queue(), [&depth_format, this](VkCommandBuffer command_buffer) { + record_and_run_commands(command_pool, vk_instance.queue, [&depth_format, this](VkCommandBuffer command_buffer) { record_image_layout_transition(command_buffer, depth_image, depth_format, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); }); @@ -255,7 +255,7 @@ void Vulkan_Demo::create_image_descriptor_set(const image_t* image) { desc.pSetLayouts = &descriptor_set_layout; VkDescriptorSet set; - VkResult result = vkAllocateDescriptorSets(get_device(), &desc, &set); + VkResult result = vkAllocateDescriptorSets(vk_instance.device, &desc, &set); check_vk_result(result, "vkAllocateDescriptorSets"); VkDescriptorImageInfo image_info; @@ -275,7 +275,7 @@ void Vulkan_Demo::create_image_descriptor_set(const image_t* image) { descriptor_writes[0].pBufferInfo = nullptr; descriptor_writes[0].pTexelBufferView = nullptr; - vkUpdateDescriptorSets(get_device(), (uint32_t)descriptor_writes.size(), descriptor_writes.data(), 0, nullptr); + vkUpdateDescriptorSets(vk_instance.device, (uint32_t)descriptor_writes.size(), descriptor_writes.data(), 0, nullptr); update_ubo_descriptor(set); @@ -291,7 +291,7 @@ void Vulkan_Demo::create_multitexture_descriptor_set(const image_t* image, const desc.pSetLayouts = &descriptor_set_layout; VkDescriptorSet set; - VkResult result = vkAllocateDescriptorSets(get_device(), &desc, &set); + VkResult result = vkAllocateDescriptorSets(vk_instance.device, &desc, &set); check_vk_result(result, "vkAllocateDescriptorSets"); VkDescriptorImageInfo image_info[2]; @@ -326,7 +326,7 @@ void Vulkan_Demo::create_multitexture_descriptor_set(const image_t* image, const descriptor_writes[1].pBufferInfo = nullptr; descriptor_writes[1].pTexelBufferView = nullptr; - vkUpdateDescriptorSets(get_device(), (uint32_t)descriptor_writes.size(), descriptor_writes.data(), 0, nullptr); + vkUpdateDescriptorSets(vk_instance.device, (uint32_t)descriptor_writes.size(), descriptor_writes.data(), 0, nullptr); update_ubo_descriptor(set); @@ -337,7 +337,7 @@ void Vulkan_Demo::create_multitexture_descriptor_set(const image_t* image, const void Vulkan_Demo::create_render_pass() { VkAttachmentDescription color_attachment; color_attachment.flags = 0; - color_attachment.format = get_swapchain_image_format(); + color_attachment.format = vk_instance.surface_format.format; color_attachment.samples = VK_SAMPLE_COUNT_1_BIT; color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; @@ -348,7 +348,7 @@ void Vulkan_Demo::create_render_pass() { VkAttachmentDescription depth_attachment; depth_attachment.flags = 0; - depth_attachment.format = find_depth_format(get_physical_device()); + depth_attachment.format = find_depth_format(vk_instance.physical_device); depth_attachment.samples = VK_SAMPLE_COUNT_1_BIT; depth_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; depth_attachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; @@ -406,10 +406,9 @@ void Vulkan_Demo::create_framebuffers() { desc.height = window_height; desc.layers = 1; - const auto& swapchain_image_views = get_swapchain_image_views(); - framebuffers.resize(swapchain_image_views.size()); + framebuffers.resize(vk_instance.swapchain_image_count); for (std::size_t i = 0; i < framebuffers.size(); i++) { - attachments[0] = swapchain_image_views[i]; // set color attachment + attachments[0] = vk_instance.swapchain_image_views[i]; // set color attachment framebuffers[i] = get_resource_manager()->create_framebuffer(desc); } } @@ -442,7 +441,7 @@ void Vulkan_Demo::upload_geometry() { tess_vertex_buffer = get_resource_manager()->create_buffer(desc); tess_vertex_buffer_memory = get_allocator()->allocate_staging_memory(tess_vertex_buffer); - VkResult result = vkBindBufferMemory(get_device(), tess_vertex_buffer, tess_vertex_buffer_memory, 0); + VkResult result = vkBindBufferMemory(vk_instance.device, tess_vertex_buffer, tess_vertex_buffer_memory, 0); check_vk_result(result, "vkBindBufferMemory"); } @@ -459,7 +458,7 @@ void Vulkan_Demo::upload_geometry() { tess_index_buffer = get_resource_manager()->create_buffer(desc); tess_index_buffer_memory = get_allocator()->allocate_staging_memory(tess_index_buffer); - VkResult result = vkBindBufferMemory(get_device(), tess_index_buffer, tess_index_buffer_memory, 0); + VkResult result = vkBindBufferMemory(vk_instance.device, tess_index_buffer, tess_index_buffer_memory, 0); check_vk_result(result, "vkBindBufferMemory"); } } @@ -482,7 +481,7 @@ void Vulkan_Demo::update_ubo_descriptor(VkDescriptorSet set) { descriptor_writes[0].pBufferInfo = &buffer_info; descriptor_writes[0].pTexelBufferView = nullptr; - vkUpdateDescriptorSets(get_device(), (uint32_t)descriptor_writes.size(), descriptor_writes.data(), 0, nullptr); + vkUpdateDescriptorSets(vk_instance.device, (uint32_t)descriptor_writes.size(), descriptor_writes.data(), 0, nullptr); } void Vulkan_Demo::update_uniform_buffer() { @@ -519,10 +518,10 @@ void Vulkan_Demo::update_uniform_buffer() { } void* data; - VkResult result = vkMapMemory(get_device(), uniform_staging_buffer_memory, tess_ubo_offset, sizeof(ubo), 0, &data); + VkResult result = vkMapMemory(vk_instance.device, uniform_staging_buffer_memory, tess_ubo_offset, sizeof(ubo), 0, &data); check_vk_result(result, "vkMapMemory"); memcpy(data, &ubo, sizeof(ubo)); - vkUnmapMemory(get_device(), uniform_staging_buffer_memory); + vkUnmapMemory(vk_instance.device, uniform_staging_buffer_memory); } void Vulkan_Demo::begin_frame() { @@ -581,7 +580,7 @@ void Vulkan_Demo::render_tess(const shaderStage_t* stage) { fflush(logfile); void* data; - VkResult result = vkMapMemory(get_device(), tess_vertex_buffer_memory, tess_vertex_buffer_offset, tess.numVertexes * sizeof(Vk_Vertex), 0, &data); + VkResult result = vkMapMemory(vk_instance.device, tess_vertex_buffer_memory, tess_vertex_buffer_offset, tess.numVertexes * sizeof(Vk_Vertex), 0, &data); check_vk_result(result, "vkMapMemory"); Vk_Vertex* v = (Vk_Vertex*)data; for (int i = 0; i < tess.numVertexes; i++, v++) { @@ -595,15 +594,15 @@ void Vulkan_Demo::render_tess(const shaderStage_t* stage) { v->st[0] = tess.svars.texcoords[0][i][0]; v->st[1] = tess.svars.texcoords[0][i][1]; } - vkUnmapMemory(get_device(), tess_vertex_buffer_memory); + vkUnmapMemory(vk_instance.device, tess_vertex_buffer_memory); - result = vkMapMemory(get_device(), tess_index_buffer_memory, tess_index_buffer_offset, tess.numIndexes * sizeof(uint32_t), 0, &data); + result = vkMapMemory(vk_instance.device, tess_index_buffer_memory, tess_index_buffer_offset, tess.numIndexes * sizeof(uint32_t), 0, &data); check_vk_result(result, "vkMapMemory"); uint32_t* ind = (uint32_t*)data; for (int i = 0; i < tess.numIndexes; i++, ind++) { *ind = tess.indexes[i]; } - vkUnmapMemory(get_device(), tess_index_buffer_memory); + vkUnmapMemory(vk_instance.device, tess_index_buffer_memory); const VkDeviceSize offset = 0; vkCmdBindVertexBuffers(command_buffer, 0, 1, &tess_vertex_buffer, &tess_vertex_buffer_offset); @@ -660,7 +659,7 @@ void Vulkan_Demo::render_tess_multi(const shaderStage_t* stage) { fflush(logfile); void* data; - VkResult result = vkMapMemory(get_device(), tess_vertex_buffer_memory, tess_vertex_buffer_offset, tess.numVertexes * sizeof(Vk_Vertex2), 0, &data); + VkResult result = vkMapMemory(vk_instance.device, tess_vertex_buffer_memory, tess_vertex_buffer_offset, tess.numVertexes * sizeof(Vk_Vertex2), 0, &data); check_vk_result(result, "vkMapMemory"); Vk_Vertex2* v = (Vk_Vertex2*)data; for (int i = 0; i < tess.numVertexes; i++, v++) { @@ -676,15 +675,15 @@ void Vulkan_Demo::render_tess_multi(const shaderStage_t* stage) { v->st2[0] = tess.svars.texcoords[1][i][0]; v->st2[1] = tess.svars.texcoords[1][i][1]; } - vkUnmapMemory(get_device(), tess_vertex_buffer_memory); + vkUnmapMemory(vk_instance.device, tess_vertex_buffer_memory); - result = vkMapMemory(get_device(), tess_index_buffer_memory, tess_index_buffer_offset, tess.numIndexes * sizeof(uint32_t), 0, &data); + result = vkMapMemory(vk_instance.device, tess_index_buffer_memory, tess_index_buffer_offset, tess.numIndexes * sizeof(uint32_t), 0, &data); check_vk_result(result, "vkMapMemory"); uint32_t* ind = (uint32_t*)data; for (int i = 0; i < tess.numIndexes; i++, ind++) { *ind = tess.indexes[i]; } - vkUnmapMemory(get_device(), tess_index_buffer_memory); + vkUnmapMemory(vk_instance.device, tess_index_buffer_memory); const VkDeviceSize offset = 0; vkCmdBindVertexBuffers(command_buffer, 0, 1, &tess_vertex_buffer, &tess_vertex_buffer_offset); diff --git a/src/engine/renderer/vk_utils.cpp b/src/engine/renderer/vk_utils.cpp index 3983a9e..23b833b 100644 --- a/src/engine/renderer/vk_utils.cpp +++ b/src/engine/renderer/vk_utils.cpp @@ -5,6 +5,8 @@ #include #include +#include "tr_local.h" + void check_vk_result(VkResult result, const std::string& functionName) { if (result < 0) { error(functionName + " has returned error code with value " + std::to_string(result)); @@ -28,12 +30,12 @@ Shader_Module::Shader_Module(uint8_t bytes[], int size) { desc.codeSize = data.size(); desc.pCode = reinterpret_cast(data.data()); - VkResult result = vkCreateShaderModule(get_device(), &desc, nullptr, &handle); + VkResult result = vkCreateShaderModule(vk_instance.device, &desc, nullptr, &handle); check_vk_result(result, "vkCreateShaderModule"); } Shader_Module::~Shader_Module() { - vkDestroyShaderModule(get_device(), handle, nullptr); + vkDestroyShaderModule(vk_instance.device, handle, nullptr); } void record_and_run_commands(VkCommandPool command_pool, VkQueue queue, std::function recorder) { @@ -46,7 +48,7 @@ void record_and_run_commands(VkCommandPool command_pool, VkQueue queue, std::fun alloc_info.commandBufferCount = 1; VkCommandBuffer command_buffer; - VkResult result = vkAllocateCommandBuffers(get_device(), &alloc_info, &command_buffer); + VkResult result = vkAllocateCommandBuffers(vk_instance.device, &alloc_info, &command_buffer); check_vk_result(result, "vkAllocateCommandBuffers"); VkCommandBufferBeginInfo begin_info; @@ -76,7 +78,7 @@ void record_and_run_commands(VkCommandPool command_pool, VkQueue queue, std::fun check_vk_result(result, "vkQueueSubmit"); result = vkQueueWaitIdle(queue); check_vk_result(result, "vkQueueWaitIdle"); - vkFreeCommandBuffers(get_device(), command_pool, 1, &command_buffer); + vkFreeCommandBuffers(vk_instance.device, command_pool, 1, &command_buffer); } static bool has_depth_component(VkFormat format) { @@ -162,7 +164,7 @@ VkImage create_texture(int image_width, int image_height, VkFormat format) { VkImage image = get_resource_manager()->create_image(desc); VkDeviceMemory memory = get_allocator()->allocate_memory(image); - VkResult result = vkBindImageMemory(get_device(), image, memory, 0); + VkResult result = vkBindImageMemory(vk_instance.device, image, memory, 0); check_vk_result(result, "vkBindImageMemory"); return image; } @@ -188,12 +190,12 @@ VkImage create_staging_texture(int image_width, int image_height, VkFormat forma desc.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; VkImage image; - VkResult result = vkCreateImage(get_device(), &desc, nullptr, &image); + VkResult result = vkCreateImage(vk_instance.device, &desc, nullptr, &image); check_vk_result(result, "vkCreateImage"); get_allocator()->get_shared_staging_memory().ensure_allocation_for_object(image); VkDeviceMemory memory = get_allocator()->get_shared_staging_memory().get_handle(); - result = vkBindImageMemory(get_device(), image, memory, 0); + result = vkBindImageMemory(vk_instance.device, image, memory, 0); check_vk_result(result, "vkBindImageMemory"); VkImageSubresource staging_image_subresource; @@ -201,10 +203,10 @@ VkImage create_staging_texture(int image_width, int image_height, VkFormat forma staging_image_subresource.mipLevel = 0; staging_image_subresource.arrayLayer = 0; VkSubresourceLayout staging_image_layout; - vkGetImageSubresourceLayout(get_device(), image, &staging_image_subresource, &staging_image_layout); + vkGetImageSubresourceLayout(vk_instance.device, image, &staging_image_subresource, &staging_image_layout); void* data; - result = vkMapMemory(get_device(), memory, 0, staging_image_layout.size, 0, &data); + result = vkMapMemory(vk_instance.device, memory, 0, staging_image_layout.size, 0, &data); check_vk_result(result, "vkMapMemory"); const int bytes_per_row = image_width * bytes_per_pixel; @@ -216,7 +218,7 @@ VkImage create_staging_texture(int image_width, int image_height, VkFormat forma memcpy(&bytes[i * staging_image_layout.rowPitch], &pixels[i * bytes_per_row], bytes_per_row); } } - vkUnmapMemory(get_device(), memory); + vkUnmapMemory(vk_instance.device, memory); return image; } @@ -243,7 +245,7 @@ VkImage create_depth_attachment_image(int image_width, int image_height, VkForma VkImage image = get_resource_manager()->create_image(desc); VkDeviceMemory memory = get_allocator()->allocate_memory(image); - VkResult result = vkBindImageMemory(get_device(), image, memory, 0); + VkResult result = vkBindImageMemory(vk_instance.device, image, memory, 0); check_vk_result(result, "vkBindImageMemory"); return image; } @@ -283,7 +285,7 @@ VkBuffer create_buffer(VkDeviceSize size, VkBufferUsageFlags usage) { VkBuffer buffer = get_resource_manager()->create_buffer(desc); VkDeviceMemory memory = get_allocator()->allocate_memory(buffer); - VkResult result = vkBindBufferMemory(get_device(), buffer, memory, 0); + VkResult result = vkBindBufferMemory(vk_instance.device, buffer, memory, 0); check_vk_result(result, "vkBindBufferMemory"); return buffer; } @@ -300,19 +302,19 @@ VkBuffer create_staging_buffer(VkDeviceSize size, const void* data) { desc.pQueueFamilyIndices = nullptr; VkBuffer buffer; - VkResult result = vkCreateBuffer(get_device(), &desc, nullptr, &buffer); + VkResult result = vkCreateBuffer(vk_instance.device, &desc, nullptr, &buffer); check_vk_result(result, "vkCreateBuffer"); get_allocator()->get_shared_staging_memory().ensure_allocation_for_object(buffer); VkDeviceMemory memory = get_allocator()->get_shared_staging_memory().get_handle(); - result = vkBindBufferMemory(get_device(), buffer, memory, 0); + result = vkBindBufferMemory(vk_instance.device, buffer, memory, 0); check_vk_result(result, "vkBindBufferMemory"); void* buffer_data; - result = vkMapMemory(get_device(), memory, 0, size, 0, &buffer_data); + result = vkMapMemory(vk_instance.device, memory, 0, size, 0, &buffer_data); check_vk_result(result, "vkMapMemory"); memcpy(buffer_data, data, size); - vkUnmapMemory(get_device(), memory); + vkUnmapMemory(vk_instance.device, memory); return buffer; } @@ -330,7 +332,7 @@ VkBuffer create_permanent_staging_buffer(VkDeviceSize size, VkDeviceMemory& memo VkBuffer buffer = get_resource_manager()->create_buffer(desc); memory = get_allocator()->allocate_staging_memory(buffer); - VkResult result = vkBindBufferMemory(get_device(), buffer, memory, 0); + VkResult result = vkBindBufferMemory(vk_instance.device, buffer, memory, 0); check_vk_result(result, "vkBindBufferMemory"); return buffer; }