diff --git a/renderdoc/CMakeLists.txt b/renderdoc/CMakeLists.txt index 6b9c6bf91..b236740e4 100644 --- a/renderdoc/CMakeLists.txt +++ b/renderdoc/CMakeLists.txt @@ -301,8 +301,10 @@ set(data data/glsl/gl_texsample.h data/glsl/gles_texsample.h data/glsl/vk_texsample.h - data/glsl/text.frag - data/glsl/text.vert + data/glsl/gltext.frag + data/glsl/gltext.vert + data/glsl/vktext.frag + data/glsl/vktext.vert data/glsl/array2ms.comp data/glsl/ms2array.comp data/glsl/trisize.frag diff --git a/renderdoc/data/embedded_files.h b/renderdoc/data/embedded_files.h index c672d11e5..c1beb80c4 100644 --- a/renderdoc/data/embedded_files.h +++ b/renderdoc/data/embedded_files.h @@ -33,8 +33,10 @@ DECLARE_EMBED(sourcecodepro_ttf); DECLARE_EMBED(glsl_blit_vert); DECLARE_EMBED(glsl_checkerboard_frag); DECLARE_EMBED(glsl_texdisplay_frag); -DECLARE_EMBED(glsl_text_vert); -DECLARE_EMBED(glsl_text_frag); +DECLARE_EMBED(glsl_gltext_vert); +DECLARE_EMBED(glsl_gltext_frag); +DECLARE_EMBED(glsl_vktext_vert); +DECLARE_EMBED(glsl_vktext_frag); DECLARE_EMBED(glsl_fixedcol_frag); DECLARE_EMBED(glsl_mesh_vert); DECLARE_EMBED(glsl_mesh_geom); diff --git a/renderdoc/data/glsl/debuguniforms.h b/renderdoc/data/glsl/debuguniforms.h index 9362bced3..867055072 100644 --- a/renderdoc/data/glsl/debuguniforms.h +++ b/renderdoc/data/glsl/debuguniforms.h @@ -74,7 +74,6 @@ struct Vec4u #define OPENGL 1 -#define FONT_UBOS #define HISTOGRAM_UBOS #ifdef GL_ES diff --git a/renderdoc/data/glsl/gltext.frag b/renderdoc/data/glsl/gltext.frag new file mode 100644 index 000000000..ee2631c07 --- /dev/null +++ b/renderdoc/data/glsl/gltext.frag @@ -0,0 +1,44 @@ +/****************************************************************************** + * The MIT License (MIT) + * + * Copyright (c) 2015-2018 Baldur Karlsson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +uniform sampler2D font_tex; + +varying vec4 tex; +varying vec2 glyphuv; + +void main(void) +{ + float text = 0.0; + + if(glyphuv.x >= 0.0 && glyphuv.x <= 1.0 && + glyphuv.y >= 0.0 && glyphuv.y <= 1.0) + { + vec2 uv; + uv.x = mix(tex.x, tex.z, glyphuv.x); + uv.y = mix(tex.y, tex.w, glyphuv.y); + text = texture2D(font_tex, uv).x; + } + + gl_FragColor = vec4(vec3(text), clamp(text + 0.5, 0.0, 1.0)); +} diff --git a/renderdoc/data/glsl/gltext.vert b/renderdoc/data/glsl/gltext.vert new file mode 100644 index 000000000..dda3693fd --- /dev/null +++ b/renderdoc/data/glsl/gltext.vert @@ -0,0 +1,47 @@ +/****************************************************************************** + * The MIT License (MIT) + * + * Copyright (c) 2015-2018 Baldur Karlsson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +varying vec4 tex; +varying vec2 glyphuv; + +attribute vec2 pos; +attribute vec2 uv; +attribute float charidx; + +// must match defines in gl_rendertext.cpp +#define FONT_FIRST_CHAR 32 +#define FONT_LAST_CHAR 126 + +uniform vec4 posdata[FONT_LAST_CHAR - FONT_FIRST_CHAR + 1]; +uniform vec4 uvdata[FONT_LAST_CHAR - FONT_FIRST_CHAR + 1]; + +void main(void) +{ + vec4 glyphposdata = posdata[int(charidx)]; + vec4 glyphuvdata = uvdata[int(charidx)]; + + gl_Position = vec4(pos, 1, 1); + glyphuv.xy = (uv.xy - glyphposdata.xy) * glyphposdata.zw; + tex = glyphuvdata; +} diff --git a/renderdoc/data/glsl/text.frag b/renderdoc/data/glsl/vktext.frag similarity index 95% rename from renderdoc/data/glsl/text.frag rename to renderdoc/data/glsl/vktext.frag index b0980f4b5..0ae76f6e5 100644 --- a/renderdoc/data/glsl/text.frag +++ b/renderdoc/data/glsl/vktext.frag @@ -22,11 +22,8 @@ * THE SOFTWARE. ******************************************************************************/ -#ifdef VULKAN layout (binding = 3) uniform sampler2D tex0; -#else // OPENGL -layout (binding = 0) uniform sampler2D tex0; -#endif + layout (location = 0) out vec4 color_out; layout (location = 0) in vec4 tex; diff --git a/renderdoc/data/glsl/text.vert b/renderdoc/data/glsl/vktext.vert similarity index 96% rename from renderdoc/data/glsl/text.vert rename to renderdoc/data/glsl/vktext.vert index 96a565984..6ab595fd3 100644 --- a/renderdoc/data/glsl/text.vert +++ b/renderdoc/data/glsl/vktext.vert @@ -22,13 +22,11 @@ * THE SOFTWARE. ******************************************************************************/ -#ifndef OPENGL_ES out gl_PerVertex { vec4 gl_Position; float gl_PointSize; }; -#endif layout (location = 0) out vec4 tex; layout (location = 1) out vec2 glyphuv; @@ -55,8 +53,4 @@ void main(void) gl_Position = vec4(charPos.xy*2.0f*general.TextSize*general.FontScreenAspect.xy + vec2(-1, -1), 1, 1); glyphuv.xy = (pos.xy - G.posdata.xy) * G.posdata.zw; tex = G.uvdata * general.CharacterSize.xyxy; - -#ifdef OPENGL - gl_Position.y = -gl_Position.y; -#endif } diff --git a/renderdoc/data/glsl_shaders.cpp b/renderdoc/data/glsl_shaders.cpp index 45d15ce63..eb364336b 100644 --- a/renderdoc/data/glsl_shaders.cpp +++ b/renderdoc/data/glsl_shaders.cpp @@ -39,7 +39,10 @@ void GenerateGLSLShader(std::vector &sources, ShaderType type, } else { - sources[0] = StringFormat::Fmt("#version %d core\n", version); + if(version == 110) + sources[0] = "#version 110"; // no core suffix + else + sources[0] = StringFormat::Fmt("#version %d core\n", version); } if(uniforms) diff --git a/renderdoc/data/renderdoc.rc b/renderdoc/data/renderdoc.rc index 8ce08a39b..df4f261c1 100644 --- a/renderdoc/data/renderdoc.rc +++ b/renderdoc/data/renderdoc.rc @@ -115,8 +115,8 @@ RESOURCE_sourcecodepro_ttf TYPE_EMBED "sourcecodepro.ttf" RESOURCE_glsl_blit_vert TYPE_EMBED "glsl/blit.vert" RESOURCE_glsl_checkerboard_frag TYPE_EMBED "glsl/checkerboard.frag" RESOURCE_glsl_texdisplay_frag TYPE_EMBED "glsl/texdisplay.frag" -RESOURCE_glsl_text_vert TYPE_EMBED "glsl/text.vert" -RESOURCE_glsl_text_frag TYPE_EMBED "glsl/text.frag" +RESOURCE_glsl_vktext_vert TYPE_EMBED "glsl/vktext.vert" +RESOURCE_glsl_vktext_frag TYPE_EMBED "glsl/vktext.frag" RESOURCE_glsl_fixedcol_frag TYPE_EMBED "glsl/fixedcol.frag" RESOURCE_glsl_mesh_vert TYPE_EMBED "glsl/mesh.vert" RESOURCE_glsl_mesh_geom TYPE_EMBED "glsl/mesh.geom" @@ -138,6 +138,8 @@ RESOURCE_glsl_trisize_frag TYPE_EMBED "glsl/trisize.frag" RESOURCE_glsl_deptharr2ms_frag TYPE_EMBED "glsl/deptharr2ms.frag" RESOURCE_glsl_depthms2arr_frag TYPE_EMBED "glsl/depthms2arr.frag" RESOURCE_glsl_gles_texsample_h TYPE_EMBED "glsl/gles_texsample.h" +RESOURCE_glsl_gltext_vert TYPE_EMBED "glsl/gltext.vert" +RESOURCE_glsl_gltext_frag TYPE_EMBED "glsl/gltext.frag" #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// diff --git a/renderdoc/data/resource.h b/renderdoc/data/resource.h index e69faa013..16da0665a 100644 --- a/renderdoc/data/resource.h +++ b/renderdoc/data/resource.h @@ -17,8 +17,8 @@ #define RESOURCE_glsl_blit_vert 401 #define RESOURCE_glsl_checkerboard_frag 402 #define RESOURCE_glsl_texdisplay_frag 403 -#define RESOURCE_glsl_text_vert 404 -#define RESOURCE_glsl_text_frag 405 +#define RESOURCE_glsl_vktext_vert 404 +#define RESOURCE_glsl_vktext_frag 405 #define RESOURCE_glsl_fixedcol_frag 408 #define RESOURCE_glsl_mesh_vert 409 #define RESOURCE_glsl_mesh_geom 410 @@ -40,6 +40,8 @@ #define RESOURCE_glsl_deptharr2ms_frag 426 #define RESOURCE_glsl_depthms2arr_frag 427 #define RESOURCE_glsl_gles_texsample_h 428 +#define RESOURCE_glsl_gltext_vert 429 +#define RESOURCE_glsl_gltext_frag 430 // Next default values for new objects // diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index c114d4bfd..3ec7a9804 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -852,12 +852,8 @@ void WrappedOpenGL::DeleteContext(void *contextHandle) { if(ctxdata.Program) GL.glDeleteProgram(ctxdata.Program); - if(ctxdata.GeneralUBO) - GL.glDeleteBuffers(1, &ctxdata.GeneralUBO); - if(ctxdata.GlyphUBO) - GL.glDeleteBuffers(1, &ctxdata.GlyphUBO); - if(ctxdata.StringUBO) - GL.glDeleteBuffers(1, &ctxdata.StringUBO); + if(ctxdata.ArrayBuffer) + GL.glDeleteBuffers(1, &ctxdata.ArrayBuffer); if(ctxdata.GlyphTexture) GL.glDeleteTextures(1, &ctxdata.GlyphTexture); } diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index 9e4c2740f..198462f00 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -308,7 +308,7 @@ private: attribsCreate = false; version = 0; isCore = false; - Program = GeneralUBO = StringUBO = GlyphUBO = 0; + Program = ArrayBuffer = 0; GlyphTexture = DummyVAO = 0; CharSize = CharAspect = 0.0f; RDCEraseEl(m_TextureRecord); @@ -356,7 +356,7 @@ private: } bool Modern() { return !Legacy(); } GLuint Program; - GLuint GeneralUBO, StringUBO, GlyphUBO; + GLuint ArrayBuffer; GLuint GlyphTexture; GLuint DummyVAO; diff --git a/renderdoc/driver/gl/gl_rendertext.cpp b/renderdoc/driver/gl/gl_rendertext.cpp index 095f0be55..8e87d2f56 100644 --- a/renderdoc/driver/gl/gl_rendertext.cpp +++ b/renderdoc/driver/gl/gl_rendertext.cpp @@ -29,18 +29,21 @@ #include "strings/string_utils.h" #include "gl_driver.h" -const int firstChar = int(' ') + 1; -const int lastChar = 127; -const int numChars = lastChar - firstChar; const float charPixelHeight = 20.0f; +#define FONT_FIRST_CHAR 32 +#define FONT_LAST_CHAR 126 + +const int numChars = FONT_LAST_CHAR - FONT_FIRST_CHAR + 1; + stbtt_bakedchar chardata[numChars]; -#define OPENGL 1 -#include "data/glsl/debuguniforms.h" - void WrappedOpenGL::ContextData::CreateDebugData() { + // if these constants change, update debuguniforms.h and gltext.vert + RDCCOMPILE_ASSERT(FONT_FIRST_CHAR == int(' '), "FONT_FIRST_CHAR is incorrect"); + RDCCOMPILE_ASSERT(FONT_LAST_CHAR == 126, "FONT_LAST_CHAR is incorrect"); + // to let us display the overlay on old GL contexts, use as simple a subset of functionality as // possible to upload the texture. VAO and shaders are used optionally on modern contexts, // otherwise we fall back to immediate mode rendering by hand @@ -52,7 +55,7 @@ void WrappedOpenGL::ContextData::CreateDebugData() byte *buf = new byte[FONT_TEX_WIDTH * FONT_TEX_HEIGHT]; stbtt_BakeFontBitmap(ttfdata, 0, charPixelHeight, buf, FONT_TEX_WIDTH, FONT_TEX_HEIGHT, - firstChar, numChars, chardata); + FONT_FIRST_CHAR + 1, numChars, chardata); CharSize = charPixelHeight; #if ENABLED(RDOC_ANDROID) @@ -97,7 +100,12 @@ void WrappedOpenGL::ContextData::CreateDebugData() delete[] buf; - Vec4f glyphData[2 * (numChars + 1)]; + Vec4f posdata[numChars + 1] = {}; + Vec4f uvdata[numChars + 1] = {}; + + // premultiply CharacterSize + const Vec4f uvscale = + Vec4f(1.0f / float(FONT_TEX_WIDTH), 1.0f / float(FONT_TEX_HEIGHT), 0.0f, 1.0f); for(int i = 0; i < numChars; i++) { @@ -106,128 +114,143 @@ void WrappedOpenGL::ContextData::CreateDebugData() float x = b->xoff; float y = b->yoff + maxheight; - glyphData[(i + 1) * 2 + 0] = - Vec4f(x / b->xadvance, y / charPixelHeight, b->xadvance / float(b->x1 - b->x0), - charPixelHeight / float(b->y1 - b->y0)); - glyphData[(i + 1) * 2 + 1] = Vec4f(b->x0, b->y0, b->x1, b->y1); + posdata[i + 1] = Vec4f(x / b->xadvance, y / charPixelHeight, b->xadvance / float(b->x1 - b->x0), + charPixelHeight / float(b->y1 - b->y0)); + uvdata[i + 1] = + Vec4f(b->x0 * uvscale.x, b->y0 * uvscale.y, b->x1 * uvscale.x, b->y1 * uvscale.y); } - if(Modern() && GL.glGenVertexArrays && GL.glBindVertexArray) + if(Modern()) { - GLuint curvao = 0; - GL.glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&curvao); - - GL.glGenVertexArrays(1, &DummyVAO); - GL.glBindVertexArray(DummyVAO); - - GL.glBindVertexArray(curvao); - } - - if(Modern() && GL.glGenBuffers && GL.glBufferData && GL.glBindBuffer) - { - GLuint curubo = 0; - GL.glGetIntegerv(eGL_UNIFORM_BUFFER_BINDING, (GLint *)&curubo); - - GL.glGenBuffers(1, &GlyphUBO); - GL.glBindBuffer(eGL_UNIFORM_BUFFER, GlyphUBO); - GL.glBufferData(eGL_UNIFORM_BUFFER, sizeof(glyphData), glyphData, eGL_STATIC_DRAW); - - GL.glGenBuffers(1, &GeneralUBO); - GL.glBindBuffer(eGL_UNIFORM_BUFFER, GeneralUBO); - GL.glBufferData(eGL_UNIFORM_BUFFER, sizeof(FontUBOData), NULL, eGL_DYNAMIC_DRAW); - - GL.glGenBuffers(1, &StringUBO); - GL.glBindBuffer(eGL_UNIFORM_BUFFER, StringUBO); - GL.glBufferData(eGL_UNIFORM_BUFFER, sizeof(uint32_t) * 4 * FONT_MAX_CHARS, NULL, - eGL_DYNAMIC_DRAW); - - GL.glBindBuffer(eGL_UNIFORM_BUFFER, curubo); - } - - if(Modern() && GL.glCreateShader && GL.glShaderSource && GL.glCompileShader && - GL.glGetShaderiv && GL.glGetShaderInfoLog && GL.glDeleteShader && GL.glCreateProgram && - GL.glAttachShader && GL.glLinkProgram && GL.glGetProgramiv && GL.glGetProgramInfoLog) - { - vector vs; - vector fs; - - ShaderType shaderType; - int glslVersion; - string fragDefines; - - if(IsGLES) + if(GLCoreVersion > 20 && GL.glGenVertexArrays && GL.glBindVertexArray) { - shaderType = eShaderGLSLES; - glslVersion = 310; - fragDefines = ""; - } - else - { - shaderType = eShaderGLSL; - glslVersion = 150; - fragDefines = - "#extension GL_ARB_shading_language_420pack : require\n" - "#extension GL_ARB_separate_shader_objects : require\n" - "#extension GL_ARB_explicit_attrib_location : require\n"; + GLuint curvao = 0; + GL.glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&curvao); + + GL.glGenVertexArrays(1, &DummyVAO); + GL.glBindVertexArray(DummyVAO); + + GL.glBindVertexArray(curvao); } - GenerateGLSLShader(vs, shaderType, "", GetEmbeddedResource(glsl_text_vert), glslVersion); - GenerateGLSLShader(fs, shaderType, fragDefines, GetEmbeddedResource(glsl_text_frag), - glslVersion); - - vector vsc; - vsc.reserve(vs.size()); - vector fsc; - fsc.reserve(fs.size()); - - for(size_t i = 0; i < vs.size(); i++) - vsc.push_back(vs[i].c_str()); - - for(size_t i = 0; i < fs.size(); i++) - fsc.push_back(fs[i].c_str()); - - GLuint vert = GL.glCreateShader(eGL_VERTEX_SHADER); - GLuint frag = GL.glCreateShader(eGL_FRAGMENT_SHADER); - - GL.glShaderSource(vert, (GLsizei)vs.size(), &vsc[0], NULL); - GL.glShaderSource(frag, (GLsizei)fs.size(), &fsc[0], NULL); - - GL.glCompileShader(vert); - GL.glCompileShader(frag); - - char buffer[1024] = {0}; - GLint status = 0; - - GL.glGetShaderiv(vert, eGL_COMPILE_STATUS, &status); - if(status == 0) + if(GL.glGenBuffers && GL.glBufferData && GL.glBindBuffer) { - GL.glGetShaderInfoLog(vert, 1024, NULL, buffer); - RDCERR("Shader error: %s", buffer); + GLuint curbuf = 0; + GL.glGetIntegerv(eGL_ARRAY_BUFFER_BINDING, (GLint *)&curbuf); + + GL.glGenBuffers(1, &ArrayBuffer); + GL.glBindBuffer(eGL_ARRAY_BUFFER, ArrayBuffer); + GL.glBufferData(eGL_ARRAY_BUFFER, sizeof(float) * 5 * FONT_MAX_CHARS * 6, NULL, + eGL_DYNAMIC_DRAW); + + GL.glBindBuffer(eGL_ARRAY_BUFFER, curbuf); } - GL.glGetShaderiv(frag, eGL_COMPILE_STATUS, &status); - if(status == 0) + if(GL.glCreateShader && GL.glShaderSource && GL.glCompileShader && GL.glGetShaderiv && + GL.glGetShaderInfoLog && GL.glDeleteShader && GL.glCreateProgram && GL.glAttachShader && + GL.glLinkProgram && GL.glGetProgramiv && GL.glGetProgramInfoLog) { - GL.glGetShaderInfoLog(frag, 1024, NULL, buffer); - RDCERR("Shader error: %s", buffer); + vector vs; + vector fs; + + ShaderType shaderType; + int glslVersion; + string fragDefines; + + if(IsGLES) + { + shaderType = eShaderGLSLES; + glslVersion = 100; + fragDefines = "precision highp float;"; + } + else + { + shaderType = eShaderGLSL; + glslVersion = 110; + } + + GenerateGLSLShader(vs, shaderType, "", GetEmbeddedResource(glsl_gltext_vert), glslVersion, + false); + GenerateGLSLShader(fs, shaderType, fragDefines.c_str(), + GetEmbeddedResource(glsl_gltext_frag), glslVersion, false); + + vector vsc; + vsc.reserve(vs.size()); + vector fsc; + fsc.reserve(fs.size()); + + for(size_t i = 0; i < vs.size(); i++) + vsc.push_back(vs[i].c_str()); + + for(size_t i = 0; i < fs.size(); i++) + fsc.push_back(fs[i].c_str()); + + GLuint vert = GL.glCreateShader(eGL_VERTEX_SHADER); + GLuint frag = GL.glCreateShader(eGL_FRAGMENT_SHADER); + + GL.glShaderSource(vert, (GLsizei)vs.size(), &vsc[0], NULL); + GL.glShaderSource(frag, (GLsizei)fs.size(), &fsc[0], NULL); + + GL.glCompileShader(vert); + GL.glCompileShader(frag); + + char buffer[1024] = {0}; + GLint status = 0; + + GL.glGetShaderiv(vert, eGL_COMPILE_STATUS, &status); + if(status == 0) + { + GL.glGetShaderInfoLog(vert, 1024, NULL, buffer); + RDCERR("Shader error: %s", buffer); + } + + GL.glGetShaderiv(frag, eGL_COMPILE_STATUS, &status); + if(status == 0) + { + GL.glGetShaderInfoLog(frag, 1024, NULL, buffer); + RDCERR("Shader error: %s", buffer); + } + + Program = GL.glCreateProgram(); + + GL.glAttachShader(Program, vert); + GL.glAttachShader(Program, frag); + + GL.glBindAttribLocation(Program, 0, "pos"); + GL.glBindAttribLocation(Program, 1, "uv"); + GL.glBindAttribLocation(Program, 2, "charidx"); + + GL.glLinkProgram(Program); + + GL.glGetProgramiv(Program, eGL_LINK_STATUS, &status); + if(status == 1) + { + GLuint prevProg = 0; + GL.glGetIntegerv(eGL_CURRENT_PROGRAM, (GLint *)&prevProg); + + GL.glUseProgram(Program); + + // texture is from texture0 + GL.glUniform1i(GL.glGetUniformLocation(Program, "font_tex"), 0); + + // upload posdata and uvdata + GL.glUniform4fv(GL.glGetUniformLocation(Program, "posdata"), numChars, &posdata[0].x); + GL.glUniform4fv(GL.glGetUniformLocation(Program, "uvdata"), numChars, &uvdata[0].x); + + GL.glUseProgram(prevProg); + } + else + { + GL.glGetProgramInfoLog(Program, 1024, NULL, buffer); + RDCERR("Link error: %s", buffer); + + GL.glDeleteProgram(Program); + Program = 0; + } + + GL.glDeleteShader(vert); + GL.glDeleteShader(frag); } - - Program = GL.glCreateProgram(); - - GL.glAttachShader(Program, vert); - GL.glAttachShader(Program, frag); - - GL.glLinkProgram(Program); - - GL.glGetProgramiv(Program, eGL_LINK_STATUS, &status); - if(status == 0) - { - GL.glGetProgramInfoLog(Program, 1024, NULL, buffer); - RDCERR("Link error: %s", buffer); - } - - GL.glDeleteShader(vert); - GL.glDeleteShader(frag); } ready = true; @@ -273,29 +296,13 @@ void WrappedOpenGL::RenderOverlayStr(float x, float y, const char *text) ContextData &ctxdata = GetCtxData(); - if(!ctxdata.built || !ctxdata.ready) + if(!ctxdata.built || !ctxdata.ready || (ctxdata.Modern() && ctxdata.Program == 0)) return; // if it's reasonably modern context, assume we can use buffers and UBOs if(ctxdata.Modern()) { - GL.glBindBuffer(eGL_UNIFORM_BUFFER, ctxdata.GeneralUBO); - - FontUBOData *ubo = (FontUBOData *)GL.glMapBufferRange( - eGL_UNIFORM_BUFFER, 0, sizeof(FontUBOData), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); - ubo->TextPosition.x = x; - ubo->TextPosition.y = y; - - ubo->FontScreenAspect.x = 1.0f / RDCMAX(1.0f, float(m_InitParams.width)); - ubo->FontScreenAspect.y = 1.0f / RDCMAX(1.0f, float(m_InitParams.height)); - - 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); - - GL.glUnmapBuffer(eGL_UNIFORM_BUFFER); + GL.glBindBuffer(eGL_ARRAY_BUFFER, ctxdata.ArrayBuffer); size_t len = strlen(text); @@ -313,38 +320,46 @@ void WrappedOpenGL::RenderOverlayStr(float x, float y, const char *text) len = FONT_MAX_CHARS; } - GL.glBindBuffer(eGL_UNIFORM_BUFFER, 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); + static const Vec2f basePos[] = { + Vec2f(0.0, 0.0), Vec2f(1.0, 0.0), Vec2f(0.0, 1.0), + Vec2f(1.0, 0.0), Vec2f(0.0, 1.0), Vec2f(1.0, 1.0), + }; - if(texs) - { - for(size_t i = 0; i < len; i++) - { - texs[i * 4 + 0] = text[i] - ' '; - texs[i * 4 + 1] = text[i] - ' '; - texs[i * 4 + 2] = text[i] - ' '; - texs[i * 4 + 3] = text[i] - ' '; - } - } - else - { - static bool printedWarning = false; + const Vec2f FontScreenAspect(ctxdata.CharAspect / RDCMAX(1.0f, float(m_InitParams.width)), + 1.0f / RDCMAX(1.0f, float(m_InitParams.height))); - // this could be called once a frame, don't want to spam the log - if(!printedWarning) + float *vertexData = new float[5 * len * 6]; + + for(size_t i = 0; i < len; i++) + { + for(int ch = 0; ch < 6; ch++) { - printedWarning = true; - RDCWARN("failed to map %d characters for '%s' (%d)", (int)len, text, ctxdata.StringUBO); + Vec2f uv = basePos[ch]; + + Vec2f pos = uv; + pos.x += float(i) + x; + pos.y += y; + + pos.x *= 2.0f * ctxdata.CharSize * FontScreenAspect.x; + pos.y *= 2.0f * ctxdata.CharSize * FontScreenAspect.y; + + pos.x -= 1.0f; + pos.y -= 1.0f; + + vertexData[(i * 6 + ch) * 5 + 0] = pos.x; + vertexData[(i * 6 + ch) * 5 + 1] = -pos.y; + vertexData[(i * 6 + ch) * 5 + 2] = uv.x; + vertexData[(i * 6 + ch) * 5 + 3] = uv.y; + vertexData[(i * 6 + ch) * 5 + 4] = float(text[i] - FONT_FIRST_CHAR); } } - GL.glUnmapBuffer(eGL_UNIFORM_BUFFER); + // we read 6 * len vec2 positions and 6 * len float characters + GL.glBufferSubData(eGL_ARRAY_BUFFER, 0, sizeof(float) * 5 * len * 6, vertexData); ////////////////////////////////////////////////////////////////////////////////// // Make sure if you change any other state in here, that you also update the push - // and pop functions above (RenderTextState) + // and pop functions in GLPushPopState // set blend state if(HasExt[ARB_draw_buffers_blend]) @@ -398,14 +413,18 @@ void WrappedOpenGL::RenderOverlayStr(float x, float y, const char *text) if(GL.glClipControl && HasExt[ARB_clip_control]) GL.glClipControl(eGL_LOWER_LEFT, eGL_NEGATIVE_ONE_TO_ONE); - // bind UBOs - 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 + // bind VAO so we can fiddle with vertex attrib state GL.glBindVertexArray(ctxdata.DummyVAO); + GLsizei stride = sizeof(float) * 5; + + GL.glVertexAttribPointer(0, 2, eGL_FLOAT, false, stride, (void *)uintptr_t(sizeof(float) * 0)); + GL.glVertexAttribPointer(1, 2, eGL_FLOAT, false, stride, (void *)uintptr_t(sizeof(float) * 2)); + GL.glVertexAttribPointer(2, 1, eGL_FLOAT, false, stride, (void *)uintptr_t(sizeof(float) * 4)); + GL.glEnableVertexAttribArray(0); + GL.glEnableVertexAttribArray(1); + GL.glEnableVertexAttribArray(2); + // bind textures GL.glActiveTexture(eGL_TEXTURE0); GL.glBindTexture(eGL_TEXTURE_2D, ctxdata.GlyphTexture); @@ -482,9 +501,10 @@ void WrappedOpenGL::RenderOverlayStr(float x, float y, const char *text) while(*prepass) { char c = *prepass; - if(c >= firstChar && c <= lastChar) + if(c >= FONT_FIRST_CHAR && c < FONT_LAST_CHAR) { - stbtt_GetBakedQuad(chardata, FONT_TEX_WIDTH, FONT_TEX_HEIGHT, c - firstChar, &x, &y, &q, 1); + stbtt_GetBakedQuad(chardata, FONT_TEX_WIDTH, FONT_TEX_HEIGHT, c - FONT_FIRST_CHAR, &x, &y, + &q, 1); maxx = RDCMAX(maxx, RDCMAX(q.x0, q.x1)); maxy = RDCMAX(maxy, RDCMAX(q.y0, q.y1)); @@ -512,9 +532,10 @@ void WrappedOpenGL::RenderOverlayStr(float x, float y, const char *text) while(*text) { char c = *text; - if(c >= firstChar && c <= lastChar) + if(c >= FONT_FIRST_CHAR && c < FONT_LAST_CHAR) { - stbtt_GetBakedQuad(chardata, FONT_TEX_WIDTH, FONT_TEX_HEIGHT, c - firstChar, &x, &y, &q, 1); + stbtt_GetBakedQuad(chardata, FONT_TEX_WIDTH, FONT_TEX_HEIGHT, c - FONT_FIRST_CHAR, &x, &y, + &q, 1); vertices.push_back(Vec4f(q.x0, q.y0, q.s0, q.t0)); vertices.push_back(Vec4f(q.x1, q.y0, q.s1, q.t0)); diff --git a/renderdoc/driver/vulkan/vk_shader_cache.cpp b/renderdoc/driver/vulkan/vk_shader_cache.cpp index 4e410769a..6f280306a 100644 --- a/renderdoc/driver/vulkan/vk_shader_cache.cpp +++ b/renderdoc/driver/vulkan/vk_shader_cache.cpp @@ -55,9 +55,9 @@ static const BuiltinShaderConfig builtinShaders[] = { SPIRVShaderStage::Fragment, FeatureCheck::NoCheck, true}, {BuiltinShader::FixedColFS, EmbeddedResource(glsl_fixedcol_frag), SPIRVShaderStage::Fragment, FeatureCheck::NoCheck, false}, - {BuiltinShader::TextVS, EmbeddedResource(glsl_text_vert), SPIRVShaderStage::Vertex, + {BuiltinShader::TextVS, EmbeddedResource(glsl_vktext_vert), SPIRVShaderStage::Vertex, FeatureCheck::NoCheck, true}, - {BuiltinShader::TextFS, EmbeddedResource(glsl_text_frag), SPIRVShaderStage::Fragment, + {BuiltinShader::TextFS, EmbeddedResource(glsl_vktext_frag), SPIRVShaderStage::Fragment, FeatureCheck::NoCheck, true}, {BuiltinShader::MeshVS, EmbeddedResource(glsl_mesh_vert), SPIRVShaderStage::Vertex, FeatureCheck::NoCheck, true}, diff --git a/renderdoc/renderdoc.vcxproj b/renderdoc/renderdoc.vcxproj index 2a654702f..d21b4d40a 100644 --- a/renderdoc/renderdoc.vcxproj +++ b/renderdoc/renderdoc.vcxproj @@ -489,6 +489,8 @@ + + @@ -501,8 +503,8 @@ - - + + diff --git a/renderdoc/renderdoc.vcxproj.filters b/renderdoc/renderdoc.vcxproj.filters index 653b5206e..0d8313f1d 100644 --- a/renderdoc/renderdoc.vcxproj.filters +++ b/renderdoc/renderdoc.vcxproj.filters @@ -835,12 +835,6 @@ Resources\glsl - - Resources\glsl - - - Resources\glsl - Resources\glsl @@ -862,6 +856,18 @@ Replay + + Resources\glsl + + + Resources\glsl + + + Resources\glsl + + + Resources\glsl +