feat(RHI): 实现 RHICommandQueue 抽象基类
This commit is contained in:
@@ -694,6 +694,72 @@ public:
|
|||||||
3. **底层逃逸**:通过 `GetNativeDevice()` 直接访问原生 API
|
3. **底层逃逸**:通过 `GetNativeDevice()` 直接访问原生 API
|
||||||
|
|
||||||
|
|
||||||
|
### 5.11 命令队列(RHICommandQueue)抽象设计
|
||||||
|
|
||||||
|
#### 5.11.1 设计理念对应
|
||||||
|
|
||||||
|
| 差异点 | 设计理念 | 处理方案 |
|
||||||
|
|--------|---------|---------|
|
||||||
|
| 初始化参数差异 | 求同存异 | 后端各自实现初始化 |
|
||||||
|
| 执行命令差异 | 特性降级 | D3D12 实现,OpenGL 空实现 |
|
||||||
|
| 同步机制差异 | 特性降级 | D3D12 实现,OpenGL 空实现 |
|
||||||
|
| 句柄类型差异 | 底层逃逸 | 统一返回 void* |
|
||||||
|
|
||||||
|
#### 5.11.2 现有实现对比
|
||||||
|
|
||||||
|
| 功能 | D3D12CommandQueue | OpenGL | 处理方案 |
|
||||||
|
|------|-------------------|--------|----------|
|
||||||
|
| 初始化 | Initialize(device, type) | 无 | OpenGL 空实现 |
|
||||||
|
| 执行命令 | ExecuteCommandLists() | 无 | OpenGL 空实现 |
|
||||||
|
| 信号同步 | Signal/Wait | 无 | OpenGL 空实现 |
|
||||||
|
| 空闲等待 | WaitForIdle() | 无 | OpenGL 空实现 |
|
||||||
|
| 句柄 | ID3D12CommandQueue* | 无 | GetNativeHandle |
|
||||||
|
|
||||||
|
#### 5.11.3 抽象接口定义
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
class RHICommandQueue {
|
||||||
|
public:
|
||||||
|
virtual ~RHICommandQueue() = default;
|
||||||
|
|
||||||
|
virtual void Shutdown() = 0;
|
||||||
|
|
||||||
|
virtual void ExecuteCommandLists(uint32_t count, void** lists) = 0;
|
||||||
|
virtual void Signal(RHIFence* fence, uint64_t value) = 0;
|
||||||
|
virtual void Wait(RHIFence* fence, uint64_t value) = 0;
|
||||||
|
virtual uint64_t GetCompletedValue() = 0;
|
||||||
|
virtual void WaitForIdle() = 0;
|
||||||
|
|
||||||
|
virtual CommandQueueType GetType() const = 0;
|
||||||
|
virtual uint64_t GetTimestampFrequency() const = 0;
|
||||||
|
|
||||||
|
virtual void* GetNativeHandle() = 0;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 5.11.4 差异处理策略
|
||||||
|
|
||||||
|
1. **初始化参数差异(求同存异)**
|
||||||
|
- D3D12:需要 device + type 参数
|
||||||
|
- OpenGL:无对等概念
|
||||||
|
- 解决:Device 的 CreateCommandQueue() 统一接收 CommandQueueDesc
|
||||||
|
|
||||||
|
2. **执行命令差异(特性降级)**
|
||||||
|
- D3D12:ExecuteCommandLists() 提交命令列表
|
||||||
|
- OpenGL:状态机模型,无命令队列概念
|
||||||
|
- 解决:OpenGL 空实现
|
||||||
|
|
||||||
|
3. **同步机制差异(特性降级)**
|
||||||
|
- D3D12:Signal/Wait/Fence 完整实现
|
||||||
|
- OpenGL:无对等概念
|
||||||
|
- 解决:OpenGL 空实现
|
||||||
|
|
||||||
|
4. **句柄类型差异(底层逃逸)**
|
||||||
|
- D3D12:ID3D12CommandQueue*
|
||||||
|
- OpenGL:无对等概念
|
||||||
|
- 解决:GetNativeHandle() 返回 void*
|
||||||
|
|
||||||
|
|
||||||
## 6. 后端实现示例
|
## 6. 后端实现示例
|
||||||
### 6.1 D3D12 设备实现(D3D12Device.h)
|
### 6.1 D3D12 设备实现(D3D12Device.h)
|
||||||
```cpp
|
```cpp
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <d3d12.h>
|
#include <d3d12.h>
|
||||||
#include <wrl/client.h>
|
#include <wrl/client.h>
|
||||||
|
|
||||||
|
#include "../RHICommandQueue.h"
|
||||||
#include "../RHIEnums.h"
|
#include "../RHIEnums.h"
|
||||||
#include "D3D12Enum.h"
|
#include "D3D12Enum.h"
|
||||||
|
|
||||||
@@ -13,26 +14,29 @@ namespace RHI {
|
|||||||
|
|
||||||
class D3D12Fence;
|
class D3D12Fence;
|
||||||
|
|
||||||
class D3D12CommandQueue {
|
class D3D12CommandQueue : public RHICommandQueue {
|
||||||
public:
|
public:
|
||||||
D3D12CommandQueue();
|
D3D12CommandQueue();
|
||||||
~D3D12CommandQueue();
|
~D3D12CommandQueue() override;
|
||||||
|
|
||||||
bool Initialize(ID3D12Device* device, CommandQueueType type = CommandQueueType::Direct);
|
bool Initialize(ID3D12Device* device, CommandQueueType type = CommandQueueType::Direct);
|
||||||
void Shutdown();
|
void Shutdown() override;
|
||||||
|
|
||||||
void ExecuteCommandLists(uint32_t count, ID3D12CommandList** lists);
|
void ExecuteCommandLists(uint32_t count, void** lists) override;
|
||||||
void Signal(D3D12Fence* fence, uint64_t value);
|
void Signal(RHIFence* fence, uint64_t value) override;
|
||||||
void Signal(ID3D12Fence* fence, uint64_t value);
|
void Wait(RHIFence* fence, uint64_t value) override;
|
||||||
void Wait(D3D12Fence* fence, uint64_t value);
|
uint64_t GetCompletedValue() override;
|
||||||
void Wait(ID3D12Fence* fence, uint64_t value);
|
void WaitForIdle() override;
|
||||||
uint64_t GetCompletedValue();
|
|
||||||
void WaitForIdle();
|
|
||||||
|
|
||||||
CommandQueueType GetType() const { return m_type; }
|
CommandQueueType GetType() const override { return m_type; }
|
||||||
uint64_t GetTimestampFrequency() const { return m_timestampFrequency; }
|
uint64_t GetTimestampFrequency() const override { return m_timestampFrequency; }
|
||||||
|
|
||||||
ID3D12CommandQueue* GetCommandQueue() const { return m_commandQueue.Get(); }
|
ID3D12CommandQueue* GetCommandQueue() const { return m_commandQueue.Get(); }
|
||||||
|
void* GetNativeHandle() override { return m_commandQueue.Get(); }
|
||||||
|
|
||||||
|
void ExecuteCommandListsInternal(uint32_t count, ID3D12CommandList** lists);
|
||||||
|
void Signal(ID3D12Fence* fence, uint64_t value);
|
||||||
|
void Wait(ID3D12Fence* fence, uint64_t value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ComPtr<ID3D12CommandQueue> m_commandQueue;
|
ComPtr<ID3D12CommandQueue> m_commandQueue;
|
||||||
|
|||||||
28
engine/include/XCEngine/RHI/OpenGL/OpenGLCommandQueue.h
Normal file
28
engine/include/XCEngine/RHI/OpenGL/OpenGLCommandQueue.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../RHICommandQueue.h"
|
||||||
|
|
||||||
|
namespace XCEngine {
|
||||||
|
namespace RHI {
|
||||||
|
|
||||||
|
class OpenGLCommandQueue : public RHICommandQueue {
|
||||||
|
public:
|
||||||
|
OpenGLCommandQueue();
|
||||||
|
~OpenGLCommandQueue() override;
|
||||||
|
|
||||||
|
void Shutdown() override;
|
||||||
|
|
||||||
|
void ExecuteCommandLists(uint32_t count, void** lists) override;
|
||||||
|
void Signal(RHIFence* fence, uint64_t value) override;
|
||||||
|
void Wait(RHIFence* fence, uint64_t value) override;
|
||||||
|
uint64_t GetCompletedValue() override;
|
||||||
|
void WaitForIdle() override;
|
||||||
|
|
||||||
|
CommandQueueType GetType() const override { return CommandQueueType::Direct; }
|
||||||
|
uint64_t GetTimestampFrequency() const override { return 0; }
|
||||||
|
|
||||||
|
void* GetNativeHandle() override { return nullptr; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace RHI
|
||||||
|
} // namespace XCEngine
|
||||||
29
engine/include/XCEngine/RHI/RHICommandQueue.h
Normal file
29
engine/include/XCEngine/RHI/RHICommandQueue.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "RHITypes.h"
|
||||||
|
|
||||||
|
namespace XCEngine {
|
||||||
|
namespace RHI {
|
||||||
|
|
||||||
|
class RHIFence;
|
||||||
|
|
||||||
|
class RHICommandQueue {
|
||||||
|
public:
|
||||||
|
virtual ~RHICommandQueue() = default;
|
||||||
|
|
||||||
|
virtual void Shutdown() = 0;
|
||||||
|
|
||||||
|
virtual void ExecuteCommandLists(uint32_t count, void** lists) = 0;
|
||||||
|
virtual void Signal(RHIFence* fence, uint64_t value) = 0;
|
||||||
|
virtual void Wait(RHIFence* fence, uint64_t value) = 0;
|
||||||
|
virtual uint64_t GetCompletedValue() = 0;
|
||||||
|
virtual void WaitForIdle() = 0;
|
||||||
|
|
||||||
|
virtual CommandQueueType GetType() const = 0;
|
||||||
|
virtual uint64_t GetTimestampFrequency() const = 0;
|
||||||
|
|
||||||
|
virtual void* GetNativeHandle() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace RHI
|
||||||
|
} // namespace XCEngine
|
||||||
@@ -36,13 +36,17 @@ void D3D12CommandQueue::Shutdown() {
|
|||||||
m_commandQueue.Reset();
|
m_commandQueue.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D12CommandQueue::ExecuteCommandLists(uint32_t count, ID3D12CommandList** lists) {
|
void D3D12CommandQueue::ExecuteCommandLists(uint32_t count, void** lists) {
|
||||||
|
ExecuteCommandListsInternal(count, reinterpret_cast<ID3D12CommandList**>(lists));
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D12CommandQueue::ExecuteCommandListsInternal(uint32_t count, ID3D12CommandList** lists) {
|
||||||
m_commandQueue->ExecuteCommandLists(count, lists);
|
m_commandQueue->ExecuteCommandLists(count, lists);
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D12CommandQueue::Signal(D3D12Fence* fence, uint64_t value) {
|
void D3D12CommandQueue::Signal(RHIFence* fence, uint64_t value) {
|
||||||
if (fence) {
|
if (fence) {
|
||||||
m_commandQueue->Signal(fence->GetFence(), value);
|
m_commandQueue->Signal(static_cast<D3D12Fence*>(fence)->GetFence(), value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,9 +56,9 @@ void D3D12CommandQueue::Signal(ID3D12Fence* fence, uint64_t value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D12CommandQueue::Wait(D3D12Fence* fence, uint64_t value) {
|
void D3D12CommandQueue::Wait(RHIFence* fence, uint64_t value) {
|
||||||
if (fence) {
|
if (fence) {
|
||||||
m_commandQueue->Wait(fence->GetFence(), value);
|
m_commandQueue->Wait(static_cast<D3D12Fence*>(fence)->GetFence(), value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
33
engine/src/RHI/OpenGL/OpenGLCommandQueue.cpp
Normal file
33
engine/src/RHI/OpenGL/OpenGLCommandQueue.cpp
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#include "XCEngine/RHI/OpenGL/OpenGLCommandQueue.h"
|
||||||
|
|
||||||
|
namespace XCEngine {
|
||||||
|
namespace RHI {
|
||||||
|
|
||||||
|
OpenGLCommandQueue::OpenGLCommandQueue() {
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenGLCommandQueue::~OpenGLCommandQueue() {
|
||||||
|
Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLCommandQueue::Shutdown() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLCommandQueue::ExecuteCommandLists(uint32_t count, void** lists) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLCommandQueue::Signal(RHIFence* fence, uint64_t value) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLCommandQueue::Wait(RHIFence* fence, uint64_t value) {
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t OpenGLCommandQueue::GetCompletedValue() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLCommandQueue::WaitForIdle() {
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace RHI
|
||||||
|
} // namespace XCEngine
|
||||||
Reference in New Issue
Block a user