diff options
Diffstat (limited to 'src')
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 @@ | |||
| 7 | #include "common/cityhash.h" | 7 | #include "common/cityhash.h" |
| 8 | #include "video_core/renderer_opengl/gl_compute_pipeline.h" | 8 | #include "video_core/renderer_opengl/gl_compute_pipeline.h" |
| 9 | #include "video_core/renderer_opengl/gl_shader_manager.h" | 9 | #include "video_core/renderer_opengl/gl_shader_manager.h" |
| 10 | #include "video_core/renderer_opengl/gl_shader_util.h" | ||
| 10 | 11 | ||
| 11 | namespace OpenGL { | 12 | namespace OpenGL { |
| 12 | 13 | ||
| @@ -39,10 +40,16 @@ ComputePipeline::ComputePipeline(const Device& device, TextureCache& texture_cac | |||
| 39 | BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_, | 40 | BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_, |
| 40 | Tegra::Engines::KeplerCompute& kepler_compute_, | 41 | Tegra::Engines::KeplerCompute& kepler_compute_, |
| 41 | ProgramManager& program_manager_, const Shader::Info& info_, | 42 | ProgramManager& program_manager_, const Shader::Info& info_, |
| 42 | OGLProgram source_program_, OGLAssemblyProgram assembly_program_) | 43 | const std::string code) |
| 43 | : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, gpu_memory{gpu_memory_}, | 44 | : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, gpu_memory{gpu_memory_}, |
| 44 | kepler_compute{kepler_compute_}, program_manager{program_manager_}, info{info_}, | 45 | kepler_compute{kepler_compute_}, program_manager{program_manager_}, info{info_} { |
| 45 | source_program{std::move(source_program_)}, assembly_program{std::move(assembly_program_)} { | 46 | if (device.UseAssemblyShaders()) { |
| 47 | assembly_program = CompileProgram(code, GL_COMPUTE_PROGRAM_NV); | ||
| 48 | } else { | ||
| 49 | source_program.handle = glCreateProgram(); | ||
| 50 | AttachShader(GL_COMPUTE_SHADER, source_program.handle, code); | ||
| 51 | LinkProgram(source_program.handle); | ||
| 52 | } | ||
| 46 | std::copy_n(info.constant_buffer_used_sizes.begin(), uniform_buffer_sizes.size(), | 53 | std::copy_n(info.constant_buffer_used_sizes.begin(), uniform_buffer_sizes.size(), |
| 47 | uniform_buffer_sizes.begin()); | 54 | uniform_buffer_sizes.begin()); |
| 48 | 55 | ||
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: | |||
| 54 | BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_, | 54 | BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_, |
| 55 | Tegra::Engines::KeplerCompute& kepler_compute_, | 55 | Tegra::Engines::KeplerCompute& kepler_compute_, |
| 56 | ProgramManager& program_manager_, const Shader::Info& info_, | 56 | ProgramManager& program_manager_, const Shader::Info& info_, |
| 57 | OGLProgram source_program_, OGLAssemblyProgram assembly_program_); | 57 | const std::string code); |
| 58 | 58 | ||
| 59 | void Configure(); | 59 | void Configure(); |
| 60 | 60 | ||
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 @@ | |||
| 9 | #include "shader_recompiler/shader_info.h" | 9 | #include "shader_recompiler/shader_info.h" |
| 10 | #include "video_core/renderer_opengl/gl_graphics_pipeline.h" | 10 | #include "video_core/renderer_opengl/gl_graphics_pipeline.h" |
| 11 | #include "video_core/renderer_opengl/gl_shader_manager.h" | 11 | #include "video_core/renderer_opengl/gl_shader_manager.h" |
| 12 | #include "video_core/renderer_opengl/gl_shader_util.h" | ||
| 12 | #include "video_core/renderer_opengl/gl_state_tracker.h" | 13 | #include "video_core/renderer_opengl/gl_state_tracker.h" |
| 13 | #include "video_core/texture_cache/texture_cache.h" | 14 | #include "video_core/texture_cache/texture_cache.h" |
| 14 | 15 | ||
| @@ -33,6 +34,40 @@ u32 AccumulateCount(const Range& range) { | |||
| 33 | return num; | 34 | return num; |
| 34 | } | 35 | } |
| 35 | 36 | ||
| 37 | GLenum Stage(size_t stage_index) { | ||
| 38 | switch (stage_index) { | ||
| 39 | case 0: | ||
| 40 | return GL_VERTEX_SHADER; | ||
| 41 | case 1: | ||
| 42 | return GL_TESS_CONTROL_SHADER; | ||
| 43 | case 2: | ||
| 44 | return GL_TESS_EVALUATION_SHADER; | ||
| 45 | case 3: | ||
| 46 | return GL_GEOMETRY_SHADER; | ||
| 47 | case 4: | ||
| 48 | return GL_FRAGMENT_SHADER; | ||
| 49 | } | ||
| 50 | UNREACHABLE_MSG("{}", stage_index); | ||
| 51 | return GL_NONE; | ||
| 52 | } | ||
| 53 | |||
| 54 | GLenum AssemblyStage(size_t stage_index) { | ||
| 55 | switch (stage_index) { | ||
| 56 | case 0: | ||
| 57 | return GL_VERTEX_PROGRAM_NV; | ||
| 58 | case 1: | ||
| 59 | return GL_TESS_CONTROL_PROGRAM_NV; | ||
| 60 | case 2: | ||
| 61 | return GL_TESS_EVALUATION_PROGRAM_NV; | ||
| 62 | case 3: | ||
| 63 | return GL_GEOMETRY_PROGRAM_NV; | ||
| 64 | case 4: | ||
| 65 | return GL_FRAGMENT_PROGRAM_NV; | ||
| 66 | } | ||
| 67 | UNREACHABLE_MSG("{}", stage_index); | ||
| 68 | return GL_NONE; | ||
| 69 | } | ||
| 70 | |||
| 36 | /// Translates hardware transform feedback indices | 71 | /// Translates hardware transform feedback indices |
| 37 | /// @param location Hardware location | 72 | /// @param location Hardware location |
| 38 | /// @return Pair of ARB_transform_feedback3 token stream first and third arguments | 73 | /// @return Pair of ARB_transform_feedback3 token stream first and third arguments |
| @@ -82,19 +117,33 @@ GraphicsPipeline::GraphicsPipeline(const Device& device, TextureCache& texture_c | |||
| 82 | BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_, | 117 | BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_, |
| 83 | Tegra::Engines::Maxwell3D& maxwell3d_, | 118 | Tegra::Engines::Maxwell3D& maxwell3d_, |
| 84 | ProgramManager& program_manager_, StateTracker& state_tracker_, | 119 | ProgramManager& program_manager_, StateTracker& state_tracker_, |
| 85 | OGLProgram program_, | 120 | const std::array<std::string, 5> assembly_sources, |
| 86 | std::array<OGLAssemblyProgram, 5> assembly_programs_, | 121 | const std::array<std::string, 5> glsl_sources, |
| 87 | const std::array<const Shader::Info*, 5>& infos, | 122 | const std::array<const Shader::Info*, 5>& infos, |
| 88 | const VideoCommon::TransformFeedbackState* xfb_state) | 123 | const VideoCommon::TransformFeedbackState* xfb_state) |
| 89 | : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, | 124 | : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, gpu_memory{gpu_memory_}, |
| 90 | gpu_memory{gpu_memory_}, maxwell3d{maxwell3d_}, program_manager{program_manager_}, | 125 | maxwell3d{maxwell3d_}, program_manager{program_manager_}, state_tracker{state_tracker_} { |
| 91 | state_tracker{state_tracker_}, program{std::move(program_)}, assembly_programs{std::move( | ||
| 92 | assembly_programs_)} { | ||
| 93 | std::ranges::transform(infos, stage_infos.begin(), | 126 | std::ranges::transform(infos, stage_infos.begin(), |
| 94 | [](const Shader::Info* info) { return info ? *info : Shader::Info{}; }); | 127 | [](const Shader::Info* info) { return info ? *info : Shader::Info{}; }); |
| 95 | 128 | if (device.UseAssemblyShaders()) { | |
| 96 | for (size_t stage = 0; stage < 5; ++stage) { | 129 | for (size_t stage = 0; stage < 5; ++stage) { |
| 97 | enabled_stages_mask |= (assembly_programs[stage].handle != 0 ? 1 : 0) << stage; | 130 | const auto code{assembly_sources[stage]}; |
| 131 | if (code.empty()) { | ||
| 132 | continue; | ||
| 133 | } | ||
| 134 | assembly_programs[stage] = CompileProgram(code, AssemblyStage(stage)); | ||
| 135 | enabled_stages_mask |= (assembly_programs[stage].handle != 0 ? 1 : 0) << stage; | ||
| 136 | } | ||
| 137 | } else { | ||
| 138 | program.handle = glCreateProgram(); | ||
| 139 | for (size_t stage = 0; stage < 5; ++stage) { | ||
| 140 | const auto code{glsl_sources[stage]}; | ||
| 141 | if (code.empty()) { | ||
| 142 | continue; | ||
| 143 | } | ||
| 144 | AttachShader(Stage(stage), program.handle, code); | ||
| 145 | } | ||
| 146 | LinkProgram(program.handle); | ||
| 98 | } | 147 | } |
| 99 | u32 num_textures{}; | 148 | u32 num_textures{}; |
| 100 | u32 num_images{}; | 149 | 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: | |||
| 65 | BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_, | 65 | BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_, |
| 66 | Tegra::Engines::Maxwell3D& maxwell3d_, | 66 | Tegra::Engines::Maxwell3D& maxwell3d_, |
| 67 | ProgramManager& program_manager_, StateTracker& state_tracker_, | 67 | ProgramManager& program_manager_, StateTracker& state_tracker_, |
| 68 | OGLProgram program_, | 68 | const std::array<std::string, 5> assembly_sources, |
| 69 | std::array<OGLAssemblyProgram, 5> assembly_programs_, | 69 | const std::array<std::string, 5> glsl_sources, |
| 70 | const std::array<const Shader::Info*, 5>& infos, | 70 | const std::array<const Shader::Info*, 5>& infos, |
| 71 | const VideoCommon::TransformFeedbackState* xfb_state); | 71 | const VideoCommon::TransformFeedbackState* xfb_state); |
| 72 | 72 | ||
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) { | |||
| 56 | return std::span(container.data(), container.size()); | 56 | return std::span(container.data(), container.size()); |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | GLenum Stage(size_t stage_index) { | ||
| 60 | switch (stage_index) { | ||
| 61 | case 0: | ||
| 62 | return GL_VERTEX_SHADER; | ||
| 63 | case 1: | ||
| 64 | return GL_TESS_CONTROL_SHADER; | ||
| 65 | case 2: | ||
| 66 | return GL_TESS_EVALUATION_SHADER; | ||
| 67 | case 3: | ||
| 68 | return GL_GEOMETRY_SHADER; | ||
| 69 | case 4: | ||
| 70 | return GL_FRAGMENT_SHADER; | ||
| 71 | } | ||
| 72 | UNREACHABLE_MSG("{}", stage_index); | ||
| 73 | return GL_NONE; | ||
| 74 | } | ||
| 75 | |||
| 76 | GLenum AssemblyStage(size_t stage_index) { | ||
| 77 | switch (stage_index) { | ||
| 78 | case 0: | ||
| 79 | return GL_VERTEX_PROGRAM_NV; | ||
| 80 | case 1: | ||
| 81 | return GL_TESS_CONTROL_PROGRAM_NV; | ||
| 82 | case 2: | ||
| 83 | return GL_TESS_EVALUATION_PROGRAM_NV; | ||
| 84 | case 3: | ||
| 85 | return GL_GEOMETRY_PROGRAM_NV; | ||
| 86 | case 4: | ||
| 87 | return GL_FRAGMENT_PROGRAM_NV; | ||
| 88 | } | ||
| 89 | UNREACHABLE_MSG("{}", stage_index); | ||
| 90 | return GL_NONE; | ||
| 91 | } | ||
| 92 | |||
| 93 | Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key, | 59 | Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key, |
| 94 | const Shader::IR::Program& program, | 60 | const Shader::IR::Program& program, |
| 95 | bool glasm_use_storage_buffers, bool use_assembly_shaders) { | 61 | bool glasm_use_storage_buffers, bool use_assembly_shaders) { |
| @@ -426,12 +392,10 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline( | |||
| 426 | std::array<const Shader::Info*, Maxwell::MaxShaderStage> infos{}; | 392 | std::array<const Shader::Info*, Maxwell::MaxShaderStage> infos{}; |
| 427 | 393 | ||
| 428 | OGLProgram source_program; | 394 | OGLProgram source_program; |
| 429 | std::array<OGLAssemblyProgram, 5> assembly_programs; | 395 | std::array<std::string, 5> assembly_sources; |
| 396 | std::array<std::string, 5> glsl_sources; | ||
| 430 | Shader::Backend::Bindings binding; | 397 | Shader::Backend::Bindings binding; |
| 431 | const bool use_glasm{device.UseAssemblyShaders()}; | 398 | const bool use_glasm{device.UseAssemblyShaders()}; |
| 432 | if (!use_glasm) { | ||
| 433 | source_program.handle = glCreateProgram(); | ||
| 434 | } | ||
| 435 | const size_t first_index = uses_vertex_a && uses_vertex_b ? 1 : 0; | 399 | const size_t first_index = uses_vertex_a && uses_vertex_b ? 1 : 0; |
| 436 | for (size_t index = first_index; index < Maxwell::MaxShaderProgram; ++index) { | 400 | for (size_t index = first_index; index < Maxwell::MaxShaderProgram; ++index) { |
| 437 | if (key.unique_hashes[index] == 0) { | 401 | if (key.unique_hashes[index] == 0) { |
| @@ -446,20 +410,14 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline( | |||
| 446 | const auto runtime_info{ | 410 | const auto runtime_info{ |
| 447 | MakeRuntimeInfo(key, program, glasm_use_storage_buffers, use_glasm)}; | 411 | MakeRuntimeInfo(key, program, glasm_use_storage_buffers, use_glasm)}; |
| 448 | if (use_glasm) { | 412 | if (use_glasm) { |
| 449 | const std::string code{EmitGLASM(profile, runtime_info, program, binding)}; | 413 | assembly_sources[stage_index] = EmitGLASM(profile, runtime_info, program, binding); |
| 450 | assembly_programs[stage_index] = CompileProgram(code, AssemblyStage(stage_index)); | ||
| 451 | } else { | 414 | } else { |
| 452 | const auto code{EmitGLSL(profile, runtime_info, program, binding)}; | 415 | glsl_sources[stage_index] = EmitGLSL(profile, runtime_info, program, binding); |
| 453 | AttachShader(Stage(stage_index), source_program.handle, code); | ||
| 454 | } | 416 | } |
| 455 | } | 417 | } |
| 456 | if (!use_glasm) { | ||
| 457 | LinkProgram(source_program.handle); | ||
| 458 | } | ||
| 459 | return std::make_unique<GraphicsPipeline>( | 418 | return std::make_unique<GraphicsPipeline>( |
| 460 | device, texture_cache, buffer_cache, gpu_memory, maxwell3d, program_manager, state_tracker, | 419 | device, texture_cache, buffer_cache, gpu_memory, maxwell3d, program_manager, state_tracker, |
| 461 | std::move(source_program), std::move(assembly_programs), infos, | 420 | assembly_sources, glsl_sources, infos, key.xfb_enabled != 0 ? &key.xfb_state : nullptr); |
| 462 | key.xfb_enabled != 0 ? &key.xfb_state : nullptr); | ||
| 463 | 421 | ||
| 464 | } catch (Shader::Exception& exception) { | 422 | } catch (Shader::Exception& exception) { |
| 465 | LOG_ERROR(Render_OpenGL, "{}", exception.what()); | 423 | LOG_ERROR(Render_OpenGL, "{}", exception.what()); |
| @@ -496,21 +454,10 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(ShaderPools& | |||
| 496 | } | 454 | } |
| 497 | Shader::RuntimeInfo info; | 455 | Shader::RuntimeInfo info; |
| 498 | info.glasm_use_storage_buffers = num_storage_buffers <= device.GetMaxGLASMStorageBufferBlocks(); | 456 | info.glasm_use_storage_buffers = num_storage_buffers <= device.GetMaxGLASMStorageBufferBlocks(); |
| 499 | 457 | const std::string code{device.UseAssemblyShaders() ? EmitGLASM(profile, info, program) | |
| 500 | OGLAssemblyProgram asm_program; | 458 | : EmitGLSL(profile, program)}; |
| 501 | OGLProgram source_program; | ||
| 502 | if (device.UseAssemblyShaders()) { | ||
| 503 | const std::string code{EmitGLASM(profile, info, program)}; | ||
| 504 | asm_program = CompileProgram(code, GL_COMPUTE_PROGRAM_NV); | ||
| 505 | } else { | ||
| 506 | const auto code{EmitGLSL(profile, program)}; | ||
| 507 | source_program.handle = glCreateProgram(); | ||
| 508 | AttachShader(GL_COMPUTE_SHADER, source_program.handle, code); | ||
| 509 | LinkProgram(source_program.handle); | ||
| 510 | } | ||
| 511 | return std::make_unique<ComputePipeline>(device, texture_cache, buffer_cache, gpu_memory, | 459 | return std::make_unique<ComputePipeline>(device, texture_cache, buffer_cache, gpu_memory, |
| 512 | kepler_compute, program_manager, program.info, | 460 | kepler_compute, program_manager, program.info, code); |
| 513 | std::move(source_program), std::move(asm_program)); | ||
| 514 | } catch (Shader::Exception& exception) { | 461 | } catch (Shader::Exception& exception) { |
| 515 | LOG_ERROR(Render_OpenGL, "{}", exception.what()); | 462 | LOG_ERROR(Render_OpenGL, "{}", exception.what()); |
| 516 | return nullptr; | 463 | return nullptr; |