diff --git a/core/rend/gl4/abuffer.cpp b/core/rend/gl4/abuffer.cpp index 16a9aa292..f11ba055e 100644 --- a/core/rend/gl4/abuffer.cpp +++ b/core/rend/gl4/abuffer.cpp @@ -19,16 +19,17 @@ #include "gl4.h" #include "rend/gles/glcache.h" -GLuint pixels_buffer; -GLuint pixels_pointers; -GLuint atomic_buffer; -gl4PipelineShader g_abuffer_final_shader; -gl4PipelineShader g_abuffer_clear_shader; -gl4PipelineShader g_abuffer_tr_modvol_shaders[ModeCount]; -static GLuint g_quadBuffer = 0; -static GLuint g_quadVertexArray = 0; +static GLuint pixels_buffer; +static GLuint pixels_pointers; +static GLuint atomic_buffer; +static gl4PipelineShader g_abuffer_final_shader; +static gl4PipelineShader g_abuffer_clear_shader; +static gl4PipelineShader g_abuffer_tr_modvol_shaders[ModeCount]; +static GLuint g_quadBuffer; +static GLuint g_quadIndexBuffer; +static GLuint g_quadVertexArray; -GLuint pixel_buffer_size = 512 * 1024 * 1024; // Initial size 512 MB +static GLuint pixel_buffer_size = 512 * 1024 * 1024; // Initial size 512 MB #define MAX_PIXELS_PER_FRAGMENT "32" @@ -254,6 +255,8 @@ void main() } )"; +static void abufferDrawQuad(); + void initABuffer() { if (max_image_width > 0 && max_image_height > 0) @@ -313,20 +316,37 @@ void initABuffer() gl4CompilePipelineShader(&g_abuffer_tr_modvol_shaders[mode], source, VertexShaderSource); } } - - if (g_quadVertexArray == 0) - glGenVertexArrays(1, &g_quadVertexArray); if (g_quadBuffer == 0) { - glBindVertexArray(g_quadVertexArray); glGenBuffers(1, &g_quadBuffer); glBindBuffer(GL_ARRAY_BUFFER, g_quadBuffer); glCheck(); + static const float vertices[] = { + -1, 1, 1, + -1, -1, 1, + 1, 1, 1, + 1, -1, 1, + }; + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + } + if (g_quadIndexBuffer == 0) + { + glGenBuffers(1, &g_quadIndexBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_quadIndexBuffer); + static const GLushort indices[] = { 0, 1, 2, 1, 3 }; + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); + } + if (g_quadVertexArray == 0) + { + glGenVertexArrays(1, &g_quadVertexArray); + glBindVertexArray(g_quadVertexArray); + glBindBuffer(GL_ARRAY_BUFFER, g_quadBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_quadIndexBuffer); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, (void*)0); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glCheck(); glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } glCheck(); @@ -367,6 +387,11 @@ void termABuffer() glDeleteBuffers(1, &g_quadBuffer); g_quadBuffer = 0; } + if (g_quadIndexBuffer != 0) + { + glDeleteBuffers(1, &g_quadIndexBuffer); + g_quadIndexBuffer = 0; + } glcache.DeleteProgram(g_abuffer_final_shader.program); g_abuffer_final_shader.program = 0; glcache.DeleteProgram(g_abuffer_clear_shader.program); @@ -388,22 +413,10 @@ void reshapeABuffer(int w, int h) initABuffer(); } -void abufferDrawQuad() +static void abufferDrawQuad() { glBindVertexArray(g_quadVertexArray); - - float vertices[] = { - -1, 1, 1, - -1, -1, 1, - 1, 1, 1, - 1, -1, 1, - }; - GLushort indices[] = { 0, 1, 2, 1, 3 }; - - glBindBuffer(GL_ARRAY_BUFFER, g_quadBuffer); glCheck(); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STREAM_DRAW); glCheck(); - - glDrawElements(GL_TRIANGLE_STRIP, 5, GL_UNSIGNED_SHORT, indices); glCheck(); + glDrawElements(GL_TRIANGLE_STRIP, 5, GL_UNSIGNED_SHORT, (GLvoid *)0); glBindVertexArray(0); glCheck(); } diff --git a/core/rend/gl4/gl4.h b/core/rend/gl4/gl4.h index 5f25048b3..79cffe309 100755 --- a/core/rend/gl4/gl4.h +++ b/core/rend/gl4/gl4.h @@ -88,11 +88,16 @@ extern int max_image_width; extern int max_image_height; GLuint gl4BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt); -void abufferDrawQuad(); extern const char *gl4PixelPipelineShader; bool gl4CompilePipelineShader(gl4PipelineShader* s, const char *pixel_source = gl4PixelPipelineShader, const char *vertex_source = NULL); -void gl4_delete_shaders(); + +void initABuffer(); +void termABuffer(); +void reshapeABuffer(int width, int height); +void renderABuffer(); +void DrawTranslucentModVols(int first, int count); +void checkOverflowAndReset(); extern GLuint stencilTexId; extern GLuint depthTexId; @@ -248,6 +253,7 @@ bool isTwoVolumes(const PolyParam pp) \n\ void gl4SetupMainVBO(); void gl4SetupModvolVBO(); +void gl4CreateTextures(int width, int height); extern struct gl4ShaderUniforms_t { diff --git a/core/rend/gl4/gldraw.cpp b/core/rend/gl4/gldraw.cpp index 429312ee2..bdca7ecd8 100644 --- a/core/rend/gl4/gldraw.cpp +++ b/core/rend/gl4/gldraw.cpp @@ -389,10 +389,6 @@ static void DrawModVols(int first, int count) glcache.DepthMask(GL_TRUE); } -void renderABuffer(); -void DrawTranslucentModVols(int first, int count); -void checkOverflowAndReset(); - static GLuint CreateColorFBOTexture(int width, int height) { GLuint texId = glcache.GenTexture(); diff --git a/core/rend/gl4/gles.cpp b/core/rend/gl4/gles.cpp index 760029d2d..b4350d86c 100644 --- a/core/rend/gl4/gles.cpp +++ b/core/rend/gl4/gles.cpp @@ -118,8 +118,10 @@ uniform sampler2D DepthTex; uniform float trilinear_alpha; uniform vec4 fog_clamp_min; uniform vec4 fog_clamp_max; +#if pp_Palette == 1 uniform sampler2D palette; uniform int palette_index; +#endif uniform ivec2 blend_mode[2]; #if pp_TwoVolumes == 1 @@ -486,7 +488,7 @@ bool gl4CompilePipelineShader( gl4PipelineShader* s, const char *pixel_source /* return glIsProgram(s->program)==GL_TRUE; } -void gl4_delete_shaders() +static void gl4_delete_shaders() { for (auto it : gl4.shaders) { @@ -556,9 +558,6 @@ static bool gl_create_resources() } //setup -extern void initABuffer(); -void reshapeABuffer(int width, int height); -extern void gl4CreateTextures(int width, int height); static bool gl4_init() { @@ -871,8 +870,6 @@ static bool RenderFrame(int width, int height) return !is_rtt; } -void termABuffer(); - struct OpenGL4Renderer : OpenGLRenderer { bool Init() override diff --git a/core/rend/gles/gldraw.cpp b/core/rend/gles/gldraw.cpp index 3346bb4a9..ec82356b3 100644 --- a/core/rend/gles/gldraw.cpp +++ b/core/rend/gles/gldraw.cpp @@ -469,42 +469,62 @@ void SetMVS_Mode(ModifierVolumeMode mv_mode, ISP_Modvol ispc) static void SetupMainVBO() { #ifndef GLES2 + if (gl.vbo.mainVAO != 0) + { + glBindVertexArray(gl.vbo.mainVAO); + return; + } if (gl.gl_major >= 3) - glBindVertexArray(gl.vbo.vao); + { + glGenVertexArrays(1, &gl.vbo.mainVAO); + glBindVertexArray(gl.vbo.mainVAO); + } #endif glBindBuffer(GL_ARRAY_BUFFER, gl.vbo.geometry); glCheck(); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl.vbo.idxs); glCheck(); //setup vertex buffers attrib pointers - glEnableVertexAttribArray(VERTEX_POS_ARRAY); glCheck(); - glVertexAttribPointer(VERTEX_POS_ARRAY, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex,x)); glCheck(); + glEnableVertexAttribArray(VERTEX_POS_ARRAY); + glVertexAttribPointer(VERTEX_POS_ARRAY, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex,x)); - glEnableVertexAttribArray(VERTEX_COL_BASE_ARRAY); glCheck(); - glVertexAttribPointer(VERTEX_COL_BASE_ARRAY, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (void*)offsetof(Vertex,col)); glCheck(); + glEnableVertexAttribArray(VERTEX_COL_BASE_ARRAY); + glVertexAttribPointer(VERTEX_COL_BASE_ARRAY, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (void*)offsetof(Vertex,col)); - glEnableVertexAttribArray(VERTEX_COL_OFFS_ARRAY); glCheck(); - glVertexAttribPointer(VERTEX_COL_OFFS_ARRAY, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (void*)offsetof(Vertex,spc)); glCheck(); + glEnableVertexAttribArray(VERTEX_COL_OFFS_ARRAY); + glVertexAttribPointer(VERTEX_COL_OFFS_ARRAY, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (void*)offsetof(Vertex,spc)); - glEnableVertexAttribArray(VERTEX_UV_ARRAY); glCheck(); - glVertexAttribPointer(VERTEX_UV_ARRAY, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex,u)); glCheck(); + glEnableVertexAttribArray(VERTEX_UV_ARRAY); + glVertexAttribPointer(VERTEX_UV_ARRAY, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex,u)); + glCheck(); } -void SetupModvolVBO() +static void SetupModvolVBO() { #ifndef GLES2 + if (gl.vbo.modvolVAO != 0) + { + glBindVertexArray(gl.vbo.modvolVAO); + return; + } if (gl.gl_major >= 3) - glBindVertexArray(gl.vbo.vao); + { + glGenVertexArrays(1, &gl.vbo.modvolVAO); + glBindVertexArray(gl.vbo.modvolVAO); + } #endif glBindBuffer(GL_ARRAY_BUFFER, gl.vbo.modvols); glCheck(); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //setup vertex buffers attrib pointers - glEnableVertexAttribArray(VERTEX_POS_ARRAY); glCheck(); - glVertexAttribPointer(VERTEX_POS_ARRAY, 3, GL_FLOAT, GL_FALSE, sizeof(float)*3, (void*)0); glCheck(); + glEnableVertexAttribArray(VERTEX_POS_ARRAY); + glVertexAttribPointer(VERTEX_POS_ARRAY, 3, GL_FLOAT, GL_FALSE, sizeof(float)*3, (void*)0); glDisableVertexAttribArray(VERTEX_UV_ARRAY); glDisableVertexAttribArray(VERTEX_COL_OFFS_ARRAY); glDisableVertexAttribArray(VERTEX_COL_BASE_ARRAY); + glCheck(); } + void DrawModVols(int first, int count) { if (count == 0 || pvrrc.modtrig.used() == 0) diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index 4d9ed347a..f6f4881dc 100644 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -112,8 +112,10 @@ uniform sampler2D tex,fog_table; uniform lowp float trilinear_alpha; uniform lowp vec4 fog_clamp_min; uniform lowp vec4 fog_clamp_max; +#if pp_Palette == 1 uniform sampler2D palette; uniform mediump int palette_index; +#endif /* Vertex input*/ INTERPOLATION in lowp vec4 vtx_base; @@ -369,6 +371,12 @@ static void gl_delete_shaders() static void gles_term() { termQuad(); +#ifndef GLES2 + glDeleteVertexArrays(1, &gl.vbo.mainVAO); + gl.vbo.mainVAO = 0; + glDeleteVertexArrays(1, &gl.vbo.modvolVAO); + gl.vbo.modvolVAO = 0; +#endif glDeleteBuffers(1, &gl.vbo.geometry); gl.vbo.geometry = 0; glDeleteBuffers(1, &gl.vbo.modvols); @@ -647,11 +655,15 @@ bool CompilePipelineShader( PipelineShader* s) static void SetupOSDVBO() { #ifndef GLES2 + if (gl.OSD_SHADER.vao != 0) + { + glBindVertexArray(gl.OSD_SHADER.vao); + return; + } if (gl.gl_major >= 3) { - if (gl.OSD_SHADER.vao == 0) - glGenVertexArrays(1, &gl.OSD_SHADER.vao); - glBindVertexArray(gl.OSD_SHADER.vao); + glGenVertexArrays(1, &gl.OSD_SHADER.vao); + glBindVertexArray(gl.OSD_SHADER.vao); } #endif if (gl.OSD_SHADER.geometry == 0) @@ -746,15 +758,8 @@ bool gl_create_resources() findGLVersion(); if (gl.gl_major >= 3) - { - verify(glGenVertexArrays != NULL); - //create vao - //This is really not "proper", vaos are supposed to be defined once - //i keep updating the same one to make the es2 code work in 3.1 context -#ifndef GLES2 - glGenVertexArrays(1, &gl.vbo.vao); -#endif - } + // will be used later. Better fail fast + verify(glGenVertexArrays != nullptr); //create vbos glGenBuffers(1, &gl.vbo.geometry); diff --git a/core/rend/gles/gles.h b/core/rend/gles/gles.h index 72b8eb3da..7037eb5df 100755 --- a/core/rend/gles/gles.h +++ b/core/rend/gles/gles.h @@ -84,7 +84,8 @@ struct gl_ctx struct { GLuint geometry,modvols,idxs,idxs2; - GLuint vao; + GLuint mainVAO; + GLuint modvolVAO; } vbo; struct