summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2018-04-15 09:32:12 +0200
committerbunnei <bunneidev@gmail.com>2018-04-15 17:50:10 +0200
commit73d9c494ea6ae0a8076f679506ff07e2fe014826 (patch)
treef283b7d9b9014488dabd45e97f5687c2d67e842d /src/video_core/renderer_opengl/gl_shader_decompiler.cpp
parentMerge pull request #328 from Subv/constbuffers (diff)
downloadyuzu-73d9c494ea6ae0a8076f679506ff07e2fe014826.tar
yuzu-73d9c494ea6ae0a8076f679506ff07e2fe014826.tar.gz
yuzu-73d9c494ea6ae0a8076f679506ff07e2fe014826.tar.bz2
yuzu-73d9c494ea6ae0a8076f679506ff07e2fe014826.tar.lz
yuzu-73d9c494ea6ae0a8076f679506ff07e2fe014826.tar.xz
yuzu-73d9c494ea6ae0a8076f679506ff07e2fe014826.tar.zst
yuzu-73d9c494ea6ae0a8076f679506ff07e2fe014826.zip
Diffstat (limited to 'src/video_core/renderer_opengl/gl_shader_decompiler.cpp')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp40
1 files changed, 32 insertions, 8 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 1290fa4cd..9cf2c6a0c 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -140,6 +140,11 @@ public:
return declarations.GetResult() + shader.GetResult();
}
+ /// Returns entries in the shader that are useful for external functions
+ ShaderEntries GetEntries() const {
+ return {GetConstBuffersDeclarations()};
+ }
+
private:
/// Gets the Subroutine object corresponding to the specified address.
const Subroutine& GetSubroutine(u32 begin, u32 end) const {
@@ -186,10 +191,9 @@ private:
}
/// Generates code representing a uniform (C buffer) register.
- std::string GetUniform(const Uniform& reg) const {
- std::string index = std::to_string(reg.index);
- return "uniform_" + index + "[" + std::to_string(reg.offset >> 2) + "][" +
- std::to_string(reg.offset & 3) + "]";
+ std::string GetUniform(const Uniform& reg) {
+ declr_const_buffers[reg.index].MarkAsUsed(reg.index, reg.offset);
+ return 'c' + std::to_string(reg.index) + '[' + std::to_string(reg.offset) + ']';
}
/**
@@ -439,6 +443,14 @@ private:
GenerateDeclarations();
}
+ /// Returns a list of constant buffer declarations
+ std::vector<ConstBufferEntry> GetConstBuffersDeclarations() const {
+ std::vector<ConstBufferEntry> result;
+ std::copy_if(declr_const_buffers.begin(), declr_const_buffers.end(),
+ std::back_inserter(result), [](const auto& entry) { return entry.IsUsed(); });
+ return result;
+ }
+
/// Add declarations for registers
void GenerateDeclarations() {
for (const auto& reg : declr_register) {
@@ -463,6 +475,17 @@ private:
") out vec4 " + GetOutputAttribute(index) + ";");
}
declarations.AddLine("");
+
+ unsigned const_buffer_layout = 0;
+ for (const auto& entry : GetConstBuffersDeclarations()) {
+ declarations.AddLine("layout(std430, binding = " + std::to_string(const_buffer_layout) +
+ ") buffer c" + std::to_string(entry.GetIndex()) + "_buffer");
+ declarations.AddLine("{");
+ declarations.AddLine(" float c" + std::to_string(entry.GetIndex()) + "[];");
+ declarations.AddLine("};");
+ declarations.AddLine("");
+ ++const_buffer_layout;
+ }
}
private:
@@ -478,18 +501,19 @@ private:
std::set<std::string> declr_register;
std::set<Attribute::Index> declr_input_attribute;
std::set<Attribute::Index> declr_output_attribute;
-}; // namespace Decompiler
+ std::array<ConstBufferEntry, Maxwell3D::Regs::MaxConstBuffers> declr_const_buffers;
+};
std::string GetCommonDeclarations() {
return "bool exec_shader();";
}
-boost::optional<std::string> DecompileProgram(const ProgramCode& program_code, u32 main_offset,
- Maxwell3D::Regs::ShaderStage stage) {
+boost::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code, u32 main_offset,
+ Maxwell3D::Regs::ShaderStage stage) {
try {
auto subroutines = ControlFlowAnalyzer(program_code, main_offset).GetSubroutines();
GLSLGenerator generator(subroutines, program_code, main_offset, stage);
- return generator.GetShaderCode();
+ return ProgramResult{generator.GetShaderCode(), generator.GetEntries()};
} catch (const DecompileFail& exception) {
LOG_ERROR(HW_GPU, "Shader decompilation failed: %s", exception.what());
}