From 5e3bb454d50091e581d5d1d03af34e38277694b3 Mon Sep 17 00:00:00 2001 From: ladevieq Date: Thu, 12 Jan 2023 00:47:59 +0100 Subject: WIP new rendering api --- include/api-test/command-buffer.hpp | 44 +++++++ include/api-test/handle.hpp | 2 +- include/api-test/vk-command-buffer.hpp | 14 --- include/api-test/vk-device.hpp | 65 ++++------ include/resource-manager.hpp | 6 - include/texture.hpp | 83 +++++++++++++ include/vec3.hpp | 20 +-- include/vk-api.hpp | 219 ++++++++++++++++----------------- include/vk-context.hpp | 2 +- include/vk-renderer.hpp | 65 ---------- 10 files changed, 274 insertions(+), 246 deletions(-) create mode 100644 include/api-test/command-buffer.hpp delete mode 100644 include/api-test/vk-command-buffer.hpp delete mode 100644 include/resource-manager.hpp create mode 100644 include/texture.hpp (limited to 'include') diff --git a/include/api-test/command-buffer.hpp b/include/api-test/command-buffer.hpp new file mode 100644 index 0000000..140a291 --- /dev/null +++ b/include/api-test/command-buffer.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include + +#include + +#include "handle.hpp" + +enum class QueueType : uint32_t { + GRAPHICS, + ASYNC_COMPUTE, + TRANSFER, + MAX, +}; + + +struct device_buffer; +struct device_texture; + +struct command_buffer { + void start() const; + void stop() const; + + void barrier(); + + VkCommandBuffer handle; + QueueType queue_type; +}; + +struct graphics_command_buffer : public command_buffer { + void set_pipeline(); + + void dispatch(); +}; + +struct compute_command_buffer : public command_buffer { + void set_pipeline(); + + void dispatch(); +}; + +struct transfer_command_buffer : public command_buffer { + void copy(::handle buffer_handle, ::handle texture_handle); +}; diff --git a/include/api-test/handle.hpp b/include/api-test/handle.hpp index 90c1ade..c14e212 100644 --- a/include/api-test/handle.hpp +++ b/include/api-test/handle.hpp @@ -4,5 +4,5 @@ template struct handle { - const uint32_t handle; + const uint32_t id; }; diff --git a/include/api-test/vk-command-buffer.hpp b/include/api-test/vk-command-buffer.hpp deleted file mode 100644 index c1f1899..0000000 --- a/include/api-test/vk-command-buffer.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -class command_buffer { - void start(); - void stop(); - - VkCommandBuffer handle; -}; - -class graphics_command_buffer : command_buffer { - -}; diff --git a/include/api-test/vk-device.hpp b/include/api-test/vk-device.hpp index f931c70..f010cc5 100644 --- a/include/api-test/vk-device.hpp +++ b/include/api-test/vk-device.hpp @@ -8,28 +8,11 @@ #include "freelist.hpp" #include "texture.hpp" #include "buffer.hpp" +#include "command-buffer.hpp" using VmaAllocator = struct VmaAllocator_T*; using VmaAllocation = struct VmaAllocation_T*; -// typedef struct VkInstance_T* VkInstance; -// typedef struct VkDevice_T* VkDevice; -// typedef struct VkPhysicalDevice_T* VkPhysicalDevice; -// typedef struct VkQueue_T* VkQueue; -// typedef uint32_t VkFlags; -// typedef VkFlags VkQueueUsageFlags; -// typedef struct VkImage_T* VkImage; -// typedef struct VkImageView_T* VkImageView; -// typedef struct VkBuffer_T* VkBuffer; -// typedef enum VkImageType VkImageType; -// typedef enum VkFormat VkFormat; -// typedef VkFlags VkImageUsageFlags; -// -// #ifdef _DEBUG -// typedef struct VkDebugUtilsMessengerEXT_T* VkDebugUtilsMessengerEXT; -// #endif // _DEBUG - - struct device_texture { VkImage handle; VkImageView whole_view; @@ -51,6 +34,13 @@ struct device_buffer { class window; class vkdevice { + struct queue { + VkQueue handle; + uint32_t index; + VkQueueFlags usages; + VkCommandPool command_pool; + }; + public: vkdevice(const window& window); @@ -59,18 +49,25 @@ public: handle create_buffer(const buffer_desc& desc); + template + void allocate_command_buffers(cmd_buf_type* buffers, size_t count, QueueType queue_type) { + allocate_command_buffers(buffers, count, queue_type); + } + const device_texture& get_texture(handle handle) { - return textures[handle.handle]; + return textures[handle.id]; } const device_buffer& get_buffer(handle handle) { - return buffers[handle.handle]; + return buffers[handle.id]; } - void submit(/*std::span*/); + void submit(command_buffer* buffers, size_t count); private: + void allocate_command_buffers(command_buffer* buffers, size_t count, QueueType type); + void create_views(device_texture& texture); void create_surface(const window& window); @@ -98,29 +95,19 @@ private: void create_debug_layer_callback(); - enum QueueTypes : uint32_t { - GRAPHICS, - // COPY, - MAX, - }; - - struct queue { - VkQueue handle; - uint32_t index; - VkQueueFlags usages; - VkCommandPool command_pool; - }; + queue queues[static_cast(QueueType::MAX)]; - queue queues[QueueTypes::MAX]; + VkInstance instance; + VkPhysicalDevice physical_device; + VkDevice device; - VkInstance instance; - VkPhysicalDevice physical_device; - VkDevice device; + VmaAllocator gpu_allocator; - VmaAllocator gpu_allocator; + static constexpr size_t max_allocable_command_buffers = 16; + static constexpr size_t max_submitable_command_buffers = 16; #ifdef _DEBUG - VkDebugUtilsMessengerEXT debug_messenger; + VkDebugUtilsMessengerEXT debug_messenger; #endif // _DEBUG freelist textures; diff --git a/include/resource-manager.hpp b/include/resource-manager.hpp deleted file mode 100644 index 2a8a787..0000000 --- a/include/resource-manager.hpp +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -class resourcemanager { - public: - static const resourcemanager resource_manager; -}; diff --git a/include/texture.hpp b/include/texture.hpp new file mode 100644 index 0000000..aac7b69 --- /dev/null +++ b/include/texture.hpp @@ -0,0 +1,83 @@ +#include + +using VkImage = struct VkImage_T*; + +struct TextureDesc { + VkImageType type; + VkFormat format; + VkExtent size; + VkImageUsageFlags usages; +}; + +class Texture { + public: + Texture(const TextureDesc desc) + : description(desc) { + create_device_image(); + } + + // Texture(handle image_handle) { + // const auto& image = vkrenderer::api.get_image(image_handle); + // width = image.size.width; + // height = image.size.height; + // depth = image.size.depth; + + // device_image = image_handle; + // } + + // Texture(size_t width, size_t height, size_t depth, VkFormat format = VK_FORMAT_R8G8B8A8_UNORM, Sampler* texture_sampler = nullptr) + // : width(width), height(height), depth(depth) { + // sampler = texture_sampler; + // device_image = vkrenderer::api.create_image( + // { .width = (uint32_t)width, .height = (uint32_t)height, .depth = 1 }, + // format, + // VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); + // } + + void update(void* new_data) { + if (data == nullptr) { + free(data); + } + data = new_data; + + vkrenderer::queue_image_update(this); + } + + ~Texture() { + vkrenderer::api.destroy_image(device_image); + + if (data == nullptr) { + free(data); + } + } + + [[nodiscard]] size_t size() const { + const auto& image = vkrenderer::api.get_image(device_image); + return width * height * depth * pixel_size(image.format); + } + + static size_t pixel_size(VkFormat format) { + switch (format) { + case VK_FORMAT_R8G8B8A8_UNORM: + return 4; + default: + return 0; + } + } + + // Sampler* sampler = nullptr; + + private: + void create_device_image(); + + void* data = nullptr; + + size_t width = 0; + size_t height = 0; + size_t depth = 0; + + TextureDesc description; + + VmaAllocationInfo alloc_info; + VkImage device_image; +}; diff --git a/include/vec3.hpp b/include/vec3.hpp index 6513ce8..2fec69e 100644 --- a/include/vec3.hpp +++ b/include/vec3.hpp @@ -4,7 +4,7 @@ #include class vec3 { - public: + public: vec3(); vec3(float x); @@ -12,7 +12,7 @@ class vec3 { vec3(__m128& v); vec3(__m128&& v); vec3(const vec3& vec); - vec3(const vec3&& vec); + vec3(const vec3&& vec) noexcept; vec3 operator-() const; @@ -26,21 +26,21 @@ class vec3 { float operator[](int axis); - float length() const; + [[nodiscard]] float length() const; - float length_sq() const; + [[nodiscard]] float length_sq() const; - float dot(const vec3& vec) const; + [[nodiscard]] float dot(const vec3& vec) const; - vec3 cross(const vec3& vec) const; + [[nodiscard]] vec3 cross(const vec3& vec) const; - vec3 min(const vec3& vec) const; + [[nodiscard]] vec3 min(const vec3& vec) const; - vec3 max(const vec3& vec) const; + [[nodiscard]] vec3 max(const vec3& vec) const; vec3& normalize(); - bool near_zero() const; + [[nodiscard]] bool near_zero() const; void print() const; @@ -72,4 +72,4 @@ vec3 refract(const vec3& uv, const vec3& n, float etai_over_etat); using point3 = vec3; using color = vec3; -#endif // !__VEC3_HPP_ +#endif // !_ diff --git a/include/vk-api.hpp b/include/vk-api.hpp index b50e751..a3442f1 100644 --- a/include/vk-api.hpp +++ b/include/vk-api.hpp @@ -1,71 +1,70 @@ #ifndef __VK_API_HPP_ #define __VK_API_HPP_ -#include #include +#include -#include "vulkan-loader.hpp" +#include using VmaAllocation = struct VmaAllocation_T*; struct buffer { - VmaAllocation alloc; - void* device_ptr; - VkBuffer handle; - size_t size; - VkDeviceAddress device_address; + VmaAllocation alloc; + void* device_ptr; + VkBuffer handle; + size_t size; + VkDeviceAddress device_address; }; struct pipeline { std::vector shader_modules; - VkPipeline handle = VK_NULL_HANDLE; - VkPipelineBindPoint bind_point; + VkPipeline handle = VK_NULL_HANDLE; + VkPipelineBindPoint bind_point; }; using bindless_index = uint32_t; using handle = uint32_t; struct image { - VkImage handle; - VkImageView view; - VmaAllocation alloc; - void* device_ptr; + VkImage handle; + VkImageView view; + VmaAllocation alloc; VkImageSubresourceRange subresource_range; - VkFormat format; - VkExtent3D size; - VkImageUsageFlags usages; - bindless_index bindless_storage_index = 0; - bindless_index bindless_sampled_index = 0; - - VkImageLayout previous_layout = VK_IMAGE_LAYOUT_UNDEFINED; - VkPipelineStageFlags previous_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - VkAccessFlags previous_access = 0; + VkFormat format; + VkExtent3D size; + VkImageUsageFlags usages; + bindless_index bindless_storage_index = 0; + bindless_index bindless_sampled_index = 0; + + VkImageLayout previous_layout = VK_IMAGE_LAYOUT_UNDEFINED; + VkPipelineStageFlags previous_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + VkAccessFlags previous_access = 0; }; struct swapchain { - uint32_t image_count; - std::vector images; - VkSwapchainKHR handle; - VkSurfaceFormatKHR surface_format; - VkExtent2D extent; + uint32_t image_count; + std::vector images; + VkSwapchainKHR handle; + VkSurfaceFormatKHR surface_format; + VkExtent2D extent; }; struct framebuffer { - VkFramebuffer handle; - VkExtent2D size; + VkFramebuffer handle; + VkExtent2D size; }; struct sampler { - VkSampler handle; - bindless_index bindless_index; + VkSampler handle; + bindless_index bindless_index; }; struct global_descriptor { - VkDescriptorSetLayout set_layout; - VkPipelineLayout pipeline_layout; - VkDescriptorSet set; + VkDescriptorSetLayout set_layout; + VkPipelineLayout pipeline_layout; + VkDescriptorSet set; - std::vector index_pool[3]; + std::vector index_pool[3]; static constexpr uint32_t pool_size = 1024U; @@ -78,7 +77,7 @@ struct global_descriptor { } uint32_t allocate(VkDescriptorType type) { - auto &pool = index_pool[descriptor_type_binding(type)]; + auto& pool = index_pool[descriptor_type_binding(type)]; auto index = pool.back(); pool.pop_back(); @@ -91,16 +90,16 @@ struct global_descriptor { } static int32_t descriptor_type_binding(VkDescriptorType type) { - switch(type) { - case VK_DESCRIPTOR_TYPE_SAMPLER: - return 0; - case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - return 1; - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - return 2; - default: - assert(true && "descriptor type not supported"); - return -1; + switch (type) { + case VK_DESCRIPTOR_TYPE_SAMPLER: + return 0; + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + return 1; + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + return 2; + default: + assert(true && "descriptor type not supported"); + return -1; } } }; @@ -110,111 +109,111 @@ class vkcontext; class vkapi { public: - vkapi(vkcontext& context); - ~vkapi(); + vkapi(vkcontext& context); + ~vkapi(); - handle create_buffer(size_t data_size, VkBufferUsageFlags buffer_usage, uint32_t 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, size_t size, size_t buffer_offset = 0); - void destroy_buffer(handle buffer); + handle create_buffer(size_t data_size, VkBufferUsageFlags buffer_usage, uint32_t 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, size_t size, size_t buffer_offset = 0); + void destroy_buffer(handle buffer); - 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& imgs); + 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& imgs); - [[nodiscard]] VkFence create_fence() const; - void destroy_fence(VkFence fence) const; - [[nodiscard]] std::vector create_fences(size_t fences_count) const; - void destroy_fences(VkFence fences[], size_t fences_count) const; + [[nodiscard]] VkFence create_fence() const; + void destroy_fence(VkFence fence) const; + [[nodiscard]] std::vector create_fences(size_t fences_count) const; + void destroy_fences(VkFence fences[], size_t fences_count) const; - [[nodiscard]] VkSemaphore create_semaphore() const; - void destroy_semaphore(VkSemaphore semaphore) const; - [[nodiscard]] std::vector create_semaphores(size_t semaphores_count) const; - void destroy_semaphores(VkSemaphore semaphores[], size_t semaphores_count) const; + [[nodiscard]] VkSemaphore create_semaphore() const; + void destroy_semaphore(VkSemaphore semaphore) const; + [[nodiscard]] std::vector create_semaphores(size_t semaphores_count) const; + void destroy_semaphores(VkSemaphore semaphores[], size_t semaphores_count) const; - handle create_sampler(VkFilter filter, VkSamplerAddressMode address_mode); - void destroy_sampler(handle sampler); + handle create_sampler(VkFilter filter, VkSamplerAddressMode address_mode); + void destroy_sampler(handle sampler); - [[nodiscard]] VkCommandPool create_command_pool() const; + [[nodiscard]] VkCommandPool create_command_pool() const; - void allocate_command_buffers(VkCommandPool command_pool, VkCommandBuffer* command_buffers, size_t count) const; + void allocate_command_buffers(VkCommandPool command_pool, VkCommandBuffer* command_buffers, size_t count) const; - VkRenderPass create_render_pass(std::vector& color_attachments_format, VkImageLayout initial_layout, VkImageLayout final_layout); - VkRenderPass create_render_pass(std::vector& color_attachments_format, VkFormat depth_attachement_format); - void destroy_render_pass(VkRenderPass render_pass); + VkRenderPass create_render_pass(std::vector& color_attachments_format, VkImageLayout initial_layout, VkImageLayout final_layout); + VkRenderPass create_render_pass(std::vector& color_attachments_format, VkFormat depth_attachement_format); + void destroy_render_pass(VkRenderPass render_pass); - 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) const; - void destroy_framebuffers(std::vector& framebuffers) const; + 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) const; + void destroy_framebuffers(std::vector& framebuffers) const; - pipeline create_compute_pipeline(const char* shader_name) const; - pipeline create_graphics_pipeline(const char* shader_name, VkShaderStageFlagBits shader_stages, VkRenderPass render_pass, std::vector& dynamic_states) const; - void destroy_pipeline(pipeline &pipeline) const; + pipeline create_compute_pipeline(const char* shader_name) const; + pipeline create_graphics_pipeline(const char* shader_name, VkShaderStageFlagBits shader_stages, VkRenderPass render_pass, std::vector& dynamic_states) const; + void destroy_pipeline(pipeline& pipeline) const; - VkSurfaceKHR create_surface(window& wnd) const; - void destroy_surface(VkSurfaceKHR surface); + VkSurfaceKHR create_surface(window& wnd) const; + void destroy_surface(VkSurfaceKHR surface); - swapchain create_swapchain(VkSurfaceKHR surface, size_t min_image_count, VkImageUsageFlags usages, VkSwapchainKHR old_swapchain); - void destroy_swapchain(swapchain& swapchain); + swapchain create_swapchain(VkSurfaceKHR surface, size_t min_image_count, VkImageUsageFlags usages, VkSwapchainKHR old_swapchain); + void destroy_swapchain(swapchain& swapchain); - 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_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 update_constants(VkCommandBuffer command_buffer, VkShaderStageFlagBits shader_stage, off_t offset, size_t size, void* data); - void start_record(VkCommandBuffer command_buffer); + void start_record(VkCommandBuffer command_buffer); - void image_barrier(VkCommandBuffer command_buffer, VkImageLayout dst_layout, VkPipelineStageFlagBits dst_stage, VkAccessFlags dst_access, handle 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, std::vector& attachments, framebuffer framebuffer, VkExtent2D size); - void end_render_pass(VkCommandBuffer command_buffer); + 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 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, handle index_buffer, uint32_t primitive_count, uint32_t indices_offset, uint32_t vertices_offset); + void draw(VkCommandBuffer command_buffer, pipeline& pipeline, uint32_t vertex_count, uint32_t vertex_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, handle src_image, handle dst_image); + void blit_full(VkCommandBuffer command_buffer, handle src_image, handle dst_image); - void end_record(VkCommandBuffer command_buffer); + void end_record(VkCommandBuffer command_buffer); - VkResult submit(VkCommandBuffer command_buffers[], size_t command_buffers_count, VkSemaphore wait_semaphore, VkSemaphore signal_semaphore, VkFence submission_fence) const; + VkResult submit(VkCommandBuffer command_buffers[], size_t command_buffers_count, VkSemaphore wait_semaphore, VkSemaphore signal_semaphore, VkFence submission_fence) const; - VkResult present(swapchain& swapchain, uint32_t image_index, VkSemaphore wait_semaphore) const; + VkResult present(swapchain& swapchain, uint32_t image_index, VkSemaphore wait_semaphore) const; - 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]; }; + const buffer& get_buffer(handle buffer_handle) { return *buffers[buffer_handle]; }; - vkcontext& context; + const image& get_image(handle image_handle) { return *images[image_handle]; }; - private: + const sampler& get_sampler(handle sampler_handle) { return *samplers[sampler_handle]; }; - global_descriptor bindless_descriptor; + vkcontext& context; - static const char* shader_stage_extension(VkShaderStageFlags shader_stage); + private: + global_descriptor bindless_descriptor; - // TODO: Use freelists instead - std::vector buffers; - std::vector images; - std::vector samplers; + static const char* shader_stage_extension(VkShaderStageFlags shader_stage); - VkDescriptorPool descriptor_pool; + // TODO: Use freelists instead + std::vector buffers; + std::vector images; + std::vector samplers; + VkDescriptorPool descriptor_pool; }; #endif // !__VK_API_HPP_ diff --git a/include/vk-context.hpp b/include/vk-context.hpp index 58d7ce9..0dfd256 100644 --- a/include/vk-context.hpp +++ b/include/vk-context.hpp @@ -1,6 +1,6 @@ #pragma once -#include "vulkan-loader.hpp" +#include using VmaAllocator = struct VmaAllocator_T*; diff --git a/include/vk-renderer.hpp b/include/vk-renderer.hpp index ab15cd1..1317912 100644 --- a/include/vk-renderer.hpp +++ b/include/vk-renderer.hpp @@ -61,8 +61,6 @@ class vkrenderer { static Buffer* create_staging_buffer(size_t size); - static Texture* create_2d_texture(size_t width, size_t height, VkFormat format, Sampler *sampler = nullptr); - static Sampler* create_sampler(VkFilter filter, VkSamplerAddressMode address_mode); @@ -163,67 +161,4 @@ class Sampler { handle device_sampler; }; -class Texture { - public: - - Texture(handle image_handle) { - const auto &image = vkrenderer::api.get_image(image_handle); - width = image.size.width; - height = image.size.height; - depth = image.size.depth; - - device_image = image_handle; - } - - Texture(size_t width, size_t height, size_t depth, VkFormat format = VK_FORMAT_R8G8B8A8_UNORM, Sampler* texture_sampler = nullptr) - : width(width), height(height), depth(depth) { - sampler = texture_sampler; - device_image = vkrenderer::api.create_image( - { .width = (uint32_t)width, .height = (uint32_t)height, .depth = 1 }, - format, - VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT - ); - } - - void update(void* new_data) { - if (data == nullptr) { - free(data); - } - data = new_data; - - vkrenderer::queue_image_update(this); - } - - ~Texture() { - vkrenderer::api.destroy_image(device_image); - - if (data == nullptr) { - free(data); - } - } - - [[nodiscard]]size_t size() const { - const auto& image = vkrenderer::api.get_image(device_image); - return width * height * depth * pixel_size(image.format); - } - - static size_t pixel_size(VkFormat format) { - switch (format) { - case VK_FORMAT_R8G8B8A8_UNORM: - return 4; - default: - return 0; - } - } - - Sampler* sampler = nullptr; - - void* data = nullptr; - - size_t width = 0; - size_t height = 0; - size_t depth = 0; - - handle device_image; -}; #endif // !__VK_RENDERER_HPP_ -- cgit v1.3