From c29105b461135f3909cca0308fb05715cee45763 Mon Sep 17 00:00:00 2001 From: Quentin LADEVIE Date: Sun, 26 Jan 2025 22:27:10 +0100 Subject: DX12 command buffers and resources --- include/api-test/command-buffer.hpp | 103 ------------------------------ include/api-test/dx12-command-buffer.hpp | 28 ++++++++ include/api-test/dx12-device-types.hpp | 47 +++++++++++++- include/api-test/dx12-device.hpp | 106 +++++++++++++++++++++++-------- include/api-test/vk-command-buffer.hpp | 103 ++++++++++++++++++++++++++++++ include/api-test/vk-device.hpp | 6 +- 6 files changed, 257 insertions(+), 136 deletions(-) delete mode 100644 include/api-test/command-buffer.hpp create mode 100644 include/api-test/dx12-command-buffer.hpp create mode 100644 include/api-test/vk-command-buffer.hpp (limited to 'include') diff --git a/include/api-test/command-buffer.hpp b/include/api-test/command-buffer.hpp deleted file mode 100644 index 0eff93a..0000000 --- a/include/api-test/command-buffer.hpp +++ /dev/null @@ -1,103 +0,0 @@ -#pragma once - -#include -#include - -#include - -#include "handle.hpp" - -#include "vec3.hpp" - -#include "vk-device-types.hpp" - -struct device_texture; -struct device_buffer; -struct device_pipeline; - -struct dispatch_params { - enum class PARAM_BINDING : uint32_t { - PARAM1, - PARAM2, - PARAM3, - PARAM4, - PARAM5, - PARAM6, - PARAM7, - PARAM8, - MAX - }; - - handle pipeline; - vec3u group_size; - vec3u local_group_size; - uint64_t params[static_cast(PARAM_BINDING::MAX)]; -}; - -struct renderpass_params { -private: - struct rect { - int32_t x; - int32_t y; - uint32_t width; - uint32_t height; - }; - -public: - rect render_area; - std::span> color_attachments; -}; - -struct draw_params { - handle pipeline; - handle index_buffer; - uint32_t vertex_count; - uint32_t vertex_offset; - uint32_t instance_count; - uint64_t globals_address = 0U; // TODO: This is probably stupid and should be set elsewhere once ??? - uint64_t instances_address = 0U; - uint64_t uniforms_address = 0U; - uint64_t vertex_address = 0U; -}; - -struct draw_indexed_params { - handle pipeline; - handle index_buffer; - uint32_t vertex_count; - uint32_t vertex_offset; - uint32_t index_offset; - uint32_t instance_count; - uint64_t globals_address = 0U; // TODO: This is probably stupid and should be set elsewhere once ??? - uint64_t instances_address = 0U; - uint64_t uniforms_address = 0U; - uint64_t vertex_address = 0U; -}; - -struct command_buffer { - void start() const; - void stop() const; - - void barrier(handle texture_handle, VkPipelineStageFlags2 stage, VkAccessFlags2 access, VkImageLayout layout) const; - - void copy(handle buffer_handle, handle texture_handle, VkDeviceSize offset = 0) const; - - VkCommandBuffer vk_command_buffer; - QueueType queue_type; -}; - -// General purpose queue -struct graphics_command_buffer: public command_buffer { - void dispatch(const dispatch_params& params) const; - - void begin_renderpass(const renderpass_params& params) const; - void draw(const draw_params& params) const; - void draw_indexed(const draw_indexed_params& params) const; - void end_renderpass() const; -}; - -struct compute_command_buffer: public command_buffer { - void dispatch(const dispatch_params& params); -}; - -struct transfer_command_buffer: public command_buffer { -}; diff --git a/include/api-test/dx12-command-buffer.hpp b/include/api-test/dx12-command-buffer.hpp new file mode 100644 index 0000000..e9de39a --- /dev/null +++ b/include/api-test/dx12-command-buffer.hpp @@ -0,0 +1,28 @@ +#include + +#include "handle.hpp" +#include "dx12-device-types.hpp" + +namespace dx12 { + struct command_buffer { + void start() const; + void stop() const; + + // void barrier(handle texture_handle, VkPipelineStageFlags2 stage, VkAccessFlags2 access, VkImageLayout layout) const; + + void copy(handle src_buffer, handle dst_texture, uint64_t offset = 0) const; + + ID3D12CommandAllocator* command_allocator; + ID3D12GraphicsCommandList* dx12_command_buffer; + dx12::QueueType queue_type; + }; + + struct graphics_command_buffer: public command_buffer { + // void dispatch(const dispatch_params& params) const; + + // void begin_renderpass(const renderpass_params& params) const; + // void draw(const draw_params& params) const; + // void draw_indexed(const draw_indexed_params& params) const; + // void end_renderpass() const; + }; +} diff --git a/include/api-test/dx12-device-types.hpp b/include/api-test/dx12-device-types.hpp index b70ecf4..4b2fc42 100644 --- a/include/api-test/dx12-device-types.hpp +++ b/include/api-test/dx12-device-types.hpp @@ -1,5 +1,9 @@ +#pragma once +#include +#include +#include + #include -#include namespace dx12 { enum class QueueType : uint32_t { @@ -9,17 +13,54 @@ namespace dx12 { MAX, }; + struct buffer_desc { + uint32_t size; + bool map; + + D3D12_RESOURCE_STATES states; + D3D12_RESOURCE_FLAGS usages; + D3D12_HEAP_TYPE heap_type = D3D12_HEAP_TYPE_DEFAULT; + }; + + struct device_buffer { + ID3D12Resource* resource; + + D3D12MA::Allocation* alloc; + uint32_t size; + void* mapped_ptr = nullptr; + }; + + struct texture_desc { + uint32_t width = 1U; + uint32_t height = 1U; + uint32_t depth = 1U; + uint32_t mips = 1U; + + D3D12_RESOURCE_STATES states; + D3D12_RESOURCE_FLAGS usages; + DXGI_FORMAT format; + D3D12_RESOURCE_DIMENSION type; }; struct device_texture { + ID3D12Resource* resource; + D3D12MA::Allocation* alloc; + + uint32_t width = 1U; + uint32_t height = 1U; + uint32_t depth = 1U; + uint32_t mips = 1U; + uint64_t row_pitch = 1U; + + DXGI_FORMAT format; + }; struct surface_desc { HWND window_handle; DXGI_FORMAT surface_format; DXGI_SWAP_EFFECT present_mode; - // VkImageUsageFlags usages; DXGI_USAGE usages; uint32_t image_count = surface_desc::default_image_count; @@ -28,6 +69,6 @@ namespace dx12 { }; struct device_surface { - IDXGISwapChain* swapchain; + IDXGISwapChain1* swapchain; }; } diff --git a/include/api-test/dx12-device.hpp b/include/api-test/dx12-device.hpp index 83d8888..baa5b60 100644 --- a/include/api-test/dx12-device.hpp +++ b/include/api-test/dx12-device.hpp @@ -1,47 +1,97 @@ +#pragma once + #include +#include #include "freelist.hpp" #include "dx12-device-types.hpp" -class dx12device { - struct queue { - ID3D12CommandQueue* dx_queue; - }; - public: - void init(); +#include "D3D12MemAlloc.h" + +namespace dx12 { + struct command_buffer; + + class device { + struct queue { + ID3D12CommandQueue* dx_queue; + D3D12_COMMAND_LIST_TYPE type; + }; + public: + void init(); + + static inline device& get_render_device() { + return render_device; + } + + handle create_surface(const surface_desc& desc); + + handle create_buffer(const buffer_desc& desc); + + handle create_texture(const texture_desc& desc); - static inline dx12device& get_render_device() { - return render_device; - } + void create_graphics_pipeline() {}; - handle create_surface(const dx12::surface_desc& desc); + void create_compute_pipeline() {}; - void create_buffer() {}; + void allocate_command_buffers(command_buffer* buffers, size_t count, QueueType type); - void create_texture() {}; - void create_graphics_pipeline() {}; + [[nodiscard]] inline device_surface& get_surface(handle handle) { + return surfaces[handle]; + } - void create_compute_pipeline() {}; + [[nodiscard]] inline device_buffer& get_buffer(handle handle) { + return buffers[handle]; + } - void allocate_command_buffers() {}; + [[nodiscard]] inline device_texture& get_texture(handle handle) { + return textures[handle]; + } - void get_buffer() {}; + [[nodiscard]] inline ID3D12Device* get_device() const { + return device; + } - void get_texture() {}; + uint32_t submit(command_buffer* buffers, uint32_t count); - [[nodiscard]] inline dx12::device_surface& get_surface(handle handle) { - return surfaces[handle]; - } + void wait(); - private: - IDXGIFactory* factory; - IDXGIAdapter* adapter; + private: + IDXGIFactory3* factory; + IDXGIAdapter* adapter; + ID3D12Debug* debug_interface; - ID3D12Device* device; - queue queues[static_cast(dx12::QueueType::MAX)]; + D3D12MA::Allocator* allocator; - freelist surfaces; + ID3D12Device* device; + ID3D12Fence* fence; + uint64_t fence_value = 0U; + queue queues[static_cast(QueueType::MAX)]; + + freelist surfaces; + freelist buffers; + freelist textures; + + static constexpr size_t max_allocable_command_buffers = 16U; + static constexpr size_t max_submitable_command_buffers = 16U; + + static class device render_device; + + struct bindless_model { + void init(); + + [[nodiscard]] inline ID3D12DescriptorHeap* const* get_heaps() const { + return &resources_heap; + } + + ID3D12DescriptorHeap* resources_heap; + ID3D12DescriptorHeap* samplers_heap; + } model; + + public: + [[nodiscard]] static inline const device::bindless_model& get_bindless_model() { + return render_device.model; + } + }; - static dx12device render_device; -}; +} diff --git a/include/api-test/vk-command-buffer.hpp b/include/api-test/vk-command-buffer.hpp new file mode 100644 index 0000000..08652fd --- /dev/null +++ b/include/api-test/vk-command-buffer.hpp @@ -0,0 +1,103 @@ +#pragma once + +#include +#include + +#include + +#include "handle.hpp" + +#include "vec3.hpp" + +#include "vk-device-types.hpp" + +struct device_texture; +struct device_buffer; +struct device_pipeline; + +struct dispatch_params { + enum class PARAM_BINDING : uint32_t { + PARAM1, + PARAM2, + PARAM3, + PARAM4, + PARAM5, + PARAM6, + PARAM7, + PARAM8, + MAX + }; + + handle pipeline; + vec3u group_size; + vec3u local_group_size; + uint64_t params[static_cast(PARAM_BINDING::MAX)]; +}; + +struct renderpass_params { +private: + struct rect { + int32_t x; + int32_t y; + uint32_t width; + uint32_t height; + }; + +public: + rect render_area; + std::span> color_attachments; +}; + +struct draw_params { + handle pipeline; + handle index_buffer; + uint32_t vertex_count; + uint32_t vertex_offset; + uint32_t instance_count; + uint64_t globals_address = 0U; // TODO: This is probably stupid and should be set elsewhere once ??? + uint64_t instances_address = 0U; + uint64_t uniforms_address = 0U; + uint64_t vertex_address = 0U; +}; + +struct draw_indexed_params { + handle pipeline; + handle index_buffer; + uint32_t vertex_count; + uint32_t vertex_offset; + uint32_t index_offset; + uint32_t instance_count; + uint64_t globals_address = 0U; // TODO: This is probably stupid and should be set elsewhere once ??? + uint64_t instances_address = 0U; + uint64_t uniforms_address = 0U; + uint64_t vertex_address = 0U; +}; + +struct command_buffer { + void start() const; + void stop() const; + + void barrier(handle texture_handle, VkPipelineStageFlags2 stage, VkAccessFlags2 access, VkImageLayout layout) const; + + void copy(handle buffer_handle, handle texture_handle, uint64_t offset = 0) const; + + VkCommandBuffer vk_command_buffer; + QueueType queue_type; +}; + +// General purpose queue +struct graphics_command_buffer: public command_buffer { + void dispatch(const dispatch_params& params) const; + + void begin_renderpass(const renderpass_params& params) const; + void draw(const draw_params& params) const; + void draw_indexed(const draw_indexed_params& params) const; + void end_renderpass() const; +}; + +struct compute_command_buffer: public command_buffer { + void dispatch(const dispatch_params& params); +}; + +struct transfer_command_buffer: public command_buffer { +}; diff --git a/include/api-test/vk-device.hpp b/include/api-test/vk-device.hpp index 9dffad8..dc46e1a 100644 --- a/include/api-test/vk-device.hpp +++ b/include/api-test/vk-device.hpp @@ -5,12 +5,13 @@ #include -#include "command-buffer.hpp" #include "freelist.hpp" +#include "vk-device-types.hpp" #include "vk-bindless.hpp" using VmaAllocator = struct VmaAllocator_T*; +struct command_buffer; class window; class vkdevice { @@ -23,6 +24,7 @@ class vkdevice { public: void init(); + void deinit(); static inline vkdevice& get_render_device() { return render_device; @@ -106,7 +108,7 @@ class vkdevice { private: vkdevice() = default; - ~vkdevice(); + ~vkdevice() = default; void allocate_command_buffers(command_buffer* buffers, size_t count, QueueType type); -- cgit v1.3