diff options
| -rw-r--r-- | src/video_core/renderer_opengl/gl_graphics_program.cpp | 15 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_graphics_program.h | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.cpp | 46 |
3 files changed, 53 insertions, 14 deletions
diff --git a/src/video_core/renderer_opengl/gl_graphics_program.cpp b/src/video_core/renderer_opengl/gl_graphics_program.cpp index fd0958719..7c0bf7bc8 100644 --- a/src/video_core/renderer_opengl/gl_graphics_program.cpp +++ b/src/video_core/renderer_opengl/gl_graphics_program.cpp | |||
| @@ -33,10 +33,12 @@ GraphicsProgram::GraphicsProgram(TextureCache& texture_cache_, BufferCache& buff | |||
| 33 | Tegra::Engines::Maxwell3D& maxwell3d_, | 33 | Tegra::Engines::Maxwell3D& maxwell3d_, |
| 34 | ProgramManager& program_manager_, StateTracker& state_tracker_, | 34 | ProgramManager& program_manager_, StateTracker& state_tracker_, |
| 35 | OGLProgram program_, | 35 | OGLProgram program_, |
| 36 | std::array<OGLAssemblyProgram, 5> assembly_programs_, | ||
| 36 | const std::array<const Shader::Info*, 5>& infos) | 37 | const std::array<const Shader::Info*, 5>& infos) |
| 37 | : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, | 38 | : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, |
| 38 | gpu_memory{gpu_memory_}, maxwell3d{maxwell3d_}, program_manager{program_manager_}, | 39 | gpu_memory{gpu_memory_}, maxwell3d{maxwell3d_}, program_manager{program_manager_}, |
| 39 | state_tracker{state_tracker_}, program{std::move(program_)} { | 40 | state_tracker{state_tracker_}, program{std::move(program_)}, assembly_programs{std::move( |
| 41 | assembly_programs_)} { | ||
| 40 | std::ranges::transform(infos, stage_infos.begin(), | 42 | std::ranges::transform(infos, stage_infos.begin(), |
| 41 | [](const Shader::Info* info) { return info ? *info : Shader::Info{}; }); | 43 | [](const Shader::Info* info) { return info ? *info : Shader::Info{}; }); |
| 42 | 44 | ||
| @@ -290,7 +292,16 @@ void GraphicsProgram::Configure(bool is_indexed) { | |||
| 290 | texture_cache.UpdateRenderTargets(false); | 292 | texture_cache.UpdateRenderTargets(false); |
| 291 | 293 | ||
| 292 | state_tracker.BindFramebuffer(texture_cache.GetFramebuffer()->Handle()); | 294 | state_tracker.BindFramebuffer(texture_cache.GetFramebuffer()->Handle()); |
| 293 | program_manager.BindProgram(program.handle); | 295 | if (assembly_programs[0].handle != 0) { |
| 296 | // TODO: State track this | ||
| 297 | glEnable(GL_VERTEX_PROGRAM_NV); | ||
| 298 | glEnable(GL_FRAGMENT_PROGRAM_NV); | ||
| 299 | glBindProgramARB(GL_VERTEX_PROGRAM_NV, assembly_programs[0].handle); | ||
| 300 | glBindProgramARB(GL_FRAGMENT_PROGRAM_NV, assembly_programs[4].handle); | ||
| 301 | program_manager.BindProgram(0); | ||
| 302 | } else { | ||
| 303 | program_manager.BindProgram(program.handle); | ||
| 304 | } | ||
| 294 | } | 305 | } |
| 295 | 306 | ||
| 296 | } // namespace OpenGL | 307 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/gl_graphics_program.h b/src/video_core/renderer_opengl/gl_graphics_program.h index 5adf3f41e..58aa4b0bc 100644 --- a/src/video_core/renderer_opengl/gl_graphics_program.h +++ b/src/video_core/renderer_opengl/gl_graphics_program.h | |||
| @@ -73,7 +73,9 @@ public: | |||
| 73 | Tegra::MemoryManager& gpu_memory_, | 73 | Tegra::MemoryManager& gpu_memory_, |
| 74 | Tegra::Engines::Maxwell3D& maxwell3d_, | 74 | Tegra::Engines::Maxwell3D& maxwell3d_, |
| 75 | ProgramManager& program_manager_, StateTracker& state_tracker_, | 75 | ProgramManager& program_manager_, StateTracker& state_tracker_, |
| 76 | OGLProgram program_, const std::array<const Shader::Info*, 5>& infos); | 76 | OGLProgram program_, |
| 77 | std::array<OGLAssemblyProgram, 5> assembly_programs_, | ||
| 78 | const std::array<const Shader::Info*, 5>& infos); | ||
| 77 | 79 | ||
| 78 | void Configure(bool is_indexed); | 80 | void Configure(bool is_indexed); |
| 79 | 81 | ||
| @@ -86,6 +88,8 @@ private: | |||
| 86 | StateTracker& state_tracker; | 88 | StateTracker& state_tracker; |
| 87 | 89 | ||
| 88 | OGLProgram program; | 90 | OGLProgram program; |
| 91 | std::array<OGLAssemblyProgram, 5> assembly_programs; | ||
| 92 | |||
| 89 | std::array<Shader::Info, 5> stage_infos{}; | 93 | std::array<Shader::Info, 5> stage_infos{}; |
| 90 | std::array<u32, 5> base_uniform_bindings{}; | 94 | std::array<u32, 5> base_uniform_bindings{}; |
| 91 | std::array<u32, 5> base_storage_bindings{}; | 95 | std::array<u32, 5> base_storage_bindings{}; |
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index d9f0bca78..c10ea2f60 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -185,6 +185,23 @@ GLenum Stage(size_t stage_index) { | |||
| 185 | UNREACHABLE_MSG("{}", stage_index); | 185 | UNREACHABLE_MSG("{}", stage_index); |
| 186 | return GL_NONE; | 186 | return GL_NONE; |
| 187 | } | 187 | } |
| 188 | |||
| 189 | GLenum AssemblyStage(size_t stage_index) { | ||
| 190 | switch (stage_index) { | ||
| 191 | case 0: | ||
| 192 | return GL_VERTEX_PROGRAM_NV; | ||
| 193 | case 1: | ||
| 194 | return GL_TESS_CONTROL_PROGRAM_NV; | ||
| 195 | case 2: | ||
| 196 | return GL_TESS_EVALUATION_PROGRAM_NV; | ||
| 197 | case 3: | ||
| 198 | return GL_GEOMETRY_PROGRAM_NV; | ||
| 199 | case 4: | ||
| 200 | return GL_FRAGMENT_PROGRAM_NV; | ||
| 201 | } | ||
| 202 | UNREACHABLE_MSG("{}", stage_index); | ||
| 203 | return GL_NONE; | ||
| 204 | } | ||
| 188 | } // Anonymous namespace | 205 | } // Anonymous namespace |
| 189 | 206 | ||
| 190 | ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindow& emu_window_, | 207 | ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindow& emu_window_, |
| @@ -269,10 +286,12 @@ std::unique_ptr<GraphicsProgram> ShaderCache::CreateGraphicsProgram( | |||
| 269 | } | 286 | } |
| 270 | std::array<const Shader::Info*, Maxwell::MaxShaderStage> infos{}; | 287 | std::array<const Shader::Info*, Maxwell::MaxShaderStage> infos{}; |
| 271 | 288 | ||
| 272 | OGLProgram gl_program; | 289 | OGLProgram source_program; |
| 273 | gl_program.handle = glCreateProgram(); | 290 | std::array<OGLAssemblyProgram, 5> assembly_programs; |
| 274 | |||
| 275 | Shader::Backend::Bindings binding; | 291 | Shader::Backend::Bindings binding; |
| 292 | if (!device.UseAssemblyShaders()) { | ||
| 293 | source_program.handle = glCreateProgram(); | ||
| 294 | } | ||
| 276 | for (size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { | 295 | for (size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { |
| 277 | if (key.unique_hashes[index] == 0) { | 296 | if (key.unique_hashes[index] == 0) { |
| 278 | continue; | 297 | continue; |
| @@ -282,15 +301,20 @@ std::unique_ptr<GraphicsProgram> ShaderCache::CreateGraphicsProgram( | |||
| 282 | Shader::IR::Program& program{programs[index]}; | 301 | Shader::IR::Program& program{programs[index]}; |
| 283 | const size_t stage_index{index - 1}; | 302 | const size_t stage_index{index - 1}; |
| 284 | infos[stage_index] = &program.info; | 303 | infos[stage_index] = &program.info; |
| 285 | 304 | if (device.UseAssemblyShaders()) { | |
| 286 | const std::vector<u32> code{EmitSPIRV(profile, program, binding)}; | 305 | const std::string code{EmitGLASM(profile, program)}; |
| 287 | AddShader(Stage(stage_index), gl_program.handle, code); | 306 | assembly_programs[stage_index] = CompileProgram(code, AssemblyStage(stage_index)); |
| 307 | } else { | ||
| 308 | const std::vector<u32> code{EmitSPIRV(profile, program, binding)}; | ||
| 309 | AddShader(Stage(stage_index), source_program.handle, code); | ||
| 310 | } | ||
| 288 | } | 311 | } |
| 289 | LinkProgram(gl_program.handle); | 312 | if (!device.UseAssemblyShaders()) { |
| 290 | 313 | LinkProgram(source_program.handle); | |
| 291 | return std::make_unique<GraphicsProgram>(texture_cache, buffer_cache, gpu_memory, maxwell3d, | 314 | } |
| 292 | program_manager, state_tracker, std::move(gl_program), | 315 | return std::make_unique<GraphicsProgram>( |
| 293 | infos); | 316 | texture_cache, buffer_cache, gpu_memory, maxwell3d, program_manager, state_tracker, |
| 317 | std::move(source_program), std::move(assembly_programs), infos); | ||
| 294 | } | 318 | } |
| 295 | 319 | ||
| 296 | std::unique_ptr<ComputeProgram> ShaderCache::CreateComputeProgram( | 320 | std::unique_ptr<ComputeProgram> ShaderCache::CreateComputeProgram( |