Implements PP shader system using attribute workaround.
This is pretty much a step backwards in our code. We used to use attributes in our PP shader system a long time ago but we changed it to attributeless for code simplicity and cleanliness. This reimplements the attribute code path as an optional path to take in the case your system doesn't work with attributeless rendering. In this case the only shipping drivers that we can know for sure supports attributeless rendering is the Nexus 5's v95 driver that is included in the Android 5.0 image. I hadn't planned on implementing a work around to get post processing working in these cases, but due to us force enabling the PP shader system at all times it sort of went up on the priority list. We can't be having a supported platform black screening at all times can we?
This commit is contained in:
parent
9da7e6ae79
commit
181ff6750e
|
@ -11,12 +11,22 @@
|
|||
#include "VideoBackends/OGL/PostProcessing.h"
|
||||
#include "VideoBackends/OGL/ProgramShaderCache.h"
|
||||
|
||||
#include "VideoCommon/DriverDetails.h"
|
||||
#include "VideoCommon/VideoCommon.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
namespace OGL
|
||||
{
|
||||
|
||||
static char s_vertex_workaround_shader[] =
|
||||
"in vec4 rawpos;\n"
|
||||
"out vec2 uv0;\n"
|
||||
"uniform vec4 src_rect;\n"
|
||||
"void main(void) {\n"
|
||||
" gl_Position = vec4(rawpos.xy, 0.0, 1.0);\n"
|
||||
" uv0 = rawpos.zw * src_rect.zw + src_rect.xy;\n"
|
||||
"}\n";
|
||||
|
||||
static char s_vertex_shader[] =
|
||||
"out vec2 uv0;\n"
|
||||
"uniform vec4 src_rect;\n"
|
||||
|
@ -29,12 +39,26 @@ static char s_vertex_shader[] =
|
|||
OpenGLPostProcessing::OpenGLPostProcessing()
|
||||
{
|
||||
CreateHeader();
|
||||
|
||||
m_attribute_workaround = DriverDetails::HasBug(DriverDetails::BUG_BROKENATTRIBUTELESS);
|
||||
if (m_attribute_workaround)
|
||||
{
|
||||
glGenBuffers(1, &m_attribute_vbo);
|
||||
glGenVertexArrays(1, &m_attribute_vao);
|
||||
}
|
||||
|
||||
m_initialized = false;
|
||||
}
|
||||
|
||||
OpenGLPostProcessing::~OpenGLPostProcessing()
|
||||
{
|
||||
m_shader.Destroy();
|
||||
|
||||
if (m_attribute_workaround)
|
||||
{
|
||||
glDeleteBuffers(1, &m_attribute_vbo);
|
||||
glDeleteVertexArrays(1, &m_attribute_vao);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLPostProcessing::BlitFromTexture(TargetRectangle src, TargetRectangle dst,
|
||||
|
@ -46,6 +70,9 @@ void OpenGLPostProcessing::BlitFromTexture(TargetRectangle src, TargetRectangle
|
|||
|
||||
glViewport(dst.left, dst.bottom, dst.GetWidth(), dst.GetHeight());
|
||||
|
||||
if (m_attribute_workaround)
|
||||
glBindVertexArray(m_attribute_vao);
|
||||
|
||||
m_shader.Bind();
|
||||
|
||||
glUniform4f(m_uniform_resolution, (float)src_width, (float)src_height, 1.0f / (float)src_width, 1.0f / (float)src_height);
|
||||
|
@ -148,13 +175,18 @@ void OpenGLPostProcessing::ApplyShader()
|
|||
|
||||
code = LoadShaderOptions(code);
|
||||
|
||||
const char* vertex_shader = s_vertex_shader;
|
||||
|
||||
if (m_attribute_workaround)
|
||||
vertex_shader = s_vertex_workaround_shader;
|
||||
|
||||
// and compile it
|
||||
if (!ProgramShaderCache::CompileShader(m_shader, s_vertex_shader, code.c_str()))
|
||||
if (!ProgramShaderCache::CompileShader(m_shader, vertex_shader, code.c_str()))
|
||||
{
|
||||
ERROR_LOG(VIDEO, "Failed to compile post-processing shader %s", m_config.GetShader().c_str());
|
||||
|
||||
code = LoadShaderOptions(default_shader);
|
||||
ProgramShaderCache::CompileShader(m_shader, s_vertex_shader, code.c_str());
|
||||
ProgramShaderCache::CompileShader(m_shader, vertex_shader, code.c_str());
|
||||
}
|
||||
|
||||
// read uniform locations
|
||||
|
@ -162,6 +194,23 @@ void OpenGLPostProcessing::ApplyShader()
|
|||
m_uniform_time = glGetUniformLocation(m_shader.glprogid, "time");
|
||||
m_uniform_src_rect = glGetUniformLocation(m_shader.glprogid, "src_rect");
|
||||
|
||||
if (m_attribute_workaround)
|
||||
{
|
||||
GLfloat vertices[] = {
|
||||
-1.f, -1.f, 0.f, 0.f,
|
||||
1.f, -1.f, 1.f, 0.f,
|
||||
-1.f, 1.f, 0.f, 1.f,
|
||||
1.f, 1.f, 1.f, 1.f,
|
||||
};
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_attribute_vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
|
||||
glBindVertexArray(m_attribute_vao);
|
||||
glEnableVertexAttribArray(SHADER_POSITION_ATTRIB);
|
||||
glVertexAttribPointer(SHADER_POSITION_ATTRIB, 4, GL_FLOAT, 0, 0, nullptr);
|
||||
}
|
||||
|
||||
for (const auto& it : m_config.GetOptions())
|
||||
{
|
||||
std::string glsl_name = "option_" + it.first;
|
||||
|
|
|
@ -34,6 +34,11 @@ private:
|
|||
GLuint m_uniform_time;
|
||||
std::string m_glsl_header;
|
||||
|
||||
// These are only used when working around Qualcomm's broken attributeless rendering
|
||||
GLuint m_attribute_vao;
|
||||
GLuint m_attribute_vbo;
|
||||
bool m_attribute_workaround = false;
|
||||
|
||||
std::unordered_map<std::string, GLuint> m_uniform_bindings;
|
||||
|
||||
void CreateHeader();
|
||||
|
|
Loading…
Reference in New Issue