gl_shader_cache: Move OGL shader compilation to the respective Pipeline constructor
This commit is contained in:
		| @@ -7,6 +7,7 @@ | |||||||
| #include "common/cityhash.h" | #include "common/cityhash.h" | ||||||
| #include "video_core/renderer_opengl/gl_compute_pipeline.h" | #include "video_core/renderer_opengl/gl_compute_pipeline.h" | ||||||
| #include "video_core/renderer_opengl/gl_shader_manager.h" | #include "video_core/renderer_opengl/gl_shader_manager.h" | ||||||
|  | #include "video_core/renderer_opengl/gl_shader_util.h" | ||||||
|  |  | ||||||
| namespace OpenGL { | namespace OpenGL { | ||||||
|  |  | ||||||
| @@ -39,10 +40,16 @@ ComputePipeline::ComputePipeline(const Device& device, TextureCache& texture_cac | |||||||
|                                  BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_, |                                  BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_, | ||||||
|                                  Tegra::Engines::KeplerCompute& kepler_compute_, |                                  Tegra::Engines::KeplerCompute& kepler_compute_, | ||||||
|                                  ProgramManager& program_manager_, const Shader::Info& info_, |                                  ProgramManager& program_manager_, const Shader::Info& info_, | ||||||
|                                  OGLProgram source_program_, OGLAssemblyProgram assembly_program_) |                                  const std::string code) | ||||||
|     : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, gpu_memory{gpu_memory_}, |     : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, gpu_memory{gpu_memory_}, | ||||||
|       kepler_compute{kepler_compute_}, program_manager{program_manager_}, info{info_}, |       kepler_compute{kepler_compute_}, program_manager{program_manager_}, info{info_} { | ||||||
|       source_program{std::move(source_program_)}, assembly_program{std::move(assembly_program_)} { |     if (device.UseAssemblyShaders()) { | ||||||
|  |         assembly_program = CompileProgram(code, GL_COMPUTE_PROGRAM_NV); | ||||||
|  |     } else { | ||||||
|  |         source_program.handle = glCreateProgram(); | ||||||
|  |         AttachShader(GL_COMPUTE_SHADER, source_program.handle, code); | ||||||
|  |         LinkProgram(source_program.handle); | ||||||
|  |     } | ||||||
|     std::copy_n(info.constant_buffer_used_sizes.begin(), uniform_buffer_sizes.size(), |     std::copy_n(info.constant_buffer_used_sizes.begin(), uniform_buffer_sizes.size(), | ||||||
|                 uniform_buffer_sizes.begin()); |                 uniform_buffer_sizes.begin()); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -54,7 +54,7 @@ public: | |||||||
|                              BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_, |                              BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_, | ||||||
|                              Tegra::Engines::KeplerCompute& kepler_compute_, |                              Tegra::Engines::KeplerCompute& kepler_compute_, | ||||||
|                              ProgramManager& program_manager_, const Shader::Info& info_, |                              ProgramManager& program_manager_, const Shader::Info& info_, | ||||||
|                              OGLProgram source_program_, OGLAssemblyProgram assembly_program_); |                              const std::string code); | ||||||
|  |  | ||||||
|     void Configure(); |     void Configure(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ | |||||||
| #include "shader_recompiler/shader_info.h" | #include "shader_recompiler/shader_info.h" | ||||||
| #include "video_core/renderer_opengl/gl_graphics_pipeline.h" | #include "video_core/renderer_opengl/gl_graphics_pipeline.h" | ||||||
| #include "video_core/renderer_opengl/gl_shader_manager.h" | #include "video_core/renderer_opengl/gl_shader_manager.h" | ||||||
|  | #include "video_core/renderer_opengl/gl_shader_util.h" | ||||||
| #include "video_core/renderer_opengl/gl_state_tracker.h" | #include "video_core/renderer_opengl/gl_state_tracker.h" | ||||||
| #include "video_core/texture_cache/texture_cache.h" | #include "video_core/texture_cache/texture_cache.h" | ||||||
|  |  | ||||||
| @@ -33,6 +34,40 @@ u32 AccumulateCount(const Range& range) { | |||||||
|     return num; |     return num; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | GLenum Stage(size_t stage_index) { | ||||||
|  |     switch (stage_index) { | ||||||
|  |     case 0: | ||||||
|  |         return GL_VERTEX_SHADER; | ||||||
|  |     case 1: | ||||||
|  |         return GL_TESS_CONTROL_SHADER; | ||||||
|  |     case 2: | ||||||
|  |         return GL_TESS_EVALUATION_SHADER; | ||||||
|  |     case 3: | ||||||
|  |         return GL_GEOMETRY_SHADER; | ||||||
|  |     case 4: | ||||||
|  |         return GL_FRAGMENT_SHADER; | ||||||
|  |     } | ||||||
|  |     UNREACHABLE_MSG("{}", stage_index); | ||||||
|  |     return GL_NONE; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | GLenum AssemblyStage(size_t stage_index) { | ||||||
|  |     switch (stage_index) { | ||||||
|  |     case 0: | ||||||
|  |         return GL_VERTEX_PROGRAM_NV; | ||||||
|  |     case 1: | ||||||
|  |         return GL_TESS_CONTROL_PROGRAM_NV; | ||||||
|  |     case 2: | ||||||
|  |         return GL_TESS_EVALUATION_PROGRAM_NV; | ||||||
|  |     case 3: | ||||||
|  |         return GL_GEOMETRY_PROGRAM_NV; | ||||||
|  |     case 4: | ||||||
|  |         return GL_FRAGMENT_PROGRAM_NV; | ||||||
|  |     } | ||||||
|  |     UNREACHABLE_MSG("{}", stage_index); | ||||||
|  |     return GL_NONE; | ||||||
|  | } | ||||||
|  |  | ||||||
| /// Translates hardware transform feedback indices | /// Translates hardware transform feedback indices | ||||||
| /// @param location Hardware location | /// @param location Hardware location | ||||||
| /// @return Pair of ARB_transform_feedback3 token stream first and third arguments | /// @return Pair of ARB_transform_feedback3 token stream first and third arguments | ||||||
| @@ -82,19 +117,33 @@ GraphicsPipeline::GraphicsPipeline(const Device& device, TextureCache& texture_c | |||||||
|                                    BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_, |                                    BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_, | ||||||
|                                    Tegra::Engines::Maxwell3D& maxwell3d_, |                                    Tegra::Engines::Maxwell3D& maxwell3d_, | ||||||
|                                    ProgramManager& program_manager_, StateTracker& state_tracker_, |                                    ProgramManager& program_manager_, StateTracker& state_tracker_, | ||||||
|                                    OGLProgram program_, |                                    const std::array<std::string, 5> assembly_sources, | ||||||
|                                    std::array<OGLAssemblyProgram, 5> assembly_programs_, |                                    const std::array<std::string, 5> glsl_sources, | ||||||
|                                    const std::array<const Shader::Info*, 5>& infos, |                                    const std::array<const Shader::Info*, 5>& infos, | ||||||
|                                    const VideoCommon::TransformFeedbackState* xfb_state) |                                    const VideoCommon::TransformFeedbackState* xfb_state) | ||||||
|     : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, |     : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, gpu_memory{gpu_memory_}, | ||||||
|       gpu_memory{gpu_memory_}, maxwell3d{maxwell3d_}, program_manager{program_manager_}, |       maxwell3d{maxwell3d_}, program_manager{program_manager_}, state_tracker{state_tracker_} { | ||||||
|       state_tracker{state_tracker_}, program{std::move(program_)}, assembly_programs{std::move( |  | ||||||
|                                                                        assembly_programs_)} { |  | ||||||
|     std::ranges::transform(infos, stage_infos.begin(), |     std::ranges::transform(infos, stage_infos.begin(), | ||||||
|                            [](const Shader::Info* info) { return info ? *info : Shader::Info{}; }); |                            [](const Shader::Info* info) { return info ? *info : Shader::Info{}; }); | ||||||
|  |     if (device.UseAssemblyShaders()) { | ||||||
|     for (size_t stage = 0; stage < 5; ++stage) { |         for (size_t stage = 0; stage < 5; ++stage) { | ||||||
|         enabled_stages_mask |= (assembly_programs[stage].handle != 0 ? 1 : 0) << stage; |             const auto code{assembly_sources[stage]}; | ||||||
|  |             if (code.empty()) { | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |             assembly_programs[stage] = CompileProgram(code, AssemblyStage(stage)); | ||||||
|  |             enabled_stages_mask |= (assembly_programs[stage].handle != 0 ? 1 : 0) << stage; | ||||||
|  |         } | ||||||
|  |     } else { | ||||||
|  |         program.handle = glCreateProgram(); | ||||||
|  |         for (size_t stage = 0; stage < 5; ++stage) { | ||||||
|  |             const auto code{glsl_sources[stage]}; | ||||||
|  |             if (code.empty()) { | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |             AttachShader(Stage(stage), program.handle, code); | ||||||
|  |         } | ||||||
|  |         LinkProgram(program.handle); | ||||||
|     } |     } | ||||||
|     u32 num_textures{}; |     u32 num_textures{}; | ||||||
|     u32 num_images{}; |     u32 num_images{}; | ||||||
|   | |||||||
| @@ -65,8 +65,8 @@ public: | |||||||
|                               BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_, |                               BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_, | ||||||
|                               Tegra::Engines::Maxwell3D& maxwell3d_, |                               Tegra::Engines::Maxwell3D& maxwell3d_, | ||||||
|                               ProgramManager& program_manager_, StateTracker& state_tracker_, |                               ProgramManager& program_manager_, StateTracker& state_tracker_, | ||||||
|                               OGLProgram program_, |                               const std::array<std::string, 5> assembly_sources, | ||||||
|                               std::array<OGLAssemblyProgram, 5> assembly_programs_, |                               const std::array<std::string, 5> glsl_sources, | ||||||
|                               const std::array<const Shader::Info*, 5>& infos, |                               const std::array<const Shader::Info*, 5>& infos, | ||||||
|                               const VideoCommon::TransformFeedbackState* xfb_state); |                               const VideoCommon::TransformFeedbackState* xfb_state); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -56,40 +56,6 @@ auto MakeSpan(Container& container) { | |||||||
|     return std::span(container.data(), container.size()); |     return std::span(container.data(), container.size()); | ||||||
| } | } | ||||||
|  |  | ||||||
| GLenum Stage(size_t stage_index) { |  | ||||||
|     switch (stage_index) { |  | ||||||
|     case 0: |  | ||||||
|         return GL_VERTEX_SHADER; |  | ||||||
|     case 1: |  | ||||||
|         return GL_TESS_CONTROL_SHADER; |  | ||||||
|     case 2: |  | ||||||
|         return GL_TESS_EVALUATION_SHADER; |  | ||||||
|     case 3: |  | ||||||
|         return GL_GEOMETRY_SHADER; |  | ||||||
|     case 4: |  | ||||||
|         return GL_FRAGMENT_SHADER; |  | ||||||
|     } |  | ||||||
|     UNREACHABLE_MSG("{}", stage_index); |  | ||||||
|     return GL_NONE; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| GLenum AssemblyStage(size_t stage_index) { |  | ||||||
|     switch (stage_index) { |  | ||||||
|     case 0: |  | ||||||
|         return GL_VERTEX_PROGRAM_NV; |  | ||||||
|     case 1: |  | ||||||
|         return GL_TESS_CONTROL_PROGRAM_NV; |  | ||||||
|     case 2: |  | ||||||
|         return GL_TESS_EVALUATION_PROGRAM_NV; |  | ||||||
|     case 3: |  | ||||||
|         return GL_GEOMETRY_PROGRAM_NV; |  | ||||||
|     case 4: |  | ||||||
|         return GL_FRAGMENT_PROGRAM_NV; |  | ||||||
|     } |  | ||||||
|     UNREACHABLE_MSG("{}", stage_index); |  | ||||||
|     return GL_NONE; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key, | Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key, | ||||||
|                                     const Shader::IR::Program& program, |                                     const Shader::IR::Program& program, | ||||||
|                                     bool glasm_use_storage_buffers, bool use_assembly_shaders) { |                                     bool glasm_use_storage_buffers, bool use_assembly_shaders) { | ||||||
| @@ -426,12 +392,10 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline( | |||||||
|     std::array<const Shader::Info*, Maxwell::MaxShaderStage> infos{}; |     std::array<const Shader::Info*, Maxwell::MaxShaderStage> infos{}; | ||||||
|  |  | ||||||
|     OGLProgram source_program; |     OGLProgram source_program; | ||||||
|     std::array<OGLAssemblyProgram, 5> assembly_programs; |     std::array<std::string, 5> assembly_sources; | ||||||
|  |     std::array<std::string, 5> glsl_sources; | ||||||
|     Shader::Backend::Bindings binding; |     Shader::Backend::Bindings binding; | ||||||
|     const bool use_glasm{device.UseAssemblyShaders()}; |     const bool use_glasm{device.UseAssemblyShaders()}; | ||||||
|     if (!use_glasm) { |  | ||||||
|         source_program.handle = glCreateProgram(); |  | ||||||
|     } |  | ||||||
|     const size_t first_index = uses_vertex_a && uses_vertex_b ? 1 : 0; |     const size_t first_index = uses_vertex_a && uses_vertex_b ? 1 : 0; | ||||||
|     for (size_t index = first_index; index < Maxwell::MaxShaderProgram; ++index) { |     for (size_t index = first_index; index < Maxwell::MaxShaderProgram; ++index) { | ||||||
|         if (key.unique_hashes[index] == 0) { |         if (key.unique_hashes[index] == 0) { | ||||||
| @@ -446,20 +410,14 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline( | |||||||
|         const auto runtime_info{ |         const auto runtime_info{ | ||||||
|             MakeRuntimeInfo(key, program, glasm_use_storage_buffers, use_glasm)}; |             MakeRuntimeInfo(key, program, glasm_use_storage_buffers, use_glasm)}; | ||||||
|         if (use_glasm) { |         if (use_glasm) { | ||||||
|             const std::string code{EmitGLASM(profile, runtime_info, program, binding)}; |             assembly_sources[stage_index] = EmitGLASM(profile, runtime_info, program, binding); | ||||||
|             assembly_programs[stage_index] = CompileProgram(code, AssemblyStage(stage_index)); |  | ||||||
|         } else { |         } else { | ||||||
|             const auto code{EmitGLSL(profile, runtime_info, program, binding)}; |             glsl_sources[stage_index] = EmitGLSL(profile, runtime_info, program, binding); | ||||||
|             AttachShader(Stage(stage_index), source_program.handle, code); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     if (!use_glasm) { |  | ||||||
|         LinkProgram(source_program.handle); |  | ||||||
|     } |  | ||||||
|     return std::make_unique<GraphicsPipeline>( |     return std::make_unique<GraphicsPipeline>( | ||||||
|         device, texture_cache, buffer_cache, gpu_memory, maxwell3d, program_manager, state_tracker, |         device, texture_cache, buffer_cache, gpu_memory, maxwell3d, program_manager, state_tracker, | ||||||
|         std::move(source_program), std::move(assembly_programs), infos, |         assembly_sources, glsl_sources, infos, key.xfb_enabled != 0 ? &key.xfb_state : nullptr); | ||||||
|         key.xfb_enabled != 0 ? &key.xfb_state : nullptr); |  | ||||||
|  |  | ||||||
| } catch (Shader::Exception& exception) { | } catch (Shader::Exception& exception) { | ||||||
|     LOG_ERROR(Render_OpenGL, "{}", exception.what()); |     LOG_ERROR(Render_OpenGL, "{}", exception.what()); | ||||||
| @@ -496,21 +454,10 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(ShaderPools& | |||||||
|     } |     } | ||||||
|     Shader::RuntimeInfo info; |     Shader::RuntimeInfo info; | ||||||
|     info.glasm_use_storage_buffers = num_storage_buffers <= device.GetMaxGLASMStorageBufferBlocks(); |     info.glasm_use_storage_buffers = num_storage_buffers <= device.GetMaxGLASMStorageBufferBlocks(); | ||||||
|  |     const std::string code{device.UseAssemblyShaders() ? EmitGLASM(profile, info, program) | ||||||
|     OGLAssemblyProgram asm_program; |                                                        : EmitGLSL(profile, program)}; | ||||||
|     OGLProgram source_program; |  | ||||||
|     if (device.UseAssemblyShaders()) { |  | ||||||
|         const std::string code{EmitGLASM(profile, info, program)}; |  | ||||||
|         asm_program = CompileProgram(code, GL_COMPUTE_PROGRAM_NV); |  | ||||||
|     } else { |  | ||||||
|         const auto code{EmitGLSL(profile, program)}; |  | ||||||
|         source_program.handle = glCreateProgram(); |  | ||||||
|         AttachShader(GL_COMPUTE_SHADER, source_program.handle, code); |  | ||||||
|         LinkProgram(source_program.handle); |  | ||||||
|     } |  | ||||||
|     return std::make_unique<ComputePipeline>(device, texture_cache, buffer_cache, gpu_memory, |     return std::make_unique<ComputePipeline>(device, texture_cache, buffer_cache, gpu_memory, | ||||||
|                                              kepler_compute, program_manager, program.info, |                                              kepler_compute, program_manager, program.info, code); | ||||||
|                                              std::move(source_program), std::move(asm_program)); |  | ||||||
| } catch (Shader::Exception& exception) { | } catch (Shader::Exception& exception) { | ||||||
|     LOG_ERROR(Render_OpenGL, "{}", exception.what()); |     LOG_ERROR(Render_OpenGL, "{}", exception.what()); | ||||||
|     return nullptr; |     return nullptr; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user