opengl: Initial (broken) support to GLASM shaders
This commit is contained in:
parent
776ab3ea12
commit
258f2dec1b
|
@ -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());
|
||||
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;
|
||||
|
||||
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), gl_program.handle, code);
|
||||
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