summaryrefslogtreecommitdiff
path: root/src/video_core
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-04-10 18:03:52 -0300
committerGravatar ReinUsesLisp2019-04-14 05:13:19 -0300
commitf15c59a164a7c4deafb77e9fc698cdf9a08691ce (patch)
treef232add61779165ba2d03773384b9df86c2f7af0 /src/video_core
parentgl_device: Implement interface and add uniform offset alignment (diff)
downloadyuzu-f15c59a164a7c4deafb77e9fc698cdf9a08691ce.tar.gz
yuzu-f15c59a164a7c4deafb77e9fc698cdf9a08691ce.tar.xz
yuzu-f15c59a164a7c4deafb77e9fc698cdf9a08691ce.zip
gl_shader_decompiler: Use variable AOFFI on supported hardware
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/renderer_opengl/gl_device.cpp24
-rw-r--r--src/video_core/renderer_opengl/gl_device.h9
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp4
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h4
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp54
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.h8
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp18
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.h8
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.cpp15
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.h29
10 files changed, 102 insertions, 71 deletions
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp
index b7ca3dca4..b6d9e0ddb 100644
--- a/src/video_core/renderer_opengl/gl_device.cpp
+++ b/src/video_core/renderer_opengl/gl_device.cpp
@@ -5,6 +5,7 @@
5#include <cstddef> 5#include <cstddef>
6#include <glad/glad.h> 6#include <glad/glad.h>
7 7
8#include "common/logging/log.h"
8#include "video_core/renderer_opengl/gl_device.h" 9#include "video_core/renderer_opengl/gl_device.h"
9 10
10namespace OpenGL { 11namespace OpenGL {
@@ -18,10 +19,27 @@ T GetInteger(GLenum pname) {
18} 19}
19} // Anonymous namespace 20} // Anonymous namespace
20 21
21Device::Device() = default; 22Device::Device() {
22
23void Device::Initialize() {
24 uniform_buffer_alignment = GetInteger<std::size_t>(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT); 23 uniform_buffer_alignment = GetInteger<std::size_t>(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT);
24 has_variable_aoffi = TestVariableAoffi();
25}
26
27bool Device::TestVariableAoffi() {
28 const GLchar* AOFFI_TEST = R"(#version 430 core
29uniform sampler2D tex;
30uniform ivec2 variable_offset;
31void main() {
32 gl_Position = textureOffset(tex, vec2(0), variable_offset);
33}
34)";
35 const GLuint shader{glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &AOFFI_TEST)};
36 GLint link_status{};
37 glGetProgramiv(shader, GL_LINK_STATUS, &link_status);
38 glDeleteProgram(shader);
39
40 const bool supported{link_status == GL_TRUE};
41 LOG_INFO(Render_OpenGL, "Renderer_VariableAOFFI: {}", supported);
42 return supported;
25} 43}
26 44
27} // namespace OpenGL 45} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_device.h b/src/video_core/renderer_opengl/gl_device.h
index 3085e04ad..78ff5ee58 100644
--- a/src/video_core/renderer_opengl/gl_device.h
+++ b/src/video_core/renderer_opengl/gl_device.h
@@ -12,14 +12,19 @@ class Device {
12public: 12public:
13 Device(); 13 Device();
14 14
15 void Initialize();
16
17 std::size_t GetUniformBufferAlignment() const { 15 std::size_t GetUniformBufferAlignment() const {
18 return uniform_buffer_alignment; 16 return uniform_buffer_alignment;
19 } 17 }
20 18
19 bool HasVariableAoffi() const {
20 return has_variable_aoffi;
21 }
22
21private: 23private:
24 static bool TestVariableAoffi();
25
22 std::size_t uniform_buffer_alignment{}; 26 std::size_t uniform_buffer_alignment{};
27 bool has_variable_aoffi{};
23}; 28};
24 29
25} // namespace OpenGL 30} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 2d638aa4e..ff5d05ced 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -99,7 +99,7 @@ struct FramebufferCacheKey {
99}; 99};
100 100
101RasterizerOpenGL::RasterizerOpenGL(Core::System& system, ScreenInfo& info) 101RasterizerOpenGL::RasterizerOpenGL(Core::System& system, ScreenInfo& info)
102 : res_cache{*this}, shader_cache{*this, system}, global_cache{*this}, system{system}, 102 : res_cache{*this}, shader_cache{*this, system, device}, global_cache{*this}, system{system},
103 screen_info{info}, buffer_cache(*this, STREAM_BUFFER_SIZE) { 103 screen_info{info}, buffer_cache(*this, STREAM_BUFFER_SIZE) {
104 // Create sampler objects 104 // Create sampler objects
105 for (std::size_t i = 0; i < texture_samplers.size(); ++i) { 105 for (std::size_t i = 0; i < texture_samplers.size(); ++i) {
@@ -107,8 +107,6 @@ RasterizerOpenGL::RasterizerOpenGL(Core::System& system, ScreenInfo& info)
107 state.texture_units[i].sampler = texture_samplers[i].sampler.handle; 107 state.texture_units[i].sampler = texture_samplers[i].sampler.handle;
108 } 108 }
109 109
110 device.Initialize();
111
112 OpenGLState::ApplyDefaultState(); 110 OpenGLState::ApplyDefaultState();
113 111
114 shader_program_manager = std::make_unique<GLShader::ProgramManager>(); 112 shader_program_manager = std::make_unique<GLShader::ProgramManager>();
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 688ba0ad2..cbcce8597 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -204,6 +204,7 @@ private:
204 /// but are needed for correct emulation 204 /// but are needed for correct emulation
205 void CheckExtensions(); 205 void CheckExtensions();
206 206
207 const Device device;
207 OpenGLState state; 208 OpenGLState state;
208 209
209 RasterizerCacheOpenGL res_cache; 210 RasterizerCacheOpenGL res_cache;
@@ -211,11 +212,8 @@ private:
211 GlobalRegionCacheOpenGL global_cache; 212 GlobalRegionCacheOpenGL global_cache;
212 213
213 Core::System& system; 214 Core::System& system;
214
215 ScreenInfo& screen_info; 215 ScreenInfo& screen_info;
216 216
217 Device device;
218
219 std::unique_ptr<GLShader::ProgramManager> shader_program_manager; 217 std::unique_ptr<GLShader::ProgramManager> shader_program_manager;
220 std::map<std::array<Tegra::Engines::Maxwell3D::Regs::VertexAttribute, 218 std::map<std::array<Tegra::Engines::Maxwell3D::Regs::VertexAttribute,
221 Tegra::Engines::Maxwell3D::Regs::NumVertexAttributes>, 219 Tegra::Engines::Maxwell3D::Regs::NumVertexAttributes>,
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index 99f67494c..4efeb9c3e 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -134,8 +134,8 @@ u64 GetUniqueIdentifier(Maxwell::ShaderProgram program_type, const ProgramCode&
134} 134}
135 135
136/// Creates an unspecialized program from code streams 136/// Creates an unspecialized program from code streams
137GLShader::ProgramResult CreateProgram(Maxwell::ShaderProgram program_type, ProgramCode program_code, 137GLShader::ProgramResult CreateProgram(const Device& device, Maxwell::ShaderProgram program_type,
138 ProgramCode program_code_b) { 138 ProgramCode program_code, ProgramCode program_code_b) {
139 GLShader::ShaderSetup setup(program_code); 139 GLShader::ShaderSetup setup(program_code);
140 if (program_type == Maxwell::ShaderProgram::VertexA) { 140 if (program_type == Maxwell::ShaderProgram::VertexA) {
141 // VertexB is always enabled, so when VertexA is enabled, we have two vertex shaders. 141 // VertexB is always enabled, so when VertexA is enabled, we have two vertex shaders.
@@ -149,11 +149,11 @@ GLShader::ProgramResult CreateProgram(Maxwell::ShaderProgram program_type, Progr
149 switch (program_type) { 149 switch (program_type) {
150 case Maxwell::ShaderProgram::VertexA: 150 case Maxwell::ShaderProgram::VertexA:
151 case Maxwell::ShaderProgram::VertexB: 151 case Maxwell::ShaderProgram::VertexB:
152 return GLShader::GenerateVertexShader(setup); 152 return GLShader::GenerateVertexShader(device, setup);
153 case Maxwell::ShaderProgram::Geometry: 153 case Maxwell::ShaderProgram::Geometry:
154 return GLShader::GenerateGeometryShader(setup); 154 return GLShader::GenerateGeometryShader(device, setup);
155 case Maxwell::ShaderProgram::Fragment: 155 case Maxwell::ShaderProgram::Fragment:
156 return GLShader::GenerateFragmentShader(setup); 156 return GLShader::GenerateFragmentShader(device, setup);
157 default: 157 default:
158 LOG_CRITICAL(HW_GPU, "Unimplemented program_type={}", static_cast<u32>(program_type)); 158 LOG_CRITICAL(HW_GPU, "Unimplemented program_type={}", static_cast<u32>(program_type));
159 UNREACHABLE(); 159 UNREACHABLE();
@@ -212,22 +212,20 @@ std::set<GLenum> GetSupportedFormats() {
212 return supported_formats; 212 return supported_formats;
213} 213}
214 214
215} // namespace 215} // Anonymous namespace
216 216
217CachedShader::CachedShader(VAddr cpu_addr, u64 unique_identifier, 217CachedShader::CachedShader(const Device& device, VAddr cpu_addr, u64 unique_identifier,
218 Maxwell::ShaderProgram program_type, ShaderDiskCacheOpenGL& disk_cache, 218 Maxwell::ShaderProgram program_type, ShaderDiskCacheOpenGL& disk_cache,
219 const PrecompiledPrograms& precompiled_programs, 219 const PrecompiledPrograms& precompiled_programs,
220 ProgramCode&& program_code, ProgramCode&& program_code_b, u8* host_ptr) 220 ProgramCode&& program_code, ProgramCode&& program_code_b, u8* host_ptr)
221 : RasterizerCacheObject{host_ptr}, host_ptr{host_ptr}, cpu_addr{cpu_addr}, 221 : RasterizerCacheObject{host_ptr}, host_ptr{host_ptr}, cpu_addr{cpu_addr},
222 unique_identifier{unique_identifier}, program_type{program_type}, disk_cache{disk_cache}, 222 unique_identifier{unique_identifier}, program_type{program_type}, disk_cache{disk_cache},
223 precompiled_programs{precompiled_programs} { 223 precompiled_programs{precompiled_programs} {
224 224 const std::size_t code_size{CalculateProgramSize(program_code)};
225 const std::size_t code_size = CalculateProgramSize(program_code); 225 const std::size_t code_size_b{program_code_b.empty() ? 0
226 const std::size_t code_size_b = 226 : CalculateProgramSize(program_code_b)};
227 program_code_b.empty() ? 0 : CalculateProgramSize(program_code_b); 227 GLShader::ProgramResult program_result{
228 228 CreateProgram(device, program_type, program_code, program_code_b)};
229 GLShader::ProgramResult program_result =
230 CreateProgram(program_type, program_code, program_code_b);
231 if (program_result.first.empty()) { 229 if (program_result.first.empty()) {
232 // TODO(Rodrigo): Unimplemented shader stages hit here, avoid using these for now 230 // TODO(Rodrigo): Unimplemented shader stages hit here, avoid using these for now
233 return; 231 return;
@@ -251,7 +249,6 @@ CachedShader::CachedShader(VAddr cpu_addr, u64 unique_identifier,
251 : RasterizerCacheObject{host_ptr}, cpu_addr{cpu_addr}, unique_identifier{unique_identifier}, 249 : RasterizerCacheObject{host_ptr}, cpu_addr{cpu_addr}, unique_identifier{unique_identifier},
252 program_type{program_type}, disk_cache{disk_cache}, precompiled_programs{ 250 program_type{program_type}, disk_cache{disk_cache}, precompiled_programs{
253 precompiled_programs} { 251 precompiled_programs} {
254
255 code = std::move(result.first); 252 code = std::move(result.first);
256 entries = result.second; 253 entries = result.second;
257 shader_length = entries.shader_length; 254 shader_length = entries.shader_length;
@@ -344,8 +341,9 @@ ShaderDiskCacheUsage CachedShader::GetUsage(GLenum primitive_mode,
344 return {unique_identifier, base_bindings, primitive_mode}; 341 return {unique_identifier, base_bindings, primitive_mode};
345} 342}
346 343
347ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system) 344ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system,
348 : RasterizerCache{rasterizer}, disk_cache{system} {} 345 const Device& device)
346 : RasterizerCache{rasterizer}, disk_cache{system}, device{device} {}
349 347
350void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading, 348void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading,
351 const VideoCore::DiskResourceLoadCallback& callback) { 349 const VideoCore::DiskResourceLoadCallback& callback) {
@@ -439,17 +437,18 @@ std::unordered_map<u64, UnspecializedShader> ShaderCacheOpenGL::GenerateUnspecia
439 const std::unordered_map<u64, ShaderDiskCacheDecompiled>& decompiled) { 437 const std::unordered_map<u64, ShaderDiskCacheDecompiled>& decompiled) {
440 std::unordered_map<u64, UnspecializedShader> unspecialized; 438 std::unordered_map<u64, UnspecializedShader> unspecialized;
441 439
442 if (callback) 440 if (callback) {
443 callback(VideoCore::LoadCallbackStage::Decompile, 0, raws.size()); 441 callback(VideoCore::LoadCallbackStage::Decompile, 0, raws.size());
442 }
444 443
445 for (std::size_t i = 0; i < raws.size(); ++i) { 444 for (std::size_t i = 0; i < raws.size(); ++i) {
446 if (stop_loading) 445 if (stop_loading) {
447 return {}; 446 return {};
448 447 }
449 const auto& raw{raws[i]}; 448 const auto& raw{raws[i]};
450 const u64 unique_identifier = raw.GetUniqueIdentifier(); 449 const u64 unique_identifier{raw.GetUniqueIdentifier()};
451 const u64 calculated_hash = 450 const u64 calculated_hash{
452 GetUniqueIdentifier(raw.GetProgramType(), raw.GetProgramCode(), raw.GetProgramCodeB()); 451 GetUniqueIdentifier(raw.GetProgramType(), raw.GetProgramCode(), raw.GetProgramCodeB())};
453 if (unique_identifier != calculated_hash) { 452 if (unique_identifier != calculated_hash) {
454 LOG_ERROR( 453 LOG_ERROR(
455 Render_OpenGL, 454 Render_OpenGL,
@@ -466,8 +465,8 @@ std::unordered_map<u64, UnspecializedShader> ShaderCacheOpenGL::GenerateUnspecia
466 result = {stored_decompiled.code, stored_decompiled.entries}; 465 result = {stored_decompiled.code, stored_decompiled.entries};
467 } else { 466 } else {
468 // Otherwise decompile the shader at boot and save the result to the decompiled file 467 // Otherwise decompile the shader at boot and save the result to the decompiled file
469 result = 468 result = CreateProgram(device, raw.GetProgramType(), raw.GetProgramCode(),
470 CreateProgram(raw.GetProgramType(), raw.GetProgramCode(), raw.GetProgramCodeB()); 469 raw.GetProgramCodeB());
471 disk_cache.SaveDecompiled(unique_identifier, result.first, result.second); 470 disk_cache.SaveDecompiled(unique_identifier, result.first, result.second);
472 } 471 }
473 472
@@ -477,8 +476,9 @@ std::unordered_map<u64, UnspecializedShader> ShaderCacheOpenGL::GenerateUnspecia
477 {raw.GetUniqueIdentifier(), 476 {raw.GetUniqueIdentifier(),
478 {std::move(result.first), std::move(result.second), raw.GetProgramType()}}); 477 {std::move(result.first), std::move(result.second), raw.GetProgramType()}});
479 478
480 if (callback) 479 if (callback) {
481 callback(VideoCore::LoadCallbackStage::Decompile, i, raws.size()); 480 callback(VideoCore::LoadCallbackStage::Decompile, i, raws.size());
481 }
482 } 482 }
483 return unspecialized; 483 return unspecialized;
484} 484}
@@ -512,7 +512,7 @@ Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) {
512 precompiled_programs, found->second, host_ptr); 512 precompiled_programs, found->second, host_ptr);
513 } else { 513 } else {
514 shader = std::make_shared<CachedShader>( 514 shader = std::make_shared<CachedShader>(
515 cpu_addr, unique_identifier, program, disk_cache, precompiled_programs, 515 device, cpu_addr, unique_identifier, program, disk_cache, precompiled_programs,
516 std::move(program_code), std::move(program_code_b), host_ptr); 516 std::move(program_code), std::move(program_code_b), host_ptr);
517 } 517 }
518 Register(shader); 518 Register(shader);
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h
index 0cf8e0b3d..a332087f8 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.h
+++ b/src/video_core/renderer_opengl/gl_shader_cache.h
@@ -27,6 +27,7 @@ class System;
27namespace OpenGL { 27namespace OpenGL {
28 28
29class CachedShader; 29class CachedShader;
30class Device;
30class RasterizerOpenGL; 31class RasterizerOpenGL;
31struct UnspecializedShader; 32struct UnspecializedShader;
32 33
@@ -38,7 +39,7 @@ using PrecompiledShaders = std::unordered_map<u64, GLShader::ProgramResult>;
38 39
39class CachedShader final : public RasterizerCacheObject { 40class CachedShader final : public RasterizerCacheObject {
40public: 41public:
41 explicit CachedShader(VAddr cpu_addr, u64 unique_identifier, 42 explicit CachedShader(const Device& device, VAddr cpu_addr, u64 unique_identifier,
42 Maxwell::ShaderProgram program_type, ShaderDiskCacheOpenGL& disk_cache, 43 Maxwell::ShaderProgram program_type, ShaderDiskCacheOpenGL& disk_cache,
43 const PrecompiledPrograms& precompiled_programs, 44 const PrecompiledPrograms& precompiled_programs,
44 ProgramCode&& program_code, ProgramCode&& program_code_b, u8* host_ptr); 45 ProgramCode&& program_code, ProgramCode&& program_code_b, u8* host_ptr);
@@ -112,7 +113,8 @@ private:
112 113
113class ShaderCacheOpenGL final : public RasterizerCache<Shader> { 114class ShaderCacheOpenGL final : public RasterizerCache<Shader> {
114public: 115public:
115 explicit ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system); 116 explicit ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system,
117 const Device& device);
116 118
117 /// Loads disk cache for the current game 119 /// Loads disk cache for the current game
118 void LoadDiskCache(const std::atomic_bool& stop_loading, 120 void LoadDiskCache(const std::atomic_bool& stop_loading,
@@ -130,6 +132,8 @@ private:
130 CachedProgram GeneratePrecompiledProgram(const ShaderDiskCacheDump& dump, 132 CachedProgram GeneratePrecompiledProgram(const ShaderDiskCacheDump& dump,
131 const std::set<GLenum>& supported_formats); 133 const std::set<GLenum>& supported_formats);
132 134
135 const Device& device;
136
133 std::array<Shader, Maxwell::MaxShaderProgram> last_shaders; 137 std::array<Shader, Maxwell::MaxShaderProgram> last_shaders;
134 138
135 ShaderDiskCacheOpenGL disk_cache; 139 ShaderDiskCacheOpenGL disk_cache;
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 28e490b3c..aee9939db 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -15,6 +15,7 @@
15#include "common/assert.h" 15#include "common/assert.h"
16#include "common/common_types.h" 16#include "common/common_types.h"
17#include "video_core/engines/maxwell_3d.h" 17#include "video_core/engines/maxwell_3d.h"
18#include "video_core/renderer_opengl/gl_device.h"
18#include "video_core/renderer_opengl/gl_rasterizer.h" 19#include "video_core/renderer_opengl/gl_rasterizer.h"
19#include "video_core/renderer_opengl/gl_shader_decompiler.h" 20#include "video_core/renderer_opengl/gl_shader_decompiler.h"
20#include "video_core/shader/shader_ir.h" 21#include "video_core/shader/shader_ir.h"
@@ -141,8 +142,9 @@ bool IsPrecise(Node node) {
141 142
142class GLSLDecompiler final { 143class GLSLDecompiler final {
143public: 144public:
144 explicit GLSLDecompiler(const ShaderIR& ir, ShaderStage stage, std::string suffix) 145 explicit GLSLDecompiler(const Device& device, const ShaderIR& ir, ShaderStage stage,
145 : ir{ir}, stage{stage}, suffix{suffix}, header{ir.GetHeader()} {} 146 std::string suffix)
147 : device{device}, ir{ir}, stage{stage}, suffix{suffix}, header{ir.GetHeader()} {}
146 148
147 void Decompile() { 149 void Decompile() {
148 DeclareVertex(); 150 DeclareVertex();
@@ -819,8 +821,12 @@ private:
819 // Inline the string as an immediate integer in GLSL (AOFFI arguments are required 821 // Inline the string as an immediate integer in GLSL (AOFFI arguments are required
820 // to be constant by the standard). 822 // to be constant by the standard).
821 expr += std::to_string(static_cast<s32>(immediate->GetValue())); 823 expr += std::to_string(static_cast<s32>(immediate->GetValue()));
822 } else { 824 } else if (device.HasVariableAoffi()) {
825 // Avoid using variable AOFFI on unsupported devices.
823 expr += "ftoi(" + Visit(operand) + ')'; 826 expr += "ftoi(" + Visit(operand) + ')';
827 } else {
828 // Insert 0 on devices not supporting variable AOFFI.
829 expr += '0';
824 } 830 }
825 if (index + 1 < aoffi.size()) { 831 if (index + 1 < aoffi.size()) {
826 expr += ", "; 832 expr += ", ";
@@ -1609,6 +1615,7 @@ private:
1609 return name + '_' + std::to_string(index) + '_' + suffix; 1615 return name + '_' + std::to_string(index) + '_' + suffix;
1610 } 1616 }
1611 1617
1618 const Device& device;
1612 const ShaderIR& ir; 1619 const ShaderIR& ir;
1613 const ShaderStage stage; 1620 const ShaderStage stage;
1614 const std::string suffix; 1621 const std::string suffix;
@@ -1636,8 +1643,9 @@ std::string GetCommonDeclarations() {
1636 "}\n"; 1643 "}\n";
1637} 1644}
1638 1645
1639ProgramResult Decompile(const ShaderIR& ir, Maxwell::ShaderStage stage, const std::string& suffix) { 1646ProgramResult Decompile(const Device& device, const ShaderIR& ir, Maxwell::ShaderStage stage,
1640 GLSLDecompiler decompiler(ir, stage, suffix); 1647 const std::string& suffix) {
1648 GLSLDecompiler decompiler(device, ir, stage, suffix);
1641 decompiler.Decompile(); 1649 decompiler.Decompile();
1642 return {decompiler.GetResult(), decompiler.GetShaderEntries()}; 1650 return {decompiler.GetResult(), decompiler.GetShaderEntries()};
1643} 1651}
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.h b/src/video_core/renderer_opengl/gl_shader_decompiler.h
index 4e04ab2f8..fa6b0a10f 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.h
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.h
@@ -12,6 +12,10 @@
12#include "video_core/engines/maxwell_3d.h" 12#include "video_core/engines/maxwell_3d.h"
13#include "video_core/shader/shader_ir.h" 13#include "video_core/shader/shader_ir.h"
14 14
15namespace OpenGL {
16class Device;
17}
18
15namespace VideoCommon::Shader { 19namespace VideoCommon::Shader {
16class ShaderIR; 20class ShaderIR;
17} 21}
@@ -65,7 +69,7 @@ struct ShaderEntries {
65 69
66std::string GetCommonDeclarations(); 70std::string GetCommonDeclarations();
67 71
68ProgramResult Decompile(const VideoCommon::Shader::ShaderIR& ir, Maxwell::ShaderStage stage, 72ProgramResult Decompile(const Device& device, const VideoCommon::Shader::ShaderIR& ir,
69 const std::string& suffix); 73 Maxwell::ShaderStage stage, const std::string& suffix);
70 74
71} // namespace OpenGL::GLShader \ No newline at end of file 75} // namespace OpenGL::GLShader \ No newline at end of file
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp
index 8763d9c71..c055005ed 100644
--- a/src/video_core/renderer_opengl/gl_shader_gen.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp
@@ -16,7 +16,7 @@ using VideoCommon::Shader::ShaderIR;
16 16
17static constexpr u32 PROGRAM_OFFSET{10}; 17static constexpr u32 PROGRAM_OFFSET{10};
18 18
19ProgramResult GenerateVertexShader(const ShaderSetup& setup) { 19ProgramResult GenerateVertexShader(const Device& device, const ShaderSetup& setup) {
20 const std::string id = fmt::format("{:016x}", setup.program.unique_identifier); 20 const std::string id = fmt::format("{:016x}", setup.program.unique_identifier);
21 21
22 std::string out = "#extension GL_ARB_separate_shader_objects : enable\n\n"; 22 std::string out = "#extension GL_ARB_separate_shader_objects : enable\n\n";
@@ -34,14 +34,15 @@ layout (std140, binding = EMULATION_UBO_BINDING) uniform vs_config {
34 34
35)"; 35)";
36 ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET); 36 ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET);
37 ProgramResult program = Decompile(program_ir, Maxwell3D::Regs::ShaderStage::Vertex, "vertex"); 37 ProgramResult program =
38 Decompile(device, program_ir, Maxwell3D::Regs::ShaderStage::Vertex, "vertex");
38 39
39 out += program.first; 40 out += program.first;
40 41
41 if (setup.IsDualProgram()) { 42 if (setup.IsDualProgram()) {
42 ShaderIR program_ir_b(setup.program.code_b, PROGRAM_OFFSET); 43 ShaderIR program_ir_b(setup.program.code_b, PROGRAM_OFFSET);
43 ProgramResult program_b = 44 ProgramResult program_b =
44 Decompile(program_ir_b, Maxwell3D::Regs::ShaderStage::Vertex, "vertex_b"); 45 Decompile(device, program_ir_b, Maxwell3D::Regs::ShaderStage::Vertex, "vertex_b");
45 46
46 out += program_b.first; 47 out += program_b.first;
47 } 48 }
@@ -75,7 +76,7 @@ void main() {
75 return {out, program.second}; 76 return {out, program.second};
76} 77}
77 78
78ProgramResult GenerateGeometryShader(const ShaderSetup& setup) { 79ProgramResult GenerateGeometryShader(const Device& device, const ShaderSetup& setup) {
79 const std::string id = fmt::format("{:016x}", setup.program.unique_identifier); 80 const std::string id = fmt::format("{:016x}", setup.program.unique_identifier);
80 81
81 std::string out = "#extension GL_ARB_separate_shader_objects : enable\n\n"; 82 std::string out = "#extension GL_ARB_separate_shader_objects : enable\n\n";
@@ -95,7 +96,7 @@ layout (std140, binding = EMULATION_UBO_BINDING) uniform gs_config {
95)"; 96)";
96 ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET); 97 ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET);
97 ProgramResult program = 98 ProgramResult program =
98 Decompile(program_ir, Maxwell3D::Regs::ShaderStage::Geometry, "geometry"); 99 Decompile(device, program_ir, Maxwell3D::Regs::ShaderStage::Geometry, "geometry");
99 out += program.first; 100 out += program.first;
100 101
101 out += R"( 102 out += R"(
@@ -106,7 +107,7 @@ void main() {
106 return {out, program.second}; 107 return {out, program.second};
107} 108}
108 109
109ProgramResult GenerateFragmentShader(const ShaderSetup& setup) { 110ProgramResult GenerateFragmentShader(const Device& device, const ShaderSetup& setup) {
110 const std::string id = fmt::format("{:016x}", setup.program.unique_identifier); 111 const std::string id = fmt::format("{:016x}", setup.program.unique_identifier);
111 112
112 std::string out = "#extension GL_ARB_separate_shader_objects : enable\n\n"; 113 std::string out = "#extension GL_ARB_separate_shader_objects : enable\n\n";
@@ -158,7 +159,7 @@ bool AlphaFunc(in float value) {
158)"; 159)";
159 ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET); 160 ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET);
160 ProgramResult program = 161 ProgramResult program =
161 Decompile(program_ir, Maxwell3D::Regs::ShaderStage::Fragment, "fragment"); 162 Decompile(device, program_ir, Maxwell3D::Regs::ShaderStage::Fragment, "fragment");
162 163
163 out += program.first; 164 out += program.first;
164 165
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.h b/src/video_core/renderer_opengl/gl_shader_gen.h
index fad346b48..0536c8a03 100644
--- a/src/video_core/renderer_opengl/gl_shader_gen.h
+++ b/src/video_core/renderer_opengl/gl_shader_gen.h
@@ -10,6 +10,10 @@
10#include "video_core/renderer_opengl/gl_shader_decompiler.h" 10#include "video_core/renderer_opengl/gl_shader_decompiler.h"
11#include "video_core/shader/shader_ir.h" 11#include "video_core/shader/shader_ir.h"
12 12
13namespace OpenGL {
14class Device;
15}
16
13namespace OpenGL::GLShader { 17namespace OpenGL::GLShader {
14 18
15using VideoCommon::Shader::ProgramCode; 19using VideoCommon::Shader::ProgramCode;
@@ -39,22 +43,13 @@ private:
39 bool has_program_b{}; 43 bool has_program_b{};
40}; 44};
41 45
42/** 46/// Generates the GLSL vertex shader program source code for the given VS program
43 * Generates the GLSL vertex shader program source code for the given VS program 47ProgramResult GenerateVertexShader(const Device& device, const ShaderSetup& setup);
44 * @returns String of the shader source code 48
45 */ 49/// Generates the GLSL geometry shader program source code for the given GS program
46ProgramResult GenerateVertexShader(const ShaderSetup& setup); 50ProgramResult GenerateGeometryShader(const Device& device, const ShaderSetup& setup);
47 51
48/** 52/// Generates the GLSL fragment shader program source code for the given FS program
49 * Generates the GLSL geometry shader program source code for the given GS program 53ProgramResult GenerateFragmentShader(const Device& device, const ShaderSetup& setup);
50 * @returns String of the shader source code
51 */
52ProgramResult GenerateGeometryShader(const ShaderSetup& setup);
53
54/**
55 * Generates the GLSL fragment shader program source code for the given FS program
56 * @returns String of the shader source code
57 */
58ProgramResult GenerateFragmentShader(const ShaderSetup& setup);
59 54
60} // namespace OpenGL::GLShader 55} // namespace OpenGL::GLShader