From 3b22f0fb0c1704fed75631686685cc78dfe8d480 Mon Sep 17 00:00:00 2001 From: "gregory.hainaut" Date: Tue, 12 Jun 2012 18:14:01 +0000 Subject: [PATCH] zzogl glsl4: * properly delete program and vertex array. Avoid a crash on plugin reload * reset shader state. Avoid to reuse invalid data on plugin reload gsdx: * add an hack to unattach/attach the gl context from different thread. Help to solve some crashes. The best will be to move gpu operation out of gsreadfifo but it would need more works * implement logz for test purpose (don't seem to help) gsdx replay: * use default xdg location git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5289 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/GSdx/CMakeLists.txt | 5 ++++ plugins/GSdx/GS.cpp | 23 ++++++++-------- plugins/GSdx/GSRendererOGL.cpp | 3 ++- plugins/GSdx/GSState.cpp | 13 ++++++++++ plugins/GSdx/GSTextureFXOGL.cpp | 1 + plugins/GSdx/GSWnd.cpp | 15 ++++++++--- plugins/GSdx/GSWnd.h | 2 ++ plugins/GSdx/linux_replay.cpp | 26 ++++++++++++++++--- plugins/GSdx/res/tfx.glsl | 10 ++++--- plugins/zzogl-pg/opengl/ZZGl.h | 11 ++++++++ plugins/zzogl-pg/opengl/ZZoglCreate.cpp | 14 +++++----- plugins/zzogl-pg/opengl/ZZoglShaders.h | 23 ++++++++++++++++ plugins/zzogl-pg/opengl/ZZoglShadersGLSL4.cpp | 12 ++++++--- plugins/zzogl-pg/opengl/ps2hw_gl4.glsl | 14 +++++----- 14 files changed, 133 insertions(+), 39 deletions(-) diff --git a/plugins/GSdx/CMakeLists.txt b/plugins/GSdx/CMakeLists.txt index b6fa45ae4..629ea4c9a 100644 --- a/plugins/GSdx/CMakeLists.txt +++ b/plugins/GSdx/CMakeLists.txt @@ -10,6 +10,7 @@ endif(NOT TOP_CMAKE_WAS_SOURCED) set(Output GSdx-0.1.16) set(CommonFlags + -DOGL_MT_HACK -D_LINUX -fno-operator-names -mpreferred-stack-boundary=2 @@ -49,6 +50,10 @@ if(CMAKE_BUILD_TYPE STREQUAL Release) add_definitions(${CommonFlags} ${SDLFlags} ${OptimizationFlags} -W) endif(CMAKE_BUILD_TYPE STREQUAL Release) +if(XDG_STD) + add_definitions(-DXDG_STD) +endif(XDG_STD) + set(GSdxSources GPU.cpp GPUDrawScanline.cpp diff --git a/plugins/GSdx/GS.cpp b/plugins/GSdx/GS.cpp index e04dde332..0e705371b 100644 --- a/plugins/GSdx/GS.cpp +++ b/plugins/GSdx/GS.cpp @@ -55,7 +55,11 @@ extern bool RunLinuxDialog(); #define PS2E_X86 0x01 // 32 bit #define PS2E_X86_64 0x02 // 64 bit +#ifdef OGL_MT_HACK +GSRenderer* s_gs = NULL; +#else static GSRenderer* s_gs = NULL; +#endif static void (*s_irq)() = NULL; static uint8* s_basemem = NULL; static int s_renderer = -1; @@ -457,18 +461,18 @@ EXPORT_C GSreadFIFO(uint8* mem) { try { -#ifdef _LINUX +#ifdef OGL_MT_HACK // FIXME: double check which thread call this function // See fifo2 issue below - if (theApp.GetConfig("renderer", 0) / 3 == 4) { - fprintf(stderr, "Disable FIFO1 on opengl\n"); - } +#ifdef OGL_DEBUG + if (theApp.GetConfig("renderer", 0) / 3 == 4) fprintf(stderr, "Disable FIFO1 on opengl\n"); +#endif s_gs->m_wnd.AttachContext(); #endif s_gs->ReadFIFO(mem, 1); -#ifdef _LINUX +#ifdef OGL_MT_HACK s_gs->m_wnd.DetachContext(); #endif } @@ -481,21 +485,18 @@ EXPORT_C GSreadFIFO2(uint8* mem, uint32 size) { try { -#ifdef _LINUX +#ifdef OGL_MT_HACK // FIXME called from EE core thread not MTGS which cause // invalidate data for opengl - if (theApp.GetConfig("renderer", 0) / 3 == 4) { #ifdef OGL_DEBUG - fprintf(stderr, "Disable FIFO2(%d) on opengl\n", size); + if (theApp.GetConfig("renderer", 0) / 3 == 4) fprintf(stderr, "Disable FIFO2(%d) on opengl\n", size); #endif - //return; - } s_gs->m_wnd.AttachContext(); #endif s_gs->ReadFIFO(mem, size); -#ifdef _LINUX +#ifdef OGL_MT_HACK s_gs->m_wnd.DetachContext(); #endif } diff --git a/plugins/GSdx/GSRendererOGL.cpp b/plugins/GSdx/GSRendererOGL.cpp index 9aa25b62f..426e49341 100644 --- a/plugins/GSdx/GSRendererOGL.cpp +++ b/plugins/GSdx/GSRendererOGL.cpp @@ -205,7 +205,8 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour vs_sel.tme = PRIM->TME; vs_sel.fst = PRIM->FST; - vs_sel.logz = dev->HasDepth32() ? 0 : m_logz ? 1 : 0; + //vs_sel.logz = dev->HasDepth32() ? 0 : m_logz ? 1 : 0; + vs_sel.logz = m_logz ? 1 : 0; //OGL vs_sel.rtcopy = !!rtcopy; vs_sel.rtcopy = false; diff --git a/plugins/GSdx/GSState.cpp b/plugins/GSdx/GSState.cpp index 4e8f24086..898b19279 100644 --- a/plugins/GSdx/GSState.cpp +++ b/plugins/GSdx/GSState.cpp @@ -23,6 +23,13 @@ #include "GSState.h" #include "GSdx.h" +#ifdef OGL_MT_HACK + +#include "GSRendererOGL.h" +extern GSRenderer* s_gs; + +#endif + //#define Offset_ST // Fixes Persona3 mini map alignment which is off even in software rendering GSState::GSState() @@ -1252,6 +1259,9 @@ void GSState::GIFRegHandlerTRXDIR(const GIFReg* RESTRICT r) break; case 1: // local -> host m_tr.Init(m_env.TRXPOS.SSAX, m_env.TRXPOS.SSAY); +#ifdef OGL_MT_HACK + s_gs->m_wnd.DetachContext(); +#endif break; case 2: // local -> local Move(); @@ -1756,6 +1766,9 @@ static hash_map s_tags; template void GSState::Transfer(const uint8* mem, uint32 size) { GSPerfMonAutoTimer pmat(&m_perfmon); +#ifdef OGL_MT_HACK + s_gs->m_wnd.AttachContext(); +#endif const uint8* start = mem; diff --git a/plugins/GSdx/GSTextureFXOGL.cpp b/plugins/GSdx/GSTextureFXOGL.cpp index ef354d775..1eb11535a 100644 --- a/plugins/GSdx/GSTextureFXOGL.cpp +++ b/plugins/GSdx/GSTextureFXOGL.cpp @@ -86,6 +86,7 @@ void GSDeviceOGL::SetupVS(VSSelector sel, const VSConstantBuffer* cb) if(i == m_vs.end()) { std::string macro = format("#define VS_BPPZ %d\n", sel.bppz) + + format("#define VS_LOGZ %d\n", sel.logz) + format("#define VS_TME %d\n", sel.tme) + format("#define VS_FST %d\n", sel.fst) + format("#define VS_RTCOPY %d\n", sel.rtcopy); diff --git a/plugins/GSdx/GSWnd.cpp b/plugins/GSdx/GSWnd.cpp index aee95c24b..9adf9f146 100644 --- a/plugins/GSdx/GSWnd.cpp +++ b/plugins/GSdx/GSWnd.cpp @@ -213,7 +213,7 @@ void GSWnd::HideFrame() #else GSWnd::GSWnd() - : m_window(NULL), m_Xwindow(0), m_XDisplay(NULL) + : m_window(NULL), m_Xwindow(0), m_XDisplay(NULL), m_ctx_attached(false) { } @@ -278,16 +278,25 @@ bool GSWnd::CreateContext(int major, int minor) if (!m_context) return false; XSync( m_XDisplay, false); + return true; } void GSWnd::AttachContext() { - glXMakeCurrent(m_XDisplay, m_Xwindow, m_context); + if (!IsContextAttached()) { + fprintf(stderr, "Attach the context\n"); + glXMakeCurrent(m_XDisplay, m_Xwindow, m_context); + m_ctx_attached = true; + } } void GSWnd::DetachContext() { - glXMakeCurrent(m_XDisplay, None, NULL); + if (IsContextAttached()) { + fprintf(stderr, "Detach the context\n"); + glXMakeCurrent(m_XDisplay, None, NULL); + m_ctx_attached = false; + } } void GSWnd::CheckContext() diff --git a/plugins/GSdx/GSWnd.h b/plugins/GSdx/GSWnd.h index 6e2967fad..763d12797 100644 --- a/plugins/GSdx/GSWnd.h +++ b/plugins/GSdx/GSWnd.h @@ -103,6 +103,7 @@ class GSWnd Window m_Xwindow; Display* m_XDisplay; + bool m_ctx_attached; bool m_managed; int m_renderer; GLXContext m_context; @@ -115,6 +116,7 @@ public: bool Attach(void* handle, bool managed = true); void Detach(); bool IsManaged() const {return m_managed;} + bool IsContextAttached() const { return m_ctx_attached; } Display* GetDisplay(); void* GetHandle() {return (void*)m_Xwindow;} diff --git a/plugins/GSdx/linux_replay.cpp b/plugins/GSdx/linux_replay.cpp index fad26cd6e..2c674e776 100644 --- a/plugins/GSdx/linux_replay.cpp +++ b/plugins/GSdx/linux_replay.cpp @@ -34,8 +34,28 @@ void help() int main ( int argc, char *argv[] ) { - if ( argc != 3 ) help(); + if ( argc == 3) { + GSsetSettingsDir(argv[1]); + GSReplay(argv[2], 12); + } else if ( argc == 2) { +#ifdef XDG_STD + std::string home("HOME"); + char * val = getenv( home.c_str() ); + if (val == NULL) { + fprintf(stderr, "Failed to get the home dir\n"); + help(); + } + + std::string ini_dir(val); + ini_dir += "/.config/pcsx2/inis"; + + GSsetSettingsDir(ini_dir.c_str()); + GSReplay(argv[1], 12); +#else + fprintf(stderr, "default ini dir only supported on XDG\n"); + help(); +#endif + } else + help(); - GSsetSettingsDir(argv[1]); - GSReplay(argv[2], 12); } diff --git a/plugins/GSdx/res/tfx.glsl b/plugins/GSdx/res/tfx.glsl index 16d28a945..6dcc2bf93 100644 --- a/plugins/GSdx/res/tfx.glsl +++ b/plugins/GSdx/res/tfx.glsl @@ -87,22 +87,24 @@ void vs_main() // input granularity is 1/16 pixel, anything smaller than that won't step drawing up/left by one pixel // example: 133.0625 (133 + 1/16) should start from line 134, ceil(133.0625 - 0.05) still above 133 - // Greg TEST - //float logz = log2(1+float(z))/32 * 0.999f; - //vec4 p = vec4(i_p, logz, 0) - vec4(0.05f, 0.05f, 0, 0); - vec4 p = vec4(i_p, z, 0) - vec4(0.05f, 0.05f, 0, 0); vec4 final_p = p * VertexScale - VertexOffset; // FIXME // FLIP vertically final_p.y *= -1.0f; + if(VS_LOGZ == 1) + { + final_p.z = log2(1.0f + float(z)) / 32.0f; + } + VSout.p = final_p; gl_Position = final_p; // NOTE I don't know if it is possible to merge POSITION_OUT and gl_Position #if VS_RTCOPY VSout.tp = final_p * vec4(0.5, -0.5, 0, 0) + 0.5; #endif + if(VS_TME != 0) { if(VS_FST != 0) diff --git a/plugins/zzogl-pg/opengl/ZZGl.h b/plugins/zzogl-pg/opengl/ZZGl.h index e33997a04..25e0c9a4f 100644 --- a/plugins/zzogl-pg/opengl/ZZGl.h +++ b/plugins/zzogl-pg/opengl/ZZGl.h @@ -185,7 +185,18 @@ namespace FB static __forceinline void Create() { + assert(buf == 0); glGenFramebuffersEXT(1, &buf); + if (buf == 0) + ZZLog::Error_Log("Failed to create the renderbuffer."); + } + + static __forceinline void Delete() + { + if (buf != 0) { + glDeleteFramebuffers(1, &buf); + buf = 0; + } } static __forceinline void Bind() diff --git a/plugins/zzogl-pg/opengl/ZZoglCreate.cpp b/plugins/zzogl-pg/opengl/ZZoglCreate.cpp index e3b5af23c..5d9ee071d 100644 --- a/plugins/zzogl-pg/opengl/ZZoglCreate.cpp +++ b/plugins/zzogl-pg/opengl/ZZoglCreate.cpp @@ -496,11 +496,6 @@ bool ZZCreate(int _width, int _height) FB::Create(); - if (FB::buf == 0) - { - ZZLog::Error_Log("Failed to create the renderbuffer."); - } - GL_REPORT_ERRORD(); FB::Bind(); @@ -803,7 +798,7 @@ bool ZZCreate(int _width, int _height) } else { - ZZLog::Debug_Log("In final init!"); + ZZLog::Debug_Log("Error In final init!"); return false; } } @@ -834,7 +829,10 @@ void ZZDestroy() } #ifdef GLSL4_API - delete vertex_array; + if (vertex_array != NULL) { + delete vertex_array; + vertex_array = NULL; + } #endif g_nCurVBOIndex = 0; @@ -878,6 +876,8 @@ void ZZDestroy() safe_delete(font_p); + FB::Delete(); + GLWin.ReleaseContext(); mapGLExtensions.clear(); diff --git a/plugins/zzogl-pg/opengl/ZZoglShaders.h b/plugins/zzogl-pg/opengl/ZZoglShaders.h index a74a6480d..d7c4912cb 100644 --- a/plugins/zzogl-pg/opengl/ZZoglShaders.h +++ b/plugins/zzogl-pg/opengl/ZZoglShaders.h @@ -110,7 +110,9 @@ const ZZshParamInfo qZero = {ShName:"", type:ZZ_UNDEFINED, fvalue:{0}, sampler: const ZZshShaderLink sZero = {link: NULL, isFragment: false}; inline bool ZZshActiveParameter(ZZshParameter param) {return (param > -1); } +#ifndef GLSL4_API #define SAFE_RELEASE_PROG(x) { /*don't know what to do*/ } +#endif // --------------------------- @@ -616,7 +618,28 @@ struct VERTEXSHADER bool IsDualContext(ZZshParameter param) { return false;} void set_context(uint new_context) { context = new_context * NOCONTEXT;} + + void release_prog() { + if(program) { + glDeleteProgram(program); + program = 0; + } + } }; +#endif + +#ifdef GLSL4_API +#define SAFE_RELEASE_PROG(x) { \ + if ((x.link) != NULL) { \ + if (x.isFragment) { \ + FRAGMENTSHADER* shader = (FRAGMENTSHADER*)x.link; \ + shader->release_prog(); \ + } else { \ + VERTEXSHADER* shader = (VERTEXSHADER*)x.link; \ + shader->release_prog(); \ + } \ + } \ +} #endif extern VERTEXSHADER pvsBitBlt; diff --git a/plugins/zzogl-pg/opengl/ZZoglShadersGLSL4.cpp b/plugins/zzogl-pg/opengl/ZZoglShadersGLSL4.cpp index 5b9ab9c89..ef2bd92b3 100644 --- a/plugins/zzogl-pg/opengl/ZZoglShadersGLSL4.cpp +++ b/plugins/zzogl-pg/opengl/ZZoglShadersGLSL4.cpp @@ -113,8 +113,6 @@ extern bool s_bWriteDepth; const char* ShaderCallerName = ""; const char* ShaderHandleName = ""; -ZZshProgram CompiledPrograms[MAX_ACTIVE_SHADERS][MAX_ACTIVE_SHADERS] = {{0}}; - // new for GLSL4 GSUniformBufferOGL *constant_buffer; GSUniformBufferOGL *common_buffer; @@ -124,7 +122,7 @@ static bool dirty_common_buffer = true; static bool dirty_vertex_buffer = true; static bool dirty_fragment_buffer = true; -GSVertexBufferStateOGL *vertex_array; +GSVertexBufferStateOGL *vertex_array = NULL; COMMONSHADER g_cs; static GLuint s_pipeline = 0; @@ -227,6 +225,14 @@ void ZZshExitCleaning() { delete vertex_buffer; delete fragment_buffer; + dirty_fragment_buffer = true; + dirty_vertex_buffer = true; + dirty_common_buffer = true; + g_current_ps = 0; + g_current_vs = 0; + for (uint i = 0; i < 11; i++) + g_current_texture_bind[i] = 0; + glDeleteProgramPipelines(1, &s_pipeline); } diff --git a/plugins/zzogl-pg/opengl/ps2hw_gl4.glsl b/plugins/zzogl-pg/opengl/ps2hw_gl4.glsl index 889f48206..f9e36e090 100644 --- a/plugins/zzogl-pg/opengl/ps2hw_gl4.glsl +++ b/plugins/zzogl-pg/opengl/ps2hw_gl4.glsl @@ -334,7 +334,7 @@ float2 ps2addr(float2 coord) half4 tex2DPS_32(float2 tex0) { - return texture(g_sMemory, ps2memcoord(tex0).xy); + return texture(g_sMemory, ps2memcoord(tex0)); } // use when texture is not tiled -- shader 1 @@ -653,7 +653,7 @@ half4 BilinearBitBlt(float2 tex0) } void BitBltPS() { - FragData0 = texture(g_sMemory, ps2memcoord(PSin.tex.xy).xy)*g_fOneColor.xxxy; + FragData0 = texture(g_sMemory, ps2memcoord(PSin.tex.xy))*g_fOneColor.xxxy; } // used when AA @@ -719,7 +719,7 @@ void CRTCInterPS() { // simpler void CRTCInterPS_Nearest() { float finter = texture(g_sInterlace, PSin.z.yy).x * g_fOneColor.z + g_fOneColor.w + g_fc0.w; - half4 c = texture(g_sMemory, ps2memcoord(PSin.tex.xy).xy); + half4 c = texture(g_sMemory, ps2memcoord(PSin.tex.xy)); c.w = (c.w * g_fOneColor.x + g_fOneColor.y)*finter; FragData0 = c; } @@ -733,7 +733,7 @@ void CRTCPS() { // simpler void CRTCPS_Nearest() { - half4 c = texture(g_sMemory, ps2memcoord(PSin.tex.xy).xy); + half4 c = texture(g_sMemory, ps2memcoord(PSin.tex.xy)); c.w = c.w * g_fOneColor.x + g_fOneColor.y; FragData0 = c; } @@ -742,14 +742,14 @@ void CRTC24InterPS() { float finter = texture(g_sInterlace, PSin.z.yy).x * g_fOneColor.z + g_fOneColor.w + g_fc0.w; float2 filtcoord = trunc(PSin.tex.xy) * g_fInvTexDims.xy + g_fInvTexDims.zw; - half4 c = texture(g_sMemory, ps2memcoord(filtcoord).xy); + half4 c = texture(g_sMemory, ps2memcoord(filtcoord)); c.w = (c.w * g_fOneColor.x + g_fOneColor.y)*finter; FragData0 = c; } void CRTC24PS() { float2 filtcoord = trunc(PSin.tex.xy) * g_fInvTexDims.xy + g_fInvTexDims.zw; - half4 c = texture(g_sMemory, ps2memcoord(filtcoord).xy); + half4 c = texture(g_sMemory, ps2memcoord(filtcoord)); c.w = c.w * g_fOneColor.x + g_fOneColor.y; FragData0 = c; } @@ -763,7 +763,7 @@ void ZeroDebugPS() { } void ZeroDebug2PS() { - vec2 xy = ps2memcoord(fract(PSin.tex.xy/PSin.tex.z)).xy * vec2(1/4096.0f, 1/48.0f); + vec2 xy = ps2memcoord(fract(PSin.tex.xy/PSin.tex.z)) * vec2(1/4096.0f, 1/48.0f); FragData0 = vec4(xy.x, xy.y, 0.0, 0.5); }