opengl: Initial (broken) support to GLASM shaders

This commit is contained in:
ReinUsesLisp 2021-05-15 18:19:08 -03:00 committed by ameerj
parent 776ab3ea12
commit 258f2dec1b
3 changed files with 53 additions and 14 deletions

View File

@ -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

View File

@ -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{};

View File

@ -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; OGLProgram source_program;
gl_program.handle = glCreateProgram(); 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;
if (device.UseAssemblyShaders()) {
const std::vector<u32> code{EmitSPIRV(profile, program, binding)}; const std::string code{EmitGLASM(profile, program)};
AddShader(Stage(stage_index), gl_program.handle, code); 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); 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(gl_program), return std::make_unique<GraphicsProgram>(
infos); 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(