refactor(RHI): 完成 Shader uniform 设置迁移到 CommandList
- 删除 RHIShader 的 OpenGL 风格 SetMat4/SetVec3/SetInt 等方法 - 添加 UniformInfo 结构体和 GetUniformInfos/GetUniformInfo 接口 - D3D12Shader 和 OpenGLShader 实现 CacheUniformInfos - RHICommandList 添加 SetUniform*/SetGlobal* 统一接口 - D3D12 实现 D3D12PipelineLayout 管理 root signature 映射 - 修复 D3D12CommandList::SetPipelineStateInternal 在 Reset 后未重新应用 root signature 的问题 - 更新 OpenGL 集成测试使用新的 SetUniform* API - 所有单元测试和集成测试通过 (8/8 integration tests)
This commit is contained in:
@@ -103,6 +103,7 @@ add_library(XCEngine STATIC
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12Shader.h
|
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12Shader.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12Texture.h
|
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12Texture.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12RootSignature.h
|
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12RootSignature.h
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12PipelineLayout.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12SwapChain.h
|
${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/D3D12Fence.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12Screenshot.h
|
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12Screenshot.h
|
||||||
@@ -119,6 +120,7 @@ add_library(XCEngine STATIC
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12Shader.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12Shader.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12Texture.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12Texture.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12RootSignature.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12RootSignature.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12PipelineLayout.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12SwapChain.cpp
|
${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/D3D12Fence.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12Screenshot.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12Screenshot.cpp
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ namespace RHI {
|
|||||||
|
|
||||||
class RHIPipelineState;
|
class RHIPipelineState;
|
||||||
class D3D12ResourceView;
|
class D3D12ResourceView;
|
||||||
|
class D3D12Shader;
|
||||||
|
class D3D12PipelineLayout;
|
||||||
|
|
||||||
class D3D12CommandList : public RHICommandList {
|
class D3D12CommandList : public RHICommandList {
|
||||||
public:
|
public:
|
||||||
@@ -31,6 +33,21 @@ public:
|
|||||||
|
|
||||||
ID3D12GraphicsCommandList* GetCommandList() const { return m_commandList.Get(); }
|
ID3D12GraphicsCommandList* GetCommandList() const { return m_commandList.Get(); }
|
||||||
|
|
||||||
|
void SetShader(RHIShader* shader) override;
|
||||||
|
|
||||||
|
void SetUniformInt(const char* name, int value) override;
|
||||||
|
void SetUniformFloat(const char* name, float value) override;
|
||||||
|
void SetUniformVec3(const char* name, float x, float y, float z) override;
|
||||||
|
void SetUniformVec4(const char* name, float x, float y, float z, float w) override;
|
||||||
|
void SetUniformMat4(const char* name, const float* value) override;
|
||||||
|
|
||||||
|
void SetGlobalInt(const char* name, int value) override;
|
||||||
|
void SetGlobalFloat(const char* name, float value) override;
|
||||||
|
void SetGlobalVec3(const char* name, float x, float y, float z) override;
|
||||||
|
void SetGlobalVec4(const char* name, float x, float y, float z, float w) override;
|
||||||
|
void SetGlobalMat4(const char* name, const float* value) override;
|
||||||
|
void SetGlobalTexture(const char* name, RHIResourceView* texture) override;
|
||||||
|
|
||||||
void TransitionBarrier(RHIResourceView* resource, ResourceStates stateBefore, ResourceStates stateAfter) override;
|
void TransitionBarrier(RHIResourceView* resource, ResourceStates stateBefore, ResourceStates stateAfter) override;
|
||||||
void TransitionBarrier(ID3D12Resource* resource, ResourceStates stateBefore, ResourceStates stateAfter);
|
void TransitionBarrier(ID3D12Resource* resource, ResourceStates stateBefore, ResourceStates stateAfter);
|
||||||
void TransitionBarrierInternal(ID3D12Resource* resource, ResourceStates stateBefore, ResourceStates stateAfter, uint32_t subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES);
|
void TransitionBarrierInternal(ID3D12Resource* resource, ResourceStates stateBefore, ResourceStates stateAfter, uint32_t subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES);
|
||||||
@@ -42,6 +59,7 @@ public:
|
|||||||
void SetPipelineState(RHIPipelineState* pso) override;
|
void SetPipelineState(RHIPipelineState* pso) override;
|
||||||
void SetPipelineState(ID3D12PipelineState* pso);
|
void SetPipelineState(ID3D12PipelineState* pso);
|
||||||
void SetPipelineStateInternal(ID3D12PipelineState* pso);
|
void SetPipelineStateInternal(ID3D12PipelineState* pso);
|
||||||
|
void SetPipelineLayout(D3D12PipelineLayout* layout);
|
||||||
void SetRootSignature(ID3D12RootSignature* signature);
|
void SetRootSignature(ID3D12RootSignature* signature);
|
||||||
void SetViewport(const Viewport& viewport) override;
|
void SetViewport(const Viewport& viewport) override;
|
||||||
void SetViewports(uint32_t count, const Viewport* viewports) override;
|
void SetViewports(uint32_t count, const Viewport* viewports) override;
|
||||||
@@ -131,6 +149,15 @@ private:
|
|||||||
std::vector<D3D12_CPU_DESCRIPTOR_HANDLE> m_boundRenderTargets;
|
std::vector<D3D12_CPU_DESCRIPTOR_HANDLE> m_boundRenderTargets;
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE m_boundDepthStencil;
|
D3D12_CPU_DESCRIPTOR_HANDLE m_boundDepthStencil;
|
||||||
bool m_depthStencilBound = false;
|
bool m_depthStencilBound = false;
|
||||||
|
|
||||||
|
D3D12Shader* m_currentShader;
|
||||||
|
class D3D12PipelineLayout* m_currentPipelineLayout;
|
||||||
|
std::unordered_map<std::string, int> m_globalIntCache;
|
||||||
|
std::unordered_map<std::string, float> m_globalFloatCache;
|
||||||
|
std::unordered_map<std::string, std::vector<float>> m_globalVec3Cache;
|
||||||
|
std::unordered_map<std::string, std::vector<float>> m_globalVec4Cache;
|
||||||
|
std::unordered_map<std::string, std::vector<float>> m_globalMat4Cache;
|
||||||
|
std::unordered_map<std::string, RHIResourceView*> m_globalTextureCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace RHI
|
} // namespace RHI
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "../RHIEnums.h"
|
#include "../RHIEnums.h"
|
||||||
#include "../RHITypes.h"
|
#include "../RHITypes.h"
|
||||||
#include "D3D12Enums.h"
|
#include "D3D12Enums.h"
|
||||||
|
#include "D3D12PipelineLayout.h"
|
||||||
|
|
||||||
using Microsoft::WRL::ComPtr;
|
using Microsoft::WRL::ComPtr;
|
||||||
|
|
||||||
@@ -69,6 +70,7 @@ public:
|
|||||||
RHICommandQueue* CreateCommandQueue(const CommandQueueDesc& desc) override;
|
RHICommandQueue* CreateCommandQueue(const CommandQueueDesc& desc) override;
|
||||||
RHIShader* CompileShader(const ShaderCompileDesc& desc) override;
|
RHIShader* CompileShader(const ShaderCompileDesc& desc) override;
|
||||||
RHIPipelineState* CreatePipelineState(const GraphicsPipelineDesc& desc) override;
|
RHIPipelineState* CreatePipelineState(const GraphicsPipelineDesc& desc) override;
|
||||||
|
RHIPipelineLayout* CreatePipelineLayout(const RHIPipelineLayoutDesc& desc) override;
|
||||||
RHIFence* CreateFence(const FenceDesc& desc) override;
|
RHIFence* CreateFence(const FenceDesc& desc) override;
|
||||||
RHISampler* CreateSampler(const SamplerDesc& desc) override;
|
RHISampler* CreateSampler(const SamplerDesc& desc) override;
|
||||||
|
|
||||||
|
|||||||
42
engine/include/XCEngine/RHI/D3D12/D3D12PipelineLayout.h
Normal file
42
engine/include/XCEngine/RHI/D3D12/D3D12PipelineLayout.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <d3d12.h>
|
||||||
|
#include <wrl/client.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include "../RHIPipelineLayout.h"
|
||||||
|
#include "D3D12RootSignature.h"
|
||||||
|
|
||||||
|
using Microsoft::WRL::ComPtr;
|
||||||
|
|
||||||
|
namespace XCEngine {
|
||||||
|
namespace RHI {
|
||||||
|
|
||||||
|
class D3D12Device;
|
||||||
|
|
||||||
|
class D3D12PipelineLayout : public RHIPipelineLayout {
|
||||||
|
public:
|
||||||
|
D3D12PipelineLayout();
|
||||||
|
~D3D12PipelineLayout() override;
|
||||||
|
|
||||||
|
bool InitializeWithDevice(D3D12Device* device, const RHIPipelineLayoutDesc& desc);
|
||||||
|
void Shutdown() override;
|
||||||
|
bool Initialize(const RHIPipelineLayoutDesc& desc) override { return false; }
|
||||||
|
|
||||||
|
void* GetNativeHandle() override { return m_rootSignature.Get(); }
|
||||||
|
ID3D12RootSignature* GetRootSignature() const { return m_rootSignature.Get(); }
|
||||||
|
|
||||||
|
uint32_t GetRootParameterIndex(uint32_t shaderRegister) const;
|
||||||
|
bool HasRootParameter(uint32_t shaderRegister) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool InitializeInternal(D3D12Device* device, const RHIPipelineLayoutDesc& desc);
|
||||||
|
|
||||||
|
ComPtr<ID3D12RootSignature> m_rootSignature;
|
||||||
|
D3D12Device* m_device;
|
||||||
|
std::unordered_map<uint32_t, uint32_t> m_registerToRootIndex;
|
||||||
|
std::vector<D3D12_ROOT_PARAMETER> m_rootParameters;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace RHI
|
||||||
|
} // namespace XCEngine
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <dxgi1_4.h>
|
#include <dxgi1_4.h>
|
||||||
#include <wrl/client.h>
|
#include <wrl/client.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "../RHIShader.h"
|
#include "../RHIShader.h"
|
||||||
#include "D3D12Enums.h"
|
#include "D3D12Enums.h"
|
||||||
@@ -32,20 +33,18 @@ public:
|
|||||||
void* GetNativeHandle() override { return m_bytecode.Get(); }
|
void* GetNativeHandle() override { return m_bytecode.Get(); }
|
||||||
bool IsValid() const override { return m_bytecode != nullptr; }
|
bool IsValid() const override { return m_bytecode != nullptr; }
|
||||||
|
|
||||||
void Bind() override { }
|
const std::vector<UniformInfo>& GetUniformInfos() const override;
|
||||||
void Unbind() override { }
|
const UniformInfo* GetUniformInfo(const char* name) const override;
|
||||||
|
|
||||||
void SetInt(const char* name, int value) override { }
|
|
||||||
void SetFloat(const char* name, float value) override { }
|
|
||||||
void SetVec3(const char* name, float x, float y, float z) override { }
|
|
||||||
void SetVec4(const char* name, float x, float y, float z, float w) override { }
|
|
||||||
void SetMat4(const char* name, const float* value) override { }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void CacheUniformInfos() const;
|
||||||
|
|
||||||
ComPtr<ID3DBlob> m_bytecode;
|
ComPtr<ID3DBlob> m_bytecode;
|
||||||
ComPtr<ID3DBlob> m_error;
|
ComPtr<ID3DBlob> m_error;
|
||||||
ShaderType m_type;
|
ShaderType m_type;
|
||||||
InputLayoutDesc m_inputLayout;
|
InputLayoutDesc m_inputLayout;
|
||||||
|
mutable std::vector<UniformInfo> m_uniformInfos;
|
||||||
|
mutable bool m_uniformsCached = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace RHI
|
} // namespace RHI
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "../RHICommandList.h"
|
#include "../RHICommandList.h"
|
||||||
|
|
||||||
@@ -51,6 +52,21 @@ public:
|
|||||||
void ClearStencil(int stencil);
|
void ClearStencil(int stencil);
|
||||||
void ClearDepthStencil(float depth, int stencil);
|
void ClearDepthStencil(float depth, int stencil);
|
||||||
|
|
||||||
|
void SetShader(RHIShader* shader) override;
|
||||||
|
|
||||||
|
void SetUniformInt(const char* name, int value) override;
|
||||||
|
void SetUniformFloat(const char* name, float value) override;
|
||||||
|
void SetUniformVec3(const char* name, float x, float y, float z) override;
|
||||||
|
void SetUniformVec4(const char* name, float x, float y, float z, float w) override;
|
||||||
|
void SetUniformMat4(const char* name, const float* value) override;
|
||||||
|
|
||||||
|
void SetGlobalInt(const char* name, int value) override;
|
||||||
|
void SetGlobalFloat(const char* name, float value) override;
|
||||||
|
void SetGlobalVec3(const char* name, float x, float y, float z) override;
|
||||||
|
void SetGlobalVec4(const char* name, float x, float y, float z, float w) override;
|
||||||
|
void SetGlobalMat4(const char* name, const float* value) override;
|
||||||
|
void SetGlobalTexture(const char* name, RHIResourceView* texture) override;
|
||||||
|
|
||||||
void SetPipelineState(RHIPipelineState* pipelineState) override;
|
void SetPipelineState(RHIPipelineState* pipelineState) override;
|
||||||
void SetVertexBuffer(uint32_t slot, RHIResourceView* buffer, uint64_t offset) override;
|
void SetVertexBuffer(uint32_t slot, RHIResourceView* buffer, uint64_t offset) override;
|
||||||
void SetVertexBuffers(uint32_t startSlot, uint32_t count, RHIResourceView** buffers, const uint64_t* offsets, const uint32_t* strides) override;
|
void SetVertexBuffers(uint32_t startSlot, uint32_t count, RHIResourceView** buffers, const uint64_t* offsets, const uint32_t* strides) override;
|
||||||
@@ -176,6 +192,13 @@ private:
|
|||||||
unsigned int m_primitiveType;
|
unsigned int m_primitiveType;
|
||||||
unsigned int m_currentVAO;
|
unsigned int m_currentVAO;
|
||||||
unsigned int m_currentProgram;
|
unsigned int m_currentProgram;
|
||||||
|
OpenGLShader* m_currentShader;
|
||||||
|
std::unordered_map<std::string, int> m_globalIntCache;
|
||||||
|
std::unordered_map<std::string, float> m_globalFloatCache;
|
||||||
|
std::unordered_map<std::string, std::vector<float>> m_globalVec3Cache;
|
||||||
|
std::unordered_map<std::string, std::vector<float>> m_globalVec4Cache;
|
||||||
|
std::unordered_map<std::string, std::vector<float>> m_globalMat4Cache;
|
||||||
|
std::unordered_map<std::string, RHIResourceView*> m_globalTextureCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace RHI
|
} // namespace RHI
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ public:
|
|||||||
RHICommandQueue* CreateCommandQueue(const CommandQueueDesc& desc) override;
|
RHICommandQueue* CreateCommandQueue(const CommandQueueDesc& desc) override;
|
||||||
RHIShader* CompileShader(const ShaderCompileDesc& desc) override;
|
RHIShader* CompileShader(const ShaderCompileDesc& desc) override;
|
||||||
RHIPipelineState* CreatePipelineState(const GraphicsPipelineDesc& desc) override;
|
RHIPipelineState* CreatePipelineState(const GraphicsPipelineDesc& desc) override;
|
||||||
|
RHIPipelineLayout* CreatePipelineLayout(const RHIPipelineLayoutDesc& desc) override;
|
||||||
RHIFence* CreateFence(const FenceDesc& desc) override;
|
RHIFence* CreateFence(const FenceDesc& desc) override;
|
||||||
RHISampler* CreateSampler(const SamplerDesc& desc) override;
|
RHISampler* CreateSampler(const SamplerDesc& desc) override;
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ namespace RHI {
|
|||||||
|
|
||||||
class RHIResourceView;
|
class RHIResourceView;
|
||||||
class RHIPipelineState;
|
class RHIPipelineState;
|
||||||
|
class RHIShader;
|
||||||
|
|
||||||
struct DepthStencilState {
|
struct DepthStencilState {
|
||||||
bool depthEnable = true;
|
bool depthEnable = true;
|
||||||
@@ -54,6 +55,21 @@ public:
|
|||||||
|
|
||||||
virtual void TransitionBarrier(RHIResourceView* resource, ResourceStates stateBefore, ResourceStates stateAfter) = 0;
|
virtual void TransitionBarrier(RHIResourceView* resource, ResourceStates stateBefore, ResourceStates stateAfter) = 0;
|
||||||
|
|
||||||
|
virtual void SetShader(RHIShader* shader) = 0;
|
||||||
|
|
||||||
|
virtual void SetUniformInt(const char* name, int value) = 0;
|
||||||
|
virtual void SetUniformFloat(const char* name, float value) = 0;
|
||||||
|
virtual void SetUniformVec3(const char* name, float x, float y, float z) = 0;
|
||||||
|
virtual void SetUniformVec4(const char* name, float x, float y, float z, float w) = 0;
|
||||||
|
virtual void SetUniformMat4(const char* name, const float* value) = 0;
|
||||||
|
|
||||||
|
virtual void SetGlobalInt(const char* name, int value) = 0;
|
||||||
|
virtual void SetGlobalFloat(const char* name, float value) = 0;
|
||||||
|
virtual void SetGlobalVec3(const char* name, float x, float y, float z) = 0;
|
||||||
|
virtual void SetGlobalVec4(const char* name, float x, float y, float z, float w) = 0;
|
||||||
|
virtual void SetGlobalMat4(const char* name, const float* value) = 0;
|
||||||
|
virtual void SetGlobalTexture(const char* name, RHIResourceView* texture) = 0;
|
||||||
|
|
||||||
virtual void SetPipelineState(RHIPipelineState* pso) = 0;
|
virtual void SetPipelineState(RHIPipelineState* pso) = 0;
|
||||||
virtual void SetPrimitiveTopology(PrimitiveTopology topology) = 0;
|
virtual void SetPrimitiveTopology(PrimitiveTopology topology) = 0;
|
||||||
virtual void SetViewport(const Viewport& viewport) = 0;
|
virtual void SetViewport(const Viewport& viewport) = 0;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ class RHICommandList;
|
|||||||
class RHICommandQueue;
|
class RHICommandQueue;
|
||||||
class RHIShader;
|
class RHIShader;
|
||||||
class RHIPipelineState;
|
class RHIPipelineState;
|
||||||
|
class RHIPipelineLayout;
|
||||||
class RHIFence;
|
class RHIFence;
|
||||||
class RHISampler;
|
class RHISampler;
|
||||||
class RHIResourceView;
|
class RHIResourceView;
|
||||||
@@ -32,6 +33,7 @@ public:
|
|||||||
virtual RHICommandQueue* CreateCommandQueue(const CommandQueueDesc& desc) = 0;
|
virtual RHICommandQueue* CreateCommandQueue(const CommandQueueDesc& desc) = 0;
|
||||||
virtual RHIShader* CompileShader(const ShaderCompileDesc& desc) = 0;
|
virtual RHIShader* CompileShader(const ShaderCompileDesc& desc) = 0;
|
||||||
virtual RHIPipelineState* CreatePipelineState(const GraphicsPipelineDesc& desc) = 0;
|
virtual RHIPipelineState* CreatePipelineState(const GraphicsPipelineDesc& desc) = 0;
|
||||||
|
virtual RHIPipelineLayout* CreatePipelineLayout(const RHIPipelineLayoutDesc& desc) = 0;
|
||||||
virtual RHIFence* CreateFence(const FenceDesc& desc) = 0;
|
virtual RHIFence* CreateFence(const FenceDesc& desc) = 0;
|
||||||
virtual RHISampler* CreateSampler(const SamplerDesc& desc) = 0;
|
virtual RHISampler* CreateSampler(const SamplerDesc& desc) = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ public:
|
|||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
uint32_t arraySize;
|
uint32_t arraySize;
|
||||||
|
uint32_t offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual const std::vector<UniformInfo>& GetUniformInfos() const = 0;
|
virtual const std::vector<UniformInfo>& GetUniformInfos() const = 0;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#include "XCEngine/RHI/D3D12/D3D12CommandList.h"
|
#include "XCEngine/RHI/D3D12/D3D12CommandList.h"
|
||||||
#include "XCEngine/RHI/D3D12/D3D12ResourceView.h"
|
#include "XCEngine/RHI/D3D12/D3D12ResourceView.h"
|
||||||
#include "XCEngine/RHI/D3D12/D3D12PipelineState.h"
|
#include "XCEngine/RHI/D3D12/D3D12PipelineState.h"
|
||||||
|
#include "XCEngine/RHI/D3D12/D3D12Shader.h"
|
||||||
|
#include "XCEngine/RHI/D3D12/D3D12PipelineLayout.h"
|
||||||
|
|
||||||
namespace XCEngine {
|
namespace XCEngine {
|
||||||
namespace RHI {
|
namespace RHI {
|
||||||
@@ -10,7 +12,9 @@ D3D12CommandList::D3D12CommandList()
|
|||||||
, m_currentTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST)
|
, m_currentTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST)
|
||||||
, m_currentPipelineState(nullptr)
|
, m_currentPipelineState(nullptr)
|
||||||
, m_currentRootSignature(nullptr)
|
, m_currentRootSignature(nullptr)
|
||||||
, m_currentDescriptorHeap(nullptr) {
|
, m_currentDescriptorHeap(nullptr)
|
||||||
|
, m_currentShader(nullptr)
|
||||||
|
, m_currentPipelineLayout(nullptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D12CommandList::~D3D12CommandList() {
|
D3D12CommandList::~D3D12CommandList() {
|
||||||
@@ -55,6 +59,13 @@ void D3D12CommandList::Shutdown() {
|
|||||||
m_rtvHeap.Reset();
|
m_rtvHeap.Reset();
|
||||||
m_resourceStateMap.clear();
|
m_resourceStateMap.clear();
|
||||||
m_trackedResources.clear();
|
m_trackedResources.clear();
|
||||||
|
m_currentShader = nullptr;
|
||||||
|
m_globalIntCache.clear();
|
||||||
|
m_globalFloatCache.clear();
|
||||||
|
m_globalVec3Cache.clear();
|
||||||
|
m_globalVec4Cache.clear();
|
||||||
|
m_globalMat4Cache.clear();
|
||||||
|
m_globalTextureCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D12CommandList::Reset() {
|
void D3D12CommandList::Reset() {
|
||||||
@@ -64,6 +75,7 @@ void D3D12CommandList::Reset() {
|
|||||||
m_currentTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
m_currentTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
||||||
m_currentPipelineState = nullptr;
|
m_currentPipelineState = nullptr;
|
||||||
m_currentRootSignature = nullptr;
|
m_currentRootSignature = nullptr;
|
||||||
|
m_currentPipelineLayout = nullptr;
|
||||||
m_currentDescriptorHeap = nullptr;
|
m_currentDescriptorHeap = nullptr;
|
||||||
m_resourceStateMap.clear();
|
m_resourceStateMap.clear();
|
||||||
m_trackedResources.clear();
|
m_trackedResources.clear();
|
||||||
@@ -75,6 +87,103 @@ void D3D12CommandList::Close() {
|
|||||||
m_commandList->Close();
|
m_commandList->Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void D3D12CommandList::SetShader(RHIShader* shader) {
|
||||||
|
m_currentShader = static_cast<D3D12Shader*>(shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D12CommandList::SetPipelineLayout(D3D12PipelineLayout* layout) {
|
||||||
|
m_currentPipelineLayout = layout;
|
||||||
|
if (layout) {
|
||||||
|
SetRootSignature(layout->GetRootSignature());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D12CommandList::SetUniformInt(const char* name, int value) {
|
||||||
|
if (m_currentShader && m_currentPipelineLayout) {
|
||||||
|
const RHIShader::UniformInfo* info = m_currentShader->GetUniformInfo(name);
|
||||||
|
if (info) {
|
||||||
|
uint32_t rootIndex = m_currentPipelineLayout->GetRootParameterIndex(info->bindPoint);
|
||||||
|
if (rootIndex != UINT32_MAX) {
|
||||||
|
m_commandList->SetGraphicsRoot32BitConstants(rootIndex, 1, &value, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D12CommandList::SetUniformFloat(const char* name, float value) {
|
||||||
|
if (m_currentShader && m_currentPipelineLayout) {
|
||||||
|
const RHIShader::UniformInfo* info = m_currentShader->GetUniformInfo(name);
|
||||||
|
if (info) {
|
||||||
|
uint32_t rootIndex = m_currentPipelineLayout->GetRootParameterIndex(info->bindPoint);
|
||||||
|
if (rootIndex != UINT32_MAX) {
|
||||||
|
m_commandList->SetGraphicsRoot32BitConstants(rootIndex, 1, &value, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D12CommandList::SetUniformVec3(const char* name, float x, float y, float z) {
|
||||||
|
if (m_currentShader && m_currentPipelineLayout) {
|
||||||
|
const RHIShader::UniformInfo* info = m_currentShader->GetUniformInfo(name);
|
||||||
|
if (info) {
|
||||||
|
uint32_t rootIndex = m_currentPipelineLayout->GetRootParameterIndex(info->bindPoint);
|
||||||
|
if (rootIndex != UINT32_MAX) {
|
||||||
|
float values[3] = { x, y, z };
|
||||||
|
m_commandList->SetGraphicsRoot32BitConstants(rootIndex, 3, values, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D12CommandList::SetUniformVec4(const char* name, float x, float y, float z, float w) {
|
||||||
|
if (m_currentShader && m_currentPipelineLayout) {
|
||||||
|
const RHIShader::UniformInfo* info = m_currentShader->GetUniformInfo(name);
|
||||||
|
if (info) {
|
||||||
|
uint32_t rootIndex = m_currentPipelineLayout->GetRootParameterIndex(info->bindPoint);
|
||||||
|
if (rootIndex != UINT32_MAX) {
|
||||||
|
float values[4] = { x, y, z, w };
|
||||||
|
m_commandList->SetGraphicsRoot32BitConstants(rootIndex, 4, values, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D12CommandList::SetUniformMat4(const char* name, const float* value) {
|
||||||
|
if (m_currentShader && m_currentPipelineLayout) {
|
||||||
|
const RHIShader::UniformInfo* info = m_currentShader->GetUniformInfo(name);
|
||||||
|
if (info) {
|
||||||
|
uint32_t rootIndex = m_currentPipelineLayout->GetRootParameterIndex(info->bindPoint);
|
||||||
|
if (rootIndex != UINT32_MAX) {
|
||||||
|
m_commandList->SetGraphicsRoot32BitConstants(rootIndex, 16, value, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D12CommandList::SetGlobalInt(const char* name, int value) {
|
||||||
|
m_globalIntCache[name] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D12CommandList::SetGlobalFloat(const char* name, float value) {
|
||||||
|
m_globalFloatCache[name] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D12CommandList::SetGlobalVec3(const char* name, float x, float y, float z) {
|
||||||
|
m_globalVec3Cache[name] = { x, y, z };
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D12CommandList::SetGlobalVec4(const char* name, float x, float y, float z, float w) {
|
||||||
|
m_globalVec4Cache[name] = { x, y, z, w };
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D12CommandList::SetGlobalMat4(const char* name, const float* value) {
|
||||||
|
m_globalMat4Cache[name] = std::vector<float>(value, value + 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D12CommandList::SetGlobalTexture(const char* name, RHIResourceView* texture) {
|
||||||
|
m_globalTextureCache[name] = texture;
|
||||||
|
}
|
||||||
|
|
||||||
void D3D12CommandList::TransitionBarrier(RHIResourceView* resource, ResourceStates stateBefore, ResourceStates stateAfter) {
|
void D3D12CommandList::TransitionBarrier(RHIResourceView* resource, ResourceStates stateBefore, ResourceStates stateAfter) {
|
||||||
if (!resource || !resource->IsValid()) return;
|
if (!resource || !resource->IsValid()) return;
|
||||||
D3D12ResourceView* d3d12View = static_cast<D3D12ResourceView*>(resource);
|
D3D12ResourceView* d3d12View = static_cast<D3D12ResourceView*>(resource);
|
||||||
@@ -139,6 +248,9 @@ void D3D12CommandList::AliasBarrierInternal(ID3D12Resource* beforeResource, ID3D
|
|||||||
void D3D12CommandList::SetPipelineStateInternal(ID3D12PipelineState* pso) {
|
void D3D12CommandList::SetPipelineStateInternal(ID3D12PipelineState* pso) {
|
||||||
m_commandList->SetPipelineState(pso);
|
m_commandList->SetPipelineState(pso);
|
||||||
m_currentPipelineState = pso;
|
m_currentPipelineState = pso;
|
||||||
|
if (m_currentRootSignature) {
|
||||||
|
m_commandList->SetGraphicsRootSignature(m_currentRootSignature);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D12CommandList::SetRootSignature(ID3D12RootSignature* signature) {
|
void D3D12CommandList::SetRootSignature(ID3D12RootSignature* signature) {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "XCEngine/RHI/D3D12/D3D12DescriptorHeap.h"
|
#include "XCEngine/RHI/D3D12/D3D12DescriptorHeap.h"
|
||||||
#include "XCEngine/RHI/D3D12/D3D12QueryHeap.h"
|
#include "XCEngine/RHI/D3D12/D3D12QueryHeap.h"
|
||||||
#include "XCEngine/RHI/D3D12/D3D12RootSignature.h"
|
#include "XCEngine/RHI/D3D12/D3D12RootSignature.h"
|
||||||
|
#include "XCEngine/RHI/D3D12/D3D12PipelineLayout.h"
|
||||||
#include "XCEngine/RHI/D3D12/D3D12PipelineState.h"
|
#include "XCEngine/RHI/D3D12/D3D12PipelineState.h"
|
||||||
#include "XCEngine/RHI/D3D12/D3D12Sampler.h"
|
#include "XCEngine/RHI/D3D12/D3D12Sampler.h"
|
||||||
#include "XCEngine/RHI/D3D12/D3D12Texture.h"
|
#include "XCEngine/RHI/D3D12/D3D12Texture.h"
|
||||||
@@ -380,6 +381,15 @@ RHIPipelineState* D3D12Device::CreatePipelineState(const GraphicsPipelineDesc& d
|
|||||||
return pso;
|
return pso;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RHIPipelineLayout* D3D12Device::CreatePipelineLayout(const RHIPipelineLayoutDesc& desc) {
|
||||||
|
auto* pipelineLayout = new D3D12PipelineLayout();
|
||||||
|
if (!pipelineLayout->InitializeWithDevice(this, desc)) {
|
||||||
|
delete pipelineLayout;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return pipelineLayout;
|
||||||
|
}
|
||||||
|
|
||||||
RHIResourceView* D3D12Device::CreateRenderTargetView(RHITexture* texture, const ResourceViewDesc& desc) {
|
RHIResourceView* D3D12Device::CreateRenderTargetView(RHITexture* texture, const ResourceViewDesc& desc) {
|
||||||
auto* view = new D3D12ResourceView();
|
auto* view = new D3D12ResourceView();
|
||||||
auto* d3d12Texture = static_cast<D3D12Texture*>(texture);
|
auto* d3d12Texture = static_cast<D3D12Texture*>(texture);
|
||||||
|
|||||||
119
engine/src/RHI/D3D12/D3D12PipelineLayout.cpp
Normal file
119
engine/src/RHI/D3D12/D3D12PipelineLayout.cpp
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
#include "XCEngine/RHI/D3D12/D3D12PipelineLayout.h"
|
||||||
|
#include "XCEngine/RHI/D3D12/D3D12Device.h"
|
||||||
|
|
||||||
|
namespace XCEngine {
|
||||||
|
namespace RHI {
|
||||||
|
|
||||||
|
D3D12PipelineLayout::D3D12PipelineLayout()
|
||||||
|
: m_device(nullptr) {
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12PipelineLayout::~D3D12PipelineLayout() {
|
||||||
|
Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool D3D12PipelineLayout::InitializeWithDevice(D3D12Device* device, const RHIPipelineLayoutDesc& desc) {
|
||||||
|
return InitializeInternal(device, desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool D3D12PipelineLayout::InitializeInternal(D3D12Device* device, const RHIPipelineLayoutDesc& desc) {
|
||||||
|
if (!device) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_device = device;
|
||||||
|
|
||||||
|
m_rootParameters.clear();
|
||||||
|
m_registerToRootIndex.clear();
|
||||||
|
|
||||||
|
uint32_t rootIndex = 0;
|
||||||
|
|
||||||
|
if (desc.constantBufferCount > 0) {
|
||||||
|
D3D12_ROOT_PARAMETER param = D3D12RootSignature::Create32BitConstants(
|
||||||
|
0, desc.constantBufferCount * 16, ShaderVisibility::All, 0);
|
||||||
|
m_rootParameters.push_back(param);
|
||||||
|
for (uint32_t i = 0; i < desc.constantBufferCount; ++i) {
|
||||||
|
m_registerToRootIndex[i] = rootIndex;
|
||||||
|
}
|
||||||
|
rootIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desc.textureCount > 0) {
|
||||||
|
D3D12_DESCRIPTOR_RANGE range = D3D12RootSignature::CreateDescriptorRange(
|
||||||
|
D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 0, desc.textureCount, 0);
|
||||||
|
D3D12_ROOT_PARAMETER param = D3D12RootSignature::CreateDescriptorTable(1, &range, ShaderVisibility::All);
|
||||||
|
m_rootParameters.push_back(param);
|
||||||
|
for (uint32_t i = 0; i < desc.textureCount; ++i) {
|
||||||
|
m_registerToRootIndex[100 + i] = rootIndex;
|
||||||
|
}
|
||||||
|
rootIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desc.samplerCount > 0) {
|
||||||
|
D3D12_DESCRIPTOR_RANGE range = D3D12RootSignature::CreateDescriptorRange(
|
||||||
|
D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 0, desc.samplerCount, 0);
|
||||||
|
D3D12_ROOT_PARAMETER param = D3D12RootSignature::CreateDescriptorTable(1, &range, ShaderVisibility::All);
|
||||||
|
m_rootParameters.push_back(param);
|
||||||
|
for (uint32_t i = 0; i < desc.samplerCount; ++i) {
|
||||||
|
m_registerToRootIndex[200 + i] = rootIndex;
|
||||||
|
}
|
||||||
|
rootIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_rootParameters.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12_ROOT_SIGNATURE_DESC rootSigDesc = D3D12RootSignature::CreateDesc(
|
||||||
|
m_rootParameters.data(),
|
||||||
|
static_cast<uint32_t>(m_rootParameters.size()),
|
||||||
|
nullptr, 0,
|
||||||
|
D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
|
||||||
|
|
||||||
|
ID3D12Device* d3d12Device = device->GetDevice();
|
||||||
|
if (!d3d12Device) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ID3DBlob* signature = nullptr;
|
||||||
|
ID3DBlob* error = nullptr;
|
||||||
|
|
||||||
|
HRESULT hr = D3D12SerializeRootSignature(&rootSigDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
if (error) {
|
||||||
|
error->Release();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = d3d12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature));
|
||||||
|
signature->Release();
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D12PipelineLayout::Shutdown() {
|
||||||
|
m_rootSignature.Reset();
|
||||||
|
m_rootParameters.clear();
|
||||||
|
m_registerToRootIndex.clear();
|
||||||
|
m_device = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t D3D12PipelineLayout::GetRootParameterIndex(uint32_t shaderRegister) const {
|
||||||
|
auto it = m_registerToRootIndex.find(shaderRegister);
|
||||||
|
if (it != m_registerToRootIndex.end()) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
return UINT32_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool D3D12PipelineLayout::HasRootParameter(uint32_t shaderRegister) const {
|
||||||
|
return m_registerToRootIndex.find(shaderRegister) != m_registerToRootIndex.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace RHI
|
||||||
|
} // namespace XCEngine
|
||||||
@@ -1,11 +1,15 @@
|
|||||||
#include "XCEngine/RHI/D3D12/D3D12Shader.h"
|
#include "XCEngine/RHI/D3D12/D3D12Shader.h"
|
||||||
#include <d3dcompiler.h>
|
#include <d3dcompiler.h>
|
||||||
|
|
||||||
|
static const IID IID_ID3D12ShaderReflection = {
|
||||||
|
0x8e5c5a69, 0x5c6a, 0x427d, {0xb0, 0xdc, 0x27, 0x63, 0xae, 0xac, 0xe3, 0x75}
|
||||||
|
};
|
||||||
|
|
||||||
namespace XCEngine {
|
namespace XCEngine {
|
||||||
namespace RHI {
|
namespace RHI {
|
||||||
|
|
||||||
D3D12Shader::D3D12Shader()
|
D3D12Shader::D3D12Shader()
|
||||||
: m_type(ShaderType::Vertex) {
|
: m_type(ShaderType::Vertex), m_uniformsCached(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D12Shader::~D3D12Shader() {
|
D3D12Shader::~D3D12Shader() {
|
||||||
@@ -35,6 +39,7 @@ bool D3D12Shader::CompileFromFile(const wchar_t* filePath, const char* entryPoin
|
|||||||
m_type = ShaderType::Compute;
|
m_type = ShaderType::Compute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_uniformsCached = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,12 +55,87 @@ bool D3D12Shader::Compile(const void* sourceData, size_t sourceSize, const char*
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_uniformsCached = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D12Shader::Shutdown() {
|
void D3D12Shader::Shutdown() {
|
||||||
m_bytecode.Reset();
|
m_bytecode.Reset();
|
||||||
m_error.Reset();
|
m_error.Reset();
|
||||||
|
m_uniformInfos.clear();
|
||||||
|
m_uniformsCached = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D12Shader::CacheUniformInfos() const {
|
||||||
|
if (m_uniformsCached || !m_bytecode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_uniformInfos.clear();
|
||||||
|
|
||||||
|
ComPtr<ID3D12ShaderReflection> pReflection;
|
||||||
|
HRESULT hr = D3DReflect(m_bytecode->GetBufferPointer(), m_bytecode->GetBufferSize(),
|
||||||
|
IID_ID3D12ShaderReflection, (void**)&pReflection);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12_SHADER_DESC shaderDesc;
|
||||||
|
pReflection->GetDesc(&shaderDesc);
|
||||||
|
|
||||||
|
for (UINT i = 0; i < shaderDesc.BoundResources; ++i) {
|
||||||
|
D3D12_SHADER_INPUT_BIND_DESC bindDesc;
|
||||||
|
pReflection->GetResourceBindingDesc(i, &bindDesc);
|
||||||
|
|
||||||
|
UniformInfo info;
|
||||||
|
info.name = bindDesc.Name;
|
||||||
|
info.bindPoint = bindDesc.BindPoint;
|
||||||
|
info.arraySize = bindDesc.NumSamples;
|
||||||
|
|
||||||
|
switch (bindDesc.Type) {
|
||||||
|
case D3D_SIT_CBUFFER:
|
||||||
|
info.type = static_cast<uint32_t>(D3D_SIT_CBUFFER);
|
||||||
|
break;
|
||||||
|
case D3D_SIT_TEXTURE:
|
||||||
|
info.type = static_cast<uint32_t>(D3D_SIT_TEXTURE);
|
||||||
|
break;
|
||||||
|
case D3D_SIT_SAMPLER:
|
||||||
|
info.type = static_cast<uint32_t>(D3D_SIT_SAMPLER);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
info.type = static_cast<uint32_t>(bindDesc.Type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12_SHADER_BUFFER_DESC bufferDesc;
|
||||||
|
if (bindDesc.Type == D3D_SIT_CBUFFER) {
|
||||||
|
ID3D12ShaderReflectionConstantBuffer* pCB = pReflection->GetConstantBufferByIndex(bindDesc.BindPoint);
|
||||||
|
pCB->GetDesc(&bufferDesc);
|
||||||
|
info.size = bufferDesc.Size;
|
||||||
|
} else {
|
||||||
|
info.size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_uniformInfos.push_back(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_uniformsCached = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<RHIShader::UniformInfo>& D3D12Shader::GetUniformInfos() const {
|
||||||
|
CacheUniformInfos();
|
||||||
|
return m_uniformInfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RHIShader::UniformInfo* D3D12Shader::GetUniformInfo(const char* name) const {
|
||||||
|
CacheUniformInfos();
|
||||||
|
for (const auto& info : m_uniformInfos) {
|
||||||
|
if (info.name == name) {
|
||||||
|
return &info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const D3D12_SHADER_BYTECODE D3D12Shader::GetD3D12Bytecode() const {
|
const D3D12_SHADER_BYTECODE D3D12Shader::GetD3D12Bytecode() const {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "XCEngine/RHI/OpenGL/OpenGLCommandList.h"
|
#include "XCEngine/RHI/OpenGL/OpenGLCommandList.h"
|
||||||
#include "XCEngine/RHI/OpenGL/OpenGLResourceView.h"
|
#include "XCEngine/RHI/OpenGL/OpenGLResourceView.h"
|
||||||
#include "XCEngine/RHI/OpenGL/OpenGLPipelineState.h"
|
#include "XCEngine/RHI/OpenGL/OpenGLPipelineState.h"
|
||||||
|
#include "XCEngine/RHI/OpenGL/OpenGLShader.h"
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
|
|
||||||
namespace XCEngine {
|
namespace XCEngine {
|
||||||
@@ -24,7 +25,8 @@ static unsigned int ToGLPrimitiveType(PrimitiveType type) {
|
|||||||
OpenGLCommandList::OpenGLCommandList()
|
OpenGLCommandList::OpenGLCommandList()
|
||||||
: m_primitiveType(GL_TRIANGLES)
|
: m_primitiveType(GL_TRIANGLES)
|
||||||
, m_currentVAO(0)
|
, m_currentVAO(0)
|
||||||
, m_currentProgram(0) {
|
, m_currentProgram(0)
|
||||||
|
, m_currentShader(nullptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGLCommandList::~OpenGLCommandList() {
|
OpenGLCommandList::~OpenGLCommandList() {
|
||||||
@@ -423,6 +425,13 @@ void OpenGLCommandList::PopDebugGroup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandList::Shutdown() {
|
void OpenGLCommandList::Shutdown() {
|
||||||
|
m_currentShader = nullptr;
|
||||||
|
m_globalIntCache.clear();
|
||||||
|
m_globalFloatCache.clear();
|
||||||
|
m_globalVec3Cache.clear();
|
||||||
|
m_globalVec4Cache.clear();
|
||||||
|
m_globalMat4Cache.clear();
|
||||||
|
m_globalTextureCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandList::Reset() {
|
void OpenGLCommandList::Reset() {
|
||||||
@@ -431,6 +440,67 @@ void OpenGLCommandList::Reset() {
|
|||||||
void OpenGLCommandList::Close() {
|
void OpenGLCommandList::Close() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenGLCommandList::SetShader(RHIShader* shader) {
|
||||||
|
m_currentShader = static_cast<OpenGLShader*>(shader);
|
||||||
|
if (m_currentShader) {
|
||||||
|
UseShader(m_currentShader->GetID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLCommandList::SetUniformInt(const char* name, int value) {
|
||||||
|
if (m_currentShader) {
|
||||||
|
glUniform1i(glGetUniformLocation(m_currentShader->GetID(), name), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLCommandList::SetUniformFloat(const char* name, float value) {
|
||||||
|
if (m_currentShader) {
|
||||||
|
glUniform1f(glGetUniformLocation(m_currentShader->GetID(), name), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLCommandList::SetUniformVec3(const char* name, float x, float y, float z) {
|
||||||
|
if (m_currentShader) {
|
||||||
|
glUniform3f(glGetUniformLocation(m_currentShader->GetID(), name), x, y, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLCommandList::SetUniformVec4(const char* name, float x, float y, float z, float w) {
|
||||||
|
if (m_currentShader) {
|
||||||
|
glUniform4f(glGetUniformLocation(m_currentShader->GetID(), name), x, y, z, w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLCommandList::SetUniformMat4(const char* name, const float* value) {
|
||||||
|
if (m_currentShader) {
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(m_currentShader->GetID(), name), 1, GL_FALSE, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLCommandList::SetGlobalInt(const char* name, int value) {
|
||||||
|
m_globalIntCache[name] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLCommandList::SetGlobalFloat(const char* name, float value) {
|
||||||
|
m_globalFloatCache[name] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLCommandList::SetGlobalVec3(const char* name, float x, float y, float z) {
|
||||||
|
m_globalVec3Cache[name] = {x, y, z};
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLCommandList::SetGlobalVec4(const char* name, float x, float y, float z, float w) {
|
||||||
|
m_globalVec4Cache[name] = {x, y, z, w};
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLCommandList::SetGlobalMat4(const char* name, const float* value) {
|
||||||
|
m_globalMat4Cache[name] = std::vector<float>(value, value + 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLCommandList::SetGlobalTexture(const char* name, RHIResourceView* texture) {
|
||||||
|
m_globalTextureCache[name] = texture;
|
||||||
|
}
|
||||||
|
|
||||||
void OpenGLCommandList::TransitionBarrier(RHIResourceView* resource, ResourceStates stateBefore, ResourceStates stateAfter) {
|
void OpenGLCommandList::TransitionBarrier(RHIResourceView* resource, ResourceStates stateBefore, ResourceStates stateAfter) {
|
||||||
(void)resource;
|
(void)resource;
|
||||||
(void)stateBefore;
|
(void)stateBefore;
|
||||||
|
|||||||
@@ -456,6 +456,10 @@ RHIPipelineState* OpenGLDevice::CreatePipelineState(const GraphicsPipelineDesc&
|
|||||||
return pso;
|
return pso;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RHIPipelineLayout* OpenGLDevice::CreatePipelineLayout(const RHIPipelineLayoutDesc& desc) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
RHIFence* OpenGLDevice::CreateFence(const FenceDesc& desc) {
|
RHIFence* OpenGLDevice::CreateFence(const FenceDesc& desc) {
|
||||||
auto* fence = new OpenGLFence();
|
auto* fence = new OpenGLFence();
|
||||||
fence->Initialize(desc.initialValue > 0);
|
fence->Initialize(desc.initialValue > 0);
|
||||||
|
|||||||
@@ -260,8 +260,7 @@ void OpenGLShader::CacheUniformInfos() const {
|
|||||||
info.offset = static_cast<uint32_t>(values[2]);
|
info.offset = static_cast<uint32_t>(values[2]);
|
||||||
info.arraySize = static_cast<uint32_t>(values[3]);
|
info.arraySize = static_cast<uint32_t>(values[3]);
|
||||||
|
|
||||||
GLint size = 0;
|
GLint size = values[3];
|
||||||
glGetActiveUniformsiv(m_program, 1, &i, GL_SIZE, &size);
|
|
||||||
switch (values[1]) {
|
switch (values[1]) {
|
||||||
case GL_FLOAT: info.size = sizeof(GLfloat) * size; break;
|
case GL_FLOAT: info.size = sizeof(GLfloat) * size; break;
|
||||||
case GL_FLOAT_VEC2: info.size = sizeof(GLfloat) * 2 * size; break;
|
case GL_FLOAT_VEC2: info.size = sizeof(GLfloat) * 2 * size; break;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@@ -20,6 +19,7 @@
|
|||||||
#include "XCEngine/RHI/OpenGL/OpenGLShader.h"
|
#include "XCEngine/RHI/OpenGL/OpenGLShader.h"
|
||||||
#include "XCEngine/RHI/OpenGL/OpenGLDevice.h"
|
#include "XCEngine/RHI/OpenGL/OpenGLDevice.h"
|
||||||
#include "XCEngine/RHI/OpenGL/OpenGLPipelineState.h"
|
#include "XCEngine/RHI/OpenGL/OpenGLPipelineState.h"
|
||||||
|
#include "XCEngine/RHI/OpenGL/OpenGLCommandList.h"
|
||||||
|
|
||||||
using namespace XCEngine::Debug;
|
using namespace XCEngine::Debug;
|
||||||
using namespace XCEngine::RHI;
|
using namespace XCEngine::RHI;
|
||||||
@@ -264,13 +264,9 @@ Model* model = nullptr;
|
|||||||
OpenGLShader* shader = nullptr;
|
OpenGLShader* shader = nullptr;
|
||||||
OpenGLDevice* device = nullptr;
|
OpenGLDevice* device = nullptr;
|
||||||
OpenGLPipelineState* pipeline = nullptr;
|
OpenGLPipelineState* pipeline = nullptr;
|
||||||
|
OpenGLCommandList* cmdList = nullptr;
|
||||||
int frameCount = 0;
|
int frameCount = 0;
|
||||||
|
|
||||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
|
||||||
{
|
|
||||||
glViewport(0, 0, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Initialize()
|
void Initialize()
|
||||||
{
|
{
|
||||||
char exePath[MAX_PATH];
|
char exePath[MAX_PATH];
|
||||||
@@ -293,6 +289,8 @@ void Initialize()
|
|||||||
shader = new OpenGLShader();
|
shader = new OpenGLShader();
|
||||||
shader->CompileFromFile("Shaders/vertexshader.glsl", "Shaders/fragmentshader.glsl");
|
shader->CompileFromFile("Shaders/vertexshader.glsl", "Shaders/fragmentshader.glsl");
|
||||||
|
|
||||||
|
cmdList = new OpenGLCommandList();
|
||||||
|
|
||||||
Log("Initialization complete");
|
Log("Initialization complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,15 +334,16 @@ void Render()
|
|||||||
glm::mat4 modelMat = glm::mat4(1.0f);
|
glm::mat4 modelMat = glm::mat4(1.0f);
|
||||||
glm::mat4 view = glm::lookAt(glm::vec3(0, 0, 3), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
|
glm::mat4 view = glm::lookAt(glm::vec3(0, 0, 3), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
|
||||||
|
|
||||||
shader->SetMat4("view", &view[0][0]);
|
cmdList->SetShader(shader);
|
||||||
shader->SetMat4("model", &modelMat[0][0]);
|
cmdList->SetUniformMat4("view", &view[0][0]);
|
||||||
shader->SetMat4("projection", &projection[0][0]);
|
cmdList->SetUniformMat4("model", &modelMat[0][0]);
|
||||||
shader->SetVec3("viewPos", 0.0f, 0.0f, 3.0f);
|
cmdList->SetUniformMat4("projection", &projection[0][0]);
|
||||||
shader->SetFloat("material.shininess", 32.0f);
|
cmdList->SetUniformVec3("viewPos", 0.0f, 0.0f, 3.0f);
|
||||||
shader->SetVec3("dirLight.direction", 0.0f, -1.0f, 0.0f);
|
cmdList->SetUniformFloat("material.shininess", 32.0f);
|
||||||
shader->SetVec3("dirLight.ambient", 0.3f, 0.3f, 0.3f);
|
cmdList->SetUniformVec3("dirLight.direction", 0.0f, -1.0f, 0.0f);
|
||||||
shader->SetVec3("dirLight.diffuse", 0.8f, 0.8f, 0.8f);
|
cmdList->SetUniformVec3("dirLight.ambient", 0.3f, 0.3f, 0.3f);
|
||||||
shader->SetVec3("dirLight.specular", 0.5f, 0.5f, 0.5f);
|
cmdList->SetUniformVec3("dirLight.diffuse", 0.8f, 0.8f, 0.8f);
|
||||||
|
cmdList->SetUniformVec3("dirLight.specular", 0.5f, 0.5f, 0.5f);
|
||||||
|
|
||||||
model->Draw(shader);
|
model->Draw(shader);
|
||||||
}
|
}
|
||||||
@@ -361,24 +360,34 @@ int main()
|
|||||||
if (!device->CreateRenderWindow(SCR_WIDTH, SCR_HEIGHT, "XCRender", false))
|
if (!device->CreateRenderWindow(SCR_WIDTH, SCR_HEIGHT, "XCRender", false))
|
||||||
{
|
{
|
||||||
Log("Failed to create window");
|
Log("Failed to create window");
|
||||||
glfwTerminate();
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
glfwSetFramebufferSizeCallback(device->GetWindow(), framebuffer_size_callback);
|
const RHIDeviceInfo& info = device->GetDeviceInfo();
|
||||||
|
Log("OpenGL Version: %ls", info.version.c_str());
|
||||||
const OpenGLDeviceInfo& info = device->GetDeviceInfo();
|
Log("Renderer: %ls", info.renderer.c_str());
|
||||||
Log("OpenGL Version: %s", info.version.c_str());
|
|
||||||
Log("Renderer: %s", info.renderer.c_str());
|
|
||||||
|
|
||||||
Initialize();
|
Initialize();
|
||||||
|
|
||||||
device->PollEvents();
|
device->PollEvents();
|
||||||
|
|
||||||
while (!glfwWindowShouldClose(device->GetWindow()))
|
MSG msg = {};
|
||||||
|
bool shouldClose = false;
|
||||||
|
while (!shouldClose)
|
||||||
{
|
{
|
||||||
if (glfwGetKey(device->GetWindow(), GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
|
||||||
glfwSetWindowShouldClose(device->GetWindow(), GLFW_TRUE);
|
{
|
||||||
|
if (msg.message == WM_QUIT)
|
||||||
|
{
|
||||||
|
shouldClose = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessageW(&msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldClose)
|
||||||
|
break;
|
||||||
|
|
||||||
Render();
|
Render();
|
||||||
device->SwapBuffers();
|
device->SwapBuffers();
|
||||||
@@ -389,12 +398,13 @@ int main()
|
|||||||
if (frameCount == 30) {
|
if (frameCount == 30) {
|
||||||
Log("Saving screenshot at frame %d", frameCount);
|
Log("Saving screenshot at frame %d", frameCount);
|
||||||
SaveScreenshot("screenshot.ppm");
|
SaveScreenshot("screenshot.ppm");
|
||||||
glfwSetWindowShouldClose(device->GetWindow(), GLFW_TRUE);
|
PostMessageW(device->GetWindow(), WM_CLOSE, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Log("Application closed");
|
Log("Application closed");
|
||||||
|
|
||||||
|
delete cmdList;
|
||||||
delete pipeline;
|
delete pipeline;
|
||||||
delete device;
|
delete device;
|
||||||
delete shader;
|
delete shader;
|
||||||
|
|||||||
@@ -161,7 +161,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
|||||||
}
|
}
|
||||||
Log("[INFO] Shaders compiled successfully");
|
Log("[INFO] Shaders compiled successfully");
|
||||||
|
|
||||||
shader.SetInt("uTexture", 0);
|
commandList.SetShader(&shader);
|
||||||
|
commandList.SetUniformInt("uTexture", 0);
|
||||||
|
|
||||||
OpenGLPipelineState pipelineState;
|
OpenGLPipelineState pipelineState;
|
||||||
OpenGLRasterizerState rasterizerState;
|
OpenGLRasterizerState rasterizerState;
|
||||||
|
|||||||
@@ -283,10 +283,11 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
|||||||
int viewLoc = shader.GetUniformLocation("gViewMatrix");
|
int viewLoc = shader.GetUniformLocation("gViewMatrix");
|
||||||
int projLoc = shader.GetUniformLocation("gProjectionMatrix");
|
int projLoc = shader.GetUniformLocation("gProjectionMatrix");
|
||||||
Log("[DEBUG] Uniform locations - gModelMatrix: %d, gViewMatrix: %d, gProjectionMatrix: %d", modelLoc, viewLoc, projLoc);
|
Log("[DEBUG] Uniform locations - gModelMatrix: %d, gViewMatrix: %d, gProjectionMatrix: %d", modelLoc, viewLoc, projLoc);
|
||||||
shader.SetMat4("gModelMatrix", modelMatrix);
|
commandList.SetShader(&shader);
|
||||||
shader.SetMat4("gViewMatrix", viewMatrix);
|
commandList.SetUniformMat4("gModelMatrix", modelMatrix);
|
||||||
shader.SetMat4("gProjectionMatrix", projectionMatrix);
|
commandList.SetUniformMat4("gViewMatrix", viewMatrix);
|
||||||
shader.SetInt("uTexture", 0);
|
commandList.SetUniformMat4("gProjectionMatrix", projectionMatrix);
|
||||||
|
commandList.SetUniformInt("uTexture", 0);
|
||||||
|
|
||||||
OpenGLTexture texture;
|
OpenGLTexture texture;
|
||||||
if (!texture.LoadFromFile("Res/Image/earth.png", true)) {
|
if (!texture.LoadFromFile("Res/Image/earth.png", true)) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "fixtures/OpenGLTestFixture.h"
|
#include "fixtures/OpenGLTestFixture.h"
|
||||||
#include "XCEngine/RHI/OpenGL/OpenGLShader.h"
|
#include "XCEngine/RHI/OpenGL/OpenGLShader.h"
|
||||||
|
#include "XCEngine/RHI/OpenGL/OpenGLCommandList.h"
|
||||||
|
|
||||||
using namespace XCEngine::RHI;
|
using namespace XCEngine::RHI;
|
||||||
|
|
||||||
@@ -102,15 +103,17 @@ TEST_F(OpenGLTestFixture, Shader_SetUniforms) {
|
|||||||
shader.Compile(vs, fs);
|
shader.Compile(vs, fs);
|
||||||
ASSERT_TRUE(shader.IsValid());
|
ASSERT_TRUE(shader.IsValid());
|
||||||
|
|
||||||
shader.Use();
|
auto cmdList = static_cast<OpenGLCommandList*>(GetDevice()->CreateCommandList(CommandListDesc{}));
|
||||||
|
ASSERT_NE(cmdList, nullptr);
|
||||||
|
|
||||||
shader.SetInt("uIntValue", 42);
|
cmdList->SetShader(&shader);
|
||||||
shader.SetFloat("uFloatValue", 3.14f);
|
cmdList->SetUniformInt("uIntValue", 42);
|
||||||
shader.SetVec3("uVec3Value", 1.0f, 2.0f, 3.0f);
|
cmdList->SetUniformFloat("uFloatValue", 3.14f);
|
||||||
|
cmdList->SetUniformVec3("uVec3Value", 1.0f, 2.0f, 3.0f);
|
||||||
|
|
||||||
float mat[16] = {};
|
float mat[16] = {};
|
||||||
mat[0] = 1.0f; mat[5] = 1.0f; mat[10] = 1.0f; mat[15] = 1.0f;
|
mat[0] = 1.0f; mat[5] = 1.0f; mat[10] = 1.0f; mat[15] = 1.0f;
|
||||||
shader.SetMat4("uMat4Value", mat);
|
cmdList->SetUniformMat4("uMat4Value", mat);
|
||||||
|
|
||||||
GLenum error = glGetError();
|
GLenum error = glGetError();
|
||||||
EXPECT_EQ(error, GL_NO_ERROR);
|
EXPECT_EQ(error, GL_NO_ERROR);
|
||||||
|
|||||||
Reference in New Issue
Block a user