Refactor RHI ResourceView abstraction layer for unified cross-platform interface
- Create unified RHIResourceView base interface with type-specific Initialize methods - Implement D3D12ResourceView with RTV/DSV/SRV/UAV/CBV support - Implement OpenGL ResourceView simulation layer using FBO, texture units, and UBO - Add OpenGLTextureUnitAllocator for managing texture unit bindings - Add OpenGLUniformBufferManager for UBO binding points - Add OpenGLFramebuffer for FBO management - Remove deprecated D3D12 view classes (RenderTargetView, DepthStencilView, etc.) - Fix ExecuteCommandLists type confusion bug by adding GetNativeHandle to RHICommandList - Fix test bug where Close() was called before ExecuteCommandLists - Update all integration tests to use new D3D12ResourceView class - All tests pass: 144 unit tests + 8 integration tests
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <d3d12.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
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
|
||||
@@ -1,33 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <d3d12.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
#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
|
||||
@@ -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);
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <d3d12.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
#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
|
||||
65
engine/include/XCEngine/RHI/D3D12/D3D12ResourceView.h
Normal file
65
engine/include/XCEngine/RHI/D3D12/D3D12ResourceView.h
Normal file
@@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
|
||||
#include <d3d12.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
#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
|
||||
@@ -1,33 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <d3d12.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
#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
|
||||
@@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <d3d12.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
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
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <Windows.h>
|
||||
|
||||
#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<OpenGLTextureUnitAllocator> m_textureUnitAllocator;
|
||||
std::unique_ptr<OpenGLUniformBufferManager> m_uniformBufferManager;
|
||||
};
|
||||
|
||||
} // namespace RHI
|
||||
|
||||
66
engine/include/XCEngine/RHI/OpenGL/OpenGLFramebuffer.h
Normal file
66
engine/include/XCEngine/RHI/OpenGL/OpenGLFramebuffer.h
Normal file
@@ -0,0 +1,66 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
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<FramebufferAttachment> 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
|
||||
69
engine/include/XCEngine/RHI/OpenGL/OpenGLResourceView.h
Normal file
69
engine/include/XCEngine/RHI/OpenGL/OpenGLResourceView.h
Normal file
@@ -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
|
||||
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
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<bool> m_allocated;
|
||||
std::vector<OpenGLTexture*> m_boundTextures;
|
||||
};
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
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<bool> m_allocated;
|
||||
std::vector<OpenGLBuffer*> m_boundBuffers;
|
||||
};
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
21
engine/include/XCEngine/RHI/RHIResourceView.h
Normal file
21
engine/include/XCEngine/RHI/RHIResourceView.h
Normal file
@@ -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
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "RHIEnums.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -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
|
||||
|
||||
@@ -59,7 +59,8 @@ void D3D12CommandQueue::ExecuteCommandLists(uint32_t count, void** lists) {
|
||||
std::vector<ID3D12CommandList*> cmdLists(count);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
if (lists[i]) {
|
||||
cmdLists[i] = static_cast<ID3D12CommandList*>(lists[i]);
|
||||
RHICommandList* cmdList = static_cast<RHICommandList*>(lists[i]);
|
||||
cmdLists[i] = static_cast<ID3D12CommandList*>(cmdList->GetNativeHandle());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 <stdio.h>
|
||||
|
||||
#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<D3D12Texture*>(texture);
|
||||
ID3D12Resource* resource = d3d12Texture->GetResource();
|
||||
|
||||
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = {};
|
||||
rtvDesc.Format = static_cast<DXGI_FORMAT>(desc.format);
|
||||
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
|
||||
|
||||
DescriptorHeapDesc heapDesc = {};
|
||||
heapDesc.descriptorCount = 1;
|
||||
heapDesc.heapType = static_cast<uint32_t>(DescriptorHeapType::RTV);
|
||||
heapDesc.shaderVisible = false;
|
||||
auto* heapPool = CreateDescriptorHeap(heapDesc);
|
||||
auto* heap = static_cast<D3D12DescriptorHeap*>(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<D3D12Texture*>(texture);
|
||||
ID3D12Resource* resource = d3d12Texture->GetResource();
|
||||
|
||||
D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = {};
|
||||
dsvDesc.Format = static_cast<DXGI_FORMAT>(desc.format);
|
||||
dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
|
||||
|
||||
DescriptorHeapDesc heapDesc = {};
|
||||
heapDesc.descriptorCount = 1;
|
||||
heapDesc.heapType = static_cast<uint32_t>(DescriptorHeapType::DSV);
|
||||
heapDesc.shaderVisible = false;
|
||||
auto* heapPool = CreateDescriptorHeap(heapDesc);
|
||||
auto* heap = static_cast<D3D12DescriptorHeap*>(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<D3D12Texture*>(texture);
|
||||
ID3D12Resource* resource = d3d12Texture->GetResource();
|
||||
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
|
||||
srvDesc.Format = static_cast<DXGI_FORMAT>(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<uint32_t>(DescriptorHeapType::CBV_SRV_UAV);
|
||||
heapDesc.shaderVisible = true;
|
||||
auto* heapPool = CreateDescriptorHeap(heapDesc);
|
||||
auto* heap = static_cast<D3D12DescriptorHeap*>(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<D3D12Texture*>(texture);
|
||||
ID3D12Resource* resource = d3d12Texture->GetResource();
|
||||
|
||||
D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
|
||||
uavDesc.Format = static_cast<DXGI_FORMAT>(desc.format);
|
||||
uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
|
||||
|
||||
DescriptorHeapDesc heapDesc = {};
|
||||
heapDesc.descriptorCount = 1;
|
||||
heapDesc.heapType = static_cast<uint32_t>(DescriptorHeapType::CBV_SRV_UAV);
|
||||
heapDesc.shaderVisible = true;
|
||||
auto* heapPool = CreateDescriptorHeap(heapDesc);
|
||||
auto* heap = static_cast<D3D12DescriptorHeap*>(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<DescriptorHeapType>(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;
|
||||
}
|
||||
|
||||
143
engine/src/RHI/D3D12/D3D12ResourceView.cpp
Normal file
143
engine/src/RHI/D3D12/D3D12ResourceView.cpp
Normal file
@@ -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
|
||||
@@ -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<OpenGLTextureUnitAllocator>();
|
||||
m_uniformBufferManager = std::make_unique<OpenGLUniformBufferManager>();
|
||||
}
|
||||
|
||||
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<uint32_t>(maxAttribs);
|
||||
|
||||
GLint maxTextureUnits = 0;
|
||||
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
|
||||
m_textureUnitAllocator->Initialize(static_cast<uint32_t>(maxTextureUnits));
|
||||
|
||||
GLint maxUniformBlocks = 0;
|
||||
glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &maxUniformBlocks);
|
||||
m_uniformBufferManager->Initialize(static_cast<uint32_t>(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<OpenGLTexture*>(texture);
|
||||
|
||||
FramebufferDesc fbDesc = {};
|
||||
fbDesc.width = static_cast<int>(texture->GetWidth());
|
||||
fbDesc.height = static_cast<int>(texture->GetHeight());
|
||||
|
||||
FramebufferAttachment colorAttachment = {};
|
||||
colorAttachment.texture = glTexture->GetID();
|
||||
colorAttachment.mipLevel = static_cast<int>(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<OpenGLTexture*>(texture);
|
||||
|
||||
FramebufferDesc fbDesc = {};
|
||||
fbDesc.width = static_cast<int>(texture->GetWidth());
|
||||
fbDesc.height = static_cast<int>(texture->GetHeight());
|
||||
|
||||
FramebufferAttachment depthAttachment = {};
|
||||
depthAttachment.texture = glTexture->GetID();
|
||||
depthAttachment.mipLevel = static_cast<int>(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<OpenGLTexture*>(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<OpenGLTexture*>(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;
|
||||
}
|
||||
|
||||
141
engine/src/RHI/OpenGL/OpenGLFramebuffer.cpp
Normal file
141
engine/src/RHI/OpenGL/OpenGLFramebuffer.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
#include "XCEngine/RHI/OpenGL/OpenGLFramebuffer.h"
|
||||
#include <glad/glad.h>
|
||||
|
||||
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<GLenum>(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
|
||||
192
engine/src/RHI/OpenGL/OpenGLResourceView.cpp
Normal file
192
engine/src/RHI/OpenGL/OpenGLResourceView.cpp
Normal file
@@ -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 <glad/glad.h>
|
||||
|
||||
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<void*>(static_cast<uintptr_t>(m_framebufferID));
|
||||
case ResourceViewType::ShaderResource:
|
||||
case ResourceViewType::UnorderedAccess:
|
||||
return reinterpret_cast<void*>(static_cast<uintptr_t>(m_texture ? m_texture->GetID() : 0));
|
||||
case ResourceViewType::ConstantBuffer:
|
||||
return reinterpret_cast<void*>(static_cast<uintptr_t>(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<GLenum>(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<uint32_t>(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
|
||||
89
engine/src/RHI/OpenGL/OpenGLTextureUnitAllocator.cpp
Normal file
89
engine/src/RHI/OpenGL/OpenGLTextureUnitAllocator.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
#include "XCEngine/RHI/OpenGL/OpenGLTextureUnitAllocator.h"
|
||||
#include "XCEngine/RHI/OpenGL/OpenGLTexture.h"
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
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<int32_t>(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<int32_t>(i);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void OpenGLTextureUnitAllocator::Free(int32_t unit) {
|
||||
if (unit < 0 || unit >= static_cast<int32_t>(m_maxUnits)) {
|
||||
return;
|
||||
}
|
||||
UnbindTexture(unit);
|
||||
m_allocated[unit] = false;
|
||||
}
|
||||
|
||||
void OpenGLTextureUnitAllocator::BindTexture(int32_t unit, OpenGLTexture* texture) {
|
||||
if (unit < 0 || unit >= static_cast<int32_t>(m_maxUnits)) {
|
||||
return;
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE0 + unit);
|
||||
if (texture) {
|
||||
glBindTexture(static_cast<GLenum>(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<int32_t>(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<int32_t>(m_maxUnits)) {
|
||||
return nullptr;
|
||||
}
|
||||
return m_boundTextures[unit];
|
||||
}
|
||||
|
||||
bool OpenGLTextureUnitAllocator::IsAllocated(int32_t unit) const {
|
||||
if (unit < 0 || unit >= static_cast<int32_t>(m_maxUnits)) {
|
||||
return false;
|
||||
}
|
||||
return m_allocated[unit];
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
87
engine/src/RHI/OpenGL/OpenGLUniformBufferManager.cpp
Normal file
87
engine/src/RHI/OpenGL/OpenGLUniformBufferManager.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#include "XCEngine/RHI/OpenGL/OpenGLUniformBufferManager.h"
|
||||
#include "XCEngine/RHI/OpenGL/OpenGLBuffer.h"
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
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<int32_t>(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<int32_t>(i);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void OpenGLUniformBufferManager::Free(int32_t bindingPoint) {
|
||||
if (bindingPoint < 0 || bindingPoint >= static_cast<int32_t>(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<int32_t>(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<int32_t>(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<int32_t>(m_maxBindingPoints)) {
|
||||
return nullptr;
|
||||
}
|
||||
return m_boundBuffers[bindingPoint];
|
||||
}
|
||||
|
||||
bool OpenGLUniformBufferManager::IsAllocated(int32_t bindingPoint) const {
|
||||
if (bindingPoint < 0 || bindingPoint >= static_cast<int32_t>(m_maxBindingPoints)) {
|
||||
return false;
|
||||
}
|
||||
return m_allocated[bindingPoint];
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
Reference in New Issue
Block a user