From bdd35fc2af40496b4cff9121ea5a3a364259642d Mon Sep 17 00:00:00 2001 From: Quentin LADEVIE Date: Thu, 3 Mar 2022 17:49:03 +0100 Subject: Primitive renderpass api & use handle for low level api resources --- include/compute-renderpass.hpp | 10 ++++- include/material.hpp | 2 +- include/primitive-renderpass.hpp | 97 ++++++++++++++++++++++++++++++++++++++++ include/renderpass.hpp | 12 ++--- include/vk-api.hpp | 71 +++++++++++++++++------------ include/vk-renderer.hpp | 65 +++++++++++---------------- 6 files changed, 178 insertions(+), 79 deletions(-) create mode 100644 include/primitive-renderpass.hpp (limited to 'include') diff --git a/include/compute-renderpass.hpp b/include/compute-renderpass.hpp index a581930..641d4b1 100644 --- a/include/compute-renderpass.hpp +++ b/include/compute-renderpass.hpp @@ -14,8 +14,12 @@ class ComputeRenderpass : public Renderpass { : Renderpass(api) {} + ~ComputeRenderpass() { + api.destroy_pipeline(pipeline); + } - void set_pipeline(std::string& shader_name) override final; + + void set_pipeline(std::string& shader_name); void set_dispatch_size(size_t count_x, size_t count_y, size_t count_z); @@ -26,7 +30,7 @@ class ComputeRenderpass : public Renderpass { void set_constant(off_t offset, Buffer* buffer); // TODO: Do not use vulkan api type - void execute(VkCommandBuffer command_buffer) override final; + void execute(vkrenderer& renderer, VkCommandBuffer command_buffer) override final; Texture* output_texture; @@ -39,4 +43,6 @@ class ComputeRenderpass : public Renderpass { size_t group_count_x; size_t group_count_y; size_t group_count_z; + + pipeline pipeline; }; diff --git a/include/material.hpp b/include/material.hpp index 0336fb5..780e68d 100644 --- a/include/material.hpp +++ b/include/material.hpp @@ -13,7 +13,7 @@ struct material { color base_color; texture base_color_texture; texture metallic_roughness_texture; - float metalness = 0.f; + float metalness = 1.f; float roughness = 1.f; }; diff --git a/include/primitive-renderpass.hpp b/include/primitive-renderpass.hpp new file mode 100644 index 0000000..45b43e9 --- /dev/null +++ b/include/primitive-renderpass.hpp @@ -0,0 +1,97 @@ +#pragma once + +#include +#include +#include + +#include "vk-renderer.hpp" +#include "renderpass.hpp" + +class Buffer; +class Texture; +class Sampler; +class Primitive; + +class PrimitiveRenderpass : public Renderpass { + public: + + PrimitiveRenderpass(vkapi& api); + + void add_primitive(Primitive* new_primitive); + + void add_color_attachment(VkFormat format); + + void set_depth_stencil(Texture* depth_stencil); + + void set_viewport(float x, float y, float width, float height); + + void set_color_attachment(uint32_t index, Texture* attachment); + + void finalize_render_pass(); + + void execute(vkrenderer& renderer, VkCommandBuffer command_buffer) override final; + + VkRenderPass render_pass = VK_NULL_HANDLE; + + private: + + void create_framebuffers(); + + void recreate_framebuffers(); + + VkViewport viewport = { .minDepth = 0.f, .maxDepth = 1.f }; + + std::vector color_attachments; + std::vector color_attachments_view; + std::vector color_attachments_format; + + std::array framebuffers; + + std::vector primitives; +}; + + +class Primitive { + public: + + Primitive(vkapi& api, PrimitiveRenderpass& render_pass) + : api(api), primitive_render_pass(render_pass) + {}; + + void set_pipeline(std::string& shader_name); + + void set_constant_offset(off_t offset); + void set_constant(off_t offset, uint64_t* constant); + void set_constant(off_t offset, Texture* texture); + void set_constant(off_t offset, Buffer* buffer); + void set_constant(off_t offset, Sampler* sampler); + + void set_index_buffer(Buffer* index_buffer); + + void set_scissor(int32_t x, int32_t y, uint32_t width, uint32_t height); + + void set_draw_info(size_t vertex_count, off_t first_vertex, off_t vertex_offset); + + void render(VkCommandBuffer command_buffer); + + +private: + + vkapi& api; + + PrimitiveRenderpass& primitive_render_pass; + + pipeline pipeline; + + Buffer* index_buffer; + + size_t element_count; + off_t first_vertex; + off_t vertex_offset; + + off_t constant_offset; + + VkRect2D scissor = {}; + + std::array constants; +}; diff --git a/include/renderpass.hpp b/include/renderpass.hpp index 64947b6..a444c64 100644 --- a/include/renderpass.hpp +++ b/include/renderpass.hpp @@ -2,7 +2,7 @@ #include -#include "vk-api.hpp" +#include "vk-renderer.hpp" class Renderpass { public: @@ -11,17 +11,11 @@ class Renderpass { :api(api) {}; - virtual ~Renderpass() { - api.destroy_pipeline(pipeline); - } - - virtual void set_pipeline(std::string& shader_name) = 0; + virtual ~Renderpass() {}; // TODO: Do not use vulkan api type - virtual void execute(VkCommandBuffer command_buffer) = 0; + virtual void execute(vkrenderer& renderer, VkCommandBuffer command_buffer) = 0; protected: vkapi &api; - - pipeline pipeline; }; diff --git a/include/vk-api.hpp b/include/vk-api.hpp index 1b9f51f..0f1431a 100644 --- a/include/vk-api.hpp +++ b/include/vk-api.hpp @@ -1,6 +1,7 @@ #ifndef __VK_API_HPP_ #define __VK_API_HPP_ +#include #include #include #include @@ -22,6 +23,7 @@ struct pipeline { }; using bindless_index = uint32_t; +using handle = uint32_t; struct image { VkImage handle; @@ -31,6 +33,7 @@ struct image { VkImageSubresourceRange subresource_range; VkFormat format; VkExtent3D size; + VkImageUsageFlags usages; bindless_index bindless_storage_index; bindless_index bindless_sampled_index; @@ -40,13 +43,18 @@ struct image { }; struct swapchain { - size_t image_count; - std::vector images; + uint32_t image_count; + std::vector images; VkSwapchainKHR handle; VkSurfaceFormatKHR surface_format; VkExtent2D extent; }; +struct framebuffer { + VkFramebuffer handle; + VkExtent2D size; +}; + struct sampler { VkSampler handle; bindless_index bindless_index; @@ -101,16 +109,16 @@ class vkapi { vkapi(); ~vkapi(); - buffer create_buffer(size_t data_size, VkBufferUsageFlags buffer_usage, VmaMemoryUsage mem_usage); - void copy_buffer(VkCommandBuffer cmd_buf, buffer src, buffer dst, size_t size); - void copy_buffer(VkCommandBuffer cmd_buf, buffer src, image dst); - void destroy_buffer(buffer& buffer); + handle create_buffer(size_t data_size, VkBufferUsageFlags buffer_usage, VmaMemoryUsage mem_usage); + void copy_buffer(VkCommandBuffer cmd_buf, handle src, handle dst, size_t size); + void copy_buffer(VkCommandBuffer cmd_buf, handle src, handle dst); + void destroy_buffer(handle buffer); - image create_image(VkExtent3D size, VkFormat format, VkImageUsageFlags usages); - void destroy_image(image &image); - std::vector create_images(VkExtent3D size, VkFormat format, VkImageUsageFlags usages, size_t image_count); - void destroy_images(std::vector &images); + handle create_image(VkExtent3D size, VkFormat format, VkImageUsageFlags usages); + void destroy_image(handle image); + std::vector create_images(VkExtent3D size, VkFormat format, VkImageUsageFlags usages, size_t image_count); + void destroy_images(std::vector& images); VkFence create_fence(); @@ -124,8 +132,8 @@ class vkapi { std::vector create_semaphores(size_t semaphores_count); void destroy_semaphores(std::vector &semaphores); - sampler create_sampler(VkFilter filter, VkSamplerAddressMode address_mode); - void destroy_sampler(sampler sampler); + handle create_sampler(VkFilter filter, VkSamplerAddressMode address_mode); + void destroy_sampler(handle sampler); std::vector create_command_buffers(size_t command_buffers_count); @@ -137,10 +145,10 @@ class vkapi { void destroy_render_pass(VkRenderPass render_pass); - VkFramebuffer create_framebuffer(VkRenderPass render_pass, std::vector& images, VkExtent2D size); - std::vector create_framebuffers(VkRenderPass render_pass, std::vector& images, VkExtent2D size, uint32_t framebuffer_count); - void destroy_framebuffer(VkFramebuffer framebuffer); - void destroy_framebuffers(std::vector& framebuffers); + framebuffer create_framebuffer(VkRenderPass render_pass, std::vector& formats, VkExtent2D size); + std::vector create_framebuffers(VkRenderPass render_pass, std::vector& formats, VkExtent2D size, uint32_t framebuffer_count); + void destroy_framebuffer(framebuffer framebuffer); + void destroy_framebuffers(std::vector& framebuffers); pipeline create_compute_pipeline(const char* shader_name); @@ -159,27 +167,27 @@ class vkapi { swapchain create_swapchain(VkSurfaceKHR surface, size_t min_image_count, VkImageUsageFlags usages, VkSwapchainKHR old_swapchain); void destroy_swapchain(swapchain& swapchain); - void update_descriptor_image(image &img, VkDescriptorType type); - void update_descriptor_images(std::vector &images, VkDescriptorType type); - void update_descriptor_sampler(sampler &sampler); - void update_descriptor_samplers(std::vector &samplers); + void update_descriptor_image(handle img, VkDescriptorType type); + void update_descriptor_images(std::vector &images, VkDescriptorType type); + void update_descriptor_sampler(handle sampler); + void update_descriptor_samplers(std::vector &samplers); void update_constants(VkCommandBuffer command_buffer, VkShaderStageFlagBits shader_stage, off_t offset, size_t size, void* data); void start_record(VkCommandBuffer command_buffer); - void image_barrier(VkCommandBuffer command_buffer, VkImageLayout dst_layout, VkPipelineStageFlagBits dst_stage, VkAccessFlags dst_access, image& image); + void image_barrier(VkCommandBuffer command_buffer, VkImageLayout dst_layout, VkPipelineStageFlagBits dst_stage, VkAccessFlags dst_access, handle image); - void begin_render_pass(VkCommandBuffer command_buffer, VkRenderPass render_pass, VkFramebuffer framebuffer, VkExtent2D size, pipeline& pipeline); + void begin_render_pass(VkCommandBuffer command_buffer, VkRenderPass render_pass, std::vector& attachments, framebuffer framebuffer, VkExtent2D size); void end_render_pass(VkCommandBuffer command_buffer); void run_compute_pipeline(VkCommandBuffer command_buffer, pipeline& pipeline, size_t group_count_x, size_t group_count_y, size_t group_count_z); void draw(VkCommandBuffer command_buffer, pipeline& pipeline, uint32_t vertex_count, uint32_t vertex_offset); - void draw(VkCommandBuffer command_buffer, pipeline& pipeline, buffer& index_buffer, uint32_t primitive_count, uint32_t indices_offset, uint32_t vertices_offset); + void draw(VkCommandBuffer command_buffer, pipeline& pipeline, handle index_buffer, uint32_t primitive_count, uint32_t indices_offset, uint32_t vertices_offset); - void blit_full(VkCommandBuffer command_buffer, image& src_image, image& dst_image); + void blit_full(VkCommandBuffer command_buffer, handle src_image, handle dst_image); void end_record(VkCommandBuffer command_buffer); @@ -187,6 +195,10 @@ class vkapi { VkResult present(swapchain& swapchain, uint32_t image_index, VkSemaphore wait_semaphore); + const buffer& get_buffer(handle buffer_handle) { return *buffers[buffer_handle]; }; + const image& get_image(handle image_handle) { return *images[image_handle]; }; + const sampler& get_sampler(handle sampler_handle) { return *samplers[sampler_handle]; }; + vkcontext context; private: @@ -195,12 +207,13 @@ class vkapi { const char* shader_stage_extension(VkShaderStageFlags shader_stage); - std::map buffers; - std::map images; - std::mapsamplers; + // TODO: Use freelists instead + std::vector buffers; + std::vector images; + std::vector samplers; - VkCommandPool command_pool; - VkDescriptorPool descriptor_pool; + VkCommandPool command_pool; + VkDescriptorPool descriptor_pool; }; diff --git a/include/vk-renderer.hpp b/include/vk-renderer.hpp index 76dfffc..864bc48 100644 --- a/include/vk-renderer.hpp +++ b/include/vk-renderer.hpp @@ -2,14 +2,16 @@ #define __VK_RENDERER_HPP_ #include +#include #include #include "vk-api.hpp" -#include "vulkan/vulkan_core.h" class Renderpass; class ComputeRenderpass; +class PrimitiveRenderpass; +class Primitive; class window; class Texture; @@ -24,67 +26,67 @@ class vkrenderer { void begin_frame(); - void ui(); - void compute(uint32_t width, uint32_t height); void finish_frame(); void recreate_swapchain(); - void update_image(Texture* texture, void* data, size_t size); + void update_image(Texture* texture, void* data); + + void update_buffer(Buffer* buffer, void* data, off_t offset, size_t size); Buffer* create_buffer(size_t size, bool isStatic); + Buffer* create_index_buffer(size_t size, bool isStatic); + Texture* create_2d_texture(size_t width, size_t height, VkFormat format); Sampler* create_sampler(VkFilter filter, VkSamplerAddressMode address_mode); ComputeRenderpass* create_compute_renderpass(); + PrimitiveRenderpass* create_primitive_renderpass(); + + Primitive* create_primitive(PrimitiveRenderpass& primitive_render_pass); + void render(); uint32_t frame_index() { return this->virtual_frame_index; } - private: + Texture* back_buffer() { return swapchain_textures[swapchain_image_index]; } - vkapi api; + VkFormat back_buffer_format() { return swapchain.surface_format.format; } - std::vector renderpasses; + static constexpr uint32_t virtual_frames_count = 2; + private: void handle_swapchain_result(VkResult function_result); - // vkapi api; + vkapi api; + + std::vector renderpasses; uint32_t virtual_frame_index = 0; uint32_t swapchain_image_index = 0; - sampler ui_texture_sampler; - image ui_texture; - std::vector command_buffers; - buffer staging_buffer; + handle staging_buffer; pipeline tonemapping_pipeline; - std::vector ui_vertex_buffers; - std::vector ui_index_buffers; - pipeline ui_pipeline; - VkRenderPass render_pass; - std::vector framebuffers; - std::vector submission_fences; std::vector execution_semaphores; std::vector acquire_semaphores; VkSurfaceKHR platform_surface; swapchain swapchain; + std::vector swapchain_textures; const uint32_t min_swapchain_image_count = 3; - static constexpr uint32_t virtual_frames_count = 2; }; // TODO: Move those to there own files @@ -93,39 +95,26 @@ class Texture { sampler sampler; - image device_image; + handle device_image; }; class Sampler { public: - sampler device_sampler; + + handle device_sampler; }; class Buffer { public: Buffer(vkrenderer* renderer, size_t size, bool isStatic) - : renderer(renderer), size(size), isStatic(isStatic) {} - - void* ptr() { - size_t offset = isStatic ? 0 : size * renderer->frame_index(); - return (uint8_t*)device_buffer.alloc_info.pMappedData + offset; - } + : size(size), isStatic(isStatic) {} - unsigned long long device_address() { - size_t offset = isStatic ? 0 : size * renderer->frame_index(); - return device_buffer.device_address + offset; - } - - buffer device_buffer; - - private: - - bool isStatic; + handle device_buffer; size_t size; - vkrenderer* renderer; + bool isStatic; }; #endif // !__VK_RENDERER_HPP_ -- cgit v1.3