forked from suyu/suyu
opengl: Initial (broken) support to GLASM shaders
This commit is contained in:
parent
776ab3ea12
commit
258f2dec1b
3 changed files with 53 additions and 14 deletions
|
@ -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());
|
||||||
|
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);
|
program_manager.BindProgram(program.handle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace OpenGL
|
} // namespace OpenGL
|
||||||
|
|
|
@ -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{};
|
||||||
|
|
|
@ -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::string code{EmitGLASM(profile, program)};
|
||||||
|
assembly_programs[stage_index] = CompileProgram(code, AssemblyStage(stage_index));
|
||||||
|
} else {
|
||||||
const std::vector<u32> code{EmitSPIRV(profile, program, binding)};
|
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);
|
}
|
||||||
|
if (!device.UseAssemblyShaders()) {
|
||||||
return std::make_unique<GraphicsProgram>(texture_cache, buffer_cache, gpu_memory, maxwell3d,
|
LinkProgram(source_program.handle);
|
||||||
program_manager, state_tracker, std::move(gl_program),
|
}
|
||||||
infos);
|
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(
|
||||||
|
|
Loading…
Reference in a new issue