summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/hid/hid.cpp8
-rw-r--r--src/core/hle/service/service.cpp2
-rw-r--r--src/core/settings.h2
-rw-r--r--src/video_core/engines/maxwell_dma.cpp12
-rw-r--r--src/video_core/engines/shader_bytecode.h41
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp23
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp8
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp223
-rw-r--r--src/video_core/renderer_opengl/gl_shader_util.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_stream_buffer.cpp2
10 files changed, 220 insertions, 103 deletions
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 0d31abe8b..a8e0c869f 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -2,7 +2,6 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <atomic>
6#include "common/logging/log.h" 5#include "common/logging/log.h"
7#include "core/core.h" 6#include "core/core.h"
8#include "core/core_timing.h" 7#include "core/core_timing.h"
@@ -78,7 +77,7 @@ private:
78 SharedMemory mem{}; 77 SharedMemory mem{};
79 std::memcpy(&mem, shared_mem->GetPointer(), sizeof(SharedMemory)); 78 std::memcpy(&mem, shared_mem->GetPointer(), sizeof(SharedMemory));
80 79
81 if (is_device_reload_pending.exchange(false)) 80 if (Settings::values.is_device_reload_pending.exchange(false))
82 LoadInputDevices(); 81 LoadInputDevices();
83 82
84 // Set up controllers as neon red+blue Joy-Con attached to console 83 // Set up controllers as neon red+blue Joy-Con attached to console
@@ -267,7 +266,6 @@ private:
267 CoreTiming::EventType* pad_update_event; 266 CoreTiming::EventType* pad_update_event;
268 267
269 // Stored input state info 268 // Stored input state info
270 std::atomic<bool> is_device_reload_pending{true};
271 std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID> 269 std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID>
272 buttons; 270 buttons;
273 std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NUM_STICKS_HID> sticks; 271 std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NUM_STICKS_HID> sticks;
@@ -797,7 +795,9 @@ public:
797 } 795 }
798}; 796};
799 797
800void ReloadInputDevices() {} 798void ReloadInputDevices() {
799 Settings::values.is_device_reload_pending.store(true);
800}
801 801
802void InstallInterfaces(SM::ServiceManager& service_manager) { 802void InstallInterfaces(SM::ServiceManager& service_manager) {
803 std::make_shared<Hid>()->InstallAsService(service_manager); 803 std::make_shared<Hid>()->InstallAsService(service_manager);
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 9d804652e..9bb7c7b26 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -74,8 +74,6 @@ using Kernel::SharedPtr;
74 74
75namespace Service { 75namespace Service {
76 76
77std::unordered_map<std::string, SharedPtr<ClientPort>> g_kernel_named_ports;
78
79/** 77/**
80 * Creates a function string for logging, complete with the name (or header code, depending 78 * Creates a function string for logging, complete with the name (or header code, depending
81 * on what's passed in) the port name, and all the cmd_buff arguments. 79 * on what's passed in) the port name, and all the cmd_buff arguments.
diff --git a/src/core/settings.h b/src/core/settings.h
index 5bf1863e6..08a16ef2c 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -5,6 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include <array> 7#include <array>
8#include <atomic>
8#include <string> 9#include <string>
9#include "common/common_types.h" 10#include "common/common_types.h"
10 11
@@ -120,6 +121,7 @@ struct Values {
120 std::array<std::string, NativeAnalog::NumAnalogs> analogs; 121 std::array<std::string, NativeAnalog::NumAnalogs> analogs;
121 std::string motion_device; 122 std::string motion_device;
122 std::string touch_device; 123 std::string touch_device;
124 std::atomic_bool is_device_reload_pending{true};
123 125
124 // Core 126 // Core
125 bool use_cpu_jit; 127 bool use_cpu_jit;
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp
index 6e740713f..c24d33d5c 100644
--- a/src/video_core/engines/maxwell_dma.cpp
+++ b/src/video_core/engines/maxwell_dma.cpp
@@ -41,7 +41,6 @@ void MaxwellDMA::HandleCopy() {
41 41
42 // TODO(Subv): Perform more research and implement all features of this engine. 42 // TODO(Subv): Perform more research and implement all features of this engine.
43 ASSERT(regs.exec.enable_swizzle == 0); 43 ASSERT(regs.exec.enable_swizzle == 0);
44 ASSERT(regs.exec.enable_2d == 1);
45 ASSERT(regs.exec.query_mode == Regs::QueryMode::None); 44 ASSERT(regs.exec.query_mode == Regs::QueryMode::None);
46 ASSERT(regs.exec.query_intr == Regs::QueryIntr::None); 45 ASSERT(regs.exec.query_intr == Regs::QueryIntr::None);
47 ASSERT(regs.exec.copy_mode == Regs::CopyMode::Unk2); 46 ASSERT(regs.exec.copy_mode == Regs::CopyMode::Unk2);
@@ -51,10 +50,19 @@ void MaxwellDMA::HandleCopy() {
51 ASSERT(regs.dst_params.pos_y == 0); 50 ASSERT(regs.dst_params.pos_y == 0);
52 51
53 if (regs.exec.is_dst_linear == regs.exec.is_src_linear) { 52 if (regs.exec.is_dst_linear == regs.exec.is_src_linear) {
54 Memory::CopyBlock(dest_cpu, source_cpu, regs.x_count * regs.y_count); 53 size_t copy_size = regs.x_count;
54
55 // When the enable_2d bit is disabled, the copy is performed as if we were copying a 1D
56 // buffer of length `x_count`, otherwise we copy a 2D buffer of size (x_count, y_count).
57 if (regs.exec.enable_2d) {
58 copy_size = copy_size * regs.y_count;
59 }
60
61 Memory::CopyBlock(dest_cpu, source_cpu, copy_size);
55 return; 62 return;
56 } 63 }
57 64
65 ASSERT(regs.exec.enable_2d == 1);
58 u8* src_buffer = Memory::GetPointer(source_cpu); 66 u8* src_buffer = Memory::GetPointer(source_cpu);
59 u8* dst_buffer = Memory::GetPointer(dest_cpu); 67 u8* dst_buffer = Memory::GetPointer(dest_cpu);
60 68
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index d2388673e..9176a8dbc 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -244,6 +244,16 @@ enum class TextureType : u64 {
244 TextureCube = 3, 244 TextureCube = 3,
245}; 245};
246 246
247enum class TextureQueryType : u64 {
248 Dimension = 1,
249 TextureType = 2,
250 SamplePosition = 5,
251 Filter = 16,
252 LevelOfDetail = 18,
253 Wrap = 20,
254 BorderColor = 22,
255};
256
247enum class IpaInterpMode : u64 { Linear = 0, Perspective = 1, Flat = 2, Sc = 3 }; 257enum class IpaInterpMode : u64 { Linear = 0, Perspective = 1, Flat = 2, Sc = 3 };
248enum class IpaSampleMode : u64 { Default = 0, Centroid = 1, Offset = 2 }; 258enum class IpaSampleMode : u64 { Default = 0, Centroid = 1, Offset = 2 };
249 259
@@ -519,6 +529,21 @@ union Instruction {
519 } tex; 529 } tex;
520 530
521 union { 531 union {
532 BitField<22, 6, TextureQueryType> query_type;
533 BitField<31, 4, u64> component_mask;
534 } txq;
535
536 union {
537 BitField<28, 1, u64> array;
538 BitField<29, 2, TextureType> texture_type;
539 BitField<31, 4, u64> component_mask;
540
541 bool IsComponentEnabled(size_t component) const {
542 return ((1ull << component) & component_mask) != 0;
543 }
544 } tmml;
545
546 union {
522 BitField<28, 1, u64> array; 547 BitField<28, 1, u64> array;
523 BitField<29, 2, TextureType> texture_type; 548 BitField<29, 2, TextureType> texture_type;
524 BitField<56, 2, u64> component; 549 BitField<56, 2, u64> component;
@@ -670,11 +695,13 @@ public:
670 LDG, // Load from global memory 695 LDG, // Load from global memory
671 STG, // Store in global memory 696 STG, // Store in global memory
672 TEX, 697 TEX,
673 TEXQ, // Texture Query 698 TXQ, // Texture Query
674 TEXS, // Texture Fetch with scalar/non-vec4 source/destinations 699 TEXS, // Texture Fetch with scalar/non-vec4 source/destinations
675 TLDS, // Texture Load with scalar/non-vec4 source/destinations 700 TLDS, // Texture Load with scalar/non-vec4 source/destinations
676 TLD4, // Texture Load 4 701 TLD4, // Texture Load 4
677 TLD4S, // Texture Load 4 with scalar / non - vec4 source / destinations 702 TLD4S, // Texture Load 4 with scalar / non - vec4 source / destinations
703 TMML_B, // Texture Mip Map Level
704 TMML, // Texture Mip Map Level
678 EXIT, 705 EXIT,
679 IPA, 706 IPA,
680 FFMA_IMM, // Fused Multiply and Add 707 FFMA_IMM, // Fused Multiply and Add
@@ -894,11 +921,13 @@ private:
894 INST("1110111011010---", Id::LDG, Type::Memory, "LDG"), 921 INST("1110111011010---", Id::LDG, Type::Memory, "LDG"),
895 INST("1110111011011---", Id::STG, Type::Memory, "STG"), 922 INST("1110111011011---", Id::STG, Type::Memory, "STG"),
896 INST("110000----111---", Id::TEX, Type::Memory, "TEX"), 923 INST("110000----111---", Id::TEX, Type::Memory, "TEX"),
897 INST("1101111101001---", Id::TEXQ, Type::Memory, "TEXQ"), 924 INST("1101111101001---", Id::TXQ, Type::Memory, "TXQ"),
898 INST("1101100---------", Id::TEXS, Type::Memory, "TEXS"), 925 INST("1101100---------", Id::TEXS, Type::Memory, "TEXS"),
899 INST("1101101---------", Id::TLDS, Type::Memory, "TLDS"), 926 INST("1101101---------", Id::TLDS, Type::Memory, "TLDS"),
900 INST("110010----111---", Id::TLD4, Type::Memory, "TLD4"), 927 INST("110010----111---", Id::TLD4, Type::Memory, "TLD4"),
901 INST("1101111100------", Id::TLD4S, Type::Memory, "TLD4S"), 928 INST("1101111100------", Id::TLD4S, Type::Memory, "TLD4S"),
929 INST("110111110110----", Id::TMML_B, Type::Memory, "TMML_B"),
930 INST("1101111101011---", Id::TMML, Type::Memory, "TMML"),
902 INST("111000110000----", Id::EXIT, Type::Trivial, "EXIT"), 931 INST("111000110000----", Id::EXIT, Type::Trivial, "EXIT"),
903 INST("11100000--------", Id::IPA, Type::Trivial, "IPA"), 932 INST("11100000--------", Id::IPA, Type::Trivial, "IPA"),
904 INST("0011001-1-------", Id::FFMA_IMM, Type::Ffma, "FFMA_IMM"), 933 INST("0011001-1-------", Id::FFMA_IMM, Type::Ffma, "FFMA_IMM"),
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 360fb0cd5..fa730b9e6 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -505,7 +505,7 @@ static void ConvertS8Z24ToZ24S8(std::vector<u8>& data, u32 width, u32 height) {
505 505
506 S8Z24 input_pixel{}; 506 S8Z24 input_pixel{};
507 Z24S8 output_pixel{}; 507 Z24S8 output_pixel{};
508 const auto bpp{CachedSurface::GetGLBytesPerPixel(PixelFormat::S8Z24)}; 508 constexpr auto bpp{CachedSurface::GetGLBytesPerPixel(PixelFormat::S8Z24)};
509 for (size_t y = 0; y < height; ++y) { 509 for (size_t y = 0; y < height; ++y) {
510 for (size_t x = 0; x < width; ++x) { 510 for (size_t x = 0; x < width; ++x) {
511 const size_t offset{bpp * (y * width + x)}; 511 const size_t offset{bpp * (y * width + x)};
@@ -518,7 +518,7 @@ static void ConvertS8Z24ToZ24S8(std::vector<u8>& data, u32 width, u32 height) {
518} 518}
519 519
520static void ConvertG8R8ToR8G8(std::vector<u8>& data, u32 width, u32 height) { 520static void ConvertG8R8ToR8G8(std::vector<u8>& data, u32 width, u32 height) {
521 const auto bpp{CachedSurface::GetGLBytesPerPixel(PixelFormat::G8R8U)}; 521 constexpr auto bpp{CachedSurface::GetGLBytesPerPixel(PixelFormat::G8R8U)};
522 for (size_t y = 0; y < height; ++y) { 522 for (size_t y = 0; y < height; ++y) {
523 for (size_t x = 0; x < width; ++x) { 523 for (size_t x = 0; x < width; ++x) {
524 const size_t offset{bpp * (y * width + x)}; 524 const size_t offset{bpp * (y * width + x)};
@@ -584,12 +584,13 @@ void CachedSurface::LoadGLBuffer() {
584 UNREACHABLE(); 584 UNREACHABLE();
585 } 585 }
586 586
587 gl_buffer.resize(params.depth * copy_size); 587 gl_buffer.resize(static_cast<size_t>(params.depth) * copy_size);
588 morton_to_gl_fns[static_cast<size_t>(params.pixel_format)]( 588 morton_to_gl_fns[static_cast<size_t>(params.pixel_format)](
589 params.width, params.block_height, params.height, gl_buffer.data(), copy_size, 589 params.width, params.block_height, params.height, gl_buffer.data(), copy_size,
590 params.addr); 590 params.addr);
591 } else { 591 } else {
592 const u8* const texture_src_data_end{texture_src_data + (params.depth * copy_size)}; 592 const u8* const texture_src_data_end{texture_src_data +
593 (static_cast<size_t>(params.depth) * copy_size)};
593 gl_buffer.assign(texture_src_data, texture_src_data_end); 594 gl_buffer.assign(texture_src_data, texture_src_data_end);
594 } 595 }
595 596
@@ -608,18 +609,20 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle
608 609
609 MICROPROFILE_SCOPE(OpenGL_TextureUL); 610 MICROPROFILE_SCOPE(OpenGL_TextureUL);
610 611
611 ASSERT(gl_buffer.size() == 612 ASSERT(gl_buffer.size() == static_cast<size_t>(params.width) * params.height *
612 params.width * params.height * GetGLBytesPerPixel(params.pixel_format) * params.depth); 613 GetGLBytesPerPixel(params.pixel_format) * params.depth);
613 614
614 const auto& rect{params.GetRect()}; 615 const auto& rect{params.GetRect()};
615 616
616 // Load data from memory to the surface 617 // Load data from memory to the surface
617 GLint x0 = static_cast<GLint>(rect.left); 618 const GLint x0 = static_cast<GLint>(rect.left);
618 GLint y0 = static_cast<GLint>(rect.bottom); 619 const GLint y0 = static_cast<GLint>(rect.bottom);
619 size_t buffer_offset = (y0 * params.width + x0) * GetGLBytesPerPixel(params.pixel_format); 620 const size_t buffer_offset =
621 static_cast<size_t>(static_cast<size_t>(y0) * params.width + static_cast<size_t>(x0)) *
622 GetGLBytesPerPixel(params.pixel_format);
620 623
621 const FormatTuple& tuple = GetFormatTuple(params.pixel_format, params.component_type); 624 const FormatTuple& tuple = GetFormatTuple(params.pixel_format, params.component_type);
622 GLuint target_tex = texture.handle; 625 const GLuint target_tex = texture.handle;
623 OpenGLState cur_state = OpenGLState::GetCurState(); 626 OpenGLState cur_state = OpenGLState::GetCurState();
624 627
625 const auto& old_tex = cur_state.texture_units[0]; 628 const auto& old_tex = cur_state.texture_units[0];
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index 7e4b85ac3..61080f5cc 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -13,8 +13,8 @@ namespace OpenGL {
13 13
14/// Gets the address for the specified shader stage program 14/// Gets the address for the specified shader stage program
15static VAddr GetShaderAddress(Maxwell::ShaderProgram program) { 15static VAddr GetShaderAddress(Maxwell::ShaderProgram program) {
16 auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); 16 const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
17 auto& shader_config = gpu.regs.shader_config[static_cast<size_t>(program)]; 17 const auto& shader_config = gpu.regs.shader_config[static_cast<size_t>(program)];
18 return *gpu.memory_manager.GpuToCpuAddress(gpu.regs.code_address.CodeAddress() + 18 return *gpu.memory_manager.GpuToCpuAddress(gpu.regs.code_address.CodeAddress() +
19 shader_config.offset); 19 shader_config.offset);
20} 20}
@@ -86,7 +86,7 @@ CachedShader::CachedShader(VAddr addr, Maxwell::ShaderProgram program_type)
86} 86}
87 87
88GLuint CachedShader::GetProgramResourceIndex(const GLShader::ConstBufferEntry& buffer) { 88GLuint CachedShader::GetProgramResourceIndex(const GLShader::ConstBufferEntry& buffer) {
89 auto search{resource_cache.find(buffer.GetHash())}; 89 const auto search{resource_cache.find(buffer.GetHash())};
90 if (search == resource_cache.end()) { 90 if (search == resource_cache.end()) {
91 const GLuint index{ 91 const GLuint index{
92 glGetProgramResourceIndex(program.handle, GL_UNIFORM_BLOCK, buffer.GetName().c_str())}; 92 glGetProgramResourceIndex(program.handle, GL_UNIFORM_BLOCK, buffer.GetName().c_str())};
@@ -98,7 +98,7 @@ GLuint CachedShader::GetProgramResourceIndex(const GLShader::ConstBufferEntry& b
98} 98}
99 99
100GLint CachedShader::GetUniformLocation(const GLShader::SamplerEntry& sampler) { 100GLint CachedShader::GetUniformLocation(const GLShader::SamplerEntry& sampler) {
101 auto search{uniform_cache.find(sampler.GetHash())}; 101 const auto search{uniform_cache.find(sampler.GetHash())};
102 if (search == uniform_cache.end()) { 102 if (search == uniform_cache.end()) {
103 const GLint index{glGetUniformLocation(program.handle, sampler.GetName().c_str())}; 103 const GLint index{glGetUniformLocation(program.handle, sampler.GetName().c_str())};
104 uniform_cache[sampler.GetHash()] = index; 104 uniform_cache[sampler.GetHash()] = index;
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 172ba8335..762e58aad 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -113,7 +113,7 @@ private:
113 113
114 /// Scans a range of code for labels and determines the exit method. 114 /// Scans a range of code for labels and determines the exit method.
115 ExitMethod Scan(u32 begin, u32 end, std::set<u32>& labels) { 115 ExitMethod Scan(u32 begin, u32 end, std::set<u32>& labels) {
116 auto [iter, inserted] = 116 const auto [iter, inserted] =
117 exit_method_map.emplace(std::make_pair(begin, end), ExitMethod::Undetermined); 117 exit_method_map.emplace(std::make_pair(begin, end), ExitMethod::Undetermined);
118 ExitMethod& exit_method = iter->second; 118 ExitMethod& exit_method = iter->second;
119 if (!inserted) 119 if (!inserted)
@@ -131,22 +131,22 @@ private:
131 if (instr.pred.pred_index == static_cast<u64>(Pred::UnusedIndex)) { 131 if (instr.pred.pred_index == static_cast<u64>(Pred::UnusedIndex)) {
132 return exit_method = ExitMethod::AlwaysEnd; 132 return exit_method = ExitMethod::AlwaysEnd;
133 } else { 133 } else {
134 ExitMethod not_met = Scan(offset + 1, end, labels); 134 const ExitMethod not_met = Scan(offset + 1, end, labels);
135 return exit_method = ParallelExit(ExitMethod::AlwaysEnd, not_met); 135 return exit_method = ParallelExit(ExitMethod::AlwaysEnd, not_met);
136 } 136 }
137 } 137 }
138 case OpCode::Id::BRA: { 138 case OpCode::Id::BRA: {
139 u32 target = offset + instr.bra.GetBranchTarget(); 139 const u32 target = offset + instr.bra.GetBranchTarget();
140 labels.insert(target); 140 labels.insert(target);
141 ExitMethod no_jmp = Scan(offset + 1, end, labels); 141 const ExitMethod no_jmp = Scan(offset + 1, end, labels);
142 ExitMethod jmp = Scan(target, end, labels); 142 const ExitMethod jmp = Scan(target, end, labels);
143 return exit_method = ParallelExit(no_jmp, jmp); 143 return exit_method = ParallelExit(no_jmp, jmp);
144 } 144 }
145 case OpCode::Id::SSY: { 145 case OpCode::Id::SSY: {
146 // The SSY instruction uses a similar encoding as the BRA instruction. 146 // The SSY instruction uses a similar encoding as the BRA instruction.
147 ASSERT_MSG(instr.bra.constant_buffer == 0, 147 ASSERT_MSG(instr.bra.constant_buffer == 0,
148 "Constant buffer SSY is not supported"); 148 "Constant buffer SSY is not supported");
149 u32 target = offset + instr.bra.GetBranchTarget(); 149 const u32 target = offset + instr.bra.GetBranchTarget();
150 labels.insert(target); 150 labels.insert(target);
151 // Continue scanning for an exit method. 151 // Continue scanning for an exit method.
152 break; 152 break;
@@ -346,8 +346,8 @@ public:
346 */ 346 */
347 void SetRegisterToInputAttibute(const Register& reg, u64 elem, Attribute::Index attribute, 347 void SetRegisterToInputAttibute(const Register& reg, u64 elem, Attribute::Index attribute,
348 const Tegra::Shader::IpaMode& input_mode) { 348 const Tegra::Shader::IpaMode& input_mode) {
349 std::string dest = GetRegisterAsFloat(reg); 349 const std::string dest = GetRegisterAsFloat(reg);
350 std::string src = GetInputAttribute(attribute, input_mode) + GetSwizzle(elem); 350 const std::string src = GetInputAttribute(attribute, input_mode) + GetSwizzle(elem);
351 shader.AddLine(dest + " = " + src + ';'); 351 shader.AddLine(dest + " = " + src + ';');
352 } 352 }
353 353
@@ -359,8 +359,8 @@ public:
359 * @param reg The register to use as the source value. 359 * @param reg The register to use as the source value.
360 */ 360 */
361 void SetOutputAttributeToRegister(Attribute::Index attribute, u64 elem, const Register& reg) { 361 void SetOutputAttributeToRegister(Attribute::Index attribute, u64 elem, const Register& reg) {
362 std::string dest = GetOutputAttribute(attribute); 362 const std::string dest = GetOutputAttribute(attribute);
363 std::string src = GetRegisterAsFloat(reg); 363 const std::string src = GetRegisterAsFloat(reg);
364 364
365 if (!dest.empty()) { 365 if (!dest.empty()) {
366 // Can happen with unknown/unimplemented output attributes, in which case we ignore the 366 // Can happen with unknown/unimplemented output attributes, in which case we ignore the
@@ -393,9 +393,9 @@ public:
393 GLSLRegister::Type type) { 393 GLSLRegister::Type type) {
394 declr_const_buffers[cbuf_index].MarkAsUsedIndirect(cbuf_index, stage); 394 declr_const_buffers[cbuf_index].MarkAsUsedIndirect(cbuf_index, stage);
395 395
396 std::string final_offset = fmt::format("({} + {})", index_str, offset / 4); 396 const std::string final_offset = fmt::format("({} + {})", index_str, offset / 4);
397 std::string value = 'c' + std::to_string(cbuf_index) + '[' + final_offset + " / 4][" + 397 const std::string value = 'c' + std::to_string(cbuf_index) + '[' + final_offset + " / 4][" +
398 final_offset + " % 4]"; 398 final_offset + " % 4]";
399 399
400 if (type == GLSLRegister::Type::Float) { 400 if (type == GLSLRegister::Type::Float) {
401 return value; 401 return value;
@@ -468,10 +468,10 @@ public:
468 /// necessary. 468 /// necessary.
469 std::string AccessSampler(const Sampler& sampler, Tegra::Shader::TextureType type, 469 std::string AccessSampler(const Sampler& sampler, Tegra::Shader::TextureType type,
470 bool is_array) { 470 bool is_array) {
471 size_t offset = static_cast<size_t>(sampler.index.Value()); 471 const size_t offset = static_cast<size_t>(sampler.index.Value());
472 472
473 // If this sampler has already been used, return the existing mapping. 473 // If this sampler has already been used, return the existing mapping.
474 auto itr = 474 const auto itr =
475 std::find_if(used_samplers.begin(), used_samplers.end(), 475 std::find_if(used_samplers.begin(), used_samplers.end(),
476 [&](const SamplerEntry& entry) { return entry.GetOffset() == offset; }); 476 [&](const SamplerEntry& entry) { return entry.GetOffset() == offset; });
477 477
@@ -481,8 +481,8 @@ public:
481 } 481 }
482 482
483 // Otherwise create a new mapping for this sampler 483 // Otherwise create a new mapping for this sampler
484 size_t next_index = used_samplers.size(); 484 const size_t next_index = used_samplers.size();
485 SamplerEntry entry{stage, offset, next_index, type, is_array}; 485 const SamplerEntry entry{stage, offset, next_index, type, is_array};
486 used_samplers.emplace_back(entry); 486 used_samplers.emplace_back(entry);
487 return entry.GetName(); 487 return entry.GetName();
488 } 488 }
@@ -699,7 +699,7 @@ private:
699 }; 699 };
700 700
701 bool IsColorComponentOutputEnabled(u32 render_target, u32 component) const { 701 bool IsColorComponentOutputEnabled(u32 render_target, u32 component) const {
702 u32 bit = render_target * 4 + component; 702 const u32 bit = render_target * 4 + component;
703 return enabled_color_outputs & (1 << bit); 703 return enabled_color_outputs & (1 << bit);
704 } 704 }
705 }; 705 };
@@ -707,7 +707,7 @@ private:
707 707
708 /// Gets the Subroutine object corresponding to the specified address. 708 /// Gets the Subroutine object corresponding to the specified address.
709 const Subroutine& GetSubroutine(u32 begin, u32 end) const { 709 const Subroutine& GetSubroutine(u32 begin, u32 end) const {
710 auto iter = subroutines.find(Subroutine{begin, end, suffix}); 710 const auto iter = subroutines.find(Subroutine{begin, end, suffix});
711 ASSERT(iter != subroutines.end()); 711 ASSERT(iter != subroutines.end());
712 return *iter; 712 return *iter;
713 } 713 }
@@ -752,7 +752,7 @@ private:
752 // Can't assign to the constant predicate. 752 // Can't assign to the constant predicate.
753 ASSERT(pred != static_cast<u64>(Pred::UnusedIndex)); 753 ASSERT(pred != static_cast<u64>(Pred::UnusedIndex));
754 754
755 std::string variable = 'p' + std::to_string(pred) + '_' + suffix; 755 const std::string variable = 'p' + std::to_string(pred) + '_' + suffix;
756 shader.AddLine(variable + " = " + value + ';'); 756 shader.AddLine(variable + " = " + value + ';');
757 declr_predicates.insert(std::move(variable)); 757 declr_predicates.insert(std::move(variable));
758 } 758 }
@@ -1033,7 +1033,11 @@ private:
1033 if (header.writes_depth) { 1033 if (header.writes_depth) {
1034 // The depth output is always 2 registers after the last color output, and current_reg 1034 // The depth output is always 2 registers after the last color output, and current_reg
1035 // already contains one past the last color register. 1035 // already contains one past the last color register.
1036 shader.AddLine("gl_FragDepth = " + regs.GetRegisterAsFloat(current_reg + 1) + ';'); 1036
1037 shader.AddLine(
1038 "gl_FragDepth = " +
1039 regs.GetRegisterAsFloat(static_cast<Tegra::Shader::Register>(current_reg) + 1) +
1040 ';');
1037 } 1041 }
1038 } 1042 }
1039 1043
@@ -1435,7 +1439,7 @@ private:
1435 if (instr.alu_integer.negate_b) 1439 if (instr.alu_integer.negate_b)
1436 op_b = "-(" + op_b + ')'; 1440 op_b = "-(" + op_b + ')';
1437 1441
1438 std::string shift = std::to_string(instr.alu_integer.shift_amount.Value()); 1442 const std::string shift = std::to_string(instr.alu_integer.shift_amount.Value());
1439 1443
1440 regs.SetRegisterToInteger(instr.gpr0, true, 0, 1444 regs.SetRegisterToInteger(instr.gpr0, true, 0,
1441 "((" + op_a + " << " + shift + ") + " + op_b + ')', 1, 1); 1445 "((" + op_a + " << " + shift + ") + " + op_b + ')', 1, 1);
@@ -1453,7 +1457,7 @@ private:
1453 case OpCode::Id::SEL_C: 1457 case OpCode::Id::SEL_C:
1454 case OpCode::Id::SEL_R: 1458 case OpCode::Id::SEL_R:
1455 case OpCode::Id::SEL_IMM: { 1459 case OpCode::Id::SEL_IMM: {
1456 std::string condition = 1460 const std::string condition =
1457 GetPredicateCondition(instr.sel.pred, instr.sel.neg_pred != 0); 1461 GetPredicateCondition(instr.sel.pred, instr.sel.neg_pred != 0);
1458 regs.SetRegisterToInteger(instr.gpr0, true, 0, 1462 regs.SetRegisterToInteger(instr.gpr0, true, 0,
1459 '(' + condition + ") ? " + op_a + " : " + op_b, 1, 1); 1463 '(' + condition + ") ? " + op_a + " : " + op_b, 1, 1);
@@ -1475,8 +1479,9 @@ private:
1475 case OpCode::Id::LOP3_C: 1479 case OpCode::Id::LOP3_C:
1476 case OpCode::Id::LOP3_R: 1480 case OpCode::Id::LOP3_R:
1477 case OpCode::Id::LOP3_IMM: { 1481 case OpCode::Id::LOP3_IMM: {
1478 std::string op_c = regs.GetRegisterAsInteger(instr.gpr39); 1482 const std::string op_c = regs.GetRegisterAsInteger(instr.gpr39);
1479 std::string lut; 1483 std::string lut;
1484
1480 if (opcode->GetId() == OpCode::Id::LOP3_R) { 1485 if (opcode->GetId() == OpCode::Id::LOP3_R) {
1481 lut = '(' + std::to_string(instr.alu.lop3.GetImmLut28()) + ')'; 1486 lut = '(' + std::to_string(instr.alu.lop3.GetImmLut28()) + ')';
1482 } else { 1487 } else {
@@ -1491,9 +1496,9 @@ private:
1491 case OpCode::Id::IMNMX_IMM: { 1496 case OpCode::Id::IMNMX_IMM: {
1492 ASSERT_MSG(instr.imnmx.exchange == Tegra::Shader::IMinMaxExchange::None, 1497 ASSERT_MSG(instr.imnmx.exchange == Tegra::Shader::IMinMaxExchange::None,
1493 "Unimplemented"); 1498 "Unimplemented");
1494 std::string condition = 1499 const std::string condition =
1495 GetPredicateCondition(instr.imnmx.pred, instr.imnmx.negate_pred != 0); 1500 GetPredicateCondition(instr.imnmx.pred, instr.imnmx.negate_pred != 0);
1496 std::string parameters = op_a + ',' + op_b; 1501 const std::string parameters = op_a + ',' + op_b;
1497 regs.SetRegisterToInteger(instr.gpr0, instr.imnmx.is_signed, 0, 1502 regs.SetRegisterToInteger(instr.gpr0, instr.imnmx.is_signed, 0,
1498 '(' + condition + ") ? min(" + parameters + ") : max(" + 1503 '(' + condition + ") ? min(" + parameters + ") : max(" +
1499 parameters + ')', 1504 parameters + ')',
@@ -1510,7 +1515,7 @@ private:
1510 break; 1515 break;
1511 } 1516 }
1512 case OpCode::Type::Ffma: { 1517 case OpCode::Type::Ffma: {
1513 std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); 1518 const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8);
1514 std::string op_b = instr.ffma.negate_b ? "-" : ""; 1519 std::string op_b = instr.ffma.negate_b ? "-" : "";
1515 std::string op_c = instr.ffma.negate_c ? "-" : ""; 1520 std::string op_c = instr.ffma.negate_c ? "-" : "";
1516 1521
@@ -1720,7 +1725,7 @@ private:
1720 shader.AddLine("uint index = (" + regs.GetRegisterAsInteger(instr.gpr8, 0, false) + 1725 shader.AddLine("uint index = (" + regs.GetRegisterAsInteger(instr.gpr8, 0, false) +
1721 " / 4) & (MAX_CONSTBUFFER_ELEMENTS - 1);"); 1726 " / 4) & (MAX_CONSTBUFFER_ELEMENTS - 1);");
1722 1727
1723 std::string op_a = 1728 const std::string op_a =
1724 regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 0, "index", 1729 regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 0, "index",
1725 GLSLRegister::Type::Float); 1730 GLSLRegister::Type::Float);
1726 1731
@@ -1730,7 +1735,7 @@ private:
1730 break; 1735 break;
1731 1736
1732 case Tegra::Shader::UniformType::Double: { 1737 case Tegra::Shader::UniformType::Double: {
1733 std::string op_b = 1738 const std::string op_b =
1734 regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 4, 1739 regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 4,
1735 "index", GLSLRegister::Type::Float); 1740 "index", GLSLRegister::Type::Float);
1736 regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1); 1741 regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1);
@@ -1760,13 +1765,13 @@ private:
1760 1765
1761 switch (texture_type) { 1766 switch (texture_type) {
1762 case Tegra::Shader::TextureType::Texture1D: { 1767 case Tegra::Shader::TextureType::Texture1D: {
1763 std::string x = regs.GetRegisterAsFloat(instr.gpr8); 1768 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
1764 coord = "float coords = " + x + ';'; 1769 coord = "float coords = " + x + ';';
1765 break; 1770 break;
1766 } 1771 }
1767 case Tegra::Shader::TextureType::Texture2D: { 1772 case Tegra::Shader::TextureType::Texture2D: {
1768 std::string x = regs.GetRegisterAsFloat(instr.gpr8); 1773 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
1769 std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 1774 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
1770 coord = "vec2 coords = vec2(" + x + ", " + y + ");"; 1775 coord = "vec2 coords = vec2(" + x + ", " + y + ");";
1771 break; 1776 break;
1772 } 1777 }
@@ -1776,8 +1781,8 @@ private:
1776 UNREACHABLE(); 1781 UNREACHABLE();
1777 1782
1778 // Fallback to interpreting as a 2D texture for now 1783 // Fallback to interpreting as a 2D texture for now
1779 std::string x = regs.GetRegisterAsFloat(instr.gpr8); 1784 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
1780 std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 1785 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
1781 coord = "vec2 coords = vec2(" + x + ", " + y + ");"; 1786 coord = "vec2 coords = vec2(" + x + ", " + y + ");";
1782 texture_type = Tegra::Shader::TextureType::Texture2D; 1787 texture_type = Tegra::Shader::TextureType::Texture2D;
1783 } 1788 }
@@ -1811,13 +1816,13 @@ private:
1811 switch (texture_type) { 1816 switch (texture_type) {
1812 case Tegra::Shader::TextureType::Texture2D: { 1817 case Tegra::Shader::TextureType::Texture2D: {
1813 if (is_array) { 1818 if (is_array) {
1814 std::string index = regs.GetRegisterAsInteger(instr.gpr8); 1819 const std::string index = regs.GetRegisterAsInteger(instr.gpr8);
1815 std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 1820 const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
1816 std::string y = regs.GetRegisterAsFloat(instr.gpr20); 1821 const std::string y = regs.GetRegisterAsFloat(instr.gpr20);
1817 coord = "vec3 coords = vec3(" + x + ", " + y + ", " + index + ");"; 1822 coord = "vec3 coords = vec3(" + x + ", " + y + ", " + index + ");";
1818 } else { 1823 } else {
1819 std::string x = regs.GetRegisterAsFloat(instr.gpr8); 1824 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
1820 std::string y = regs.GetRegisterAsFloat(instr.gpr20); 1825 const std::string y = regs.GetRegisterAsFloat(instr.gpr20);
1821 coord = "vec2 coords = vec2(" + x + ", " + y + ");"; 1826 coord = "vec2 coords = vec2(" + x + ", " + y + ");";
1822 } 1827 }
1823 break; 1828 break;
@@ -1828,8 +1833,8 @@ private:
1828 UNREACHABLE(); 1833 UNREACHABLE();
1829 1834
1830 // Fallback to interpreting as a 2D texture for now 1835 // Fallback to interpreting as a 2D texture for now
1831 std::string x = regs.GetRegisterAsFloat(instr.gpr8); 1836 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
1832 std::string y = regs.GetRegisterAsFloat(instr.gpr20); 1837 const std::string y = regs.GetRegisterAsFloat(instr.gpr20);
1833 coord = "vec2 coords = vec2(" + x + ", " + y + ");"; 1838 coord = "vec2 coords = vec2(" + x + ", " + y + ");";
1834 texture_type = Tegra::Shader::TextureType::Texture2D; 1839 texture_type = Tegra::Shader::TextureType::Texture2D;
1835 is_array = false; 1840 is_array = false;
@@ -1850,8 +1855,8 @@ private:
1850 LOG_CRITICAL(HW_GPU, "Unhandled 2d array texture"); 1855 LOG_CRITICAL(HW_GPU, "Unhandled 2d array texture");
1851 UNREACHABLE(); 1856 UNREACHABLE();
1852 } else { 1857 } else {
1853 std::string x = regs.GetRegisterAsInteger(instr.gpr8); 1858 const std::string x = regs.GetRegisterAsInteger(instr.gpr8);
1854 std::string y = regs.GetRegisterAsInteger(instr.gpr20); 1859 const std::string y = regs.GetRegisterAsInteger(instr.gpr20);
1855 coord = "ivec2 coords = ivec2(" + x + ", " + y + ");"; 1860 coord = "ivec2 coords = ivec2(" + x + ", " + y + ");";
1856 } 1861 }
1857 break; 1862 break;
@@ -1874,8 +1879,8 @@ private:
1874 1879
1875 switch (instr.tld4.texture_type) { 1880 switch (instr.tld4.texture_type) {
1876 case Tegra::Shader::TextureType::Texture2D: { 1881 case Tegra::Shader::TextureType::Texture2D: {
1877 std::string x = regs.GetRegisterAsFloat(instr.gpr8); 1882 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
1878 std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 1883 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
1879 coord = "vec2 coords = vec2(" + x + ", " + y + ");"; 1884 coord = "vec2 coords = vec2(" + x + ", " + y + ");";
1880 break; 1885 break;
1881 } 1886 }
@@ -1920,6 +1925,74 @@ private:
1920 WriteTexsInstruction(instr, coord, texture); 1925 WriteTexsInstruction(instr, coord, texture);
1921 break; 1926 break;
1922 } 1927 }
1928 case OpCode::Id::TXQ: {
1929 // TODO: the new commits on the texture refactor, change the way samplers work.
1930 // Sadly, not all texture instructions specify the type of texture their sampler
1931 // uses. This must be fixed at a later instance.
1932 const std::string sampler =
1933 GetSampler(instr.sampler, Tegra::Shader::TextureType::Texture2D, false);
1934 switch (instr.txq.query_type) {
1935 case Tegra::Shader::TextureQueryType::Dimension: {
1936 const std::string texture = "textureQueryLevels(" + sampler + ')';
1937 regs.SetRegisterToInteger(instr.gpr0, true, 0, texture, 1, 1);
1938 break;
1939 }
1940 default: {
1941 LOG_CRITICAL(HW_GPU, "Unhandled texture query type: {}",
1942 static_cast<u32>(instr.txq.query_type.Value()));
1943 UNREACHABLE();
1944 }
1945 }
1946 break;
1947 }
1948 case OpCode::Id::TMML: {
1949 const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8);
1950 const std::string op_b = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
1951 const bool is_array = instr.tmml.array != 0;
1952 auto texture_type = instr.tmml.texture_type.Value();
1953 const std::string sampler = GetSampler(instr.sampler, texture_type, is_array);
1954
1955 // TODO: add coordinates for different samplers once other texture types are
1956 // implemented.
1957 std::string coord;
1958 switch (texture_type) {
1959 case Tegra::Shader::TextureType::Texture1D: {
1960 std::string x = regs.GetRegisterAsFloat(instr.gpr8);
1961 coord = "float coords = " + x + ';';
1962 break;
1963 }
1964 case Tegra::Shader::TextureType::Texture2D: {
1965 std::string x = regs.GetRegisterAsFloat(instr.gpr8);
1966 std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
1967 coord = "vec2 coords = vec2(" + x + ", " + y + ");";
1968 break;
1969 }
1970 default:
1971 LOG_CRITICAL(HW_GPU, "Unhandled texture type {}",
1972 static_cast<u32>(texture_type));
1973 UNREACHABLE();
1974
1975 // Fallback to interpreting as a 2D texture for now
1976 std::string x = regs.GetRegisterAsFloat(instr.gpr8);
1977 std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
1978 coord = "vec2 coords = vec2(" + x + ", " + y + ");";
1979 texture_type = Tegra::Shader::TextureType::Texture2D;
1980 }
1981 // Add an extra scope and declare the texture coords inside to prevent
1982 // overwriting them in case they are used as outputs of the texs instruction.
1983 shader.AddLine('{');
1984 ++shader.scope;
1985 shader.AddLine(coord);
1986 const std::string texture = "textureQueryLod(" + sampler + ", coords)";
1987 const std::string tmp = "vec2 tmp = " + texture + "*vec2(256.0, 256.0);";
1988 shader.AddLine(tmp);
1989
1990 regs.SetRegisterToInteger(instr.gpr0, true, 0, "int(tmp.y)", 1, 1);
1991 regs.SetRegisterToInteger(instr.gpr0.Value() + 1, false, 0, "uint(tmp.x)", 1, 1);
1992 --shader.scope;
1993 shader.AddLine('}');
1994 break;
1995 }
1923 default: { 1996 default: {
1924 LOG_CRITICAL(HW_GPU, "Unhandled memory instruction: {}", opcode->GetName()); 1997 LOG_CRITICAL(HW_GPU, "Unhandled memory instruction: {}", opcode->GetName());
1925 UNREACHABLE(); 1998 UNREACHABLE();
@@ -1959,12 +2032,12 @@ private:
1959 // We can't use the constant predicate as destination. 2032 // We can't use the constant predicate as destination.
1960 ASSERT(instr.fsetp.pred3 != static_cast<u64>(Pred::UnusedIndex)); 2033 ASSERT(instr.fsetp.pred3 != static_cast<u64>(Pred::UnusedIndex));
1961 2034
1962 std::string second_pred = 2035 const std::string second_pred =
1963 GetPredicateCondition(instr.fsetp.pred39, instr.fsetp.neg_pred != 0); 2036 GetPredicateCondition(instr.fsetp.pred39, instr.fsetp.neg_pred != 0);
1964 2037
1965 std::string combiner = GetPredicateCombiner(instr.fsetp.op); 2038 const std::string combiner = GetPredicateCombiner(instr.fsetp.op);
1966 2039
1967 std::string predicate = GetPredicateComparison(instr.fsetp.cond, op_a, op_b); 2040 const std::string predicate = GetPredicateComparison(instr.fsetp.cond, op_a, op_b);
1968 // Set the primary predicate to the result of Predicate OP SecondPredicate 2041 // Set the primary predicate to the result of Predicate OP SecondPredicate
1969 SetPredicate(instr.fsetp.pred3, 2042 SetPredicate(instr.fsetp.pred3,
1970 '(' + predicate + ") " + combiner + " (" + second_pred + ')'); 2043 '(' + predicate + ") " + combiner + " (" + second_pred + ')');
@@ -1978,7 +2051,8 @@ private:
1978 break; 2051 break;
1979 } 2052 }
1980 case OpCode::Type::IntegerSetPredicate: { 2053 case OpCode::Type::IntegerSetPredicate: {
1981 std::string op_a = regs.GetRegisterAsInteger(instr.gpr8, 0, instr.isetp.is_signed); 2054 const std::string op_a =
2055 regs.GetRegisterAsInteger(instr.gpr8, 0, instr.isetp.is_signed);
1982 std::string op_b; 2056 std::string op_b;
1983 2057
1984 if (instr.is_b_imm) { 2058 if (instr.is_b_imm) {
@@ -1995,12 +2069,12 @@ private:
1995 // We can't use the constant predicate as destination. 2069 // We can't use the constant predicate as destination.
1996 ASSERT(instr.isetp.pred3 != static_cast<u64>(Pred::UnusedIndex)); 2070 ASSERT(instr.isetp.pred3 != static_cast<u64>(Pred::UnusedIndex));
1997 2071
1998 std::string second_pred = 2072 const std::string second_pred =
1999 GetPredicateCondition(instr.isetp.pred39, instr.isetp.neg_pred != 0); 2073 GetPredicateCondition(instr.isetp.pred39, instr.isetp.neg_pred != 0);
2000 2074
2001 std::string combiner = GetPredicateCombiner(instr.isetp.op); 2075 const std::string combiner = GetPredicateCombiner(instr.isetp.op);
2002 2076
2003 std::string predicate = GetPredicateComparison(instr.isetp.cond, op_a, op_b); 2077 const std::string predicate = GetPredicateComparison(instr.isetp.cond, op_a, op_b);
2004 // Set the primary predicate to the result of Predicate OP SecondPredicate 2078 // Set the primary predicate to the result of Predicate OP SecondPredicate
2005 SetPredicate(instr.isetp.pred3, 2079 SetPredicate(instr.isetp.pred3,
2006 '(' + predicate + ") " + combiner + " (" + second_pred + ')'); 2080 '(' + predicate + ") " + combiner + " (" + second_pred + ')');
@@ -2014,20 +2088,20 @@ private:
2014 break; 2088 break;
2015 } 2089 }
2016 case OpCode::Type::PredicateSetPredicate: { 2090 case OpCode::Type::PredicateSetPredicate: {
2017 std::string op_a = 2091 const std::string op_a =
2018 GetPredicateCondition(instr.psetp.pred12, instr.psetp.neg_pred12 != 0); 2092 GetPredicateCondition(instr.psetp.pred12, instr.psetp.neg_pred12 != 0);
2019 std::string op_b = 2093 const std::string op_b =
2020 GetPredicateCondition(instr.psetp.pred29, instr.psetp.neg_pred29 != 0); 2094 GetPredicateCondition(instr.psetp.pred29, instr.psetp.neg_pred29 != 0);
2021 2095
2022 // We can't use the constant predicate as destination. 2096 // We can't use the constant predicate as destination.
2023 ASSERT(instr.psetp.pred3 != static_cast<u64>(Pred::UnusedIndex)); 2097 ASSERT(instr.psetp.pred3 != static_cast<u64>(Pred::UnusedIndex));
2024 2098
2025 std::string second_pred = 2099 const std::string second_pred =
2026 GetPredicateCondition(instr.psetp.pred39, instr.psetp.neg_pred39 != 0); 2100 GetPredicateCondition(instr.psetp.pred39, instr.psetp.neg_pred39 != 0);
2027 2101
2028 std::string combiner = GetPredicateCombiner(instr.psetp.op); 2102 const std::string combiner = GetPredicateCombiner(instr.psetp.op);
2029 2103
2030 std::string predicate = 2104 const std::string predicate =
2031 '(' + op_a + ") " + GetPredicateCombiner(instr.psetp.cond) + " (" + op_b + ')'; 2105 '(' + op_a + ") " + GetPredicateCombiner(instr.psetp.cond) + " (" + op_b + ')';
2032 2106
2033 // Set the primary predicate to the result of Predicate OP SecondPredicate 2107 // Set the primary predicate to the result of Predicate OP SecondPredicate
@@ -2053,7 +2127,7 @@ private:
2053 std::string op_b = instr.fset.neg_b ? "-" : ""; 2127 std::string op_b = instr.fset.neg_b ? "-" : "";
2054 2128
2055 if (instr.is_b_imm) { 2129 if (instr.is_b_imm) {
2056 std::string imm = GetImmediate19(instr); 2130 const std::string imm = GetImmediate19(instr);
2057 if (instr.fset.neg_imm) 2131 if (instr.fset.neg_imm)
2058 op_b += "(-" + imm + ')'; 2132 op_b += "(-" + imm + ')';
2059 else 2133 else
@@ -2073,13 +2147,14 @@ private:
2073 2147
2074 // The fset instruction sets a register to 1.0 or -1 (depending on the bf bit) if the 2148 // The fset instruction sets a register to 1.0 or -1 (depending on the bf bit) if the
2075 // condition is true, and to 0 otherwise. 2149 // condition is true, and to 0 otherwise.
2076 std::string second_pred = 2150 const std::string second_pred =
2077 GetPredicateCondition(instr.fset.pred39, instr.fset.neg_pred != 0); 2151 GetPredicateCondition(instr.fset.pred39, instr.fset.neg_pred != 0);
2078 2152
2079 std::string combiner = GetPredicateCombiner(instr.fset.op); 2153 const std::string combiner = GetPredicateCombiner(instr.fset.op);
2080 2154
2081 std::string predicate = "((" + GetPredicateComparison(instr.fset.cond, op_a, op_b) + 2155 const std::string predicate = "((" +
2082 ") " + combiner + " (" + second_pred + "))"; 2156 GetPredicateComparison(instr.fset.cond, op_a, op_b) +
2157 ") " + combiner + " (" + second_pred + "))";
2083 2158
2084 if (instr.fset.bf) { 2159 if (instr.fset.bf) {
2085 regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1); 2160 regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1);
@@ -2090,7 +2165,7 @@ private:
2090 break; 2165 break;
2091 } 2166 }
2092 case OpCode::Type::IntegerSet: { 2167 case OpCode::Type::IntegerSet: {
2093 std::string op_a = regs.GetRegisterAsInteger(instr.gpr8, 0, instr.iset.is_signed); 2168 const std::string op_a = regs.GetRegisterAsInteger(instr.gpr8, 0, instr.iset.is_signed);
2094 2169
2095 std::string op_b; 2170 std::string op_b;
2096 2171
@@ -2107,13 +2182,14 @@ private:
2107 2182
2108 // The iset instruction sets a register to 1.0 or -1 (depending on the bf bit) if the 2183 // The iset instruction sets a register to 1.0 or -1 (depending on the bf bit) if the
2109 // condition is true, and to 0 otherwise. 2184 // condition is true, and to 0 otherwise.
2110 std::string second_pred = 2185 const std::string second_pred =
2111 GetPredicateCondition(instr.iset.pred39, instr.iset.neg_pred != 0); 2186 GetPredicateCondition(instr.iset.pred39, instr.iset.neg_pred != 0);
2112 2187
2113 std::string combiner = GetPredicateCombiner(instr.iset.op); 2188 const std::string combiner = GetPredicateCombiner(instr.iset.op);
2114 2189
2115 std::string predicate = "((" + GetPredicateComparison(instr.iset.cond, op_a, op_b) + 2190 const std::string predicate = "((" +
2116 ") " + combiner + " (" + second_pred + "))"; 2191 GetPredicateComparison(instr.iset.cond, op_a, op_b) +
2192 ") " + combiner + " (" + second_pred + "))";
2117 2193
2118 if (instr.iset.bf) { 2194 if (instr.iset.bf) {
2119 regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1); 2195 regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1);
@@ -2263,7 +2339,7 @@ private:
2263 case OpCode::Id::BRA: { 2339 case OpCode::Id::BRA: {
2264 ASSERT_MSG(instr.bra.constant_buffer == 0, 2340 ASSERT_MSG(instr.bra.constant_buffer == 0,
2265 "BRA with constant buffers are not implemented"); 2341 "BRA with constant buffers are not implemented");
2266 u32 target = offset + instr.bra.GetBranchTarget(); 2342 const u32 target = offset + instr.bra.GetBranchTarget();
2267 shader.AddLine("{ jmp_to = " + std::to_string(target) + "u; break; }"); 2343 shader.AddLine("{ jmp_to = " + std::to_string(target) + "u; break; }");
2268 break; 2344 break;
2269 } 2345 }
@@ -2287,7 +2363,7 @@ private:
2287 // has a similar structure to the BRA opcode. 2363 // has a similar structure to the BRA opcode.
2288 ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer SSY is not supported"); 2364 ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer SSY is not supported");
2289 2365
2290 u32 target = offset + instr.bra.GetBranchTarget(); 2366 const u32 target = offset + instr.bra.GetBranchTarget();
2291 EmitPushToSSYStack(target); 2367 EmitPushToSSYStack(target);
2292 break; 2368 break;
2293 } 2369 }
@@ -2381,10 +2457,10 @@ private:
2381 shader.AddLine("case " + std::to_string(label) + "u: {"); 2457 shader.AddLine("case " + std::to_string(label) + "u: {");
2382 ++shader.scope; 2458 ++shader.scope;
2383 2459
2384 auto next_it = labels.lower_bound(label + 1); 2460 const auto next_it = labels.lower_bound(label + 1);
2385 u32 next_label = next_it == labels.end() ? subroutine.end : *next_it; 2461 const u32 next_label = next_it == labels.end() ? subroutine.end : *next_it;
2386 2462
2387 u32 compile_end = CompileRange(label, next_label); 2463 const u32 compile_end = CompileRange(label, next_label);
2388 if (compile_end > next_label && compile_end != PROGRAM_END) { 2464 if (compile_end > next_label && compile_end != PROGRAM_END) {
2389 // This happens only when there is a label inside a IF/LOOP block 2465 // This happens only when there is a label inside a IF/LOOP block
2390 shader.AddLine(" jmp_to = " + std::to_string(compile_end) + "u; break; }"); 2466 shader.AddLine(" jmp_to = " + std::to_string(compile_end) + "u; break; }");
@@ -2447,7 +2523,8 @@ boost::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code,
2447 Maxwell3D::Regs::ShaderStage stage, 2523 Maxwell3D::Regs::ShaderStage stage,
2448 const std::string& suffix) { 2524 const std::string& suffix) {
2449 try { 2525 try {
2450 auto subroutines = ControlFlowAnalyzer(program_code, main_offset, suffix).GetSubroutines(); 2526 const auto subroutines =
2527 ControlFlowAnalyzer(program_code, main_offset, suffix).GetSubroutines();
2451 GLSLGenerator generator(subroutines, program_code, main_offset, stage, suffix); 2528 GLSLGenerator generator(subroutines, program_code, main_offset, stage, suffix);
2452 return ProgramResult{generator.GetShaderCode(), generator.GetEntries()}; 2529 return ProgramResult{generator.GetShaderCode(), generator.GetEntries()};
2453 } catch (const DecompileFail& exception) { 2530 } catch (const DecompileFail& exception) {
diff --git a/src/video_core/renderer_opengl/gl_shader_util.cpp b/src/video_core/renderer_opengl/gl_shader_util.cpp
index 5781d9d16..5f3fe067e 100644
--- a/src/video_core/renderer_opengl/gl_shader_util.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_util.cpp
@@ -25,7 +25,7 @@ GLuint LoadShader(const char* source, GLenum type) {
25 default: 25 default:
26 UNREACHABLE(); 26 UNREACHABLE();
27 } 27 }
28 GLuint shader_id = glCreateShader(type); 28 const GLuint shader_id = glCreateShader(type);
29 glShaderSource(shader_id, 1, &source, nullptr); 29 glShaderSource(shader_id, 1, &source, nullptr);
30 LOG_DEBUG(Render_OpenGL, "Compiling {} shader...", debug_type); 30 LOG_DEBUG(Render_OpenGL, "Compiling {} shader...", debug_type);
31 glCompileShader(shader_id); 31 glCompileShader(shader_id);
diff --git a/src/video_core/renderer_opengl/gl_stream_buffer.cpp b/src/video_core/renderer_opengl/gl_stream_buffer.cpp
index e565afcee..aadf68f16 100644
--- a/src/video_core/renderer_opengl/gl_stream_buffer.cpp
+++ b/src/video_core/renderer_opengl/gl_stream_buffer.cpp
@@ -29,7 +29,7 @@ OGLStreamBuffer::OGLStreamBuffer(GLenum target, GLsizeiptr size, bool prefer_coh
29 if (GLAD_GL_ARB_buffer_storage) { 29 if (GLAD_GL_ARB_buffer_storage) {
30 persistent = true; 30 persistent = true;
31 coherent = prefer_coherent; 31 coherent = prefer_coherent;
32 GLbitfield flags = 32 const GLbitfield flags =
33 GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | (coherent ? GL_MAP_COHERENT_BIT : 0); 33 GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | (coherent ? GL_MAP_COHERENT_BIT : 0);
34 glBufferStorage(gl_target, allocate_size, nullptr, flags); 34 glBufferStorage(gl_target, allocate_size, nullptr, flags);
35 mapped_ptr = static_cast<u8*>(glMapBufferRange( 35 mapped_ptr = static_cast<u8*>(glMapBufferRange(