opengl: Initial (broken) support to GLASM shaders
This commit is contained in:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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{};
 | 
			
		||||
 
 | 
			
		||||
@@ -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(
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user