Преглед изворни кода

gl_shader_cache: Move OGL shader compilation to the respective Pipeline constructor

ameerj пре 5 година
родитељ
комит
413eb6983f

+ 10 - 3
src/video_core/renderer_opengl/gl_compute_pipeline.cpp

@@ -7,6 +7,7 @@
 #include "common/cityhash.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_util.h"
 
 namespace OpenGL {
 
@@ -39,10 +40,16 @@ ComputePipeline::ComputePipeline(const Device& device, TextureCache& texture_cac
                                  BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_,
                                  Tegra::Engines::KeplerCompute& kepler_compute_,
                                  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_},
-      kepler_compute{kepler_compute_}, program_manager{program_manager_}, info{info_},
-      source_program{std::move(source_program_)}, assembly_program{std::move(assembly_program_)} {
+      kepler_compute{kepler_compute_}, program_manager{program_manager_}, info{info_} {
+    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(),
                 uniform_buffer_sizes.begin());
 

+ 1 - 1
src/video_core/renderer_opengl/gl_compute_pipeline.h

@@ -54,7 +54,7 @@ public:
                              BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_,
                              Tegra::Engines::KeplerCompute& kepler_compute_,
                              ProgramManager& program_manager_, const Shader::Info& info_,
-                             OGLProgram source_program_, OGLAssemblyProgram assembly_program_);
+                             const std::string code);
 
     void Configure();
 

+ 58 - 9
src/video_core/renderer_opengl/gl_graphics_pipeline.cpp

@@ -9,6 +9,7 @@
 #include "shader_recompiler/shader_info.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_util.h"
 #include "video_core/renderer_opengl/gl_state_tracker.h"
 #include "video_core/texture_cache/texture_cache.h"
 
@@ -33,6 +34,40 @@ u32 AccumulateCount(const Range& range) {
     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
 /// @param location Hardware location
 /// @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_,
                                    Tegra::Engines::Maxwell3D& maxwell3d_,
                                    ProgramManager& program_manager_, StateTracker& state_tracker_,
-                                   OGLProgram program_,
-                                   std::array<OGLAssemblyProgram, 5> assembly_programs_,
+                                   const std::array<std::string, 5> assembly_sources,
+                                   const std::array<std::string, 5> glsl_sources,
                                    const std::array<const Shader::Info*, 5>& infos,
                                    const VideoCommon::TransformFeedbackState* xfb_state)
-    : texture_cache{texture_cache_}, buffer_cache{buffer_cache_},
-      gpu_memory{gpu_memory_}, maxwell3d{maxwell3d_}, program_manager{program_manager_},
-      state_tracker{state_tracker_}, program{std::move(program_)}, assembly_programs{std::move(
-                                                                       assembly_programs_)} {
+    : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, gpu_memory{gpu_memory_},
+      maxwell3d{maxwell3d_}, program_manager{program_manager_}, state_tracker{state_tracker_} {
     std::ranges::transform(infos, stage_infos.begin(),
                            [](const Shader::Info* info) { return info ? *info : Shader::Info{}; });
-
-    for (size_t stage = 0; stage < 5; ++stage) {
-        enabled_stages_mask |= (assembly_programs[stage].handle != 0 ? 1 : 0) << stage;
+    if (device.UseAssemblyShaders()) {
+        for (size_t stage = 0; stage < 5; ++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_images{};

+ 2 - 2
src/video_core/renderer_opengl/gl_graphics_pipeline.h

@@ -65,8 +65,8 @@ public:
                               BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_,
                               Tegra::Engines::Maxwell3D& maxwell3d_,
                               ProgramManager& program_manager_, StateTracker& state_tracker_,
-                              OGLProgram program_,
-                              std::array<OGLAssemblyProgram, 5> assembly_programs_,
+                              const std::array<std::string, 5> assembly_sources,
+                              const std::array<std::string, 5> glsl_sources,
                               const std::array<const Shader::Info*, 5>& infos,
                               const VideoCommon::TransformFeedbackState* xfb_state);
 

+ 8 - 61
src/video_core/renderer_opengl/gl_shader_cache.cpp

@@ -56,40 +56,6 @@ auto MakeSpan(Container& container) {
     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,
                                     const Shader::IR::Program& program,
                                     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{};
 
     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;
     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;
     for (size_t index = first_index; index < Maxwell::MaxShaderProgram; ++index) {
         if (key.unique_hashes[index] == 0) {
@@ -446,20 +410,14 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
         const auto runtime_info{
             MakeRuntimeInfo(key, program, glasm_use_storage_buffers, use_glasm)};
         if (use_glasm) {
-            const std::string code{EmitGLASM(profile, runtime_info, program, binding)};
-            assembly_programs[stage_index] = CompileProgram(code, AssemblyStage(stage_index));
+            assembly_sources[stage_index] = EmitGLASM(profile, runtime_info, program, binding);
         } else {
-            const auto code{EmitGLSL(profile, runtime_info, program, binding)};
-            AttachShader(Stage(stage_index), source_program.handle, code);
+            glsl_sources[stage_index] = EmitGLSL(profile, runtime_info, program, binding);
         }
     }
-    if (!use_glasm) {
-        LinkProgram(source_program.handle);
-    }
     return std::make_unique<GraphicsPipeline>(
         device, texture_cache, buffer_cache, gpu_memory, maxwell3d, program_manager, state_tracker,
-        std::move(source_program), std::move(assembly_programs), infos,
-        key.xfb_enabled != 0 ? &key.xfb_state : nullptr);
+        assembly_sources, glsl_sources, infos, key.xfb_enabled != 0 ? &key.xfb_state : nullptr);
 
 } catch (Shader::Exception& exception) {
     LOG_ERROR(Render_OpenGL, "{}", exception.what());
@@ -496,21 +454,10 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(ShaderPools&
     }
     Shader::RuntimeInfo info;
     info.glasm_use_storage_buffers = num_storage_buffers <= device.GetMaxGLASMStorageBufferBlocks();
-
-    OGLAssemblyProgram asm_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);
-    }
+    const std::string code{device.UseAssemblyShaders() ? EmitGLASM(profile, info, program)
+                                                       : EmitGLSL(profile, program)};
     return std::make_unique<ComputePipeline>(device, texture_cache, buffer_cache, gpu_memory,
-                                             kepler_compute, program_manager, program.info,
-                                             std::move(source_program), std::move(asm_program));
+                                             kepler_compute, program_manager, program.info, code);
 } catch (Shader::Exception& exception) {
     LOG_ERROR(Render_OpenGL, "{}", exception.what());
     return nullptr;