summaryrefslogtreecommitdiffstats
path: root/src/video_core
diff options
context:
space:
mode:
Diffstat (limited to '')
-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
Tegra::Engines::Maxwell3D& maxwell3d_,
ProgramManager& program_manager_, StateTracker& state_tracker_,
OGLProgram program_,
+ std::array<OGLAssemblyProgram, 5> assembly_programs_,
const std::array<const Shader::Info*, 5>& infos)
: 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_)} {
+ state_tracker{state_tracker_}, program{std::move(program_)}, assembly_programs{std::move(
+ assembly_programs_)} {
std::ranges::transform(infos, stage_infos.begin(),
[](const Shader::Info* info) { return info ? *info : Shader::Info{}; });
@@ -290,7 +292,16 @@ void GraphicsProgram::Configure(bool is_indexed) {
texture_cache.UpdateRenderTargets(false);
state_tracker.BindFramebuffer(texture_cache.GetFramebuffer()->Handle());
- program_manager.BindProgram(program.handle);
+ if (assembly_programs[0].handle != 0) {
+ // TODO: State track this
+ glEnable(GL_VERTEX_PROGRAM_NV);
+ glEnable(GL_FRAGMENT_PROGRAM_NV);
+ glBindProgramARB(GL_VERTEX_PROGRAM_NV, assembly_programs[0].handle);
+ glBindProgramARB(GL_FRAGMENT_PROGRAM_NV, assembly_programs[4].handle);
+ program_manager.BindProgram(0);
+ } else {
+ program_manager.BindProgram(program.handle);
+ }
}
} // 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:
Tegra::MemoryManager& gpu_memory_,
Tegra::Engines::Maxwell3D& maxwell3d_,
ProgramManager& program_manager_, StateTracker& state_tracker_,
- OGLProgram program_, const std::array<const Shader::Info*, 5>& infos);
+ OGLProgram program_,
+ std::array<OGLAssemblyProgram, 5> assembly_programs_,
+ const std::array<const Shader::Info*, 5>& infos);
void Configure(bool is_indexed);
@@ -86,6 +88,8 @@ private:
StateTracker& state_tracker;
OGLProgram program;
+ std::array<OGLAssemblyProgram, 5> assembly_programs;
+
std::array<Shader::Info, 5> stage_infos{};
std::array<u32, 5> base_uniform_bindings{};
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) {
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;
+}
} // Anonymous namespace
ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindow& emu_window_,
@@ -269,10 +286,12 @@ std::unique_ptr<GraphicsProgram> ShaderCache::CreateGraphicsProgram(
}
std::array<const Shader::Info*, Maxwell::MaxShaderStage> infos{};
- OGLProgram gl_program;
- gl_program.handle = glCreateProgram();
-
+ OGLProgram source_program;
+ std::array<OGLAssemblyProgram, 5> assembly_programs;
Shader::Backend::Bindings binding;
+ if (!device.UseAssemblyShaders()) {
+ source_program.handle = glCreateProgram();
+ }
for (size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) {
if (key.unique_hashes[index] == 0) {
continue;
@@ -282,15 +301,20 @@ std::unique_ptr<GraphicsProgram> ShaderCache::CreateGraphicsProgram(
Shader::IR::Program& program{programs[index]};
const size_t stage_index{index - 1};
infos[stage_index] = &program.info;
-
- const std::vector<u32> code{EmitSPIRV(profile, program, binding)};
- AddShader(Stage(stage_index), gl_program.handle, code);
+ if (device.UseAssemblyShaders()) {
+ const std::string code{EmitGLASM(profile, program)};
+ assembly_programs[stage_index] = CompileProgram(code, AssemblyStage(stage_index));
+ } else {
+ const std::vector<u32> code{EmitSPIRV(profile, program, binding)};
+ AddShader(Stage(stage_index), source_program.handle, code);
+ }
}
- LinkProgram(gl_program.handle);
-
- return std::make_unique<GraphicsProgram>(texture_cache, buffer_cache, gpu_memory, maxwell3d,
- program_manager, state_tracker, std::move(gl_program),
- infos);
+ if (!device.UseAssemblyShaders()) {
+ LinkProgram(source_program.handle);
+ }
+ return std::make_unique<GraphicsProgram>(
+ texture_cache, buffer_cache, gpu_memory, maxwell3d, program_manager, state_tracker,
+ std::move(source_program), std::move(assembly_programs), infos);
}
std::unique_ptr<ComputeProgram> ShaderCache::CreateComputeProgram(