fix: D3D12 screenshot implementation and tests
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user