fix: D3D12 screenshot implementation and tests

This commit is contained in:
2026-03-20 02:35:59 +08:00
parent 070b444f8f
commit 77ef74bec6
21 changed files with 762 additions and 919 deletions

View File

@@ -6,9 +6,11 @@
namespace XCEngine {
namespace RHI {
class D3D12CommandQueue;
class D3D12Screenshot {
public:
static bool Capture(ID3D12Device* device,
static bool Capture(ID3D12Device* device,
ID3D12CommandQueue* commandQueue,
ID3D12Resource* renderTarget,
const char* filename,

View File

@@ -73,11 +73,23 @@ uint64_t D3D12CommandQueue::GetCompletedValue() {
}
void D3D12CommandQueue::WaitForIdle() {
ID3D12Fence* fence = nullptr;
HRESULT hResult = m_commandQueue->GetDevice(IID_PPV_ARGS(&fence));
if (SUCCEEDED(hResult)) {
m_commandQueue->Wait(fence, UINT64_MAX);
fence->Release();
// Get the device from the command queue
ID3D12Device* device = nullptr;
HRESULT hr = m_commandQueue->GetDevice(IID_PPV_ARGS(&device));
if (SUCCEEDED(hr)) {
// Create a fence to signal when queue is idle
ID3D12Fence* fence = nullptr;
hr = device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence));
if (SUCCEEDED(hr)) {
// Signal the fence
m_commandQueue->Signal(fence, 1);
// Wait for it to complete
while (fence->GetCompletedValue() < 1) {
Sleep(1);
}
fence->Release();
}
device->Release();
}
}

View File

@@ -21,7 +21,24 @@ bool D3D12Screenshot::CopyToReadbackAndSave(ID3D12Device* device,
const char* filename,
uint32_t width,
uint32_t height) {
if (!device) {
XCEngine::Debug::Logger::Get().Error(XCEngine::Debug::LogCategory::Rendering, "Screenshot: device is null");
return false;
}
if (!commandQueue) {
XCEngine::Debug::Logger::Get().Error(XCEngine::Debug::LogCategory::Rendering, "Screenshot: commandQueue is null");
return false;
}
if (!renderTarget) {
XCEngine::Debug::Logger::Get().Error(XCEngine::Debug::LogCategory::Rendering, "Screenshot: renderTarget is null");
return false;
}
D3D12_RESOURCE_DESC rtDesc = renderTarget->GetDesc();
if (rtDesc.Width == 0 || rtDesc.Height == 0) {
XCEngine::Debug::Logger::Get().Error(XCEngine::Debug::LogCategory::Rendering, "Screenshot: invalid render target desc");
return false;
}
D3D12_PLACED_SUBRESOURCE_FOOTPRINT layout = {};
UINT64 totalSize = 0;
@@ -165,4 +182,4 @@ bool D3D12Screenshot::CopyToReadbackAndSave(ID3D12Device* device,
}
} // namespace RHI
} // namespace XCEngine
} // namespace XCEngine