From 4a55ba30672175174523beaad38044a5ebbaf1d2 Mon Sep 17 00:00:00 2001 From: DH Date: Wed, 14 Oct 2015 03:15:23 +0300 Subject: [PATCH] OpenGL renderer improvements Flush program cache at thread exit Use cached locations --- rpcs3/Emu/RSX/Common/ProgramStateCache.h | 9 ++++++ rpcs3/Emu/RSX/GL/GLGSRender.cpp | 39 ++++++++++++------------ rpcs3/Emu/RSX/GL/GLGSRender.h | 3 +- 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/ProgramStateCache.h b/rpcs3/Emu/RSX/Common/ProgramStateCache.h index 3c1f85bae3..46513fb626 100644 --- a/rpcs3/Emu/RSX/Common/ProgramStateCache.h +++ b/rpcs3/Emu/RSX/Common/ProgramStateCache.h @@ -290,11 +290,20 @@ private: public: ProgramStateCache() : m_currentShaderId(0) {} ~ProgramStateCache() + { + clear(); + } + + void clear() { for (auto pair : m_cachePSO) BackendTraits::DeleteProgram(pair.second); + m_cachePSO.clear(); + for (auto pair : m_cacheFS) free(pair.first); + + m_cacheFS.clear(); } typename BackendTraits::PipelineData *getGraphicPipelineState( diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index b2e956936d..3276ce7e3a 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -840,10 +840,10 @@ void GLGSRender::end() return; } - LOG_NOTICE(Log::RSX, "draw()"); + //LOG_NOTICE(Log::RSX, "draw()"); draw_fbo.bind(); - m_program.use(); + m_program->use(); //setup textures for (int i = 0; i < rsx::limits::textures_count; ++i) @@ -852,10 +852,10 @@ void GLGSRender::end() continue; int location; - if (m_program.uniforms.has_location("tex" + std::to_string(i), &location)) + if (m_program->uniforms.has_location("tex" + std::to_string(i), &location)) { __glcheck m_gl_textures[i].init(textures[i]); - __glcheck m_program.uniforms.texture(location, i, gl::texture_view(gl::texture::target::texture2D, m_gl_textures[i].id())); + __glcheck m_program->uniforms.texture(location, i, gl::texture_view(gl::texture::target::texture2D, m_gl_textures[i].id())); } } @@ -997,11 +997,11 @@ void GLGSRender::end() "in_tc4", "in_tc5", "in_tc6", "in_tc7" }; - int location = m_program.attribs.location(reg_table[index]); + int location = m_program->attribs.location(reg_table[index]); if (vertex_info.array) { - __glcheck m_program.attribs[location] = + __glcheck m_program->attribs[location] = (m_vao + vertex_arrays_offsets[index]) .config(gl_types[vertex_info.type], vertex_info.size, gl_normalized[vertex_info.type]); } @@ -1014,10 +1014,10 @@ void GLGSRender::end() case CELL_GCM_VERTEX_F: switch (vertex_info.size) { - case 1: apply_attrib_array(m_program, location, vertex_data); break; - case 2: apply_attrib_array(m_program, location, vertex_data); break; - case 3: apply_attrib_array(m_program, location, vertex_data); break; - case 4: apply_attrib_array(m_program, location, vertex_data); break; + case 1: apply_attrib_array(*m_program, location, vertex_data); break; + case 2: apply_attrib_array(*m_program, location, vertex_data); break; + case 3: apply_attrib_array(*m_program, location, vertex_data); break; + case 4: apply_attrib_array(*m_program, location, vertex_data); break; } break; @@ -1095,11 +1095,13 @@ void GLGSRender::onexit_thread() if (m_vao) m_vao.remove(); + + m_prog_buffer.clear(); } void nv4097_clear_surface(u32 arg, GLGSRender* renderer) { - LOG_NOTICE(Log::RSX, "nv4097_clear_surface(0x%x)", arg); + //LOG_NOTICE(Log::RSX, "nv4097_clear_surface(0x%x)", arg); if ((arg & 0xf3) == 0) { @@ -1214,11 +1216,8 @@ bool GLGSRender::load_program() fragment_program.addr = rsx::get_address(fragment_program.offset, (shader_program & 0x3) - 1); fragment_program.ctrl = rsx::method_registers[NV4097_SET_SHADER_CONTROL]; - gl::glsl::program *result; - __glcheck result = m_prog_buffer.getGraphicPipelineState(&vertex_program, &fragment_program, nullptr, nullptr); - __glcheck result->use(); - - m_program.set_id(result->id()); + __glcheck m_program = m_prog_buffer.getGraphicPipelineState(&vertex_program, &fragment_program, nullptr, nullptr); + __glcheck m_program->use(); #else std::vector vertex_program; @@ -1287,12 +1286,12 @@ bool GLGSRender::load_program() scaleOffsetMat[1][3] = viewport_offset_y * 2.f / viewport_h - 1.f; scaleOffsetMat[2][3] = viewport_offset_z - .5f; - __glcheck m_program.uniforms["scaleOffsetMat"] = scaleOffsetMat; + __glcheck m_program->uniforms["scaleOffsetMat"] = scaleOffsetMat; for (auto &constant : transform_constants) { //LOG_WARNING(RSX, "vc[%u] = (%f, %f, %f, %f)", constant.first, constant.second.r, constant.second.g, constant.second.b, constant.second.a); - __glcheck m_program.uniforms["vc[" + std::to_string(constant.first) + "]"] = constant.second; + __glcheck m_program->uniforms["vc[" + std::to_string(constant.first) + "]"] = constant.second; } for (u32 constant_offset : m_prog_buffer.getFragmentConstantOffsetsCache(&fragment_program)) @@ -1304,7 +1303,7 @@ bool GLGSRender::load_program() u32 c2 = (data[2] >> 16 | data[2] << 16); u32 c3 = (data[3] >> 16 | data[3] << 16); - m_program.uniforms["fc" + std::to_string(constant_offset)] = color4f{ (f32&)c0, (f32&)c1, (f32&)c2, (f32&)c3 }; + m_program->uniforms["fc" + std::to_string(constant_offset)] = color4f{ (f32&)c0, (f32&)c1, (f32&)c2, (f32&)c3 }; } return true; @@ -1714,7 +1713,7 @@ void GLGSRender::write_buffers() void GLGSRender::flip(int buffer) { - LOG_NOTICE(Log::RSX, "flip(%d)", buffer); + //LOG_NOTICE(Log::RSX, "flip(%d)", buffer); u32 buffer_width = gcm_buffers[buffer].width; u32 buffer_height = gcm_buffers[buffer].height; u32 buffer_pitch = gcm_buffers[buffer].pitch; diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.h b/rpcs3/Emu/RSX/GL/GLGSRender.h index e388598e8d..71f0c08ac0 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.h +++ b/rpcs3/Emu/RSX/GL/GLGSRender.h @@ -57,8 +57,7 @@ private: GLTexture m_gl_textures[rsx::limits::textures_count]; GLTexture m_gl_vertex_textures[rsx::limits::vertex_textures_count]; - //TODO: program cache - gl::glsl::program m_program; + gl::glsl::program *m_program; rsx::surface_info m_surface;