CMakeLists: Specify -Wextra on linux builds

Allows reporting more cases where logic errors may exist, such as
implicit fallthrough cases, etc.

We currently ignore unused parameters, since we currently have many
cases where this is intentional (virtual interfaces).

While we're at it, we can also tidy up any existing code that causes
warnings. This also uncovered a few bugs as well.
merge-requests/60/head
Lioncash 2020-04-15 15:59:23 +07:00
parent e33196d4e7
commit 1c340c6efa
26 changed files with 93 additions and 70 deletions

@ -53,8 +53,11 @@ if (MSVC)
else() else()
add_compile_options( add_compile_options(
-Wall -Wall
-Werror=implicit-fallthrough
-Werror=reorder -Werror=reorder
-Wextra
-Wno-attributes -Wno-attributes
-Wno-unused-parameter
) )
if (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL Clang) if (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL Clang)

@ -123,7 +123,7 @@ Symbols GetSymbols(VAddr text_offset, Memory::Memory& memory) {
std::optional<std::string> GetSymbolName(const Symbols& symbols, VAddr func_address) { std::optional<std::string> GetSymbolName(const Symbols& symbols, VAddr func_address) {
const auto iter = const auto iter =
std::find_if(symbols.begin(), symbols.end(), [func_address](const auto& pair) { std::find_if(symbols.begin(), symbols.end(), [func_address](const auto& pair) {
const auto& [symbol, name] = pair; const auto& symbol = pair.first;
const auto end_address = symbol.value + symbol.size; const auto end_address = symbol.value + symbol.size;
return func_address >= symbol.value && func_address < end_address; return func_address >= symbol.value && func_address < end_address;
}); });
@ -146,7 +146,7 @@ std::vector<ARM_Interface::BacktraceEntry> ARM_Interface::GetBacktrace() const {
auto fp = GetReg(29); auto fp = GetReg(29);
auto lr = GetReg(30); auto lr = GetReg(30);
while (true) { while (true) {
out.push_back({"", 0, lr, 0}); out.push_back({"", 0, lr, 0, ""});
if (!fp) { if (!fp) {
break; break;
} }

@ -440,7 +440,8 @@ std::map<std::string, std::string, std::less<>> PatchManager::GetPatchVersionNam
// Game Updates // Game Updates
const auto update_tid = GetUpdateTitleID(title_id); const auto update_tid = GetUpdateTitleID(title_id);
PatchManager update{update_tid}; PatchManager update{update_tid};
auto [nacp, discard_icon_file] = update.GetControlMetadata(); const auto metadata = update.GetControlMetadata();
const auto& nacp = metadata.first;
const auto update_disabled = const auto update_disabled =
std::find(disabled.cbegin(), disabled.cend(), "Update") != disabled.cend(); std::find(disabled.cbegin(), disabled.cend(), "Update") != disabled.cend();

@ -591,14 +591,18 @@ InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_ex
InstallResult RegisteredCache::InstallEntry(const NCA& nca, TitleType type, InstallResult RegisteredCache::InstallEntry(const NCA& nca, TitleType type,
bool overwrite_if_exists, const VfsCopyFunction& copy) { bool overwrite_if_exists, const VfsCopyFunction& copy) {
CNMTHeader header{ CNMTHeader header{
nca.GetTitleId(), ///< Title ID nca.GetTitleId(), // Title ID
0, ///< Ignore/Default title version 0, // Ignore/Default title version
type, ///< Type type, // Type
{}, ///< Padding {}, // Padding
0x10, ///< Default table offset 0x10, // Default table offset
1, ///< 1 Content Entry 1, // 1 Content Entry
0, ///< No Meta Entries 0, // No Meta Entries
{}, ///< Padding {}, // Padding
{}, // Reserved 1
0, // Is committed
0, // Required download system version
{}, // Reserved 2
}; };
OptionalHeader opt_header{0, 0}; OptionalHeader opt_header{0, 0};
ContentRecord c_rec{{}, {}, {}, GetCRTypeFromNCAType(nca.GetType()), {}}; ContentRecord c_rec{{}, {}, {}, GetCRTypeFromNCAType(nca.GetType()), {}};
@ -848,7 +852,8 @@ VirtualFile ManualContentProvider::GetEntryUnparsed(u64 title_id, ContentRecordT
VirtualFile ManualContentProvider::GetEntryRaw(u64 title_id, ContentRecordType type) const { VirtualFile ManualContentProvider::GetEntryRaw(u64 title_id, ContentRecordType type) const {
const auto iter = const auto iter =
std::find_if(entries.begin(), entries.end(), [title_id, type](const auto& entry) { std::find_if(entries.begin(), entries.end(), [title_id, type](const auto& entry) {
const auto [title_type, content_type, e_title_id] = entry.first; const auto content_type = std::get<1>(entry.first);
const auto e_title_id = std::get<2>(entry.first);
return content_type == type && e_title_id == title_id; return content_type == type && e_title_id == title_id;
}); });
if (iter == entries.end()) if (iter == entries.end())

@ -42,11 +42,11 @@ VirtualDir ExtractZIP(VirtualFile file) {
continue; continue;
if (name.back() != '/') { if (name.back() != '/') {
std::unique_ptr<zip_file_t, decltype(&zip_fclose)> file{ std::unique_ptr<zip_file_t, decltype(&zip_fclose)> file2{
zip_fopen_index(zip.get(), i, 0), zip_fclose}; zip_fopen_index(zip.get(), i, 0), zip_fclose};
std::vector<u8> buf(stat.size); std::vector<u8> buf(stat.size);
if (zip_fread(file.get(), buf.data(), buf.size()) != buf.size()) if (zip_fread(file2.get(), buf.data(), buf.size()) != s64(buf.size()))
return nullptr; return nullptr;
const auto parts = FileUtil::SplitPathComponents(stat.name); const auto parts = FileUtil::SplitPathComponents(stat.name);

@ -25,7 +25,7 @@ FramebufferLayout DefaultFrameLayout(u32 width, u32 height) {
ASSERT(height > 0); ASSERT(height > 0);
// The drawing code needs at least somewhat valid values for both screens // The drawing code needs at least somewhat valid values for both screens
// so just calculate them both even if the other isn't showing. // so just calculate them both even if the other isn't showing.
FramebufferLayout res{width, height}; FramebufferLayout res{width, height, false, {}};
const float window_aspect_ratio = static_cast<float>(height) / width; const float window_aspect_ratio = static_cast<float>(height) / width;
const float emulation_aspect_ratio = EmulationAspectRatio( const float emulation_aspect_ratio = EmulationAspectRatio(

@ -284,17 +284,17 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(Thread& thread) {
std::vector<u8> HLERequestContext::ReadBuffer(int buffer_index) const { std::vector<u8> HLERequestContext::ReadBuffer(int buffer_index) const {
std::vector<u8> buffer; std::vector<u8> buffer;
const bool is_buffer_a{BufferDescriptorA().size() > buffer_index && const bool is_buffer_a{BufferDescriptorA().size() > std::size_t(buffer_index) &&
BufferDescriptorA()[buffer_index].Size()}; BufferDescriptorA()[buffer_index].Size()};
auto& memory = Core::System::GetInstance().Memory(); auto& memory = Core::System::GetInstance().Memory();
if (is_buffer_a) { if (is_buffer_a) {
ASSERT_MSG(BufferDescriptorA().size() > buffer_index, ASSERT_MSG(BufferDescriptorA().size() > std::size_t(buffer_index),
"BufferDescriptorA invalid buffer_index {}", buffer_index); "BufferDescriptorA invalid buffer_index {}", buffer_index);
buffer.resize(BufferDescriptorA()[buffer_index].Size()); buffer.resize(BufferDescriptorA()[buffer_index].Size());
memory.ReadBlock(BufferDescriptorA()[buffer_index].Address(), buffer.data(), buffer.size()); memory.ReadBlock(BufferDescriptorA()[buffer_index].Address(), buffer.data(), buffer.size());
} else { } else {
ASSERT_MSG(BufferDescriptorX().size() > buffer_index, ASSERT_MSG(BufferDescriptorX().size() > std::size_t(buffer_index),
"BufferDescriptorX invalid buffer_index {}", buffer_index); "BufferDescriptorX invalid buffer_index {}", buffer_index);
buffer.resize(BufferDescriptorX()[buffer_index].Size()); buffer.resize(BufferDescriptorX()[buffer_index].Size());
memory.ReadBlock(BufferDescriptorX()[buffer_index].Address(), buffer.data(), buffer.size()); memory.ReadBlock(BufferDescriptorX()[buffer_index].Address(), buffer.data(), buffer.size());
@ -310,7 +310,7 @@ std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size,
return 0; return 0;
} }
const bool is_buffer_b{BufferDescriptorB().size() > buffer_index && const bool is_buffer_b{BufferDescriptorB().size() > std::size_t(buffer_index) &&
BufferDescriptorB()[buffer_index].Size()}; BufferDescriptorB()[buffer_index].Size()};
const std::size_t buffer_size{GetWriteBufferSize(buffer_index)}; const std::size_t buffer_size{GetWriteBufferSize(buffer_index)};
if (size > buffer_size) { if (size > buffer_size) {
@ -321,13 +321,13 @@ std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size,
auto& memory = Core::System::GetInstance().Memory(); auto& memory = Core::System::GetInstance().Memory();
if (is_buffer_b) { if (is_buffer_b) {
ASSERT_MSG(BufferDescriptorB().size() > buffer_index, ASSERT_MSG(BufferDescriptorB().size() > std::size_t(buffer_index),
"BufferDescriptorB invalid buffer_index {}", buffer_index); "BufferDescriptorB invalid buffer_index {}", buffer_index);
ASSERT_MSG(BufferDescriptorB()[buffer_index].Size() >= size, ASSERT_MSG(BufferDescriptorB()[buffer_index].Size() >= size,
"BufferDescriptorB buffer_index {} is not large enough", buffer_index); "BufferDescriptorB buffer_index {} is not large enough", buffer_index);
memory.WriteBlock(BufferDescriptorB()[buffer_index].Address(), buffer, size); memory.WriteBlock(BufferDescriptorB()[buffer_index].Address(), buffer, size);
} else { } else {
ASSERT_MSG(BufferDescriptorC().size() > buffer_index, ASSERT_MSG(BufferDescriptorC().size() > std::size_t(buffer_index),
"BufferDescriptorC invalid buffer_index {}", buffer_index); "BufferDescriptorC invalid buffer_index {}", buffer_index);
ASSERT_MSG(BufferDescriptorC()[buffer_index].Size() >= size, ASSERT_MSG(BufferDescriptorC()[buffer_index].Size() >= size,
"BufferDescriptorC buffer_index {} is not large enough", buffer_index); "BufferDescriptorC buffer_index {} is not large enough", buffer_index);
@ -338,16 +338,16 @@ std::size_t HLERequestContext::WriteBuffer(const void* buffer, std::size_t size,
} }
std::size_t HLERequestContext::GetReadBufferSize(int buffer_index) const { std::size_t HLERequestContext::GetReadBufferSize(int buffer_index) const {
const bool is_buffer_a{BufferDescriptorA().size() > buffer_index && const bool is_buffer_a{BufferDescriptorA().size() > std::size_t(buffer_index) &&
BufferDescriptorA()[buffer_index].Size()}; BufferDescriptorA()[buffer_index].Size()};
if (is_buffer_a) { if (is_buffer_a) {
ASSERT_MSG(BufferDescriptorA().size() > buffer_index, ASSERT_MSG(BufferDescriptorA().size() > std::size_t(buffer_index),
"BufferDescriptorA invalid buffer_index {}", buffer_index); "BufferDescriptorA invalid buffer_index {}", buffer_index);
ASSERT_MSG(BufferDescriptorA()[buffer_index].Size() > 0, ASSERT_MSG(BufferDescriptorA()[buffer_index].Size() > 0,
"BufferDescriptorA buffer_index {} is empty", buffer_index); "BufferDescriptorA buffer_index {} is empty", buffer_index);
return BufferDescriptorA()[buffer_index].Size(); return BufferDescriptorA()[buffer_index].Size();
} else { } else {
ASSERT_MSG(BufferDescriptorX().size() > buffer_index, ASSERT_MSG(BufferDescriptorX().size() > std::size_t(buffer_index),
"BufferDescriptorX invalid buffer_index {}", buffer_index); "BufferDescriptorX invalid buffer_index {}", buffer_index);
ASSERT_MSG(BufferDescriptorX()[buffer_index].Size() > 0, ASSERT_MSG(BufferDescriptorX()[buffer_index].Size() > 0,
"BufferDescriptorX buffer_index {} is empty", buffer_index); "BufferDescriptorX buffer_index {} is empty", buffer_index);
@ -356,14 +356,14 @@ std::size_t HLERequestContext::GetReadBufferSize(int buffer_index) const {
} }
std::size_t HLERequestContext::GetWriteBufferSize(int buffer_index) const { std::size_t HLERequestContext::GetWriteBufferSize(int buffer_index) const {
const bool is_buffer_b{BufferDescriptorB().size() > buffer_index && const bool is_buffer_b{BufferDescriptorB().size() > std::size_t(buffer_index) &&
BufferDescriptorB()[buffer_index].Size()}; BufferDescriptorB()[buffer_index].Size()};
if (is_buffer_b) { if (is_buffer_b) {
ASSERT_MSG(BufferDescriptorB().size() > buffer_index, ASSERT_MSG(BufferDescriptorB().size() > std::size_t(buffer_index),
"BufferDescriptorB invalid buffer_index {}", buffer_index); "BufferDescriptorB invalid buffer_index {}", buffer_index);
return BufferDescriptorB()[buffer_index].Size(); return BufferDescriptorB()[buffer_index].Size();
} else { } else {
ASSERT_MSG(BufferDescriptorC().size() > buffer_index, ASSERT_MSG(BufferDescriptorC().size() > std::size_t(buffer_index),
"BufferDescriptorC invalid buffer_index {}", buffer_index); "BufferDescriptorC invalid buffer_index {}", buffer_index);
return BufferDescriptorC()[buffer_index].Size(); return BufferDescriptorC()[buffer_index].Size();
} }

@ -129,7 +129,7 @@ private:
LOG_DEBUG(Service_Audio, "called. rendering_time_limit_percent={}", LOG_DEBUG(Service_Audio, "called. rendering_time_limit_percent={}",
rendering_time_limit_percent); rendering_time_limit_percent);
ASSERT(rendering_time_limit_percent >= 0 && rendering_time_limit_percent <= 100); ASSERT(rendering_time_limit_percent <= 100);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);

@ -451,7 +451,8 @@ FileSys::SaveDataSize FileSystemController::ReadSaveDataSize(FileSys::SaveDataTy
if (res != Loader::ResultStatus::Success) { if (res != Loader::ResultStatus::Success) {
FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID()}; FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID()};
auto [nacp_unique, discard] = pm.GetControlMetadata(); const auto metadata = pm.GetControlMetadata();
const auto& nacp_unique = metadata.first;
if (nacp_unique != nullptr) { if (nacp_unique != nullptr) {
new_size = {nacp_unique->GetDefaultNormalSaveSize(), new_size = {nacp_unique->GetDefaultNormalSaveSize(),

@ -575,6 +575,7 @@ private:
0, 0,
user_id->GetSize(), user_id->GetSize(),
{}, {},
{},
}); });
continue; continue;
@ -595,6 +596,7 @@ private:
stoull_be(title_id->GetName()), stoull_be(title_id->GetName()),
title_id->GetSize(), title_id->GetSize(),
{}, {},
{},
}); });
} }
} }
@ -619,6 +621,7 @@ private:
stoull_be(title_id->GetName()), stoull_be(title_id->GetName()),
title_id->GetSize(), title_id->GetSize(),
{}, {},
{},
}); });
} }
} }

@ -309,7 +309,7 @@ static bool ParsePosixName(const char* name, TimeZoneRule& rule) {
offset = GetTZName(name, offset); offset = GetTZName(name, offset);
std_len = offset; std_len = offset;
} }
if (!std_len) { if (std_len == 0) {
return {}; return {};
} }
if (!GetOffset(name, offset, std_offset)) { if (!GetOffset(name, offset, std_offset)) {
@ -320,7 +320,7 @@ static bool ParsePosixName(const char* name, TimeZoneRule& rule) {
int dest_len{}; int dest_len{};
int dest_offset{}; int dest_offset{};
const char* dest_name{name + offset}; const char* dest_name{name + offset};
if (rule.chars.size() < char_count) { if (rule.chars.size() < std::size_t(char_count)) {
return {}; return {};
} }
@ -343,7 +343,7 @@ static bool ParsePosixName(const char* name, TimeZoneRule& rule) {
return {}; return {};
} }
char_count += dest_len + 1; char_count += dest_len + 1;
if (rule.chars.size() < char_count) { if (rule.chars.size() < std::size_t(char_count)) {
return {}; return {};
} }
if (name[offset] != '\0' && name[offset] != ',' && name[offset] != ';') { if (name[offset] != '\0' && name[offset] != ',' && name[offset] != ';') {
@ -414,7 +414,7 @@ static bool ParsePosixName(const char* name, TimeZoneRule& rule) {
if (is_reversed || if (is_reversed ||
(start_time < end_time && (start_time < end_time &&
(end_time - start_time < (year_seconds + (std_offset - dest_offset))))) { (end_time - start_time < (year_seconds + (std_offset - dest_offset))))) {
if (rule.ats.size() - 2 < time_count) { if (rule.ats.size() - 2 < std::size_t(time_count)) {
break; break;
} }
@ -609,7 +609,7 @@ static bool ParseTimeZoneBinary(TimeZoneRule& time_zone_rule, FileSys::VirtualFi
} }
const u64 position{(read_offset - sizeof(TzifHeader))}; const u64 position{(read_offset - sizeof(TzifHeader))};
const std::size_t bytes_read{vfs_file->GetSize() - sizeof(TzifHeader) - position}; const s64 bytes_read = s64(vfs_file->GetSize() - sizeof(TzifHeader) - position);
if (bytes_read < 0) { if (bytes_read < 0) {
return {}; return {};
} }
@ -621,11 +621,11 @@ static bool ParseTimeZoneBinary(TimeZoneRule& time_zone_rule, FileSys::VirtualFi
std::array<char, time_zone_name_max + 1> temp_name{}; std::array<char, time_zone_name_max + 1> temp_name{};
vfs_file->ReadArray(temp_name.data(), bytes_read, read_offset); vfs_file->ReadArray(temp_name.data(), bytes_read, read_offset);
if (bytes_read > 2 && temp_name[0] == '\n' && temp_name[bytes_read - 1] == '\n' && if (bytes_read > 2 && temp_name[0] == '\n' && temp_name[bytes_read - 1] == '\n' &&
time_zone_rule.type_count + 2 <= time_zone_rule.ttis.size()) { std::size_t(time_zone_rule.type_count) + 2 <= time_zone_rule.ttis.size()) {
temp_name[bytes_read - 1] = '\0'; temp_name[bytes_read - 1] = '\0';
std::array<char, time_zone_name_max> name{}; std::array<char, time_zone_name_max> name{};
std::memcpy(name.data(), temp_name.data() + 1, bytes_read - 1); std::memcpy(name.data(), temp_name.data() + 1, std::size_t(bytes_read - 1));
TimeZoneRule temp_rule; TimeZoneRule temp_rule;
if (ParsePosixName(name.data(), temp_rule)) { if (ParsePosixName(name.data(), temp_rule)) {

@ -101,8 +101,8 @@ public:
} }
std::u16string ReadInterfaceToken() { std::u16string ReadInterfaceToken() {
u32 unknown = Read<u32_le>(); [[maybe_unused]] const u32 unknown = Read<u32_le>();
u32 length = Read<u32_le>(); const u32 length = Read<u32_le>();
std::u16string token{}; std::u16string token{};

@ -55,7 +55,7 @@ void DmntCheatVm::LogOpcode(const CheatVmOpcode& opcode) {
fmt::format("Cond Type: {:X}", static_cast<u32>(begin_cond->cond_type))); fmt::format("Cond Type: {:X}", static_cast<u32>(begin_cond->cond_type)));
callbacks->CommandLog(fmt::format("Rel Addr: {:X}", begin_cond->rel_address)); callbacks->CommandLog(fmt::format("Rel Addr: {:X}", begin_cond->rel_address));
callbacks->CommandLog(fmt::format("Value: {:X}", begin_cond->value.bit64)); callbacks->CommandLog(fmt::format("Value: {:X}", begin_cond->value.bit64));
} else if (auto end_cond = std::get_if<EndConditionalOpcode>(&opcode.opcode)) { } else if (std::holds_alternative<EndConditionalOpcode>(opcode.opcode)) {
callbacks->CommandLog("Opcode: End Conditional"); callbacks->CommandLog("Opcode: End Conditional");
} else if (auto ctrl_loop = std::get_if<ControlLoopOpcode>(&opcode.opcode)) { } else if (auto ctrl_loop = std::get_if<ControlLoopOpcode>(&opcode.opcode)) {
if (ctrl_loop->start_loop) { if (ctrl_loop->start_loop) {
@ -399,6 +399,7 @@ bool DmntCheatVm::DecodeNextOpcode(CheatVmOpcode& out) {
// 8kkkkkkk // 8kkkkkkk
// Just parse the mask. // Just parse the mask.
begin_keypress_cond.key_mask = first_dword & 0x0FFFFFFF; begin_keypress_cond.key_mask = first_dword & 0x0FFFFFFF;
opcode.opcode = begin_keypress_cond;
} break; } break;
case CheatVmOpcodeType::PerformArithmeticRegister: { case CheatVmOpcodeType::PerformArithmeticRegister: {
PerformArithmeticRegisterOpcode perform_math_reg{}; PerformArithmeticRegisterOpcode perform_math_reg{};
@ -779,7 +780,7 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) {
if (!cond_met) { if (!cond_met) {
SkipConditionalBlock(); SkipConditionalBlock();
} }
} else if (auto end_cond = std::get_if<EndConditionalOpcode>(&cur_opcode.opcode)) { } else if (std::holds_alternative<EndConditionalOpcode>(cur_opcode.opcode)) {
// Decrement the condition depth. // Decrement the condition depth.
// We will assume, graciously, that mismatched conditional block ends are a nop. // We will assume, graciously, that mismatched conditional block ends are a nop.
if (condition_depth > 0) { if (condition_depth > 0) {

@ -153,9 +153,9 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader) {
app_loader.ReadTitle(name); app_loader.ReadTitle(name);
if (name.empty()) { if (name.empty()) {
auto [nacp, icon_file] = FileSys::PatchManager(program_id).GetControlMetadata(); const auto metadata = FileSys::PatchManager(program_id).GetControlMetadata();
if (nacp != nullptr) { if (metadata.first != nullptr) {
name = nacp->GetApplicationName(); name = metadata.first->GetApplicationName();
} }
} }

@ -603,6 +603,7 @@ public:
if (std::abs(event.jaxis.value / 32767.0) < 0.5) { if (std::abs(event.jaxis.value / 32767.0) < 0.5) {
break; break;
} }
[[fallthrough]];
case SDL_JOYBUTTONUP: case SDL_JOYBUTTONUP:
case SDL_JOYHATMOTION: case SDL_JOYHATMOTION:
return SDLEventToButtonParamPackage(state, event); return SDLEventToButtonParamPackage(state, event);

@ -1507,7 +1507,7 @@ union Instruction {
TextureType GetTextureType() const { TextureType GetTextureType() const {
// The TLDS instruction has a weird encoding for the texture type. // The TLDS instruction has a weird encoding for the texture type.
if (texture_info >= 0 && texture_info <= 1) { if (texture_info <= 1) {
return TextureType::Texture1D; return TextureType::Texture1D;
} }
if (texture_info == 2 || texture_info == 8 || texture_info == 12 || if (texture_info == 2 || texture_info == 8 || texture_info == 12 ||

@ -835,7 +835,8 @@ private:
void DeclareConstantBuffers() { void DeclareConstantBuffers() {
u32 binding = device.GetBaseBindings(stage).uniform_buffer; u32 binding = device.GetBaseBindings(stage).uniform_buffer;
for (const auto& [index, cbuf] : ir.GetConstantBuffers()) { for (const auto& buffers : ir.GetConstantBuffers()) {
const auto index = buffers.first;
code.AddLine("layout (std140, binding = {}) uniform {} {{", binding++, code.AddLine("layout (std140, binding = {}) uniform {} {{", binding++,
GetConstBufferBlock(index)); GetConstBufferBlock(index));
code.AddLine(" uvec4 {}[{}];", GetConstBuffer(index), MAX_CONSTBUFFER_ELEMENTS); code.AddLine(" uvec4 {}[{}];", GetConstBuffer(index), MAX_CONSTBUFFER_ELEMENTS);

@ -352,8 +352,10 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) {
registry.ObtainBoundSampler(static_cast<u32>(instr.image.index.Value())); registry.ObtainBoundSampler(static_cast<u32>(instr.image.index.Value()));
} else { } else {
const Node image_register = GetRegister(instr.gpr39); const Node image_register = GetRegister(instr.gpr39);
const auto [base_image, buffer, offset] = TrackCbuf( const auto result = TrackCbuf(image_register, global_code,
image_register, global_code, static_cast<s64>(global_code.size())); static_cast<s64>(global_code.size()));
const auto buffer = std::get<1>(result);
const auto offset = std::get<2>(result);
descriptor = registry.ObtainBindlessSampler(buffer, offset); descriptor = registry.ObtainBindlessSampler(buffer, offset);
} }
if (!descriptor) { if (!descriptor) {
@ -497,9 +499,12 @@ Image& ShaderIR::GetImage(Tegra::Shader::Image image, Tegra::Shader::ImageType t
Image& ShaderIR::GetBindlessImage(Tegra::Shader::Register reg, Tegra::Shader::ImageType type) { Image& ShaderIR::GetBindlessImage(Tegra::Shader::Register reg, Tegra::Shader::ImageType type) {
const Node image_register = GetRegister(reg); const Node image_register = GetRegister(reg);
const auto [base_image, buffer, offset] = const auto result =
TrackCbuf(image_register, global_code, static_cast<s64>(global_code.size())); TrackCbuf(image_register, global_code, static_cast<s64>(global_code.size()));
const auto buffer = std::get<1>(result);
const auto offset = std::get<2>(result);
const auto it = const auto it =
std::find_if(std::begin(used_images), std::end(used_images), std::find_if(std::begin(used_images), std::end(used_images),
[buffer = buffer, offset = offset](const Image& entry) { [buffer = buffer, offset = offset](const Image& entry) {

@ -56,8 +56,7 @@ Node ShaderIR::GetConstBuffer(u64 index_, u64 offset_) {
const auto index = static_cast<u32>(index_); const auto index = static_cast<u32>(index_);
const auto offset = static_cast<u32>(offset_); const auto offset = static_cast<u32>(offset_);
const auto [entry, is_new] = used_cbufs.try_emplace(index); used_cbufs.try_emplace(index).first->second.MarkAsUsed(offset);
entry->second.MarkAsUsed(offset);
return MakeNode<CbufNode>(index, Immediate(offset)); return MakeNode<CbufNode>(index, Immediate(offset));
} }
@ -66,8 +65,7 @@ Node ShaderIR::GetConstBufferIndirect(u64 index_, u64 offset_, Node node) {
const auto index = static_cast<u32>(index_); const auto index = static_cast<u32>(index_);
const auto offset = static_cast<u32>(offset_); const auto offset = static_cast<u32>(offset_);
const auto [entry, is_new] = used_cbufs.try_emplace(index); used_cbufs.try_emplace(index).first->second.MarkAsUsedIndirect();
entry->second.MarkAsUsedIndirect();
Node final_offset = [&] { Node final_offset = [&] {
// Attempt to inline constant buffer without a variable offset. This is done to allow // Attempt to inline constant buffer without a variable offset. This is done to allow
@ -166,6 +164,7 @@ Node ShaderIR::ConvertIntegerSize(Node value, Register::Size size, bool is_signe
std::move(value), Immediate(16)); std::move(value), Immediate(16));
value = SignedOperation(OperationCode::IArithmeticShiftRight, is_signed, NO_PRECISE, value = SignedOperation(OperationCode::IArithmeticShiftRight, is_signed, NO_PRECISE,
std::move(value), Immediate(16)); std::move(value), Immediate(16));
return value;
case Register::Size::Word: case Register::Size::Word:
// Default - do nothing // Default - do nothing
return value; return value;

@ -27,8 +27,9 @@ std::pair<Node, s64> FindOperation(const NodeBlock& code, s64 cursor,
if (const auto conditional = std::get_if<ConditionalNode>(&*node)) { if (const auto conditional = std::get_if<ConditionalNode>(&*node)) {
const auto& conditional_code = conditional->GetCode(); const auto& conditional_code = conditional->GetCode();
auto [found, internal_cursor] = FindOperation( auto result = FindOperation(
conditional_code, static_cast<s64>(conditional_code.size() - 1), operation_code); conditional_code, static_cast<s64>(conditional_code.size() - 1), operation_code);
auto& found = result.first;
if (found) { if (found) {
return {std::move(found), cursor}; return {std::move(found), cursor};
} }
@ -186,8 +187,8 @@ std::tuple<Node, u32, u32> ShaderIR::TrackCbuf(Node tracked, const NodeBlock& co
std::optional<u32> ShaderIR::TrackImmediate(Node tracked, const NodeBlock& code, s64 cursor) const { std::optional<u32> ShaderIR::TrackImmediate(Node tracked, const NodeBlock& code, s64 cursor) const {
// Reduce the cursor in one to avoid infinite loops when the instruction sets the same register // Reduce the cursor in one to avoid infinite loops when the instruction sets the same register
// that it uses as operand // that it uses as operand
const auto [found, found_cursor] = const auto result = TrackRegister(&std::get<GprNode>(*tracked), code, cursor - 1);
TrackRegister(&std::get<GprNode>(*tracked), code, cursor - 1); const auto& found = result.first;
if (!found) { if (!found) {
return {}; return {};
} }

@ -167,7 +167,6 @@ SurfaceParams SurfaceParams::CreateForImage(const FormatLookupTable& lookup_tabl
SurfaceParams SurfaceParams::CreateForDepthBuffer(Core::System& system) { SurfaceParams SurfaceParams::CreateForDepthBuffer(Core::System& system) {
const auto& regs = system.GPU().Maxwell3D().regs; const auto& regs = system.GPU().Maxwell3D().regs;
regs.zeta_width, regs.zeta_height, regs.zeta.format, regs.zeta.memory_layout.type;
SurfaceParams params; SurfaceParams params;
params.is_tiled = regs.zeta.memory_layout.type == params.is_tiled = regs.zeta.memory_layout.type ==
Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear; Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear;

@ -647,7 +647,8 @@ private:
break; break;
} }
const u32 offset = static_cast<u32>(surface->GetCpuAddr() - cpu_addr); const u32 offset = static_cast<u32>(surface->GetCpuAddr() - cpu_addr);
const auto [x, y, z] = params.GetBlockOffsetXYZ(offset); const auto offsets = params.GetBlockOffsetXYZ(offset);
const auto z = std::get<2>(offsets);
modified |= surface->IsModified(); modified |= surface->IsModified();
const CopyParams copy_params(0, 0, 0, 0, 0, z, 0, 0, params.width, params.height, const CopyParams copy_params(0, 0, 0, 0, 0, z, 0, 0, params.width, params.height,
1); 1);

@ -43,7 +43,7 @@ struct Client::Impl {
if (jwt.empty() && !allow_anonymous) { if (jwt.empty() && !allow_anonymous) {
LOG_ERROR(WebService, "Credentials must be provided for authenticated requests"); LOG_ERROR(WebService, "Credentials must be provided for authenticated requests");
return Common::WebResult{Common::WebResult::Code::CredentialsMissing, return Common::WebResult{Common::WebResult::Code::CredentialsMissing,
"Credentials needed"}; "Credentials needed", ""};
} }
auto result = GenericRequest(method, path, data, accept, jwt); auto result = GenericRequest(method, path, data, accept, jwt);
@ -81,12 +81,12 @@ struct Client::Impl {
cli = std::make_unique<httplib::SSLClient>(parsedUrl.m_Host.c_str(), port); cli = std::make_unique<httplib::SSLClient>(parsedUrl.m_Host.c_str(), port);
} else { } else {
LOG_ERROR(WebService, "Bad URL scheme {}", parsedUrl.m_Scheme); LOG_ERROR(WebService, "Bad URL scheme {}", parsedUrl.m_Scheme);
return Common::WebResult{Common::WebResult::Code::InvalidURL, "Bad URL scheme"}; return Common::WebResult{Common::WebResult::Code::InvalidURL, "Bad URL scheme", ""};
} }
} }
if (cli == nullptr) { if (cli == nullptr) {
LOG_ERROR(WebService, "Invalid URL {}", host + path); LOG_ERROR(WebService, "Invalid URL {}", host + path);
return Common::WebResult{Common::WebResult::Code::InvalidURL, "Invalid URL"}; return Common::WebResult{Common::WebResult::Code::InvalidURL, "Invalid URL", ""};
} }
cli->set_timeout_sec(TIMEOUT_SECONDS); cli->set_timeout_sec(TIMEOUT_SECONDS);
@ -118,27 +118,27 @@ struct Client::Impl {
if (!cli->send(request, response)) { if (!cli->send(request, response)) {
LOG_ERROR(WebService, "{} to {} returned null", method, host + path); LOG_ERROR(WebService, "{} to {} returned null", method, host + path);
return Common::WebResult{Common::WebResult::Code::LibError, "Null response"}; return Common::WebResult{Common::WebResult::Code::LibError, "Null response", ""};
} }
if (response.status >= 400) { if (response.status >= 400) {
LOG_ERROR(WebService, "{} to {} returned error status code: {}", method, host + path, LOG_ERROR(WebService, "{} to {} returned error status code: {}", method, host + path,
response.status); response.status);
return Common::WebResult{Common::WebResult::Code::HttpError, return Common::WebResult{Common::WebResult::Code::HttpError,
std::to_string(response.status)}; std::to_string(response.status), ""};
} }
auto content_type = response.headers.find("content-type"); auto content_type = response.headers.find("content-type");
if (content_type == response.headers.end()) { if (content_type == response.headers.end()) {
LOG_ERROR(WebService, "{} to {} returned no content", method, host + path); LOG_ERROR(WebService, "{} to {} returned no content", method, host + path);
return Common::WebResult{Common::WebResult::Code::WrongContent, ""}; return Common::WebResult{Common::WebResult::Code::WrongContent, "", ""};
} }
if (content_type->second.find(accept) == std::string::npos) { if (content_type->second.find(accept) == std::string::npos) {
LOG_ERROR(WebService, "{} to {} returned wrong content: {}", method, host + path, LOG_ERROR(WebService, "{} to {} returned wrong content: {}", method, host + path,
content_type->second); content_type->second);
return Common::WebResult{Common::WebResult::Code::WrongContent, "Wrong content"}; return Common::WebResult{Common::WebResult::Code::WrongContent, "Wrong content", ""};
} }
return Common::WebResult{Common::WebResult::Code::Success, "", response.body}; return Common::WebResult{Common::WebResult::Code::Success, "", response.body};
} }

@ -51,7 +51,8 @@ MicroProfileDialog::MicroProfileDialog(QWidget* parent) : QWidget(parent, Qt::Di
setWindowTitle(tr("MicroProfile")); setWindowTitle(tr("MicroProfile"));
resize(1000, 600); resize(1000, 600);
// Remove the "?" button from the titlebar and enable the maximize button // Remove the "?" button from the titlebar and enable the maximize button
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint | Qt::WindowMaximizeButtonHint); setWindowFlags((windowFlags() & ~Qt::WindowContextHelpButtonHint) |
Qt::WindowMaximizeButtonHint);
#if MICROPROFILE_ENABLED #if MICROPROFILE_ENABLED

@ -91,7 +91,8 @@ std::pair<std::vector<u8>, std::string> GetGameListCachedObject(
return generator(); return generator();
} }
if (file1.write(reinterpret_cast<const char*>(icon.data()), icon.size()) != icon.size()) { if (file1.write(reinterpret_cast<const char*>(icon.data()), icon.size()) !=
s64(icon.size())) {
LOG_ERROR(Frontend, "Failed to write data to cache file."); LOG_ERROR(Frontend, "Failed to write data to cache file.");
return generator(); return generator();
} }

@ -1019,9 +1019,9 @@ void GMainWindow::BootGame(const QString& filename) {
std::string title_name; std::string title_name;
const auto res = Core::System::GetInstance().GetGameName(title_name); const auto res = Core::System::GetInstance().GetGameName(title_name);
if (res != Loader::ResultStatus::Success) { if (res != Loader::ResultStatus::Success) {
const auto [nacp, icon_file] = FileSys::PatchManager(title_id).GetControlMetadata(); const auto metadata = FileSys::PatchManager(title_id).GetControlMetadata();
if (nacp != nullptr) if (metadata.first != nullptr)
title_name = nacp->GetApplicationName(); title_name = metadata.first->GetApplicationName();
if (title_name.empty()) if (title_name.empty())
title_name = FileUtil::GetFilename(filename.toStdString()); title_name = FileUtil::GetFilename(filename.toStdString());
@ -1628,7 +1628,7 @@ void GMainWindow::OnMenuInstallToNAND() {
} }
FileSys::InstallResult res; FileSys::InstallResult res;
if (index >= static_cast<size_t>(FileSys::TitleType::Application)) { if (index >= static_cast<s32>(FileSys::TitleType::Application)) {
res = Core::System::GetInstance() res = Core::System::GetInstance()
.GetFileSystemController() .GetFileSystemController()
.GetUserNANDContents() .GetUserNANDContents()