summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_program.cpp15
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_program.h6
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp46
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
189GLenum 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
190ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindow& emu_window_, 207ShaderCache::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
296std::unique_ptr<ComputeProgram> ShaderCache::CreateComputeProgram( 320std::unique_ptr<ComputeProgram> ShaderCache::CreateComputeProgram(