diff --git a/Source/Core/VideoBackends/OGL/PostProcessing.cpp b/Source/Core/VideoBackends/OGL/PostProcessing.cpp index 434a1d94a3..2681fcd345 100644 --- a/Source/Core/VideoBackends/OGL/PostProcessing.cpp +++ b/Source/Core/VideoBackends/OGL/PostProcessing.cpp @@ -36,7 +36,7 @@ static char s_vertex_shader[] = " uv0 = rawpos * src_rect.zw + src_rect.xy;\n" "}\n"; -OpenGLPostProcessing::OpenGLPostProcessing() +OpenGLPostProcessing::OpenGLPostProcessing() : m_initialized(false) { CreateHeader(); @@ -46,8 +46,6 @@ OpenGLPostProcessing::OpenGLPostProcessing() glGenBuffers(1, &m_attribute_vbo); glGenVertexArrays(1, &m_attribute_vao); } - - m_initialized = false; } OpenGLPostProcessing::~OpenGLPostProcessing() @@ -62,7 +60,7 @@ OpenGLPostProcessing::~OpenGLPostProcessing() } void OpenGLPostProcessing::BlitFromTexture(TargetRectangle src, TargetRectangle dst, - int src_texture, int src_width, int src_height) + int src_texture, int src_width, int src_height, int layer) { ApplyShader(); @@ -79,6 +77,7 @@ void OpenGLPostProcessing::BlitFromTexture(TargetRectangle src, TargetRectangle glUniform4f(m_uniform_src_rect, src.left / (float) src_width, src.bottom / (float) src_height, src.GetWidth() / (float) src_width, src.GetHeight() / (float) src_height); glUniform1ui(m_uniform_time, (GLuint)m_timer.GetTimeElapsed()); + glUniform1i(m_uniform_layer, layer); if (m_config.IsDirty()) { @@ -151,9 +150,9 @@ void OpenGLPostProcessing::BlitFromTexture(TargetRectangle src, TargetRectangle } glActiveTexture(GL_TEXTURE0+9); - glBindTexture(GL_TEXTURE_2D, src_texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glBindTexture(GL_TEXTURE_2D_ARRAY, src_texture); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } @@ -167,7 +166,7 @@ void OpenGLPostProcessing::ApplyShader() m_uniform_bindings.clear(); // load shader from disk - std::string default_shader = "void main() { SetOutput(Sample()); }"; + std::string default_shader = "void main() { SetOutput(Sample()); }\n"; std::string code = ""; if (g_ActiveConfig.sPostProcessingShader != "") code = m_config.LoadShader(); @@ -195,6 +194,7 @@ void OpenGLPostProcessing::ApplyShader() m_uniform_resolution = glGetUniformLocation(m_shader.glprogid, "resolution"); m_uniform_time = glGetUniformLocation(m_shader.glprogid, "time"); m_uniform_src_rect = glGetUniformLocation(m_shader.glprogid, "src_rect"); + m_uniform_layer = glGetUniformLocation(m_shader.glprogid, "layer"); if (m_attribute_workaround) { @@ -228,7 +228,7 @@ void OpenGLPostProcessing::CreateHeader() // Shouldn't be accessed directly by the PP shader // Texture sampler "SAMPLER_BINDING(8) uniform sampler2D samp8;\n" - "SAMPLER_BINDING(9) uniform sampler2D samp9;\n" + "SAMPLER_BINDING(9) uniform sampler2DArray samp9;\n" // Output variable "out float4 ocol0;\n" @@ -238,16 +238,18 @@ void OpenGLPostProcessing::CreateHeader() "uniform float4 resolution;\n" // Time "uniform uint time;\n" + // Layer + "uniform int layer;\n" // Interfacing functions "float4 Sample()\n" "{\n" - "\treturn texture(samp9, uv0);\n" + "\treturn texture(samp9, float3(uv0, layer));\n" "}\n" "float4 SampleLocation(float2 location)\n" "{\n" - "\treturn texture(samp9, location);\n" + "\treturn texture(samp9, float3(location, layer));\n" "}\n" "#define SampleOffset(offset) textureOffset(samp9, uv0, offset)\n" diff --git a/Source/Core/VideoBackends/OGL/PostProcessing.h b/Source/Core/VideoBackends/OGL/PostProcessing.h index 9f4f6ba5bc..4c67eca839 100644 --- a/Source/Core/VideoBackends/OGL/PostProcessing.h +++ b/Source/Core/VideoBackends/OGL/PostProcessing.h @@ -23,7 +23,7 @@ public: ~OpenGLPostProcessing(); void BlitFromTexture(TargetRectangle src, TargetRectangle dst, - int src_texture, int src_width, int src_height) override; + int src_texture, int src_width, int src_height, int layer) override; void ApplyShader() override; private: @@ -32,6 +32,7 @@ private: GLuint m_uniform_resolution; GLuint m_uniform_src_rect; GLuint m_uniform_time; + GLuint m_uniform_layer; std::string m_glsl_header; // These are only used when working around Qualcomm's broken attributeless rendering diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index 99066e24ea..b6c288bf2c 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -1505,7 +1505,20 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co sourceRc.right -= fbStride - fbWidth; - m_post_processor->BlitFromTexture(sourceRc, drawRc, xfbSource->texture, xfbSource->texWidth, xfbSource->texHeight); + if (g_ActiveConfig.bStereo) + { + TargetRectangle leftRc = drawRc, rightRc = drawRc; + int width = drawRc.right - drawRc.left; + leftRc.right -= width / 2; + rightRc.left += width / 2; + + m_post_processor->BlitFromTexture(sourceRc, leftRc, xfbSource->texture, xfbSource->texWidth, xfbSource->texHeight, 0); + m_post_processor->BlitFromTexture(sourceRc, rightRc, xfbSource->texture, xfbSource->texWidth, xfbSource->texHeight, 1); + } + else + { + m_post_processor->BlitFromTexture(sourceRc, drawRc, xfbSource->texture, xfbSource->texWidth, xfbSource->texHeight, 1); + } } } else @@ -1515,7 +1528,20 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co // for msaa mode, we must resolve the efb content to non-msaa GLuint tex = FramebufferManager::ResolveAndGetRenderTarget(rc); - m_post_processor->BlitFromTexture(targetRc, flipped_trc, tex, s_target_width, s_target_height); + if (g_ActiveConfig.bStereo) + { + TargetRectangle leftRc = flipped_trc, rightRc = flipped_trc; + int width = flipped_trc.right - flipped_trc.left; + leftRc.right -= width / 2; + rightRc.left += width / 2; + + m_post_processor->BlitFromTexture(targetRc, leftRc, tex, s_target_width, s_target_height, 0); + m_post_processor->BlitFromTexture(targetRc, rightRc, tex, s_target_width, s_target_height, 1); + } + else + { + m_post_processor->BlitFromTexture(targetRc, flipped_trc, tex, s_target_width, s_target_height); + } } glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); diff --git a/Source/Core/VideoCommon/PostProcessing.h b/Source/Core/VideoCommon/PostProcessing.h index 68ab47cff6..7c4f942214 100644 --- a/Source/Core/VideoCommon/PostProcessing.h +++ b/Source/Core/VideoCommon/PostProcessing.h @@ -91,7 +91,7 @@ public: // Should be implemented by the backends for backend specific code virtual void BlitFromTexture(TargetRectangle src, TargetRectangle dst, - int src_texture, int src_width, int src_height) = 0; + int src_texture, int src_width, int src_height, int layer = 0) = 0; virtual void ApplyShader() = 0; protected: