feat: 实现D3D12 RHI抽象层,修复PSO创建问题
- 添加RHI接口定义(IRHIDevice, ICommandList, IResource等) - 实现D3D12Device, D3D12CommandList, D3D12PipelineState等 - 修复RootSignature参数数量(3->4)与HelloEarth一致 - 修复DSV格式设置(Unknown->D24_UNorm_S8_UInt) - 添加Geometry Shader编译 - 创建XCEngineDemo项目验证RHI功能
This commit is contained in:
44
engine/include/XCEngine/RHI/ICommandList.h
Normal file
44
engine/include/XCEngine/RHI/ICommandList.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#include "RHIDefines.h"
|
||||
#include "IRHIResources.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
class IResource {
|
||||
public:
|
||||
virtual ~IResource() = default;
|
||||
virtual void* GetNativeResource() const = 0;
|
||||
};
|
||||
|
||||
class ICommandList {
|
||||
public:
|
||||
virtual ~ICommandList() = default;
|
||||
|
||||
virtual void Reset(void* allocator) = 0;
|
||||
virtual void Close() = 0;
|
||||
virtual void SetPipelineState(IPipelineState* pso) = 0;
|
||||
virtual void SetRootSignature(IRootSignature* signature) = 0;
|
||||
virtual void SetPrimitiveTopology(PrimitiveTopology topology) = 0;
|
||||
virtual void SetVertexBuffer(uint32_t slot, IResource* buffer, uint32_t offset = 0, uint32_t stride = 0) = 0;
|
||||
virtual void SetIndexBuffer(IResource* buffer, uint32_t offset = 0) = 0;
|
||||
virtual void SetDescriptorHeap(IDescriptorHeap* heap) = 0;
|
||||
virtual void SetGraphicsDescriptorTable(uint32_t rootParameterIndex, uint64_t baseDescriptor) = 0;
|
||||
virtual void SetComputeDescriptorTable(uint32_t rootParameterIndex, uint64_t baseDescriptor) = 0;
|
||||
virtual void DrawInstanced(uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertex, uint32_t startInstance) = 0;
|
||||
virtual void DrawIndexedInstanced(uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndex, int32_t baseVertex, uint32_t startInstance) = 0;
|
||||
virtual void Dispatch(uint32_t x, uint32_t y, uint32_t z) = 0;
|
||||
virtual void SetViewports(const Viewport* viewports, uint32_t count) = 0;
|
||||
virtual void SetScissorRects(const Rect* rects, uint32_t count) = 0;
|
||||
virtual void SetRenderTargets(void** targets, uint32_t count, void* depthStencil) = 0;
|
||||
virtual void ClearRenderTargetView(void* target, const float color[4]) = 0;
|
||||
virtual void ClearDepthStencilView(void* depth, float depthValue, uint8_t stencil) = 0;
|
||||
virtual void CopyResource(IResource* dst, const IResource* src) = 0;
|
||||
virtual void CopyBuffer(IResource* dst, uint64_t dstOffset, const IResource* src, uint64_t srcOffset, uint64_t size) = 0;
|
||||
virtual void ResourceBarrier(IResource* resource, ResourceStateFlag before, ResourceStateFlag after) = 0;
|
||||
virtual void* GetNativeCommandList() const = 0;
|
||||
};
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
161
engine/include/XCEngine/RHI/IRHIDevice.h
Normal file
161
engine/include/XCEngine/RHI/IRHIDevice.h
Normal file
@@ -0,0 +1,161 @@
|
||||
#pragma once
|
||||
|
||||
#include "RHIDefines.h"
|
||||
#include "ICommandList.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
struct ShaderBytecode {
|
||||
const void* bytecode = nullptr;
|
||||
uint64_t size = 0;
|
||||
};
|
||||
|
||||
struct InputElementDesc {
|
||||
const char* semanticName = nullptr;
|
||||
uint32_t semanticIndex = 0;
|
||||
Format format = Format::Unknown;
|
||||
uint32_t inputSlot = 0;
|
||||
uint32_t alignedByteOffset = 0;
|
||||
uint32_t inputSlotClass = 0; // 0 = per-vertex
|
||||
uint32_t instanceDataStepRate = 0;
|
||||
};
|
||||
|
||||
struct InputLayoutDesc {
|
||||
const InputElementDesc* elements = nullptr;
|
||||
uint32_t elementCount = 0;
|
||||
};
|
||||
|
||||
enum class PrimitiveTopologyType {
|
||||
Undefined,
|
||||
Point,
|
||||
Line,
|
||||
Triangle,
|
||||
Patch
|
||||
};
|
||||
|
||||
enum class BlendFactor {
|
||||
Zero,
|
||||
One,
|
||||
SrcColor,
|
||||
InvSrcColor,
|
||||
SrcAlpha,
|
||||
InvSrcAlpha,
|
||||
DestAlpha,
|
||||
InvDestAlpha,
|
||||
DestColor,
|
||||
InvDestColor
|
||||
};
|
||||
|
||||
enum class BlendOp {
|
||||
Add,
|
||||
Subtract,
|
||||
ReverseSubtract,
|
||||
Min,
|
||||
Max
|
||||
};
|
||||
|
||||
enum class ComparisonFunc {
|
||||
Never,
|
||||
Less,
|
||||
Equal,
|
||||
LessEqual,
|
||||
Greater,
|
||||
NotEqual,
|
||||
GreaterEqual,
|
||||
Always
|
||||
};
|
||||
|
||||
enum class CullMode {
|
||||
None,
|
||||
Front,
|
||||
Back
|
||||
};
|
||||
|
||||
enum class FillMode {
|
||||
Wireframe,
|
||||
Solid
|
||||
};
|
||||
|
||||
struct BlendState {
|
||||
bool enable = false;
|
||||
BlendFactor srcBlend = BlendFactor::SrcAlpha;
|
||||
BlendFactor destBlend = BlendFactor::InvSrcAlpha;
|
||||
BlendOp blendOp = BlendOp::Add;
|
||||
BlendFactor srcBlendAlpha = BlendFactor::One;
|
||||
BlendFactor destBlendAlpha = BlendFactor::Zero;
|
||||
BlendOp blendOpAlpha = BlendOp::Add;
|
||||
uint8_t renderTargetWriteMask = 0xF;
|
||||
};
|
||||
|
||||
struct DepthStencilState {
|
||||
bool depthEnable = true;
|
||||
bool stencilEnable = false;
|
||||
ComparisonFunc depthFunc = ComparisonFunc::Less;
|
||||
uint8_t depthWriteMask = 0xFF;
|
||||
uint8_t stencilReadMask = 0xFF;
|
||||
uint8_t stencilWriteMask = 0xFF;
|
||||
};
|
||||
|
||||
struct RasterizerState {
|
||||
FillMode fillMode = FillMode::Solid;
|
||||
CullMode cullMode = CullMode::Back;
|
||||
bool frontCounterClockwise = true;
|
||||
int32_t depthBias = 0;
|
||||
float depthBiasClamp = 0.0f;
|
||||
float slopeScaledDepthBias = 0.0f;
|
||||
bool depthClipEnable = true;
|
||||
bool scissorEnable = false;
|
||||
bool multisampleEnable = false;
|
||||
};
|
||||
|
||||
struct RenderState {
|
||||
BlendState blendState;
|
||||
DepthStencilState depthStencilState;
|
||||
RasterizerState rasterizerState;
|
||||
};
|
||||
|
||||
struct PipelineDesc {
|
||||
IRootSignature* rootSignature = nullptr;
|
||||
ShaderBytecode vertexShader;
|
||||
ShaderBytecode pixelShader;
|
||||
ShaderBytecode geometryShader;
|
||||
ShaderBytecode computeShader;
|
||||
RenderState renderState;
|
||||
InputLayoutDesc inputLayout;
|
||||
PrimitiveTopologyType topologyType = PrimitiveTopologyType::Triangle;
|
||||
uint32_t numRenderTargets = 1;
|
||||
Format rtvFormats[8] = { Format::Unknown };
|
||||
Format dsvFormat = Format::Unknown;
|
||||
SampleCount sampleCount = SampleCount::Count1;
|
||||
};
|
||||
|
||||
class IRHIDevice {
|
||||
public:
|
||||
virtual ~IRHIDevice() = default;
|
||||
|
||||
virtual GraphicsAPI GetAPI() const = 0;
|
||||
virtual const char* GetAPIName() const = 0;
|
||||
|
||||
virtual bool Initialize(void* windowHandle, uint32_t width, uint32_t height) = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
virtual bool CreateCommandQueue(ICommandQueue** queue, const CommandQueueDesc& desc) = 0;
|
||||
virtual bool CreateCommandAllocator(ICommandAllocator** allocator) = 0;
|
||||
virtual bool CreateCommandList(ICommandList** list, ICommandAllocator* allocator) = 0;
|
||||
virtual bool CreateFence(IFence** fence) = 0;
|
||||
|
||||
virtual bool CreateDescriptorHeap(IDescriptorHeap** heap, const DescriptorHeapDesc& desc) = 0;
|
||||
|
||||
virtual bool CreateRootSignature(IRootSignature** signature, const RootSignatureDesc& desc) = 0;
|
||||
virtual bool CreatePipelineState(IPipelineState** pso, const PipelineDesc& desc) = 0;
|
||||
|
||||
virtual bool CreateSwapChain(ISwapChain** swapChain, const SwapChainDesc& desc, void* windowHandle) = 0;
|
||||
|
||||
virtual ICommandQueue* GetCommandQueue() = 0;
|
||||
virtual void* GetNativeDevice() const = 0;
|
||||
virtual void* GetNativeAdapter() const = 0;
|
||||
};
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
97
engine/include/XCEngine/RHI/IRHIResources.h
Normal file
97
engine/include/XCEngine/RHI/IRHIResources.h
Normal file
@@ -0,0 +1,97 @@
|
||||
#pragma once
|
||||
|
||||
#include "RHIDefines.h"
|
||||
#include <unknwn.h>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
class ICommandQueue {
|
||||
public:
|
||||
virtual ~ICommandQueue() = default;
|
||||
|
||||
virtual void ExecuteCommandLists(void** lists, uint32_t count) = 0;
|
||||
virtual void Signal(void* fence, uint64_t value) = 0;
|
||||
virtual void Wait(void* fence, uint64_t value) = 0;
|
||||
virtual uint64_t GetTimestampFrequency() const = 0;
|
||||
virtual IUnknown* GetNativeQueue() const = 0;
|
||||
};
|
||||
|
||||
class ICommandAllocator {
|
||||
public:
|
||||
virtual ~ICommandAllocator() = default;
|
||||
virtual void Reset() = 0;
|
||||
};
|
||||
|
||||
class IFence {
|
||||
public:
|
||||
virtual ~IFence() = default;
|
||||
virtual uint64_t GetCompletedValue() const = 0;
|
||||
virtual void Signal(uint64_t value) = 0;
|
||||
virtual void Wait(uint64_t value) = 0;
|
||||
virtual void Wait(uint64_t value, uint64_t timeoutMs) = 0;
|
||||
};
|
||||
|
||||
class IDescriptorHeap {
|
||||
public:
|
||||
virtual ~IDescriptorHeap() = default;
|
||||
virtual DescriptorHeapType GetType() const = 0;
|
||||
virtual uint32_t GetDescriptorCount() const = 0;
|
||||
virtual void* GetCPUDescriptorHandle(uint32_t index) const = 0;
|
||||
virtual uint64_t GetGPUDescriptorHandle(uint32_t index) const = 0;
|
||||
virtual void SetName(const char* name) = 0;
|
||||
};
|
||||
|
||||
class ISwapChain {
|
||||
public:
|
||||
virtual ~ISwapChain() = default;
|
||||
virtual bool Initialize(const SwapChainDesc& desc, void* windowHandle) = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
virtual bool Present() = 0;
|
||||
virtual bool Resize(uint32_t width, uint32_t height) = 0;
|
||||
virtual uint32_t GetCurrentBufferIndex() const = 0;
|
||||
virtual void* GetBuffer(uint32_t index) = 0;
|
||||
virtual void SetFullscreen(bool fullscreen) = 0;
|
||||
virtual bool IsFullscreen() const = 0;
|
||||
};
|
||||
|
||||
enum class RootParameterType {
|
||||
DescriptorTable,
|
||||
Constants,
|
||||
CBV,
|
||||
SRV,
|
||||
UAV,
|
||||
Sampler
|
||||
};
|
||||
|
||||
struct RootParameter {
|
||||
RootParameterType type;
|
||||
uint32_t shaderRegister = 0;
|
||||
uint32_t registerSpace = 0;
|
||||
uint32_t num32BitValues = 4;
|
||||
ShaderVisibility visibility = ShaderVisibility::All;
|
||||
};
|
||||
|
||||
struct RootSignatureDesc {
|
||||
RootParameter* parameters = nullptr;
|
||||
uint32_t parameterCount = 0;
|
||||
uint32_t flags = 0;
|
||||
};
|
||||
|
||||
class IRootSignature {
|
||||
public:
|
||||
virtual ~IRootSignature() = default;
|
||||
virtual bool Initialize(const RootSignatureDesc& desc) = 0;
|
||||
virtual void SetName(const char* name) = 0;
|
||||
virtual void* GetNativeRootSignature() const = 0;
|
||||
};
|
||||
|
||||
class IPipelineState {
|
||||
public:
|
||||
virtual ~IPipelineState() = default;
|
||||
virtual void SetName(const char* name) = 0;
|
||||
virtual void* GetNativePipelineState() const = 0;
|
||||
};
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
27
engine/include/XCEngine/RHI/IResourceViews.h
Normal file
27
engine/include/XCEngine/RHI/IResourceViews.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include "RHIDefines.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
class IShaderResourceView {
|
||||
public:
|
||||
virtual ~IShaderResourceView() = default;
|
||||
virtual void* GetNativeSRV() const = 0;
|
||||
};
|
||||
|
||||
class IRenderTargetView {
|
||||
public:
|
||||
virtual ~IRenderTargetView() = default;
|
||||
virtual void* GetNativeRTV() const = 0;
|
||||
};
|
||||
|
||||
class IDepthStencilView {
|
||||
public:
|
||||
virtual ~IDepthStencilView() = default;
|
||||
virtual void* GetNativeDSV() const = 0;
|
||||
};
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
226
engine/include/XCEngine/RHI/RHIDefines.h
Normal file
226
engine/include/XCEngine/RHI/RHIDefines.h
Normal file
@@ -0,0 +1,226 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <dxgi1_4.h>
|
||||
#include <d3d12.h>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
enum class Format : uint32_t {
|
||||
Unknown = 0,
|
||||
R8_UNorm = 61,
|
||||
R8G8_UNorm = 49,
|
||||
R8G8B8A8_UNorm = 28,
|
||||
R16G16B16A16_Float = 10,
|
||||
R32G32B32A32_Float = 2,
|
||||
R16_Float = 54,
|
||||
R32_Float = 41,
|
||||
D16_UNorm = 55,
|
||||
D24_UNorm_S8_UInt = 45,
|
||||
D32_Float = 40,
|
||||
BC1_UNorm = 71,
|
||||
BC2_UNorm = 74,
|
||||
BC3_UNorm = 77,
|
||||
BC4_UNorm = 80,
|
||||
BC5_UNorm = 83,
|
||||
BC6H_UF16 = 95,
|
||||
BC7_UNorm = 98
|
||||
};
|
||||
|
||||
enum class PrimitiveTopology : uint8_t {
|
||||
Undefined = 0,
|
||||
PointList = 1,
|
||||
LineList = 2,
|
||||
LineStrip = 3,
|
||||
TriangleList = 4,
|
||||
TriangleStrip = 5,
|
||||
LineListAdj = 10,
|
||||
LineStripAdj = 11,
|
||||
TriangleListAdj = 12,
|
||||
TriangleStripAdj = 13,
|
||||
PatchList = 33
|
||||
};
|
||||
|
||||
enum class GraphicsAPI : uint8_t {
|
||||
Unknown,
|
||||
Direct3D11,
|
||||
Direct3D12,
|
||||
Vulkan,
|
||||
Metal,
|
||||
OpenGL
|
||||
};
|
||||
|
||||
enum class CommandListType : uint8_t {
|
||||
Direct,
|
||||
Compute,
|
||||
Copy,
|
||||
Bundle
|
||||
};
|
||||
|
||||
enum class ShaderVisibility : uint8_t {
|
||||
All = 0,
|
||||
Vertex = 1,
|
||||
Hull = 2,
|
||||
Domain = 3,
|
||||
Geometry = 4,
|
||||
Pixel = 5,
|
||||
Amplification = 6,
|
||||
Mesh = 7
|
||||
};
|
||||
|
||||
enum class DescriptorHeapType : uint8_t {
|
||||
CBV_SRV_UAV,
|
||||
Sampler,
|
||||
RTV,
|
||||
DSV
|
||||
};
|
||||
|
||||
enum class QueryType : uint8_t {
|
||||
Occlusion,
|
||||
Timestamp,
|
||||
PipelineStatistics
|
||||
};
|
||||
|
||||
enum class SampleCount : uint8_t {
|
||||
Count1 = 1,
|
||||
Count2 = 2,
|
||||
Count4 = 4,
|
||||
Count8 = 8
|
||||
};
|
||||
|
||||
struct CommandQueueDesc {
|
||||
CommandListType type = CommandListType::Direct;
|
||||
int32_t priority = 0;
|
||||
const char* name = nullptr;
|
||||
};
|
||||
|
||||
struct DescriptorHeapDesc {
|
||||
DescriptorHeapType type;
|
||||
uint32_t count = 0;
|
||||
bool shaderVisible = false;
|
||||
const char* name = nullptr;
|
||||
};
|
||||
|
||||
struct QueryHeapDesc {
|
||||
QueryType type;
|
||||
uint32_t count = 0;
|
||||
const char* name = nullptr;
|
||||
};
|
||||
|
||||
struct SwapChainDesc {
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
Format format = Format::Unknown;
|
||||
uint32_t bufferCount = 2;
|
||||
bool vsync = false;
|
||||
bool fullscreen = false;
|
||||
};
|
||||
|
||||
enum class ResourceStateFlag : uint32_t {
|
||||
Common = 0,
|
||||
VertexBuffer = 1 << 0,
|
||||
ConstantBuffer = 1 << 1,
|
||||
IndexBuffer = 1 << 2,
|
||||
RenderTarget = 1 << 3,
|
||||
UnorderedAccess = 1 << 4,
|
||||
DepthWrite = 1 << 5,
|
||||
DepthRead = 1 << 6,
|
||||
ShaderResource = 1 << 7,
|
||||
IndirectArgument = 1 << 8,
|
||||
CopyDest = 1 << 9,
|
||||
CopySource = 1 << 10,
|
||||
ResolveDest = 1 << 11,
|
||||
ResolveSource = 1 << 12,
|
||||
Present = 1 << 13,
|
||||
RaytracingAccelerationStructure = 1 << 14,
|
||||
ShadingRateSource = 1 << 15
|
||||
};
|
||||
|
||||
inline ResourceStateFlag operator|(ResourceStateFlag a, ResourceStateFlag b) {
|
||||
return static_cast<ResourceStateFlag>(static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
|
||||
}
|
||||
|
||||
inline ResourceStateFlag operator&(ResourceStateFlag a, ResourceStateFlag b) {
|
||||
return static_cast<ResourceStateFlag>(static_cast<uint32_t>(a) & static_cast<uint32_t>(b));
|
||||
}
|
||||
|
||||
struct Viewport {
|
||||
float topLeftX = 0.0f;
|
||||
float topLeftY = 0.0f;
|
||||
float width = 0.0f;
|
||||
float height = 0.0f;
|
||||
float minDepth = 0.0f;
|
||||
float maxDepth = 1.0f;
|
||||
};
|
||||
|
||||
struct Rect {
|
||||
int32_t left = 0;
|
||||
int32_t top = 0;
|
||||
int32_t right = 0;
|
||||
int32_t bottom = 0;
|
||||
};
|
||||
|
||||
struct Color {
|
||||
float r = 0.0f;
|
||||
float g = 0.0f;
|
||||
float b = 0.0f;
|
||||
float a = 1.0f;
|
||||
};
|
||||
|
||||
struct ClearValue {
|
||||
Color color;
|
||||
float depth = 1.0f;
|
||||
uint8_t stencil = 0;
|
||||
};
|
||||
|
||||
inline DXGI_FORMAT FormatToDXGIFormat(Format format) {
|
||||
switch (format) {
|
||||
case Format::Unknown: return DXGI_FORMAT_UNKNOWN;
|
||||
case Format::R8_UNorm: return DXGI_FORMAT_R8_UNORM;
|
||||
case Format::R8G8_UNorm: return DXGI_FORMAT_R8G8_UNORM;
|
||||
case Format::R8G8B8A8_UNorm: return DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
case Format::R16G16B16A16_Float: return DXGI_FORMAT_R16G16B16A16_FLOAT;
|
||||
case Format::R32G32B32A32_Float: return DXGI_FORMAT_R32G32B32A32_FLOAT;
|
||||
case Format::R16_Float: return DXGI_FORMAT_R16_FLOAT;
|
||||
case Format::R32_Float: return DXGI_FORMAT_R32_FLOAT;
|
||||
case Format::D16_UNorm: return DXGI_FORMAT_D16_UNORM;
|
||||
case Format::D24_UNorm_S8_UInt: return DXGI_FORMAT_D24_UNORM_S8_UINT;
|
||||
case Format::D32_Float: return DXGI_FORMAT_D32_FLOAT;
|
||||
case Format::BC1_UNorm: return DXGI_FORMAT_BC1_UNORM;
|
||||
case Format::BC2_UNorm: return DXGI_FORMAT_BC2_UNORM;
|
||||
case Format::BC3_UNorm: return DXGI_FORMAT_BC3_UNORM;
|
||||
case Format::BC4_UNorm: return DXGI_FORMAT_BC4_UNORM;
|
||||
case Format::BC5_UNorm: return DXGI_FORMAT_BC5_UNORM;
|
||||
case Format::BC6H_UF16: return DXGI_FORMAT_BC6H_UF16;
|
||||
case Format::BC7_UNorm: return DXGI_FORMAT_BC7_UNORM;
|
||||
default: return DXGI_FORMAT_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
inline Format DXGIFormatToFormat(DXGI_FORMAT dxgiFormat) {
|
||||
switch (dxgiFormat) {
|
||||
case DXGI_FORMAT_UNKNOWN: return Format::Unknown;
|
||||
case DXGI_FORMAT_R8_UNORM: return Format::R8_UNorm;
|
||||
case DXGI_FORMAT_R8G8_UNORM: return Format::R8G8_UNorm;
|
||||
case DXGI_FORMAT_R8G8B8A8_UNORM: return Format::R8G8B8A8_UNorm;
|
||||
case DXGI_FORMAT_R16G16B16A16_FLOAT: return Format::R16G16B16A16_Float;
|
||||
case DXGI_FORMAT_R32G32B32A32_FLOAT: return Format::R32G32B32A32_Float;
|
||||
case DXGI_FORMAT_R16_FLOAT: return Format::R16_Float;
|
||||
case DXGI_FORMAT_R32_FLOAT: return Format::R32_Float;
|
||||
case DXGI_FORMAT_D16_UNORM: return Format::D16_UNorm;
|
||||
case DXGI_FORMAT_D24_UNORM_S8_UINT: return Format::D24_UNorm_S8_UInt;
|
||||
case DXGI_FORMAT_D32_FLOAT: return Format::D32_Float;
|
||||
case DXGI_FORMAT_BC1_UNORM: return Format::BC1_UNorm;
|
||||
case DXGI_FORMAT_BC2_UNORM: return Format::BC2_UNorm;
|
||||
case DXGI_FORMAT_BC3_UNORM: return Format::BC3_UNorm;
|
||||
case DXGI_FORMAT_BC4_UNORM: return Format::BC4_UNorm;
|
||||
case DXGI_FORMAT_BC5_UNORM: return Format::BC5_UNorm;
|
||||
case DXGI_FORMAT_BC6H_UF16: return Format::BC6H_UF16;
|
||||
case DXGI_FORMAT_BC7_UNORM: return Format::BC7_UNorm;
|
||||
default: return Format::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
28
engine/include/XCEngine/RHI/RHISystem.h
Normal file
28
engine/include/XCEngine/RHI/RHISystem.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include "RHIDefines.h"
|
||||
#include "IRHIDevice.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
class RHISystem {
|
||||
public:
|
||||
static RHISystem& Get();
|
||||
|
||||
bool Initialize(GraphicsAPI api, void* windowHandle, uint32_t width, uint32_t height);
|
||||
void Shutdown();
|
||||
|
||||
IRHIDevice* GetDevice() { return m_device; }
|
||||
GraphicsAPI GetAPI() const { return m_api; }
|
||||
|
||||
private:
|
||||
RHISystem() = default;
|
||||
~RHISystem() = default;
|
||||
|
||||
GraphicsAPI m_api = GraphicsAPI::Unknown;
|
||||
IRHIDevice* m_device = nullptr;
|
||||
};
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
46
engine/include/XCEngine/Rendering/RenderContext.h
Normal file
46
engine/include/XCEngine/Rendering/RenderContext.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include <RHI\IRHIDevice.h>
|
||||
#include <RHI\IRHIResources.h>
|
||||
#include <Rendering\RenderTarget.h>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
class RenderContext {
|
||||
public:
|
||||
RenderContext(D3D12Device* device);
|
||||
~RenderContext();
|
||||
|
||||
bool Initialize(uint32_t width, uint32_t height);
|
||||
void Shutdown();
|
||||
|
||||
void BeginFrame();
|
||||
void EndFrame();
|
||||
|
||||
ICommandList* GetCommandList() { return m_commandList; }
|
||||
ISwapChain* GetSwapChain() { return m_swapChain; }
|
||||
IRenderTarget* GetCurrentRenderTarget() { return m_currentRenderTarget; }
|
||||
IDepthStencil* GetDepthStencil() { return m_depthStencil; }
|
||||
|
||||
void SetViewport(float width, float height);
|
||||
void SetScissor(int32_t width, int32_t height);
|
||||
void ClearRenderTarget(const float color[4]);
|
||||
void ClearDepthStencil();
|
||||
void Present();
|
||||
|
||||
private:
|
||||
D3D12Device* m_device = nullptr;
|
||||
ICommandAllocator* m_commandAllocator = nullptr;
|
||||
ICommandList* m_commandList = nullptr;
|
||||
IFence* m_fence = nullptr;
|
||||
ISwapChain* m_swapChain = nullptr;
|
||||
IRenderTarget* m_currentRenderTarget = nullptr;
|
||||
IDepthStencil* m_depthStencil = nullptr;
|
||||
uint64_t m_fenceValue = 0;
|
||||
uint32_t m_width = 0;
|
||||
uint32_t m_height = 0;
|
||||
};
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
26
engine/include/XCEngine/Rendering/RenderTarget.h
Normal file
26
engine/include/XCEngine/Rendering/RenderTarget.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <Rendering/Resources.h>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
class D3D12Device;
|
||||
class D3D12SwapChain;
|
||||
|
||||
class IDepthStencil : public ITexture2D {
|
||||
public:
|
||||
virtual ~IDepthStencil() = default;
|
||||
};
|
||||
|
||||
class IRenderTarget : public ITexture2D {
|
||||
public:
|
||||
virtual ~IRenderTarget() = default;
|
||||
};
|
||||
|
||||
bool CreateDepthStencil(D3D12Device* device, uint32_t width, uint32_t height, Format format, IDepthStencil** outDepthStencil);
|
||||
|
||||
bool CreateRenderTargetFromSwapChain(D3D12Device* device, D3D12SwapChain* swapChain, uint32_t bufferIndex, IRenderTarget** outRenderTarget);
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
74
engine/include/XCEngine/Rendering/Resources.h
Normal file
74
engine/include/XCEngine/Rendering/Resources.h
Normal file
@@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
#include <RHI\IRHIDevice.h>
|
||||
#include <RHI\IRHIResources.h>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
struct BufferDesc {
|
||||
uint64_t size = 0;
|
||||
uint32_t stride = 0;
|
||||
bool cpuAccessible = false;
|
||||
};
|
||||
|
||||
class IBuffer : public IResource {
|
||||
public:
|
||||
virtual ~IBuffer() = default;
|
||||
virtual const BufferDesc& GetDesc() const = 0;
|
||||
virtual void* Map() = 0;
|
||||
virtual void Unmap() = 0;
|
||||
};
|
||||
|
||||
class IVertexBuffer : public IBuffer {
|
||||
public:
|
||||
virtual ~IVertexBuffer() = default;
|
||||
};
|
||||
|
||||
class IIndexBuffer : public IBuffer {
|
||||
public:
|
||||
virtual ~IIndexBuffer() = default;
|
||||
};
|
||||
|
||||
class IConstantBuffer : public IBuffer {
|
||||
public:
|
||||
virtual ~IConstantBuffer() = default;
|
||||
};
|
||||
|
||||
struct TextureDesc {
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
uint32_t depth = 1;
|
||||
uint32_t mipLevels = 1;
|
||||
uint32_t arraySize = 1;
|
||||
Format format = Format::Unknown;
|
||||
bool renderTarget = false;
|
||||
bool depthStencil = false;
|
||||
};
|
||||
|
||||
class ITexture2D : public IResource {
|
||||
public:
|
||||
virtual ~ITexture2D() = default;
|
||||
virtual const TextureDesc& GetDesc() const = 0;
|
||||
virtual void CreateSRV() = 0;
|
||||
virtual void* GetSRV() = 0;
|
||||
virtual void CreateRTV() = 0;
|
||||
virtual void* GetRTV() = 0;
|
||||
virtual void CreateDSV() = 0;
|
||||
virtual void* GetDSV() = 0;
|
||||
};
|
||||
|
||||
class ITextureCube : public IResource {
|
||||
public:
|
||||
virtual ~ITextureCube() = default;
|
||||
virtual const TextureDesc& GetDesc() const = 0;
|
||||
};
|
||||
|
||||
class ISampler {
|
||||
public:
|
||||
virtual ~ISampler() = default;
|
||||
virtual void* GetNativeSampler() const = 0;
|
||||
};
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
20
engine/include/XCEngine/Rendering/Shader.h
Normal file
20
engine/include/XCEngine/Rendering/Shader.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <RHI\RHIDefines.h>
|
||||
#include <RHI\IRHIDevice.h>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
class IShader {
|
||||
public:
|
||||
virtual ~IShader() = default;
|
||||
virtual const ShaderBytecode& GetBytecode() const = 0;
|
||||
virtual const char* GetEntryPoint() const = 0;
|
||||
virtual const char* GetTarget() const = 0;
|
||||
};
|
||||
|
||||
bool CompileShader(const char* filePath, const char* entryPoint, const char* target, ShaderBytecode& outBytecode);
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
41
engine/include/XCEngine/Rendering/StaticMeshComponent.h
Normal file
41
engine/include/XCEngine/Rendering/StaticMeshComponent.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <Rendering\Resources.h>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
struct MeshVertex {
|
||||
float position[4];
|
||||
float texcoord[4];
|
||||
float normal[4];
|
||||
float tangent[4];
|
||||
};
|
||||
|
||||
struct SubMesh {
|
||||
IIndexBuffer* indexBuffer = nullptr;
|
||||
uint32_t indexCount = 0;
|
||||
};
|
||||
|
||||
class StaticMeshComponent {
|
||||
public:
|
||||
StaticMeshComponent();
|
||||
~StaticMeshComponent();
|
||||
|
||||
bool Initialize(ICommandList* commandList, const char* filePath);
|
||||
void Render(ICommandList* commandList);
|
||||
|
||||
IVertexBuffer* GetVertexBuffer() { return m_vertexBuffer; }
|
||||
uint32_t GetVertexCount() const { return m_vertexCount; }
|
||||
|
||||
private:
|
||||
IVertexBuffer* m_vertexBuffer = nullptr;
|
||||
uint32_t m_vertexCount = 0;
|
||||
std::unordered_map<std::string, SubMesh*> m_subMeshes;
|
||||
};
|
||||
|
||||
} // namespace RHI
|
||||
} // namespace XCEngine
|
||||
Reference in New Issue
Block a user