summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--src/common/CMakeLists.txt2
-rw-r--r--src/common/break_points.cpp90
-rw-r--r--src/common/break_points.h49
-rw-r--r--src/common/misc.cpp2
-rw-r--r--src/common/x64/xbyak_abi.h20
-rw-r--r--src/common/x64/xbyak_util.h6
-rw-r--r--src/core/frontend/emu_window.h6
-rw-r--r--src/core/hle/kernel/svc.cpp7
-rw-r--r--src/core/hle/service/mm/mm_u.cpp83
-rw-r--r--src/core/hle/service/mm/mm_u.h15
-rw-r--r--src/core/loader/deconstructed_rom_directory.cpp1
-rw-r--r--src/core/loader/elf.cpp1
-rw-r--r--src/core/loader/loader.cpp6
-rw-r--r--src/core/loader/loader.h7
-rw-r--r--src/core/loader/nro.cpp1
-rw-r--r--src/core/loader/nso.cpp1
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp6
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp14
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h71
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp35
21 files changed, 150 insertions, 275 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ff8385e3a..59c610732 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -66,10 +66,12 @@ if (NOT ENABLE_GENERIC)
detect_architecture("_M_AMD64" x86_64)
detect_architecture("_M_IX86" x86)
detect_architecture("_M_ARM" ARM)
+ detect_architecture("_M_ARM64" ARM64)
else()
detect_architecture("__x86_64__" x86_64)
detect_architecture("__i386__" x86)
detect_architecture("__arm__" ARM)
+ detect_architecture("__aarch64__" ARM64)
endif()
endif()
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index d5d4f6f82..939b8a7d3 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -29,8 +29,6 @@ add_library(common STATIC
assert.h
bit_field.h
bit_set.h
- break_points.cpp
- break_points.h
cityhash.cpp
cityhash.h
color.h
diff --git a/src/common/break_points.cpp b/src/common/break_points.cpp
deleted file mode 100644
index fa367a4ca..000000000
--- a/src/common/break_points.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include <algorithm>
-#include <sstream>
-#include "common/break_points.h"
-
-bool BreakPoints::IsAddressBreakPoint(u32 iAddress) const {
- auto cond = [&iAddress](const TBreakPoint& bp) { return bp.iAddress == iAddress; };
- auto it = std::find_if(m_BreakPoints.begin(), m_BreakPoints.end(), cond);
- return it != m_BreakPoints.end();
-}
-
-bool BreakPoints::IsTempBreakPoint(u32 iAddress) const {
- auto cond = [&iAddress](const TBreakPoint& bp) {
- return bp.iAddress == iAddress && bp.bTemporary;
- };
- auto it = std::find_if(m_BreakPoints.begin(), m_BreakPoints.end(), cond);
- return it != m_BreakPoints.end();
-}
-
-BreakPoints::TBreakPointsStr BreakPoints::GetStrings() const {
- TBreakPointsStr bps;
- for (auto breakpoint : m_BreakPoints) {
- if (!breakpoint.bTemporary) {
- std::stringstream bp;
- bp << std::hex << breakpoint.iAddress << " " << (breakpoint.bOn ? "n" : "");
- bps.push_back(bp.str());
- }
- }
-
- return bps;
-}
-
-void BreakPoints::AddFromStrings(const TBreakPointsStr& bps) {
- for (auto bps_item : bps) {
- TBreakPoint bp;
- std::stringstream bpstr;
- bpstr << std::hex << bps_item;
- bpstr >> bp.iAddress;
- bp.bOn = bps_item.find("n") != bps_item.npos;
- bp.bTemporary = false;
- Add(bp);
- }
-}
-
-void BreakPoints::Add(const TBreakPoint& bp) {
- if (!IsAddressBreakPoint(bp.iAddress)) {
- m_BreakPoints.push_back(bp);
- // if (jit)
- // jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4);
- }
-}
-
-void BreakPoints::Add(u32 em_address, bool temp) {
- if (!IsAddressBreakPoint(em_address)) // only add new addresses
- {
- TBreakPoint pt; // breakpoint settings
- pt.bOn = true;
- pt.bTemporary = temp;
- pt.iAddress = em_address;
-
- m_BreakPoints.push_back(pt);
-
- // if (jit)
- // jit->GetBlockCache()->InvalidateICache(em_address, 4);
- }
-}
-
-void BreakPoints::Remove(u32 em_address) {
- auto cond = [&em_address](const TBreakPoint& bp) { return bp.iAddress == em_address; };
- auto it = std::find_if(m_BreakPoints.begin(), m_BreakPoints.end(), cond);
- if (it != m_BreakPoints.end())
- m_BreakPoints.erase(it);
-}
-
-void BreakPoints::Clear() {
- // if (jit)
- //{
- // std::for_each(m_BreakPoints.begin(), m_BreakPoints.end(),
- // [](const TBreakPoint& bp)
- // {
- // jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4);
- // }
- // );
- //}
-
- m_BreakPoints.clear();
-}
diff --git a/src/common/break_points.h b/src/common/break_points.h
deleted file mode 100644
index e15b9f842..000000000
--- a/src/common/break_points.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include <string>
-#include <vector>
-#include "common/common_types.h"
-
-class DebugInterface;
-
-struct TBreakPoint {
- u32 iAddress;
- bool bOn;
- bool bTemporary;
-};
-
-// Code breakpoints.
-class BreakPoints {
-public:
- typedef std::vector<TBreakPoint> TBreakPoints;
- typedef std::vector<std::string> TBreakPointsStr;
-
- const TBreakPoints& GetBreakPoints() {
- return m_BreakPoints;
- }
-
- TBreakPointsStr GetStrings() const;
- void AddFromStrings(const TBreakPointsStr& bps);
-
- // is address breakpoint
- bool IsAddressBreakPoint(u32 iAddress) const;
- bool IsTempBreakPoint(u32 iAddress) const;
-
- // Add BreakPoint
- void Add(u32 em_address, bool temp = false);
- void Add(const TBreakPoint& bp);
-
- // Remove Breakpoint
- void Remove(u32 iAddress);
- void Clear();
-
- void DeleteByAddress(u32 Address);
-
-private:
- TBreakPoints m_BreakPoints;
- u32 m_iBreakOnCount;
-};
diff --git a/src/common/misc.cpp b/src/common/misc.cpp
index 217a87098..3fa8a3bc4 100644
--- a/src/common/misc.cpp
+++ b/src/common/misc.cpp
@@ -4,7 +4,7 @@
#include <cstddef>
#ifdef _WIN32
-#include <Windows.h>
+#include <windows.h>
#else
#include <cerrno>
#include <cstring>
diff --git a/src/common/x64/xbyak_abi.h b/src/common/x64/xbyak_abi.h
index fd3fbdd4b..927da9187 100644
--- a/src/common/x64/xbyak_abi.h
+++ b/src/common/x64/xbyak_abi.h
@@ -9,10 +9,9 @@
#include "common/assert.h"
#include "common/bit_set.h"
-namespace Common {
-namespace X64 {
+namespace Common::X64 {
-int RegToIndex(const Xbyak::Reg& reg) {
+inline int RegToIndex(const Xbyak::Reg& reg) {
using Kind = Xbyak::Reg::Kind;
ASSERT_MSG((reg.getKind() & (Kind::REG | Kind::XMM)) != 0,
"RegSet only support GPRs and XMM registers.");
@@ -152,8 +151,8 @@ constexpr size_t ABI_SHADOW_SPACE = 0;
#endif
-void ABI_CalculateFrameSize(BitSet32 regs, size_t rsp_alignment, size_t needed_frame_size,
- s32* out_subtraction, s32* out_xmm_offset) {
+inline void ABI_CalculateFrameSize(BitSet32 regs, size_t rsp_alignment, size_t needed_frame_size,
+ s32* out_subtraction, s32* out_xmm_offset) {
int count = (regs & ABI_ALL_GPRS).Count();
rsp_alignment -= count * 8;
size_t subtraction = 0;
@@ -174,8 +173,8 @@ void ABI_CalculateFrameSize(BitSet32 regs, size_t rsp_alignment, size_t needed_f
*out_xmm_offset = (s32)(subtraction - xmm_base_subtraction);
}
-size_t ABI_PushRegistersAndAdjustStack(Xbyak::CodeGenerator& code, BitSet32 regs,
- size_t rsp_alignment, size_t needed_frame_size = 0) {
+inline size_t ABI_PushRegistersAndAdjustStack(Xbyak::CodeGenerator& code, BitSet32 regs,
+ size_t rsp_alignment, size_t needed_frame_size = 0) {
s32 subtraction, xmm_offset;
ABI_CalculateFrameSize(regs, rsp_alignment, needed_frame_size, &subtraction, &xmm_offset);
@@ -195,8 +194,8 @@ size_t ABI_PushRegistersAndAdjustStack(Xbyak::CodeGenerator& code, BitSet32 regs
return ABI_SHADOW_SPACE;
}
-void ABI_PopRegistersAndAdjustStack(Xbyak::CodeGenerator& code, BitSet32 regs, size_t rsp_alignment,
- size_t needed_frame_size = 0) {
+inline void ABI_PopRegistersAndAdjustStack(Xbyak::CodeGenerator& code, BitSet32 regs,
+ size_t rsp_alignment, size_t needed_frame_size = 0) {
s32 subtraction, xmm_offset;
ABI_CalculateFrameSize(regs, rsp_alignment, needed_frame_size, &subtraction, &xmm_offset);
@@ -217,5 +216,4 @@ void ABI_PopRegistersAndAdjustStack(Xbyak::CodeGenerator& code, BitSet32 regs, s
}
}
-} // namespace X64
-} // namespace Common
+} // namespace Common::X64
diff --git a/src/common/x64/xbyak_util.h b/src/common/x64/xbyak_util.h
index ec76e0a47..02323a017 100644
--- a/src/common/x64/xbyak_util.h
+++ b/src/common/x64/xbyak_util.h
@@ -8,8 +8,7 @@
#include <xbyak.h>
#include "common/x64/xbyak_abi.h"
-namespace Common {
-namespace X64 {
+namespace Common::X64 {
// Constants for use with cmpps/cmpss
enum {
@@ -45,5 +44,4 @@ inline void CallFarFunction(Xbyak::CodeGenerator& code, const T f) {
}
}
-} // namespace X64
-} // namespace Common
+} // namespace Common::X64
diff --git a/src/core/frontend/emu_window.h b/src/core/frontend/emu_window.h
index 384dc7822..7006a37b3 100644
--- a/src/core/frontend/emu_window.h
+++ b/src/core/frontend/emu_window.h
@@ -34,9 +34,9 @@ class EmuWindow {
public:
/// Data structure to store emuwindow configuration
struct WindowConfig {
- bool fullscreen;
- int res_width;
- int res_height;
+ bool fullscreen = false;
+ int res_width = 0;
+ int res_height = 0;
std::pair<unsigned, unsigned> min_client_area_size;
};
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index b24f409b3..6be5c474e 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -250,8 +250,11 @@ static ResultCode ArbitrateUnlock(VAddr mutex_addr) {
}
/// Break program execution
-static void Break(u64 unk_0, u64 unk_1, u64 unk_2) {
- LOG_CRITICAL(Debug_Emulated, "Emulated program broke execution!");
+static void Break(u64 reason, u64 info1, u64 info2) {
+ LOG_CRITICAL(
+ Debug_Emulated,
+ "Emulated program broke execution! reason=0x{:016X}, info1=0x{:016X}, info2=0x{:016X}",
+ reason, info1, info2);
ASSERT(false);
}
diff --git a/src/core/hle/service/mm/mm_u.cpp b/src/core/hle/service/mm/mm_u.cpp
index 08f45b78a..7b91bb258 100644
--- a/src/core/hle/service/mm/mm_u.cpp
+++ b/src/core/hle/service/mm/mm_u.cpp
@@ -9,42 +9,63 @@
namespace Service::MM {
-void InstallInterfaces(SM::ServiceManager& service_manager) {
- std::make_shared<MM_U>()->InstallAsService(service_manager);
-}
+class MM_U final : public ServiceFramework<MM_U> {
+public:
+ explicit MM_U() : ServiceFramework{"mm:u"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, &MM_U::Initialize, "InitializeOld"},
+ {1, &MM_U::Finalize, "FinalizeOld"},
+ {2, &MM_U::SetAndWait, "SetAndWaitOld"},
+ {3, &MM_U::Get, "GetOld"},
+ {4, &MM_U::Initialize, "Initialize"},
+ {5, &MM_U::Finalize, "Finalize"},
+ {6, &MM_U::SetAndWait, "SetAndWait"},
+ {7, &MM_U::Get, "Get"},
+ };
+ // clang-format on
-void MM_U::Initialize(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_MM, "(STUBBED) called");
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
-}
+ RegisterHandlers(functions);
+ }
-void MM_U::SetAndWait(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- min = rp.Pop<u32>();
- max = rp.Pop<u32>();
- current = min;
+private:
+ void Initialize(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_MM, "(STUBBED) called");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+ }
- LOG_WARNING(Service_MM, "(STUBBED) called, min=0x{:X}, max=0x{:X}", min, max);
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
-}
+ void Finalize(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_MM, "(STUBBED) called");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+ }
-void MM_U::Get(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_MM, "(STUBBED) called");
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(RESULT_SUCCESS);
- rb.Push(current);
-}
+ void SetAndWait(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ min = rp.Pop<u32>();
+ max = rp.Pop<u32>();
+ current = min;
-MM_U::MM_U() : ServiceFramework("mm:u") {
- static const FunctionInfo functions[] = {
- {0, nullptr, "InitializeOld"}, {1, nullptr, "FinalizeOld"},
- {2, nullptr, "SetAndWaitOld"}, {3, nullptr, "GetOld"},
- {4, &MM_U::Initialize, "Initialize"}, {5, nullptr, "Finalize"},
- {6, &MM_U::SetAndWait, "SetAndWait"}, {7, &MM_U::Get, "Get"},
- };
- RegisterHandlers(functions);
+ LOG_WARNING(Service_MM, "(STUBBED) called, min=0x{:X}, max=0x{:X}", min, max);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+ }
+
+ void Get(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_MM, "(STUBBED) called");
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push(current);
+ }
+
+ u32 min{0};
+ u32 max{0};
+ u32 current{0};
+};
+
+void InstallInterfaces(SM::ServiceManager& service_manager) {
+ std::make_shared<MM_U>()->InstallAsService(service_manager);
}
} // namespace Service::MM
diff --git a/src/core/hle/service/mm/mm_u.h b/src/core/hle/service/mm/mm_u.h
index 79eeedf9c..5439fa653 100644
--- a/src/core/hle/service/mm/mm_u.h
+++ b/src/core/hle/service/mm/mm_u.h
@@ -8,21 +8,6 @@
namespace Service::MM {
-class MM_U final : public ServiceFramework<MM_U> {
-public:
- MM_U();
- ~MM_U() = default;
-
-private:
- void Initialize(Kernel::HLERequestContext& ctx);
- void SetAndWait(Kernel::HLERequestContext& ctx);
- void Get(Kernel::HLERequestContext& ctx);
-
- u32 min{0};
- u32 max{0};
- u32 current{0};
-};
-
/// Registers all MM services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& service_manager);
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp
index de05f21d8..d575a9bea 100644
--- a/src/core/loader/deconstructed_rom_directory.cpp
+++ b/src/core/loader/deconstructed_rom_directory.cpp
@@ -118,7 +118,6 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(
process->program_id = metadata.GetTitleID();
process->svc_access_mask.set();
- process->address_mappings = default_address_mappings;
process->resource_limit =
Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
process->Run(Memory::PROCESS_IMAGE_VADDR, metadata.GetMainThreadPriority(),
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp
index 401cad3ab..6420a7f11 100644
--- a/src/core/loader/elf.cpp
+++ b/src/core/loader/elf.cpp
@@ -398,7 +398,6 @@ ResultStatus AppLoader_ELF::Load(Kernel::SharedPtr<Kernel::Process>& process) {
process->LoadModule(codeset, codeset->entrypoint);
process->svc_access_mask.set();
- process->address_mappings = default_address_mappings;
// Attach the default resource limit (APPLICATION) to the process
process->resource_limit =
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index 1f2f31535..b143f043c 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -17,12 +17,6 @@
namespace Loader {
-const std::initializer_list<Kernel::AddressMapping> default_address_mappings = {
- {0x1FF50000, 0x8000, true}, // part of DSP RAM
- {0x1FF70000, 0x8000, true}, // part of DSP RAM
- {0x1F000000, 0x600000, false}, // entire VRAM
-};
-
FileType IdentifyFile(FileSys::VirtualFile file) {
FileType type;
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h
index 285363549..6dffe451a 100644
--- a/src/core/loader/loader.h
+++ b/src/core/loader/loader.h
@@ -5,7 +5,6 @@
#pragma once
#include <algorithm>
-#include <initializer_list>
#include <memory>
#include <string>
#include <utility>
@@ -208,12 +207,6 @@ protected:
};
/**
- * Common address mappings found in most games, used for binary formats that don't have this
- * information.
- */
-extern const std::initializer_list<Kernel::AddressMapping> default_address_mappings;
-
-/**
* Identifies a bootable file and return a suitable loader
* @param file The bootable file
* @return the best loader for this file
diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp
index 908d91eab..2179cf2ea 100644
--- a/src/core/loader/nro.cpp
+++ b/src/core/loader/nro.cpp
@@ -186,7 +186,6 @@ ResultStatus AppLoader_NRO::Load(Kernel::SharedPtr<Kernel::Process>& process) {
}
process->svc_access_mask.set();
- process->address_mappings = default_address_mappings;
process->resource_limit =
Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
process->Run(base_addr, THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE);
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp
index fee7d58c6..a94558ac5 100644
--- a/src/core/loader/nso.cpp
+++ b/src/core/loader/nso.cpp
@@ -152,7 +152,6 @@ ResultStatus AppLoader_NSO::Load(Kernel::SharedPtr<Kernel::Process>& process) {
LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", file->GetName(), Memory::PROCESS_IMAGE_VADDR);
process->svc_access_mask.set();
- process->address_mappings = default_address_mappings;
process->resource_limit =
Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
process->Run(Memory::PROCESS_IMAGE_VADDR, THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 52a649e2f..9d1549fe9 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -648,11 +648,11 @@ std::tuple<u8*, GLintptr, u32> RasterizerOpenGL::SetupConstBuffers(
if (used_buffer.IsIndirect()) {
// Buffer is accessed indirectly, so upload the entire thing
- size = buffer.size * sizeof(float);
+ size = buffer.size;
if (size > MaxConstbufferSize) {
- LOG_ERROR(HW_GPU, "indirect constbuffer size {} exceeds maximum {}", size,
- MaxConstbufferSize);
+ LOG_CRITICAL(HW_GPU, "indirect constbuffer size {} exceeds maximum {}", size,
+ MaxConstbufferSize);
size = MaxConstbufferSize;
}
} else {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 5d58ebd4f..05f153599 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -119,7 +119,8 @@ static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_form
{GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm,
true}, // BC7U
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_4X4
- {GL_RG8, GL_RG, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // G8R8
+ {GL_RG8, GL_RG, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // G8R8U
+ {GL_RG8, GL_RG, GL_BYTE, ComponentType::SNorm, false}, // G8R8S
{GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // BGRA8
{GL_RGBA32F, GL_RGBA, GL_FLOAT, ComponentType::Float, false}, // RGBA32F
{GL_RG32F, GL_RG, GL_FLOAT, ComponentType::Float, false}, // RG32F
@@ -260,7 +261,8 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPU
MortonCopy<true, PixelFormat::DXN2SNORM>,
MortonCopy<true, PixelFormat::BC7U>,
MortonCopy<true, PixelFormat::ASTC_2D_4X4>,
- MortonCopy<true, PixelFormat::G8R8>,
+ MortonCopy<true, PixelFormat::G8R8U>,
+ MortonCopy<true, PixelFormat::G8R8S>,
MortonCopy<true, PixelFormat::BGRA8>,
MortonCopy<true, PixelFormat::RGBA32F>,
MortonCopy<true, PixelFormat::RG32F>,
@@ -315,7 +317,8 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPU
nullptr,
nullptr,
nullptr,
- MortonCopy<false, PixelFormat::G8R8>,
+ MortonCopy<false, PixelFormat::G8R8U>,
+ MortonCopy<false, PixelFormat::G8R8S>,
MortonCopy<false, PixelFormat::BGRA8>,
MortonCopy<false, PixelFormat::RGBA32F>,
MortonCopy<false, PixelFormat::RG32F>,
@@ -461,7 +464,7 @@ static void ConvertS8Z24ToZ24S8(std::vector<u8>& data, u32 width, u32 height) {
}
static void ConvertG8R8ToR8G8(std::vector<u8>& data, u32 width, u32 height) {
- const auto bpp{CachedSurface::GetGLBytesPerPixel(PixelFormat::G8R8)};
+ const auto bpp{CachedSurface::GetGLBytesPerPixel(PixelFormat::G8R8U)};
for (size_t y = 0; y < height; ++y) {
for (size_t x = 0; x < width; ++x) {
const size_t offset{bpp * (y * width + x)};
@@ -493,7 +496,8 @@ static void ConvertFormatAsNeeded_LoadGLBuffer(std::vector<u8>& data, PixelForma
ConvertS8Z24ToZ24S8(data, width, height);
break;
- case PixelFormat::G8R8:
+ case PixelFormat::G8R8U:
+ case PixelFormat::G8R8S:
// Convert the G8R8 color format to R8G8, as OpenGL does not support G8R8.
ConvertG8R8ToR8G8(data, width, height);
break;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index 36a41522b..37eef5ad0 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -43,36 +43,37 @@ struct SurfaceParams {
DXN2SNORM = 17,
BC7U = 18,
ASTC_2D_4X4 = 19,
- G8R8 = 20,
- BGRA8 = 21,
- RGBA32F = 22,
- RG32F = 23,
- R32F = 24,
- R16F = 25,
- R16UNORM = 26,
- R16S = 27,
- R16UI = 28,
- R16I = 29,
- RG16 = 30,
- RG16F = 31,
- RG16UI = 32,
- RG16I = 33,
- RG16S = 34,
- RGB32F = 35,
- SRGBA8 = 36,
- RG8U = 37,
- RG8S = 38,
- RG32UI = 39,
- R32UI = 40,
+ G8R8U = 20,
+ G8R8S = 21,
+ BGRA8 = 22,
+ RGBA32F = 23,
+ RG32F = 24,
+ R32F = 25,
+ R16F = 26,
+ R16UNORM = 27,
+ R16S = 28,
+ R16UI = 29,
+ R16I = 30,
+ RG16 = 31,
+ RG16F = 32,
+ RG16UI = 33,
+ RG16I = 34,
+ RG16S = 35,
+ RGB32F = 36,
+ SRGBA8 = 37,
+ RG8U = 38,
+ RG8S = 39,
+ RG32UI = 40,
+ R32UI = 41,
MaxColorFormat,
// DepthStencil formats
- Z24S8 = 41,
- S8Z24 = 42,
- Z32F = 43,
- Z16 = 44,
- Z32FS8 = 45,
+ Z24S8 = 42,
+ S8Z24 = 43,
+ Z32F = 44,
+ Z16 = 45,
+ Z32FS8 = 46,
MaxDepthStencilFormat,
@@ -130,7 +131,8 @@ struct SurfaceParams {
4, // DXN2SNORM
4, // BC7U
4, // ASTC_2D_4X4
- 1, // G8R8
+ 1, // G8R8U
+ 1, // G8R8S
1, // BGRA8
1, // RGBA32F
1, // RG32F
@@ -187,7 +189,8 @@ struct SurfaceParams {
128, // DXN2SNORM
128, // BC7U
32, // ASTC_2D_4X4
- 16, // G8R8
+ 16, // G8R8U
+ 16, // G8R8S
32, // BGRA8
128, // RGBA32F
64, // RG32F
@@ -341,7 +344,15 @@ struct SurfaceParams {
static_cast<u32>(component_type));
UNREACHABLE();
case Tegra::Texture::TextureFormat::G8R8:
- return PixelFormat::G8R8;
+ switch (component_type) {
+ case Tegra::Texture::ComponentType::UNORM:
+ return PixelFormat::G8R8U;
+ case Tegra::Texture::ComponentType::SNORM:
+ return PixelFormat::G8R8S;
+ }
+ LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
+ static_cast<u32>(component_type));
+ UNREACHABLE();
case Tegra::Texture::TextureFormat::R16_G16_B16_A16:
return PixelFormat::RGBA16F;
case Tegra::Texture::TextureFormat::BF10GF11RF11:
@@ -396,6 +407,8 @@ struct SurfaceParams {
UNREACHABLE();
case Tegra::Texture::TextureFormat::ZF32:
return PixelFormat::Z32F;
+ case Tegra::Texture::TextureFormat::Z16:
+ return PixelFormat::Z16;
case Tegra::Texture::TextureFormat::Z24S8:
return PixelFormat::Z24S8;
case Tegra::Texture::TextureFormat::DXT1:
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 6834d7085..dabf98b74 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -383,15 +383,13 @@ public:
}
}
- std::string GetUniformIndirect(u64 index, s64 offset, const Register& index_reg,
+ std::string GetUniformIndirect(u64 cbuf_index, s64 offset, const std::string& index_str,
GLSLRegister::Type type) {
- declr_const_buffers[index].MarkAsUsedIndirect(index, stage);
+ declr_const_buffers[cbuf_index].MarkAsUsedIndirect(cbuf_index, stage);
- std::string final_offset = "((floatBitsToInt(" + GetRegister(index_reg, 0) + ") + " +
- std::to_string(offset) + ") / 4)";
-
- std::string value =
- 'c' + std::to_string(index) + '[' + final_offset + " / 4][" + final_offset + " % 4]";
+ std::string final_offset = fmt::format("({} + {})", index_str, offset / 4);
+ std::string value = 'c' + std::to_string(cbuf_index) + '[' + final_offset + " / 4][" +
+ final_offset + " % 4]";
if (type == GLSLRegister::Type::Float) {
return value;
@@ -1355,11 +1353,16 @@ private:
case OpCode::Id::LD_C: {
ASSERT_MSG(instr.ld_c.unknown == 0, "Unimplemented");
+ // Add an extra scope and declare the index register inside to prevent
+ // overwriting it in case it is used as an output of the LD instruction.
+ shader.AddLine("{");
+ ++shader.scope;
+
+ shader.AddLine("uint index = (" + regs.GetRegisterAsInteger(instr.gpr8, 0, false) +
+ " / 4) & (MAX_CONSTBUFFER_ELEMENTS - 1);");
+
std::string op_a =
- regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 0, instr.gpr8,
- GLSLRegister::Type::Float);
- std::string op_b =
- regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 4, instr.gpr8,
+ regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 0, "index",
GLSLRegister::Type::Float);
switch (instr.ld_c.type.Value()) {
@@ -1367,16 +1370,22 @@ private:
regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1);
break;
- case Tegra::Shader::UniformType::Double:
+ case Tegra::Shader::UniformType::Double: {
+ std::string op_b =
+ regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 4,
+ "index", GLSLRegister::Type::Float);
regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1);
regs.SetRegisterToFloat(instr.gpr0.Value() + 1, 0, op_b, 1, 1);
break;
-
+ }
default:
LOG_CRITICAL(HW_GPU, "Unhandled type: {}",
static_cast<unsigned>(instr.ld_c.type.Value()));
UNREACHABLE();
}
+
+ --shader.scope;
+ shader.AddLine("}");
break;
}
case OpCode::Id::ST_A: {