From aa6751ee4a906474367187e4b5cfaf2b8706b0b6 Mon Sep 17 00:00:00 2001 From: Andre Weissflog Date: Tue, 2 Sep 2014 22:59:44 +0200 Subject: [PATCH] Merge uniforms into a single uniform array, reducing number of glUniform calls. Conflicts: src/nanovg_gl.h --- src/nanovg_gl.h | 179 +++++++++++++++++++----------------------------- 1 file changed, 69 insertions(+), 110 deletions(-) diff --git a/src/nanovg_gl.h b/src/nanovg_gl.h index 5ed5ef9..24be2d5 100644 --- a/src/nanovg_gl.h +++ b/src/nanovg_gl.h @@ -107,23 +107,7 @@ GLuint nvglImageHandle(NVGcontext* ctx, int image); enum GLNVGuniformLoc { GLNVG_LOC_VIEWSIZE, GLNVG_LOC_TEX, -#if NANOVG_GL_USE_UNIFORMBUFFER GLNVG_LOC_FRAG, -#else - GLNVG_LOC_SCISSORMAT, - GLNVG_LOC_SCISSOREXT, - GLNVG_LOC_SCISSORSCALE, - GLNVG_LOC_PAINTMAT, - GLNVG_LOC_EXTENT, - GLNVG_LOC_RADIUS, - GLNVG_LOC_FEATHER, - GLNVG_LOC_INNERCOL, - GLNVG_LOC_OUTERCOL, - GLNVG_LOC_STROKEMULT, - GLNVG_LOC_STROKETHR, - GLNVG_LOC_TEXTYPE, - GLNVG_LOC_TYPE, -#endif GLNVG_MAX_LOCS }; @@ -185,19 +169,43 @@ struct GLNVGpath { typedef struct GLNVGpath GLNVGpath; struct GLNVGfragUniforms { - float scissorMat[12]; // matrices are actually 3 vec4s - float paintMat[12]; - struct NVGcolor innerCol; - struct NVGcolor outerCol; - float scissorExt[2]; - float scissorScale[2]; - float extent[2]; - float radius; - float feather; - float strokeMult; - float strokeThr; - int texType; - int type; + #if NANOVG_GL_USE_UNIFORMBUFFER + float scissorMat[12]; // matrices are actually 3 vec4s + float paintMat[12]; + struct NVGcolor innerCol; + struct NVGcolor outerCol; + float scissorExt[2]; + float scissorScale[2]; + float extent[2]; + float radius; + float feather; + float strokeMult; + float strokeThr; + int texType; + int type; + #else + // note: after modifying layout or size of uniform array, + // don't forget to also update the fragment shader source! + #define NANOVG_GL_UNIFORMARRAY_SIZE 11 + union { + struct { + float scissorMat[12]; // matrices are actually 3 vec4s + float paintMat[12]; + struct NVGcolor innerCol; + struct NVGcolor outerCol; + float scissorExt[2]; + float scissorScale[2]; + float extent[2]; + float radius; + float feather; + float strokeMult; + float strokeThr; + float texType; + float type; + }; + float uniformArray[NANOVG_GL_UNIFORMARRAY_SIZE][4]; + }; + #endif }; typedef struct GLNVGfragUniforms GLNVGfragUniforms; @@ -403,19 +411,7 @@ static void glnvg__getUniforms(GLNVGshader* shader) #if NANOVG_GL_USE_UNIFORMBUFFER shader->loc[GLNVG_LOC_FRAG] = glGetUniformBlockIndex(shader->prog, "frag"); #else - shader->loc[GLNVG_LOC_SCISSORMAT] = glGetUniformLocation(shader->prog, "scissorMat"); - shader->loc[GLNVG_LOC_SCISSOREXT] = glGetUniformLocation(shader->prog, "scissorExt"); - shader->loc[GLNVG_LOC_SCISSORSCALE] = glGetUniformLocation(shader->prog, "scissorScale"); - shader->loc[GLNVG_LOC_PAINTMAT] = glGetUniformLocation(shader->prog, "paintMat"); - shader->loc[GLNVG_LOC_EXTENT] = glGetUniformLocation(shader->prog, "extent"); - shader->loc[GLNVG_LOC_RADIUS] = glGetUniformLocation(shader->prog, "radius"); - shader->loc[GLNVG_LOC_FEATHER] = glGetUniformLocation(shader->prog, "feather"); - shader->loc[GLNVG_LOC_INNERCOL] = glGetUniformLocation(shader->prog, "innerCol"); - shader->loc[GLNVG_LOC_OUTERCOL] = glGetUniformLocation(shader->prog, "outerCol"); - shader->loc[GLNVG_LOC_STROKEMULT] = glGetUniformLocation(shader->prog, "strokeMult"); - shader->loc[GLNVG_LOC_STROKETHR] = glGetUniformLocation(shader->prog, "strokeThr"); - shader->loc[GLNVG_LOC_TEXTYPE] = glGetUniformLocation(shader->prog, "texType"); - shader->loc[GLNVG_LOC_TYPE] = glGetUniformLocation(shader->prog, "type"); + shader->loc[GLNVG_LOC_FRAG] = glGetUniformLocation(shader->prog, "frag"); #endif } @@ -428,20 +424,24 @@ static int glnvg__renderCreate(void* uptr) // see the following discussion: https://github.com/memononen/nanovg/issues/46 static const char* shaderHeader = #if defined NANOVG_GL2 - "#define NANOVG_GL2 1\n"; + "#define NANOVG_GL2 1\n" #elif defined NANOVG_GL3 "#version 150 core\n" -#if NANOVG_GL_USE_UNIFORMBUFFER - "#define USE_UNIFORMBUFFER 1\n" -#endif - "#define NANOVG_GL3 1\n"; + "#define NANOVG_GL3 1\n" #elif defined NANOVG_GLES2 "#version 100\n" - "#define NANOVG_GL2 1\n"; + "#define NANOVG_GL2 1\n" #elif defined NANOVG_GLES3 "#version 300 es\n" - "#define NANOVG_GL3 1\n"; + "#define NANOVG_GL3 1\n" +#endif + +#if NANOVG_GL_USE_UNIFORMBUFFER + "#define USE_UNIFORMBUFFER 1\n" +#else + "#define UNIFORMARRAY_SIZE 11\n" #endif + "\n"; static const char* fillVertShader = "#ifdef NANOVG_GL3\n" @@ -488,43 +488,34 @@ static int glnvg__renderCreate(void* uptr) " int texType;\n" " int type;\n" " };\n" - "#else\n" - " uniform mat3 scissorMat;\n" - " uniform mat3 paintMat;\n" - " uniform vec4 innerCol;\n" - " uniform vec4 outerCol;\n" - " uniform vec2 scissorExt;\n" - " uniform vec2 scissorScale;\n" - " uniform vec2 extent;\n" - " uniform float radius;\n" - " uniform float feather;\n" - " uniform float strokeMult;\n" - " uniform float strokeThr;\n" - " uniform int texType;\n" - " uniform int type;\n" + "#else\n" // NANOVG_GL3 && !USE_UNIFORMBUFFER + " uniform vec4 frag[UNIFORMARRAY_SIZE];\n" "#endif\n" " uniform sampler2D tex;\n" " in vec2 ftcoord;\n" " in vec2 fpos;\n" " out vec4 outColor;\n" - "#else\n" - " uniform mat3 scissorMat;\n" - " uniform mat3 paintMat;\n" - " uniform vec4 innerCol;\n" - " uniform vec4 outerCol;\n" - " uniform vec2 scissorExt;\n" - " uniform vec2 scissorScale;\n" - " uniform vec2 extent;\n" - " uniform float radius;\n" - " uniform float feather;\n" - " uniform float strokeMult;\n" - " uniform float strokeThr;\n" - " uniform int texType;\n" - " uniform int type;\n" + "#else\n" // !NANOVG_GL3 + " uniform vec4 frag[UNIFORMARRAY_SIZE];\n" " uniform sampler2D tex;\n" " varying vec2 ftcoord;\n" " varying vec2 fpos;\n" "#endif\n" + "#ifndef USE_UNIFORMBUFFER\n" + " #define scissorMat mat3(frag[0].xyz, frag[1].xyz, frag[2].xyz)\n" + " #define paintMat mat3(frag[3].xyz, frag[4].xyz, frag[5].xyz)\n" + " #define innerCol frag[6]\n" + " #define outerCol frag[7]\n" + " #define scissorExt frag[8].xy\n" + " #define scissorScale frag[8].zw\n" + " #define extent frag[9].xy\n" + " #define radius frag[9].z\n" + " #define feather frag[9].w\n" + " #define strokeMult frag[10].x\n" + " #define strokeThr frag[10].y\n" + " #define texType int(frag[10].z)\n" + " #define type int(frag[10].w)\n" + "#endif\n" "\n" "float sdroundrect(vec2 pt, vec2 ext, float rad) {\n" " vec2 ext2 = ext - vec2(rad,rad);\n" @@ -874,45 +865,13 @@ static int glnvg__convertPaint(GLNVGcontext* gl, GLNVGfragUniforms* frag, NVGpai static GLNVGfragUniforms* nvg__fragUniformPtr(GLNVGcontext* gl, int i); -#if !NANOVG_GL_USE_UNIFORMBUFFER -static void glnvg__mat3(float* dst, float* src) -{ - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; - - dst[3] = src[4]; - dst[4] = src[5]; - dst[5] = src[6]; - - dst[6] = src[8]; - dst[7] = src[9]; - dst[8] = src[10]; -} -#endif - static void glnvg__setUniforms(GLNVGcontext* gl, int uniformOffset, int image) { #if NANOVG_GL_USE_UNIFORMBUFFER glBindBufferRange(GL_UNIFORM_BUFFER, GLNVG_FRAG_BINDING, gl->fragBuf, uniformOffset, sizeof(GLNVGfragUniforms)); #else GLNVGfragUniforms* frag = nvg__fragUniformPtr(gl, uniformOffset); - float tmp[9]; // Maybe there's a way to get rid of this... - glnvg__mat3(tmp, frag->scissorMat); - glUniformMatrix3fv(gl->shader.loc[GLNVG_LOC_SCISSORMAT], 1, GL_FALSE, tmp); - glnvg__mat3(tmp, frag->paintMat); - glUniformMatrix3fv(gl->shader.loc[GLNVG_LOC_PAINTMAT], 1, GL_FALSE, tmp); - glUniform4fv(gl->shader.loc[GLNVG_LOC_INNERCOL], 1, frag->innerCol.rgba); - glUniform4fv(gl->shader.loc[GLNVG_LOC_OUTERCOL], 1, frag->outerCol.rgba); - glUniform2fv(gl->shader.loc[GLNVG_LOC_SCISSOREXT], 1, frag->scissorExt); - glUniform2fv(gl->shader.loc[GLNVG_LOC_SCISSORSCALE], 1, frag->scissorScale); - glUniform2fv(gl->shader.loc[GLNVG_LOC_EXTENT], 1, frag->extent); - glUniform1f(gl->shader.loc[GLNVG_LOC_RADIUS], frag->radius); - glUniform1f(gl->shader.loc[GLNVG_LOC_FEATHER], frag->feather); - glUniform1f(gl->shader.loc[GLNVG_LOC_STROKEMULT], frag->strokeMult); - glUniform1f(gl->shader.loc[GLNVG_LOC_STROKETHR], frag->strokeThr); - glUniform1i(gl->shader.loc[GLNVG_LOC_TEXTYPE], frag->texType); - glUniform1i(gl->shader.loc[GLNVG_LOC_TYPE], frag->type); + glUniform4fv(gl->shader.loc[GLNVG_LOC_FRAG], NANOVG_GL_UNIFORMARRAY_SIZE, &(frag->uniformArray[0][0])); #endif if (image != 0) {