diff options
Diffstat (limited to 'src/vk/graphics_pipeline_2d.cpp')
-rw-r--r-- | src/vk/graphics_pipeline_2d.cpp | 226 |
1 files changed, 45 insertions, 181 deletions
diff --git a/src/vk/graphics_pipeline_2d.cpp b/src/vk/graphics_pipeline_2d.cpp index 61cfe3f..08bdb6e 100644 --- a/src/vk/graphics_pipeline_2d.cpp +++ b/src/vk/graphics_pipeline_2d.cpp @@ -25,123 +25,6 @@ namespace { void -load_projection_uniform_buffer(void *obj) -{ - auto self = static_cast<VK::GraphicsPipeline2D*>(obj); - - try - { - self->ub_projection.reserve(cg_core.vk_swapchain->images_count); - for(auto i{0}; i < cg_core.vk_swapchain->images_count; i++) - self->ub_projection.emplace_back( - cg_core.vk_device_with_swapchain, sizeof(VK::UBOProjection)); - } - catch(const std::exception& e) - { - throw CommandError{e.what()}; - } -} - -void -unload_projection_uniform_buffer(void *obj) -{ - auto self = static_cast<VK::GraphicsPipeline2D*>(obj); - - self->ub_projection.clear(); -} - -void -load_descriptor_pool(void *obj) -{ - auto self = static_cast<VK::GraphicsPipeline2D*>(obj); - - VkDescriptorPoolSize descriptor_pool_size{}; - descriptor_pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - descriptor_pool_size.descriptorCount = self->ub_projection.size(); - - VkDescriptorPoolCreateInfo pool_info{}; - pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - pool_info.pNext = nullptr; - pool_info.flags = 0; - pool_info.maxSets = self->ub_projection.size(); - pool_info.poolSizeCount = 1; - pool_info.pPoolSizes = &descriptor_pool_size; - - if(vkCreateDescriptorPool( - cg_core.vk_device_with_swapchain->device, &pool_info, nullptr, - &self->descriptor_pool) != VK_SUCCESS) - throw CommandError{"Failed to create a Vulkan descriptor pool."}; -} - -void -unload_descriptor_pool(void *obj) -{ - auto self = static_cast<VK::GraphicsPipeline2D*>(obj); - - vkDestroyDescriptorPool( - cg_core.vk_device_with_swapchain->device, self->descriptor_pool, - nullptr); -} - -void -load_projection_descriptor_sets(void *obj) -{ - auto self = static_cast<VK::GraphicsPipeline2D*>(obj); - - std::vector<VkDescriptorSetLayout> layouts( - self->ub_projection.size(), - cg_core.vk_graphics_pipeline_2d_layout->descriptor_set_projection); - - VkDescriptorSetAllocateInfo alloc_info{}; - alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - alloc_info.descriptorPool = self->descriptor_pool; - alloc_info.descriptorSetCount = layouts.size(); - alloc_info.pSetLayouts = layouts.data(); - - self->projection_descriptor_sets.resize(layouts.size()); - if(vkAllocateDescriptorSets( - cg_core.vk_device_with_swapchain->device, &alloc_info, - self->projection_descriptor_sets.data()) != VK_SUCCESS) - throw CommandError{"Failed to create Vulkan projection descriptor sets."}; -} - -void -load_resources_to_descriptor_sets(void *obj) -{ - auto self = static_cast<VK::GraphicsPipeline2D*>(obj); - - for(auto i{0}; i < self->ub_projection.size(); i++) - { - VkDescriptorBufferInfo projection_info{}; - projection_info.buffer = self->ub_projection[i].buffer; - projection_info.offset = 0; - projection_info.range = sizeof(VK::UBOProjection); - - std::array<VkWriteDescriptorSet, 1> write_descriptors{}; - write_descriptors[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_descriptors[0].dstSet = self->projection_descriptor_sets[i]; - write_descriptors[0].dstBinding = 0; - write_descriptors[0].dstArrayElement = 0; - write_descriptors[0].descriptorCount = 1; - write_descriptors[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - write_descriptors[0].pBufferInfo = &projection_info; - write_descriptors[0].pImageInfo = nullptr; - write_descriptors[0].pTexelBufferView = nullptr; - - vkUpdateDescriptorSets( - cg_core.vk_device_with_swapchain->device, write_descriptors.size(), - write_descriptors.data(), 0, nullptr); - - VK::UBOProjection ubo_projection; - ubo_projection.proj = glm::ortho( - 0.0f, static_cast<float>(cg_core.game_width), - 0.0f, static_cast<float>(cg_core.game_height), - 0.0f, 100.0f); - self->ub_projection[i].copy_data(&ubo_projection); - } -} - -void load_framebuffer(void *obj) { auto self = static_cast<VK::GraphicsPipeline2D*>(obj); @@ -245,10 +128,10 @@ load_pipeline(void *obj) input_assembly.primitiveRestartEnable = VK_FALSE; VkViewport viewport = {}; - viewport.x = 0.0f; - viewport.y = 0.0f; - viewport.width = static_cast<float>(cg_core.screen_width); - viewport.height = static_cast<float>(cg_core.screen_height); + viewport.x = 0; + viewport.y = 0; + viewport.width = cg_core.screen_width; + viewport.height = cg_core.screen_height; viewport.minDepth = 0.0f; viewport.maxDepth = 1.0f; @@ -368,11 +251,6 @@ unload_pipeline(void *obj) } const CommandChain loader{ - {&load_projection_uniform_buffer, &unload_projection_uniform_buffer}, - {&load_descriptor_pool, &unload_descriptor_pool}, - // By destroying the pool the sets are also destroyed. - {&load_projection_descriptor_sets, nullptr}, - {&load_resources_to_descriptor_sets, nullptr}, {&load_framebuffer, &unload_framebuffer}, {&load_pipeline, &unload_pipeline} }; @@ -382,8 +260,7 @@ const CommandChain loader{ namespace VK { -GraphicsPipeline2D::GraphicsPipeline2D(): - sprites_to_draw{cg_core.vk_swapchain->images_count} +GraphicsPipeline2D::GraphicsPipeline2D() { loader.execute(this); } @@ -395,74 +272,61 @@ GraphicsPipeline2D::~GraphicsPipeline2D() void GraphicsPipeline2D::draw( - const VkCommandBuffer draw_command_buffer, const size_t current_frame, - const size_t next_frame, const uint32_t image_index) + std::shared_ptr<View> view, const VkCommandBuffer draw_command_buffer, + const size_t current_frame, const size_t next_frame, + const uint32_t image_index) { - // Load command + // Set viewport { - VkRenderPassBeginInfo render_pass_begin{}; - render_pass_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - render_pass_begin.pNext = nullptr; - render_pass_begin.renderPass = - cg_core.vk_graphics_pipeline_2d_layout->render_pass; - render_pass_begin.framebuffer = this->swapchain_framebuffers[image_index]; - render_pass_begin.renderArea.offset = {0, 0}; - render_pass_begin.renderArea.extent = { - cg_core.screen_width, cg_core.screen_height}; - render_pass_begin.clearValueCount = 0; - render_pass_begin.pClearValues = nullptr; - - vkCmdBeginRenderPass( - draw_command_buffer, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE); - VkViewport vk_viewport{}; - vk_viewport.width = static_cast<float>(cg_core.screen_width); - vk_viewport.height = static_cast<float>(cg_core.screen_height); + vk_viewport.x = view->region.x; + vk_viewport.y = view->region.y; + vk_viewport.width = view->region.z; + vk_viewport.height = view->region.w; vk_viewport.minDepth = 0.0f; vk_viewport.maxDepth = 1.0f; vkCmdSetViewport(draw_command_buffer, 0, 1, &vk_viewport); VkRect2D vk_scissor{}; - vk_scissor.extent.width = cg_core.screen_width; - vk_scissor.extent.height = cg_core.screen_height; - vk_scissor.offset.x = 0; - vk_scissor.offset.y = 0; + vk_scissor.offset.x = static_cast<int32_t>(view->region.x); + vk_scissor.offset.y = static_cast<int32_t>(view->region.y); + vk_scissor.extent.width = static_cast<uint32_t>(view->region.z); + vk_scissor.extent.height = static_cast<uint32_t>(view->region.w); vkCmdSetScissor(draw_command_buffer, 0, 1, &vk_scissor); + } - // Draw sprites - for(auto& [sprite, positions]: this->sprites_to_draw[current_frame]) + // Draw sprites + for(auto& [sprite, positions]: view->sprites_to_draw[current_frame]) + { + // Commands { - // Commands - { - std::array<VkDescriptorSet, 2> vk_descriptor_sets{ - this->projection_descriptor_sets[image_index], - sprite->descriptor_sets[image_index]}; - VkDeviceSize offsets[]{0}; - - vkCmdBindDescriptorSets( - draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - cg_core.vk_graphics_pipeline_2d_layout->pipeline, 0, - vk_descriptor_sets.size(), vk_descriptor_sets.data(), 0, nullptr); - vkCmdBindPipeline( - draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - this->graphic_pipeline); - vkCmdBindVertexBuffers( - draw_command_buffer, 0, 1, &sprite->vertex_buffer->buffer, offsets); - vkCmdDraw( - draw_command_buffer, Sprite::vertex_count, positions.size(), 0, 0); - } - - VK::UBOSpritePositions ubo_sprite_positions; - for(auto i{0}; i < positions.size(); i++) - ubo_sprite_positions.positions[i] = positions[i]; - sprite->ub_sprite_positions[image_index].copy_data( - &ubo_sprite_positions); + std::array<VkDescriptorSet, 2> vk_descriptor_sets{ + view->descriptor_sets_2d[image_index], + sprite->descriptor_sets[image_index]}; + VkDeviceSize offsets[]{0}; + + vkCmdBindDescriptorSets( + draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + cg_core.vk_graphics_pipeline_2d_layout->pipeline, 0, + vk_descriptor_sets.size(), vk_descriptor_sets.data(), 0, nullptr); + vkCmdBindPipeline( + draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + this->graphic_pipeline); + vkCmdBindVertexBuffers( + draw_command_buffer, 0, 1, &sprite->vertex_buffer->buffer, offsets); + vkCmdDraw( + draw_command_buffer, Sprite::vertex_count, positions.size(), 0, 0); } + + VK::UBOSpritePositions ubo_sprite_positions; + for(auto i{0}; i < positions.size(); i++) + ubo_sprite_positions.positions[i] = positions[i]; + sprite->ub_sprite_positions[image_index].copy_data( + &ubo_sprite_positions); } - vkCmdEndRenderPass(draw_command_buffer); // Prepare for the next frame. - this->sprites_to_draw[next_frame].clear(); + view->sprites_to_draw[next_frame].clear(); } } |