Просмотр исходного кода

opengl: Initial (broken) support to GLASM shaders

ReinUsesLisp 5 лет назад
Родитель
Сommit
258f2dec1b

+ 13 - 2
src/video_core/renderer_opengl/gl_graphics_program.cpp

@@ -33,10 +33,12 @@ GraphicsProgram::GraphicsProgram(TextureCache& texture_cache_, BufferCache& buff
                                  Tegra::Engines::Maxwell3D& maxwell3d_,
                                  Tegra::Engines::Maxwell3D& maxwell3d_,
                                  ProgramManager& program_manager_, StateTracker& state_tracker_,
                                  ProgramManager& program_manager_, StateTracker& state_tracker_,
                                  OGLProgram program_,
                                  OGLProgram program_,
+                                 std::array<OGLAssemblyProgram, 5> assembly_programs_,
                                  const std::array<const Shader::Info*, 5>& infos)
                                  const std::array<const Shader::Info*, 5>& infos)
     : texture_cache{texture_cache_}, buffer_cache{buffer_cache_},
     : texture_cache{texture_cache_}, buffer_cache{buffer_cache_},
       gpu_memory{gpu_memory_}, maxwell3d{maxwell3d_}, program_manager{program_manager_},
       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(),
     std::ranges::transform(infos, stage_infos.begin(),
                            [](const Shader::Info* info) { return info ? *info : Shader::Info{}; });
                            [](const Shader::Info* info) { return info ? *info : Shader::Info{}; });
 
 
@@ -290,7 +292,16 @@ void GraphicsProgram::Configure(bool is_indexed) {
     texture_cache.UpdateRenderTargets(false);
     texture_cache.UpdateRenderTargets(false);
 
 
     state_tracker.BindFramebuffer(texture_cache.GetFramebuffer()->Handle());
     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
 } // namespace OpenGL

+ 5 - 1
src/video_core/renderer_opengl/gl_graphics_program.h

@@ -73,7 +73,9 @@ public:
                              Tegra::MemoryManager& gpu_memory_,
                              Tegra::MemoryManager& gpu_memory_,
                              Tegra::Engines::Maxwell3D& maxwell3d_,
                              Tegra::Engines::Maxwell3D& maxwell3d_,
                              ProgramManager& program_manager_, StateTracker& state_tracker_,
                              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);
     void Configure(bool is_indexed);
 
 
@@ -86,6 +88,8 @@ private:
     StateTracker& state_tracker;
     StateTracker& state_tracker;
 
 
     OGLProgram program;
     OGLProgram program;
+    std::array<OGLAssemblyProgram, 5> assembly_programs;
+
     std::array<Shader::Info, 5> stage_infos{};
     std::array<Shader::Info, 5> stage_infos{};
     std::array<u32, 5> base_uniform_bindings{};
     std::array<u32, 5> base_uniform_bindings{};
     std::array<u32, 5> base_storage_bindings{};
     std::array<u32, 5> base_storage_bindings{};

+ 35 - 11
src/video_core/renderer_opengl/gl_shader_cache.cpp

@@ -185,6 +185,23 @@ GLenum Stage(size_t stage_index) {
     UNREACHABLE_MSG("{}", stage_index);
     UNREACHABLE_MSG("{}", stage_index);
     return GL_NONE;
     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
 } // Anonymous namespace
 
 
 ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindow& emu_window_,
 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{};
     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;
     Shader::Backend::Bindings binding;
+    if (!device.UseAssemblyShaders()) {
+        source_program.handle = glCreateProgram();
+    }
     for (size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) {
     for (size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) {
         if (key.unique_hashes[index] == 0) {
         if (key.unique_hashes[index] == 0) {
             continue;
             continue;
@@ -282,15 +301,20 @@ std::unique_ptr<GraphicsProgram> ShaderCache::CreateGraphicsProgram(
         Shader::IR::Program& program{programs[index]};
         Shader::IR::Program& program{programs[index]};
         const size_t stage_index{index - 1};
         const size_t stage_index{index - 1};
         infos[stage_index] = &program.info;
         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(
 std::unique_ptr<ComputeProgram> ShaderCache::CreateComputeProgram(