Fix RenderDoc OpenGL capture - pass HGLRC instead of HDC
Critical fix: For OpenGL, RenderDoc requires HGLRC (OpenGL context) as the device pointer, not HDC. Previously OpenGL test incorrectly passed HDC which caused capture to silently fail (NumCaptures=0). Changes: - OpenGLDevice: Add wglCreateContextAttribsARB support for debug context - OpenGLDevice: Create OpenGL 4.6 core profile with debug flag - RenderDocCapture: Pass correct window to SetActiveWindow/StartFrameCapture - OpenGL test: Pass HGLRC via SetDevice(), use BeginCapture/EndCapture Fix root cause identified via RenderDoc docs analysis: 'For OpenGL it must be the HGLRC, GLXContext, or EGLContext'
This commit is contained in:
@@ -122,14 +122,19 @@ void RenderDocCapture::BeginCapture(const char* title) {
|
||||
if (title) {
|
||||
m_api->SetCaptureTitle(title);
|
||||
}
|
||||
m_api->StartFrameCapture(m_device, nullptr);
|
||||
|
||||
SetForegroundWindow((HWND)m_window);
|
||||
SetFocus((HWND)m_window);
|
||||
|
||||
m_api->SetActiveWindow(m_device, m_window);
|
||||
m_api->StartFrameCapture(m_device, m_window);
|
||||
}
|
||||
|
||||
void RenderDocCapture::EndCapture() {
|
||||
if (!m_isLoaded || !m_api) {
|
||||
return;
|
||||
}
|
||||
m_api->EndFrameCapture(m_device, nullptr);
|
||||
m_api->EndFrameCapture(m_device, m_window);
|
||||
}
|
||||
|
||||
void RenderDocCapture::TriggerCapture() {
|
||||
|
||||
@@ -14,10 +14,26 @@
|
||||
#include "XCEngine/RHI/OpenGL/OpenGLCommandList.h"
|
||||
#include "XCEngine/RHI/OpenGL/OpenGLCommandQueue.h"
|
||||
#include "XCEngine/RHI/OpenGL/OpenGLSwapChain.h"
|
||||
#include "XCEngine/Debug/Logger.h"
|
||||
|
||||
static bool s_windowClassRegistered = false;
|
||||
static const wchar_t kWindowClassName[] = L"XCEngine_OpenGL_WindowClass";
|
||||
|
||||
typedef const char* (WINAPI* PFNWGLGETEXTENSIONSSTRINGARBPROC)(HDC hdc);
|
||||
typedef BOOL (WINAPI* PFNWGLCHOOSEPIXELFORMATARBPROC)(HDC hdc, const int* piAttribIList, const FLOAT* pfAttribFList, UINT nMaxFormats, int* piFormats, UINT* nNumFormats);
|
||||
typedef HGLRC (WINAPI* PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC hdc, HGLRC hShareContext, const int* attribList);
|
||||
|
||||
static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = nullptr;
|
||||
static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = nullptr;
|
||||
static PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = nullptr;
|
||||
|
||||
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
|
||||
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
|
||||
#define WGL_CONTEXT_FLAGS_ARB 0x2094
|
||||
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
|
||||
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
|
||||
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x0001
|
||||
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
@@ -135,13 +151,60 @@ bool OpenGLDevice::InitializeWithExistingWindow(HWND hwnd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_hglrc = wglCreateContext(m_hdc);
|
||||
if (!m_hglrc) {
|
||||
HGLRC tempRC = wglCreateContext(m_hdc);
|
||||
if (!tempRC) {
|
||||
ReleaseDC(m_hwnd, m_hdc);
|
||||
m_hdc = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!wglMakeCurrent(m_hdc, tempRC)) {
|
||||
wglDeleteContext(tempRC);
|
||||
ReleaseDC(m_hwnd, m_hdc);
|
||||
m_hdc = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
|
||||
if (wglGetExtensionsStringARB) {
|
||||
const char* extensions = wglGetExtensionsStringARB(m_hdc);
|
||||
if (extensions && strstr(extensions, "WGL_ARB_pixel_format")) {
|
||||
wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
|
||||
}
|
||||
if (extensions && strstr(extensions, "WGL_ARB_create_context")) {
|
||||
wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
|
||||
}
|
||||
}
|
||||
|
||||
wglMakeCurrent(nullptr, nullptr);
|
||||
wglDeleteContext(tempRC);
|
||||
|
||||
if (wglCreateContextAttribsARB) {
|
||||
int debugAttribs[] = {
|
||||
WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
|
||||
WGL_CONTEXT_MINOR_VERSION_ARB, 6,
|
||||
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,
|
||||
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||
0, 0
|
||||
};
|
||||
|
||||
m_hglrc = wglCreateContextAttribsARB(m_hdc, nullptr, debugAttribs);
|
||||
if (m_hglrc) {
|
||||
XCEngine::Debug::Logger::Get().Info(XCEngine::Debug::LogCategory::General, "Created OpenGL debug context with WGL_ARB_create_context");
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_hglrc) {
|
||||
m_hglrc = wglCreateContext(m_hdc);
|
||||
if (m_hglrc) {
|
||||
XCEngine::Debug::Logger::Get().Warning(XCEngine::Debug::LogCategory::General, "Created OpenGL context without debug bit (wglCreateContextAttribsARB failed)");
|
||||
} else {
|
||||
ReleaseDC(m_hwnd, m_hdc);
|
||||
m_hdc = nullptr;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!wglMakeCurrent(m_hdc, m_hglrc)) {
|
||||
wglDeleteContext(m_hglrc);
|
||||
ReleaseDC(m_hwnd, m_hdc);
|
||||
@@ -159,6 +222,14 @@ bool OpenGLDevice::InitializeWithExistingWindow(HWND hwnd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GLint contextFlags = 0;
|
||||
glGetIntegerv(GL_CONTEXT_FLAGS, &contextFlags);
|
||||
if (contextFlags & GL_CONTEXT_FLAG_DEBUG_BIT) {
|
||||
XCEngine::Debug::Logger::Get().Info(XCEngine::Debug::LogCategory::General, "OpenGL debug context is active");
|
||||
} else {
|
||||
XCEngine::Debug::Logger::Get().Warning(XCEngine::Debug::LogCategory::General, "OpenGL debug context is NOT active");
|
||||
}
|
||||
|
||||
const char* vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
|
||||
const char* renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
|
||||
const char* version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
|
||||
|
||||
Reference in New Issue
Block a user