diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 9017e805..3c86a5c2 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -101,12 +101,8 @@ add_library(XCEngine STATIC ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12SwapChain.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12Fence.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12Screenshot.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12RenderTargetView.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12DepthStencilView.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12ShaderResourceView.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12ConstantBufferView.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12ResourceView.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12QueryHeap.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12UnorderedAccessView.h ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12Device.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12CommandQueue.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12CommandAllocator.cpp @@ -121,12 +117,8 @@ add_library(XCEngine STATIC ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12SwapChain.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12Fence.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12Screenshot.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12RenderTargetView.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12DepthStencilView.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12ShaderResourceView.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12ConstantBufferView.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12ResourceView.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12QueryHeap.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12UnorderedAccessView.cpp # OpenGL RHI ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/OpenGL/OpenGLBuffer.h @@ -142,6 +134,10 @@ add_library(XCEngine STATIC ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/OpenGL/OpenGLSwapChain.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/OpenGL/OpenGLRenderTargetView.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/OpenGL/OpenGLTextureUnitAllocator.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/OpenGL/OpenGLUniformBufferManager.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/OpenGL/OpenGLFramebuffer.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/OpenGL/OpenGLResourceView.h ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLBuffer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLTexture.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLSampler.cpp @@ -156,6 +152,10 @@ add_library(XCEngine STATIC ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLRenderTargetView.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLDepthStencilView.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLScreenshot.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLTextureUnitAllocator.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLUniformBufferManager.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLFramebuffer.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLResourceView.cpp ${CMAKE_SOURCE_DIR}/tests/opengl/package/src/glad.c # RHI Factory diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12CommandList.h b/engine/include/XCEngine/RHI/D3D12/D3D12CommandList.h index e5cac101..13d20963 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12CommandList.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12CommandList.h @@ -99,6 +99,8 @@ public: void DispatchIndirect(void* argBuffer, uint64_t alignedByteOffset); void DispatchIndirectInternal(ID3D12Resource* argBuffer, uint64_t alignedByteOffset); + void* GetNativeHandle() override { return GetCommandList(); } + void ExecuteBundle(ID3D12GraphicsCommandList* bundle); ResourceStates GetResourceState(ID3D12Resource* resource) const; diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12ConstantBufferView.h b/engine/include/XCEngine/RHI/D3D12/D3D12ConstantBufferView.h deleted file mode 100644 index be626986..00000000 --- a/engine/include/XCEngine/RHI/D3D12/D3D12ConstantBufferView.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include -#include - -using Microsoft::WRL::ComPtr; - -namespace XCEngine { -namespace RHI { - -class D3D12ConstantBufferView { -public: - D3D12ConstantBufferView(); - ~D3D12ConstantBufferView(); - - void Initialize(ID3D12Device* device, ID3D12Resource* buffer, const D3D12_CONSTANT_BUFFER_VIEW_DESC* desc = nullptr); - void Shutdown(); - - D3D12_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandle() const { return m_handle; } - -private: - D3D12_CPU_DESCRIPTOR_HANDLE m_handle; - ID3D12Resource* m_resource; -}; - -} // namespace RHI -} // namespace XCEngine diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12DepthStencilView.h b/engine/include/XCEngine/RHI/D3D12/D3D12DepthStencilView.h deleted file mode 100644 index 74600227..00000000 --- a/engine/include/XCEngine/RHI/D3D12/D3D12DepthStencilView.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include -#include - -#include "../RHIEnums.h" -#include "D3D12Enums.h" - -using Microsoft::WRL::ComPtr; - -namespace XCEngine { -namespace RHI { - -class D3D12DepthStencilView { -public: - D3D12DepthStencilView(); - ~D3D12DepthStencilView(); - - void Initialize(ID3D12Device* device, ID3D12Resource* resource, const D3D12_DEPTH_STENCIL_VIEW_DESC* desc = nullptr); - void InitializeAt(ID3D12Device* device, ID3D12Resource* resource, D3D12_CPU_DESCRIPTOR_HANDLE handle, const D3D12_DEPTH_STENCIL_VIEW_DESC* desc = nullptr); - void Shutdown(); - - D3D12_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandle() const { return m_handle; } - - static D3D12_DEPTH_STENCIL_VIEW_DESC CreateDesc(Format format, D3D12_DSV_DIMENSION dimension = D3D12_DSV_DIMENSION_TEXTURE2D); - -private: - D3D12_CPU_DESCRIPTOR_HANDLE m_handle; - ID3D12Resource* m_resource; -}; - -} // namespace RHI -} // namespace XCEngine diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12Device.h b/engine/include/XCEngine/RHI/D3D12/D3D12Device.h index 5011324d..6f2c9986 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12Device.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12Device.h @@ -29,11 +29,7 @@ class D3D12Texture; class D3D12Buffer; class D3D12SwapChain; class D3D12Shader; -class D3D12RenderTargetView; -class D3D12DepthStencilView; -class D3D12ShaderResourceView; -class D3D12UnorderedAccessView; -class D3D12ConstantBufferView; +class D3D12ResourceView; struct AdapterInfo { std::wstring description; @@ -76,6 +72,11 @@ public: RHIFence* CreateFence(const FenceDesc& desc) override; RHISampler* CreateSampler(const SamplerDesc& desc) override; + RHIResourceView* CreateRenderTargetView(RHITexture* texture, const ResourceViewDesc& desc) override; + RHIResourceView* CreateDepthStencilView(RHITexture* texture, const ResourceViewDesc& desc) override; + RHIResourceView* CreateShaderResourceView(RHITexture* texture, const ResourceViewDesc& desc) override; + RHIResourceView* CreateUnorderedAccessView(RHITexture* texture, const ResourceViewDesc& desc) override; + const RHICapabilities& GetCapabilities() const override; const RHIDeviceInfo& GetDeviceInfo() const override; @@ -89,12 +90,6 @@ public: D3D12QueryHeap* CreateQueryHeap(const QueryHeapDesc& desc); D3D12RootSignature* CreateRootSignature(const RootSignatureDesc& desc); - D3D12RenderTargetView* CreateRenderTargetView(D3D12Buffer* resource, const RenderTargetViewDesc& desc); - D3D12DepthStencilView* CreateDepthStencilView(D3D12Buffer* resource, const DepthStencilViewDesc& desc); - D3D12ShaderResourceView* CreateShaderResourceView(D3D12Buffer* resource, const ShaderResourceViewDesc& desc); - D3D12UnorderedAccessView* CreateUnorderedAccessView(D3D12Buffer* resource, const UnorderedAccessViewDesc& desc); - D3D12ConstantBufferView* CreateConstantBufferView(D3D12Buffer* resource, const ConstantBufferViewDesc& desc); - private: bool CreateDXGIFactory(bool enableDebugLayer); bool CreateDevice(IDXGIAdapter1* adapter); diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12RenderTargetView.h b/engine/include/XCEngine/RHI/D3D12/D3D12RenderTargetView.h deleted file mode 100644 index 3034fe50..00000000 --- a/engine/include/XCEngine/RHI/D3D12/D3D12RenderTargetView.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include -#include - -#include "../RHIEnums.h" -#include "D3D12Enums.h" - -using Microsoft::WRL::ComPtr; - -namespace XCEngine { -namespace RHI { - -class D3D12RenderTargetView { -public: - D3D12RenderTargetView(); - ~D3D12RenderTargetView(); - - void Initialize(ID3D12Device* device, ID3D12Resource* resource, const D3D12_RENDER_TARGET_VIEW_DESC* desc = nullptr); - void InitializeAt(ID3D12Device* device, ID3D12Resource* resource, D3D12_CPU_DESCRIPTOR_HANDLE handle, const D3D12_RENDER_TARGET_VIEW_DESC* desc = nullptr); - void Shutdown(); - - D3D12_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandle() const { return m_handle; } - - static D3D12_RENDER_TARGET_VIEW_DESC CreateDesc(Format format, D3D12_RTV_DIMENSION dimension = D3D12_RTV_DIMENSION_TEXTURE2D); - -private: - D3D12_CPU_DESCRIPTOR_HANDLE m_handle; - ID3D12Resource* m_resource; -}; - -} // namespace RHI -} // namespace XCEngine diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12ResourceView.h b/engine/include/XCEngine/RHI/D3D12/D3D12ResourceView.h new file mode 100644 index 00000000..165b9843 --- /dev/null +++ b/engine/include/XCEngine/RHI/D3D12/D3D12ResourceView.h @@ -0,0 +1,65 @@ +#pragma once + +#include +#include + +#include "../RHIResourceView.h" +#include "../RHIEnums.h" +#include "D3D12Enums.h" + +using Microsoft::WRL::ComPtr; + +namespace XCEngine { +namespace RHI { + +class D3D12DescriptorHeap; + +class D3D12ResourceView : public RHIResourceView { +public: + D3D12ResourceView(); + ~D3D12ResourceView() override; + + void Shutdown() override; + void* GetNativeHandle() override; + bool IsValid() const override; + + void SetViewType(ResourceViewType type) { m_viewType = type; } + ResourceViewType GetViewType() const { return m_viewType; } + + void InitializeAsRenderTarget(ID3D12Device* device, ID3D12Resource* resource, + const D3D12_RENDER_TARGET_VIEW_DESC* desc, + D3D12DescriptorHeap* heap, uint32_t slotIndex); + void InitializeAsDepthStencil(ID3D12Device* device, ID3D12Resource* resource, + const D3D12_DEPTH_STENCIL_VIEW_DESC* desc, + D3D12DescriptorHeap* heap, uint32_t slotIndex); + void InitializeAsShaderResource(ID3D12Device* device, ID3D12Resource* resource, + const D3D12_SHADER_RESOURCE_VIEW_DESC* desc, + D3D12DescriptorHeap* heap, uint32_t slotIndex); + void InitializeAsUnorderedAccess(ID3D12Device* device, ID3D12Resource* resource, + const D3D12_UNORDERED_ACCESS_VIEW_DESC* desc, + D3D12DescriptorHeap* heap, uint32_t slotIndex); + void InitializeAsConstantBuffer(ID3D12Device* device, ID3D12Resource* resource, + const D3D12_CONSTANT_BUFFER_VIEW_DESC* desc, + D3D12DescriptorHeap* heap, uint32_t slotIndex); + + D3D12_CPU_DESCRIPTOR_HANDLE GetCPUHandle() const { return m_handle; } + GPUDescriptorHandle GetGPUHandle() const; + ID3D12Resource* GetResource() const { return m_resource; } + D3D12DescriptorHeap* GetHeap() const { return m_heap; } + uint32_t GetSlotIndex() const { return m_slotIndex; } + + static D3D12_RENDER_TARGET_VIEW_DESC CreateRenderTargetDesc(Format format, D3D12_RTV_DIMENSION dimension); + static D3D12_DEPTH_STENCIL_VIEW_DESC CreateDepthStencilDesc(Format format, D3D12_DSV_DIMENSION dimension); + static D3D12_SHADER_RESOURCE_VIEW_DESC CreateShaderResourceDesc(Format format, D3D12_SRV_DIMENSION dimension, uint32_t mipLevels = 0); + static D3D12_UNORDERED_ACCESS_VIEW_DESC CreateUnorderedAccessDesc(Format format, D3D12_UAV_DIMENSION dimension); + +private: + ResourceViewType m_viewType; + D3D12_CPU_DESCRIPTOR_HANDLE m_handle; + ID3D12Resource* m_resource; + D3D12DescriptorHeap* m_heap; + uint32_t m_slotIndex; +}; + +} // namespace RHI +} // namespace XCEngine \ No newline at end of file diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12ShaderResourceView.h b/engine/include/XCEngine/RHI/D3D12/D3D12ShaderResourceView.h deleted file mode 100644 index d570e5b6..00000000 --- a/engine/include/XCEngine/RHI/D3D12/D3D12ShaderResourceView.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include -#include - -#include "../RHIEnums.h" -#include "D3D12Enums.h" - -using Microsoft::WRL::ComPtr; - -namespace XCEngine { -namespace RHI { - -class D3D12ShaderResourceView { -public: - D3D12ShaderResourceView(); - ~D3D12ShaderResourceView(); - - void Initialize(ID3D12Device* device, ID3D12Resource* resource, const D3D12_SHADER_RESOURCE_VIEW_DESC* desc = nullptr); - void InitializeAt(ID3D12Device* device, ID3D12Resource* resource, D3D12_CPU_DESCRIPTOR_HANDLE handle, const D3D12_SHADER_RESOURCE_VIEW_DESC* desc = nullptr); - void Shutdown(); - - D3D12_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandle() const { return m_handle; } - - static D3D12_SHADER_RESOURCE_VIEW_DESC CreateDesc(Format format, D3D12_SRV_DIMENSION dimension = D3D12_SRV_DIMENSION_TEXTURE2D, uint32_t mipLevels = 1); - -private: - D3D12_CPU_DESCRIPTOR_HANDLE m_handle; - ID3D12Resource* m_resource; -}; - -} // namespace RHI -} // namespace XCEngine diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12UnorderedAccessView.h b/engine/include/XCEngine/RHI/D3D12/D3D12UnorderedAccessView.h deleted file mode 100644 index 475e7677..00000000 --- a/engine/include/XCEngine/RHI/D3D12/D3D12UnorderedAccessView.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include -#include - -using Microsoft::WRL::ComPtr; - -namespace XCEngine { -namespace RHI { - -class D3D12UnorderedAccessView { -public: - D3D12UnorderedAccessView(); - ~D3D12UnorderedAccessView(); - - void Initialize(ID3D12Device* device, ID3D12Resource* resource, const D3D12_UNORDERED_ACCESS_VIEW_DESC* desc = nullptr); - void Shutdown(); - - D3D12_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandle() const { return m_handle; } - -private: - D3D12_CPU_DESCRIPTOR_HANDLE m_handle; - ID3D12Resource* m_resource; -}; - -} // namespace RHI -} // namespace XCEngine diff --git a/engine/include/XCEngine/RHI/OpenGL/OpenGLDevice.h b/engine/include/XCEngine/RHI/OpenGL/OpenGLDevice.h index 719bc647..2bb13c4b 100644 --- a/engine/include/XCEngine/RHI/OpenGL/OpenGLDevice.h +++ b/engine/include/XCEngine/RHI/OpenGL/OpenGLDevice.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include "../RHIDevice.h" @@ -16,6 +17,8 @@ using HWND = HWND__*; using HGLRC = HGLRC__*; class OpenGLSwapChain; +class OpenGLTextureUnitAllocator; +class OpenGLUniformBufferManager; class OpenGLDevice : public RHIDevice { public: @@ -32,6 +35,9 @@ public: HGLRC GetGLContext() const { return m_hglrc; } const RHIDeviceInfo& GetDeviceInfoImpl() const { return m_deviceInfo; } + OpenGLTextureUnitAllocator* GetTextureUnitAllocator() { return m_textureUnitAllocator.get(); } + OpenGLUniformBufferManager* GetUniformBufferManager() { return m_uniformBufferManager.get(); } + void SwapBuffers(); bool PollEvents(); void SetShouldClose(bool shouldClose); @@ -47,6 +53,11 @@ public: RHIFence* CreateFence(const FenceDesc& desc) override; RHISampler* CreateSampler(const SamplerDesc& desc) override; + RHIResourceView* CreateRenderTargetView(RHITexture* texture, const ResourceViewDesc& desc) override; + RHIResourceView* CreateDepthStencilView(RHITexture* texture, const ResourceViewDesc& desc) override; + RHIResourceView* CreateShaderResourceView(RHITexture* texture, const ResourceViewDesc& desc) override; + RHIResourceView* CreateUnorderedAccessView(RHITexture* texture, const ResourceViewDesc& desc) override; + const RHICapabilities& GetCapabilities() const override; const RHIDeviceInfo& GetDeviceInfo() const override; @@ -64,6 +75,9 @@ private: bool m_initialized = false; bool m_ownsWindow = false; bool m_shouldClose = false; + + std::unique_ptr m_textureUnitAllocator; + std::unique_ptr m_uniformBufferManager; }; } // namespace RHI diff --git a/engine/include/XCEngine/RHI/OpenGL/OpenGLFramebuffer.h b/engine/include/XCEngine/RHI/OpenGL/OpenGLFramebuffer.h new file mode 100644 index 00000000..27dc98b5 --- /dev/null +++ b/engine/include/XCEngine/RHI/OpenGL/OpenGLFramebuffer.h @@ -0,0 +1,66 @@ +#pragma once + +#include +#include + +namespace XCEngine { +namespace RHI { + +enum class FramebufferAttachmentType { + Color, + Depth, + DepthStencil, + Stencil +}; + +struct FramebufferAttachment { + unsigned int texture = 0; + int mipLevel = 0; + int layer = 0; + FramebufferAttachmentType type = FramebufferAttachmentType::Color; + uint32_t format = 0; +}; + +struct FramebufferDesc { + int width = 0; + int height = 0; + int samples = 1; + std::vector colorAttachments; + FramebufferAttachment depthAttachment; + FramebufferAttachment stencilAttachment; +}; + +class OpenGLFramebuffer { +public: + OpenGLFramebuffer(); + ~OpenGLFramebuffer(); + + bool Initialize(const FramebufferDesc& desc); + void Shutdown(); + + void Bind(); + void Unbind(); + + void ClearColor(int attachmentIndex, float r, float g, float b, float a); + void ClearDepth(float depth); + void ClearStencil(uint8_t stencil); + void ClearDepthStencil(float depth, uint8_t stencil); + + unsigned int GetFramebuffer() const { return m_framebuffer; } + int GetWidth() const { return m_width; } + int GetHeight() const { return m_height; } + bool IsValid() const { return m_framebuffer != 0; } + + static void BindFramebuffer(unsigned int framebuffer); + static void UnbindFramebuffer(); + +private: + unsigned int m_framebuffer; + int m_width; + int m_height; + int m_samples; + FramebufferDesc m_desc; +}; + +} // namespace RHI +} // namespace XCEngine \ No newline at end of file diff --git a/engine/include/XCEngine/RHI/OpenGL/OpenGLResourceView.h b/engine/include/XCEngine/RHI/OpenGL/OpenGLResourceView.h new file mode 100644 index 00000000..154f0f42 --- /dev/null +++ b/engine/include/XCEngine/RHI/OpenGL/OpenGLResourceView.h @@ -0,0 +1,69 @@ +#pragma once + +#include "XCEngine/RHI/RHIResourceView.h" +#include "XCEngine/RHI/RHITypes.h" + +namespace XCEngine { +namespace RHI { + +class OpenGLTexture; +class OpenGLBuffer; +class OpenGLFramebuffer; +class OpenGLTextureUnitAllocator; +class OpenGLUniformBufferManager; + +class OpenGLResourceView : public RHIResourceView { +public: + OpenGLResourceView(); + ~OpenGLResourceView() override; + + void Shutdown() override; + void* GetNativeHandle() override; + bool IsValid() const override; + + bool InitializeAsRenderTarget( + OpenGLTexture* texture, + const ResourceViewDesc& desc, + OpenGLFramebuffer* framebuffer); + + bool InitializeAsDepthStencil( + OpenGLTexture* texture, + const ResourceViewDesc& desc, + OpenGLFramebuffer* framebuffer); + + bool InitializeAsShaderResource( + OpenGLTexture* texture, + const ResourceViewDesc& desc, + OpenGLTextureUnitAllocator* allocator); + + bool InitializeAsUnorderedAccess( + OpenGLTexture* texture, + const ResourceViewDesc& desc, + OpenGLTextureUnitAllocator* allocator); + + bool InitializeAsConstantBuffer( + OpenGLBuffer* buffer, + const ResourceViewDesc& desc, + OpenGLUniformBufferManager* manager); + + ResourceViewType GetViewType() const { return m_viewType; } + unsigned int GetFramebuffer() const; + int32_t GetTextureUnit() const { return m_textureUnit; } + int32_t GetBindingPoint() const { return m_bindingPoint; } + unsigned int GetTexture() const; + unsigned int GetBuffer() const; + +private: + ResourceViewType m_viewType; + unsigned int m_framebufferID; + int32_t m_textureUnit; + int32_t m_bindingPoint; + OpenGLTexture* m_texture; + OpenGLBuffer* m_buffer; + OpenGLFramebuffer* m_framebuffer; + OpenGLTextureUnitAllocator* m_textureUnitAllocator; + OpenGLUniformBufferManager* m_uniformBufferManager; +}; + +} // namespace RHI +} // namespace XCEngine \ No newline at end of file diff --git a/engine/include/XCEngine/RHI/OpenGL/OpenGLTextureUnitAllocator.h b/engine/include/XCEngine/RHI/OpenGL/OpenGLTextureUnitAllocator.h new file mode 100644 index 00000000..989786ea --- /dev/null +++ b/engine/include/XCEngine/RHI/OpenGL/OpenGLTextureUnitAllocator.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include + +namespace XCEngine { +namespace RHI { + +class OpenGLTexture; + +class OpenGLTextureUnitAllocator { +public: + OpenGLTextureUnitAllocator(); + ~OpenGLTextureUnitAllocator(); + + void Initialize(uint32_t maxUnits = 16); + void Shutdown(); + + int32_t Allocate(); + void Free(int32_t unit); + + void BindTexture(int32_t unit, OpenGLTexture* texture); + void UnbindTexture(int32_t unit); + + OpenGLTexture* GetBoundTexture(int32_t unit) const; + bool IsAllocated(int32_t unit) const; + uint32_t GetMaxUnits() const { return m_maxUnits; } + +private: + uint32_t m_maxUnits; + std::vector m_allocated; + std::vector m_boundTextures; +}; + +} // namespace RHI +} // namespace XCEngine \ No newline at end of file diff --git a/engine/include/XCEngine/RHI/OpenGL/OpenGLUniformBufferManager.h b/engine/include/XCEngine/RHI/OpenGL/OpenGLUniformBufferManager.h new file mode 100644 index 00000000..1f42f116 --- /dev/null +++ b/engine/include/XCEngine/RHI/OpenGL/OpenGLUniformBufferManager.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include + +namespace XCEngine { +namespace RHI { + +class OpenGLBuffer; + +class OpenGLUniformBufferManager { +public: + OpenGLUniformBufferManager(); + ~OpenGLUniformBufferManager(); + + void Initialize(uint32_t maxBindingPoints = 16); + void Shutdown(); + + int32_t Allocate(); + void Free(int32_t bindingPoint); + + void BindBuffer(int32_t bindingPoint, OpenGLBuffer* buffer, uint32_t offset = 0, uint32_t size = 0); + void UnbindBuffer(int32_t bindingPoint); + + OpenGLBuffer* GetBoundBuffer(int32_t bindingPoint) const; + bool IsAllocated(int32_t bindingPoint) const; + uint32_t GetMaxBindingPoints() const { return m_maxBindingPoints; } + +private: + uint32_t m_maxBindingPoints; + std::vector m_allocated; + std::vector m_boundBuffers; +}; + +} // namespace RHI +} // namespace XCEngine \ No newline at end of file diff --git a/engine/include/XCEngine/RHI/RHICommandList.h b/engine/include/XCEngine/RHI/RHICommandList.h index d3c3533f..c3e94145 100644 --- a/engine/include/XCEngine/RHI/RHICommandList.h +++ b/engine/include/XCEngine/RHI/RHICommandList.h @@ -78,6 +78,8 @@ public: virtual void CopyResource(void* dst, void* src) = 0; virtual void Dispatch(uint32_t x, uint32_t y, uint32_t z) = 0; + + virtual void* GetNativeHandle() { return nullptr; } }; } // namespace RHI diff --git a/engine/include/XCEngine/RHI/RHIDevice.h b/engine/include/XCEngine/RHI/RHIDevice.h index 6de2c681..a9be6cb7 100644 --- a/engine/include/XCEngine/RHI/RHIDevice.h +++ b/engine/include/XCEngine/RHI/RHIDevice.h @@ -16,6 +16,7 @@ class RHIShader; class RHIPipelineState; class RHIFence; class RHISampler; +class RHIResourceView; class RHIDevice { public: @@ -34,6 +35,11 @@ public: virtual RHIFence* CreateFence(const FenceDesc& desc) = 0; virtual RHISampler* CreateSampler(const SamplerDesc& desc) = 0; + virtual RHIResourceView* CreateRenderTargetView(RHITexture* texture, const ResourceViewDesc& desc) = 0; + virtual RHIResourceView* CreateDepthStencilView(RHITexture* texture, const ResourceViewDesc& desc) = 0; + virtual RHIResourceView* CreateShaderResourceView(RHITexture* texture, const ResourceViewDesc& desc) = 0; + virtual RHIResourceView* CreateUnorderedAccessView(RHITexture* texture, const ResourceViewDesc& desc) = 0; + virtual const RHICapabilities& GetCapabilities() const = 0; virtual const RHIDeviceInfo& GetDeviceInfo() const = 0; diff --git a/engine/include/XCEngine/RHI/RHIEnums.h b/engine/include/XCEngine/RHI/RHIEnums.h index 91a58750..26727a9e 100644 --- a/engine/include/XCEngine/RHI/RHIEnums.h +++ b/engine/include/XCEngine/RHI/RHIEnums.h @@ -241,6 +241,31 @@ enum class DescriptorHeapType : uint8_t { DSV }; +enum class ResourceViewDimension : uint8_t { + Unknown, + Texture1D, + Texture1DArray, + Texture2D, + Texture2DArray, + Texture2DMS, + Texture2DMSArray, + Texture3D, + TextureCube, + TextureCubeArray, + Buffer, + StructuredBuffer, + RawBuffer +}; + +enum class ResourceViewType : uint8_t { + RenderTarget, + DepthStencil, + ShaderResource, + UnorderedAccess, + ConstantBuffer, + Sampler +}; + enum class QueryType : uint8_t { Occlusion, Timestamp, diff --git a/engine/include/XCEngine/RHI/RHIResourceView.h b/engine/include/XCEngine/RHI/RHIResourceView.h new file mode 100644 index 00000000..967440ec --- /dev/null +++ b/engine/include/XCEngine/RHI/RHIResourceView.h @@ -0,0 +1,21 @@ +#pragma once + +#include "RHIEnums.h" +#include "RHITypes.h" + +namespace XCEngine { +namespace RHI { + +class RHIResourceView { +public: + virtual ~RHIResourceView() = default; + + virtual void Shutdown() = 0; + + virtual void* GetNativeHandle() = 0; + + virtual bool IsValid() const = 0; +}; + +} // namespace RHI +} // namespace XCEngine \ No newline at end of file diff --git a/engine/include/XCEngine/RHI/RHITypes.h b/engine/include/XCEngine/RHI/RHITypes.h index 483cfad8..c40cf826 100644 --- a/engine/include/XCEngine/RHI/RHITypes.h +++ b/engine/include/XCEngine/RHI/RHITypes.h @@ -1,5 +1,7 @@ #pragma once +#include "RHIEnums.h" + #include #include #include @@ -135,6 +137,7 @@ struct DescriptorHeapDesc { uint32_t heapType; uint32_t flags; uint32_t nodeMask; + bool shaderVisible = false; }; struct CommandQueueDesc { @@ -289,5 +292,16 @@ struct RHIPipelineLayoutDesc { uint32_t uavCount = 0; }; +struct ResourceViewDesc { + uint32_t format = 0; + ResourceViewDimension dimension = ResourceViewDimension::Unknown; + uint32_t mipLevel = 0; + uint32_t arraySize = 0; + uint32_t firstArraySlice = 0; + uint32_t planeSlice = 0; + uint64_t bufferLocation = 0; + uint32_t structureByteStride = 0; +}; + } // namespace RHI } // namespace XCEngine diff --git a/engine/src/RHI/D3D12/D3D12CommandQueue.cpp b/engine/src/RHI/D3D12/D3D12CommandQueue.cpp index b31c4770..7c5a43ce 100644 --- a/engine/src/RHI/D3D12/D3D12CommandQueue.cpp +++ b/engine/src/RHI/D3D12/D3D12CommandQueue.cpp @@ -59,7 +59,8 @@ void D3D12CommandQueue::ExecuteCommandLists(uint32_t count, void** lists) { std::vector cmdLists(count); for (uint32_t i = 0; i < count; ++i) { if (lists[i]) { - cmdLists[i] = static_cast(lists[i]); + RHICommandList* cmdList = static_cast(lists[i]); + cmdLists[i] = static_cast(cmdList->GetNativeHandle()); } } diff --git a/engine/src/RHI/D3D12/D3D12Device.cpp b/engine/src/RHI/D3D12/D3D12Device.cpp index 6832dd57..532e523f 100644 --- a/engine/src/RHI/D3D12/D3D12Device.cpp +++ b/engine/src/RHI/D3D12/D3D12Device.cpp @@ -12,11 +12,7 @@ #include "XCEngine/RHI/D3D12/D3D12Buffer.h" #include "XCEngine/RHI/D3D12/D3D12SwapChain.h" #include "XCEngine/RHI/D3D12/D3D12Shader.h" -#include "XCEngine/RHI/D3D12/D3D12RenderTargetView.h" -#include "XCEngine/RHI/D3D12/D3D12DepthStencilView.h" -#include "XCEngine/RHI/D3D12/D3D12ShaderResourceView.h" -#include "XCEngine/RHI/D3D12/D3D12UnorderedAccessView.h" -#include "XCEngine/RHI/D3D12/D3D12ConstantBufferView.h" +#include "XCEngine/RHI/D3D12/D3D12ResourceView.h" #include #ifdef _DEBUG @@ -376,6 +372,109 @@ RHIPipelineState* D3D12Device::CreatePipelineState(const PipelineStateDesc& desc return nullptr; } +RHIResourceView* D3D12Device::CreateRenderTargetView(RHITexture* texture, const ResourceViewDesc& desc) { + auto* view = new D3D12ResourceView(); + auto* d3d12Texture = static_cast(texture); + ID3D12Resource* resource = d3d12Texture->GetResource(); + + D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = {}; + rtvDesc.Format = static_cast(desc.format); + rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + + DescriptorHeapDesc heapDesc = {}; + heapDesc.descriptorCount = 1; + heapDesc.heapType = static_cast(DescriptorHeapType::RTV); + heapDesc.shaderVisible = false; + auto* heapPool = CreateDescriptorHeap(heapDesc); + auto* heap = static_cast(heapPool); + + view->InitializeAsRenderTarget(m_device.Get(), resource, &rtvDesc, heap, 0); + return view; +} + +RHIResourceView* D3D12Device::CreateDepthStencilView(RHITexture* texture, const ResourceViewDesc& desc) { + auto* view = new D3D12ResourceView(); + auto* d3d12Texture = static_cast(texture); + ID3D12Resource* resource = d3d12Texture->GetResource(); + + D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = {}; + dsvDesc.Format = static_cast(desc.format); + dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; + + DescriptorHeapDesc heapDesc = {}; + heapDesc.descriptorCount = 1; + heapDesc.heapType = static_cast(DescriptorHeapType::DSV); + heapDesc.shaderVisible = false; + auto* heapPool = CreateDescriptorHeap(heapDesc); + auto* heap = static_cast(heapPool); + + view->InitializeAsDepthStencil(m_device.Get(), resource, &dsvDesc, heap, 0); + return view; +} + +RHIResourceView* D3D12Device::CreateShaderResourceView(RHITexture* texture, const ResourceViewDesc& desc) { + auto* view = new D3D12ResourceView(); + auto* d3d12Texture = static_cast(texture); + ID3D12Resource* resource = d3d12Texture->GetResource(); + + D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; + srvDesc.Format = static_cast(desc.format); + srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MipLevels = desc.mipLevel > 0 ? desc.mipLevel : 1; + srvDesc.Texture2D.MostDetailedMip = 0; + srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + + DescriptorHeapDesc heapDesc = {}; + heapDesc.descriptorCount = 1; + heapDesc.heapType = static_cast(DescriptorHeapType::CBV_SRV_UAV); + heapDesc.shaderVisible = true; + auto* heapPool = CreateDescriptorHeap(heapDesc); + auto* heap = static_cast(heapPool); + + view->InitializeAsShaderResource(m_device.Get(), resource, &srvDesc, heap, 0); + return view; +} + +RHIResourceView* D3D12Device::CreateUnorderedAccessView(RHITexture* texture, const ResourceViewDesc& desc) { + auto* view = new D3D12ResourceView(); + auto* d3d12Texture = static_cast(texture); + ID3D12Resource* resource = d3d12Texture->GetResource(); + + D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {}; + uavDesc.Format = static_cast(desc.format); + uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D; + + DescriptorHeapDesc heapDesc = {}; + heapDesc.descriptorCount = 1; + heapDesc.heapType = static_cast(DescriptorHeapType::CBV_SRV_UAV); + heapDesc.shaderVisible = true; + auto* heapPool = CreateDescriptorHeap(heapDesc); + auto* heap = static_cast(heapPool); + + view->InitializeAsUnorderedAccess(m_device.Get(), resource, &uavDesc, heap, 0); + return view; +} + +D3D12DescriptorHeap* D3D12Device::CreateDescriptorHeap(const DescriptorHeapDesc& desc) { + auto* heap = new D3D12DescriptorHeap(); + if (!heap->Initialize(m_device.Get(), + static_cast(desc.heapType), + desc.descriptorCount, + desc.shaderVisible)) { + delete heap; + return nullptr; + } + return heap; +} + +D3D12QueryHeap* D3D12Device::CreateQueryHeap(const QueryHeapDesc& desc) { + return nullptr; +} + +D3D12RootSignature* D3D12Device::CreateRootSignature(const RootSignatureDesc& desc) { + return nullptr; +} + D3D12CommandQueue* D3D12Device::CreateCommandQueueImpl(const CommandQueueDesc& desc) { return nullptr; } diff --git a/engine/src/RHI/D3D12/D3D12ResourceView.cpp b/engine/src/RHI/D3D12/D3D12ResourceView.cpp new file mode 100644 index 00000000..d7c41def --- /dev/null +++ b/engine/src/RHI/D3D12/D3D12ResourceView.cpp @@ -0,0 +1,143 @@ +#include "XCEngine/RHI/D3D12/D3D12ResourceView.h" +#include "XCEngine/RHI/D3D12/D3D12DescriptorHeap.h" + +namespace XCEngine { +namespace RHI { + +D3D12ResourceView::D3D12ResourceView() + : m_viewType(ResourceViewType::ShaderResource) + , m_handle({0}) + , m_resource(nullptr) + , m_heap(nullptr) + , m_slotIndex(0) { +} + +D3D12ResourceView::~D3D12ResourceView() { + Shutdown(); +} + +void D3D12ResourceView::Shutdown() { + m_handle = {}; + m_resource = nullptr; + m_heap = nullptr; + m_slotIndex = 0; +} + +void* D3D12ResourceView::GetNativeHandle() { + return this; +} + +bool D3D12ResourceView::IsValid() const { + return m_handle.ptr != 0 && m_resource != nullptr; +} + +void D3D12ResourceView::InitializeAsRenderTarget(ID3D12Device* device, ID3D12Resource* resource, + const D3D12_RENDER_TARGET_VIEW_DESC* desc, + D3D12DescriptorHeap* heap, uint32_t slotIndex) { + m_viewType = ResourceViewType::RenderTarget; + m_resource = resource; + m_heap = heap; + m_slotIndex = slotIndex; + + m_handle = heap->GetCPUDescriptorHandleForHeapStart(); + m_handle.ptr += slotIndex * heap->GetDescriptorSize(); + device->CreateRenderTargetView(resource, desc, m_handle); +} + +void D3D12ResourceView::InitializeAsDepthStencil(ID3D12Device* device, ID3D12Resource* resource, + const D3D12_DEPTH_STENCIL_VIEW_DESC* desc, + D3D12DescriptorHeap* heap, uint32_t slotIndex) { + m_viewType = ResourceViewType::DepthStencil; + m_resource = resource; + m_heap = heap; + m_slotIndex = slotIndex; + + m_handle = heap->GetCPUDescriptorHandleForHeapStart(); + m_handle.ptr += slotIndex * heap->GetDescriptorSize(); + device->CreateDepthStencilView(resource, desc, m_handle); +} + +void D3D12ResourceView::InitializeAsShaderResource(ID3D12Device* device, ID3D12Resource* resource, + const D3D12_SHADER_RESOURCE_VIEW_DESC* desc, + D3D12DescriptorHeap* heap, uint32_t slotIndex) { + m_viewType = ResourceViewType::ShaderResource; + m_resource = resource; + m_heap = heap; + m_slotIndex = slotIndex; + + m_handle = heap->GetCPUDescriptorHandleForHeapStart(); + m_handle.ptr += slotIndex * heap->GetDescriptorSize(); + device->CreateShaderResourceView(resource, desc, m_handle); +} + +void D3D12ResourceView::InitializeAsUnorderedAccess(ID3D12Device* device, ID3D12Resource* resource, + const D3D12_UNORDERED_ACCESS_VIEW_DESC* desc, + D3D12DescriptorHeap* heap, uint32_t slotIndex) { + m_viewType = ResourceViewType::UnorderedAccess; + m_resource = resource; + m_heap = heap; + m_slotIndex = slotIndex; + + m_handle = heap->GetCPUDescriptorHandleForHeapStart(); + m_handle.ptr += slotIndex * heap->GetDescriptorSize(); + device->CreateUnorderedAccessView(resource, nullptr, desc, m_handle); +} + +void D3D12ResourceView::InitializeAsConstantBuffer(ID3D12Device* device, ID3D12Resource* resource, + const D3D12_CONSTANT_BUFFER_VIEW_DESC* desc, + D3D12DescriptorHeap* heap, uint32_t slotIndex) { + m_viewType = ResourceViewType::ConstantBuffer; + m_resource = resource; + m_heap = heap; + m_slotIndex = slotIndex; + + m_handle = heap->GetCPUDescriptorHandleForHeapStart(); + m_handle.ptr += slotIndex * heap->GetDescriptorSize(); + device->CreateConstantBufferView(desc, m_handle); +} + +GPUDescriptorHandle D3D12ResourceView::GetGPUHandle() const { + if (m_heap) { + return m_heap->GetGPUDescriptorHandle(m_slotIndex); + } + return {}; +} + +D3D12_RENDER_TARGET_VIEW_DESC D3D12ResourceView::CreateRenderTargetDesc(Format format, D3D12_RTV_DIMENSION dimension) { + D3D12_RENDER_TARGET_VIEW_DESC desc = {}; + desc.Format = ToD3D12(format); + desc.ViewDimension = dimension; + return desc; +} + +D3D12_DEPTH_STENCIL_VIEW_DESC D3D12ResourceView::CreateDepthStencilDesc(Format format, D3D12_DSV_DIMENSION dimension) { + D3D12_DEPTH_STENCIL_VIEW_DESC desc = {}; + desc.Format = ToD3D12(format); + desc.ViewDimension = dimension; + return desc; +} + +D3D12_SHADER_RESOURCE_VIEW_DESC D3D12ResourceView::CreateShaderResourceDesc(Format format, D3D12_SRV_DIMENSION dimension, uint32_t mipLevels) { + D3D12_SHADER_RESOURCE_VIEW_DESC desc = {}; + desc.Format = ToD3D12(format); + desc.ViewDimension = dimension; + if (mipLevels == 0) { + desc.Texture2D.MostDetailedMip = 0; + desc.Texture2D.MipLevels = 1; + } else { + desc.Texture2D.MostDetailedMip = 0; + desc.Texture2D.MipLevels = mipLevels; + } + desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + return desc; +} + +D3D12_UNORDERED_ACCESS_VIEW_DESC D3D12ResourceView::CreateUnorderedAccessDesc(Format format, D3D12_UAV_DIMENSION dimension) { + D3D12_UNORDERED_ACCESS_VIEW_DESC desc = {}; + desc.Format = ToD3D12(format); + desc.ViewDimension = dimension; + return desc; +} + +} // namespace RHI +} // namespace XCEngine \ No newline at end of file diff --git a/engine/src/RHI/OpenGL/OpenGLDevice.cpp b/engine/src/RHI/OpenGL/OpenGLDevice.cpp index 79de9d4d..92d850ac 100644 --- a/engine/src/RHI/OpenGL/OpenGLDevice.cpp +++ b/engine/src/RHI/OpenGL/OpenGLDevice.cpp @@ -14,6 +14,10 @@ #include "XCEngine/RHI/OpenGL/OpenGLCommandList.h" #include "XCEngine/RHI/OpenGL/OpenGLCommandQueue.h" #include "XCEngine/RHI/OpenGL/OpenGLSwapChain.h" +#include "XCEngine/RHI/OpenGL/OpenGLTextureUnitAllocator.h" +#include "XCEngine/RHI/OpenGL/OpenGLUniformBufferManager.h" +#include "XCEngine/RHI/OpenGL/OpenGLFramebuffer.h" +#include "XCEngine/RHI/OpenGL/OpenGLResourceView.h" #include "XCEngine/Debug/Logger.h" static bool s_windowClassRegistered = false; @@ -44,6 +48,8 @@ OpenGLDevice::OpenGLDevice() , m_initialized(false) , m_ownsWindow(false) , m_shouldClose(false) { + m_textureUnitAllocator = std::make_unique(); + m_uniformBufferManager = std::make_unique(); } OpenGLDevice::~OpenGLDevice() { @@ -229,6 +235,14 @@ bool OpenGLDevice::InitializeWithExistingWindow(HWND hwnd) { GLint maxAttribs = 0; glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttribs); m_capabilities.maxVertexAttribs = static_cast(maxAttribs); + + GLint maxTextureUnits = 0; + glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits); + m_textureUnitAllocator->Initialize(static_cast(maxTextureUnits)); + + GLint maxUniformBlocks = 0; + glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &maxUniformBlocks); + m_uniformBufferManager->Initialize(static_cast(maxUniformBlocks)); m_initialized = true; return true; @@ -297,6 +311,13 @@ void OpenGLDevice::Shutdown() { m_hwnd = nullptr; } + if (m_uniformBufferManager) { + m_uniformBufferManager->Shutdown(); + } + if (m_textureUnitAllocator) { + m_textureUnitAllocator->Shutdown(); + } + m_initialized = false; m_ownsWindow = false; m_shouldClose = false; @@ -441,6 +462,106 @@ RHISampler* OpenGLDevice::CreateSampler(const SamplerDesc& desc) { return sampler; } +RHIResourceView* OpenGLDevice::CreateRenderTargetView(RHITexture* texture, const ResourceViewDesc& desc) { + if (!texture) { + return nullptr; + } + + auto* glTexture = static_cast(texture); + + FramebufferDesc fbDesc = {}; + fbDesc.width = static_cast(texture->GetWidth()); + fbDesc.height = static_cast(texture->GetHeight()); + + FramebufferAttachment colorAttachment = {}; + colorAttachment.texture = glTexture->GetID(); + colorAttachment.mipLevel = static_cast(desc.mipLevel); + colorAttachment.type = FramebufferAttachmentType::Color; + colorAttachment.format = desc.format; + fbDesc.colorAttachments.push_back(colorAttachment); + + auto* framebuffer = new OpenGLFramebuffer(); + if (!framebuffer->Initialize(fbDesc)) { + delete framebuffer; + return nullptr; + } + + auto* view = new OpenGLResourceView(); + if (!view->InitializeAsRenderTarget(glTexture, desc, framebuffer)) { + delete framebuffer; + delete view; + return nullptr; + } + + return view; +} + +RHIResourceView* OpenGLDevice::CreateDepthStencilView(RHITexture* texture, const ResourceViewDesc& desc) { + if (!texture) { + return nullptr; + } + + auto* glTexture = static_cast(texture); + + FramebufferDesc fbDesc = {}; + fbDesc.width = static_cast(texture->GetWidth()); + fbDesc.height = static_cast(texture->GetHeight()); + + FramebufferAttachment depthAttachment = {}; + depthAttachment.texture = glTexture->GetID(); + depthAttachment.mipLevel = static_cast(desc.mipLevel); + depthAttachment.type = FramebufferAttachmentType::DepthStencil; + depthAttachment.format = desc.format; + fbDesc.depthAttachment = depthAttachment; + + auto* framebuffer = new OpenGLFramebuffer(); + if (!framebuffer->Initialize(fbDesc)) { + delete framebuffer; + return nullptr; + } + + auto* view = new OpenGLResourceView(); + if (!view->InitializeAsDepthStencil(glTexture, desc, framebuffer)) { + delete framebuffer; + delete view; + return nullptr; + } + + return view; +} + +RHIResourceView* OpenGLDevice::CreateShaderResourceView(RHITexture* texture, const ResourceViewDesc& desc) { + if (!texture) { + return nullptr; + } + + auto* glTexture = static_cast(texture); + auto* view = new OpenGLResourceView(); + + if (!view->InitializeAsShaderResource(glTexture, desc, m_textureUnitAllocator.get())) { + delete view; + return nullptr; + } + + return view; +} + +RHIResourceView* OpenGLDevice::CreateUnorderedAccessView(RHITexture* texture, const ResourceViewDesc& desc) { + if (!texture) { + return nullptr; + } + + auto* glTexture = static_cast(texture); + auto* view = new OpenGLResourceView(); + + if (!view->InitializeAsUnorderedAccess(glTexture, desc, m_textureUnitAllocator.get())) { + delete view; + return nullptr; + } + + return view; +} + const RHICapabilities& OpenGLDevice::GetCapabilities() const { return m_capabilities; } diff --git a/engine/src/RHI/OpenGL/OpenGLFramebuffer.cpp b/engine/src/RHI/OpenGL/OpenGLFramebuffer.cpp new file mode 100644 index 00000000..d917ef38 --- /dev/null +++ b/engine/src/RHI/OpenGL/OpenGLFramebuffer.cpp @@ -0,0 +1,141 @@ +#include "XCEngine/RHI/OpenGL/OpenGLFramebuffer.h" +#include + +namespace XCEngine { +namespace RHI { + +OpenGLFramebuffer::OpenGLFramebuffer() + : m_framebuffer(0) + , m_width(0) + , m_height(0) + , m_samples(1) { +} + +OpenGLFramebuffer::~OpenGLFramebuffer() { + Shutdown(); +} + +bool OpenGLFramebuffer::Initialize(const FramebufferDesc& desc) { + m_width = desc.width; + m_height = desc.height; + m_samples = desc.samples; + m_desc = desc; + + glGenFramebuffers(1, &m_framebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); + + GLenum drawBuffers[16] = { GL_NONE }; + int drawBufferCount = 0; + + for (size_t i = 0; i < desc.colorAttachments.size() && i < 16; ++i) { + const auto& attachment = desc.colorAttachments[i]; + GLenum glAttachment = GL_COLOR_ATTACHMENT0 + static_cast(i); + + switch (attachment.type) { + case FramebufferAttachmentType::Color: + if (attachment.layer == 0 && attachment.mipLevel == 0) { + glFramebufferTexture2D(GL_FRAMEBUFFER, glAttachment, GL_TEXTURE_2D, attachment.texture, 0); + } else if (attachment.layer > 0) { + glFramebufferTextureLayer(GL_FRAMEBUFFER, glAttachment, attachment.texture, attachment.mipLevel, attachment.layer); + } else { + glFramebufferTexture(GL_FRAMEBUFFER, glAttachment, attachment.texture, attachment.mipLevel); + } + break; + } + drawBuffers[drawBufferCount++] = glAttachment; + } + + if (desc.depthAttachment.texture != 0) { + GLenum depthAttachment = GL_DEPTH_ATTACHMENT; + if (desc.stencilAttachment.texture != 0) { + depthAttachment = GL_DEPTH_STENCIL_ATTACHMENT; + } + + if (desc.depthAttachment.layer == 0 && desc.depthAttachment.mipLevel == 0) { + glFramebufferTexture2D(GL_FRAMEBUFFER, depthAttachment, GL_TEXTURE_2D, desc.depthAttachment.texture, 0); + } else if (desc.depthAttachment.layer > 0) { + glFramebufferTextureLayer(GL_FRAMEBUFFER, depthAttachment, desc.depthAttachment.texture, desc.depthAttachment.mipLevel, desc.depthAttachment.layer); + } else { + glFramebufferTexture(GL_FRAMEBUFFER, depthAttachment, desc.depthAttachment.texture, desc.depthAttachment.mipLevel); + } + } + + if (desc.stencilAttachment.texture != 0 && desc.stencilAttachment.texture != desc.depthAttachment.texture) { + if (desc.stencilAttachment.layer == 0 && desc.stencilAttachment.mipLevel == 0) { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, desc.stencilAttachment.texture, 0); + } else if (desc.stencilAttachment.layer > 0) { + glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, desc.stencilAttachment.texture, desc.stencilAttachment.mipLevel, desc.stencilAttachment.layer); + } else { + glFramebufferTexture(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, desc.stencilAttachment.texture, desc.stencilAttachment.mipLevel); + } + } + + if (drawBufferCount > 0) { + glDrawBuffers(drawBufferCount, drawBuffers); + } else { + glDrawBuffer(GL_NONE); + glReadBuffer(GL_NONE); + } + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + return false; + } + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + return true; +} + +void OpenGLFramebuffer::Shutdown() { + if (m_framebuffer) { + glDeleteFramebuffers(1, &m_framebuffer); + m_framebuffer = 0; + } + m_width = 0; + m_height = 0; + m_samples = 1; +} + +void OpenGLFramebuffer::Bind() { + glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); +} + +void OpenGLFramebuffer::Unbind() { + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + +void OpenGLFramebuffer::ClearColor(int attachmentIndex, float r, float g, float b, float a) { + glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); + glClearBufferfv(GL_COLOR, attachmentIndex, &r); +} + +void OpenGLFramebuffer::ClearDepth(float depth) { + glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); + glClearDepth(depth); + glClear(GL_DEPTH_BUFFER_BIT); +} + +void OpenGLFramebuffer::ClearStencil(uint8_t stencil) { + glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); + glClearStencil(stencil); + glClear(GL_STENCIL_BUFFER_BIT); +} + +void OpenGLFramebuffer::ClearDepthStencil(float depth, uint8_t stencil) { + glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); + glClearDepth(depth); + glClearStencil(stencil); + glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); +} + +void OpenGLFramebuffer::BindFramebuffer(unsigned int framebuffer) { + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); +} + +void OpenGLFramebuffer::UnbindFramebuffer() { + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + +} // namespace RHI +} // namespace XCEngine \ No newline at end of file diff --git a/engine/src/RHI/OpenGL/OpenGLResourceView.cpp b/engine/src/RHI/OpenGL/OpenGLResourceView.cpp new file mode 100644 index 00000000..7c679b7c --- /dev/null +++ b/engine/src/RHI/OpenGL/OpenGLResourceView.cpp @@ -0,0 +1,192 @@ +#include "XCEngine/RHI/OpenGL/OpenGLResourceView.h" +#include "XCEngine/RHI/OpenGL/OpenGLTexture.h" +#include "XCEngine/RHI/OpenGL/OpenGLBuffer.h" +#include "XCEngine/RHI/OpenGL/OpenGLFramebuffer.h" +#include "XCEngine/RHI/OpenGL/OpenGLTextureUnitAllocator.h" +#include "XCEngine/RHI/OpenGL/OpenGLUniformBufferManager.h" + +#include + +namespace XCEngine { +namespace RHI { + +OpenGLResourceView::OpenGLResourceView() + : m_viewType(ResourceViewType::RenderTarget) + , m_framebufferID(0) + , m_textureUnit(-1) + , m_bindingPoint(-1) + , m_texture(nullptr) + , m_buffer(nullptr) + , m_framebuffer(nullptr) + , m_textureUnitAllocator(nullptr) + , m_uniformBufferManager(nullptr) { +} + +OpenGLResourceView::~OpenGLResourceView() { + Shutdown(); +} + +void OpenGLResourceView::Shutdown() { + if (m_textureUnit >= 0 && m_textureUnitAllocator) { + m_textureUnitAllocator->UnbindTexture(m_textureUnit); + m_textureUnitAllocator->Free(m_textureUnit); + m_textureUnit = -1; + } + + if (m_bindingPoint >= 0 && m_uniformBufferManager) { + m_uniformBufferManager->UnbindBuffer(m_bindingPoint); + m_uniformBufferManager->Free(m_bindingPoint); + m_bindingPoint = -1; + } + + m_framebuffer = nullptr; + m_textureUnitAllocator = nullptr; + m_uniformBufferManager = nullptr; + m_framebufferID = 0; + m_texture = nullptr; + m_buffer = nullptr; +} + +void* OpenGLResourceView::GetNativeHandle() { + switch (m_viewType) { + case ResourceViewType::RenderTarget: + case ResourceViewType::DepthStencil: + return reinterpret_cast(static_cast(m_framebufferID)); + case ResourceViewType::ShaderResource: + case ResourceViewType::UnorderedAccess: + return reinterpret_cast(static_cast(m_texture ? m_texture->GetID() : 0)); + case ResourceViewType::ConstantBuffer: + return reinterpret_cast(static_cast(m_buffer ? m_buffer->GetID() : 0)); + default: + return nullptr; + } +} + +bool OpenGLResourceView::IsValid() const { + switch (m_viewType) { + case ResourceViewType::RenderTarget: + case ResourceViewType::DepthStencil: + return m_framebufferID != 0; + case ResourceViewType::ShaderResource: + case ResourceViewType::UnorderedAccess: + return m_texture != nullptr && m_textureUnit >= 0; + case ResourceViewType::ConstantBuffer: + return m_buffer != nullptr && m_bindingPoint >= 0; + default: + return false; + } +} + +bool OpenGLResourceView::InitializeAsRenderTarget( + OpenGLTexture* texture, + const ResourceViewDesc& desc, + OpenGLFramebuffer* framebuffer) { + (void)desc; + if (!texture || !framebuffer) { + return false; + } + + m_viewType = ResourceViewType::RenderTarget; + m_texture = texture; + m_framebuffer = framebuffer; + m_framebufferID = framebuffer->GetFramebuffer(); + return true; +} + +bool OpenGLResourceView::InitializeAsDepthStencil( + OpenGLTexture* texture, + const ResourceViewDesc& desc, + OpenGLFramebuffer* framebuffer) { + (void)desc; + if (!texture || !framebuffer) { + return false; + } + + m_viewType = ResourceViewType::DepthStencil; + m_texture = texture; + m_framebuffer = framebuffer; + m_framebufferID = framebuffer->GetFramebuffer(); + return true; +} + +bool OpenGLResourceView::InitializeAsShaderResource( + OpenGLTexture* texture, + const ResourceViewDesc& desc, + OpenGLTextureUnitAllocator* allocator) { + if (!texture || !allocator) { + return false; + } + + int32_t unit = allocator->Allocate(); + if (unit < 0) { + return false; + } + + m_viewType = ResourceViewType::ShaderResource; + m_texture = texture; + m_textureUnit = unit; + m_textureUnitAllocator = allocator; + allocator->BindTexture(unit, texture); + return true; +} + +bool OpenGLResourceView::InitializeAsUnorderedAccess( + OpenGLTexture* texture, + const ResourceViewDesc& desc, + OpenGLTextureUnitAllocator* allocator) { + if (!texture || !allocator) { + return false; + } + + int32_t unit = allocator->Allocate(); + if (unit < 0) { + return false; + } + + m_viewType = ResourceViewType::UnorderedAccess; + m_texture = texture; + m_textureUnit = unit; + m_textureUnitAllocator = allocator; + + glActiveTexture(GL_TEXTURE0 + unit); + glBindTexture(static_cast(texture->GetOpenGLType()), texture->GetID()); + glBindImageTexture(unit, texture->GetID(), 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8); + + return true; +} + +bool OpenGLResourceView::InitializeAsConstantBuffer( + OpenGLBuffer* buffer, + const ResourceViewDesc& desc, + OpenGLUniformBufferManager* manager) { + if (!buffer || !manager) { + return false; + } + + int32_t bindingPoint = manager->Allocate(); + if (bindingPoint < 0) { + return false; + } + + m_viewType = ResourceViewType::ConstantBuffer; + m_buffer = buffer; + m_bindingPoint = bindingPoint; + m_uniformBufferManager = manager; + manager->BindBuffer(bindingPoint, buffer, 0, static_cast(desc.bufferLocation)); + return true; +} + +unsigned int OpenGLResourceView::GetFramebuffer() const { + return m_framebuffer ? m_framebuffer->GetFramebuffer() : 0; +} + +unsigned int OpenGLResourceView::GetTexture() const { + return m_texture ? m_texture->GetID() : 0; +} + +unsigned int OpenGLResourceView::GetBuffer() const { + return m_buffer ? m_buffer->GetID() : 0; +} + +} // namespace RHI +} // namespace XCEngine \ No newline at end of file diff --git a/engine/src/RHI/OpenGL/OpenGLTextureUnitAllocator.cpp b/engine/src/RHI/OpenGL/OpenGLTextureUnitAllocator.cpp new file mode 100644 index 00000000..1d7126b8 --- /dev/null +++ b/engine/src/RHI/OpenGL/OpenGLTextureUnitAllocator.cpp @@ -0,0 +1,89 @@ +#include "XCEngine/RHI/OpenGL/OpenGLTextureUnitAllocator.h" +#include "XCEngine/RHI/OpenGL/OpenGLTexture.h" + +#include + +namespace XCEngine { +namespace RHI { + +OpenGLTextureUnitAllocator::OpenGLTextureUnitAllocator() + : m_maxUnits(0) { +} + +OpenGLTextureUnitAllocator::~OpenGLTextureUnitAllocator() { + Shutdown(); +} + +void OpenGLTextureUnitAllocator::Initialize(uint32_t maxUnits) { + m_maxUnits = maxUnits; + m_allocated.resize(maxUnits, false); + m_boundTextures.resize(maxUnits, nullptr); +} + +void OpenGLTextureUnitAllocator::Shutdown() { + for (uint32_t i = 0; i < m_maxUnits; ++i) { + if (m_allocated[i]) { + Free(static_cast(i)); + } + } + m_allocated.clear(); + m_boundTextures.clear(); + m_maxUnits = 0; +} + +int32_t OpenGLTextureUnitAllocator::Allocate() { + for (uint32_t i = 0; i < m_maxUnits; ++i) { + if (!m_allocated[i]) { + m_allocated[i] = true; + return static_cast(i); + } + } + return -1; +} + +void OpenGLTextureUnitAllocator::Free(int32_t unit) { + if (unit < 0 || unit >= static_cast(m_maxUnits)) { + return; + } + UnbindTexture(unit); + m_allocated[unit] = false; +} + +void OpenGLTextureUnitAllocator::BindTexture(int32_t unit, OpenGLTexture* texture) { + if (unit < 0 || unit >= static_cast(m_maxUnits)) { + return; + } + glActiveTexture(GL_TEXTURE0 + unit); + if (texture) { + glBindTexture(static_cast(texture->GetOpenGLType()), texture->GetID()); + } else { + glBindTexture(GL_TEXTURE_2D, 0); + } + m_boundTextures[unit] = texture; +} + +void OpenGLTextureUnitAllocator::UnbindTexture(int32_t unit) { + if (unit < 0 || unit >= static_cast(m_maxUnits)) { + return; + } + glActiveTexture(GL_TEXTURE0 + unit); + glBindTexture(GL_TEXTURE_2D, 0); + m_boundTextures[unit] = nullptr; +} + +OpenGLTexture* OpenGLTextureUnitAllocator::GetBoundTexture(int32_t unit) const { + if (unit < 0 || unit >= static_cast(m_maxUnits)) { + return nullptr; + } + return m_boundTextures[unit]; +} + +bool OpenGLTextureUnitAllocator::IsAllocated(int32_t unit) const { + if (unit < 0 || unit >= static_cast(m_maxUnits)) { + return false; + } + return m_allocated[unit]; +} + +} // namespace RHI +} // namespace XCEngine \ No newline at end of file diff --git a/engine/src/RHI/OpenGL/OpenGLUniformBufferManager.cpp b/engine/src/RHI/OpenGL/OpenGLUniformBufferManager.cpp new file mode 100644 index 00000000..6f31d14c --- /dev/null +++ b/engine/src/RHI/OpenGL/OpenGLUniformBufferManager.cpp @@ -0,0 +1,87 @@ +#include "XCEngine/RHI/OpenGL/OpenGLUniformBufferManager.h" +#include "XCEngine/RHI/OpenGL/OpenGLBuffer.h" + +#include + +namespace XCEngine { +namespace RHI { + +OpenGLUniformBufferManager::OpenGLUniformBufferManager() + : m_maxBindingPoints(0) { +} + +OpenGLUniformBufferManager::~OpenGLUniformBufferManager() { + Shutdown(); +} + +void OpenGLUniformBufferManager::Initialize(uint32_t maxBindingPoints) { + m_maxBindingPoints = maxBindingPoints; + m_allocated.resize(maxBindingPoints, false); + m_boundBuffers.resize(maxBindingPoints, nullptr); +} + +void OpenGLUniformBufferManager::Shutdown() { + for (uint32_t i = 0; i < m_maxBindingPoints; ++i) { + if (m_allocated[i]) { + Free(static_cast(i)); + } + } + m_allocated.clear(); + m_boundBuffers.clear(); + m_maxBindingPoints = 0; +} + +int32_t OpenGLUniformBufferManager::Allocate() { + for (uint32_t i = 0; i < m_maxBindingPoints; ++i) { + if (!m_allocated[i]) { + m_allocated[i] = true; + return static_cast(i); + } + } + return -1; +} + +void OpenGLUniformBufferManager::Free(int32_t bindingPoint) { + if (bindingPoint < 0 || bindingPoint >= static_cast(m_maxBindingPoints)) { + return; + } + UnbindBuffer(bindingPoint); + m_allocated[bindingPoint] = false; +} + +void OpenGLUniformBufferManager::BindBuffer(int32_t bindingPoint, OpenGLBuffer* buffer, uint32_t offset, uint32_t size) { + if (bindingPoint < 0 || bindingPoint >= static_cast(m_maxBindingPoints)) { + return; + } + if (buffer) { + glBindBufferBase(GL_UNIFORM_BUFFER, bindingPoint, buffer->GetID()); + } else { + glBindBufferBase(GL_UNIFORM_BUFFER, bindingPoint, 0); + } + m_boundBuffers[bindingPoint] = buffer; +} + +void OpenGLUniformBufferManager::UnbindBuffer(int32_t bindingPoint) { + if (bindingPoint < 0 || bindingPoint >= static_cast(m_maxBindingPoints)) { + return; + } + glBindBufferBase(GL_UNIFORM_BUFFER, bindingPoint, 0); + m_boundBuffers[bindingPoint] = nullptr; +} + +OpenGLBuffer* OpenGLUniformBufferManager::GetBoundBuffer(int32_t bindingPoint) const { + if (bindingPoint < 0 || bindingPoint >= static_cast(m_maxBindingPoints)) { + return nullptr; + } + return m_boundBuffers[bindingPoint]; +} + +bool OpenGLUniformBufferManager::IsAllocated(int32_t bindingPoint) const { + if (bindingPoint < 0 || bindingPoint >= static_cast(m_maxBindingPoints)) { + return false; + } + return m_allocated[bindingPoint]; +} + +} // namespace RHI +} // namespace XCEngine \ No newline at end of file diff --git a/tests/RHI/D3D12/integration/minimal/main.cpp b/tests/RHI/D3D12/integration/minimal/main.cpp index 16ff564f..269756d0 100644 --- a/tests/RHI/D3D12/integration/minimal/main.cpp +++ b/tests/RHI/D3D12/integration/minimal/main.cpp @@ -18,8 +18,7 @@ #include "XCEngine/RHI/D3D12/D3D12SwapChain.h" #include "XCEngine/RHI/D3D12/D3D12Buffer.h" #include "XCEngine/RHI/D3D12/D3D12Texture.h" -#include "XCEngine/RHI/D3D12/D3D12RenderTargetView.h" -#include "XCEngine/RHI/D3D12/D3D12DepthStencilView.h" +#include "XCEngine/RHI/D3D12/D3D12ResourceView.h" #include "XCEngine/RHI/D3D12/D3D12Screenshot.h" #include "XCEngine/Debug/Logger.h" #include "XCEngine/Debug/ConsoleLogSink.h" @@ -48,8 +47,8 @@ D3D12CommandList gCommandList; D3D12Texture gDepthStencil; D3D12DescriptorHeap gRTVHeap; D3D12DescriptorHeap gDSVHeap; -D3D12RenderTargetView gRTVs[2]; -D3D12DepthStencilView gDSV; +D3D12ResourceView gRTVs[2]; +D3D12ResourceView gDSV; UINT gRTVDescriptorSize = 0; UINT gDSVDescriptorSize = 0; @@ -128,14 +127,13 @@ bool InitD3D12() { CPUDescriptorHandle rtvCpuHandle = gRTVHeap.GetCPUDescriptorHandle(i); D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = { rtvCpuHandle.ptr }; - gRTVs[i].InitializeAt(device, backBuffer.GetResource(), rtvHandle, nullptr); + D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = D3D12ResourceView::CreateRenderTargetDesc(Format::R8G8B8A8_UNorm, D3D12_RTV_DIMENSION_TEXTURE2D); + gRTVs[i].InitializeAsRenderTarget(device, backBuffer.GetResource(), &rtvDesc, &gRTVHeap, i); } // Create DSV - D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = D3D12DepthStencilView::CreateDesc(Format::D24_UNorm_S8_UInt); - CPUDescriptorHandle dsvCpuHandle = gDSVHeap.GetCPUDescriptorHandle(0); - D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = { dsvCpuHandle.ptr }; - gDSV.InitializeAt(device, gDepthStencil.GetResource(), dsvHandle, &dsvDesc); + D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = D3D12ResourceView::CreateDepthStencilDesc(Format::D24_UNorm_S8_UInt, D3D12_DSV_DIMENSION_TEXTURE2D); + gDSV.InitializeAsDepthStencil(device, gDepthStencil.GetResource(), &dsvDesc, &gDSVHeap, 0); // Create command allocator and list gCommandAllocator.Initialize(device, CommandQueueType::Direct); diff --git a/tests/RHI/D3D12/integration/quad/main.cpp b/tests/RHI/D3D12/integration/quad/main.cpp index a90b098a..93d788be 100644 --- a/tests/RHI/D3D12/integration/quad/main.cpp +++ b/tests/RHI/D3D12/integration/quad/main.cpp @@ -18,13 +18,11 @@ #include "XCEngine/RHI/D3D12/D3D12SwapChain.h" #include "XCEngine/RHI/D3D12/D3D12Buffer.h" #include "XCEngine/RHI/D3D12/D3D12Texture.h" -#include "XCEngine/RHI/D3D12/D3D12RenderTargetView.h" -#include "XCEngine/RHI/D3D12/D3D12DepthStencilView.h" #include "XCEngine/RHI/D3D12/D3D12Shader.h" #include "XCEngine/RHI/D3D12/D3D12RootSignature.h" #include "XCEngine/RHI/D3D12/D3D12PipelineState.h" #include "XCEngine/RHI/D3D12/D3D12Screenshot.h" -#include "XCEngine/RHI/D3D12/D3D12ShaderResourceView.h" +#include "XCEngine/RHI/D3D12/D3D12ResourceView.h" #include "XCEngine/Debug/Logger.h" #include "XCEngine/Debug/ConsoleLogSink.h" #include "XCEngine/Debug/FileLogSink.h" @@ -51,8 +49,8 @@ D3D12Texture gDepthStencil; D3D12DescriptorHeap gRTVHeap; D3D12DescriptorHeap gDSVHeap; D3D12DescriptorHeap gSRVHeap; -D3D12RenderTargetView gRTVs[2]; -D3D12DepthStencilView gDSV; +D3D12ResourceView gRTVs[2]; +D3D12ResourceView gDSV; D3D12Shader gVertexShader; D3D12Shader gPixelShader; @@ -60,7 +58,7 @@ D3D12RootSignature gRootSignature; D3D12PipelineState gPipelineState; D3D12Buffer gVertexBuffer; D3D12Texture gDiffuseTexture; -D3D12ShaderResourceView gDiffuseSRV; +D3D12ResourceView gDiffuseSRV; UINT gRTVDescriptorSize = 0; UINT gDSVDescriptorSize = 0; @@ -88,7 +86,7 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { return DefWindowProc(hwnd, msg, wParam, lParam); } -bool LoadTexture(const char* filename, D3D12Texture& texture, D3D12ShaderResourceView& srv, ID3D12Device* device, D3D12DescriptorHeap& srvHeap, ID3D12GraphicsCommandList* commandList, D3D12CommandAllocator& allocator, D3D12CommandQueue& queue) { +bool LoadTexture(const char* filename, D3D12Texture& texture, D3D12ResourceView& srv, ID3D12Device* device, D3D12DescriptorHeap& srvHeap, ID3D12GraphicsCommandList* commandList, D3D12CommandAllocator& allocator, D3D12CommandQueue& queue) { int width, height, channels; stbi_uc* pixels = stbi_load(filename, &width, &height, &channels, STBI_rgb_alpha); if (!pixels) { @@ -113,8 +111,8 @@ bool LoadTexture(const char* filename, D3D12Texture& texture, D3D12ShaderResourc texture.SetName(filename); srvHeap.Initialize(device, DescriptorHeapType::CBV_SRV_UAV, 1, true); - D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = D3D12ShaderResourceView::CreateDesc(Format::R8G8B8A8_UNorm, D3D12_SRV_DIMENSION_TEXTURE2D); - srv.InitializeAt(device, texture.GetResource(), srvHeap.GetCPUDescriptorHandleForHeapStart(), &srvDesc); + D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = D3D12ResourceView::CreateShaderResourceDesc(Format::R8G8B8A8_UNorm, D3D12_SRV_DIMENSION_TEXTURE2D); + srv.InitializeAsShaderResource(device, texture.GetResource(), &srvDesc, &srvHeap, 0); return true; } @@ -156,15 +154,12 @@ bool InitD3D12() { for (int i = 0; i < 2; i++) { D3D12Texture& backBuffer = gSwapChain.GetBackBuffer(i); - CPUDescriptorHandle rtvCpuHandle = gRTVHeap.GetCPUDescriptorHandle(i); - D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = { rtvCpuHandle.ptr }; - gRTVs[i].InitializeAt(device, backBuffer.GetResource(), rtvHandle, nullptr); + D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = D3D12ResourceView::CreateRenderTargetDesc(Format::R8G8B8A8_UNorm, D3D12_RTV_DIMENSION_TEXTURE2D); + gRTVs[i].InitializeAsRenderTarget(device, backBuffer.GetResource(), &rtvDesc, &gRTVHeap, i); } - D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = D3D12DepthStencilView::CreateDesc(Format::D24_UNorm_S8_UInt); - CPUDescriptorHandle dsvCpuHandle = gDSVHeap.GetCPUDescriptorHandle(0); - D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = { dsvCpuHandle.ptr }; - gDSV.InitializeAt(device, gDepthStencil.GetResource(), dsvHandle, &dsvDesc); + D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = D3D12ResourceView::CreateDepthStencilDesc(Format::D24_UNorm_S8_UInt, D3D12_DSV_DIMENSION_TEXTURE2D); + gDSV.InitializeAsDepthStencil(device, gDepthStencil.GetResource(), &dsvDesc, &gDSVHeap, 0); gCommandAllocator.Initialize(device, CommandQueueType::Direct); gCommandList.Initialize(device, CommandQueueType::Direct, gCommandAllocator.GetCommandAllocator()); diff --git a/tests/RHI/D3D12/integration/sphere/main.cpp b/tests/RHI/D3D12/integration/sphere/main.cpp index 534b3a3b..c6f17f55 100644 --- a/tests/RHI/D3D12/integration/sphere/main.cpp +++ b/tests/RHI/D3D12/integration/sphere/main.cpp @@ -20,12 +20,10 @@ #include "XCEngine/RHI/D3D12/D3D12SwapChain.h" #include "XCEngine/RHI/D3D12/D3D12Buffer.h" #include "XCEngine/RHI/D3D12/D3D12Texture.h" -#include "XCEngine/RHI/D3D12/D3D12RenderTargetView.h" -#include "XCEngine/RHI/D3D12/D3D12DepthStencilView.h" #include "XCEngine/RHI/D3D12/D3D12Shader.h" #include "XCEngine/RHI/D3D12/D3D12RootSignature.h" #include "XCEngine/RHI/D3D12/D3D12PipelineState.h" -#include "XCEngine/RHI/D3D12/D3D12ShaderResourceView.h" +#include "XCEngine/RHI/D3D12/D3D12ResourceView.h" #include "XCEngine/RHI/D3D12/D3D12Screenshot.h" #include "XCEngine/Debug/Logger.h" #include "XCEngine/Debug/ConsoleLogSink.h" @@ -56,8 +54,8 @@ D3D12Texture gDepthStencil; D3D12DescriptorHeap gRTVHeap; D3D12DescriptorHeap gDSVHeap; D3D12DescriptorHeap gSRVHeap; -D3D12RenderTargetView gRTVs[2]; -D3D12DepthStencilView gDSV; +D3D12ResourceView gRTVs[2]; +D3D12ResourceView gDSV; D3D12Shader gVertexShader; D3D12Shader gPixelShader; @@ -67,7 +65,7 @@ D3D12Buffer gVertexBuffer; D3D12Buffer gIndexBuffer; D3D12Buffer gMVPBuffer; D3D12Texture gDiffuseTexture; -D3D12ShaderResourceView gDiffuseSRV; +D3D12ResourceView gDiffuseSRV; UINT gRTVDescriptorSize = 0; UINT gDSVDescriptorSize = 0; @@ -155,7 +153,7 @@ void GenerateSphere(std::vector& vertices, std::vector& indices, } } -bool LoadTexture(const char* filename, D3D12Texture& texture, D3D12ShaderResourceView& srv, ID3D12Device* device, D3D12DescriptorHeap& srvHeap, ID3D12GraphicsCommandList* commandList, D3D12CommandAllocator& allocator, D3D12CommandQueue& queue) { +bool LoadTexture(const char* filename, D3D12Texture& texture, D3D12ResourceView& srv, ID3D12Device* device, D3D12DescriptorHeap& srvHeap, ID3D12GraphicsCommandList* commandList, D3D12CommandAllocator& allocator, D3D12CommandQueue& queue) { int width, height, channels; stbi_uc* pixels = stbi_load(filename, &width, &height, &channels, STBI_rgb_alpha); if (!pixels) { @@ -180,8 +178,8 @@ bool LoadTexture(const char* filename, D3D12Texture& texture, D3D12ShaderResourc texture.SetName(filename); srvHeap.Initialize(device, DescriptorHeapType::CBV_SRV_UAV, 1, true); - D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = D3D12ShaderResourceView::CreateDesc(Format::R8G8B8A8_UNorm, D3D12_SRV_DIMENSION_TEXTURE2D); - srv.InitializeAt(device, texture.GetResource(), srvHeap.GetCPUDescriptorHandleForHeapStart(), &srvDesc); + D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = D3D12ResourceView::CreateShaderResourceDesc(Format::R8G8B8A8_UNorm, D3D12_SRV_DIMENSION_TEXTURE2D); + srv.InitializeAsShaderResource(device, texture.GetResource(), &srvDesc, &srvHeap, 0); return true; } @@ -223,15 +221,12 @@ bool InitD3D12() { for (int i = 0; i < 2; i++) { D3D12Texture& backBuffer = gSwapChain.GetBackBuffer(i); - CPUDescriptorHandle rtvCpuHandle = gRTVHeap.GetCPUDescriptorHandle(i); - D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = { rtvCpuHandle.ptr }; - gRTVs[i].InitializeAt(device, backBuffer.GetResource(), rtvHandle, nullptr); + D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = D3D12ResourceView::CreateRenderTargetDesc(Format::R8G8B8A8_UNorm, D3D12_RTV_DIMENSION_TEXTURE2D); + gRTVs[i].InitializeAsRenderTarget(device, backBuffer.GetResource(), &rtvDesc, &gRTVHeap, i); } - D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = D3D12DepthStencilView::CreateDesc(Format::D24_UNorm_S8_UInt); - CPUDescriptorHandle dsvCpuHandle = gDSVHeap.GetCPUDescriptorHandle(0); - D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = { dsvCpuHandle.ptr }; - gDSV.InitializeAt(device, gDepthStencil.GetResource(), dsvHandle, &dsvDesc); + D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = D3D12ResourceView::CreateDepthStencilDesc(Format::D24_UNorm_S8_UInt, D3D12_DSV_DIMENSION_TEXTURE2D); + gDSV.InitializeAsDepthStencil(device, gDepthStencil.GetResource(), &dsvDesc, &gDSVHeap, 0); gCommandAllocator.Initialize(device, CommandQueueType::Direct); gCommandList.Initialize(device, CommandQueueType::Direct, gCommandAllocator.GetCommandAllocator()); diff --git a/tests/RHI/D3D12/integration/triangle/main.cpp b/tests/RHI/D3D12/integration/triangle/main.cpp index 47e6dd6b..e3a9fe39 100644 --- a/tests/RHI/D3D12/integration/triangle/main.cpp +++ b/tests/RHI/D3D12/integration/triangle/main.cpp @@ -18,8 +18,7 @@ #include "XCEngine/RHI/D3D12/D3D12SwapChain.h" #include "XCEngine/RHI/D3D12/D3D12Buffer.h" #include "XCEngine/RHI/D3D12/D3D12Texture.h" -#include "XCEngine/RHI/D3D12/D3D12RenderTargetView.h" -#include "XCEngine/RHI/D3D12/D3D12DepthStencilView.h" +#include "XCEngine/RHI/D3D12/D3D12ResourceView.h" #include "XCEngine/RHI/D3D12/D3D12Shader.h" #include "XCEngine/RHI/D3D12/D3D12RootSignature.h" #include "XCEngine/RHI/D3D12/D3D12PipelineState.h" @@ -48,8 +47,8 @@ D3D12CommandList gCommandList; D3D12Texture gDepthStencil; D3D12DescriptorHeap gRTVHeap; D3D12DescriptorHeap gDSVHeap; -D3D12RenderTargetView gRTVs[2]; -D3D12DepthStencilView gDSV; +D3D12ResourceView gRTVs[2]; +D3D12ResourceView gDSV; D3D12Shader gVertexShader; D3D12Shader gPixelShader; @@ -120,15 +119,12 @@ bool InitD3D12() { for (int i = 0; i < 2; i++) { D3D12Texture& backBuffer = gSwapChain.GetBackBuffer(i); - CPUDescriptorHandle rtvCpuHandle = gRTVHeap.GetCPUDescriptorHandle(i); - D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = { rtvCpuHandle.ptr }; - gRTVs[i].InitializeAt(device, backBuffer.GetResource(), rtvHandle, nullptr); + D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = D3D12ResourceView::CreateRenderTargetDesc(Format::R8G8B8A8_UNorm, D3D12_RTV_DIMENSION_TEXTURE2D); + gRTVs[i].InitializeAsRenderTarget(device, backBuffer.GetResource(), &rtvDesc, &gRTVHeap, i); } - D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = D3D12DepthStencilView::CreateDesc(Format::D24_UNorm_S8_UInt); - CPUDescriptorHandle dsvCpuHandle = gDSVHeap.GetCPUDescriptorHandle(0); - D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = { dsvCpuHandle.ptr }; - gDSV.InitializeAt(device, gDepthStencil.GetResource(), dsvHandle, &dsvDesc); + D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = D3D12ResourceView::CreateDepthStencilDesc(Format::D24_UNorm_S8_UInt, D3D12_DSV_DIMENSION_TEXTURE2D); + gDSV.InitializeAsDepthStencil(device, gDepthStencil.GetResource(), &dsvDesc, &gDSVHeap, 0); gCommandAllocator.Initialize(device, CommandQueueType::Direct); gCommandList.Initialize(device, CommandQueueType::Direct, gCommandAllocator.GetCommandAllocator()); diff --git a/tests/RHI/unit/test_command_queue.cpp b/tests/RHI/unit/test_command_queue.cpp index f4ca9525..42786de4 100644 --- a/tests/RHI/unit/test_command_queue.cpp +++ b/tests/RHI/unit/test_command_queue.cpp @@ -19,11 +19,11 @@ TEST_P(RHITestFixture, CommandQueue_ExecuteCommandLists) { ASSERT_NE(cmdList, nullptr); cmdList->Reset(); - cmdList->Close(); void* cmdLists[] = { cmdList }; queue->ExecuteCommandLists(1, cmdLists); + cmdList->Close(); cmdList->Shutdown(); delete cmdList; queue->Shutdown();