diff options
| author | Stenzek <stenzek@gmail.com> | 2019-04-15 23:38:10 +1000 |
|---|---|---|
| committer | Stenzek <stenzek@gmail.com> | 2019-04-16 00:39:43 +1000 |
| commit | 616ad378b7e129645714858ebd0e541471704487 (patch) | |
| tree | 39f3b0d19670b07de65a122d6152533ec5c9424d /Source/Core/VideoBackends/OGL/OGLPipeline.cpp | |
| parent | 5cef09e383c7f9c3bf006407d06f68d18b2db438 (diff) | |
OGL: Support returning pipeline cache data
Diffstat (limited to 'Source/Core/VideoBackends/OGL/OGLPipeline.cpp')
| -rw-r--r-- | Source/Core/VideoBackends/OGL/OGLPipeline.cpp | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/Source/Core/VideoBackends/OGL/OGLPipeline.cpp b/Source/Core/VideoBackends/OGL/OGLPipeline.cpp index bd439898db..00ae8aa873 100644 --- a/Source/Core/VideoBackends/OGL/OGLPipeline.cpp +++ b/Source/Core/VideoBackends/OGL/OGLPipeline.cpp @@ -9,6 +9,7 @@ #include "VideoBackends/OGL/ProgramShaderCache.h" #include "VideoBackends/OGL/Render.h" #include "VideoBackends/OGL/VertexManager.h" +#include "VideoCommon/VideoConfig.h" namespace OGL { @@ -31,7 +32,7 @@ static GLenum MapToGLPrimitive(PrimitiveType primitive_type) OGLPipeline::OGLPipeline(const GLVertexFormat* vertex_format, const RasterizationState& rasterization_state, const DepthState& depth_state, const BlendingState& blending_state, - const PipelineProgram* program, GLuint gl_primitive) + PipelineProgram* program, GLuint gl_primitive) : m_vertex_format(vertex_format), m_rasterization_state(rasterization_state), m_depth_state(depth_state), m_blending_state(blending_state), m_program(program), m_gl_primitive(gl_primitive) @@ -44,13 +45,47 @@ OGLPipeline::~OGLPipeline() ProgramShaderCache::ReleasePipelineProgram(m_program); } -std::unique_ptr<OGLPipeline> OGLPipeline::Create(const AbstractPipelineConfig& config) +AbstractPipeline::CacheData OGLPipeline::GetCacheData() const { - const PipelineProgram* program = ProgramShaderCache::GetPipelineProgram( + // More than one pipeline can share the same shaders. To avoid bloating the cache with multiple + // copies of the same program combination, we set a flag on the program object so that it can't + // be retrieved again. When booting, the pipeline cache is loaded in-order, so the additional + // pipelines which use the program combination will re-use the already-created object. + if (!g_ActiveConfig.backend_info.bSupportsPipelineCacheData || m_program->binary_retrieved) + return {}; + + GLint program_size = 0; + glGetProgramiv(m_program->shader.glprogid, GL_PROGRAM_BINARY_LENGTH, &program_size); + if (program_size == 0) + return {}; + + // Clear any existing error. + glGetError(); + + // We pack the format at the start of the buffer. + CacheData data(program_size + sizeof(u32)); + GLsizei data_size = 0; + GLenum program_format = 0; + glGetProgramBinary(m_program->shader.glprogid, program_size, &data_size, &program_format, + &data[sizeof(u32)]); + if (glGetError() != GL_NO_ERROR || data_size == 0) + return {}; + + u32 program_format_u32 = static_cast<u32>(program_format); + std::memcpy(&data[0], &program_format_u32, sizeof(u32)); + data.resize(data_size + sizeof(u32)); + m_program->binary_retrieved = true; + return data; +} + +std::unique_ptr<OGLPipeline> OGLPipeline::Create(const AbstractPipelineConfig& config, + const void* cache_data, size_t cache_data_size) +{ + PipelineProgram* program = ProgramShaderCache::GetPipelineProgram( static_cast<const GLVertexFormat*>(config.vertex_format), static_cast<const OGLShader*>(config.vertex_shader), static_cast<const OGLShader*>(config.geometry_shader), - static_cast<const OGLShader*>(config.pixel_shader)); + static_cast<const OGLShader*>(config.pixel_shader), cache_data, cache_data_size); if (!program) return nullptr; |
