summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.h1
-rw-r--r--src/core/settings.cpp6
-rw-r--r--src/video_core/command_processor.h3
-rw-r--r--src/video_core/engines/shader_bytecode.h10
-rw-r--r--src/video_core/gpu.cpp42
-rw-r--r--src/video_core/gpu.h17
-rw-r--r--src/video_core/renderer_base.cpp19
-rw-r--r--src/video_core/renderer_base.h24
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp11
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp56
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h140
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp39
-rw-r--r--src/video_core/renderer_opengl/maxwell_to_gl.h3
-rw-r--r--src/video_core/textures/decoders.cpp85
-rw-r--r--src/video_core/textures/decoders.h4
-rw-r--r--src/video_core/video_core.cpp2
-rw-r--r--src/video_core/video_core.h7
-rw-r--r--src/yuzu/debugger/graphics/graphics_surface.cpp6
-rw-r--r--src/yuzu/game_list_p.h25
19 files changed, 229 insertions, 271 deletions
diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h
index f86e1056c..db2e17c0c 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.h
+++ b/src/core/hle/service/nvflinger/buffer_queue.h
@@ -6,6 +6,7 @@
6 6
7#include <vector> 7#include <vector>
8#include <boost/optional.hpp> 8#include <boost/optional.hpp>
9#include "common/common_funcs.h"
9#include "common/math_util.h" 10#include "common/math_util.h"
10#include "common/swap.h" 11#include "common/swap.h"
11#include "core/hle/kernel/event.h" 12#include "core/hle/kernel/event.h"
diff --git a/src/core/settings.cpp b/src/core/settings.cpp
index a4623223d..0da159559 100644
--- a/src/core/settings.cpp
+++ b/src/core/settings.cpp
@@ -7,22 +7,18 @@
7#include "core/hle/service/hid/hid.h" 7#include "core/hle/service/hid/hid.h"
8#include "core/settings.h" 8#include "core/settings.h"
9#include "video_core/renderer_base.h" 9#include "video_core/renderer_base.h"
10#include "video_core/video_core.h"
11 10
12namespace Settings { 11namespace Settings {
13 12
14Values values = {}; 13Values values = {};
15 14
16void Apply() { 15void Apply() {
17
18 GDBStub::SetServerPort(values.gdbstub_port); 16 GDBStub::SetServerPort(values.gdbstub_port);
19 GDBStub::ToggleServer(values.use_gdbstub); 17 GDBStub::ToggleServer(values.use_gdbstub);
20 18
21 VideoCore::g_toggle_framelimit_enabled = values.toggle_framelimit;
22
23 auto& system_instance = Core::System::GetInstance(); 19 auto& system_instance = Core::System::GetInstance();
24 if (system_instance.IsPoweredOn()) { 20 if (system_instance.IsPoweredOn()) {
25 system_instance.Renderer().UpdateCurrentFramebufferLayout(); 21 system_instance.Renderer().RefreshBaseSettings();
26 } 22 }
27 23
28 Service::HID::ReloadInputDevices(); 24 Service::HID::ReloadInputDevices();
diff --git a/src/video_core/command_processor.h b/src/video_core/command_processor.h
index f7214ffec..a01153e0b 100644
--- a/src/video_core/command_processor.h
+++ b/src/video_core/command_processor.h
@@ -30,8 +30,7 @@ union CommandHeader {
30 30
31 BitField<29, 3, SubmissionMode> mode; 31 BitField<29, 3, SubmissionMode> mode;
32}; 32};
33static_assert(std::is_standard_layout<CommandHeader>::value == true, 33static_assert(std::is_standard_layout_v<CommandHeader>, "CommandHeader is not standard layout");
34 "CommandHeader does not use standard layout");
35static_assert(sizeof(CommandHeader) == sizeof(u32), "CommandHeader has incorrect size!"); 34static_assert(sizeof(CommandHeader) == sizeof(u32), "CommandHeader has incorrect size!");
36 35
37} // namespace Tegra 36} // namespace Tegra
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 3d4557b7e..6cb7bea1c 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -477,8 +477,7 @@ union Instruction {
477 u64 value; 477 u64 value;
478}; 478};
479static_assert(sizeof(Instruction) == 0x8, "Incorrect structure size"); 479static_assert(sizeof(Instruction) == 0x8, "Incorrect structure size");
480static_assert(std::is_standard_layout<Instruction>::value, 480static_assert(std::is_standard_layout_v<Instruction>, "Instruction is not standard layout");
481 "Structure does not have standard layout");
482 481
483class OpCode { 482class OpCode {
484public: 483public:
@@ -598,6 +597,13 @@ public:
598 Unknown, 597 Unknown,
599 }; 598 };
600 599
600 /// Returns whether an opcode has an execution predicate field or not (ie, whether it can be
601 /// conditionally executed).
602 static bool IsPredicatedInstruction(Id opcode) {
603 // TODO(Subv): Add the rest of unpredicated instructions.
604 return opcode != Id::SSY;
605 }
606
601 class Matcher { 607 class Matcher {
602 public: 608 public:
603 Matcher(const char* const name, u16 mask, u16 expected, OpCode::Id id, OpCode::Type type) 609 Matcher(const char* const name, u16 mask, u16 expected, OpCode::Id id, OpCode::Type type)
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 4ff4d71c5..ceaf86654 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -2,6 +2,7 @@
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 "common/assert.h"
5#include "video_core/engines/fermi_2d.h" 6#include "video_core/engines/fermi_2d.h"
6#include "video_core/engines/maxwell_3d.h" 7#include "video_core/engines/maxwell_3d.h"
7#include "video_core/engines/maxwell_compute.h" 8#include "video_core/engines/maxwell_compute.h"
@@ -11,6 +12,15 @@
11 12
12namespace Tegra { 13namespace Tegra {
13 14
15u32 FramebufferConfig::BytesPerPixel(PixelFormat format) {
16 switch (format) {
17 case PixelFormat::ABGR8:
18 return 4;
19 }
20
21 UNREACHABLE();
22}
23
14GPU::GPU(VideoCore::RasterizerInterface& rasterizer) { 24GPU::GPU(VideoCore::RasterizerInterface& rasterizer) {
15 memory_manager = std::make_unique<MemoryManager>(); 25 memory_manager = std::make_unique<MemoryManager>();
16 maxwell_3d = std::make_unique<Engines::Maxwell3D>(rasterizer, *memory_manager); 26 maxwell_3d = std::make_unique<Engines::Maxwell3D>(rasterizer, *memory_manager);
@@ -34,19 +44,51 @@ u32 RenderTargetBytesPerPixel(RenderTargetFormat format) {
34 44
35 switch (format) { 45 switch (format) {
36 case RenderTargetFormat::RGBA32_FLOAT: 46 case RenderTargetFormat::RGBA32_FLOAT:
47 case RenderTargetFormat::RGBA32_UINT:
37 return 16; 48 return 16;
38 case RenderTargetFormat::RGBA16_FLOAT: 49 case RenderTargetFormat::RGBA16_FLOAT:
39 case RenderTargetFormat::RG32_FLOAT: 50 case RenderTargetFormat::RG32_FLOAT:
40 return 8; 51 return 8;
41 case RenderTargetFormat::RGBA8_UNORM: 52 case RenderTargetFormat::RGBA8_UNORM:
53 case RenderTargetFormat::RGBA8_SRGB:
42 case RenderTargetFormat::RGB10_A2_UNORM: 54 case RenderTargetFormat::RGB10_A2_UNORM:
43 case RenderTargetFormat::BGRA8_UNORM: 55 case RenderTargetFormat::BGRA8_UNORM:
56 case RenderTargetFormat::RG16_UNORM:
57 case RenderTargetFormat::RG16_SNORM:
58 case RenderTargetFormat::RG16_UINT:
59 case RenderTargetFormat::RG16_SINT:
60 case RenderTargetFormat::RG16_FLOAT:
44 case RenderTargetFormat::R32_FLOAT: 61 case RenderTargetFormat::R32_FLOAT:
45 case RenderTargetFormat::R11G11B10_FLOAT: 62 case RenderTargetFormat::R11G11B10_FLOAT:
46 return 4; 63 return 4;
64 case RenderTargetFormat::R16_UNORM:
65 case RenderTargetFormat::R16_SNORM:
66 case RenderTargetFormat::R16_UINT:
67 case RenderTargetFormat::R16_SINT:
68 case RenderTargetFormat::R16_FLOAT:
69 return 2;
70 case RenderTargetFormat::R8_UNORM:
71 return 1;
47 default: 72 default:
48 UNIMPLEMENTED_MSG("Unimplemented render target format {}", static_cast<u32>(format)); 73 UNIMPLEMENTED_MSG("Unimplemented render target format {}", static_cast<u32>(format));
49 } 74 }
50} 75}
51 76
77u32 DepthFormatBytesPerPixel(DepthFormat format) {
78 switch (format) {
79 case DepthFormat::Z32_S8_X24_FLOAT:
80 return 8;
81 case DepthFormat::Z32_FLOAT:
82 case DepthFormat::S8_Z24_UNORM:
83 case DepthFormat::Z24_X8_UNORM:
84 case DepthFormat::Z24_S8_UNORM:
85 case DepthFormat::Z24_C8_UNORM:
86 return 4;
87 case DepthFormat::Z16_UNORM:
88 return 2;
89 default:
90 UNIMPLEMENTED_MSG("Unimplemented Depth format {}", static_cast<u32>(format));
91 }
92}
93
52} // namespace Tegra 94} // namespace Tegra
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index 874eddd78..b57312b3b 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -6,7 +6,6 @@
6 6
7#include <memory> 7#include <memory>
8#include <unordered_map> 8#include <unordered_map>
9#include <vector>
10#include "common/common_types.h" 9#include "common/common_types.h"
11#include "core/hle/service/nvflinger/buffer_queue.h" 10#include "core/hle/service/nvflinger/buffer_queue.h"
12#include "video_core/memory_manager.h" 11#include "video_core/memory_manager.h"
@@ -35,6 +34,10 @@ enum class RenderTargetFormat : u32 {
35 R11G11B10_FLOAT = 0xE0, 34 R11G11B10_FLOAT = 0xE0,
36 R32_FLOAT = 0xE5, 35 R32_FLOAT = 0xE5,
37 B5G6R5_UNORM = 0xE8, 36 B5G6R5_UNORM = 0xE8,
37 R16_UNORM = 0xEE,
38 R16_SNORM = 0xEF,
39 R16_SINT = 0xF0,
40 R16_UINT = 0xF1,
38 R16_FLOAT = 0xF2, 41 R16_FLOAT = 0xF2,
39 R8_UNORM = 0xF3, 42 R8_UNORM = 0xF3,
40}; 43};
@@ -52,6 +55,9 @@ enum class DepthFormat : u32 {
52/// Returns the number of bytes per pixel of each rendertarget format. 55/// Returns the number of bytes per pixel of each rendertarget format.
53u32 RenderTargetBytesPerPixel(RenderTargetFormat format); 56u32 RenderTargetBytesPerPixel(RenderTargetFormat format);
54 57
58/// Returns the number of bytes per pixel of each depth format.
59u32 DepthFormatBytesPerPixel(DepthFormat format);
60
55class DebugContext; 61class DebugContext;
56 62
57/** 63/**
@@ -65,14 +71,7 @@ struct FramebufferConfig {
65 /** 71 /**
66 * Returns the number of bytes per pixel. 72 * Returns the number of bytes per pixel.
67 */ 73 */
68 static u32 BytesPerPixel(PixelFormat format) { 74 static u32 BytesPerPixel(PixelFormat format);
69 switch (format) {
70 case PixelFormat::ABGR8:
71 return 4;
72 }
73
74 UNREACHABLE();
75 }
76 75
77 VAddr address; 76 VAddr address;
78 u32 offset; 77 u32 offset;
diff --git a/src/video_core/renderer_base.cpp b/src/video_core/renderer_base.cpp
index 3ca350243..e87016429 100644
--- a/src/video_core/renderer_base.cpp
+++ b/src/video_core/renderer_base.cpp
@@ -4,18 +4,23 @@
4 4
5#include <memory> 5#include <memory>
6#include "core/frontend/emu_window.h" 6#include "core/frontend/emu_window.h"
7#include "core/settings.h"
7#include "video_core/renderer_base.h" 8#include "video_core/renderer_base.h"
8#include "video_core/renderer_opengl/gl_rasterizer.h" 9#include "video_core/renderer_opengl/gl_rasterizer.h"
9 10
10namespace VideoCore { 11namespace VideoCore {
11 12
12RendererBase::RendererBase(EmuWindow& window) : render_window{window} {} 13RendererBase::RendererBase(EmuWindow& window) : render_window{window} {
14 RefreshBaseSettings();
15}
16
13RendererBase::~RendererBase() = default; 17RendererBase::~RendererBase() = default;
14 18
15void RendererBase::UpdateCurrentFramebufferLayout() { 19void RendererBase::RefreshBaseSettings() {
16 const Layout::FramebufferLayout& layout = render_window.GetFramebufferLayout(); 20 RefreshRasterizerSetting();
21 UpdateCurrentFramebufferLayout();
17 22
18 render_window.UpdateCurrentFramebufferLayout(layout.width, layout.height); 23 renderer_settings.use_framelimiter = Settings::values.toggle_framelimit;
19} 24}
20 25
21void RendererBase::RefreshRasterizerSetting() { 26void RendererBase::RefreshRasterizerSetting() {
@@ -24,4 +29,10 @@ void RendererBase::RefreshRasterizerSetting() {
24 } 29 }
25} 30}
26 31
32void RendererBase::UpdateCurrentFramebufferLayout() {
33 const Layout::FramebufferLayout& layout = render_window.GetFramebufferLayout();
34
35 render_window.UpdateCurrentFramebufferLayout(layout.width, layout.height);
36}
37
27} // namespace VideoCore 38} // namespace VideoCore
diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h
index 235de23a1..fd8c47592 100644
--- a/src/video_core/renderer_base.h
+++ b/src/video_core/renderer_base.h
@@ -4,9 +4,9 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <atomic>
7#include <memory> 8#include <memory>
8#include <boost/optional.hpp> 9#include <boost/optional.hpp>
9#include "common/assert.h"
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "video_core/gpu.h" 11#include "video_core/gpu.h"
12#include "video_core/rasterizer_interface.h" 12#include "video_core/rasterizer_interface.h"
@@ -15,11 +15,12 @@ class EmuWindow;
15 15
16namespace VideoCore { 16namespace VideoCore {
17 17
18struct RendererSettings {
19 std::atomic_bool use_framelimiter{false};
20};
21
18class RendererBase : NonCopyable { 22class RendererBase : NonCopyable {
19public: 23public:
20 /// Used to reference a framebuffer
21 enum kFramebuffer { kFramebuffer_VirtualXFB = 0, kFramebuffer_EFB, kFramebuffer_Texture };
22
23 explicit RendererBase(EmuWindow& window); 24 explicit RendererBase(EmuWindow& window);
24 virtual ~RendererBase(); 25 virtual ~RendererBase();
25 26
@@ -32,9 +33,6 @@ public:
32 /// Shutdown the renderer 33 /// Shutdown the renderer
33 virtual void ShutDown() = 0; 34 virtual void ShutDown() = 0;
34 35
35 /// Updates the framebuffer layout of the contained render window handle.
36 void UpdateCurrentFramebufferLayout();
37
38 // Getter/setter functions: 36 // Getter/setter functions:
39 // ------------------------ 37 // ------------------------
40 38
@@ -54,13 +52,23 @@ public:
54 return *rasterizer; 52 return *rasterizer;
55 } 53 }
56 54
57 void RefreshRasterizerSetting(); 55 /// Refreshes the settings common to all renderers
56 void RefreshBaseSettings();
58 57
59protected: 58protected:
59 /// Refreshes settings specific to the rasterizer.
60 void RefreshRasterizerSetting();
61
60 EmuWindow& render_window; ///< Reference to the render window handle. 62 EmuWindow& render_window; ///< Reference to the render window handle.
61 std::unique_ptr<RasterizerInterface> rasterizer; 63 std::unique_ptr<RasterizerInterface> rasterizer;
62 f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer 64 f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer
63 int m_current_frame = 0; ///< Current frame, should be set by the renderer 65 int m_current_frame = 0; ///< Current frame, should be set by the renderer
66
67 RendererSettings renderer_settings;
68
69private:
70 /// Updates the framebuffer layout of the contained render window handle.
71 void UpdateCurrentFramebufferLayout();
64}; 72};
65 73
66} // namespace VideoCore 74} // namespace VideoCore
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 546e86532..8360feb5d 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -332,8 +332,6 @@ std::pair<Surface, Surface> RasterizerOpenGL::ConfigureFramebuffers(bool using_c
332 // TODO(bunnei): Implement this 332 // TODO(bunnei): Implement this
333 const bool has_stencil = false; 333 const bool has_stencil = false;
334 334
335 const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()};
336
337 const bool write_color_fb = 335 const bool write_color_fb =
338 state.color_mask.red_enabled == GL_TRUE || state.color_mask.green_enabled == GL_TRUE || 336 state.color_mask.red_enabled == GL_TRUE || state.color_mask.green_enabled == GL_TRUE ||
339 state.color_mask.blue_enabled == GL_TRUE || state.color_mask.alpha_enabled == GL_TRUE; 337 state.color_mask.blue_enabled == GL_TRUE || state.color_mask.alpha_enabled == GL_TRUE;
@@ -346,9 +344,10 @@ std::pair<Surface, Surface> RasterizerOpenGL::ConfigureFramebuffers(bool using_c
346 Surface depth_surface; 344 Surface depth_surface;
347 MathUtil::Rectangle<u32> surfaces_rect; 345 MathUtil::Rectangle<u32> surfaces_rect;
348 std::tie(color_surface, depth_surface, surfaces_rect) = 346 std::tie(color_surface, depth_surface, surfaces_rect) =
349 res_cache.GetFramebufferSurfaces(using_color_fb, using_depth_fb, viewport_rect); 347 res_cache.GetFramebufferSurfaces(using_color_fb, using_depth_fb);
350 348
351 MathUtil::Rectangle<u32> draw_rect{ 349 const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()};
350 const MathUtil::Rectangle<u32> draw_rect{
352 static_cast<u32>(std::clamp<s32>(static_cast<s32>(surfaces_rect.left) + viewport_rect.left, 351 static_cast<u32>(std::clamp<s32>(static_cast<s32>(surfaces_rect.left) + viewport_rect.left,
353 surfaces_rect.left, surfaces_rect.right)), // Left 352 surfaces_rect.left, surfaces_rect.right)), // Left
354 static_cast<u32>(std::clamp<s32>(static_cast<s32>(surfaces_rect.bottom) + viewport_rect.top, 353 static_cast<u32>(std::clamp<s32>(static_cast<s32>(surfaces_rect.bottom) + viewport_rect.top,
@@ -812,9 +811,7 @@ void RasterizerOpenGL::SyncClipCoef() {
812void RasterizerOpenGL::SyncCullMode() { 811void RasterizerOpenGL::SyncCullMode() {
813 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; 812 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
814 813
815 // TODO(bunnei): Enable the below once more things work - until then, this may hide regressions 814 state.cull.enabled = regs.cull.enabled != 0;
816 // state.cull.enabled = regs.cull.enabled != 0;
817 state.cull.enabled = false;
818 815
819 if (state.cull.enabled) { 816 if (state.cull.enabled) {
820 state.cull.front_face = MaxwellToGL::FrontFace(regs.cull.front_face); 817 state.cull.front_face = MaxwellToGL::FrontFace(regs.cull.front_face);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 114d35ce6..15a33ed9b 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -122,6 +122,9 @@ static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_form
122 {GL_R32F, GL_RED, GL_FLOAT, ComponentType::Float, false}, // R32F 122 {GL_R32F, GL_RED, GL_FLOAT, ComponentType::Float, false}, // R32F
123 {GL_R16F, GL_RED, GL_HALF_FLOAT, ComponentType::Float, false}, // R16F 123 {GL_R16F, GL_RED, GL_HALF_FLOAT, ComponentType::Float, false}, // R16F
124 {GL_R16, GL_RED, GL_UNSIGNED_SHORT, ComponentType::UNorm, false}, // R16UNORM 124 {GL_R16, GL_RED, GL_UNSIGNED_SHORT, ComponentType::UNorm, false}, // R16UNORM
125 {GL_R16_SNORM, GL_RED, GL_SHORT, ComponentType::SNorm, false}, // R16S
126 {GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT, ComponentType::UInt, false}, // R16UI
127 {GL_R16I, GL_RED_INTEGER, GL_SHORT, ComponentType::SInt, false}, // R16I
125 {GL_RG16, GL_RG, GL_UNSIGNED_SHORT, ComponentType::UNorm, false}, // RG16 128 {GL_RG16, GL_RG, GL_UNSIGNED_SHORT, ComponentType::UNorm, false}, // RG16
126 {GL_RG16F, GL_RG, GL_HALF_FLOAT, ComponentType::Float, false}, // RG16F 129 {GL_RG16F, GL_RG, GL_HALF_FLOAT, ComponentType::Float, false}, // RG16F
127 {GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT, ComponentType::UInt, false}, // RG16UI 130 {GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT, ComponentType::UInt, false}, // RG16UI
@@ -183,6 +186,21 @@ MathUtil::Rectangle<u32> SurfaceParams::GetRect() const {
183 return {0, actual_height, width, 0}; 186 return {0, actual_height, width, 0};
184} 187}
185 188
189/// Returns true if the specified PixelFormat is a BCn format, e.g. DXT or DXN
190static bool IsFormatBCn(PixelFormat format) {
191 switch (format) {
192 case PixelFormat::DXT1:
193 case PixelFormat::DXT23:
194 case PixelFormat::DXT45:
195 case PixelFormat::DXN1:
196 case PixelFormat::DXN2SNORM:
197 case PixelFormat::DXN2UNORM:
198 case PixelFormat::BC7U:
199 return true;
200 }
201 return false;
202}
203
186template <bool morton_to_gl, PixelFormat format> 204template <bool morton_to_gl, PixelFormat format>
187void MortonCopy(u32 stride, u32 block_height, u32 height, std::vector<u8>& gl_buffer, 205void MortonCopy(u32 stride, u32 block_height, u32 height, std::vector<u8>& gl_buffer,
188 Tegra::GPUVAddr addr) { 206 Tegra::GPUVAddr addr) {
@@ -191,16 +209,12 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, std::vector<u8>& gl_bu
191 const auto& gpu = Core::System::GetInstance().GPU(); 209 const auto& gpu = Core::System::GetInstance().GPU();
192 210
193 if (morton_to_gl) { 211 if (morton_to_gl) {
194 std::vector<u8> data; 212 // With the BCn formats (DXT and DXN), each 4x4 tile is swizzled instead of just individual
195 if (SurfaceParams::GetFormatType(format) == SurfaceType::ColorTexture) { 213 // pixel values.
196 data = Tegra::Texture::UnswizzleTexture( 214 const u32 tile_size{IsFormatBCn(format) ? 4U : 1U};
197 *gpu.memory_manager->GpuToCpuAddress(addr), 215 const std::vector<u8> data =
198 SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, block_height); 216 Tegra::Texture::UnswizzleTexture(*gpu.memory_manager->GpuToCpuAddress(addr), tile_size,
199 } else { 217 bytes_per_pixel, stride, height, block_height);
200 data = Tegra::Texture::UnswizzleDepthTexture(
201 *gpu.memory_manager->GpuToCpuAddress(addr),
202 SurfaceParams::DepthFormatFromPixelFormat(format), stride, height, block_height);
203 }
204 const size_t size_to_copy{std::min(gl_buffer.size(), data.size())}; 218 const size_t size_to_copy{std::min(gl_buffer.size(), data.size())};
205 gl_buffer.assign(data.begin(), data.begin() + size_to_copy); 219 gl_buffer.assign(data.begin(), data.begin() + size_to_copy);
206 } else { 220 } else {
@@ -228,13 +242,14 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPU
228 MortonCopy<true, PixelFormat::G8R8>, MortonCopy<true, PixelFormat::BGRA8>, 242 MortonCopy<true, PixelFormat::G8R8>, MortonCopy<true, PixelFormat::BGRA8>,
229 MortonCopy<true, PixelFormat::RGBA32F>, MortonCopy<true, PixelFormat::RG32F>, 243 MortonCopy<true, PixelFormat::RGBA32F>, MortonCopy<true, PixelFormat::RG32F>,
230 MortonCopy<true, PixelFormat::R32F>, MortonCopy<true, PixelFormat::R16F>, 244 MortonCopy<true, PixelFormat::R32F>, MortonCopy<true, PixelFormat::R16F>,
231 MortonCopy<true, PixelFormat::R16UNORM>, MortonCopy<true, PixelFormat::RG16>, 245 MortonCopy<true, PixelFormat::R16UNORM>, MortonCopy<true, PixelFormat::R16S>,
232 MortonCopy<true, PixelFormat::RG16F>, MortonCopy<true, PixelFormat::RG16UI>, 246 MortonCopy<true, PixelFormat::R16UI>, MortonCopy<true, PixelFormat::R16I>,
233 MortonCopy<true, PixelFormat::RG16I>, MortonCopy<true, PixelFormat::RG16S>, 247 MortonCopy<true, PixelFormat::RG16>, MortonCopy<true, PixelFormat::RG16F>,
234 MortonCopy<true, PixelFormat::RGB32F>, MortonCopy<true, PixelFormat::SRGBA8>, 248 MortonCopy<true, PixelFormat::RG16UI>, MortonCopy<true, PixelFormat::RG16I>,
235 MortonCopy<true, PixelFormat::Z24S8>, MortonCopy<true, PixelFormat::S8Z24>, 249 MortonCopy<true, PixelFormat::RG16S>, MortonCopy<true, PixelFormat::RGB32F>,
236 MortonCopy<true, PixelFormat::Z32F>, MortonCopy<true, PixelFormat::Z16>, 250 MortonCopy<true, PixelFormat::SRGBA8>, MortonCopy<true, PixelFormat::Z24S8>,
237 MortonCopy<true, PixelFormat::Z32FS8>, 251 MortonCopy<true, PixelFormat::S8Z24>, MortonCopy<true, PixelFormat::Z32F>,
252 MortonCopy<true, PixelFormat::Z16>, MortonCopy<true, PixelFormat::Z32FS8>,
238}; 253};
239 254
240static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPUVAddr), 255static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPUVAddr),
@@ -265,6 +280,9 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPU
265 MortonCopy<false, PixelFormat::R32F>, 280 MortonCopy<false, PixelFormat::R32F>,
266 MortonCopy<false, PixelFormat::R16F>, 281 MortonCopy<false, PixelFormat::R16F>,
267 MortonCopy<false, PixelFormat::R16UNORM>, 282 MortonCopy<false, PixelFormat::R16UNORM>,
283 MortonCopy<false, PixelFormat::R16S>,
284 MortonCopy<false, PixelFormat::R16UI>,
285 MortonCopy<false, PixelFormat::R16I>,
268 MortonCopy<false, PixelFormat::RG16>, 286 MortonCopy<false, PixelFormat::RG16>,
269 MortonCopy<false, PixelFormat::RG16F>, 287 MortonCopy<false, PixelFormat::RG16F>,
270 MortonCopy<false, PixelFormat::RG16UI>, 288 MortonCopy<false, PixelFormat::RG16UI>,
@@ -611,8 +629,8 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu
611 return GetSurface(SurfaceParams::CreateForTexture(config)); 629 return GetSurface(SurfaceParams::CreateForTexture(config));
612} 630}
613 631
614SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( 632SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(bool using_color_fb,
615 bool using_color_fb, bool using_depth_fb, const MathUtil::Rectangle<s32>& viewport) { 633 bool using_depth_fb) {
616 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; 634 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
617 635
618 // TODO(bunnei): This is hard corded to use just the first render buffer 636 // TODO(bunnei): This is hard corded to use just the first render buffer
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index 26e2ee203..e24ba8cfe 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -46,22 +46,25 @@ struct SurfaceParams {
46 R32F = 20, 46 R32F = 20,
47 R16F = 21, 47 R16F = 21,
48 R16UNORM = 22, 48 R16UNORM = 22,
49 RG16 = 23, 49 R16S = 23,
50 RG16F = 24, 50 R16UI = 24,
51 RG16UI = 25, 51 R16I = 25,
52 RG16I = 26, 52 RG16 = 26,
53 RG16S = 27, 53 RG16F = 27,
54 RGB32F = 28, 54 RG16UI = 28,
55 SRGBA8 = 29, 55 RG16I = 29,
56 RG16S = 30,
57 RGB32F = 31,
58 SRGBA8 = 32,
56 59
57 MaxColorFormat, 60 MaxColorFormat,
58 61
59 // DepthStencil formats 62 // DepthStencil formats
60 Z24S8 = 30, 63 Z24S8 = 33,
61 S8Z24 = 31, 64 S8Z24 = 34,
62 Z32F = 32, 65 Z32F = 35,
63 Z16 = 33, 66 Z16 = 36,
64 Z32FS8 = 34, 67 Z32FS8 = 37,
65 68
66 MaxDepthStencilFormat, 69 MaxDepthStencilFormat,
67 70
@@ -122,6 +125,9 @@ struct SurfaceParams {
122 1, // R32F 125 1, // R32F
123 1, // R16F 126 1, // R16F
124 1, // R16UNORM 127 1, // R16UNORM
128 1, // R16S
129 1, // R16UI
130 1, // R16I
125 1, // RG16 131 1, // RG16
126 1, // RG16F 132 1, // RG16F
127 1, // RG16UI 133 1, // RG16UI
@@ -168,6 +174,9 @@ struct SurfaceParams {
168 32, // R32F 174 32, // R32F
169 16, // R16F 175 16, // R16F
170 16, // R16UNORM 176 16, // R16UNORM
177 16, // R16S
178 16, // R16UI
179 16, // R16I
171 32, // RG16 180 32, // RG16
172 32, // RG16F 181 32, // RG16F
173 32, // RG16UI 182 32, // RG16UI
@@ -245,6 +254,14 @@ struct SurfaceParams {
245 return PixelFormat::RG16S; 254 return PixelFormat::RG16S;
246 case Tegra::RenderTargetFormat::R16_FLOAT: 255 case Tegra::RenderTargetFormat::R16_FLOAT:
247 return PixelFormat::R16F; 256 return PixelFormat::R16F;
257 case Tegra::RenderTargetFormat::R16_UNORM:
258 return PixelFormat::R16UNORM;
259 case Tegra::RenderTargetFormat::R16_SNORM:
260 return PixelFormat::R16S;
261 case Tegra::RenderTargetFormat::R16_UINT:
262 return PixelFormat::R16UI;
263 case Tegra::RenderTargetFormat::R16_SINT:
264 return PixelFormat::R16I;
248 case Tegra::RenderTargetFormat::R32_FLOAT: 265 case Tegra::RenderTargetFormat::R32_FLOAT:
249 return PixelFormat::R32F; 266 return PixelFormat::R32F;
250 default: 267 default:
@@ -293,6 +310,12 @@ struct SurfaceParams {
293 return PixelFormat::R16F; 310 return PixelFormat::R16F;
294 case Tegra::Texture::ComponentType::UNORM: 311 case Tegra::Texture::ComponentType::UNORM:
295 return PixelFormat::R16UNORM; 312 return PixelFormat::R16UNORM;
313 case Tegra::Texture::ComponentType::SNORM:
314 return PixelFormat::R16S;
315 case Tegra::Texture::ComponentType::UINT:
316 return PixelFormat::R16UI;
317 case Tegra::Texture::ComponentType::SINT:
318 return PixelFormat::R16I;
296 } 319 }
297 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", 320 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
298 static_cast<u32>(component_type)); 321 static_cast<u32>(component_type));
@@ -348,92 +371,6 @@ struct SurfaceParams {
348 } 371 }
349 } 372 }
350 373
351 static Tegra::Texture::TextureFormat TextureFormatFromPixelFormat(PixelFormat format) {
352 // TODO(Subv): Properly implement this
353 switch (format) {
354 case PixelFormat::ABGR8:
355 case PixelFormat::SRGBA8:
356 return Tegra::Texture::TextureFormat::A8R8G8B8;
357 case PixelFormat::B5G6R5:
358 return Tegra::Texture::TextureFormat::B5G6R5;
359 case PixelFormat::A2B10G10R10:
360 return Tegra::Texture::TextureFormat::A2B10G10R10;
361 case PixelFormat::A1B5G5R5:
362 return Tegra::Texture::TextureFormat::A1B5G5R5;
363 case PixelFormat::R8:
364 return Tegra::Texture::TextureFormat::R8;
365 case PixelFormat::G8R8:
366 return Tegra::Texture::TextureFormat::G8R8;
367 case PixelFormat::RGBA16F:
368 return Tegra::Texture::TextureFormat::R16_G16_B16_A16;
369 case PixelFormat::R11FG11FB10F:
370 return Tegra::Texture::TextureFormat::BF10GF11RF11;
371 case PixelFormat::RGBA32UI:
372 return Tegra::Texture::TextureFormat::R32_G32_B32_A32;
373 case PixelFormat::DXT1:
374 return Tegra::Texture::TextureFormat::DXT1;
375 case PixelFormat::DXT23:
376 return Tegra::Texture::TextureFormat::DXT23;
377 case PixelFormat::DXT45:
378 return Tegra::Texture::TextureFormat::DXT45;
379 case PixelFormat::DXN1:
380 return Tegra::Texture::TextureFormat::DXN1;
381 case PixelFormat::DXN2UNORM:
382 case PixelFormat::DXN2SNORM:
383 return Tegra::Texture::TextureFormat::DXN2;
384 case PixelFormat::BC7U:
385 return Tegra::Texture::TextureFormat::BC7U;
386 case PixelFormat::ASTC_2D_4X4:
387 return Tegra::Texture::TextureFormat::ASTC_2D_4X4;
388 case PixelFormat::BGRA8:
389 // TODO(bunnei): This is fine for unswizzling (since we just need the right component
390 // sizes), but could be a bug if we used this function in different ways.
391 return Tegra::Texture::TextureFormat::A8R8G8B8;
392 case PixelFormat::RGBA32F:
393 return Tegra::Texture::TextureFormat::R32_G32_B32_A32;
394 case PixelFormat::RGB32F:
395 return Tegra::Texture::TextureFormat::R32_G32_B32;
396 case PixelFormat::RG32F:
397 return Tegra::Texture::TextureFormat::R32_G32;
398 case PixelFormat::R32F:
399 return Tegra::Texture::TextureFormat::R32;
400 case PixelFormat::R16F:
401 case PixelFormat::R16UNORM:
402 return Tegra::Texture::TextureFormat::R16;
403 case PixelFormat::Z32F:
404 return Tegra::Texture::TextureFormat::ZF32;
405 case PixelFormat::Z24S8:
406 return Tegra::Texture::TextureFormat::Z24S8;
407 case PixelFormat::RG16F:
408 case PixelFormat::RG16:
409 case PixelFormat::RG16UI:
410 case PixelFormat::RG16I:
411 case PixelFormat::RG16S:
412 return Tegra::Texture::TextureFormat::R16_G16;
413 default:
414 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
415 UNREACHABLE();
416 }
417 }
418
419 static Tegra::DepthFormat DepthFormatFromPixelFormat(PixelFormat format) {
420 switch (format) {
421 case PixelFormat::S8Z24:
422 return Tegra::DepthFormat::S8_Z24_UNORM;
423 case PixelFormat::Z24S8:
424 return Tegra::DepthFormat::Z24_S8_UNORM;
425 case PixelFormat::Z32F:
426 return Tegra::DepthFormat::Z32_FLOAT;
427 case PixelFormat::Z16:
428 return Tegra::DepthFormat::Z16_UNORM;
429 case PixelFormat::Z32FS8:
430 return Tegra::DepthFormat::Z32_S8_X24_FLOAT;
431 default:
432 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
433 UNREACHABLE();
434 }
435 }
436
437 static ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type) { 374 static ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type) {
438 // TODO(Subv): Implement more component types 375 // TODO(Subv): Implement more component types
439 switch (type) { 376 switch (type) {
@@ -462,9 +399,11 @@ struct SurfaceParams {
462 case Tegra::RenderTargetFormat::RGB10_A2_UNORM: 399 case Tegra::RenderTargetFormat::RGB10_A2_UNORM:
463 case Tegra::RenderTargetFormat::R8_UNORM: 400 case Tegra::RenderTargetFormat::R8_UNORM:
464 case Tegra::RenderTargetFormat::RG16_UNORM: 401 case Tegra::RenderTargetFormat::RG16_UNORM:
402 case Tegra::RenderTargetFormat::R16_UNORM:
465 case Tegra::RenderTargetFormat::B5G6R5_UNORM: 403 case Tegra::RenderTargetFormat::B5G6R5_UNORM:
466 return ComponentType::UNorm; 404 return ComponentType::UNorm;
467 case Tegra::RenderTargetFormat::RG16_SNORM: 405 case Tegra::RenderTargetFormat::RG16_SNORM:
406 case Tegra::RenderTargetFormat::R16_SNORM:
468 return ComponentType::SNorm; 407 return ComponentType::SNorm;
469 case Tegra::RenderTargetFormat::RGBA16_FLOAT: 408 case Tegra::RenderTargetFormat::RGBA16_FLOAT:
470 case Tegra::RenderTargetFormat::R11G11B10_FLOAT: 409 case Tegra::RenderTargetFormat::R11G11B10_FLOAT:
@@ -476,8 +415,10 @@ struct SurfaceParams {
476 return ComponentType::Float; 415 return ComponentType::Float;
477 case Tegra::RenderTargetFormat::RGBA32_UINT: 416 case Tegra::RenderTargetFormat::RGBA32_UINT:
478 case Tegra::RenderTargetFormat::RG16_UINT: 417 case Tegra::RenderTargetFormat::RG16_UINT:
418 case Tegra::RenderTargetFormat::R16_UINT:
479 return ComponentType::UInt; 419 return ComponentType::UInt;
480 case Tegra::RenderTargetFormat::RG16_SINT: 420 case Tegra::RenderTargetFormat::RG16_SINT:
421 case Tegra::RenderTargetFormat::R16_SINT:
481 return ComponentType::SInt; 422 return ComponentType::SInt;
482 default: 423 default:
483 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); 424 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
@@ -634,8 +575,7 @@ public:
634 Surface GetTextureSurface(const Tegra::Texture::FullTextureInfo& config); 575 Surface GetTextureSurface(const Tegra::Texture::FullTextureInfo& config);
635 576
636 /// Get the color and depth surfaces based on the framebuffer configuration 577 /// Get the color and depth surfaces based on the framebuffer configuration
637 SurfaceSurfaceRect_Tuple GetFramebufferSurfaces(bool using_color_fb, bool using_depth_fb, 578 SurfaceSurfaceRect_Tuple GetFramebufferSurfaces(bool using_color_fb, bool using_depth_fb);
638 const MathUtil::Rectangle<s32>& viewport);
639 579
640 /// Flushes the surface to Switch memory 580 /// Flushes the surface to Switch memory
641 void FlushSurface(const Surface& surface); 581 void FlushSurface(const Surface& surface);
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 32f06f409..8954deb81 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -141,6 +141,15 @@ private:
141 ExitMethod jmp = Scan(target, end, labels); 141 ExitMethod jmp = Scan(target, end, labels);
142 return exit_method = ParallelExit(no_jmp, jmp); 142 return exit_method = ParallelExit(no_jmp, jmp);
143 } 143 }
144 case OpCode::Id::SSY: {
145 // The SSY instruction uses a similar encoding as the BRA instruction.
146 ASSERT_MSG(instr.bra.constant_buffer == 0,
147 "Constant buffer SSY is not supported");
148 u32 target = offset + instr.bra.GetBranchTarget();
149 labels.insert(target);
150 // Continue scanning for an exit method.
151 break;
152 }
144 } 153 }
145 } 154 }
146 } 155 }
@@ -828,7 +837,11 @@ private:
828 ASSERT_MSG(instr.pred.full_pred != Pred::NeverExecute, 837 ASSERT_MSG(instr.pred.full_pred != Pred::NeverExecute,
829 "NeverExecute predicate not implemented"); 838 "NeverExecute predicate not implemented");
830 839
831 if (instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)) { 840 // Some instructions (like SSY) don't have a predicate field, they are always
841 // unconditionally executed.
842 bool can_be_predicated = OpCode::IsPredicatedInstruction(opcode->GetId());
843
844 if (can_be_predicated && instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)) {
832 shader.AddLine("if (" + 845 shader.AddLine("if (" +
833 GetPredicateCondition(instr.pred.pred_index, instr.negate_pred != 0) + 846 GetPredicateCondition(instr.pred.pred_index, instr.negate_pred != 0) +
834 ')'); 847 ')');
@@ -1668,16 +1681,25 @@ private:
1668 break; 1681 break;
1669 } 1682 }
1670 case OpCode::Id::SSY: { 1683 case OpCode::Id::SSY: {
1671 // The SSY opcode tells the GPU where to re-converge divergent execution paths, we 1684 // The SSY opcode tells the GPU where to re-converge divergent execution paths, it
1672 // can ignore this when generating GLSL code. 1685 // sets the target of the jump that the SYNC instruction will make. The SSY opcode
1686 // has a similar structure to the BRA opcode.
1687 ASSERT_MSG(instr.bra.constant_buffer == 0, "Constant buffer SSY is not supported");
1688
1689 u32 target = offset + instr.bra.GetBranchTarget();
1690 shader.AddLine("ssy_target = " + std::to_string(target) + "u;");
1673 break; 1691 break;
1674 } 1692 }
1675 case OpCode::Id::SYNC: 1693 case OpCode::Id::SYNC: {
1694 // The SYNC opcode jumps to the address previously set by the SSY opcode
1676 ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always); 1695 ASSERT(instr.flow.cond == Tegra::Shader::FlowCondition::Always);
1696 shader.AddLine("{ jmp_to = ssy_target; break; }");
1697 break;
1698 }
1677 case OpCode::Id::DEPBAR: { 1699 case OpCode::Id::DEPBAR: {
1678 // TODO(Subv): Find out if we actually have to care about these instructions or if 1700 // TODO(Subv): Find out if we actually have to care about this instruction or if
1679 // the GLSL compiler takes care of that for us. 1701 // the GLSL compiler takes care of that for us.
1680 LOG_WARNING(HW_GPU, "DEPBAR/SYNC instruction is stubbed"); 1702 LOG_WARNING(HW_GPU, "DEPBAR instruction is stubbed");
1681 break; 1703 break;
1682 } 1704 }
1683 default: { 1705 default: {
@@ -1691,7 +1713,7 @@ private:
1691 } 1713 }
1692 1714
1693 // Close the predicate condition scope. 1715 // Close the predicate condition scope.
1694 if (instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)) { 1716 if (can_be_predicated && instr.pred.pred_index != static_cast<u64>(Pred::UnusedIndex)) {
1695 --shader.scope; 1717 --shader.scope;
1696 shader.AddLine('}'); 1718 shader.AddLine('}');
1697 } 1719 }
@@ -1742,6 +1764,7 @@ private:
1742 } else { 1764 } else {
1743 labels.insert(subroutine.begin); 1765 labels.insert(subroutine.begin);
1744 shader.AddLine("uint jmp_to = " + std::to_string(subroutine.begin) + "u;"); 1766 shader.AddLine("uint jmp_to = " + std::to_string(subroutine.begin) + "u;");
1767 shader.AddLine("uint ssy_target = 0u;");
1745 shader.AddLine("while (true) {"); 1768 shader.AddLine("while (true) {");
1746 ++shader.scope; 1769 ++shader.scope;
1747 1770
@@ -1757,7 +1780,7 @@ private:
1757 u32 compile_end = CompileRange(label, next_label); 1780 u32 compile_end = CompileRange(label, next_label);
1758 if (compile_end > next_label && compile_end != PROGRAM_END) { 1781 if (compile_end > next_label && compile_end != PROGRAM_END) {
1759 // This happens only when there is a label inside a IF/LOOP block 1782 // This happens only when there is a label inside a IF/LOOP block
1760 shader.AddLine("{ jmp_to = " + std::to_string(compile_end) + "u; break; }"); 1783 shader.AddLine(" jmp_to = " + std::to_string(compile_end) + "u; break; }");
1761 labels.emplace(compile_end); 1784 labels.emplace(compile_end);
1762 } 1785 }
1763 1786
diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h
index 43be69dd1..c439446b1 100644
--- a/src/video_core/renderer_opengl/maxwell_to_gl.h
+++ b/src/video_core/renderer_opengl/maxwell_to_gl.h
@@ -45,6 +45,9 @@ inline GLenum VertexType(Maxwell::VertexAttribute attrib) {
45 case Maxwell::VertexAttribute::Type::SignedNorm: { 45 case Maxwell::VertexAttribute::Type::SignedNorm: {
46 46
47 switch (attrib.size) { 47 switch (attrib.size) {
48 case Maxwell::VertexAttribute::Size::Size_32_32_32:
49 return GL_INT;
50 case Maxwell::VertexAttribute::Size::Size_8_8:
48 case Maxwell::VertexAttribute::Size::Size_8_8_8_8: 51 case Maxwell::VertexAttribute::Size::Size_8_8_8_8:
49 return GL_BYTE; 52 return GL_BYTE;
50 case Maxwell::VertexAttribute::Size::Size_16_16: 53 case Maxwell::VertexAttribute::Size::Size_16_16:
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp
index 7ea66584c..70746a34e 100644
--- a/src/video_core/textures/decoders.cpp
+++ b/src/video_core/textures/decoders.cpp
@@ -86,88 +86,11 @@ u32 BytesPerPixel(TextureFormat format) {
86 } 86 }
87} 87}
88 88
89static u32 DepthBytesPerPixel(DepthFormat format) { 89std::vector<u8> UnswizzleTexture(VAddr address, u32 tile_size, u32 bytes_per_pixel, u32 width,
90 switch (format) { 90 u32 height, u32 block_height) {
91 case DepthFormat::Z16_UNORM:
92 return 2;
93 case DepthFormat::S8_Z24_UNORM:
94 case DepthFormat::Z24_S8_UNORM:
95 case DepthFormat::Z32_FLOAT:
96 return 4;
97 case DepthFormat::Z32_S8_X24_FLOAT:
98 return 8;
99 default:
100 UNIMPLEMENTED_MSG("Format not implemented");
101 break;
102 }
103}
104
105std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height,
106 u32 block_height) {
107 u8* data = Memory::GetPointer(address);
108 u32 bytes_per_pixel = BytesPerPixel(format);
109
110 std::vector<u8> unswizzled_data(width * height * bytes_per_pixel);
111
112 switch (format) {
113 case TextureFormat::DXT1:
114 case TextureFormat::DXT23:
115 case TextureFormat::DXT45:
116 case TextureFormat::DXN1:
117 case TextureFormat::DXN2:
118 case TextureFormat::BC7U:
119 // In the DXT and DXN formats, each 4x4 tile is swizzled instead of just individual pixel
120 // values.
121 CopySwizzledData(width / 4, height / 4, bytes_per_pixel, bytes_per_pixel, data,
122 unswizzled_data.data(), true, block_height);
123 break;
124 case TextureFormat::A8R8G8B8:
125 case TextureFormat::A2B10G10R10:
126 case TextureFormat::A1B5G5R5:
127 case TextureFormat::B5G6R5:
128 case TextureFormat::R8:
129 case TextureFormat::G8R8:
130 case TextureFormat::R16_G16_B16_A16:
131 case TextureFormat::R32_G32_B32_A32:
132 case TextureFormat::R32_G32:
133 case TextureFormat::R32:
134 case TextureFormat::R16:
135 case TextureFormat::R16_G16:
136 case TextureFormat::BF10GF11RF11:
137 case TextureFormat::ASTC_2D_4X4:
138 case TextureFormat::R32_G32_B32:
139 CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data,
140 unswizzled_data.data(), true, block_height);
141 break;
142 default:
143 UNIMPLEMENTED_MSG("Format not implemented");
144 break;
145 }
146
147 return unswizzled_data;
148}
149
150std::vector<u8> UnswizzleDepthTexture(VAddr address, DepthFormat format, u32 width, u32 height,
151 u32 block_height) {
152 u8* data = Memory::GetPointer(address);
153 u32 bytes_per_pixel = DepthBytesPerPixel(format);
154
155 std::vector<u8> unswizzled_data(width * height * bytes_per_pixel); 91 std::vector<u8> unswizzled_data(width * height * bytes_per_pixel);
156 92 CopySwizzledData(width / tile_size, height / tile_size, bytes_per_pixel, bytes_per_pixel,
157 switch (format) { 93 Memory::GetPointer(address), unswizzled_data.data(), true, block_height);
158 case DepthFormat::Z16_UNORM:
159 case DepthFormat::S8_Z24_UNORM:
160 case DepthFormat::Z24_S8_UNORM:
161 case DepthFormat::Z32_FLOAT:
162 case DepthFormat::Z32_S8_X24_FLOAT:
163 CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data,
164 unswizzled_data.data(), true, block_height);
165 break;
166 default:
167 UNIMPLEMENTED_MSG("Format not implemented");
168 break;
169 }
170
171 return unswizzled_data; 94 return unswizzled_data;
172} 95}
173 96
diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h
index 73a4924d1..1f7b731be 100644
--- a/src/video_core/textures/decoders.h
+++ b/src/video_core/textures/decoders.h
@@ -13,8 +13,8 @@ namespace Tegra::Texture {
13/** 13/**
14 * Unswizzles a swizzled texture without changing its format. 14 * Unswizzles a swizzled texture without changing its format.
15 */ 15 */
16std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height, 16std::vector<u8> UnswizzleTexture(VAddr address, u32 tile_size, u32 bytes_per_pixel, u32 width,
17 u32 block_height = TICEntry::DefaultBlockHeight); 17 u32 height, u32 block_height = TICEntry::DefaultBlockHeight);
18 18
19/** 19/**
20 * Unswizzles a swizzled depth texture without changing its format. 20 * Unswizzles a swizzled depth texture without changing its format.
diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp
index 5085ef96b..1e686b89e 100644
--- a/src/video_core/video_core.cpp
+++ b/src/video_core/video_core.cpp
@@ -9,8 +9,6 @@
9 9
10namespace VideoCore { 10namespace VideoCore {
11 11
12std::atomic<bool> g_toggle_framelimit_enabled;
13
14std::unique_ptr<RendererBase> CreateRenderer(EmuWindow& emu_window) { 12std::unique_ptr<RendererBase> CreateRenderer(EmuWindow& emu_window) {
15 return std::make_unique<RendererOpenGL>(emu_window); 13 return std::make_unique<RendererOpenGL>(emu_window);
16} 14}
diff --git a/src/video_core/video_core.h b/src/video_core/video_core.h
index 7c01c0b8d..2dc07540f 100644
--- a/src/video_core/video_core.h
+++ b/src/video_core/video_core.h
@@ -4,7 +4,6 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <atomic>
8#include <memory> 7#include <memory>
9 8
10class EmuWindow; 9class EmuWindow;
@@ -13,12 +12,6 @@ namespace VideoCore {
13 12
14class RendererBase; 13class RendererBase;
15 14
16enum class Renderer { Software, OpenGL };
17
18// TODO: Wrap these in a user settings struct along with any other graphics settings (often set from
19// qt ui)
20extern std::atomic<bool> g_toggle_framelimit_enabled;
21
22/** 15/**
23 * Creates a renderer instance. 16 * Creates a renderer instance.
24 * 17 *
diff --git a/src/yuzu/debugger/graphics/graphics_surface.cpp b/src/yuzu/debugger/graphics/graphics_surface.cpp
index 3f7103ab9..e037223c2 100644
--- a/src/yuzu/debugger/graphics/graphics_surface.cpp
+++ b/src/yuzu/debugger/graphics/graphics_surface.cpp
@@ -383,8 +383,10 @@ void GraphicsSurfaceWidget::OnUpdate() {
383 QImage decoded_image(surface_width, surface_height, QImage::Format_ARGB32); 383 QImage decoded_image(surface_width, surface_height, QImage::Format_ARGB32);
384 boost::optional<VAddr> address = gpu.memory_manager->GpuToCpuAddress(surface_address); 384 boost::optional<VAddr> address = gpu.memory_manager->GpuToCpuAddress(surface_address);
385 385
386 auto unswizzled_data = 386 // TODO(bunnei): Will not work with BCn formats that swizzle 4x4 tiles.
387 Tegra::Texture::UnswizzleTexture(*address, surface_format, surface_width, surface_height); 387 // Needs to be fixed if we plan to use this feature more, otherwise we may remove it.
388 auto unswizzled_data = Tegra::Texture::UnswizzleTexture(
389 *address, 1, Tegra::Texture::BytesPerPixel(surface_format), surface_width, surface_height);
388 390
389 auto texture_data = Tegra::Texture::DecodeTexture(unswizzled_data, surface_format, 391 auto texture_data = Tegra::Texture::DecodeTexture(unswizzled_data, surface_format,
390 surface_width, surface_height); 392 surface_width, surface_height);
diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h
index 114a0fc7f..8fe5e8b80 100644
--- a/src/yuzu/game_list_p.h
+++ b/src/yuzu/game_list_p.h
@@ -4,6 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <array>
7#include <atomic> 8#include <atomic>
8#include <utility> 9#include <utility>
9#include <QImage> 10#include <QImage>
@@ -39,7 +40,6 @@ public:
39 * If this class receives valid SMDH data, it will also display game icons and titles. 40 * If this class receives valid SMDH data, it will also display game icons and titles.
40 */ 41 */
41class GameListItemPath : public GameListItem { 42class GameListItemPath : public GameListItem {
42
43public: 43public:
44 static const int FullPathRole = Qt::UserRole + 1; 44 static const int FullPathRole = Qt::UserRole + 1;
45 static const int TitleRole = Qt::UserRole + 2; 45 static const int TitleRole = Qt::UserRole + 2;
@@ -48,18 +48,18 @@ public:
48 48
49 GameListItemPath() = default; 49 GameListItemPath() = default;
50 GameListItemPath(const QString& game_path, const std::vector<u8>& picture_data, 50 GameListItemPath(const QString& game_path, const std::vector<u8>& picture_data,
51 const QString& game_name, const QString& game_type, u64 program_id) 51 const QString& game_name, const QString& game_type, u64 program_id) {
52 : GameListItem() {
53 setData(game_path, FullPathRole); 52 setData(game_path, FullPathRole);
54 setData(game_name, TitleRole); 53 setData(game_name, TitleRole);
55 setData(qulonglong(program_id), ProgramIdRole); 54 setData(qulonglong(program_id), ProgramIdRole);
56 setData(game_type, FileTypeRole); 55 setData(game_type, FileTypeRole);
57 56
57 const u32 size = UISettings::values.icon_size;
58
58 QPixmap picture; 59 QPixmap picture;
59 u32 size = UISettings::values.icon_size; 60 if (!picture.loadFromData(picture_data.data(), static_cast<u32>(picture_data.size()))) {
60 if (!picture.loadFromData(picture_data.data(), picture_data.size()))
61 picture = GetDefaultIcon(size); 61 picture = GetDefaultIcon(size);
62 62 }
63 picture = picture.scaled(size, size); 63 picture = picture.scaled(size, size);
64 64
65 setData(picture, Qt::DecorationRole); 65 setData(picture, Qt::DecorationRole);
@@ -70,17 +70,16 @@ public:
70 std::string filename; 70 std::string filename;
71 Common::SplitPath(data(FullPathRole).toString().toStdString(), nullptr, &filename, 71 Common::SplitPath(data(FullPathRole).toString().toStdString(), nullptr, &filename,
72 nullptr); 72 nullptr);
73 QString title = data(TitleRole).toString();
74 73
75 std::vector<QString> row_data{ 74 const std::array<QString, 4> row_data{{
76 QString::fromStdString(filename), 75 QString::fromStdString(filename),
77 data(FileTypeRole).toString(), 76 data(FileTypeRole).toString(),
78 QString::fromStdString(fmt::format("0x{:016X}", data(ProgramIdRole).toULongLong())), 77 QString::fromStdString(fmt::format("0x{:016X}", data(ProgramIdRole).toULongLong())),
79 data(TitleRole).toString(), 78 data(TitleRole).toString(),
80 }; 79 }};
81 80
82 auto row1 = row_data.at(UISettings::values.row_1_text_id); 81 const auto& row1 = row_data.at(UISettings::values.row_1_text_id);
83 auto row2 = row_data.at(UISettings::values.row_2_text_id); 82 const auto& row2 = row_data.at(UISettings::values.row_2_text_id);
84 83
85 if (row1.isEmpty() || row1 == row2) 84 if (row1.isEmpty() || row1 == row2)
86 return row2; 85 return row2;
@@ -88,9 +87,9 @@ public:
88 return row1; 87 return row1;
89 88
90 return row1 + "\n " + row2; 89 return row1 + "\n " + row2;
91 } else {
92 return GameListItem::data(role);
93 } 90 }
91
92 return GameListItem::data(role);
94 } 93 }
95}; 94};
96 95