diff options
| author | skidau <skidau@gmail.com> | 2013-03-27 13:19:23 +1100 |
|---|---|---|
| committer | skidau <skidau@gmail.com> | 2013-03-27 13:19:23 +1100 |
| commit | 7784fa4c67cc8d2545f45694d83805e7e89cd583 (patch) | |
| tree | 7724133aabe971ec417d1dea0977a525bb8debfb /Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | |
| parent | d33c19b0cd2bae982c8d35e86a9d3551f9e5c72f (diff) | |
| parent | 5cea0d9defeaa23e7af94adf7615a44fb2c9c173 (diff) | |
Merge branch 'master' into wii-network
# By Ryan Houdek (185) and others
# Via degasus (12) and others
* master: (625 commits)
Revert "Don't open/close file for every file operation." as it was crashing PokePark in Windows builds.
Array overrun fixed in VertexShaderCache for the DX11 plugin.
Fixed DSPTool build.
Windows build fix
Go back to assuming every HID device is a wiimote on Windows. Fixed issue 6117. Unfixed issue 6031.
VideoSoftware: Improve fog range adjustment by using less magic and more comments.
revert RasterFont for VideoSoftware
ogl: fix virtual xfb
Windows build fix from web interface...
Adjusted the audio loop criteria, using >= on the Wii and == on GC. This fixes the audio static that occurred in Wii games after hours of play.
Forced the exception check only for ARAM DMA transfers. Removed the Eternal Darkness boot hack and replaced it with an exception check.
VideoSoftware: Implement fog range adjustment, fixing issue 6147.
implement 4xSSAA for OGL
move ogl-only settings into backend
Fix description of disable fog, and move it to enhancements tab.
Reverted rd76ca5783743 as it was made obsolete by r1d550f4496e4.
Removed the tracking of the FIFO Writes as it was made obsolete by r1d550f4496e4.
Forced the external exception check to occur sooner by changing the downcount.
Mark the Direct3D9 backend deprecated.
Prefer D3D11 and OpenGL over D3D9 by default.
...
Conflicts:
CMakeLists.txt
Source/Core/Common/Common.vcxproj.filters
Source/Core/Common/Src/CommonPaths.h
Source/Core/Core/Core.vcxproj.filters
Source/Core/Core/Src/Core.cpp
Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp
Source/VSProps/Dolphin.Win32.props
Source/VSProps/Dolphin.x64.props
Diffstat (limited to 'Source/Plugins/Plugin_VideoOGL/Src/Render.cpp')
| -rw-r--r-- | Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 756 |
1 files changed, 387 insertions, 369 deletions
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 3ff8b834ce..97015db667 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -24,6 +24,9 @@ #include <cstdio> #include "GLUtil.h" +#if defined(HAVE_WX) && HAVE_WX +#include "WxUtils.h" +#endif #include "FileUtil.h" @@ -43,9 +46,8 @@ #include "RasterFont.h" #include "VertexShaderGen.h" #include "DLCache.h" -#include "PixelShaderCache.h" #include "PixelShaderManager.h" -#include "VertexShaderCache.h" +#include "ProgramShaderCache.h" #include "VertexShaderManager.h" #include "VertexLoaderManager.h" #include "VertexLoader.h" @@ -63,6 +65,9 @@ #include "BPFunctions.h" #include "FPSCounter.h" #include "ConfigManager.h" +#include "VertexManager.h" +#include "SamplerCache.h" +#include "StreamBuffer.h" #include "main.h" // Local #ifdef _WIN32 @@ -94,31 +99,41 @@ typedef struct } ScrStrct; #endif -#if defined HAVE_CG && HAVE_CG -CGcontext g_cgcontext; -CGprofile g_cgvProf; -CGprofile g_cgfProf; -#endif int OSDInternalW, OSDInternalH; namespace OGL { +enum MultisampleMode { + MULTISAMPLE_OFF, + MULTISAMPLE_2X, + MULTISAMPLE_4X, + MULTISAMPLE_8X, + MULTISAMPLE_CSAA_8X, + MULTISAMPLE_CSAA_8XQ, + MULTISAMPLE_CSAA_16X, + MULTISAMPLE_CSAA_16XQ, + MULTISAMPLE_SSAA_4X, +}; + + +VideoConfig g_ogl_config; + // Declarations and definitions // ---------------------------- -int s_fps=0; - +static int s_fps = 0; +static GLuint s_ShowEFBCopyRegions_VBO = 0; +static GLuint s_ShowEFBCopyRegions_VAO = 0; +static SHADER s_ShowEFBCopyRegions; -RasterFont* s_pfont = NULL; +static RasterFont* s_pfont = NULL; // 1 for no MSAA. Use s_MSAASamples > 1 to check for MSAA. static int s_MSAASamples = 1; static int s_MSAACoverageSamples = 0; static int s_LastMultisampleMode = 0; -bool s_bHaveFramebufferBlit = false; // export to FramebufferManager.cpp -static bool s_bHaveCoverageMSAA = false; static u32 s_blendMode; #if defined(HAVE_WX) && HAVE_WX @@ -126,69 +141,82 @@ static std::thread scrshotThread; #endif // EFB cache related -const u32 EFB_CACHE_RECT_SIZE = 64; // Cache 64x64 blocks. -const u32 EFB_CACHE_WIDTH = (EFB_WIDTH + EFB_CACHE_RECT_SIZE - 1) / EFB_CACHE_RECT_SIZE; // round up -const u32 EFB_CACHE_HEIGHT = (EFB_HEIGHT + EFB_CACHE_RECT_SIZE - 1) / EFB_CACHE_RECT_SIZE; +static const u32 EFB_CACHE_RECT_SIZE = 64; // Cache 64x64 blocks. +static const u32 EFB_CACHE_WIDTH = (EFB_WIDTH + EFB_CACHE_RECT_SIZE - 1) / EFB_CACHE_RECT_SIZE; // round up +static const u32 EFB_CACHE_HEIGHT = (EFB_HEIGHT + EFB_CACHE_RECT_SIZE - 1) / EFB_CACHE_RECT_SIZE; static bool s_efbCacheValid[2][EFB_CACHE_WIDTH * EFB_CACHE_HEIGHT]; static std::vector<u32> s_efbCache[2][EFB_CACHE_WIDTH * EFB_CACHE_HEIGHT]; // 2 for PEEK_Z and PEEK_COLOR - -#if defined HAVE_CG && HAVE_CG -void HandleCgError(CGcontext ctx, CGerror err, void* appdata) -{ - DEBUG_LOG(VIDEO, "Cg error: %s", cgGetErrorString(err)); - const char* listing = cgGetLastListing(g_cgcontext); - if (listing != NULL) - DEBUG_LOG(VIDEO, " last listing: %s", listing); -} -#endif - int GetNumMSAASamples(int MSAAMode) { - // required for MSAA - if (!s_bHaveFramebufferBlit) - return 1; - + int samples; switch (MSAAMode) { case MULTISAMPLE_OFF: - return 1; + samples = 1; + break; case MULTISAMPLE_2X: - return 2; + samples = 2; + break; case MULTISAMPLE_4X: case MULTISAMPLE_CSAA_8X: case MULTISAMPLE_CSAA_16X: - return 4; + case MULTISAMPLE_SSAA_4X: + samples = 4; + break; case MULTISAMPLE_8X: case MULTISAMPLE_CSAA_8XQ: case MULTISAMPLE_CSAA_16XQ: - return 8; + samples = 8; + break; default: - return 1; + samples = 1; } + + if(samples <= g_ogl_config.max_samples) return samples; + + ERROR_LOG(VIDEO, "MSAA Bug: %d samples selected, but only %d supported by gpu.", samples, g_ogl_config.max_samples); + return g_ogl_config.max_samples; } int GetNumMSAACoverageSamples(int MSAAMode) { - if (!s_bHaveCoverageMSAA) - return 0; - + int samples; switch (g_ActiveConfig.iMultisampleMode) { case MULTISAMPLE_CSAA_8X: case MULTISAMPLE_CSAA_8XQ: - return 8; + samples = 8; + break; case MULTISAMPLE_CSAA_16X: case MULTISAMPLE_CSAA_16XQ: - return 16; + samples = 16; + break; default: - return 0; + samples = 0; + } + if(g_ogl_config.bSupportCoverageMSAA || samples == 0) return samples; + + ERROR_LOG(VIDEO, "MSAA Bug: CSAA selected, but not supported by gpu."); + return 0; +} + +void ApplySSAASettings() { + if(g_ActiveConfig.iMultisampleMode == MULTISAMPLE_SSAA_4X) { + if(g_ogl_config.bSupportSampleShading) { + glEnable(GL_SAMPLE_SHADING_ARB); + glMinSampleShadingARB(s_MSAASamples); + } else { + ERROR_LOG(VIDEO, "MSAA Bug: SSAA selected, but not supported by gpu."); + } + } else if(g_ogl_config.bSupportSampleShading) { + glDisable(GL_SAMPLE_SHADING_ARB); } } @@ -199,39 +227,14 @@ Renderer::Renderer() OSDInternalH = 0; s_fps=0; + s_ShowEFBCopyRegions_VBO = 0; s_blendMode = 0; - InitFPSCounter(); -#if defined HAVE_CG && HAVE_CG - g_cgcontext = cgCreateContext(); - cgGetError(); - cgSetErrorHandler(HandleCgError, NULL); -#endif - - // Look for required extensions. - const char *ptoken = (const char*)glGetString(GL_EXTENSIONS); - if (!ptoken) - { - PanicAlert("Your OpenGL Driver seems to be not working.\n" - "Please make sure your drivers are up-to-date and\n" - "that your video hardware is OpenGL 2.x compatible."); - return; // TODO: fail - } - - INFO_LOG(VIDEO, "Supported OpenGL Extensions:"); - INFO_LOG(VIDEO, "%s", ptoken); // write to the log file - INFO_LOG(VIDEO, "\n"); - - OSD::AddMessage(StringFromFormat("Video Info: %s, %s, %s", - glGetString(GL_VENDOR), - glGetString(GL_RENDERER), - glGetString(GL_VERSION)).c_str(), 5000); - bool bSuccess = true; GLint numvertexattribs = 0; glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &numvertexattribs); - if (numvertexattribs < 11) + if (numvertexattribs < 16) { ERROR_LOG(VIDEO, "GPU: OGL ERROR: Number of attributes %d not enough.\n" "GPU: Does your video card support OpenGL 2.x?", @@ -240,42 +243,113 @@ Renderer::Renderer() } // Init extension support. +#ifdef __APPLE__ + glewExperimental = 1; +#endif if (glewInit() != GLEW_OK) { ERROR_LOG(VIDEO, "glewInit() failed! Does your video card support OpenGL 2.x?"); return; // TODO: fail } - if (!GLEW_EXT_framebuffer_object) + if (!GLEW_EXT_secondary_color) { - ERROR_LOG(VIDEO, "GPU: ERROR: Need GL_EXT_framebufer_object for multiple render targets.\n" + ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_EXT_secondary_color.\n" "GPU: Does your video card support OpenGL 2.x?"); bSuccess = false; } - if (!GLEW_EXT_secondary_color) + if (!GLEW_ARB_framebuffer_object) { - ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_EXT_secondary_color.\n" - "GPU: Does your video card support OpenGL 2.x?"); + ERROR_LOG(VIDEO, "GPU: ERROR: Need GL_ARB_framebufer_object for multiple render targets.\n" + "GPU: Does your video card support OpenGL 3.0?"); bSuccess = false; } - s_bHaveFramebufferBlit = strstr(ptoken, "GL_EXT_framebuffer_blit") != NULL; - s_bHaveCoverageMSAA = strstr(ptoken, "GL_NV_framebuffer_multisample_coverage") != NULL; + if (!GLEW_ARB_vertex_array_object) + { + ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_ARB_vertex_array_object.\n" + "GPU: Does your video card support OpenGL 3.0?"); + bSuccess = false; + } + + if (!GLEW_ARB_map_buffer_range) + { + ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_ARB_map_buffer_range.\n" + "GPU: Does your video card support OpenGL 3.0?"); + bSuccess = false; + } - s_LastMultisampleMode = g_ActiveConfig.iMultisampleMode; - s_MSAASamples = GetNumMSAASamples(s_LastMultisampleMode); - s_MSAACoverageSamples = GetNumMSAACoverageSamples(s_LastMultisampleMode); + if (!GLEW_ARB_sampler_objects && bSuccess) + { + ERROR_LOG(VIDEO, "GPU: OGL ERROR: Need GL_ARB_sampler_objects." + "GPU: Does your video card support OpenGL 3.2?" + "Please report this issue, then there will be a workaround"); + bSuccess = false; + } if (!bSuccess) return; // TODO: fail + + g_Config.backend_info.bSupportsDualSourceBlend = GLEW_ARB_blend_func_extended; + g_Config.backend_info.bSupportsGLSLUBO = GLEW_ARB_uniform_buffer_object; + + g_ogl_config.bSupportsGLSLCache = GLEW_ARB_get_program_binary; + g_ogl_config.bSupportsGLPinnedMemory = GLEW_AMD_pinned_memory; + g_ogl_config.bSupportsGLSync = GLEW_ARB_sync; + g_ogl_config.bSupportsGLBaseVertex = GLEW_ARB_draw_elements_base_vertex; + g_ogl_config.bSupportCoverageMSAA = GLEW_NV_framebuffer_multisample_coverage; + g_ogl_config.bSupportSampleShading = GLEW_ARB_sample_shading; + + g_ogl_config.gl_vendor = (const char*)glGetString(GL_VENDOR); + g_ogl_config.gl_renderer = (const char*)glGetString(GL_RENDERER); + g_ogl_config.gl_version = (const char*)glGetString(GL_VERSION); + + glGetIntegerv(GL_MAX_SAMPLES, &g_ogl_config.max_samples); + + if(g_Config.backend_info.bSupportsGLSLUBO && ( + // hd3000 get corruption, hd4000 also and a big slowdown + !strcmp(g_ogl_config.gl_vendor, "Intel Open Source Technology Center") && ( + !strcmp(g_ogl_config.gl_version, "3.0 Mesa 9.0.0") || + !strcmp(g_ogl_config.gl_version, "3.0 Mesa 9.0.1") || + !strcmp(g_ogl_config.gl_version, "3.0 Mesa 9.0.2") || + !strcmp(g_ogl_config.gl_version, "3.0 Mesa 9.0.3") || + !strcmp(g_ogl_config.gl_version, "3.0 Mesa 9.1.0") || + !strcmp(g_ogl_config.gl_version, "3.0 Mesa 9.1.1") ) + )) { + g_Config.backend_info.bSupportsGLSLUBO = false; + ERROR_LOG(VIDEO, "buggy driver detected. Disable UBO"); + } + + UpdateActiveConfig(); + OSD::AddMessage(StringFromFormat("Video Info: %s, %s, %s", + g_ogl_config.gl_vendor, + g_ogl_config.gl_renderer, + g_ogl_config.gl_version).c_str(), 5000); + + OSD::AddMessage(StringFromFormat("Missing Extensions: %s%s%s%s%s%s%s%s", + g_ActiveConfig.backend_info.bSupportsDualSourceBlend ? "" : "DualSourceBlend ", + g_ActiveConfig.backend_info.bSupportsGLSLUBO ? "" : "UniformBuffer ", + g_ogl_config.bSupportsGLPinnedMemory ? "" : "PinnedMemory ", + g_ogl_config.bSupportsGLSLCache ? "" : "ShaderCache ", + g_ogl_config.bSupportsGLBaseVertex ? "" : "BaseVertex ", + g_ogl_config.bSupportsGLSync ? "" : "Sync ", + g_ogl_config.bSupportCoverageMSAA ? "" : "CSAA ", + g_ogl_config.bSupportSampleShading ? "" : "SSAA " + ).c_str(), 5000); + + s_LastMultisampleMode = g_ActiveConfig.iMultisampleMode; + s_MSAASamples = GetNumMSAASamples(s_LastMultisampleMode); + s_MSAACoverageSamples = GetNumMSAACoverageSamples(s_LastMultisampleMode); + ApplySSAASettings(); + // Decide frambuffer size s_backbuffer_width = (int)GLInterface->GetBackBufferWidth(); s_backbuffer_height = (int)GLInterface->GetBackBufferHeight(); // Handle VSync on/off - int swapInterval = g_ActiveConfig.bVSync ? 1 : 0; + int swapInterval = g_ActiveConfig.IsVSync() ? 1 : 0; GLInterface->SwapInterval(swapInterval); // check the max texture width and height @@ -288,9 +362,6 @@ Renderer::Renderer() if (GL_REPORT_ERROR() != GL_NO_ERROR) bSuccess = false; - if (glDrawBuffers == NULL && !GLEW_ARB_draw_buffers) - glDrawBuffers = glDrawBuffersARB; - if (!GLEW_ARB_texture_non_power_of_two) WARN_LOG(VIDEO, "ARB_texture_non_power_of_two not supported."); @@ -314,90 +385,17 @@ Renderer::Renderer() g_framebuffer_manager = new FramebufferManager(s_target_width, s_target_height, s_MSAASamples, s_MSAACoverageSamples); - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - if (GL_REPORT_ERROR() != GL_NO_ERROR) bSuccess = false; - - s_pfont = new RasterFont(); - -#if defined HAVE_CG && HAVE_CG - // load the effect, find the best profiles (if any) - if (cgGLIsProfileSupported(CG_PROFILE_ARBVP1) != CG_TRUE) - { - ERROR_LOG(VIDEO, "arbvp1 not supported"); - return; // TODO: fail - } - - if (cgGLIsProfileSupported(CG_PROFILE_ARBFP1) != CG_TRUE) - { - ERROR_LOG(VIDEO, "arbfp1 not supported"); - return; // TODO: fail - } - - g_cgvProf = cgGLGetLatestProfile(CG_GL_VERTEX); - g_cgfProf = cgGLGetLatestProfile(CG_GL_FRAGMENT); - if (strstr((const char*)glGetString(GL_VENDOR), "Humper") == NULL) - { -#if CG_VERSION_NUM == 2100 - // A bug was introduced in Cg2.1's handling of very large profile option values - // so this will not work on ATI. ATI returns MAXINT = 2147483647 (0x7fffffff) - // which is correct in OpenGL but Cg fails to handle it properly. As a result - // -1 is used by Cg resulting (signedness incorrect) and compilation fails. - if (strstr((const char*)glGetString(GL_VENDOR), "ATI") == NULL) -#endif - { - cgGLSetOptimalOptions(g_cgvProf); - cgGLSetOptimalOptions(g_cgfProf); - } - } -#endif // HAVE_CG - - int nenvvertparams, nenvfragparams, naddrregisters[2]; - glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, - GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, - (GLint *)&nenvvertparams); - glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, - GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, - (GLint *)&nenvfragparams); - glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, - GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB, - (GLint *)&naddrregisters[0]); - glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, - GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB, - (GLint *)&naddrregisters[1]); - DEBUG_LOG(VIDEO, "Max program env parameters: vert=%d, frag=%d", - nenvvertparams, nenvfragparams); - DEBUG_LOG(VIDEO, "Max program address register parameters: vert=%d, frag=%d", - naddrregisters[0], naddrregisters[1]); - - if (nenvvertparams < 238) - ERROR_LOG(VIDEO, "Not enough vertex shader environment constants!!"); - -#if defined HAVE_CG && HAVE_CG - INFO_LOG(VIDEO, "Max buffer sizes: %d %d", - cgGetProgramBufferMaxSize(g_cgvProf), - cgGetProgramBufferMaxSize(g_cgfProf)); -#ifndef _DEBUG - cgGLSetDebugMode(GL_FALSE); -#endif -#endif - + glStencilFunc(GL_ALWAYS, 0, 0); glBlendFunc(GL_ONE, GL_ONE); glViewport(0, 0, GetTargetWidth(), GetTargetHeight()); // Reset The Current Viewport - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glShadeModel(GL_SMOOTH); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); glDepthFunc(GL_LEQUAL); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // 4-byte pixel alignment @@ -406,39 +404,14 @@ Renderer::Renderer() glEnable(GL_SCISSOR_TEST); glScissor(0, 0, GetTargetWidth(), GetTargetHeight()); - glBlendColorEXT(0, 0, 0, 0.5f); + glBlendColor(0, 0, 0, 0.5f); glClearDepth(1.0f); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - // legacy multitexturing: select texture channel only. - glActiveTexture(GL_TEXTURE0); - glClientActiveTexture(GL_TEXTURE0); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - UpdateActiveConfig(); - - //return GL_REPORT_ERROR() == GL_NO_ERROR && bSuccess; - return; } Renderer::~Renderer() { - g_Config.bRunning = false; - UpdateActiveConfig(); - delete s_pfont; - s_pfont = 0; - -#if defined HAVE_CG && HAVE_CG - if (g_cgcontext) - { - cgDestroyContext(g_cgcontext); - g_cgcontext = 0; - } -#endif #if defined(HAVE_WX) && HAVE_WX if (scrshotThread.joinable()) @@ -448,6 +421,49 @@ Renderer::~Renderer() delete g_framebuffer_manager; } +void Renderer::Shutdown() +{ + g_Config.bRunning = false; + UpdateActiveConfig(); + + glDeleteBuffers(1, &s_ShowEFBCopyRegions_VBO); + glDeleteVertexArrays(1, &s_ShowEFBCopyRegions_VAO); + s_ShowEFBCopyRegions_VBO = 0; + + delete s_pfont; + s_pfont = 0; + s_ShowEFBCopyRegions.Destroy(); +} + +void Renderer::Init() +{ + s_pfont = new RasterFont(); + + ProgramShaderCache::CompileShader(s_ShowEFBCopyRegions, + "in vec2 rawpos;\n" + "in vec3 color0;\n" + "out vec4 c;\n" + "void main(void) {\n" + " gl_Position = vec4(rawpos,0,1);\n" + " c = vec4(color0, 1.0);\n" + "}\n", + "in vec4 c;\n" + "out vec4 ocol0;\n" + "void main(void) {\n" + " ocol0 = c;\n" + "}\n"); + + // creating buffers + glGenBuffers(1, &s_ShowEFBCopyRegions_VBO); + glGenVertexArrays(1, &s_ShowEFBCopyRegions_VAO); + glBindBuffer(GL_ARRAY_BUFFER, s_ShowEFBCopyRegions_VBO); + glBindVertexArray( s_ShowEFBCopyRegions_VAO ); + glEnableVertexAttribArray(SHADER_POSITION_ATTRIB); + glVertexAttribPointer(SHADER_POSITION_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*5, NULL); + glEnableVertexAttribArray(SHADER_COLOR0_ATTRIB); + glVertexAttribPointer(SHADER_COLOR0_ATTRIB, 3, GL_FLOAT, 0, sizeof(GLfloat)*5, (GLfloat*)NULL+2); +} + // Create On-Screen-Messages void Renderer::DrawDebugInfo() { @@ -469,16 +485,18 @@ void Renderer::DrawDebugInfo() if (g_ActiveConfig.bShowEFBCopyRegions) { - // Store Line Size - GLfloat lSize; - glGetFloatv(GL_LINE_WIDTH, &lSize); - // Set Line Size glLineWidth(3.0f); - glBegin(GL_LINES); + // 2*Coords + 3*Color + glBindBuffer(GL_ARRAY_BUFFER, s_ShowEFBCopyRegions_VBO); + glBufferData(GL_ARRAY_BUFFER, stats.efb_regions.size() * sizeof(GLfloat) * (2+3)*2*6, NULL, GL_STREAM_DRAW); + GLfloat *Vertices = (GLfloat*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); // Draw EFB copy regions rectangles + int a = 0; + GLfloat color[3] = {0.0f, 1.0f, 1.0f}; + for (std::vector<EFBRectangle>::const_iterator it = stats.efb_regions.begin(); it != stats.efb_regions.end(); ++it) { @@ -489,25 +507,97 @@ void Renderer::DrawDebugInfo() GLfloat x2 = (GLfloat) -1.0f + ((GLfloat)it->right / halfWidth); GLfloat y2 = (GLfloat) 1.0f - ((GLfloat)it->bottom / halfHeight); - // Draw shadow of rect - glColor3f(0.0f, 0.0f, 0.0f); - glVertex2f(x, y - 0.01); glVertex2f(x2, y - 0.01); - glVertex2f(x, y2 - 0.01); glVertex2f(x2, y2 - 0.01); - glVertex2f(x + 0.005, y); glVertex2f(x + 0.005, y2); - glVertex2f(x2 + 0.005, y); glVertex2f(x2 + 0.005, y2); - - // Draw rect - glColor3f(0.0f, 1.0f, 1.0f); - glVertex2f(x, y); glVertex2f(x2, y); - glVertex2f(x, y2); glVertex2f(x2, y2); - glVertex2f(x, y); glVertex2f(x, y2); - glVertex2f(x2, y); glVertex2f(x2, y2); + Vertices[a++] = x; + Vertices[a++] = y; + Vertices[a++] = color[0]; + Vertices[a++] = color[1]; + Vertices[a++] = color[2]; + + Vertices[a++] = x2; + Vertices[a++] = y; + Vertices[a++] = color[0]; + Vertices[a++] = color[1]; + Vertices[a++] = color[2]; + + + Vertices[a++] = x2; + Vertices[a++] = y; + Vertices[a++] = color[0]; + Vertices[a++] = color[1]; + Vertices[a++] = color[2]; + + Vertices[a++] = x2; + Vertices[a++] = y2; + Vertices[a++] = color[0]; + Vertices[a++] = color[1]; + Vertices[a++] = color[2]; + + + Vertices[a++] = x2; + Vertices[a++] = y2; + Vertices[a++] = color[0]; + Vertices[a++] = color[1]; + Vertices[a++] = color[2]; + + Vertices[a++] = x; + Vertices[a++] = y2; + Vertices[a++] = color[0]; + Vertices[a++] = color[1]; + Vertices[a++] = color[2]; + + + Vertices[a++] = x; + Vertices[a++] = y2; + Vertices[a++] = color[0]; + Vertices[a++] = color[1]; + Vertices[a++] = color[2]; + + Vertices[a++] = x; + Vertices[a++] = y; + Vertices[a++] = color[0]; + Vertices[a++] = color[1]; + Vertices[a++] = color[2]; + + + Vertices[a++] = x; + Vertices[a++] = y; + Vertices[a++] = color[0]; + Vertices[a++] = color[1]; + Vertices[a++] = color[2]; + + Vertices[a++] = x2; + Vertices[a++] = y2; + Vertices[a++] = color[0]; + Vertices[a++] = color[1]; + Vertices[a++] = color[2]; + + + Vertices[a++] = x2; + Vertices[a++] = y; + Vertices[a++] = color[0]; + Vertices[a++] = color[1]; + Vertices[a++] = color[2]; + + Vertices[a++] = x; + Vertices[a++] = y2; + Vertices[a++] = color[0]; + Vertices[a++] = color[1]; + Vertices[a++] = color[2]; + + // TO DO: build something nicer here + GLfloat temp = color[0]; + color[0] = color[1]; + color[1] = color[2]; + color[2] = temp; } - - glEnd(); + glUnmapBuffer(GL_ARRAY_BUFFER); + + s_ShowEFBCopyRegions.Bind(); + glBindVertexArray( s_ShowEFBCopyRegions_VAO ); + glDrawArrays(GL_LINES, 0, stats.efb_regions.size() * 2*6); // Restore Line Size - glLineWidth(lSize); + SetLineWidth(); // Clear stored regions stats.efb_regions.clear(); @@ -532,20 +622,12 @@ void Renderer::RenderText(const char *text, int left, int top, u32 color) const int nBackbufferWidth = (int)GLInterface->GetBackBufferWidth(); const int nBackbufferHeight = (int)GLInterface->GetBackBufferHeight(); - glColor4f(((color>>16) & 0xff)/255.0f, ((color>> 8) & 0xff)/255.0f, - ((color>> 0) & 0xff)/255.0f, ((color>>24) & 0xFF)/255.0f); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - s_pfont->printMultilineText(text, left * 2.0f / (float)nBackbufferWidth - 1, 1 - top * 2.0f / (float)nBackbufferHeight, - 0, nBackbufferWidth, nBackbufferHeight); + 0, nBackbufferWidth, nBackbufferHeight, color); GL_REPORT_ERRORD(); - - glDisable(GL_BLEND); } TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc) @@ -671,7 +753,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) { // Resolve our rectangle. FramebufferManager::GetEFBDepthTexture(efbPixelRc); - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, FramebufferManager::GetResolvedFramebuffer()); + glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferManager::GetResolvedFramebuffer()); } u32* depthMap = new u32[targetPixelRcWidth * targetPixelRcHeight]; @@ -720,7 +802,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) { // Resolve our rectangle. FramebufferManager::GetEFBColorTexture(efbPixelRc); - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, FramebufferManager::GetResolvedFramebuffer()); + glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferManager::GetResolvedFramebuffer()); } u32* colorMap = new u32[targetPixelRcWidth * targetPixelRcHeight]; @@ -858,7 +940,11 @@ void Renderer::SetBlendMode(bool forceUpdate) { // Our render target always uses an alpha channel, so we need to override the blend functions to assume a destination alpha of 1 if the render target isn't supposed to have an alpha channel // Example: D3DBLEND_DESTALPHA needs to be D3DBLEND_ONE since the result without an alpha channel is assumed to always be 1. - bool target_has_alpha = bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; + bool target_has_alpha = bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; + + bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && target_has_alpha; + bool useDualSource = useDstAlpha && g_ActiveConfig.backend_info.bSupportsDualSourceBlend; + const GLenum glSrcFactors[8] = { GL_ZERO, @@ -884,11 +970,13 @@ void Renderer::SetBlendMode(bool forceUpdate) // blend mode bit mask // 0 - blend enable + // 1 - dst alpha enabled // 2 - reverse subtract enable (else add) // 3-5 - srcRGB function // 6-8 - dstRGB function - u32 newval = bpmem.blendmode.subtract << 2; + u32 newval = useDualSource << 1; + newval |= bpmem.blendmode.subtract << 2; if (bpmem.blendmode.subtract) newval |= 0x0049; // enable blending src 1 dst 1 @@ -901,33 +989,23 @@ void Renderer::SetBlendMode(bool forceUpdate) u32 changes = forceUpdate ? 0xFFFFFFFF : newval ^ s_blendMode; -#ifdef USE_DUAL_SOURCE_BLEND - bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate - && bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; - bool useDualSource = useDstAlpha && GLEW_ARB_blend_func_extended; -#endif - if (changes & 1) // blend enable change (newval & 1) ? glEnable(GL_BLEND) : glDisable(GL_BLEND); if (changes & 4) { -#ifdef USE_DUAL_SOURCE_BLEND // subtract enable change GLenum equation = newval & 4 ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD; GLenum equationAlpha = useDualSource ? GL_FUNC_ADD : equation; + glBlendEquationSeparate(equation, equationAlpha); -#else - glBlendEquation(newval & 4 ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD); -#endif } - if (changes & 0x1F8) + if (changes & 0x1FA) { GLenum srcFactor = glSrcFactors[(newval >> 3) & 7]; GLenum dstFactor = glDestFactors[(newval >> 6) & 7]; -#ifdef USE_DUAL_SOURCE_BLEND GLenum srcFactorAlpha = srcFactor; GLenum dstFactorAlpha = dstFactor; if (useDualSource) @@ -945,31 +1023,31 @@ void Renderer::SetBlendMode(bool forceUpdate) else if (dstFactor == GL_ONE_MINUS_SRC_ALPHA) dstFactor = GL_ONE_MINUS_SRC1_ALPHA; } - + // blend RGB change glBlendFuncSeparate(srcFactor, dstFactor, srcFactorAlpha, dstFactorAlpha); -#else - glBlendFunc(srcFactor, dstFactor); -#endif } s_blendMode = newval; } +void DumpFrame(const std::vector<u8>& data, int w, int h) +{ +#if defined(HAVE_LIBAV) || defined(_WIN32) + if (g_ActiveConfig.bDumpFrames && !data.empty()) + { + AVIDump::AddFrame(&data[0], w, h); + } +#endif +} + // This function has the final picture. We adjust the aspect ratio here. void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma) { static int w = 0, h = 0; if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) || !fbWidth || !fbHeight) { - if (g_ActiveConfig.bDumpFrames && frame_data) - { -#ifdef _WIN32 - AVIDump::AddFrame(frame_data); -#elif defined HAVE_LIBAV - AVIDump::AddFrame((u8*)frame_data, w, h); -#endif - } + DumpFrame(frame_data, w, h); Core::Callback_VideoCopiedToXFB(false); return; } @@ -979,20 +1057,14 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); if (g_ActiveConfig.VirtualXFBEnabled() && (!xfbSourceList || xfbCount == 0)) { - if (g_ActiveConfig.bDumpFrames && frame_data) - { -#ifdef _WIN32 - AVIDump::AddFrame(frame_data); -#elif defined HAVE_LIBAV - AVIDump::AddFrame((u8*)frame_data, w, h); -#endif - } + DumpFrame(frame_data, w, h); Core::Callback_VideoCopiedToXFB(false); return; } ResetAPIState(); + PostProcessing::Update(s_backbuffer_width, s_backbuffer_height); UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height); TargetRectangle flipped_trc = GetTargetRectangle(); @@ -1000,38 +1072,20 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons int tmp = flipped_trc.top; flipped_trc.top = flipped_trc.bottom; flipped_trc.bottom = tmp; - - // Textured triangles are necessary because of post-processing shaders - - // Disable all other stages - for (int i = 1; i < 8; ++i) - OGL::TextureCache::DisableStage(i); - - // Update GLViewPort - glViewport(flipped_trc.left, flipped_trc.bottom, flipped_trc.GetWidth(), flipped_trc.GetHeight()); - + GL_REPORT_ERRORD(); // Copy the framebuffer to screen. - // Texture map s_xfbTexture onto the main buffer - glActiveTexture(GL_TEXTURE0); - glEnable(GL_TEXTURE_RECTANGLE_ARB); - // Use linear filtering. - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - - // We must call ApplyShader here even if no post proc is selected - it takes - // care of disabling it in that case. It returns false in case of no post processing. - bool applyShader = PostProcessing::ApplyShader(); - const XFBSourceBase* xfbSource = NULL; if(g_ActiveConfig.bUseXFB) { + // Render to the real/postprocessing buffer now. + PostProcessing::BindTargetFramebuffer(); + // draw each xfb source - // Render to the real buffer now. - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the window backbuffer + glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferManager::GetXFBFramebuffer()); for (u32 i = 0; i < xfbCount; ++i) { @@ -1041,10 +1095,10 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons if (g_ActiveConfig.bUseRealXFB) { - drawRc.top = 1; - drawRc.bottom = -1; - drawRc.left = -1; - drawRc.right = 1; + drawRc.top = flipped_trc.top; + drawRc.bottom = flipped_trc.bottom; + drawRc.left = flipped_trc.left; + drawRc.right = flipped_trc.right; } else { @@ -1052,12 +1106,12 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons int xfbHeight = xfbSource->srcHeight; int xfbWidth = xfbSource->srcWidth; int hOffset = ((s32)xfbSource->srcAddr - (s32)xfbAddr) / ((s32)fbWidth * 2); - - drawRc.top = 1.0f - (2.0f * (hOffset) / (float)fbHeight); - drawRc.bottom = 1.0f - (2.0f * (hOffset + xfbHeight) / (float)fbHeight); - drawRc.left = -(xfbWidth / (float)fbWidth); - drawRc.right = (xfbWidth / (float)fbWidth); - + + drawRc.top = flipped_trc.top - hOffset * flipped_trc.GetHeight() / fbHeight; + drawRc.bottom = flipped_trc.top - (hOffset + xfbHeight) * flipped_trc.GetHeight() / fbHeight; + drawRc.left = flipped_trc.left + (flipped_trc.GetWidth() - xfbWidth * flipped_trc.GetWidth() / fbWidth)/2; + drawRc.right = flipped_trc.left + (flipped_trc.GetWidth() + xfbWidth * flipped_trc.GetWidth() / fbWidth)/2; + // The following code disables auto stretch. Kept for reference. // scale draw area for a 1 to 1 pixel mapping with the draw target //float vScale = (float)fbHeight / (float)flipped_trc.GetHeight(); @@ -1077,62 +1131,30 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons sourceRc.bottom = xfbSource->sourceRc.bottom; xfbSource->Draw(sourceRc, drawRc, 0, 0); - - // We must call ApplyShader here even if no post proc is selected. - // It takes care of disabling it in that case. It returns false in - // case of no post processing. - if (applyShader) - PixelShaderCache::DisableShader(); } } else { TargetRectangle targetRc = ConvertEFBRectangle(rc); - GLuint read_texture = FramebufferManager::ResolveAndGetRenderTarget(rc); - // Render to the real buffer now. - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the window backbuffer - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, read_texture); - if (applyShader) - { - glBegin(GL_QUADS); - glTexCoord2f(targetRc.left, targetRc.bottom); - glMultiTexCoord2fARB(GL_TEXTURE1, 0, 0); - glVertex2f(-1, -1); - - glTexCoord2f(targetRc.left, targetRc.top); - glMultiTexCoord2fARB(GL_TEXTURE1, 0, 1); - glVertex2f(-1, 1); - - glTexCoord2f(targetRc.right, targetRc.top); - glMultiTexCoord2fARB(GL_TEXTURE1, 1, 1); - glVertex2f( 1, 1); - - glTexCoord2f(targetRc.right, targetRc.bottom); - glMultiTexCoord2fARB(GL_TEXTURE1, 1, 0); - glVertex2f( 1, -1); - glEnd(); - PixelShaderCache::DisableShader(); - } - else - { - glBegin(GL_QUADS); - glTexCoord2f(targetRc.left, targetRc.bottom); - glVertex2f(-1, -1); - - glTexCoord2f(targetRc.left, targetRc.top); - glVertex2f(-1, 1); - - glTexCoord2f(targetRc.right, targetRc.top); - glVertex2f( 1, 1); - - glTexCoord2f(targetRc.right, targetRc.bottom); - glVertex2f( 1, -1); - glEnd(); - } + + // for msaa mode, we must resolve the efb content to non-msaa + FramebufferManager::ResolveAndGetRenderTarget(rc); + + // Render to the real/postprocessing buffer now. (resolve have changed this in msaa mode) + PostProcessing::BindTargetFramebuffer(); + + // always the non-msaa fbo + GLuint fb = s_MSAASamples>1?FramebufferManager::GetResolvedFramebuffer():FramebufferManager::GetEFBFramebuffer(); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, fb); + glBlitFramebuffer(targetRc.left, targetRc.bottom, targetRc.right, targetRc.top, + flipped_trc.left, flipped_trc.bottom, flipped_trc.right, flipped_trc.top, + GL_COLOR_BUFFER_BIT, GL_LINEAR); } + + PostProcessing::BlitToScreen(); - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); - OGL::TextureCache::DisableStage(0); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); // Save screenshot if (s_bScreenshot) @@ -1149,16 +1171,15 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons if (g_ActiveConfig.bDumpFrames) { std::lock_guard<std::mutex> lk(s_criticalScreenshot); - if (!frame_data || w != flipped_trc.GetWidth() || + if (frame_data.empty() || w != flipped_trc.GetWidth() || h != flipped_trc.GetHeight()) { - if (frame_data) delete[] frame_data; w = flipped_trc.GetWidth(); h = flipped_trc.GetHeight(); - frame_data = new char[3 * w * h]; + frame_data.resize(3 * w * h); } glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadPixels(flipped_trc.left, flipped_trc.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, frame_data); + glReadPixels(flipped_trc.left, flipped_trc.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, &frame_data[0]); if (GL_REPORT_ERROR() == GL_NO_ERROR && w > 0 && h > 0) { if (!bLastFrameDumped) @@ -1179,12 +1200,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons } if (bAVIDumping) { - #ifdef _WIN32 - AVIDump::AddFrame(frame_data); - #else - FlipImageData((u8*)frame_data, w, h); - AVIDump::AddFrame((u8*)frame_data, w, h); + #ifndef _WIN32 + FlipImageData(&frame_data[0], w, h); #endif + + AVIDump::AddFrame(&frame_data[0], w, h); } bLastFrameDumped = true; @@ -1196,12 +1216,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons { if (bLastFrameDumped && bAVIDumping) { - if (frame_data) - { - delete[] frame_data; - frame_data = NULL; - w = h = 0; - } + std::vector<u8>().swap(frame_data); + w = h = 0; AVIDump::Stop(); bAVIDumping = false; OSD::AddMessage("Stop dumping frames", 2000); @@ -1215,9 +1231,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons std::string movie_file_name; w = GetTargetRectangle().GetWidth(); h = GetTargetRectangle().GetHeight(); - frame_data = new char[3 * w * h]; + frame_data.resize(3 * w * h); glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadPixels(GetTargetRectangle().left, GetTargetRectangle().bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, frame_data); + glReadPixels(GetTargetRectangle().left, GetTargetRectangle().bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, &frame_data[0]); if (GL_REPORT_ERROR() == GL_NO_ERROR) { if (!bLastFrameDumped) @@ -1228,21 +1244,17 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons OSD::AddMessage("Error opening framedump.raw for writing.", 2000); else { - char msg [255]; - sprintf(msg, "Dumping Frames to \"%s\" (%dx%d RGB24)", movie_file_name.c_str(), w, h); - OSD::AddMessage(msg, 2000); + OSD::AddMessage(StringFromFormat("Dumping Frames to \"%s\" (%dx%d RGB24)", movie_file_name.c_str(), w, h).c_str(), 2000); } } if (pFrameDump) { - FlipImageData((u8*)frame_data, w, h); - pFrameDump.WriteBytes(frame_data, w * 3 * h); + FlipImageData(&frame_data[0], w, h); + pFrameDump.WriteBytes(&frame_data[0], w * 3 * h); pFrameDump.Flush(); } bLastFrameDumped = true; } - - delete[] frame_data; } else { @@ -1289,11 +1301,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons s_LastMultisampleMode = g_ActiveConfig.iMultisampleMode; s_MSAASamples = GetNumMSAASamples(s_LastMultisampleMode); s_MSAACoverageSamples = GetNumMSAACoverageSamples(s_LastMultisampleMode); - + ApplySSAASettings(); + delete g_framebuffer_manager; g_framebuffer_manager = new FramebufferManager(s_target_width, s_target_height, s_MSAASamples, s_MSAACoverageSamples); - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); } } @@ -1301,18 +1313,16 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons s_fps = UpdateFPSCounter(); // --------------------------------------------------------------------- GL_REPORT_ERRORD(); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - DrawDebugText(); DrawDebugInfo(); + DrawDebugText(); GL_REPORT_ERRORD(); - // Get the status of the Blend mode - GLboolean blend_enabled = glIsEnabled(GL_BLEND); - glDisable(GL_BLEND); OSD::DrawMessages(); - if (blend_enabled) - glEnable(GL_BLEND); GL_REPORT_ERRORD(); // Copy the rendered frame to the real window @@ -1329,6 +1339,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons GL_REPORT_ERRORD(); + GLInterface->SwapInterval(g_ActiveConfig.IsVSync() ? 1 : 0); + // Clean out old stuff from caches. It's not worth it to clean out the shader caches. DLCache::ProgressiveCleanup(); TextureCache::Cleanup(); @@ -1371,8 +1383,6 @@ void Renderer::ResetAPIState() { // Gets us to a reasonably sane state where it's possible to do things like // image copies with textured quads, etc. - VertexShaderCache::DisableShader(); - PixelShaderCache::DisableShader(); glDisable(GL_SCISSOR_TEST); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); @@ -1393,9 +1403,12 @@ void Renderer::RestoreAPIState() VertexShaderManager::SetViewportChanged(); glPolygonMode(GL_FRONT_AND_BACK, g_ActiveConfig.bWireFrame ? GL_LINE : GL_FILL); - - VertexShaderCache::SetCurrentShader(0); - PixelShaderCache::SetCurrentShader(0); + + VertexManager *vm = (OGL::VertexManager*)g_vertex_manager; + glBindBuffer(GL_ARRAY_BUFFER, vm->m_vertex_buffers); + vm->m_last_vao = 0; + + TextureCache::SetStage(); } void Renderer::SetGenerationMode() @@ -1433,6 +1446,7 @@ void Renderer::SetDepthMode() else { // if the test is disabled write is disabled too + // TODO: When PE performance metrics are being emulated via occlusion queries, we should (probably?) enable depth test with depth function ALWAYS here glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); } @@ -1492,7 +1506,11 @@ void Renderer::SetLineWidth() void Renderer::SetSamplerState(int stage, int texindex) { - // TODO + auto const& tex = bpmem.tex[texindex]; + auto const& tm0 = tex.texMode0[stage]; + auto const& tm1 = tex.texMode1[stage]; + + g_sampler_cache->SetSamplerState((texindex * 4) + stage, tm0, tm1); } void Renderer::SetInterlacingMode() @@ -1552,7 +1570,7 @@ void TakeScreenshot(ScrStrct* threadStruct) // Save the screenshot and finally kill the wxImage object // This is really expensive when saving to PNG, but not at all when using BMP - threadStruct->img->SaveFile(wxString::FromAscii(threadStruct->filename.c_str()), + threadStruct->img->SaveFile(StrToWxStr(threadStruct->filename), wxBITMAP_TYPE_PNG); threadStruct->img->Destroy(); |
