summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/CMakeLists.txt2
-rw-r--r--src/video_core/renderer_opengl/gl_device.cpp45
-rw-r--r--src/video_core/renderer_opengl/gl_device.h30
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp25
-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
11 files changed, 163 insertions, 75 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 1e31a2900..6821f275d 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -36,6 +36,8 @@ add_library(video_core STATIC
36 renderer_base.h 36 renderer_base.h
37 renderer_opengl/gl_buffer_cache.cpp 37 renderer_opengl/gl_buffer_cache.cpp
38 renderer_opengl/gl_buffer_cache.h 38 renderer_opengl/gl_buffer_cache.h
39 renderer_opengl/gl_device.cpp
40 renderer_opengl/gl_device.h
39 renderer_opengl/gl_global_cache.cpp 41 renderer_opengl/gl_global_cache.cpp
40 renderer_opengl/gl_global_cache.h 42 renderer_opengl/gl_global_cache.h
41 renderer_opengl/gl_primitive_assembler.cpp 43 renderer_opengl/gl_primitive_assembler.cpp
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp
new file mode 100644
index 000000000..b6d9e0ddb
--- /dev/null
+++ b/src/video_core/renderer_opengl/gl_device.cpp
@@ -0,0 +1,45 @@
1// Copyright 2019 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <cstddef>
6#include <glad/glad.h>
7
8#include "common/logging/log.h"
9#include "video_core/renderer_opengl/gl_device.h"
10
11namespace OpenGL {
12
13namespace {
14template <typename T>
15T GetInteger(GLenum pname) {
16 GLint temporary;
17 glGetIntegerv(pname, &temporary);
18 return static_cast<T>(temporary);
19}
20} // Anonymous namespace
21
22Device::Device() {
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;
43}
44
45} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_device.h b/src/video_core/renderer_opengl/gl_device.h
new file mode 100644
index 000000000..78ff5ee58
--- /dev/null
+++ b/src/video_core/renderer_opengl/gl_device.h
@@ -0,0 +1,30 @@
1// Copyright 2019 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <cstddef>
8
9namespace OpenGL {
10
11class Device {
12public:
13 Device();
14
15 std::size_t GetUniformBufferAlignment() const {
16 return uniform_buffer_alignment;
17 }
18
19 bool HasVariableAoffi() const {
20 return has_variable_aoffi;
21 }
22
23private:
24 static bool TestVariableAoffi();
25
26 std::size_t uniform_buffer_alignment{};
27 bool has_variable_aoffi{};
28};
29
30} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 6034dc489..9a088a503 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 OpenGLState::ApplyDefaultState(); 104 OpenGLState::ApplyDefaultState();
105 105
@@ -107,8 +107,6 @@ RasterizerOpenGL::RasterizerOpenGL(Core::System& system, ScreenInfo& info)
107 state.draw.shader_program = 0; 107 state.draw.shader_program = 0;
108 state.Apply(); 108 state.Apply();
109 109
110 glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &uniform_buffer_alignment);
111
112 LOG_DEBUG(Render_OpenGL, "Sync fixed function OpenGL state here"); 110 LOG_DEBUG(Render_OpenGL, "Sync fixed function OpenGL state here");
113 CheckExtensions(); 111 CheckExtensions();
114} 112}
@@ -315,8 +313,8 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
315 313
316 GLShader::MaxwellUniformData ubo{}; 314 GLShader::MaxwellUniformData ubo{};
317 ubo.SetFromRegs(gpu, stage); 315 ubo.SetFromRegs(gpu, stage);
318 const GLintptr offset = buffer_cache.UploadHostMemory( 316 const GLintptr offset =
319 &ubo, sizeof(ubo), static_cast<std::size_t>(uniform_buffer_alignment)); 317 buffer_cache.UploadHostMemory(&ubo, sizeof(ubo), device.GetUniformBufferAlignment());
320 318
321 // Bind the emulation info buffer 319 // Bind the emulation info buffer
322 bind_ubo_pushbuffer.Push(buffer_cache.GetHandle(), offset, 320 bind_ubo_pushbuffer.Push(buffer_cache.GetHandle(), offset,
@@ -700,23 +698,24 @@ void RasterizerOpenGL::DrawArrays() {
700 // Add space for index buffer (keeping in mind non-core primitives) 698 // Add space for index buffer (keeping in mind non-core primitives)
701 switch (regs.draw.topology) { 699 switch (regs.draw.topology) {
702 case Maxwell::PrimitiveTopology::Quads: 700 case Maxwell::PrimitiveTopology::Quads:
703 buffer_size = Common::AlignUp<std::size_t>(buffer_size, 4) + 701 buffer_size = Common::AlignUp(buffer_size, 4) +
704 primitive_assembler.CalculateQuadSize(regs.vertex_buffer.count); 702 primitive_assembler.CalculateQuadSize(regs.vertex_buffer.count);
705 break; 703 break;
706 default: 704 default:
707 if (is_indexed) { 705 if (is_indexed) {
708 buffer_size = Common::AlignUp<std::size_t>(buffer_size, 4) + CalculateIndexBufferSize(); 706 buffer_size = Common::AlignUp(buffer_size, 4) + CalculateIndexBufferSize();
709 } 707 }
710 break; 708 break;
711 } 709 }
712 710
713 // Uniform space for the 5 shader stages 711 // Uniform space for the 5 shader stages
714 buffer_size = 712 buffer_size = Common::AlignUp<std::size_t>(buffer_size, 4) +
715 Common::AlignUp<std::size_t>(buffer_size, 4) + 713 (sizeof(GLShader::MaxwellUniformData) + device.GetUniformBufferAlignment()) *
716 (sizeof(GLShader::MaxwellUniformData) + uniform_buffer_alignment) * Maxwell::MaxShaderStage; 714 Maxwell::MaxShaderStage;
717 715
718 // Add space for at least 18 constant buffers 716 // Add space for at least 18 constant buffers
719 buffer_size += Maxwell::MaxConstBuffers * (MaxConstbufferSize + uniform_buffer_alignment); 717 buffer_size +=
718 Maxwell::MaxConstBuffers * (MaxConstbufferSize + device.GetUniformBufferAlignment());
720 719
721 const bool invalidate = buffer_cache.Map(buffer_size); 720 const bool invalidate = buffer_cache.Map(buffer_size);
722 if (invalidate) { 721 if (invalidate) {
@@ -848,8 +847,8 @@ void RasterizerOpenGL::SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::Shader
848 size = Common::AlignUp(size, sizeof(GLvec4)); 847 size = Common::AlignUp(size, sizeof(GLvec4));
849 ASSERT_MSG(size <= MaxConstbufferSize, "Constbuffer too big"); 848 ASSERT_MSG(size <= MaxConstbufferSize, "Constbuffer too big");
850 849
851 const GLintptr const_buffer_offset = buffer_cache.UploadMemory( 850 const GLintptr const_buffer_offset =
852 buffer.address, size, static_cast<std::size_t>(uniform_buffer_alignment)); 851 buffer_cache.UploadMemory(buffer.address, size, device.GetUniformBufferAlignment());
853 852
854 bind_ubo_pushbuffer.Push(buffer_cache.GetHandle(), const_buffer_offset, size); 853 bind_ubo_pushbuffer.Push(buffer_cache.GetHandle(), const_buffer_offset, size);
855 } 854 }
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index a0e056142..71b9c5ead 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -21,6 +21,7 @@
21#include "video_core/rasterizer_cache.h" 21#include "video_core/rasterizer_cache.h"
22#include "video_core/rasterizer_interface.h" 22#include "video_core/rasterizer_interface.h"
23#include "video_core/renderer_opengl/gl_buffer_cache.h" 23#include "video_core/renderer_opengl/gl_buffer_cache.h"
24#include "video_core/renderer_opengl/gl_device.h"
24#include "video_core/renderer_opengl/gl_global_cache.h" 25#include "video_core/renderer_opengl/gl_global_cache.h"
25#include "video_core/renderer_opengl/gl_primitive_assembler.h" 26#include "video_core/renderer_opengl/gl_primitive_assembler.h"
26#include "video_core/renderer_opengl/gl_rasterizer_cache.h" 27#include "video_core/renderer_opengl/gl_rasterizer_cache.h"
@@ -172,6 +173,7 @@ private:
172 /// but are needed for correct emulation 173 /// but are needed for correct emulation
173 void CheckExtensions(); 174 void CheckExtensions();
174 175
176 const Device device;
175 OpenGLState state; 177 OpenGLState state;
176 178
177 RasterizerCacheOpenGL res_cache; 179 RasterizerCacheOpenGL res_cache;
@@ -180,7 +182,6 @@ private:
180 SamplerCacheOpenGL sampler_cache; 182 SamplerCacheOpenGL sampler_cache;
181 183
182 Core::System& system; 184 Core::System& system;
183
184 ScreenInfo& screen_info; 185 ScreenInfo& screen_info;
185 186
186 std::unique_ptr<GLShader::ProgramManager> shader_program_manager; 187 std::unique_ptr<GLShader::ProgramManager> shader_program_manager;
@@ -196,7 +197,6 @@ private:
196 static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; 197 static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024;
197 OGLBufferCache buffer_cache; 198 OGLBufferCache buffer_cache;
198 PrimitiveAssembler primitive_assembler{buffer_cache}; 199 PrimitiveAssembler primitive_assembler{buffer_cache};
199 GLint uniform_buffer_alignment;
200 200
201 BindBuffersRangePushBuffer bind_ubo_pushbuffer{GL_UNIFORM_BUFFER}; 201 BindBuffersRangePushBuffer bind_ubo_pushbuffer{GL_UNIFORM_BUFFER};
202 BindBuffersRangePushBuffer bind_ssbo_pushbuffer{GL_SHADER_STORAGE_BUFFER}; 202 BindBuffersRangePushBuffer bind_ssbo_pushbuffer{GL_SHADER_STORAGE_BUFFER};
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index 43f2906a8..2a81b1169 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -136,8 +136,8 @@ u64 GetUniqueIdentifier(Maxwell::ShaderProgram program_type, const ProgramCode&
136} 136}
137 137
138/// Creates an unspecialized program from code streams 138/// Creates an unspecialized program from code streams
139GLShader::ProgramResult CreateProgram(Maxwell::ShaderProgram program_type, ProgramCode program_code, 139GLShader::ProgramResult CreateProgram(const Device& device, Maxwell::ShaderProgram program_type,
140 ProgramCode program_code_b) { 140 ProgramCode program_code, ProgramCode program_code_b) {
141 GLShader::ShaderSetup setup(program_code); 141 GLShader::ShaderSetup setup(program_code);
142 if (program_type == Maxwell::ShaderProgram::VertexA) { 142 if (program_type == Maxwell::ShaderProgram::VertexA) {
143 // VertexB is always enabled, so when VertexA is enabled, we have two vertex shaders. 143 // VertexB is always enabled, so when VertexA is enabled, we have two vertex shaders.
@@ -151,11 +151,11 @@ GLShader::ProgramResult CreateProgram(Maxwell::ShaderProgram program_type, Progr
151 switch (program_type) { 151 switch (program_type) {
152 case Maxwell::ShaderProgram::VertexA: 152 case Maxwell::ShaderProgram::VertexA:
153 case Maxwell::ShaderProgram::VertexB: 153 case Maxwell::ShaderProgram::VertexB:
154 return GLShader::GenerateVertexShader(setup); 154 return GLShader::GenerateVertexShader(device, setup);
155 case Maxwell::ShaderProgram::Geometry: 155 case Maxwell::ShaderProgram::Geometry:
156 return GLShader::GenerateGeometryShader(setup); 156 return GLShader::GenerateGeometryShader(device, setup);
157 case Maxwell::ShaderProgram::Fragment: 157 case Maxwell::ShaderProgram::Fragment:
158 return GLShader::GenerateFragmentShader(setup); 158 return GLShader::GenerateFragmentShader(device, setup);
159 default: 159 default:
160 LOG_CRITICAL(HW_GPU, "Unimplemented program_type={}", static_cast<u32>(program_type)); 160 LOG_CRITICAL(HW_GPU, "Unimplemented program_type={}", static_cast<u32>(program_type));
161 UNREACHABLE(); 161 UNREACHABLE();
@@ -214,22 +214,20 @@ std::set<GLenum> GetSupportedFormats() {
214 return supported_formats; 214 return supported_formats;
215} 215}
216 216
217} // namespace 217} // Anonymous namespace
218 218
219CachedShader::CachedShader(VAddr cpu_addr, u64 unique_identifier, 219CachedShader::CachedShader(const Device& device, VAddr cpu_addr, u64 unique_identifier,
220 Maxwell::ShaderProgram program_type, ShaderDiskCacheOpenGL& disk_cache, 220 Maxwell::ShaderProgram program_type, ShaderDiskCacheOpenGL& disk_cache,
221 const PrecompiledPrograms& precompiled_programs, 221 const PrecompiledPrograms& precompiled_programs,
222 ProgramCode&& program_code, ProgramCode&& program_code_b, u8* host_ptr) 222 ProgramCode&& program_code, ProgramCode&& program_code_b, u8* host_ptr)
223 : RasterizerCacheObject{host_ptr}, host_ptr{host_ptr}, cpu_addr{cpu_addr}, 223 : RasterizerCacheObject{host_ptr}, host_ptr{host_ptr}, cpu_addr{cpu_addr},
224 unique_identifier{unique_identifier}, program_type{program_type}, disk_cache{disk_cache}, 224 unique_identifier{unique_identifier}, program_type{program_type}, disk_cache{disk_cache},
225 precompiled_programs{precompiled_programs} { 225 precompiled_programs{precompiled_programs} {
226 226 const std::size_t code_size{CalculateProgramSize(program_code)};
227 const std::size_t code_size = CalculateProgramSize(program_code); 227 const std::size_t code_size_b{program_code_b.empty() ? 0
228 const std::size_t code_size_b = 228 : CalculateProgramSize(program_code_b)};
229 program_code_b.empty() ? 0 : CalculateProgramSize(program_code_b); 229 GLShader::ProgramResult program_result{
230 230 CreateProgram(device, program_type, program_code, program_code_b)};
231 GLShader::ProgramResult program_result =
232 CreateProgram(program_type, program_code, program_code_b);
233 if (program_result.first.empty()) { 231 if (program_result.first.empty()) {
234 // TODO(Rodrigo): Unimplemented shader stages hit here, avoid using these for now 232 // TODO(Rodrigo): Unimplemented shader stages hit here, avoid using these for now
235 return; 233 return;
@@ -253,7 +251,6 @@ CachedShader::CachedShader(VAddr cpu_addr, u64 unique_identifier,
253 : RasterizerCacheObject{host_ptr}, cpu_addr{cpu_addr}, unique_identifier{unique_identifier}, 251 : RasterizerCacheObject{host_ptr}, cpu_addr{cpu_addr}, unique_identifier{unique_identifier},
254 program_type{program_type}, disk_cache{disk_cache}, precompiled_programs{ 252 program_type{program_type}, disk_cache{disk_cache}, precompiled_programs{
255 precompiled_programs} { 253 precompiled_programs} {
256
257 code = std::move(result.first); 254 code = std::move(result.first);
258 entries = result.second; 255 entries = result.second;
259 shader_length = entries.shader_length; 256 shader_length = entries.shader_length;
@@ -346,8 +343,9 @@ ShaderDiskCacheUsage CachedShader::GetUsage(GLenum primitive_mode,
346 return {unique_identifier, base_bindings, primitive_mode}; 343 return {unique_identifier, base_bindings, primitive_mode};
347} 344}
348 345
349ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system) 346ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system,
350 : RasterizerCache{rasterizer}, disk_cache{system} {} 347 const Device& device)
348 : RasterizerCache{rasterizer}, disk_cache{system}, device{device} {}
351 349
352void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading, 350void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading,
353 const VideoCore::DiskResourceLoadCallback& callback) { 351 const VideoCore::DiskResourceLoadCallback& callback) {
@@ -441,17 +439,18 @@ std::unordered_map<u64, UnspecializedShader> ShaderCacheOpenGL::GenerateUnspecia
441 const std::unordered_map<u64, ShaderDiskCacheDecompiled>& decompiled) { 439 const std::unordered_map<u64, ShaderDiskCacheDecompiled>& decompiled) {
442 std::unordered_map<u64, UnspecializedShader> unspecialized; 440 std::unordered_map<u64, UnspecializedShader> unspecialized;
443 441
444 if (callback) 442 if (callback) {
445 callback(VideoCore::LoadCallbackStage::Decompile, 0, raws.size()); 443 callback(VideoCore::LoadCallbackStage::Decompile, 0, raws.size());
444 }
446 445
447 for (std::size_t i = 0; i < raws.size(); ++i) { 446 for (std::size_t i = 0; i < raws.size(); ++i) {
448 if (stop_loading) 447 if (stop_loading) {
449 return {}; 448 return {};
450 449 }
451 const auto& raw{raws[i]}; 450 const auto& raw{raws[i]};
452 const u64 unique_identifier = raw.GetUniqueIdentifier(); 451 const u64 unique_identifier{raw.GetUniqueIdentifier()};
453 const u64 calculated_hash = 452 const u64 calculated_hash{
454 GetUniqueIdentifier(raw.GetProgramType(), raw.GetProgramCode(), raw.GetProgramCodeB()); 453 GetUniqueIdentifier(raw.GetProgramType(), raw.GetProgramCode(), raw.GetProgramCodeB())};
455 if (unique_identifier != calculated_hash) { 454 if (unique_identifier != calculated_hash) {
456 LOG_ERROR( 455 LOG_ERROR(
457 Render_OpenGL, 456 Render_OpenGL,
@@ -468,8 +467,8 @@ std::unordered_map<u64, UnspecializedShader> ShaderCacheOpenGL::GenerateUnspecia
468 result = {stored_decompiled.code, stored_decompiled.entries}; 467 result = {stored_decompiled.code, stored_decompiled.entries};
469 } else { 468 } else {
470 // Otherwise decompile the shader at boot and save the result to the decompiled file 469 // Otherwise decompile the shader at boot and save the result to the decompiled file
471 result = 470 result = CreateProgram(device, raw.GetProgramType(), raw.GetProgramCode(),
472 CreateProgram(raw.GetProgramType(), raw.GetProgramCode(), raw.GetProgramCodeB()); 471 raw.GetProgramCodeB());
473 disk_cache.SaveDecompiled(unique_identifier, result.first, result.second); 472 disk_cache.SaveDecompiled(unique_identifier, result.first, result.second);
474 } 473 }
475 474
@@ -479,8 +478,9 @@ std::unordered_map<u64, UnspecializedShader> ShaderCacheOpenGL::GenerateUnspecia
479 {raw.GetUniqueIdentifier(), 478 {raw.GetUniqueIdentifier(),
480 {std::move(result.first), std::move(result.second), raw.GetProgramType()}}); 479 {std::move(result.first), std::move(result.second), raw.GetProgramType()}});
481 480
482 if (callback) 481 if (callback) {
483 callback(VideoCore::LoadCallbackStage::Decompile, i, raws.size()); 482 callback(VideoCore::LoadCallbackStage::Decompile, i, raws.size());
483 }
484 } 484 }
485 return unspecialized; 485 return unspecialized;
486} 486}
@@ -515,7 +515,7 @@ Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) {
515 precompiled_programs, found->second, host_ptr); 515 precompiled_programs, found->second, host_ptr);
516 } else { 516 } else {
517 shader = std::make_shared<CachedShader>( 517 shader = std::make_shared<CachedShader>(
518 cpu_addr, unique_identifier, program, disk_cache, precompiled_programs, 518 device, cpu_addr, unique_identifier, program, disk_cache, precompiled_programs,
519 std::move(program_code), std::move(program_code_b), host_ptr); 519 std::move(program_code), std::move(program_code_b), host_ptr);
520 } 520 }
521 Register(shader); 521 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 cd462621d..ef1a1995f 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"
@@ -135,8 +136,9 @@ bool IsPrecise(Node node) {
135 136
136class GLSLDecompiler final { 137class GLSLDecompiler final {
137public: 138public:
138 explicit GLSLDecompiler(const ShaderIR& ir, ShaderStage stage, std::string suffix) 139 explicit GLSLDecompiler(const Device& device, const ShaderIR& ir, ShaderStage stage,
139 : ir{ir}, stage{stage}, suffix{suffix}, header{ir.GetHeader()} {} 140 std::string suffix)
141 : device{device}, ir{ir}, stage{stage}, suffix{suffix}, header{ir.GetHeader()} {}
140 142
141 void Decompile() { 143 void Decompile() {
142 DeclareVertex(); 144 DeclareVertex();
@@ -802,8 +804,12 @@ private:
802 // Inline the string as an immediate integer in GLSL (AOFFI arguments are required 804 // Inline the string as an immediate integer in GLSL (AOFFI arguments are required
803 // to be constant by the standard). 805 // to be constant by the standard).
804 expr += std::to_string(static_cast<s32>(immediate->GetValue())); 806 expr += std::to_string(static_cast<s32>(immediate->GetValue()));
805 } else { 807 } else if (device.HasVariableAoffi()) {
808 // Avoid using variable AOFFI on unsupported devices.
806 expr += "ftoi(" + Visit(operand) + ')'; 809 expr += "ftoi(" + Visit(operand) + ')';
810 } else {
811 // Insert 0 on devices not supporting variable AOFFI.
812 expr += '0';
807 } 813 }
808 if (index + 1 < aoffi.size()) { 814 if (index + 1 < aoffi.size()) {
809 expr += ", "; 815 expr += ", ";
@@ -1645,6 +1651,7 @@ private:
1645 return name + '_' + std::to_string(index) + '_' + suffix; 1651 return name + '_' + std::to_string(index) + '_' + suffix;
1646 } 1652 }
1647 1653
1654 const Device& device;
1648 const ShaderIR& ir; 1655 const ShaderIR& ir;
1649 const ShaderStage stage; 1656 const ShaderStage stage;
1650 const std::string suffix; 1657 const std::string suffix;
@@ -1676,8 +1683,9 @@ std::string GetCommonDeclarations() {
1676 "}\n"; 1683 "}\n";
1677} 1684}
1678 1685
1679ProgramResult Decompile(const ShaderIR& ir, Maxwell::ShaderStage stage, const std::string& suffix) { 1686ProgramResult Decompile(const Device& device, const ShaderIR& ir, Maxwell::ShaderStage stage,
1680 GLSLDecompiler decompiler(ir, stage, suffix); 1687 const std::string& suffix) {
1688 GLSLDecompiler decompiler(device, ir, stage, suffix);
1681 decompiler.Decompile(); 1689 decompiler.Decompile();
1682 return {decompiler.GetResult(), decompiler.GetShaderEntries()}; 1690 return {decompiler.GetResult(), decompiler.GetShaderEntries()};
1683} 1691}
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.h b/src/video_core/renderer_opengl/gl_shader_decompiler.h
index 74032d237..c1569e737 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}
@@ -77,7 +81,7 @@ struct ShaderEntries {
77 81
78std::string GetCommonDeclarations(); 82std::string GetCommonDeclarations();
79 83
80ProgramResult Decompile(const VideoCommon::Shader::ShaderIR& ir, Maxwell::ShaderStage stage, 84ProgramResult Decompile(const Device& device, const VideoCommon::Shader::ShaderIR& ir,
81 const std::string& suffix); 85 Maxwell::ShaderStage stage, const std::string& suffix);
82 86
83} // namespace OpenGL::GLShader 87} // namespace OpenGL::GLShader
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