diff --git a/engine/include/XCEngine/Debug/RenderDocCapture.h b/engine/include/XCEngine/Debug/RenderDocCapture.h index cebf8b3a..b681c957 100644 --- a/engine/include/XCEngine/Debug/RenderDocCapture.h +++ b/engine/include/XCEngine/Debug/RenderDocCapture.h @@ -14,9 +14,11 @@ public: bool Initialize(void* device, void* window = nullptr); void Shutdown(); + void SetDevice(void* device); bool IsLoaded() const { return m_isLoaded; } bool IsCapturing() const; + uint32_t GetNumCaptures() const; void BeginCapture(const char* title = nullptr); void EndCapture(); diff --git a/engine/src/Debug/RenderDocCapture.cpp b/engine/src/Debug/RenderDocCapture.cpp index 45c305af..bc7b6c29 100644 --- a/engine/src/Debug/RenderDocCapture.cpp +++ b/engine/src/Debug/RenderDocCapture.cpp @@ -46,6 +46,10 @@ void RenderDocCapture::Shutdown() { } } +void RenderDocCapture::SetDevice(void* device) { + m_device = device; +} + bool RenderDocCapture::LoadRenderDoc() { char exePath[MAX_PATH]; GetModuleFileNameA(NULL, exePath, MAX_PATH); @@ -104,6 +108,13 @@ bool RenderDocCapture::IsCapturing() const { return m_api->IsFrameCapturing() != 0; } +uint32_t RenderDocCapture::GetNumCaptures() const { + if (!m_isLoaded || !m_api) { + return 0; + } + return m_api->GetNumCaptures(); +} + void RenderDocCapture::BeginCapture(const char* title) { if (!m_isLoaded || !m_api) { return; @@ -111,15 +122,14 @@ void RenderDocCapture::BeginCapture(const char* title) { if (title) { m_api->SetCaptureTitle(title); } - m_api->SetActiveWindow(m_device, m_window); - m_api->StartFrameCapture(m_device, m_window); + m_api->StartFrameCapture(m_device, nullptr); } void RenderDocCapture::EndCapture() { if (!m_isLoaded || !m_api) { return; } - m_api->EndFrameCapture(m_device, m_window); + m_api->EndFrameCapture(m_device, nullptr); } void RenderDocCapture::TriggerCapture() { diff --git a/engine/third_party/renderdoc/renderdoc.dll b/engine/third_party/renderdoc/renderdoc.dll new file mode 100644 index 00000000..01c09c96 Binary files /dev/null and b/engine/third_party/renderdoc/renderdoc.dll differ diff --git a/engine/third_party/renderdoc/renderdoc.pyd b/engine/third_party/renderdoc/renderdoc.pyd new file mode 100644 index 00000000..6382d37a Binary files /dev/null and b/engine/third_party/renderdoc/renderdoc.pyd differ diff --git a/tests/RHI/D3D12/integration/minimal/CMakeLists.txt b/tests/RHI/D3D12/integration/minimal/CMakeLists.txt index 2b9034c9..0dd7bc93 100644 --- a/tests/RHI/D3D12/integration/minimal/CMakeLists.txt +++ b/tests/RHI/D3D12/integration/minimal/CMakeLists.txt @@ -39,6 +39,9 @@ add_custom_command(TARGET D3D12_Minimal POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/GT.ppm $/ + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${ENGINE_ROOT_DIR}/third_party/renderdoc/renderdoc.dll + $/ ) add_test(NAME D3D12_Minimal_Integration diff --git a/tests/RHI/D3D12/integration/minimal/main.cpp b/tests/RHI/D3D12/integration/minimal/main.cpp index ef784af9..cf2c1743 100644 --- a/tests/RHI/D3D12/integration/minimal/main.cpp +++ b/tests/RHI/D3D12/integration/minimal/main.cpp @@ -24,6 +24,7 @@ #include "XCEngine/Debug/Logger.h" #include "XCEngine/Debug/ConsoleLogSink.h" #include "XCEngine/Debug/FileLogSink.h" +#include "XCEngine/Debug/RenderDocCapture.h" #include "XCEngine/Containers/String.h" using namespace XCEngine::RHI; @@ -228,12 +229,22 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine return -1; } + // Initialize RenderDoc capture (MUST be before D3D12 init) + if (!RenderDocCapture::Get().Initialize(nullptr, gHWND)) { + Log("[WARNING] Failed to initialize RenderDoc, frame capture will not be available"); + } else { + RenderDocCapture::Get().SetCaptureFilePath(".\\minimal_frame30"); + } + // Initialize D3D12 if (!InitD3D12()) { MessageBox(NULL, L"Failed to initialize D3D12", L"Error", MB_OK); return -1; } + // Set device for RenderDoc (must be called after D3D12 init) + RenderDocCapture::Get().SetDevice(gDevice.GetDevice()); + // Show window ShowWindow(gHWND, nShowCmd); UpdateWindow(gHWND); @@ -267,7 +278,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine frameCount++; if (frameCount >= targetFrameCount) { - Log("[INFO] Reached target frame count %d - taking screenshot before present!", targetFrameCount); + Log("[INFO] Reached target frame count %d - ending capture and taking screenshot!", targetFrameCount); + RenderDocCapture::Get().EndCapture(); ExecuteCommandList(); WaitForGPU(); Log("[INFO] GPU idle, taking screenshot..."); @@ -282,9 +294,14 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine } else { Log("[ERROR] Screenshot failed"); } + Log("[INFO] RenderDoc capture completed"); break; } + if (frameCount == targetFrameCount - 1) { + RenderDocCapture::Get().BeginCapture("Minimal_Test_Frame30"); + } + EndRender(); // Execute @@ -296,6 +313,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine } // Shutdown + RenderDocCapture::Get().Shutdown(); gCommandList.Shutdown(); gCommandAllocator.Shutdown(); gSwapChain.Shutdown();