From 77fae1ef09262c562ecfbe3e79491b4f0d303ab3 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Fri, 5 Oct 2018 15:07:30 +0200 Subject: [PATCH] Backport changes from libretro --- core/rend/gl4/gl4.h | 4 -- core/rend/gl4/gldraw.cpp | 28 ++++++++-- core/rend/gl4/gles.cpp | 94 ++++++++++++++++++++------------ core/rend/gles/glcache.h | 112 ++++++++++++++++++++++----------------- core/rend/gles/gles.cpp | 13 +++-- 5 files changed, 157 insertions(+), 94 deletions(-) diff --git a/core/rend/gl4/gl4.h b/core/rend/gl4/gl4.h index 46a80d2b1..73c72cc0c 100755 --- a/core/rend/gl4/gl4.h +++ b/core/rend/gl4/gl4.h @@ -77,10 +77,6 @@ extern int screen_height; GLuint gl4BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt); void gl4DrawFramebuffer(float w, float h); -int gl4GetProgramID(u32 cp_AlphaTest, u32 pp_ClipTestMode, - u32 pp_Texture, u32 pp_UseAlpha, u32 pp_IgnoreTexA, u32 pp_ShadInstr, u32 pp_Offset, - u32 pp_FogCtrl, bool two_volumes, u32 pp_DepthFunc, bool pp_Gouraud, bool pp_BumpMap, bool fog_clamping, int pass); - extern const char *gl4PixelPipelineShader; bool gl4CompilePipelineShader(gl4PipelineShader* s, const char *source = gl4PixelPipelineShader); diff --git a/core/rend/gl4/gldraw.cpp b/core/rend/gl4/gldraw.cpp index 8a784489e..cbf516bfb 100644 --- a/core/rend/gl4/gldraw.cpp +++ b/core/rend/gl4/gldraw.cpp @@ -44,6 +44,30 @@ static GLuint texSamplers[2]; static GLuint depth_fbo; GLuint depthSaveTexId; +static int gl4GetProgramID(u32 cp_AlphaTest, u32 pp_ClipTestMode, + u32 pp_Texture, u32 pp_UseAlpha, u32 pp_IgnoreTexA, u32 pp_ShadInstr, u32 pp_Offset, + u32 pp_FogCtrl, bool pp_TwoVolumes, u32 pp_DepthFunc, bool pp_Gouraud, bool pp_BumpMap, bool fog_clamping, int pass) +{ + u32 rv=0; + + rv|=pp_ClipTestMode; + rv<<=1; rv|=cp_AlphaTest; + rv<<=1; rv|=pp_Texture; + rv<<=1; rv|=pp_UseAlpha; + rv<<=1; rv|=pp_IgnoreTexA; + rv<<=2; rv|=pp_ShadInstr; + rv<<=1; rv|=pp_Offset; + rv<<=2; rv|=pp_FogCtrl; + rv <<= 1; rv |= (int)pp_TwoVolumes; + rv <<= 3; rv |= pp_DepthFunc; + rv <<= 1; rv |= (int)pp_Gouraud; + rv <<= 1; rv |= pp_BumpMap; + rv <<= 1; rv |= fog_clamping; + rv <<= 2; rv |= pass; + + return rv; +} + static void setCurrentShader(u32 cp_AlphaTest, u32 pp_ClipTestMode, u32 pp_Texture, u32 pp_UseAlpha, u32 pp_IgnoreTexA, u32 pp_ShadInstr, u32 pp_Offset, u32 pp_FogCtrl, bool pp_TwoVolumes, u32 pp_DepthFunc, bool pp_Gouraud, bool pp_BumpMap, bool fog_clamping, int pass) @@ -446,11 +470,9 @@ void gl4DrawStrips(GLuint output_fbo) if (texSamplers[0] == 0) glGenSamplers(2, texSamplers); - glcache.ClearColor(0, 0, 0, 0); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glcache.DepthMask(GL_TRUE); glStencilMask(0xFF); - glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glCheck(); + glClear(GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glCheck(); SetupMainVBO(); //Draw the strips ! diff --git a/core/rend/gl4/gles.cpp b/core/rend/gl4/gles.cpp index 7755d87cf..ed182b556 100644 --- a/core/rend/gl4/gles.cpp +++ b/core/rend/gl4/gles.cpp @@ -409,30 +409,6 @@ gl4_ctx gl4; struct gl4ShaderUniforms_t gl4ShaderUniforms; -int gl4GetProgramID(u32 cp_AlphaTest, u32 pp_ClipTestMode, - u32 pp_Texture, u32 pp_UseAlpha, u32 pp_IgnoreTexA, u32 pp_ShadInstr, u32 pp_Offset, - u32 pp_FogCtrl, bool pp_TwoVolumes, u32 pp_DepthFunc, bool pp_Gouraud, bool pp_BumpMap, bool fog_clamping, int pass) -{ - u32 rv=0; - - rv|=pp_ClipTestMode; - rv<<=1; rv|=cp_AlphaTest; - rv<<=1; rv|=pp_Texture; - rv<<=1; rv|=pp_UseAlpha; - rv<<=1; rv|=pp_IgnoreTexA; - rv<<=2; rv|=pp_ShadInstr; - rv<<=1; rv|=pp_Offset; - rv<<=2; rv|=pp_FogCtrl; - rv <<= 1; rv |= (int)pp_TwoVolumes; - rv <<= 3; rv |= pp_DepthFunc; - rv <<= 1; rv |= (int)pp_Gouraud; - rv <<= 1; rv |= pp_BumpMap; - rv <<= 1; rv |= fog_clamping; - rv <<= 2; rv |= pass; - - return rv; -} - bool gl4CompilePipelineShader( gl4PipelineShader* s, const char *source /* = PixelPipelineShader */) { char vshader[16384]; @@ -505,6 +481,7 @@ bool gl4CompilePipelineShader( gl4PipelineShader* s, const char *source /* = Pix glUniform1i(gu, 3); // GL_TEXTURE3 s->pp_Number = glGetUniformLocation(s->program, "pp_Number"); + s->pp_DepthFunc = glGetUniformLocation(s->program, "pp_DepthFunc"); s->blend_mode = glGetUniformLocation(s->program, "blend_mode"); s->use_alpha = glGetUniformLocation(s->program, "use_alpha"); @@ -515,6 +492,24 @@ bool gl4CompilePipelineShader( gl4PipelineShader* s, const char *source /* = Pix return glIsProgram(s->program)==GL_TRUE; } +static void gl_term(void) +{ + gl4.vbo.geometry = 0; + glDeleteProgram(gl4.modvol_shader.program); + glDeleteBuffers(1, &gl4.vbo.geometry); + glDeleteBuffers(1, &gl4.vbo.modvols); + glDeleteBuffers(1, &gl4.vbo.idxs); + glDeleteBuffers(1, &gl4.vbo.idxs2); + glDeleteBuffers(1, &gl4.vbo.tr_poly_params); + for (auto it = gl4.shaders.begin(); it != gl4.shaders.end(); it++) + { + if (it->second->program != -1) + glDeleteProgram(it->second->program); + delete it->second; + } + gl4.shaders.clear(); +} + static bool gl_create_resources() { if (gl4.vbo.geometry != 0) @@ -579,6 +574,8 @@ static bool gles_init() } printf("Per-pixel sorting enabled\n"); + glcache.DisableCache(); + if (!gl_create_resources()) return false; @@ -602,6 +599,7 @@ static bool gles_init() u32 dst[16]; UpscalexBRZ(2, src, dst, 2, 2, false); } + fog_needs_update = true; return true; } @@ -822,9 +820,6 @@ static bool RenderFrame() glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(struct PolyParam) * pvrrc.global_param_tr.used(), pvrrc.global_param_tr.head(), GL_STATIC_DRAW); glCheck(); - int offs_x=ds2s_offs_x+0.5f; - //this needs to be scaled - //not all scaling affects pixel operations, scale to adjust for that scale_x *= scissoring_scale_x; @@ -844,7 +839,7 @@ static bool RenderFrame() if (!is_rtt) { // Add x offset for aspect ratio > 4/3 - min_x = min_x * dc2s_scale_h + offs_x; + min_x = min_x * dc2s_scale_h + ds2s_offs_x; // Invert y coordinates when rendering to screen min_y = screen_height - (min_y + height) * dc2s_scale_h; width *= dc2s_scale_h; @@ -852,11 +847,13 @@ static bool RenderFrame() if (ds2s_offs_x > 0) { + float rounded_offs_x = ds2s_offs_x + 0.5f; + glcache.ClearColor(0.f, 0.f, 0.f, 0.f); glcache.Enable(GL_SCISSOR_TEST); - glScissor(0, 0, ds2s_offs_x, screen_height); + glScissor(0, 0, rounded_offs_x, screen_height); glClear(GL_COLOR_BUFFER_BIT); - glScissor(screen_width - ds2s_offs_x, 0, ds2s_offs_x, screen_height); + glScissor(screen_width - rounded_offs_x, 0, rounded_offs_x, screen_height); glClear(GL_COLOR_BUFFER_BIT); } } @@ -868,7 +865,7 @@ static bool RenderFrame() height *= settings.rend.RenderToTextureUpscale; } - glScissor(min_x, min_y, width, height); + glScissor(min_x + 0.5f, min_y + 0.5f, width + 0.5f, height + 0.5f); glcache.Enable(GL_SCISSOR_TEST); } @@ -883,11 +880,8 @@ static bool RenderFrame() glcache.ClearColor(0.f, 0.f, 0.f, 0.f); glClear(GL_COLOR_BUFFER_BIT); - DrawFramebuffer(dc_width, dc_height); + gl4DrawFramebuffer(dc_width, dc_height); } - #if HOST_OS==OS_WINDOWS - //Sleep(40); //to test MT stability - #endif eglCheck(); @@ -934,6 +928,36 @@ struct gl4rend : Renderer void Term() { termABuffer(); + if (stencilTexId != 0) + { + glcache.DeleteTextures(1, &stencilTexId); + stencilTexId = 0; + } + if (depthTexId != 0) + { + glcache.DeleteTextures(1, &depthTexId); + depthTexId = 0; + } + if (opaqueTexId != 0) + { + glcache.DeleteTextures(1, &opaqueTexId); + opaqueTexId = 0; + } + if (depthSaveTexId != 0) + { + glcache.DeleteTextures(1, &depthSaveTexId); + depthSaveTexId = 0; + } + if (KillTex) + { + void killtex(); + killtex(); + printf("Texture cache cleared\n"); + } + + CollectCleanup(); + + gl_term(); } bool Process(TA_context* ctx) { return ProcessFrame(ctx); } diff --git a/core/rend/gles/glcache.h b/core/rend/gles/glcache.h index b72bd61fa..d7f292af9 100644 --- a/core/rend/gles/glcache.h +++ b/core/rend/gles/glcache.h @@ -9,16 +9,18 @@ public: GLCache() { Reset(); } void BindTexture(GLenum target, GLuint texture) { - if (target == GL_TEXTURE_2D && texture != _texture) { + if (target == GL_TEXTURE_2D && !_disable_cache) { + if (texture != _texture) { glBindTexture(target, texture); _texture = texture; + } } else glBindTexture(target, texture); } void BlendFunc(GLenum sfactor, GLenum dfactor) { - if (sfactor != _src_blend_factor || dfactor != _dst_blend_factor) { + if (sfactor != _src_blend_factor || dfactor != _dst_blend_factor || _disable_cache) { _src_blend_factor = sfactor; _dst_blend_factor = dfactor; glBlendFunc(sfactor, dfactor); @@ -26,7 +28,7 @@ public: } void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { - if (red != _clear_r || green != _clear_g || blue != _clear_b || alpha != _clear_a) { + if (red != _clear_r || green != _clear_g || blue != _clear_b || alpha != _clear_a || _disable_cache) { _clear_r = red; _clear_g = green; _clear_b = blue; @@ -36,15 +38,16 @@ public: } void CullFace(GLenum mode) { - if (mode != _cull_face) { + if (mode != _cull_face || _disable_cache) { _cull_face = mode; glCullFace(mode); } } void DeleteTextures(GLsizei n, const GLuint *textures) { - for (int i = 0; i < n; i++) { - _texture_params.erase(textures[i]); + for (int i = 0; i < n; i++) + { + _texture_params.erase(textures[i]); if (textures[i] == _texture) _texture = 0; } @@ -52,61 +55,64 @@ public: } void DepthFunc(GLenum func) { - if (func != _depth_func) { + if (func != _depth_func || _disable_cache) { _depth_func = func; glDepthFunc(func); } } void DepthMask(GLboolean flag) { - if (flag != _depth_mask) { + if (flag != _depth_mask || _disable_cache) { _depth_mask = flag; glDepthMask(flag); } } void Enable(GLenum cap) { - setCapability(cap, true); + setCapability(cap, GL_TRUE); } void Disable(GLenum cap) { - setCapability(cap, false); + setCapability(cap, GL_FALSE); } void UseProgram(GLuint program) { - if (program != _program) { + if (program != _program || _disable_cache) { _program = program; glUseProgram(program); } } void StencilFunc(GLenum func, GLint ref, GLuint mask) { - if (_stencil_func != func || _stencil_ref != ref || _stencil_fmask != mask) { + if (_stencil_func != func || _stencil_ref != ref || _stencil_fmask != mask || _disable_cache) { _stencil_func = func; _stencil_ref = ref; _stencil_fmask = mask; + glStencilFunc(func, ref, mask); } } void StencilOp(GLenum sfail, GLenum dpfail, GLenum dppass) { - if (_stencil_sfail != sfail ||_stencil_dpfail != dpfail || _stencil_dppass != dppass) { + if (_stencil_sfail != sfail ||_stencil_dpfail != dpfail || _stencil_dppass != dppass || _disable_cache) { _stencil_sfail = sfail; _stencil_dpfail = dpfail; _stencil_dppass = dppass; + glStencilOp(sfail, dpfail, dppass); } } void StencilMask(GLuint mask) { - if (_stencil_mask != mask) { + if (_stencil_mask != mask || _disable_cache) { _stencil_mask = mask; glStencilMask(mask); } } - void TexParameteri(GLenum target, GLenum pname, GLint param) { - if (target == GL_TEXTURE_2D) + void TexParameteri(GLenum target, GLenum pname, GLint param) + { + if (target == GL_TEXTURE_2D && !_disable_cache) { TextureParameters &cur_params = _texture_params[_texture]; switch (pname) { @@ -144,36 +150,43 @@ public: } void Reset() { - _texture = 0; - _src_blend_factor = GL_ONE; - _dst_blend_factor = GL_ZERO; - _clear_r = 0.f; - _clear_g = 0.f; - _clear_b = 0.f; - _clear_a = 0.f; - _en_blend = false; - _en_cull_face = false; - _en_depth_test = false; - _en_scissor_test = false; - _en_stencil_test = false; - _cull_face = GL_BACK; - _depth_func = GL_LESS; - _depth_mask = true; - _program = 0; + _texture = 0xFFFFFFFFu; + _src_blend_factor = 0xFFFFFFFFu; + _dst_blend_factor = 0xFFFFFFFFu; + _clear_r = -1.f; + _clear_g = -1.f; + _clear_b = -1.f; + _clear_a = -1.f; + _en_blend = 0xFF; + _en_cull_face = 0xFF; + _en_depth_test = 0xFF; + _en_scissor_test = 0xFF; + _en_stencil_test = 0xFF; + _cull_face = 0xFFFFFFFFu; + _depth_func = 0xFFFFFFFFu; + _depth_mask = 0xFF; + _program = 0xFFFFFFFFu; _texture_cache_size = 0; - _stencil_func = GL_ALWAYS; - _stencil_ref = 0; - _stencil_fmask = ~0; - _stencil_sfail = GL_KEEP; - _stencil_dpfail = GL_KEEP; - _stencil_dppass = GL_KEEP; - _stencil_mask = ~0; + _stencil_func = 0xFFFFFFFFu; + _stencil_ref = -1; + _stencil_fmask = 0; + _stencil_sfail = 0xFFFFFFFFu; + _stencil_dpfail = 0xFFFFFFFFu; + _stencil_dppass = 0xFFFFFFFFu; + _stencil_mask = 0; + } + + void DisableCache() { _disable_cache = true; } + void EnableCache() + { + _disable_cache = true; + Reset(); } private: class TextureParameters { public: - TextureParameters() : _min_filter(GL_NEAREST_MIPMAP_LINEAR), _mag_filter(GL_LINEAR), _wrap_s(GL_REPEAT), _wrap_t(GL_REPEAT) {} + TextureParameters() : _min_filter(0xFFFFFFFFu), _mag_filter(0xFFFFFFFFu), _wrap_s(0xFFFFFFFFu), _wrap_t(0xFFFFFFFFu) {} GLenum _min_filter; GLenum _mag_filter; @@ -181,8 +194,8 @@ private: GLenum _wrap_t; }; - void setCapability(GLenum cap, bool value) { - bool *pCap = NULL; + void setCapability(GLenum cap, GLboolean value) { + GLboolean *pCap = NULL; switch (cap) { case GL_BLEND: pCap = &_en_blend; @@ -201,7 +214,7 @@ private: break; } if (pCap != NULL) { - if (*pCap == value) + if (*pCap == value && !_disable_cache) return; *pCap = value; } @@ -211,6 +224,8 @@ private: glDisable(cap); } + GLuint _array_buffer; + GLuint _element_array_buffer; GLuint _texture; GLenum _src_blend_factor; GLenum _dst_blend_factor; @@ -218,11 +233,11 @@ private: GLclampf _clear_g; GLclampf _clear_b; GLclampf _clear_a; - bool _en_blend; - bool _en_cull_face; - bool _en_depth_test; - bool _en_scissor_test; - bool _en_stencil_test; + GLboolean _en_blend; + GLboolean _en_cull_face; + GLboolean _en_depth_test; + GLboolean _en_scissor_test; + GLboolean _en_stencil_test; GLenum _cull_face; GLenum _depth_func; GLboolean _depth_mask; @@ -237,6 +252,7 @@ private: GLuint _texture_ids[TEXTURE_ID_CACHE_SIZE]; GLuint _texture_cache_size; std::map _texture_params; + bool _disable_cache; }; extern GLCache glcache; diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index a63d69322..841e45e6c 100644 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -1087,6 +1087,8 @@ bool gles_init() (void*)libPvr_GetRenderSurface())) return false; + glcache.EnableCache(); + if (!gl_create_resources()) return false; @@ -1119,6 +1121,7 @@ bool gles_init() u32 dst[16]; UpscalexBRZ(2, src, dst, 2, 2, false); } + fog_needs_update = true; return true; } @@ -1905,7 +1908,7 @@ bool RenderFrame() if (!is_rtt) { // Add x offset for aspect ratio > 4/3 - min_x = min_x * dc2s_scale_h + offs_x; + min_x = min_x * dc2s_scale_h + ds2s_offs_x; // Invert y coordinates when rendering to screen min_y = screen_height - (min_y + height) * dc2s_scale_h; width *= dc2s_scale_h; @@ -1913,11 +1916,13 @@ bool RenderFrame() if (ds2s_offs_x > 0) { + float rounded_offs_x = ds2s_offs_x + 0.5f; + glcache.ClearColor(0.f, 0.f, 0.f, 0.f); glcache.Enable(GL_SCISSOR_TEST); - glScissor(0, 0, offs_x, screen_height); + glScissor(0, 0, rounded_offs_x, screen_height); glClear(GL_COLOR_BUFFER_BIT); - glScissor(screen_width - offs_x, 0, offs_x, screen_height); + glScissor(screen_width - rounded_offs_x, 0, rounded_offs_x, screen_height); glClear(GL_COLOR_BUFFER_BIT); } } @@ -1929,7 +1934,7 @@ bool RenderFrame() height *= settings.rend.RenderToTextureUpscale; } - glScissor(min_x, min_y, width, height); + glScissor(min_x + 0.5f, min_y + 0.5f, width + 0.5f, height + 0.5f); glcache.Enable(GL_SCISSOR_TEST); }