diff options
| author | Matthew Parlane <parlane@gmail.com> | 2013-08-16 19:17:07 +1200 |
|---|---|---|
| committer | Matthew Parlane <parlane@gmail.com> | 2013-08-16 19:17:07 +1200 |
| commit | 9de7611ff940d24551bc77a5e29b86911e3fa749 (patch) | |
| tree | 7615ec4cfd3aaba63d96ef1cb3cc33fd0efa516a /Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp | |
| parent | 417552b21e30aee3dc2b720d65c2cd757997a33e (diff) | |
| parent | bff2bc1288fa4309e1b2aef1486845ba01311100 (diff) | |
Merge branch 'master' into wii-network
Conflicts:
CMakeLists.txt
Source/Core/Core/Core.vcxproj
Source/Core/DolphinWX/Dolphin.vcxproj
Source/Core/DolphinWX/Dolphin.vcxproj.filters
Source/Dolphin_2010.sln
Source/VSProps/Dolphin.Win32.props
Source/VSProps/Dolphin.x64.props
Diffstat (limited to 'Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp')
| -rw-r--r-- | Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp | 156 |
1 files changed, 136 insertions, 20 deletions
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp index f590208fc3..b381cd2375 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp @@ -29,6 +29,12 @@ GLuint FramebufferManager::m_resolvedDepthTexture; GLuint FramebufferManager::m_xfbFramebuffer; +// reinterpret pixel format +GLuint FramebufferManager::m_pixel_format_vao; +GLuint FramebufferManager::m_pixel_format_vbo; +SHADER FramebufferManager::m_pixel_format_shaders[2]; + + FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int msaaSamples, int msaaCoverageSamples) { m_efbFramebuffer = 0; @@ -59,33 +65,40 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms // Create EFB target. glGenFramebuffers(1, &m_efbFramebuffer); + glActiveTexture(GL_TEXTURE0 + 9); if (m_msaaSamples <= 1) { // EFB targets will be textures in non-MSAA mode. - GLuint glObj[2]; - glGenTextures(2, glObj); + GLuint glObj[3]; + glGenTextures(3, glObj); m_efbColor = glObj[0]; m_efbDepth = glObj[1]; + m_resolvedColorTexture = glObj[2]; // needed for pixel format convertion - glBindTexture(GL_TEXTURE_RECTANGLE, m_efbColor); - glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture(getFbType(), m_efbColor); + glTexParameteri(getFbType(), GL_TEXTURE_MAX_LEVEL, 0); + glTexImage2D(getFbType(), 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_RECTANGLE, m_efbDepth); - glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); - - glBindTexture(GL_TEXTURE_RECTANGLE, 0); + glBindTexture(getFbType(), m_efbDepth); + glTexParameteri(getFbType(), GL_TEXTURE_MAX_LEVEL, 0); + glTexImage2D(getFbType(), 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); + + glBindTexture(getFbType(), m_resolvedColorTexture); + glTexParameteri(getFbType(), GL_TEXTURE_MAX_LEVEL, 0); + glTexImage2D(getFbType(), 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); // Bind target textures to the EFB framebuffer. glBindFramebuffer(GL_FRAMEBUFFER, m_efbFramebuffer); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, m_efbColor, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_RECTANGLE, m_efbDepth, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, getFbType(), m_efbColor, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, getFbType(), m_efbDepth, 0); GL_REPORT_FBO_ERROR(); } +#ifndef USE_GLES3 else { // EFB targets will be renderbuffers in MSAA mode (required by OpenGL). @@ -130,20 +143,20 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms m_resolvedColorTexture = glObj[0]; m_resolvedDepthTexture = glObj[1]; - glBindTexture(GL_TEXTURE_RECTANGLE, m_resolvedColorTexture); - glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - - glBindTexture(GL_TEXTURE_RECTANGLE, m_resolvedDepthTexture); - glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); + glBindTexture(getFbType(), m_resolvedColorTexture); + glTexParameteri(getFbType(), GL_TEXTURE_MAX_LEVEL, 0); + glTexImage2D(getFbType(), 0, GL_RGBA8, m_targetWidth, m_targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_RECTANGLE, 0); + glBindTexture(getFbType(), m_resolvedDepthTexture); + glTexParameteri(getFbType(), GL_TEXTURE_MAX_LEVEL, 0); + glTexImage2D(getFbType(), 0, GL_DEPTH_COMPONENT24, m_targetWidth, m_targetHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); // Bind resolved textures to resolved framebuffer. glBindFramebuffer(GL_FRAMEBUFFER, m_resolvedFramebuffer); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, m_resolvedColorTexture, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_RECTANGLE, m_resolvedDepthTexture, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, getFbType(), m_resolvedColorTexture, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, getFbType(), m_resolvedDepthTexture, 0); GL_REPORT_FBO_ERROR(); @@ -151,7 +164,7 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms glBindFramebuffer(GL_FRAMEBUFFER, m_efbFramebuffer); } - +#endif // Create XFB framebuffer; targets will be created elsewhere. glGenFramebuffers(1, &m_xfbFramebuffer); @@ -160,8 +173,62 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms glViewport(0, 0, m_targetWidth, m_targetHeight); glScissor(0, 0, m_targetWidth, m_targetHeight); glClearColor(0.f, 0.f, 0.f, 1.f); - glClearDepth(1.0); + glClearDepthf(1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + // reinterpret pixel format + glGenBuffers(1, &m_pixel_format_vbo); + glGenVertexArrays(1, &m_pixel_format_vao); + glBindVertexArray(m_pixel_format_vao); + glBindBuffer(GL_ARRAY_BUFFER, m_pixel_format_vbo); + glEnableVertexAttribArray(SHADER_POSITION_ATTRIB); + glVertexAttribPointer(SHADER_POSITION_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*2, NULL); + + float vertices[] = { + -1.0, -1.0, + 1.0, -1.0, + -1.0, 1.0, + 1.0, 1.0, + }; + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + char vs[] = + "ATTRIN vec2 rawpos;\n" + "void main(void) {\n" + " gl_Position = vec4(rawpos,0,1);\n" + "}\n"; + + char ps_rgba6_to_rgb8[] = + "uniform sampler2DRect samp9;\n" + "COLOROUT(ocol0)\n" + "void main()\n" + "{\n" + " ivec4 src6 = ivec4(round(texture2DRect(samp9, gl_FragCoord.xy) * 63.f));\n" + " ivec4 dst8;\n" + " dst8.r = (src6.r << 2) | (src6.g >> 4);\n" + " dst8.g = ((src6.g & 0xF) << 4) | (src6.b >> 2);\n" + " dst8.b = ((src6.b & 0x3) << 6) | src6.a;\n" + " dst8.a = 255;\n" + " ocol0 = float4(dst8) / 255.f;\n" + "}"; + + char ps_rgb8_to_rgba6[] = + "uniform sampler2DRect samp9;\n" + "COLOROUT(ocol0)\n" + "void main()\n" + "{\n" + " ivec4 src8 = ivec4(round(texture2DRect(samp9, gl_FragCoord.xy) * 255.f));\n" + " ivec4 dst6;\n" + " dst6.r = src8.r >> 2;\n" + " dst6.g = ((src8.r & 0x3) << 4) | (src8.g >> 4);\n" + " dst6.b = ((src8.g & 0xF) << 2) | (src8.b >> 6);\n" + " dst6.a = src8.b & 0x3F;\n" + " ocol0 = float4(dst6) / 63.f;\n" + "}"; + + ProgramShaderCache::CompileShader(m_pixel_format_shaders[0], vs, ps_rgb8_to_rgba6); + ProgramShaderCache::CompileShader(m_pixel_format_shaders[1], vs, ps_rgba6_to_rgb8); + } FramebufferManager::~FramebufferManager() @@ -193,6 +260,12 @@ FramebufferManager::~FramebufferManager() glDeleteRenderbuffers(2, glObj); m_efbColor = 0; m_efbDepth = 0; + + // reinterpret pixel format + glDeleteVertexArrays(1, &m_pixel_format_vao); + glDeleteBuffers(1, &m_pixel_format_vbo); + m_pixel_format_shaders[0].Destroy(); + m_pixel_format_shaders[1].Destroy(); } GLuint FramebufferManager::GetEFBColorTexture(const EFBRectangle& sourceRc) @@ -284,6 +357,49 @@ GLuint FramebufferManager::ResolveAndGetDepthTarget(const EFBRectangle &source_r return GetEFBDepthTexture(source_rect); } +void FramebufferManager::ReinterpretPixelData(unsigned int convtype) +{ + g_renderer->ResetAPIState(); + + GLuint src_texture = 0; + + if(m_msaaSamples > 1) + { + // MSAA mode, so resolve first + glBindFramebuffer(GL_READ_FRAMEBUFFER, m_efbFramebuffer); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_resolvedFramebuffer); + glBlitFramebuffer( + 0, 0, m_targetWidth, m_targetHeight, + 0, 0, m_targetWidth, m_targetHeight, + GL_COLOR_BUFFER_BIT, GL_NEAREST + ); + + // Return to EFB. + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_efbFramebuffer); + + src_texture = m_resolvedColorTexture; + } + else + { + // non-MSAA mode, so switch textures + src_texture = m_efbColor; + m_efbColor = m_resolvedColorTexture; + m_resolvedColorTexture = src_texture; + + // also switch them on fbo + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, getFbType(), m_efbColor, 0); + } + glViewport(0,0, m_targetWidth, m_targetHeight); + glActiveTexture(GL_TEXTURE0 + 9); + glBindTexture(getFbType(), src_texture); + + m_pixel_format_shaders[convtype ? 1 : 0].Bind(); + glBindVertexArray(m_pixel_format_vao); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + g_renderer->RestoreAPIState(); +} + XFBSource::~XFBSource() { glDeleteRenderbuffers(1, &renderbuf); |
