diff options
Diffstat (limited to 'drivers/d3d12/rendering_device_driver_d3d12.h')
-rw-r--r-- | drivers/d3d12/rendering_device_driver_d3d12.h | 185 |
1 files changed, 163 insertions, 22 deletions
diff --git a/drivers/d3d12/rendering_device_driver_d3d12.h b/drivers/d3d12/rendering_device_driver_d3d12.h index 0da339c6fd..5fe5aff6cf 100644 --- a/drivers/d3d12/rendering_device_driver_d3d12.h +++ b/drivers/d3d12/rendering_device_driver_d3d12.h @@ -65,14 +65,11 @@ using Microsoft::WRL::ComPtr; #define D3D12_BITCODE_OFFSETS_NUM_STAGES 3 struct dxil_validator; - -class D3D12Context; +class RenderingContextDriverD3D12; // Design principles: // - D3D12 structs are zero-initialized and fields not requiring a non-zero value are omitted (except in cases where expresivity reasons apply). class RenderingDeviceDriverD3D12 : public RenderingDeviceDriver { - friend class D3D12Context; // For FramebufferInfo, RenderPassInfo and CommandBufferInfo. - /*****************/ /**** GENERIC ****/ /*****************/ @@ -86,8 +83,58 @@ class RenderingDeviceDriverD3D12 : public RenderingDeviceDriver { static const D3D12Format RD_TO_D3D12_FORMAT[RDD::DATA_FORMAT_MAX]; - D3D12Context *context = nullptr; - ID3D12Device *device = nullptr; // Owned by the context. + struct DeviceLimits { + uint64_t max_srvs_per_shader_stage = 0; + uint64_t max_cbvs_per_shader_stage = 0; + uint64_t max_samplers_across_all_stages = 0; + uint64_t max_uavs_across_all_stages = 0; + uint64_t timestamp_frequency = 0; + }; + + struct SubgroupCapabilities { + uint32_t size = 0; + bool wave_ops_supported = false; + uint32_t supported_stages_flags_rd() const; + uint32_t supported_operations_flags_rd() const; + }; + + struct VRSCapabilities { + bool draw_call_supported = false; // We can specify our fragment rate on a draw call level. + bool primitive_supported = false; // We can specify our fragment rate on each drawcall. + bool primitive_in_multiviewport = false; + bool ss_image_supported = false; // We can provide a density map attachment on our framebuffer. + uint32_t ss_image_tile_size = 0; + bool additional_rates_supported = false; + }; + + struct ShaderCapabilities { + D3D_SHADER_MODEL shader_model = (D3D_SHADER_MODEL)0; + bool native_16bit_ops = false; + }; + + struct StorageBufferCapabilities { + bool storage_buffer_16_bit_access_is_supported = false; + }; + + struct FormatCapabilities { + bool relaxed_casting_supported = false; + }; + + RenderingContextDriverD3D12 *context_driver = nullptr; + RenderingContextDriver::Device context_device; + ComPtr<IDXGIAdapter> adapter; + DXGI_ADAPTER_DESC adapter_desc; + ComPtr<ID3D12Device> device; + DeviceLimits device_limits; + RDD::Capabilities device_capabilities; + uint32_t feature_level = 0; // Major * 10 + minor. + SubgroupCapabilities subgroup_capabilities; + RDD::MultiviewCapabilities multiview_capabilities; + VRSCapabilities vrs_capabilities; + ShaderCapabilities shader_capabilities; + StorageBufferCapabilities storage_buffer_capabilities; + FormatCapabilities format_capabilities; + String pipeline_cache_id; class DescriptorsHeap { D3D12_DESCRIPTOR_HEAP_DESC desc = {}; @@ -127,6 +174,19 @@ class RenderingDeviceDriverD3D12 : public RenderingDeviceDriver { ComPtr<ID3D12CommandSignature> dispatch; } indirect_cmd_signatures; + static void STDMETHODCALLTYPE _debug_message_func(D3D12_MESSAGE_CATEGORY p_category, D3D12_MESSAGE_SEVERITY p_severity, D3D12_MESSAGE_ID p_id, LPCSTR p_description, void *p_context); + void _set_object_name(ID3D12Object *p_object, String p_object_name); + Error _initialize_device(); + Error _check_capabilities(); + Error _get_device_limits(); + Error _initialize_allocator(); + Error _initialize_frames(uint32_t p_frame_count); + Error _initialize_command_signatures(); + +public: + Error initialize(uint32_t p_device_index, uint32_t p_frame_count) override final; + +private: /****************/ /**** MEMORY ****/ /****************/ @@ -183,7 +243,7 @@ class RenderingDeviceDriverD3D12 : public RenderingDeviceDriver { uint64_t subres_mask[MAX_SUBRESOURCES / 64] = {}; } groups[MAX_GROUPS]; uint8_t groups_count = 0; - static const D3D12_RESOURCE_STATES DELETED_GROUP = D3D12_RESOURCE_STATE_COMMON; + static const D3D12_RESOURCE_STATES DELETED_GROUP = D3D12_RESOURCE_STATES(0xFFFFFFFFU); }; PagedAllocator<HashMapElement<ResourceInfo::States *, BarrierRequest>> res_barriers_requests_allocator; HashMap<ResourceInfo::States *, BarrierRequest, HashMapHasherDefault, HashMapComparatorDefault<ResourceInfo::States *>, decltype(res_barriers_requests_allocator)> res_barriers_requests; @@ -307,13 +367,65 @@ public: VectorView<RDD::BufferBarrier> p_buffer_barriers, VectorView<RDD::TextureBarrier> p_texture_barriers) override final; - /*************************/ - /**** COMMAND BUFFERS ****/ - /*************************/ +private: + /****************/ + /**** FENCES ****/ + /****************/ + + struct FenceInfo { + ComPtr<ID3D12Fence> d3d_fence = nullptr; + HANDLE event_handle = NULL; + UINT64 fence_value = 0; + }; + +public: + virtual FenceID fence_create() override; + virtual Error fence_wait(FenceID p_fence) override; + virtual void fence_free(FenceID p_fence) override; + +private: + /********************/ + /**** SEMAPHORES ****/ + /********************/ + + struct SemaphoreInfo { + ComPtr<ID3D12Fence> d3d_fence = nullptr; + UINT64 fence_value = 0; + }; + + virtual SemaphoreID semaphore_create() override; + virtual void semaphore_free(SemaphoreID p_semaphore) override; + + /******************/ + /**** COMMANDS ****/ + /******************/ + + // ----- QUEUE FAMILY ----- + virtual CommandQueueFamilyID command_queue_family_get(BitField<CommandQueueFamilyBits> p_cmd_queue_family_bits, RenderingContextDriver::SurfaceID p_surface = 0) override; + +private: + // ----- QUEUE ----- + + struct CommandQueueInfo { + ComPtr<ID3D12CommandQueue> d3d_queue; + }; + +public: + virtual CommandQueueID command_queue_create(CommandQueueFamilyID p_cmd_queue_family, bool p_identify_as_main_queue = false) override; + virtual Error command_queue_execute(CommandQueueID p_cmd_queue, VectorView<CommandBufferID> p_cmd_buffers, VectorView<SemaphoreID> p_wait_semaphores, VectorView<SemaphoreID> p_signal_semaphores, FenceID p_signal_fence) override; + virtual Error command_queue_present(CommandQueueID p_cmd_queue, VectorView<SwapChainID> p_swap_chains, VectorView<SemaphoreID> p_wait_semaphores) override; + virtual void command_queue_free(CommandQueueID p_cmd_queue) override; + +private: // ----- POOL ----- + struct CommandPoolInfo { + CommandQueueFamilyID queue_family; + CommandBufferType buffer_type = COMMAND_BUFFER_TYPE_PRIMARY; + }; - virtual CommandPoolID command_pool_create(CommandBufferType p_cmd_buffer_type) override final; +public: + virtual CommandPoolID command_pool_create(CommandQueueFamilyID p_cmd_queue_family, CommandBufferType p_cmd_buffer_type) override final; virtual void command_pool_free(CommandPoolID p_cmd_pool) override final; // ----- BUFFER ----- @@ -347,17 +459,45 @@ private: uint32_t compute_root_signature_crc = 0; RenderPassState render_pass_state; + bool descriptor_heaps_set = false; }; - RBMap<CommandPoolID, LocalVector<CommandBufferInfo *>> pools_command_buffers; - CommandPoolID last_command_pool_id; public: - virtual CommandBufferID command_buffer_create(CommandBufferType p_cmd_buffer_type, CommandPoolID p_cmd_pool) override final; + virtual CommandBufferID command_buffer_create(CommandPoolID p_cmd_pool) override final; virtual bool command_buffer_begin(CommandBufferID p_cmd_buffer) override final; virtual bool command_buffer_begin_secondary(CommandBufferID p_cmd_buffer, RenderPassID p_render_pass, uint32_t p_subpass, FramebufferID p_framebuffer) override final; virtual void command_buffer_end(CommandBufferID p_cmd_buffer) override final; virtual void command_buffer_execute_secondary(CommandBufferID p_cmd_buffer, VectorView<CommandBufferID> p_secondary_cmd_buffers) override final; +private: + /********************/ + /**** SWAP CHAIN ****/ + /********************/ + + struct SwapChain { + ComPtr<IDXGISwapChain3> d3d_swap_chain; + RenderingContextDriver::SurfaceID surface = RenderingContextDriver::SurfaceID(); + UINT present_flags = 0; + UINT sync_interval = 1; + UINT creation_flags = 0; + RenderPassID render_pass; + TightLocalVector<ID3D12Resource *> render_targets; + TightLocalVector<TextureInfo> render_targets_info; + TightLocalVector<FramebufferID> framebuffers; + RDD::DataFormat data_format = DATA_FORMAT_MAX; + }; + + void _swap_chain_release(SwapChain *p_swap_chain); + void _swap_chain_release_buffers(SwapChain *p_swap_chain); + +public: + virtual SwapChainID swap_chain_create(RenderingContextDriver::SurfaceID p_surface) override; + virtual Error swap_chain_resize(CommandQueueID p_cmd_queue, SwapChainID p_swap_chain, uint32_t p_desired_framebuffer_count) override; + virtual FramebufferID swap_chain_acquire_framebuffer(CommandQueueID p_cmd_queue, SwapChainID p_swap_chain, bool &r_resize_required) override; + virtual RenderPassID swap_chain_get_render_pass(SwapChainID p_swap_chain) override; + virtual DataFormat swap_chain_get_format(SwapChainID p_swap_chain) override; + virtual void swap_chain_free(SwapChainID p_swap_chain) override; + /*********************/ /**** FRAMEBUFFER ****/ /*********************/ @@ -376,6 +516,8 @@ private: D3D12_RENDER_TARGET_VIEW_DESC _make_rtv_for_texture(const TextureInfo *p_texture_info, uint32_t p_mipmap_offset, uint32_t p_layer_offset, uint32_t p_layers, bool p_add_bases = true); D3D12_DEPTH_STENCIL_VIEW_DESC _make_dsv_for_texture(const TextureInfo *p_texture_info); + FramebufferID _framebuffer_create(RenderPassID p_render_pass, VectorView<TextureID> p_attachments, uint32_t p_width, uint32_t p_height, bool p_is_screen); + public: virtual FramebufferID framebuffer_create(RenderPassID p_render_pass, VectorView<TextureID> p_attachments, uint32_t p_width, uint32_t p_height) override final; virtual void framebuffer_free(FramebufferID p_framebuffer) override final; @@ -602,6 +744,7 @@ public: virtual void command_uniform_set_prepare_for_use(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) override final; private: + void _command_check_descriptor_sets(CommandBufferID p_cmd_buffer); void _command_bind_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index, bool p_for_compute); public: @@ -777,12 +920,6 @@ public: virtual void command_begin_label(CommandBufferID p_cmd_buffer, const char *p_label_name, const Color &p_color) override final; virtual void command_end_label(CommandBufferID p_cmd_buffer) override final; - /****************/ - /**** SCREEN ****/ - /****************/ - - virtual DataFormat screen_get_format() override final; - /********************/ /**** SUBMISSION ****/ /********************/ @@ -821,7 +958,7 @@ private: bool segment_begun = false; public: - virtual void begin_segment(CommandBufferID p_cmd_buffer, uint32_t p_frame_index, uint32_t p_frames_drawn) override final; + virtual void begin_segment(uint32_t p_frame_index, uint32_t p_frames_drawn) override final; virtual void end_segment() override final; /**************/ @@ -835,6 +972,10 @@ public: virtual uint64_t api_trait_get(ApiTrait p_trait) override final; virtual bool has_feature(Features p_feature) override final; virtual const MultiviewCapabilities &get_multiview_capabilities() override final; + virtual String get_api_name() const override final; + virtual String get_api_version() const override final; + virtual String get_pipeline_cache_uuid() const override final; + virtual const Capabilities &get_capabilities() const override final; private: /*********************/ @@ -858,7 +999,7 @@ private: /******************/ public: - RenderingDeviceDriverD3D12(D3D12Context *p_context, ID3D12Device *p_device, uint32_t p_frame_count); + RenderingDeviceDriverD3D12(RenderingContextDriverD3D12 *p_context_driver); virtual ~RenderingDeviceDriverD3D12(); }; |