diff options
Diffstat (limited to 'src/video_core')
5 files changed, 79 insertions, 76 deletions
| diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp index a40106c87..f984b635c 100644 --- a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp +++ b/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()); diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.h b/src/video_core/renderer_opengl/gl_compute_pipeline.h index b5dfb65e9..a93166eb6 100644 --- a/src/video_core/renderer_opengl/gl_compute_pipeline.h +++ b/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(); diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp index a2ea35d5a..4d62d7062 100644 --- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp +++ b/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{}; diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.h b/src/video_core/renderer_opengl/gl_graphics_pipeline.h index 508fad5bb..984bf994f 100644 --- a/src/video_core/renderer_opengl/gl_graphics_pipeline.h +++ b/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); diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index 4fcf4e458..884739aec 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/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; | 
