diff --git a/renderdoc/driver/gl/gl_common.cpp b/renderdoc/driver/gl/gl_common.cpp index b5565929c..46bda1f4e 100644 --- a/renderdoc/driver/gl/gl_common.cpp +++ b/renderdoc/driver/gl/gl_common.cpp @@ -47,6 +47,7 @@ bool ExtensionSupported[ExtensionSupported_Count]; bool VendorCheck[VendorCheck_Count]; int GLCoreVersion = 0; +bool GLIsCore = false; // simple wrapper for OS functions to make/delete a context GLWindowingData MakeContext(GLWindowingData share); diff --git a/renderdoc/driver/gl/gl_common.h b/renderdoc/driver/gl/gl_common.h index 93d3e02b1..ffbabb786 100644 --- a/renderdoc/driver/gl/gl_common.h +++ b/renderdoc/driver/gl/gl_common.h @@ -90,6 +90,7 @@ GLenum MakeGLFormat(WrappedOpenGL &gl, GLenum target, ResourceFormat fmt); GLuint GetBoundVertexBuffer(const GLHookSet &gl, GLuint idx); extern int GLCoreVersion; +extern bool GLIsCore; // extensions we know we want to check for are precached, indexd by this enum enum ExtensionCheckEnum diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index 4a8f0fec6..be73d2217 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -671,29 +671,32 @@ void *WrappedOpenGL::SwitchToContext(void *ctx) void WrappedOpenGL::DeleteContext(void *contextHandle) { - ContextData &font = m_ContextData[contextHandle]; + ContextData &ctxdata = m_ContextData[contextHandle]; - if(font.built && font.ready) + if(ctxdata.built && ctxdata.ready) { - if(font.Program) - m_Real.glDeleteProgram(font.Program); - if(font.GeneralUBO) - m_Real.glDeleteBuffers(1, &font.GeneralUBO); - if(font.GlyphUBO) - m_Real.glDeleteBuffers(1, &font.GlyphUBO); - if(font.StringUBO) - m_Real.glDeleteBuffers(1, &font.StringUBO); - if(font.GlyphTexture) - m_Real.glDeleteTextures(1, &font.GlyphTexture); + if(ctxdata.Program) + m_Real.glDeleteProgram(ctxdata.Program); + if(ctxdata.GeneralUBO) + m_Real.glDeleteBuffers(1, &ctxdata.GeneralUBO); + if(ctxdata.GlyphUBO) + m_Real.glDeleteBuffers(1, &ctxdata.GlyphUBO); + if(ctxdata.StringUBO) + m_Real.glDeleteBuffers(1, &ctxdata.StringUBO); + if(ctxdata.GlyphTexture) + m_Real.glDeleteTextures(1, &ctxdata.GlyphTexture); } m_ContextData.erase(contextHandle); } -void WrappedOpenGL::CreateContext(GLWindowingData winData, void *shareContext, GLInitParams initParams) +void WrappedOpenGL::CreateContext(GLWindowingData winData, void *shareContext, GLInitParams initParams, bool core) { // TODO: support multiple GL contexts more explicitly m_InitParams = initParams; + + ContextData &ctxdata = m_ContextData[winData.ctx]; + ctxdata.isCore = core; } void WrappedOpenGL::ActivateContext(GLWindowingData winData) @@ -712,11 +715,11 @@ void WrappedOpenGL::ActivateContext(GLWindowingData winData) m_ContextRecord->AddChunk(scope.Get()); } - ContextData &font = m_ContextData[winData.ctx]; + ContextData &ctxdata = m_ContextData[winData.ctx]; - if(!font.built) + if(!ctxdata.built) { - font.built = true; + ctxdata.built = true; const GLHookSet &gl = m_Real; @@ -734,9 +737,10 @@ void WrappedOpenGL::ActivateContext(GLWindowingData winData) int ver = mj*10 + mn; - if(ver > GLCoreVersion) + if(ver > GLCoreVersion || (!GLIsCore && ctxdata.isCore)) { GLCoreVersion = ver; + GLIsCore = ctxdata.isCore; DoVendorChecks(gl, winData); } } @@ -747,14 +751,14 @@ void WrappedOpenGL::ActivateContext(GLWindowingData winData) gl.glCreateShader && gl.glShaderSource && gl.glCompileShader && gl.glGetShaderiv && gl.glGetShaderInfoLog && gl.glDeleteShader && gl.glCreateProgram && gl.glAttachShader && gl.glLinkProgram && gl.glGetProgramiv && gl.glGetProgramInfoLog) { - gl.glGenTextures(1, &font.GlyphTexture); - gl.glTextureStorage2DEXT(font.GlyphTexture, eGL_TEXTURE_2D, 1, eGL_R8, FONT_TEX_WIDTH, FONT_TEX_HEIGHT); + gl.glGenTextures(1, &ctxdata.GlyphTexture); + gl.glTextureStorage2DEXT(ctxdata.GlyphTexture, eGL_TEXTURE_2D, 1, eGL_R8, FONT_TEX_WIDTH, FONT_TEX_HEIGHT); GLuint curvao = 0; gl.glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&curvao); - gl.glGenVertexArrays(1, &font.DummyVAO); - gl.glBindVertexArray(font.DummyVAO); + gl.glGenVertexArrays(1, &ctxdata.DummyVAO); + gl.glBindVertexArray(ctxdata.DummyVAO); string ttfstring = GetEmbeddedResource(sourcecodepro_ttf); byte *ttfdata = (byte *)ttfstring.c_str(); @@ -770,8 +774,8 @@ void WrappedOpenGL::ActivateContext(GLWindowingData winData) stbtt_bakedchar chardata[numChars]; int ret = stbtt_BakeFontBitmap(ttfdata, 0, pixelHeight, buf, FONT_TEX_WIDTH, FONT_TEX_HEIGHT, firstChar, numChars, chardata); - font.CharSize = pixelHeight; - font.CharAspect = chardata->xadvance / pixelHeight; + ctxdata.CharSize = pixelHeight; + ctxdata.CharAspect = chardata->xadvance / pixelHeight; stbtt_fontinfo f = {0}; stbtt_InitFont(&f, ttfdata, 0); @@ -781,7 +785,7 @@ void WrappedOpenGL::ActivateContext(GLWindowingData winData) float maxheight = float(ascent)*stbtt_ScaleForPixelHeight(&f, pixelHeight); - gl.glTextureSubImage2DEXT(font.GlyphTexture, eGL_TEXTURE_2D, 0, 0, 0, FONT_TEX_WIDTH, FONT_TEX_HEIGHT, + gl.glTextureSubImage2DEXT(ctxdata.GlyphTexture, eGL_TEXTURE_2D, 0, 0, 0, FONT_TEX_WIDTH, FONT_TEX_HEIGHT, eGL_RED, eGL_UNSIGNED_BYTE, (void *)buf); delete[] buf; @@ -799,14 +803,14 @@ void WrappedOpenGL::ActivateContext(GLWindowingData winData) glyphData[(i+1)*2 + 1] = Vec4f(b->x0, b->y0, b->x1, b->y1); } - gl.glGenBuffers(1, &font.GlyphUBO); - gl.glNamedBufferStorageEXT(font.GlyphUBO, sizeof(glyphData), glyphData, 0); + gl.glGenBuffers(1, &ctxdata.GlyphUBO); + gl.glNamedBufferStorageEXT(ctxdata.GlyphUBO, sizeof(glyphData), glyphData, 0); - gl.glGenBuffers(1, &font.GeneralUBO); - gl.glNamedBufferStorageEXT(font.GeneralUBO, sizeof(FontUniforms), NULL, GL_MAP_WRITE_BIT); + gl.glGenBuffers(1, &ctxdata.GeneralUBO); + gl.glNamedBufferStorageEXT(ctxdata.GeneralUBO, sizeof(FontUniforms), NULL, GL_MAP_WRITE_BIT); - gl.glGenBuffers(1, &font.StringUBO); - gl.glNamedBufferStorageEXT(font.StringUBO, sizeof(uint32_t)*4*FONT_MAX_CHARS, NULL, GL_MAP_WRITE_BIT); + gl.glGenBuffers(1, &ctxdata.StringUBO); + gl.glNamedBufferStorageEXT(ctxdata.StringUBO, sizeof(uint32_t)*4*FONT_MAX_CHARS, NULL, GL_MAP_WRITE_BIT); string textvs = GetEmbeddedResource(debuguniforms_h); textvs += GetEmbeddedResource(text_vert); @@ -840,24 +844,24 @@ void WrappedOpenGL::ActivateContext(GLWindowingData winData) RDCERR("Shader error: %s", buffer); } - font.Program = gl.glCreateProgram(); + ctxdata.Program = gl.glCreateProgram(); - gl.glAttachShader(font.Program, vs); - gl.glAttachShader(font.Program, fs); + gl.glAttachShader(ctxdata.Program, vs); + gl.glAttachShader(ctxdata.Program, fs); - gl.glLinkProgram(font.Program); + gl.glLinkProgram(ctxdata.Program); - gl.glGetProgramiv(font.Program, eGL_LINK_STATUS, &status); + gl.glGetProgramiv(ctxdata.Program, eGL_LINK_STATUS, &status); if(status == 0) { - gl.glGetProgramInfoLog(font.Program, 1024, NULL, buffer); + gl.glGetProgramInfoLog(ctxdata.Program, 1024, NULL, buffer); RDCERR("Link error: %s", buffer); } gl.glDeleteShader(vs); gl.glDeleteShader(fs); - font.ready = true; + ctxdata.ready = true; gl.glBindVertexArray(curvao); } @@ -996,11 +1000,11 @@ void WrappedOpenGL::RenderOverlayStr(float x, float y, const char *text) RDCASSERT(strlen(text) < (size_t)FONT_MAX_CHARS); - ContextData &font = m_ContextData[GetCtx()]; + ContextData &ctxdata = m_ContextData[GetCtx()]; - if(!font.built || !font.ready) return; + if(!ctxdata.built || !ctxdata.ready) return; - gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, font.GeneralUBO); + gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, ctxdata.GeneralUBO); FontUniforms *ubo = (FontUniforms *)gl.glMapBufferRange(eGL_UNIFORM_BUFFER, 0, sizeof(FontUniforms), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); ubo->TextPosition.x = x; @@ -1009,8 +1013,8 @@ void WrappedOpenGL::RenderOverlayStr(float x, float y, const char *text) ubo->FontScreenAspect.x = 1.0f/float(m_InitParams.width); ubo->FontScreenAspect.y = 1.0f/float(m_InitParams.height); - ubo->TextSize = font.CharSize; - ubo->FontScreenAspect.x *= font.CharAspect; + ubo->TextSize = ctxdata.CharSize; + ubo->FontScreenAspect.x *= ctxdata.CharAspect; ubo->CharacterSize.x = 1.0f/float(FONT_TEX_WIDTH); ubo->CharacterSize.y = 1.0f/float(FONT_TEX_HEIGHT); @@ -1019,7 +1023,7 @@ void WrappedOpenGL::RenderOverlayStr(float x, float y, const char *text) size_t len = strlen(text); - gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, font.StringUBO); + gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, ctxdata.StringUBO); uint32_t *texs = (uint32_t *)gl.glMapBufferRange(eGL_UNIFORM_BUFFER, 0, len*4*sizeof(uint32_t), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); for(size_t i=0; i < len; i++) @@ -1053,19 +1057,19 @@ void WrappedOpenGL::RenderOverlayStr(float x, float y, const char *text) gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_FILL); // bind UBOs - gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, font.GeneralUBO); - gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 1, font.GlyphUBO); - gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 2, font.StringUBO); + gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, ctxdata.GeneralUBO); + gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 1, ctxdata.GlyphUBO); + gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 2, ctxdata.StringUBO); // bind empty VAO just for valid rendering - gl.glBindVertexArray(font.DummyVAO); + gl.glBindVertexArray(ctxdata.DummyVAO); // bind textures gl.glActiveTexture(eGL_TEXTURE0); - gl.glBindTexture(eGL_TEXTURE_2D, font.GlyphTexture); + gl.glBindTexture(eGL_TEXTURE_2D, ctxdata.GlyphTexture); // bind program - gl.glUseProgram(font.Program); + gl.glUseProgram(ctxdata.Program); // draw string gl.glDrawArraysInstanced(eGL_TRIANGLE_STRIP, 0, 4, (GLsizei)len); diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index 2278f3aa4..3e4e7d932 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -286,6 +286,8 @@ class WrappedOpenGL bool built; bool ready; + bool isCore; + GLuint Program; GLuint GeneralUBO, StringUBO, GlyphUBO; GLuint GlyphTexture; @@ -352,7 +354,7 @@ class WrappedOpenGL vector &GetFrameRecord() { return m_FrameRecord; } FetchAPIEvent GetEvent(uint32_t eventID); - void CreateContext(GLWindowingData winData, void *shareContext, GLInitParams initParams); + void CreateContext(GLWindowingData winData, void *shareContext, GLInitParams initParams, bool core); void DeleteContext(void *contextHandle); void ActivateContext(GLWindowingData winData); void WindowSize(void *windowHandle, uint32_t w, uint32_t h); diff --git a/renderdoc/driver/gl/gl_replay_linux.cpp b/renderdoc/driver/gl/gl_replay_linux.cpp index b7885ce0a..990b25044 100644 --- a/renderdoc/driver/gl/gl_replay_linux.cpp +++ b/renderdoc/driver/gl/gl_replay_linux.cpp @@ -119,7 +119,9 @@ uint64_t GLReplay::MakeOutputWindow(void *wn, bool depth) attribs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB; attribs[i++] = 3; attribs[i++] = GLX_CONTEXT_FLAGS_ARB; - attribs[i++] = GLX_CONTEXT_CORE_PROFILE_BIT_ARB|GLX_CONTEXT_DEBUG_BIT_ARB; + attribs[i++] = GLX_CONTEXT_DEBUG_BIT_ARB; + attribs[i++] = GLX_CONTEXT_PROFILE_MASK_ARB; + attribs[i++] = GLX_CONTEXT_CORE_PROFILE_BIT_ARB; GLXContext ctx = glXCreateContextAttribsProc(dpy, fbcfg[0], m_ReplayCtx.ctx, true, attribs); @@ -249,7 +251,9 @@ ReplayCreateStatus GL_CreateReplayDevice(const char *logfile, IReplayDriver **dr attribs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB; attribs[i++] = 3; attribs[i++] = GLX_CONTEXT_FLAGS_ARB; - attribs[i++] = GLX_CONTEXT_CORE_PROFILE_BIT_ARB|GLX_CONTEXT_DEBUG_BIT_ARB; + attribs[i++] = GLX_CONTEXT_DEBUG_BIT_ARB; + attribs[i++] = GLX_CONTEXT_PROFILE_MASK_ARB; + attribs[i++] = GLX_CONTEXT_CORE_PROFILE_BIT_ARB; Display *dpy = XOpenDisplay(NULL); diff --git a/renderdoc/driver/gl/gl_replay_win32.cpp b/renderdoc/driver/gl/gl_replay_win32.cpp index 17a7ed8e0..892ada280 100644 --- a/renderdoc/driver/gl/gl_replay_win32.cpp +++ b/renderdoc/driver/gl/gl_replay_win32.cpp @@ -159,7 +159,9 @@ uint64_t GLReplay::MakeOutputWindow(void *wn, bool depth) attribs[i++] = WGL_CONTEXT_MINOR_VERSION_ARB; attribs[i++] = 3; attribs[i++] = WGL_CONTEXT_FLAGS_ARB; - attribs[i++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB|WGL_CONTEXT_DEBUG_BIT_ARB; + attribs[i++] = WGL_CONTEXT_DEBUG_BIT_ARB; + attribs[i++] = WGL_CONTEXT_PROFILE_MASK_ARB; + attribs[i++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; HGLRC rc = createContextAttribs(DC, m_ReplayCtx.ctx, attribs); if(rc == NULL) @@ -375,7 +377,9 @@ ReplayCreateStatus GL_CreateReplayDevice(const char *logfile, IReplayDriver **dr attribs[i++] = WGL_CONTEXT_MINOR_VERSION_ARB; attribs[i++] = 3; attribs[i++] = WGL_CONTEXT_FLAGS_ARB; - attribs[i++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB|WGL_CONTEXT_DEBUG_BIT_ARB; + attribs[i++] = WGL_CONTEXT_DEBUG_BIT_ARB; + attribs[i++] = WGL_CONTEXT_PROFILE_MASK_ARB; + attribs[i++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; rc = createContextAttribs(dc, NULL, attribs); if(rc == NULL) diff --git a/renderdoc/hooks/gl_linux_hooks.cpp b/renderdoc/hooks/gl_linux_hooks.cpp index 94495d76e..db7e8e737 100644 --- a/renderdoc/hooks/gl_linux_hooks.cpp +++ b/renderdoc/hooks/gl_linux_hooks.cpp @@ -310,6 +310,8 @@ class OpenGLHook : LibraryHook GLX_CONTEXT_MINOR_VERSION_ARB, 2, GLX_CONTEXT_FLAGS_ARB, + 0, + GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, 0, 0, }; @@ -404,7 +406,7 @@ GLXContext glXCreateContext(Display *dpy, XVisualInfo *vis, GLXContext shareList data.wnd = (GLXDrawable)NULL; data.ctx = ret; - OpenGLHook::glhooks.GetDriver()->CreateContext(data, shareList, init); + OpenGLHook::glhooks.GetDriver()->CreateContext(data, shareList, init, false); return ret; } @@ -460,6 +462,20 @@ GLXContext glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config, GLXConte attribs = &attribVec[0]; } + RDCDEBUG("glXCreateContextAttribsARB:"); + + bool core = false; + + int *a = (int *)attribs; + while(*a) + { + RDCDEBUG("%x: %d", a[0], a[1]); + a += 2; + + if(a[0] == GLX_CONTEXT_PROFILE_MASK_ARB) + core = (a[1] & GLX_CONTEXT_CORE_PROFILE_BIT_ARB); + } + GLXContext ret = OpenGLHook::glhooks.glXCreateContextAttribsARB_real(dpy, config, shareList, direct, attribs); XVisualInfo *vis = OpenGLHook::glhooks.glXGetVisualFromFBConfig_real(dpy, config); @@ -488,7 +504,7 @@ GLXContext glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config, GLXConte data.wnd = (GLXDrawable)NULL; data.ctx = ret; - OpenGLHook::glhooks.GetDriver()->CreateContext(data, shareList, init); + OpenGLHook::glhooks.GetDriver()->CreateContext(data, shareList, init, core); return ret; } diff --git a/renderdoc/hooks/gl_win32_hooks.cpp b/renderdoc/hooks/gl_win32_hooks.cpp index bd836b111..dd3b727a8 100644 --- a/renderdoc/hooks/gl_win32_hooks.cpp +++ b/renderdoc/hooks/gl_win32_hooks.cpp @@ -277,6 +277,8 @@ class OpenGLHook : LibraryHook WGL_CONTEXT_MINOR_VERSION_ARB, 2, WGL_CONTEXT_FLAGS_ARB, + 0, + WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, 0, 0, }; @@ -377,7 +379,7 @@ class OpenGLHook : LibraryHook data.wnd = WindowFromDC(dc); data.ctx = ret; - glhooks.GetDriver()->CreateContext(data, NULL, GetInitParamsForDC(dc)); + glhooks.GetDriver()->CreateContext(data, NULL, GetInitParamsForDC(dc), false); return ret; } @@ -398,7 +400,7 @@ class OpenGLHook : LibraryHook data.wnd = WindowFromDC(dc); data.ctx = ret; - glhooks.GetDriver()->CreateContext(data, NULL, GetInitParamsForDC(dc)); + glhooks.GetDriver()->CreateContext(data, NULL, GetInitParamsForDC(dc), false); return ret; } @@ -447,11 +449,16 @@ class OpenGLHook : LibraryHook RDCDEBUG("wglCreateContextAttribsARB:"); + bool core = false; + int *a = (int *)attribs; while(*a) { RDCDEBUG("%x: %d", a[0], a[1]); a += 2; + + if(a[0] == WGL_CONTEXT_PROFILE_MASK_ARB) + core = (a[1] & WGL_CONTEXT_CORE_PROFILE_BIT_ARB); } HGLRC ret = glhooks.wglCreateContextAttribsARB_realfunc(dc, hShareContext, attribs); @@ -461,7 +468,7 @@ class OpenGLHook : LibraryHook data.wnd = WindowFromDC(dc); data.ctx = ret; - glhooks.GetDriver()->CreateContext(data, hShareContext, GetInitParamsForDC(dc)); + glhooks.GetDriver()->CreateContext(data, hShareContext, GetInitParamsForDC(dc), core); return ret; }