summaryrefslogtreecommitdiff
path: root/src/video_core
diff options
context:
space:
mode:
authorGravatar Frederic L2018-10-30 05:03:25 +0100
committerGravatar bunnei2018-10-30 00:03:25 -0400
commit7a5eda59146306dedaf3e6f07f97a8c6898543dd (patch)
tree78e07b43fb0113f95e1c8e9426d3b394b9524d4e /src/video_core
parentMerge pull request #1621 from lioncash/ipc (diff)
downloadyuzu-7a5eda59146306dedaf3e6f07f97a8c6898543dd.tar.gz
yuzu-7a5eda59146306dedaf3e6f07f97a8c6898543dd.tar.xz
yuzu-7a5eda59146306dedaf3e6f07f97a8c6898543dd.zip
global: Use std::optional instead of boost::optional (#1578)
* get rid of boost::optional * Remove optional references * Use std::reference_wrapper for optional references * Fix clang format * Fix clang format part 2 * Adressed feedback * Fix clang format and MacOS build
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/command_processor.cpp2
-rw-r--r--src/video_core/engines/maxwell_3d.cpp10
-rw-r--r--src/video_core/engines/shader_bytecode.h8
-rw-r--r--src/video_core/macro_interpreter.cpp6
-rw-r--r--src/video_core/macro_interpreter.h5
-rw-r--r--src/video_core/memory_manager.cpp8
-rw-r--r--src/video_core/memory_manager.h7
-rw-r--r--src/video_core/renderer_base.h6
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_primitive_assembler.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h4
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp112
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.h8
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.cpp8
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp11
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.h3
17 files changed, 107 insertions, 97 deletions
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp
index f1aa6091b..28e8c13aa 100644
--- a/src/video_core/command_processor.cpp
+++ b/src/video_core/command_processor.cpp
@@ -81,7 +81,7 @@ void GPU::ProcessCommandLists(const std::vector<CommandListHeader>& commands) {
81 for (auto entry : commands) { 81 for (auto entry : commands) {
82 Tegra::GPUVAddr address = entry.Address(); 82 Tegra::GPUVAddr address = entry.Address();
83 u32 size = entry.sz; 83 u32 size = entry.sz;
84 const boost::optional<VAddr> head_address = memory_manager->GpuToCpuAddress(address); 84 const std::optional<VAddr> head_address = memory_manager->GpuToCpuAddress(address);
85 VAddr current_addr = *head_address; 85 VAddr current_addr = *head_address;
86 while (current_addr < *head_address + size * sizeof(CommandHeader)) { 86 while (current_addr < *head_address + size * sizeof(CommandHeader)) {
87 const CommandHeader header = {Memory::Read32(current_addr)}; 87 const CommandHeader header = {Memory::Read32(current_addr)};
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 27ef865a2..7357d20d1 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -167,7 +167,7 @@ void Maxwell3D::ProcessQueryGet() {
167 GPUVAddr sequence_address = regs.query.QueryAddress(); 167 GPUVAddr sequence_address = regs.query.QueryAddress();
168 // Since the sequence address is given as a GPU VAddr, we have to convert it to an application 168 // Since the sequence address is given as a GPU VAddr, we have to convert it to an application
169 // VAddr before writing. 169 // VAddr before writing.
170 boost::optional<VAddr> address = memory_manager.GpuToCpuAddress(sequence_address); 170 std::optional<VAddr> address = memory_manager.GpuToCpuAddress(sequence_address);
171 171
172 // TODO(Subv): Support the other query units. 172 // TODO(Subv): Support the other query units.
173 ASSERT_MSG(regs.query.query_get.unit == Regs::QueryUnit::Crop, 173 ASSERT_MSG(regs.query.query_get.unit == Regs::QueryUnit::Crop,
@@ -285,7 +285,7 @@ void Maxwell3D::ProcessCBData(u32 value) {
285 // Don't allow writing past the end of the buffer. 285 // Don't allow writing past the end of the buffer.
286 ASSERT(regs.const_buffer.cb_pos + sizeof(u32) <= regs.const_buffer.cb_size); 286 ASSERT(regs.const_buffer.cb_pos + sizeof(u32) <= regs.const_buffer.cb_size);
287 287
288 boost::optional<VAddr> address = 288 std::optional<VAddr> address =
289 memory_manager.GpuToCpuAddress(buffer_address + regs.const_buffer.cb_pos); 289 memory_manager.GpuToCpuAddress(buffer_address + regs.const_buffer.cb_pos);
290 290
291 Memory::Write32(*address, value); 291 Memory::Write32(*address, value);
@@ -298,7 +298,7 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const {
298 GPUVAddr tic_base_address = regs.tic.TICAddress(); 298 GPUVAddr tic_base_address = regs.tic.TICAddress();
299 299
300 GPUVAddr tic_address_gpu = tic_base_address + tic_index * sizeof(Texture::TICEntry); 300 GPUVAddr tic_address_gpu = tic_base_address + tic_index * sizeof(Texture::TICEntry);
301 boost::optional<VAddr> tic_address_cpu = memory_manager.GpuToCpuAddress(tic_address_gpu); 301 std::optional<VAddr> tic_address_cpu = memory_manager.GpuToCpuAddress(tic_address_gpu);
302 302
303 Texture::TICEntry tic_entry; 303 Texture::TICEntry tic_entry;
304 Memory::ReadBlock(*tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry)); 304 Memory::ReadBlock(*tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry));
@@ -322,7 +322,7 @@ Texture::TSCEntry Maxwell3D::GetTSCEntry(u32 tsc_index) const {
322 GPUVAddr tsc_base_address = regs.tsc.TSCAddress(); 322 GPUVAddr tsc_base_address = regs.tsc.TSCAddress();
323 323
324 GPUVAddr tsc_address_gpu = tsc_base_address + tsc_index * sizeof(Texture::TSCEntry); 324 GPUVAddr tsc_address_gpu = tsc_base_address + tsc_index * sizeof(Texture::TSCEntry);
325 boost::optional<VAddr> tsc_address_cpu = memory_manager.GpuToCpuAddress(tsc_address_gpu); 325 std::optional<VAddr> tsc_address_cpu = memory_manager.GpuToCpuAddress(tsc_address_gpu);
326 326
327 Texture::TSCEntry tsc_entry; 327 Texture::TSCEntry tsc_entry;
328 Memory::ReadBlock(*tsc_address_cpu, &tsc_entry, sizeof(Texture::TSCEntry)); 328 Memory::ReadBlock(*tsc_address_cpu, &tsc_entry, sizeof(Texture::TSCEntry));
@@ -386,7 +386,7 @@ Texture::FullTextureInfo Maxwell3D::GetStageTexture(Regs::ShaderStage stage,
386 386
387 ASSERT(tex_info_address < tex_info_buffer.address + tex_info_buffer.size); 387 ASSERT(tex_info_address < tex_info_buffer.address + tex_info_buffer.size);
388 388
389 boost::optional<VAddr> tex_address_cpu = memory_manager.GpuToCpuAddress(tex_info_address); 389 std::optional<VAddr> tex_address_cpu = memory_manager.GpuToCpuAddress(tex_info_address);
390 Texture::TextureHandle tex_handle{Memory::Read32(*tex_address_cpu)}; 390 Texture::TextureHandle tex_handle{Memory::Read32(*tex_address_cpu)};
391 391
392 Texture::FullTextureInfo tex_info{}; 392 Texture::FullTextureInfo tex_info{};
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 141b9159b..b84da512f 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -5,12 +5,11 @@
5#pragma once 5#pragma once
6 6
7#include <bitset> 7#include <bitset>
8#include <optional>
8#include <string> 9#include <string>
9#include <tuple> 10#include <tuple>
10#include <vector> 11#include <vector>
11 12
12#include <boost/optional.hpp>
13
14#include "common/assert.h" 13#include "common/assert.h"
15#include "common/bit_field.h" 14#include "common/bit_field.h"
16#include "common/common_types.h" 15#include "common/common_types.h"
@@ -1456,7 +1455,7 @@ public:
1456 Type type; 1455 Type type;
1457 }; 1456 };
1458 1457
1459 static boost::optional<const Matcher&> Decode(Instruction instr) { 1458 static std::optional<std::reference_wrapper<const Matcher>> Decode(Instruction instr) {
1460 static const auto table{GetDecodeTable()}; 1459 static const auto table{GetDecodeTable()};
1461 1460
1462 const auto matches_instruction = [instr](const auto& matcher) { 1461 const auto matches_instruction = [instr](const auto& matcher) {
@@ -1464,7 +1463,8 @@ public:
1464 }; 1463 };
1465 1464
1466 auto iter = std::find_if(table.begin(), table.end(), matches_instruction); 1465 auto iter = std::find_if(table.begin(), table.end(), matches_instruction);
1467 return iter != table.end() ? boost::optional<const Matcher&>(*iter) : boost::none; 1466 return iter != table.end() ? std::optional<std::reference_wrapper<const Matcher>>(*iter)
1467 : std::nullopt;
1468 } 1468 }
1469 1469
1470private: 1470private:
diff --git a/src/video_core/macro_interpreter.cpp b/src/video_core/macro_interpreter.cpp
index 377bd66ab..f6af132fb 100644
--- a/src/video_core/macro_interpreter.cpp
+++ b/src/video_core/macro_interpreter.cpp
@@ -29,7 +29,7 @@ void MacroInterpreter::Execute(const std::vector<u32>& code, std::vector<u32> pa
29void MacroInterpreter::Reset() { 29void MacroInterpreter::Reset() {
30 registers = {}; 30 registers = {};
31 pc = 0; 31 pc = 0;
32 delayed_pc = boost::none; 32 delayed_pc = {};
33 method_address.raw = 0; 33 method_address.raw = 0;
34 parameters.clear(); 34 parameters.clear();
35 // The next parameter index starts at 1, because $r1 already has the value of the first 35 // The next parameter index starts at 1, because $r1 already has the value of the first
@@ -44,10 +44,10 @@ bool MacroInterpreter::Step(const std::vector<u32>& code, bool is_delay_slot) {
44 pc += 4; 44 pc += 4;
45 45
46 // Update the program counter if we were delayed 46 // Update the program counter if we were delayed
47 if (delayed_pc != boost::none) { 47 if (delayed_pc) {
48 ASSERT(is_delay_slot); 48 ASSERT(is_delay_slot);
49 pc = *delayed_pc; 49 pc = *delayed_pc;
50 delayed_pc = boost::none; 50 delayed_pc = {};
51 } 51 }
52 52
53 switch (opcode.operation) { 53 switch (opcode.operation) {
diff --git a/src/video_core/macro_interpreter.h b/src/video_core/macro_interpreter.h
index cee0baaf3..773684bde 100644
--- a/src/video_core/macro_interpreter.h
+++ b/src/video_core/macro_interpreter.h
@@ -5,8 +5,9 @@
5#pragma once 5#pragma once
6 6
7#include <array> 7#include <array>
8#include <optional>
8#include <vector> 9#include <vector>
9#include <boost/optional.hpp> 10
10#include "common/bit_field.h" 11#include "common/bit_field.h"
11#include "common/common_types.h" 12#include "common/common_types.h"
12 13
@@ -149,7 +150,7 @@ private:
149 Engines::Maxwell3D& maxwell3d; 150 Engines::Maxwell3D& maxwell3d;
150 151
151 u32 pc; ///< Current program counter 152 u32 pc; ///< Current program counter
152 boost::optional<u32> 153 std::optional<u32>
153 delayed_pc; ///< Program counter to execute at after the delay slot is executed. 154 delayed_pc; ///< Program counter to execute at after the delay slot is executed.
154 155
155 static constexpr std::size_t NumMacroRegisters = 8; 156 static constexpr std::size_t NumMacroRegisters = 8;
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp
index 022d4ab74..90a8e825d 100644
--- a/src/video_core/memory_manager.cpp
+++ b/src/video_core/memory_manager.cpp
@@ -9,7 +9,7 @@
9namespace Tegra { 9namespace Tegra {
10 10
11GPUVAddr MemoryManager::AllocateSpace(u64 size, u64 align) { 11GPUVAddr MemoryManager::AllocateSpace(u64 size, u64 align) {
12 boost::optional<GPUVAddr> gpu_addr = FindFreeBlock(size, align); 12 std::optional<GPUVAddr> gpu_addr = FindFreeBlock(size, align);
13 ASSERT(gpu_addr); 13 ASSERT(gpu_addr);
14 14
15 for (u64 offset = 0; offset < size; offset += PAGE_SIZE) { 15 for (u64 offset = 0; offset < size; offset += PAGE_SIZE) {
@@ -34,7 +34,7 @@ GPUVAddr MemoryManager::AllocateSpace(GPUVAddr gpu_addr, u64 size, u64 align) {
34} 34}
35 35
36GPUVAddr MemoryManager::MapBufferEx(VAddr cpu_addr, u64 size) { 36GPUVAddr MemoryManager::MapBufferEx(VAddr cpu_addr, u64 size) {
37 boost::optional<GPUVAddr> gpu_addr = FindFreeBlock(size, PAGE_SIZE); 37 std::optional<GPUVAddr> gpu_addr = FindFreeBlock(size, PAGE_SIZE);
38 ASSERT(gpu_addr); 38 ASSERT(gpu_addr);
39 39
40 for (u64 offset = 0; offset < size; offset += PAGE_SIZE) { 40 for (u64 offset = 0; offset < size; offset += PAGE_SIZE) {
@@ -97,7 +97,7 @@ GPUVAddr MemoryManager::GetRegionEnd(GPUVAddr region_start) const {
97 return {}; 97 return {};
98} 98}
99 99
100boost::optional<GPUVAddr> MemoryManager::FindFreeBlock(u64 size, u64 align) { 100std::optional<GPUVAddr> MemoryManager::FindFreeBlock(u64 size, u64 align) {
101 GPUVAddr gpu_addr = 0; 101 GPUVAddr gpu_addr = 0;
102 u64 free_space = 0; 102 u64 free_space = 0;
103 align = (align + PAGE_MASK) & ~PAGE_MASK; 103 align = (align + PAGE_MASK) & ~PAGE_MASK;
@@ -118,7 +118,7 @@ boost::optional<GPUVAddr> MemoryManager::FindFreeBlock(u64 size, u64 align) {
118 return {}; 118 return {};
119} 119}
120 120
121boost::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) { 121std::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) {
122 VAddr base_addr = PageSlot(gpu_addr); 122 VAddr base_addr = PageSlot(gpu_addr);
123 123
124 if (base_addr == static_cast<u64>(PageStatus::Allocated) || 124 if (base_addr == static_cast<u64>(PageStatus::Allocated) ||
diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h
index caf80093f..b1255fd56 100644
--- a/src/video_core/memory_manager.h
+++ b/src/video_core/memory_manager.h
@@ -6,10 +6,9 @@
6 6
7#include <array> 7#include <array>
8#include <memory> 8#include <memory>
9#include <optional>
9#include <vector> 10#include <vector>
10 11
11#include <boost/optional.hpp>
12
13#include "common/common_types.h" 12#include "common/common_types.h"
14 13
15namespace Tegra { 14namespace Tegra {
@@ -27,7 +26,7 @@ public:
27 GPUVAddr MapBufferEx(VAddr cpu_addr, GPUVAddr gpu_addr, u64 size); 26 GPUVAddr MapBufferEx(VAddr cpu_addr, GPUVAddr gpu_addr, u64 size);
28 GPUVAddr UnmapBuffer(GPUVAddr gpu_addr, u64 size); 27 GPUVAddr UnmapBuffer(GPUVAddr gpu_addr, u64 size);
29 GPUVAddr GetRegionEnd(GPUVAddr region_start) const; 28 GPUVAddr GetRegionEnd(GPUVAddr region_start) const;
30 boost::optional<VAddr> GpuToCpuAddress(GPUVAddr gpu_addr); 29 std::optional<VAddr> GpuToCpuAddress(GPUVAddr gpu_addr);
31 std::vector<GPUVAddr> CpuToGpuAddress(VAddr cpu_addr) const; 30 std::vector<GPUVAddr> CpuToGpuAddress(VAddr cpu_addr) const;
32 31
33 static constexpr u64 PAGE_BITS = 16; 32 static constexpr u64 PAGE_BITS = 16;
@@ -35,7 +34,7 @@ public:
35 static constexpr u64 PAGE_MASK = PAGE_SIZE - 1; 34 static constexpr u64 PAGE_MASK = PAGE_SIZE - 1;
36 35
37private: 36private:
38 boost::optional<GPUVAddr> FindFreeBlock(u64 size, u64 align = 1); 37 std::optional<GPUVAddr> FindFreeBlock(u64 size, u64 align = 1);
39 bool IsPageMapped(GPUVAddr gpu_addr); 38 bool IsPageMapped(GPUVAddr gpu_addr);
40 VAddr& PageSlot(GPUVAddr gpu_addr); 39 VAddr& PageSlot(GPUVAddr gpu_addr);
41 40
diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h
index 2cd0738ff..669e26e15 100644
--- a/src/video_core/renderer_base.h
+++ b/src/video_core/renderer_base.h
@@ -6,7 +6,8 @@
6 6
7#include <atomic> 7#include <atomic>
8#include <memory> 8#include <memory>
9#include <boost/optional.hpp> 9#include <optional>
10
10#include "common/common_types.h" 11#include "common/common_types.h"
11#include "video_core/gpu.h" 12#include "video_core/gpu.h"
12#include "video_core/rasterizer_interface.h" 13#include "video_core/rasterizer_interface.h"
@@ -28,7 +29,8 @@ public:
28 virtual ~RendererBase(); 29 virtual ~RendererBase();
29 30
30 /// Swap buffers (render frame) 31 /// Swap buffers (render frame)
31 virtual void SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) = 0; 32 virtual void SwapBuffers(
33 std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) = 0;
32 34
33 /// Initialize the renderer 35 /// Initialize the renderer
34 virtual bool Init() = 0; 36 virtual bool Init() = 0;
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
index c142095c5..41a54b3e7 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
@@ -17,7 +17,7 @@ OGLBufferCache::OGLBufferCache(std::size_t size) : stream_buffer(GL_ARRAY_BUFFER
17GLintptr OGLBufferCache::UploadMemory(Tegra::GPUVAddr gpu_addr, std::size_t size, 17GLintptr OGLBufferCache::UploadMemory(Tegra::GPUVAddr gpu_addr, std::size_t size,
18 std::size_t alignment, bool cache) { 18 std::size_t alignment, bool cache) {
19 auto& memory_manager = Core::System::GetInstance().GPU().MemoryManager(); 19 auto& memory_manager = Core::System::GetInstance().GPU().MemoryManager();
20 const boost::optional<VAddr> cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr)}; 20 const std::optional<VAddr> cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr)};
21 21
22 // Cache management is a big overhead, so only cache entries with a given size. 22 // Cache management is a big overhead, so only cache entries with a given size.
23 // TODO: Figure out which size is the best for given games. 23 // TODO: Figure out which size is the best for given games.
diff --git a/src/video_core/renderer_opengl/gl_primitive_assembler.cpp b/src/video_core/renderer_opengl/gl_primitive_assembler.cpp
index ee1d9601b..741f14bc3 100644
--- a/src/video_core/renderer_opengl/gl_primitive_assembler.cpp
+++ b/src/video_core/renderer_opengl/gl_primitive_assembler.cpp
@@ -45,7 +45,7 @@ GLintptr PrimitiveAssembler::MakeQuadIndexed(Tegra::GPUVAddr gpu_addr, std::size
45 auto [dst_pointer, index_offset] = buffer_cache.ReserveMemory(map_size); 45 auto [dst_pointer, index_offset] = buffer_cache.ReserveMemory(map_size);
46 46
47 auto& memory_manager = Core::System::GetInstance().GPU().MemoryManager(); 47 auto& memory_manager = Core::System::GetInstance().GPU().MemoryManager();
48 const boost::optional<VAddr> cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr)}; 48 const std::optional<VAddr> cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr)};
49 const u8* source{Memory::GetPointer(*cpu_addr)}; 49 const u8* source{Memory::GetPointer(*cpu_addr)};
50 50
51 for (u32 primitive = 0; primitive < count / 4; ++primitive) { 51 for (u32 primitive = 0; primitive < count / 4; ++primitive) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 7bb5544fc..bf381271e 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -401,7 +401,7 @@ void RasterizerOpenGL::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {
401 401
402void RasterizerOpenGL::ConfigureFramebuffers(bool using_color_fb, bool using_depth_fb, 402void RasterizerOpenGL::ConfigureFramebuffers(bool using_color_fb, bool using_depth_fb,
403 bool preserve_contents, 403 bool preserve_contents,
404 boost::optional<std::size_t> single_color_target) { 404 std::optional<std::size_t> single_color_target) {
405 MICROPROFILE_SCOPE(OpenGL_Framebuffer); 405 MICROPROFILE_SCOPE(OpenGL_Framebuffer);
406 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; 406 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
407 407
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 7b0615125..47097c569 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -8,12 +8,12 @@
8#include <cstddef> 8#include <cstddef>
9#include <map> 9#include <map>
10#include <memory> 10#include <memory>
11#include <optional>
11#include <tuple> 12#include <tuple>
12#include <utility> 13#include <utility>
13#include <vector> 14#include <vector>
14 15
15#include <boost/icl/interval_map.hpp> 16#include <boost/icl/interval_map.hpp>
16#include <boost/optional.hpp>
17#include <boost/range/iterator_range.hpp> 17#include <boost/range/iterator_range.hpp>
18#include <glad/glad.h> 18#include <glad/glad.h>
19 19
@@ -111,7 +111,7 @@ private:
111 */ 111 */
112 void ConfigureFramebuffers(bool use_color_fb = true, bool using_depth_fb = true, 112 void ConfigureFramebuffers(bool use_color_fb = true, bool using_depth_fb = true,
113 bool preserve_contents = true, 113 bool preserve_contents = true,
114 boost::optional<std::size_t> single_color_target = {}); 114 std::optional<std::size_t> single_color_target = {});
115 115
116 /* 116 /*
117 * Configures the current constbuffers to use for the draw command. 117 * Configures the current constbuffers to use for the draw command.
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index dcf6941b0..d1f6ffe40 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -3,12 +3,12 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <map> 5#include <map>
6#include <optional>
6#include <set> 7#include <set>
7#include <string> 8#include <string>
8#include <string_view> 9#include <string_view>
9#include <unordered_set> 10#include <unordered_set>
10 11
11#include <boost/optional.hpp>
12#include <fmt/format.h> 12#include <fmt/format.h>
13 13
14#include "common/assert.h" 14#include "common/assert.h"
@@ -144,7 +144,7 @@ private:
144 for (u32 offset = begin; offset != end && offset != PROGRAM_END; ++offset) { 144 for (u32 offset = begin; offset != end && offset != PROGRAM_END; ++offset) {
145 const Instruction instr = {program_code[offset]}; 145 const Instruction instr = {program_code[offset]};
146 if (const auto opcode = OpCode::Decode(instr)) { 146 if (const auto opcode = OpCode::Decode(instr)) {
147 switch (opcode->GetId()) { 147 switch (opcode->get().GetId()) {
148 case OpCode::Id::EXIT: { 148 case OpCode::Id::EXIT: {
149 // The EXIT instruction can be predicated, which means that the shader can 149 // The EXIT instruction can be predicated, which means that the shader can
150 // conditionally end on this instruction. We have to consider the case where the 150 // conditionally end on this instruction. We have to consider the case where the
@@ -430,7 +430,7 @@ public:
430 */ 430 */
431 void SetRegisterToInputAttibute(const Register& reg, u64 elem, Attribute::Index attribute, 431 void SetRegisterToInputAttibute(const Register& reg, u64 elem, Attribute::Index attribute,
432 const Tegra::Shader::IpaMode& input_mode, 432 const Tegra::Shader::IpaMode& input_mode,
433 boost::optional<Register> vertex = {}) { 433 std::optional<Register> vertex = {}) {
434 const std::string dest = GetRegisterAsFloat(reg); 434 const std::string dest = GetRegisterAsFloat(reg);
435 const std::string src = GetInputAttribute(attribute, input_mode, vertex) + GetSwizzle(elem); 435 const std::string src = GetInputAttribute(attribute, input_mode, vertex) + GetSwizzle(elem);
436 shader.AddLine(dest + " = " + src + ';'); 436 shader.AddLine(dest + " = " + src + ';');
@@ -807,10 +807,10 @@ private:
807 /// Generates code representing an input attribute register. 807 /// Generates code representing an input attribute register.
808 std::string GetInputAttribute(Attribute::Index attribute, 808 std::string GetInputAttribute(Attribute::Index attribute,
809 const Tegra::Shader::IpaMode& input_mode, 809 const Tegra::Shader::IpaMode& input_mode,
810 boost::optional<Register> vertex = {}) { 810 std::optional<Register> vertex = {}) {
811 auto GeometryPass = [&](const std::string& name) { 811 auto GeometryPass = [&](const std::string& name) {
812 if (stage == Maxwell3D::Regs::ShaderStage::Geometry && vertex) { 812 if (stage == Maxwell3D::Regs::ShaderStage::Geometry && vertex) {
813 return "gs_" + name + '[' + GetRegisterAsInteger(vertex.value(), 0, false) + ']'; 813 return "gs_" + name + '[' + GetRegisterAsInteger(*vertex, 0, false) + ']';
814 } 814 }
815 return name; 815 return name;
816 }; 816 };
@@ -1465,7 +1465,7 @@ private:
1465 } 1465 }
1466 1466
1467 shader.AddLine( 1467 shader.AddLine(
1468 fmt::format("// {}: {} (0x{:016x})", offset, opcode->GetName(), instr.value)); 1468 fmt::format("// {}: {} (0x{:016x})", offset, opcode->get().GetName(), instr.value));
1469 1469
1470 using Tegra::Shader::Pred; 1470 using Tegra::Shader::Pred;
1471 ASSERT_MSG(instr.pred.full_pred != Pred::NeverExecute, 1471 ASSERT_MSG(instr.pred.full_pred != Pred::NeverExecute,
@@ -1473,7 +1473,7 @@ private:
1473 1473
1474 // Some instructions (like SSY) don't have a predicate field, they are always 1474 // Some instructions (like SSY) don't have a predicate field, they are always
1475 // unconditionally executed. 1475 // unconditionally executed.
1476 bool can_be_predicated = OpCode::IsPredicatedInstruction(opcode->GetId()); 1476 bool can_be_predicated = OpCode::IsPredicatedInstruction(opcode->get().GetId());
1477 1477
1478 if (can_be_predicated && instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)) { 1478 if (can_be_predicated && instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)) {
1479 shader.AddLine("if (" + 1479 shader.AddLine("if (" +
@@ -1483,7 +1483,7 @@ private:
1483 ++shader.scope; 1483 ++shader.scope;
1484 } 1484 }
1485 1485
1486 switch (opcode->GetType()) { 1486 switch (opcode->get().GetType()) {
1487 case OpCode::Type::Arithmetic: { 1487 case OpCode::Type::Arithmetic: {
1488 std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); 1488 std::string op_a = regs.GetRegisterAsFloat(instr.gpr8);
1489 1489
@@ -1500,7 +1500,7 @@ private:
1500 } 1500 }
1501 } 1501 }
1502 1502
1503 switch (opcode->GetId()) { 1503 switch (opcode->get().GetId()) {
1504 case OpCode::Id::MOV_C: 1504 case OpCode::Id::MOV_C:
1505 case OpCode::Id::MOV_R: { 1505 case OpCode::Id::MOV_R: {
1506 // MOV does not have neither 'abs' nor 'neg' bits. 1506 // MOV does not have neither 'abs' nor 'neg' bits.
@@ -1600,14 +1600,15 @@ private:
1600 break; 1600 break;
1601 } 1601 }
1602 default: { 1602 default: {
1603 LOG_CRITICAL(HW_GPU, "Unhandled arithmetic instruction: {}", opcode->GetName()); 1603 LOG_CRITICAL(HW_GPU, "Unhandled arithmetic instruction: {}",
1604 opcode->get().GetName());
1604 UNREACHABLE(); 1605 UNREACHABLE();
1605 } 1606 }
1606 } 1607 }
1607 break; 1608 break;
1608 } 1609 }
1609 case OpCode::Type::ArithmeticImmediate: { 1610 case OpCode::Type::ArithmeticImmediate: {
1610 switch (opcode->GetId()) { 1611 switch (opcode->get().GetId()) {
1611 case OpCode::Id::MOV32_IMM: { 1612 case OpCode::Id::MOV32_IMM: {
1612 regs.SetRegisterToFloat(instr.gpr0, 0, GetImmediate32(instr), 1, 1); 1613 regs.SetRegisterToFloat(instr.gpr0, 0, GetImmediate32(instr), 1, 1);
1613 break; 1614 break;
@@ -1651,7 +1652,7 @@ private:
1651 std::string op_a = instr.bfe.negate_a ? "-" : ""; 1652 std::string op_a = instr.bfe.negate_a ? "-" : "";
1652 op_a += regs.GetRegisterAsInteger(instr.gpr8); 1653 op_a += regs.GetRegisterAsInteger(instr.gpr8);
1653 1654
1654 switch (opcode->GetId()) { 1655 switch (opcode->get().GetId()) {
1655 case OpCode::Id::BFE_IMM: { 1656 case OpCode::Id::BFE_IMM: {
1656 std::string inner_shift = 1657 std::string inner_shift =
1657 '(' + op_a + " << " + std::to_string(instr.bfe.GetLeftShiftValue()) + ')'; 1658 '(' + op_a + " << " + std::to_string(instr.bfe.GetLeftShiftValue()) + ')';
@@ -1663,7 +1664,7 @@ private:
1663 break; 1664 break;
1664 } 1665 }
1665 default: { 1666 default: {
1666 LOG_CRITICAL(HW_GPU, "Unhandled BFE instruction: {}", opcode->GetName()); 1667 LOG_CRITICAL(HW_GPU, "Unhandled BFE instruction: {}", opcode->get().GetName());
1667 UNREACHABLE(); 1668 UNREACHABLE();
1668 } 1669 }
1669 } 1670 }
@@ -1685,7 +1686,7 @@ private:
1685 } 1686 }
1686 } 1687 }
1687 1688
1688 switch (opcode->GetId()) { 1689 switch (opcode->get().GetId()) {
1689 case OpCode::Id::SHR_C: 1690 case OpCode::Id::SHR_C:
1690 case OpCode::Id::SHR_R: 1691 case OpCode::Id::SHR_R:
1691 case OpCode::Id::SHR_IMM: { 1692 case OpCode::Id::SHR_IMM: {
@@ -1705,7 +1706,7 @@ private:
1705 regs.SetRegisterToInteger(instr.gpr0, true, 0, op_a + " << " + op_b, 1, 1); 1706 regs.SetRegisterToInteger(instr.gpr0, true, 0, op_a + " << " + op_b, 1, 1);
1706 break; 1707 break;
1707 default: { 1708 default: {
1708 LOG_CRITICAL(HW_GPU, "Unhandled shift instruction: {}", opcode->GetName()); 1709 LOG_CRITICAL(HW_GPU, "Unhandled shift instruction: {}", opcode->get().GetName());
1709 UNREACHABLE(); 1710 UNREACHABLE();
1710 } 1711 }
1711 } 1712 }
@@ -1715,7 +1716,7 @@ private:
1715 std::string op_a = regs.GetRegisterAsInteger(instr.gpr8); 1716 std::string op_a = regs.GetRegisterAsInteger(instr.gpr8);
1716 std::string op_b = std::to_string(instr.alu.imm20_32.Value()); 1717 std::string op_b = std::to_string(instr.alu.imm20_32.Value());
1717 1718
1718 switch (opcode->GetId()) { 1719 switch (opcode->get().GetId()) {
1719 case OpCode::Id::IADD32I: 1720 case OpCode::Id::IADD32I:
1720 if (instr.iadd32i.negate_a) 1721 if (instr.iadd32i.negate_a)
1721 op_a = "-(" + op_a + ')'; 1722 op_a = "-(" + op_a + ')';
@@ -1737,7 +1738,7 @@ private:
1737 } 1738 }
1738 default: { 1739 default: {
1739 LOG_CRITICAL(HW_GPU, "Unhandled ArithmeticIntegerImmediate instruction: {}", 1740 LOG_CRITICAL(HW_GPU, "Unhandled ArithmeticIntegerImmediate instruction: {}",
1740 opcode->GetName()); 1741 opcode->get().GetName());
1741 UNREACHABLE(); 1742 UNREACHABLE();
1742 } 1743 }
1743 } 1744 }
@@ -1757,7 +1758,7 @@ private:
1757 } 1758 }
1758 } 1759 }
1759 1760
1760 switch (opcode->GetId()) { 1761 switch (opcode->get().GetId()) {
1761 case OpCode::Id::IADD_C: 1762 case OpCode::Id::IADD_C:
1762 case OpCode::Id::IADD_R: 1763 case OpCode::Id::IADD_R:
1763 case OpCode::Id::IADD_IMM: { 1764 case OpCode::Id::IADD_IMM: {
@@ -1793,7 +1794,7 @@ private:
1793 } 1794 }
1794 }; 1795 };
1795 1796
1796 if (opcode->GetId() == OpCode::Id::IADD3_R) { 1797 if (opcode->get().GetId() == OpCode::Id::IADD3_R) {
1797 apply_height(instr.iadd3.height_a, op_a); 1798 apply_height(instr.iadd3.height_a, op_a);
1798 apply_height(instr.iadd3.height_b, op_b); 1799 apply_height(instr.iadd3.height_b, op_b);
1799 apply_height(instr.iadd3.height_c, op_c); 1800 apply_height(instr.iadd3.height_c, op_c);
@@ -1809,7 +1810,7 @@ private:
1809 op_c = "-(" + op_c + ')'; 1810 op_c = "-(" + op_c + ')';
1810 1811
1811 std::string result; 1812 std::string result;
1812 if (opcode->GetId() == OpCode::Id::IADD3_R) { 1813 if (opcode->get().GetId() == OpCode::Id::IADD3_R) {
1813 switch (instr.iadd3.mode) { 1814 switch (instr.iadd3.mode) {
1814 case Tegra::Shader::IAdd3Mode::RightShift: 1815 case Tegra::Shader::IAdd3Mode::RightShift:
1815 // TODO(tech4me): According to 1816 // TODO(tech4me): According to
@@ -1884,7 +1885,7 @@ private:
1884 const std::string op_c = regs.GetRegisterAsInteger(instr.gpr39); 1885 const std::string op_c = regs.GetRegisterAsInteger(instr.gpr39);
1885 std::string lut; 1886 std::string lut;
1886 1887
1887 if (opcode->GetId() == OpCode::Id::LOP3_R) { 1888 if (opcode->get().GetId() == OpCode::Id::LOP3_R) {
1888 lut = '(' + std::to_string(instr.alu.lop3.GetImmLut28()) + ')'; 1889 lut = '(' + std::to_string(instr.alu.lop3.GetImmLut28()) + ')';
1889 } else { 1890 } else {
1890 lut = '(' + std::to_string(instr.alu.lop3.GetImmLut48()) + ')'; 1891 lut = '(' + std::to_string(instr.alu.lop3.GetImmLut48()) + ')';
@@ -1914,7 +1915,7 @@ private:
1914 case OpCode::Id::LEA_HI: { 1915 case OpCode::Id::LEA_HI: {
1915 std::string op_c; 1916 std::string op_c;
1916 1917
1917 switch (opcode->GetId()) { 1918 switch (opcode->get().GetId()) {
1918 case OpCode::Id::LEA_R2: { 1919 case OpCode::Id::LEA_R2: {
1919 op_a = regs.GetRegisterAsInteger(instr.gpr20); 1920 op_a = regs.GetRegisterAsInteger(instr.gpr20);
1920 op_b = regs.GetRegisterAsInteger(instr.gpr39); 1921 op_b = regs.GetRegisterAsInteger(instr.gpr39);
@@ -1959,7 +1960,8 @@ private:
1959 op_b = regs.GetRegisterAsInteger(instr.gpr8); 1960 op_b = regs.GetRegisterAsInteger(instr.gpr8);
1960 op_a = std::to_string(instr.lea.imm.entry_a); 1961 op_a = std::to_string(instr.lea.imm.entry_a);
1961 op_c = std::to_string(instr.lea.imm.entry_b); 1962 op_c = std::to_string(instr.lea.imm.entry_b);
1962 LOG_CRITICAL(HW_GPU, "Unhandled LEA subinstruction: {}", opcode->GetName()); 1963 LOG_CRITICAL(HW_GPU, "Unhandled LEA subinstruction: {}",
1964 opcode->get().GetName());
1963 UNREACHABLE(); 1965 UNREACHABLE();
1964 } 1966 }
1965 } 1967 }
@@ -1974,7 +1976,7 @@ private:
1974 } 1976 }
1975 default: { 1977 default: {
1976 LOG_CRITICAL(HW_GPU, "Unhandled ArithmeticInteger instruction: {}", 1978 LOG_CRITICAL(HW_GPU, "Unhandled ArithmeticInteger instruction: {}",
1977 opcode->GetName()); 1979 opcode->get().GetName());
1978 UNREACHABLE(); 1980 UNREACHABLE();
1979 } 1981 }
1980 } 1982 }
@@ -1982,20 +1984,21 @@ private:
1982 break; 1984 break;
1983 } 1985 }
1984 case OpCode::Type::ArithmeticHalf: { 1986 case OpCode::Type::ArithmeticHalf: {
1985 if (opcode->GetId() == OpCode::Id::HADD2_C || opcode->GetId() == OpCode::Id::HADD2_R) { 1987 if (opcode->get().GetId() == OpCode::Id::HADD2_C ||
1988 opcode->get().GetId() == OpCode::Id::HADD2_R) {
1986 ASSERT_MSG(instr.alu_half.ftz == 0, "Unimplemented"); 1989 ASSERT_MSG(instr.alu_half.ftz == 0, "Unimplemented");
1987 } 1990 }
1988 const bool negate_a = 1991 const bool negate_a =
1989 opcode->GetId() != OpCode::Id::HMUL2_R && instr.alu_half.negate_a != 0; 1992 opcode->get().GetId() != OpCode::Id::HMUL2_R && instr.alu_half.negate_a != 0;
1990 const bool negate_b = 1993 const bool negate_b =
1991 opcode->GetId() != OpCode::Id::HMUL2_C && instr.alu_half.negate_b != 0; 1994 opcode->get().GetId() != OpCode::Id::HMUL2_C && instr.alu_half.negate_b != 0;
1992 1995
1993 const std::string op_a = 1996 const std::string op_a =
1994 GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr8, 0, false), instr.alu_half.type_a, 1997 GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr8, 0, false), instr.alu_half.type_a,
1995 instr.alu_half.abs_a != 0, negate_a); 1998 instr.alu_half.abs_a != 0, negate_a);
1996 1999
1997 std::string op_b; 2000 std::string op_b;
1998 switch (opcode->GetId()) { 2001 switch (opcode->get().GetId()) {
1999 case OpCode::Id::HADD2_C: 2002 case OpCode::Id::HADD2_C:
2000 case OpCode::Id::HMUL2_C: 2003 case OpCode::Id::HMUL2_C:
2001 op_b = regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset, 2004 op_b = regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
@@ -2013,7 +2016,7 @@ private:
2013 op_b = GetHalfFloat(op_b, instr.alu_half.type_b, instr.alu_half.abs_b != 0, negate_b); 2016 op_b = GetHalfFloat(op_b, instr.alu_half.type_b, instr.alu_half.abs_b != 0, negate_b);
2014 2017
2015 const std::string result = [&]() { 2018 const std::string result = [&]() {
2016 switch (opcode->GetId()) { 2019 switch (opcode->get().GetId()) {
2017 case OpCode::Id::HADD2_C: 2020 case OpCode::Id::HADD2_C:
2018 case OpCode::Id::HADD2_R: 2021 case OpCode::Id::HADD2_R:
2019 return '(' + op_a + " + " + op_b + ')'; 2022 return '(' + op_a + " + " + op_b + ')';
@@ -2021,7 +2024,8 @@ private:
2021 case OpCode::Id::HMUL2_R: 2024 case OpCode::Id::HMUL2_R:
2022 return '(' + op_a + " * " + op_b + ')'; 2025 return '(' + op_a + " * " + op_b + ')';
2023 default: 2026 default:
2024 LOG_CRITICAL(HW_GPU, "Unhandled half float instruction: {}", opcode->GetName()); 2027 LOG_CRITICAL(HW_GPU, "Unhandled half float instruction: {}",
2028 opcode->get().GetName());
2025 UNREACHABLE(); 2029 UNREACHABLE();
2026 return std::string("0"); 2030 return std::string("0");
2027 } 2031 }
@@ -2032,7 +2036,7 @@ private:
2032 break; 2036 break;
2033 } 2037 }
2034 case OpCode::Type::ArithmeticHalfImmediate: { 2038 case OpCode::Type::ArithmeticHalfImmediate: {
2035 if (opcode->GetId() == OpCode::Id::HADD2_IMM) { 2039 if (opcode->get().GetId() == OpCode::Id::HADD2_IMM) {
2036 ASSERT_MSG(instr.alu_half_imm.ftz == 0, "Unimplemented"); 2040 ASSERT_MSG(instr.alu_half_imm.ftz == 0, "Unimplemented");
2037 } else { 2041 } else {
2038 ASSERT_MSG(instr.alu_half_imm.precision == Tegra::Shader::HalfPrecision::None, 2042 ASSERT_MSG(instr.alu_half_imm.precision == Tegra::Shader::HalfPrecision::None,
@@ -2046,7 +2050,7 @@ private:
2046 const std::string op_b = UnpackHalfImmediate(instr, true); 2050 const std::string op_b = UnpackHalfImmediate(instr, true);
2047 2051
2048 const std::string result = [&]() { 2052 const std::string result = [&]() {
2049 switch (opcode->GetId()) { 2053 switch (opcode->get().GetId()) {
2050 case OpCode::Id::HADD2_IMM: 2054 case OpCode::Id::HADD2_IMM:
2051 return op_a + " + " + op_b; 2055 return op_a + " + " + op_b;
2052 case OpCode::Id::HMUL2_IMM: 2056 case OpCode::Id::HMUL2_IMM:
@@ -2072,7 +2076,7 @@ private:
2072 ASSERT_MSG(instr.ffma.tab5980_1 == 0, "FFMA tab5980_1({}) not implemented", 2076 ASSERT_MSG(instr.ffma.tab5980_1 == 0, "FFMA tab5980_1({}) not implemented",
2073 instr.ffma.tab5980_1.Value()); 2077 instr.ffma.tab5980_1.Value());
2074 2078
2075 switch (opcode->GetId()) { 2079 switch (opcode->get().GetId()) {
2076 case OpCode::Id::FFMA_CR: { 2080 case OpCode::Id::FFMA_CR: {
2077 op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset, 2081 op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
2078 GLSLRegister::Type::Float); 2082 GLSLRegister::Type::Float);
@@ -2096,7 +2100,7 @@ private:
2096 break; 2100 break;
2097 } 2101 }
2098 default: { 2102 default: {
2099 LOG_CRITICAL(HW_GPU, "Unhandled FFMA instruction: {}", opcode->GetName()); 2103 LOG_CRITICAL(HW_GPU, "Unhandled FFMA instruction: {}", opcode->get().GetName());
2100 UNREACHABLE(); 2104 UNREACHABLE();
2101 } 2105 }
2102 } 2106 }
@@ -2107,14 +2111,14 @@ private:
2107 break; 2111 break;
2108 } 2112 }
2109 case OpCode::Type::Hfma2: { 2113 case OpCode::Type::Hfma2: {
2110 if (opcode->GetId() == OpCode::Id::HFMA2_RR) { 2114 if (opcode->get().GetId() == OpCode::Id::HFMA2_RR) {
2111 ASSERT_MSG(instr.hfma2.rr.precision == Tegra::Shader::HalfPrecision::None, 2115 ASSERT_MSG(instr.hfma2.rr.precision == Tegra::Shader::HalfPrecision::None,
2112 "Unimplemented"); 2116 "Unimplemented");
2113 } else { 2117 } else {
2114 ASSERT_MSG(instr.hfma2.precision == Tegra::Shader::HalfPrecision::None, 2118 ASSERT_MSG(instr.hfma2.precision == Tegra::Shader::HalfPrecision::None,
2115 "Unimplemented"); 2119 "Unimplemented");
2116 } 2120 }
2117 const bool saturate = opcode->GetId() == OpCode::Id::HFMA2_RR 2121 const bool saturate = opcode->get().GetId() == OpCode::Id::HFMA2_RR
2118 ? instr.hfma2.rr.saturate != 0 2122 ? instr.hfma2.rr.saturate != 0
2119 : instr.hfma2.saturate != 0; 2123 : instr.hfma2.saturate != 0;
2120 2124
@@ -2122,7 +2126,7 @@ private:
2122 GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr8, 0, false), instr.hfma2.type_a); 2126 GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr8, 0, false), instr.hfma2.type_a);
2123 std::string op_b, op_c; 2127 std::string op_b, op_c;
2124 2128
2125 switch (opcode->GetId()) { 2129 switch (opcode->get().GetId()) {
2126 case OpCode::Id::HFMA2_CR: 2130 case OpCode::Id::HFMA2_CR:
2127 op_b = GetHalfFloat(regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset, 2131 op_b = GetHalfFloat(regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
2128 GLSLRegister::Type::UnsignedInteger), 2132 GLSLRegister::Type::UnsignedInteger),
@@ -2160,7 +2164,7 @@ private:
2160 break; 2164 break;
2161 } 2165 }
2162 case OpCode::Type::Conversion: { 2166 case OpCode::Type::Conversion: {
2163 switch (opcode->GetId()) { 2167 switch (opcode->get().GetId()) {
2164 case OpCode::Id::I2I_R: { 2168 case OpCode::Id::I2I_R: {
2165 ASSERT_MSG(!instr.conversion.selector, "Unimplemented"); 2169 ASSERT_MSG(!instr.conversion.selector, "Unimplemented");
2166 2170
@@ -2298,14 +2302,15 @@ private:
2298 break; 2302 break;
2299 } 2303 }
2300 default: { 2304 default: {
2301 LOG_CRITICAL(HW_GPU, "Unhandled conversion instruction: {}", opcode->GetName()); 2305 LOG_CRITICAL(HW_GPU, "Unhandled conversion instruction: {}",
2306 opcode->get().GetName());
2302 UNREACHABLE(); 2307 UNREACHABLE();
2303 } 2308 }
2304 } 2309 }
2305 break; 2310 break;
2306 } 2311 }
2307 case OpCode::Type::Memory: { 2312 case OpCode::Type::Memory: {
2308 switch (opcode->GetId()) { 2313 switch (opcode->get().GetId()) {
2309 case OpCode::Id::LD_A: { 2314 case OpCode::Id::LD_A: {
2310 // Note: Shouldn't this be interp mode flat? As in no interpolation made. 2315 // Note: Shouldn't this be interp mode flat? As in no interpolation made.
2311 ASSERT_MSG(instr.gpr8.Value() == Register::ZeroIndex, 2316 ASSERT_MSG(instr.gpr8.Value() == Register::ZeroIndex,
@@ -2949,7 +2954,7 @@ private:
2949 break; 2954 break;
2950 } 2955 }
2951 default: { 2956 default: {
2952 LOG_CRITICAL(HW_GPU, "Unhandled memory instruction: {}", opcode->GetName()); 2957 LOG_CRITICAL(HW_GPU, "Unhandled memory instruction: {}", opcode->get().GetName());
2953 UNREACHABLE(); 2958 UNREACHABLE();
2954 } 2959 }
2955 } 2960 }
@@ -3043,7 +3048,7 @@ private:
3043 instr.hsetp2.abs_a, instr.hsetp2.negate_a); 3048 instr.hsetp2.abs_a, instr.hsetp2.negate_a);
3044 3049
3045 const std::string op_b = [&]() { 3050 const std::string op_b = [&]() {
3046 switch (opcode->GetId()) { 3051 switch (opcode->get().GetId()) {
3047 case OpCode::Id::HSETP2_R: 3052 case OpCode::Id::HSETP2_R:
3048 return GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr20, 0, false), 3053 return GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr20, 0, false),
3049 instr.hsetp2.type_b, instr.hsetp2.abs_a, 3054 instr.hsetp2.type_b, instr.hsetp2.abs_a,
@@ -3105,7 +3110,7 @@ private:
3105 break; 3110 break;
3106 } 3111 }
3107 case OpCode::Type::PredicateSetPredicate: { 3112 case OpCode::Type::PredicateSetPredicate: {
3108 switch (opcode->GetId()) { 3113 switch (opcode->get().GetId()) {
3109 case OpCode::Id::PSETP: { 3114 case OpCode::Id::PSETP: {
3110 const std::string op_a = 3115 const std::string op_a =
3111 GetPredicateCondition(instr.psetp.pred12, instr.psetp.neg_pred12 != 0); 3116 GetPredicateCondition(instr.psetp.pred12, instr.psetp.neg_pred12 != 0);
@@ -3151,7 +3156,8 @@ private:
3151 break; 3156 break;
3152 } 3157 }
3153 default: { 3158 default: {
3154 LOG_CRITICAL(HW_GPU, "Unhandled predicate instruction: {}", opcode->GetName()); 3159 LOG_CRITICAL(HW_GPU, "Unhandled predicate instruction: {}",
3160 opcode->get().GetName());
3155 UNREACHABLE(); 3161 UNREACHABLE();
3156 } 3162 }
3157 } 3163 }
@@ -3239,7 +3245,7 @@ private:
3239 instr.hset2.abs_a != 0, instr.hset2.negate_a != 0); 3245 instr.hset2.abs_a != 0, instr.hset2.negate_a != 0);
3240 3246
3241 const std::string op_b = [&]() { 3247 const std::string op_b = [&]() {
3242 switch (opcode->GetId()) { 3248 switch (opcode->get().GetId()) {
3243 case OpCode::Id::HSET2_R: 3249 case OpCode::Id::HSET2_R:
3244 return GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr20, 0, false), 3250 return GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr20, 0, false),
3245 instr.hset2.type_b, instr.hset2.abs_b != 0, 3251 instr.hset2.type_b, instr.hset2.abs_b != 0,
@@ -3288,7 +3294,7 @@ private:
3288 const bool is_signed{instr.xmad.sign_a == 1}; 3294 const bool is_signed{instr.xmad.sign_a == 1};
3289 3295
3290 bool is_merge{}; 3296 bool is_merge{};
3291 switch (opcode->GetId()) { 3297 switch (opcode->get().GetId()) {
3292 case OpCode::Id::XMAD_CR: { 3298 case OpCode::Id::XMAD_CR: {
3293 is_merge = instr.xmad.merge_56; 3299 is_merge = instr.xmad.merge_56;
3294 op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset, 3300 op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
@@ -3317,7 +3323,7 @@ private:
3317 break; 3323 break;
3318 } 3324 }
3319 default: { 3325 default: {
3320 LOG_CRITICAL(HW_GPU, "Unhandled XMAD instruction: {}", opcode->GetName()); 3326 LOG_CRITICAL(HW_GPU, "Unhandled XMAD instruction: {}", opcode->get().GetName());
3321 UNREACHABLE(); 3327 UNREACHABLE();
3322 } 3328 }
3323 } 3329 }
@@ -3369,7 +3375,7 @@ private:
3369 break; 3375 break;
3370 } 3376 }
3371 default: { 3377 default: {
3372 switch (opcode->GetId()) { 3378 switch (opcode->get().GetId()) {
3373 case OpCode::Id::EXIT: { 3379 case OpCode::Id::EXIT: {
3374 if (stage == Maxwell3D::Regs::ShaderStage::Fragment) { 3380 if (stage == Maxwell3D::Regs::ShaderStage::Fragment) {
3375 EmitFragmentOutputsWrite(); 3381 EmitFragmentOutputsWrite();
@@ -3564,7 +3570,7 @@ private:
3564 break; 3570 break;
3565 } 3571 }
3566 default: { 3572 default: {
3567 LOG_CRITICAL(HW_GPU, "Unhandled instruction: {}", opcode->GetName()); 3573 LOG_CRITICAL(HW_GPU, "Unhandled instruction: {}", opcode->get().GetName());
3568 UNREACHABLE(); 3574 UNREACHABLE();
3569 } 3575 }
3570 } 3576 }
@@ -3705,9 +3711,9 @@ std::string GetCommonDeclarations() {
3705 RasterizerOpenGL::MaxConstbufferSize / sizeof(GLvec4)); 3711 RasterizerOpenGL::MaxConstbufferSize / sizeof(GLvec4));
3706} 3712}
3707 3713
3708boost::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code, u32 main_offset, 3714std::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code, u32 main_offset,
3709 Maxwell3D::Regs::ShaderStage stage, 3715 Maxwell3D::Regs::ShaderStage stage,
3710 const std::string& suffix) { 3716 const std::string& suffix) {
3711 try { 3717 try {
3712 const auto subroutines = 3718 const auto subroutines =
3713 ControlFlowAnalyzer(program_code, main_offset, suffix).GetSubroutines(); 3719 ControlFlowAnalyzer(program_code, main_offset, suffix).GetSubroutines();
@@ -3716,7 +3722,7 @@ boost::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code,
3716 } catch (const DecompileFail& exception) { 3722 } catch (const DecompileFail& exception) {
3717 LOG_ERROR(HW_GPU, "Shader decompilation failed: {}", exception.what()); 3723 LOG_ERROR(HW_GPU, "Shader decompilation failed: {}", exception.what());
3718 } 3724 }
3719 return boost::none; 3725 return {};
3720} 3726}
3721 3727
3722} // namespace OpenGL::GLShader::Decompiler 3728} // namespace OpenGL::GLShader::Decompiler
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.h b/src/video_core/renderer_opengl/gl_shader_decompiler.h
index b20cc4bfa..d01a4a7ee 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.h
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.h
@@ -6,8 +6,8 @@
6 6
7#include <array> 7#include <array>
8#include <functional> 8#include <functional>
9#include <optional>
9#include <string> 10#include <string>
10#include <boost/optional.hpp>
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "video_core/engines/maxwell_3d.h" 12#include "video_core/engines/maxwell_3d.h"
13#include "video_core/renderer_opengl/gl_shader_gen.h" 13#include "video_core/renderer_opengl/gl_shader_gen.h"
@@ -18,8 +18,8 @@ using Tegra::Engines::Maxwell3D;
18 18
19std::string GetCommonDeclarations(); 19std::string GetCommonDeclarations();
20 20
21boost::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code, u32 main_offset, 21std::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code, u32 main_offset,
22 Maxwell3D::Regs::ShaderStage stage, 22 Maxwell3D::Regs::ShaderStage stage,
23 const std::string& suffix); 23 const std::string& suffix);
24 24
25} // namespace OpenGL::GLShader::Decompiler 25} // namespace OpenGL::GLShader::Decompiler
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp
index dfb562706..9d17edd63 100644
--- a/src/video_core/renderer_opengl/gl_shader_gen.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp
@@ -37,7 +37,7 @@ layout(std140) uniform vs_config {
37 ProgramResult program = 37 ProgramResult program =
38 Decompiler::DecompileProgram(setup.program.code, PROGRAM_OFFSET, 38 Decompiler::DecompileProgram(setup.program.code, PROGRAM_OFFSET,
39 Maxwell3D::Regs::ShaderStage::Vertex, "vertex") 39 Maxwell3D::Regs::ShaderStage::Vertex, "vertex")
40 .get_value_or({}); 40 .value_or(ProgramResult());
41 41
42 out += program.first; 42 out += program.first;
43 43
@@ -45,7 +45,7 @@ layout(std140) uniform vs_config {
45 ProgramResult program_b = 45 ProgramResult program_b =
46 Decompiler::DecompileProgram(setup.program.code_b, PROGRAM_OFFSET, 46 Decompiler::DecompileProgram(setup.program.code_b, PROGRAM_OFFSET,
47 Maxwell3D::Regs::ShaderStage::Vertex, "vertex_b") 47 Maxwell3D::Regs::ShaderStage::Vertex, "vertex_b")
48 .get_value_or({}); 48 .value_or(ProgramResult());
49 out += program_b.first; 49 out += program_b.first;
50 } 50 }
51 51
@@ -90,7 +90,7 @@ ProgramResult GenerateGeometryShader(const ShaderSetup& setup) {
90 ProgramResult program = 90 ProgramResult program =
91 Decompiler::DecompileProgram(setup.program.code, PROGRAM_OFFSET, 91 Decompiler::DecompileProgram(setup.program.code, PROGRAM_OFFSET,
92 Maxwell3D::Regs::ShaderStage::Geometry, "geometry") 92 Maxwell3D::Regs::ShaderStage::Geometry, "geometry")
93 .get_value_or({}); 93 .value_or(ProgramResult());
94 out += R"( 94 out += R"(
95out gl_PerVertex { 95out gl_PerVertex {
96 vec4 gl_Position; 96 vec4 gl_Position;
@@ -124,7 +124,7 @@ ProgramResult GenerateFragmentShader(const ShaderSetup& setup) {
124 ProgramResult program = 124 ProgramResult program =
125 Decompiler::DecompileProgram(setup.program.code, PROGRAM_OFFSET, 125 Decompiler::DecompileProgram(setup.program.code, PROGRAM_OFFSET,
126 Maxwell3D::Regs::ShaderStage::Fragment, "fragment") 126 Maxwell3D::Regs::ShaderStage::Fragment, "fragment")
127 .get_value_or({}); 127 .value_or(ProgramResult());
128 out += R"( 128 out += R"(
129layout(location = 0) out vec4 FragColor0; 129layout(location = 0) out vec4 FragColor0;
130layout(location = 1) out vec4 FragColor1; 130layout(location = 1) out vec4 FragColor1;
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 90b68943d..ea38da932 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -115,7 +115,8 @@ RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& window)
115RendererOpenGL::~RendererOpenGL() = default; 115RendererOpenGL::~RendererOpenGL() = default;
116 116
117/// Swap buffers (render frame) 117/// Swap buffers (render frame)
118void RendererOpenGL::SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) { 118void RendererOpenGL::SwapBuffers(
119 std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) {
119 ScopeAcquireGLContext acquire_context{render_window}; 120 ScopeAcquireGLContext acquire_context{render_window};
120 121
121 Core::System::GetInstance().GetPerfStats().EndSystemFrame(); 122 Core::System::GetInstance().GetPerfStats().EndSystemFrame();
@@ -124,11 +125,11 @@ void RendererOpenGL::SwapBuffers(boost::optional<const Tegra::FramebufferConfig&
124 OpenGLState prev_state = OpenGLState::GetCurState(); 125 OpenGLState prev_state = OpenGLState::GetCurState();
125 state.Apply(); 126 state.Apply();
126 127
127 if (framebuffer != boost::none) { 128 if (framebuffer) {
128 // If framebuffer is provided, reload it from memory to a texture 129 // If framebuffer is provided, reload it from memory to a texture
129 if (screen_info.texture.width != (GLsizei)framebuffer->width || 130 if (screen_info.texture.width != (GLsizei)framebuffer->get().width ||
130 screen_info.texture.height != (GLsizei)framebuffer->height || 131 screen_info.texture.height != (GLsizei)framebuffer->get().height ||
131 screen_info.texture.pixel_format != framebuffer->pixel_format) { 132 screen_info.texture.pixel_format != framebuffer->get().pixel_format) {
132 // Reallocate texture if the framebuffer size has changed. 133 // Reallocate texture if the framebuffer size has changed.
133 // This is expected to not happen very often and hence should not be a 134 // This is expected to not happen very often and hence should not be a
134 // performance problem. 135 // performance problem.
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index 961467a62..c0868c0e4 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -51,7 +51,8 @@ public:
51 ~RendererOpenGL() override; 51 ~RendererOpenGL() override;
52 52
53 /// Swap buffers (render frame) 53 /// Swap buffers (render frame)
54 void SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) override; 54 void SwapBuffers(
55 std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) override;
55 56
56 /// Initialize the renderer 57 /// Initialize the renderer
57 bool Init() override; 58 bool Init() override;