summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/CMakeLists.txt13
-rw-r--r--src/common/bit_field.h11
-rw-r--r--src/common/common_funcs.h22
-rw-r--r--src/core/file_sys/content_archive.cpp39
-rw-r--r--src/core/file_sys/romfs.h19
-rw-r--r--src/core/hle/ipc.h6
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp3
-rw-r--r--src/core/hle/kernel/object.h5
-rw-r--r--src/core/hle/kernel/readable_event.cpp10
-rw-r--r--src/core/hle/kernel/readable_event.h7
-rw-r--r--src/core/hle/kernel/svc.cpp2
-rw-r--r--src/core/hle/kernel/writable_event.cpp8
-rw-r--r--src/core/hle/kernel/writable_event.h6
-rw-r--r--src/core/hle/service/am/am.cpp47
-rw-r--r--src/core/hle/service/am/am.h3
-rw-r--r--src/core/hle/service/am/applets/applets.cpp10
-rw-r--r--src/core/hle/service/am/applets/error.cpp11
-rw-r--r--src/core/hle/service/aoc/aoc_u.cpp4
-rw-r--r--src/core/hle/service/audio/audout_u.cpp4
-rw-r--r--src/core/hle/service/audio/audren_u.cpp12
-rw-r--r--src/core/hle/service/bcat/backend/backend.cpp3
-rw-r--r--src/core/hle/service/btdrv/btdrv.cpp3
-rw-r--r--src/core/hle/service/btm/btm.cpp14
-rw-r--r--src/core/hle/service/friend/friend.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp2
-rw-r--r--src/core/hle/service/hid/hid.cpp204
-rw-r--r--src/core/hle/service/hid/hid.h14
-rw-r--r--src/core/hle/service/nfp/nfp.cpp10
-rw-r--r--src/core/hle/service/nifm/nifm.cpp6
-rw-r--r--src/core/hle/service/nim/nim.cpp3
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.cpp3
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.cpp3
-rw-r--r--src/core/hle/service/vi/display/vi_display.cpp4
-rw-r--r--src/core/hle/service/vi/vi.cpp2
-rw-r--r--src/video_core/engines/fermi_2d.cpp30
-rw-r--r--src/video_core/engines/fermi_2d.h12
-rw-r--r--src/video_core/engines/kepler_compute.h18
-rw-r--r--src/video_core/engines/kepler_memory.h4
-rw-r--r--src/video_core/engines/maxwell_3d.h116
-rw-r--r--src/video_core/engines/maxwell_dma.h10
-rw-r--r--src/video_core/engines/shader_header.h50
-rw-r--r--src/video_core/gpu.h8
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp19
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp12
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.h3
-rw-r--r--src/video_core/shader/decode/image.cpp50
-rw-r--r--src/video_core/shader/decode/texture.cpp59
-rw-r--r--src/video_core/shader/node.h101
-rw-r--r--src/video_core/shader/shader_ir.h12
-rw-r--r--src/video_core/textures/texture.h2
-rw-r--r--src/yuzu/debugger/wait_tree.cpp21
-rw-r--r--src/yuzu/debugger/wait_tree.h4
-rw-r--r--src/yuzu/main.cpp21
-rw-r--r--src/yuzu/main.h1
54 files changed, 541 insertions, 527 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 9c6f1c07c..9b0c3db68 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -3,17 +3,8 @@
# could affect the result, but much more unlikely than the following files. Keeping a list of files
# like this allows for much better caching since it doesn't force the user to recompile binary shaders every update
set(VIDEO_CORE "${CMAKE_SOURCE_DIR}/src/video_core")
-if (DEFINED ENV{CI})
- if (DEFINED ENV{TRAVIS})
- set(BUILD_REPOSITORY $ENV{TRAVIS_REPO_SLUG})
- set(BUILD_TAG $ENV{TRAVIS_TAG})
- elseif(DEFINED ENV{APPVEYOR})
- set(BUILD_REPOSITORY $ENV{APPVEYOR_REPO_NAME})
- set(BUILD_TAG $ENV{APPVEYOR_REPO_TAG_NAME})
- elseif(DEFINED ENV{AZURE})
- set(BUILD_REPOSITORY $ENV{AZURE_REPO_NAME})
- set(BUILD_TAG $ENV{AZURE_REPO_TAG})
- endif()
+if (DEFINED ENV{AZURECIREPO})
+ set(BUILD_REPOSITORY $ENV{AZURECIREPO})
endif()
if (DEFINED ENV{TITLEBARFORMATIDLE})
set(TITLE_BAR_FORMAT_IDLE $ENV{TITLEBARFORMATIDLE})
diff --git a/src/common/bit_field.h b/src/common/bit_field.h
index 902e668e3..fd2bbbd99 100644
--- a/src/common/bit_field.h
+++ b/src/common/bit_field.h
@@ -36,6 +36,13 @@
#include "common/common_funcs.h"
#include "common/swap.h"
+// Inlining
+#ifdef _WIN32
+#define FORCE_INLINE __forceinline
+#else
+#define FORCE_INLINE inline __attribute__((always_inline))
+#endif
+
/*
* Abstract bitfield class
*
@@ -168,11 +175,11 @@ public:
constexpr BitField(BitField&&) noexcept = default;
constexpr BitField& operator=(BitField&&) noexcept = default;
- constexpr FORCE_INLINE operator T() const {
+ constexpr operator T() const {
return Value();
}
- constexpr FORCE_INLINE void Assign(const T& value) {
+ constexpr void Assign(const T& value) {
storage = (static_cast<StorageType>(storage) & ~mask) | FormatValue(value);
}
diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h
index 04ecac959..c029dc7b3 100644
--- a/src/common/common_funcs.h
+++ b/src/common/common_funcs.h
@@ -1,10 +1,11 @@
-// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project
+// Copyright 2019 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <algorithm>
+#include <array>
#include <string>
#if !defined(ARCHITECTURE_x86_64)
@@ -16,18 +17,15 @@
#define CONCAT2(x, y) DO_CONCAT2(x, y)
#define DO_CONCAT2(x, y) x##y
-// helper macro to properly align structure members.
-// Calling INSERT_PADDING_BYTES will add a new member variable with a name like "pad121",
-// depending on the current source line to make sure variable names are unique.
-#define INSERT_PADDING_BYTES(num_bytes) u8 CONCAT2(pad, __LINE__)[(num_bytes)]
-#define INSERT_PADDING_WORDS(num_words) u32 CONCAT2(pad, __LINE__)[(num_words)]
+/// Helper macros to insert unused bytes or words to properly align structs. These values will be
+/// zero-initialized.
+#define INSERT_PADDING_BYTES(num_bytes) std::array<u8, num_bytes> CONCAT2(pad, __LINE__){};
+#define INSERT_PADDING_WORDS(num_words) std::array<u32, num_words> CONCAT2(pad, __LINE__){};
-// Inlining
-#ifdef _WIN32
-#define FORCE_INLINE __forceinline
-#else
-#define FORCE_INLINE inline __attribute__((always_inline))
-#endif
+/// These are similar to the INSERT_PADDING_* macros, but are needed for padding unions. This is
+/// because unions can only be initialized by one member.
+#define INSERT_UNION_PADDING_BYTES(num_bytes) std::array<u8, num_bytes> CONCAT2(pad, __LINE__);
+#define INSERT_UNION_PADDING_WORDS(num_words) std::array<u32, num_words> CONCAT2(pad, __LINE__);
#ifndef _MSC_VER
diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp
index ea5c92f61..b8bbdd1ef 100644
--- a/src/core/file_sys/content_archive.cpp
+++ b/src/core/file_sys/content_archive.cpp
@@ -32,11 +32,28 @@ enum class NCASectionFilesystemType : u8 {
ROMFS = 0x3,
};
+struct IVFCLevel {
+ u64_le offset;
+ u64_le size;
+ u32_le block_size;
+ u32_le reserved;
+};
+static_assert(sizeof(IVFCLevel) == 0x18, "IVFCLevel has incorrect size.");
+
+struct IVFCHeader {
+ u32_le magic;
+ u32_le magic_number;
+ INSERT_UNION_PADDING_BYTES(8);
+ std::array<IVFCLevel, 6> levels;
+ INSERT_UNION_PADDING_BYTES(64);
+};
+static_assert(sizeof(IVFCHeader) == 0xE0, "IVFCHeader has incorrect size.");
+
struct NCASectionHeaderBlock {
- INSERT_PADDING_BYTES(3);
+ INSERT_UNION_PADDING_BYTES(3);
NCASectionFilesystemType filesystem_type;
NCASectionCryptoType crypto_type;
- INSERT_PADDING_BYTES(3);
+ INSERT_UNION_PADDING_BYTES(3);
};
static_assert(sizeof(NCASectionHeaderBlock) == 0x8, "NCASectionHeaderBlock has incorrect size.");
@@ -44,7 +61,7 @@ struct NCASectionRaw {
NCASectionHeaderBlock header;
std::array<u8, 0x138> block_data;
std::array<u8, 0x8> section_ctr;
- INSERT_PADDING_BYTES(0xB8);
+ INSERT_UNION_PADDING_BYTES(0xB8);
};
static_assert(sizeof(NCASectionRaw) == 0x200, "NCASectionRaw has incorrect size.");
@@ -52,19 +69,19 @@ struct PFS0Superblock {
NCASectionHeaderBlock header_block;
std::array<u8, 0x20> hash;
u32_le size;
- INSERT_PADDING_BYTES(4);
+ INSERT_UNION_PADDING_BYTES(4);
u64_le hash_table_offset;
u64_le hash_table_size;
u64_le pfs0_header_offset;
u64_le pfs0_size;
- INSERT_PADDING_BYTES(0x1B0);
+ INSERT_UNION_PADDING_BYTES(0x1B0);
};
static_assert(sizeof(PFS0Superblock) == 0x200, "PFS0Superblock has incorrect size.");
struct RomFSSuperblock {
NCASectionHeaderBlock header_block;
IVFCHeader ivfc;
- INSERT_PADDING_BYTES(0x118);
+ INSERT_UNION_PADDING_BYTES(0x118);
};
static_assert(sizeof(RomFSSuperblock) == 0x200, "RomFSSuperblock has incorrect size.");
@@ -72,24 +89,24 @@ struct BKTRHeader {
u64_le offset;
u64_le size;
u32_le magic;
- INSERT_PADDING_BYTES(0x4);
+ INSERT_UNION_PADDING_BYTES(0x4);
u32_le number_entries;
- INSERT_PADDING_BYTES(0x4);
+ INSERT_UNION_PADDING_BYTES(0x4);
};
static_assert(sizeof(BKTRHeader) == 0x20, "BKTRHeader has incorrect size.");
struct BKTRSuperblock {
NCASectionHeaderBlock header_block;
IVFCHeader ivfc;
- INSERT_PADDING_BYTES(0x18);
+ INSERT_UNION_PADDING_BYTES(0x18);
BKTRHeader relocation;
BKTRHeader subsection;
- INSERT_PADDING_BYTES(0xC0);
+ INSERT_UNION_PADDING_BYTES(0xC0);
};
static_assert(sizeof(BKTRSuperblock) == 0x200, "BKTRSuperblock has incorrect size.");
union NCASectionHeader {
- NCASectionRaw raw;
+ NCASectionRaw raw{};
PFS0Superblock pfs0;
RomFSSuperblock romfs;
BKTRSuperblock bktr;
diff --git a/src/core/file_sys/romfs.h b/src/core/file_sys/romfs.h
index 0f35639bc..1c89be8a4 100644
--- a/src/core/file_sys/romfs.h
+++ b/src/core/file_sys/romfs.h
@@ -13,25 +13,6 @@
namespace FileSys {
-struct RomFSHeader;
-
-struct IVFCLevel {
- u64_le offset;
- u64_le size;
- u32_le block_size;
- u32_le reserved;
-};
-static_assert(sizeof(IVFCLevel) == 0x18, "IVFCLevel has incorrect size.");
-
-struct IVFCHeader {
- u32_le magic;
- u32_le magic_number;
- INSERT_PADDING_BYTES(8);
- std::array<IVFCLevel, 6> levels;
- INSERT_PADDING_BYTES(64);
-};
-static_assert(sizeof(IVFCHeader) == 0xE0, "IVFCHeader has incorrect size.");
-
enum class RomFSExtractionType {
Full, // Includes data directory
Truncated, // Traverses into data directory
diff --git a/src/core/hle/ipc.h b/src/core/hle/ipc.h
index fae54bcc7..7ce313190 100644
--- a/src/core/hle/ipc.h
+++ b/src/core/hle/ipc.h
@@ -160,7 +160,7 @@ struct DomainMessageHeader {
// Used when responding to an IPC request, Server -> Client.
struct {
u32_le num_objects;
- INSERT_PADDING_WORDS(3);
+ INSERT_UNION_PADDING_WORDS(3);
};
// Used when performing an IPC request, Client -> Server.
@@ -171,8 +171,10 @@ struct DomainMessageHeader {
BitField<16, 16, u32> size;
};
u32_le object_id;
- INSERT_PADDING_WORDS(2);
+ INSERT_UNION_PADDING_WORDS(2);
};
+
+ std::array<u32, 4> raw{};
};
};
static_assert(sizeof(DomainMessageHeader) == 16, "DomainMessageHeader size is incorrect");
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index f3da525d6..a7b5849b0 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -58,8 +58,7 @@ SharedPtr<WritableEvent> HLERequestContext::SleepClientThread(
auto& kernel = Core::System::GetInstance().Kernel();
if (!writable_event) {
// Create event if not provided
- const auto pair = WritableEvent::CreateEventPair(kernel, ResetType::Automatic,
- "HLE Pause Event: " + reason);
+ const auto pair = WritableEvent::CreateEventPair(kernel, "HLE Pause Event: " + reason);
writable_event = pair.writable;
}
diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h
index 2821176a7..a6faeb83b 100644
--- a/src/core/hle/kernel/object.h
+++ b/src/core/hle/kernel/object.h
@@ -32,11 +32,6 @@ enum class HandleType : u32 {
ServerSession,
};
-enum class ResetType {
- Automatic, ///< Reset automatically on object acquisition
- Manual, ///< Never reset automatically
-};
-
class Object : NonCopyable {
public:
explicit Object(KernelCore& kernel);
diff --git a/src/core/hle/kernel/readable_event.cpp b/src/core/hle/kernel/readable_event.cpp
index 06463cd26..d8ac97aa1 100644
--- a/src/core/hle/kernel/readable_event.cpp
+++ b/src/core/hle/kernel/readable_event.cpp
@@ -20,15 +20,13 @@ bool ReadableEvent::ShouldWait(const Thread* thread) const {
void ReadableEvent::Acquire(Thread* thread) {
ASSERT_MSG(!ShouldWait(thread), "object unavailable!");
-
- if (reset_type == ResetType::Automatic) {
- signaled = false;
- }
}
void ReadableEvent::Signal() {
- signaled = true;
- WakeupAllWaitingThreads();
+ if (!signaled) {
+ signaled = true;
+ WakeupAllWaitingThreads();
+ };
}
void ReadableEvent::Clear() {
diff --git a/src/core/hle/kernel/readable_event.h b/src/core/hle/kernel/readable_event.h
index 84215f572..11ff71c3a 100644
--- a/src/core/hle/kernel/readable_event.h
+++ b/src/core/hle/kernel/readable_event.h
@@ -27,10 +27,6 @@ public:
return name;
}
- ResetType GetResetType() const {
- return reset_type;
- }
-
static constexpr HandleType HANDLE_TYPE = HandleType::ReadableEvent;
HandleType GetHandleType() const override {
return HANDLE_TYPE;
@@ -55,8 +51,7 @@ private:
void Signal();
- ResetType reset_type;
- bool signaled;
+ bool signaled{};
std::string name; ///< Name of event (optional)
};
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index f64236be1..c63a9ba8b 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -2099,7 +2099,7 @@ static ResultCode CreateEvent(Core::System& system, Handle* write_handle, Handle
auto& kernel = system.Kernel();
const auto [readable_event, writable_event] =
- WritableEvent::CreateEventPair(kernel, ResetType::Manual, "CreateEvent");
+ WritableEvent::CreateEventPair(kernel, "CreateEvent");
HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable();
diff --git a/src/core/hle/kernel/writable_event.cpp b/src/core/hle/kernel/writable_event.cpp
index a58ea6ec8..c783a34ee 100644
--- a/src/core/hle/kernel/writable_event.cpp
+++ b/src/core/hle/kernel/writable_event.cpp
@@ -15,8 +15,7 @@ namespace Kernel {
WritableEvent::WritableEvent(KernelCore& kernel) : Object{kernel} {}
WritableEvent::~WritableEvent() = default;
-EventPair WritableEvent::CreateEventPair(KernelCore& kernel, ResetType reset_type,
- std::string name) {
+EventPair WritableEvent::CreateEventPair(KernelCore& kernel, std::string name) {
SharedPtr<WritableEvent> writable_event(new WritableEvent(kernel));
SharedPtr<ReadableEvent> readable_event(new ReadableEvent(kernel));
@@ -24,7 +23,6 @@ EventPair WritableEvent::CreateEventPair(KernelCore& kernel, ResetType reset_typ
writable_event->readable = readable_event;
readable_event->name = name + ":Readable";
readable_event->signaled = false;
- readable_event->reset_type = reset_type;
return {std::move(readable_event), std::move(writable_event)};
}
@@ -33,10 +31,6 @@ SharedPtr<ReadableEvent> WritableEvent::GetReadableEvent() const {
return readable;
}
-ResetType WritableEvent::GetResetType() const {
- return readable->reset_type;
-}
-
void WritableEvent::Signal() {
readable->Signal();
}
diff --git a/src/core/hle/kernel/writable_event.h b/src/core/hle/kernel/writable_event.h
index d00c92a6b..f46cf1dd8 100644
--- a/src/core/hle/kernel/writable_event.h
+++ b/src/core/hle/kernel/writable_event.h
@@ -24,11 +24,9 @@ public:
/**
* Creates an event
* @param kernel The kernel instance to create this event under.
- * @param reset_type ResetType describing how to create event
* @param name Optional name of event
*/
- static EventPair CreateEventPair(KernelCore& kernel, ResetType reset_type,
- std::string name = "Unknown");
+ static EventPair CreateEventPair(KernelCore& kernel, std::string name = "Unknown");
std::string GetTypeName() const override {
return "WritableEvent";
@@ -44,8 +42,6 @@ public:
SharedPtr<ReadableEvent> GetReadableEvent() const;
- ResetType GetResetType() const;
-
void Signal();
void Clear();
bool IsSignaled() const;
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 3a32d5b41..ba54b3040 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -289,8 +289,8 @@ ISelfController::ISelfController(Core::System& system,
RegisterHandlers(functions);
auto& kernel = system.Kernel();
- launchable_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
- "ISelfController:LaunchableEvent");
+ launchable_event =
+ Kernel::WritableEvent::CreateEventPair(kernel, "ISelfController:LaunchableEvent");
// This event is created by AM on the first time GetAccumulatedSuspendedTickChangedEvent() is
// called. Yuzu can just create it unconditionally, since it doesn't need to support multiple
@@ -298,7 +298,7 @@ ISelfController::ISelfController(Core::System& system,
// suspended if the event has previously been created by a call to
// GetAccumulatedSuspendedTickChangedEvent.
accumulated_suspended_tick_changed_event = Kernel::WritableEvent::CreateEventPair(
- kernel, Kernel::ResetType::Manual, "ISelfController:AccumulatedSuspendedTickChangedEvent");
+ kernel, "ISelfController:AccumulatedSuspendedTickChangedEvent");
accumulated_suspended_tick_changed_event.writable->Signal();
}
@@ -523,10 +523,10 @@ void ISelfController::GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequest
}
AppletMessageQueue::AppletMessageQueue(Kernel::KernelCore& kernel) {
- on_new_message = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
- "AMMessageQueue:OnMessageRecieved");
- on_operation_mode_changed = Kernel::WritableEvent::CreateEventPair(
- kernel, Kernel::ResetType::Automatic, "AMMessageQueue:OperationModeChanged");
+ on_new_message =
+ Kernel::WritableEvent::CreateEventPair(kernel, "AMMessageQueue:OnMessageRecieved");
+ on_operation_mode_changed =
+ Kernel::WritableEvent::CreateEventPair(kernel, "AMMessageQueue:OperationModeChanged");
}
AppletMessageQueue::~AppletMessageQueue() = default;
@@ -1073,9 +1073,9 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
{71, nullptr, "RequestToReboot"},
{80, nullptr, "ExitAndRequestToShowThanksMessage"},
{90, &IApplicationFunctions::EnableApplicationCrashReport, "EnableApplicationCrashReport"},
- {100, nullptr, "InitializeApplicationCopyrightFrameBuffer"},
- {101, nullptr, "SetApplicationCopyrightImage"},
- {102, nullptr, "SetApplicationCopyrightVisibility"},
+ {100, &IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer, "InitializeApplicationCopyrightFrameBuffer"},
+ {101, &IApplicationFunctions::SetApplicationCopyrightImage, "SetApplicationCopyrightImage"},
+ {102, &IApplicationFunctions::SetApplicationCopyrightVisibility, "SetApplicationCopyrightVisibility"},
{110, nullptr, "QueryApplicationPlayStatistics"},
{120, nullptr, "ExecuteProgram"},
{121, nullptr, "ClearUserChannel"},
@@ -1091,7 +1091,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
auto& kernel = system.Kernel();
gpu_error_detected_event = Kernel::WritableEvent::CreateEventPair(
- kernel, Kernel::ResetType::Manual, "IApplicationFunctions:GpuErrorDetectedSystemEvent");
+ kernel, "IApplicationFunctions:GpuErrorDetectedSystemEvent");
}
IApplicationFunctions::~IApplicationFunctions() = default;
@@ -1103,6 +1103,31 @@ void IApplicationFunctions::EnableApplicationCrashReport(Kernel::HLERequestConte
rb.Push(RESULT_SUCCESS);
}
+void IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer(
+ Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_AM, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+}
+
+void IApplicationFunctions::SetApplicationCopyrightImage(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_AM, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+}
+
+void IApplicationFunctions::SetApplicationCopyrightVisibility(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto is_visible = rp.Pop<bool>();
+
+ LOG_WARNING(Service_AM, "(STUBBED) called, is_visible={}", is_visible);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+}
+
void IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed(
Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index ccd053c13..2ae9402a8 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -252,6 +252,9 @@ private:
void BeginBlockingHomeButton(Kernel::HLERequestContext& ctx);
void EndBlockingHomeButton(Kernel::HLERequestContext& ctx);
void EnableApplicationCrashReport(Kernel::HLERequestContext& ctx);
+ void InitializeApplicationCopyrightFrameBuffer(Kernel::HLERequestContext& ctx);
+ void SetApplicationCopyrightImage(Kernel::HLERequestContext& ctx);
+ void SetApplicationCopyrightVisibility(Kernel::HLERequestContext& ctx);
void GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx);
bool launch_popped_application_specific = false;
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp
index 720fe766f..673ad1f7f 100644
--- a/src/core/hle/service/am/applets/applets.cpp
+++ b/src/core/hle/service/am/applets/applets.cpp
@@ -24,12 +24,12 @@
namespace Service::AM::Applets {
AppletDataBroker::AppletDataBroker(Kernel::KernelCore& kernel) {
- state_changed_event = Kernel::WritableEvent::CreateEventPair(
- kernel, Kernel::ResetType::Manual, "ILibraryAppletAccessor:StateChangedEvent");
- pop_out_data_event = Kernel::WritableEvent::CreateEventPair(
- kernel, Kernel::ResetType::Manual, "ILibraryAppletAccessor:PopDataOutEvent");
+ state_changed_event =
+ Kernel::WritableEvent::CreateEventPair(kernel, "ILibraryAppletAccessor:StateChangedEvent");
+ pop_out_data_event =
+ Kernel::WritableEvent::CreateEventPair(kernel, "ILibraryAppletAccessor:PopDataOutEvent");
pop_interactive_out_data_event = Kernel::WritableEvent::CreateEventPair(
- kernel, Kernel::ResetType::Manual, "ILibraryAppletAccessor:PopInteractiveDataOutEvent");
+ kernel, "ILibraryAppletAccessor:PopInteractiveDataOutEvent");
}
AppletDataBroker::~AppletDataBroker() = default;
diff --git a/src/core/hle/service/am/applets/error.cpp b/src/core/hle/service/am/applets/error.cpp
index a7db26725..eab0d42c9 100644
--- a/src/core/hle/service/am/applets/error.cpp
+++ b/src/core/hle/service/am/applets/error.cpp
@@ -20,9 +20,9 @@ namespace Service::AM::Applets {
struct ShowError {
u8 mode;
bool jump;
- INSERT_PADDING_BYTES(4);
+ INSERT_UNION_PADDING_BYTES(4);
bool use_64bit_error_code;
- INSERT_PADDING_BYTES(1);
+ INSERT_UNION_PADDING_BYTES(1);
u64 error_code_64;
u32 error_code_32;
};
@@ -32,7 +32,7 @@ static_assert(sizeof(ShowError) == 0x14, "ShowError has incorrect size.");
struct ShowErrorRecord {
u8 mode;
bool jump;
- INSERT_PADDING_BYTES(6);
+ INSERT_UNION_PADDING_BYTES(6);
u64 error_code_64;
u64 posix_time;
};
@@ -41,7 +41,7 @@ static_assert(sizeof(ShowErrorRecord) == 0x18, "ShowErrorRecord has incorrect si
struct SystemErrorArg {
u8 mode;
bool jump;
- INSERT_PADDING_BYTES(6);
+ INSERT_UNION_PADDING_BYTES(6);
u64 error_code_64;
std::array<char, 8> language_code;
std::array<char, 0x800> main_text;
@@ -52,7 +52,7 @@ static_assert(sizeof(SystemErrorArg) == 0x1018, "SystemErrorArg has incorrect si
struct ApplicationErrorArg {
u8 mode;
bool jump;
- INSERT_PADDING_BYTES(6);
+ INSERT_UNION_PADDING_BYTES(6);
u32 error_code;
std::array<char, 8> language_code;
std::array<char, 0x800> main_text;
@@ -65,6 +65,7 @@ union Error::ErrorArguments {
ShowErrorRecord error_record;
SystemErrorArg system_error;
ApplicationErrorArg application_error;
+ std::array<u8, 0x1018> raw{};
};
namespace {
diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp
index e9cf1e840..f36ccbc49 100644
--- a/src/core/hle/service/aoc/aoc_u.cpp
+++ b/src/core/hle/service/aoc/aoc_u.cpp
@@ -67,8 +67,8 @@ AOC_U::AOC_U(Core::System& system)
RegisterHandlers(functions);
auto& kernel = system.Kernel();
- aoc_change_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
- "GetAddOnContentListChanged:Event");
+ aoc_change_event =
+ Kernel::WritableEvent::CreateEventPair(kernel, "GetAddOnContentListChanged:Event");
}
AOC_U::~AOC_U() = default;
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index 9afefb5c6..6a29377e3 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -65,8 +65,8 @@ public:
RegisterHandlers(functions);
// This is the event handle used to check if the audio buffer was released
- buffer_event = Kernel::WritableEvent::CreateEventPair(
- system.Kernel(), Kernel::ResetType::Manual, "IAudioOutBufferReleased");
+ buffer_event =
+ Kernel::WritableEvent::CreateEventPair(system.Kernel(), "IAudioOutBufferReleased");
stream = audio_core.OpenStream(system.CoreTiming(), audio_params.sample_rate,
audio_params.channel_count, std::move(unique_name),
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index f162249ed..4ea7ade6e 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -47,8 +47,8 @@ public:
// clang-format on
RegisterHandlers(functions);
- system_event = Kernel::WritableEvent::CreateEventPair(
- system.Kernel(), Kernel::ResetType::Manual, "IAudioRenderer:SystemEvent");
+ system_event =
+ Kernel::WritableEvent::CreateEventPair(system.Kernel(), "IAudioRenderer:SystemEvent");
renderer = std::make_unique<AudioCore::AudioRenderer>(
system.CoreTiming(), audren_params, system_event.writable, instance_number);
}
@@ -180,17 +180,17 @@ public:
RegisterHandlers(functions);
auto& kernel = system.Kernel();
- buffer_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
- "IAudioOutBufferReleasedEvent");
+ buffer_event =
+ Kernel::WritableEvent::CreateEventPair(kernel, "IAudioOutBufferReleasedEvent");
// Should be similar to audio_output_device_switch_event
audio_input_device_switch_event = Kernel::WritableEvent::CreateEventPair(
- kernel, Kernel::ResetType::Automatic, "IAudioDevice:AudioInputDeviceSwitchedEvent");
+ kernel, "IAudioDevice:AudioInputDeviceSwitchedEvent");
// Should only be signalled when an audio output device has been changed, example: speaker
// to headset
audio_output_device_switch_event = Kernel::WritableEvent::CreateEventPair(
- kernel, Kernel::ResetType::Automatic, "IAudioDevice:AudioOutputDeviceSwitchedEvent");
+ kernel, "IAudioDevice:AudioOutputDeviceSwitchedEvent");
}
private:
diff --git a/src/core/hle/service/bcat/backend/backend.cpp b/src/core/hle/service/bcat/backend/backend.cpp
index b86fda29a..dec0849b8 100644
--- a/src/core/hle/service/bcat/backend/backend.cpp
+++ b/src/core/hle/service/bcat/backend/backend.cpp
@@ -13,8 +13,7 @@ namespace Service::BCAT {
ProgressServiceBackend::ProgressServiceBackend(Kernel::KernelCore& kernel,
std::string_view event_name) {
event = Kernel::WritableEvent::CreateEventPair(
- kernel, Kernel::ResetType::Automatic,
- std::string("ProgressServiceBackend:UpdateEvent:").append(event_name));
+ kernel, std::string("ProgressServiceBackend:UpdateEvent:").append(event_name));
}
Kernel::SharedPtr<Kernel::ReadableEvent> ProgressServiceBackend::GetEvent() const {
diff --git a/src/core/hle/service/btdrv/btdrv.cpp b/src/core/hle/service/btdrv/btdrv.cpp
index afce581e5..4574d9572 100644
--- a/src/core/hle/service/btdrv/btdrv.cpp
+++ b/src/core/hle/service/btdrv/btdrv.cpp
@@ -34,8 +34,7 @@ public:
RegisterHandlers(functions);
auto& kernel = system.Kernel();
- register_event = Kernel::WritableEvent::CreateEventPair(
- kernel, Kernel::ResetType::Automatic, "BT:RegisterEvent");
+ register_event = Kernel::WritableEvent::CreateEventPair(kernel, "BT:RegisterEvent");
}
private:
diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp
index 920fc6ff7..251b3c9df 100644
--- a/src/core/hle/service/btm/btm.cpp
+++ b/src/core/hle/service/btm/btm.cpp
@@ -57,14 +57,12 @@ public:
RegisterHandlers(functions);
auto& kernel = system.Kernel();
- scan_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
- "IBtmUserCore:ScanEvent");
- connection_event = Kernel::WritableEvent::CreateEventPair(
- kernel, Kernel::ResetType::Automatic, "IBtmUserCore:ConnectionEvent");
- service_discovery = Kernel::WritableEvent::CreateEventPair(
- kernel, Kernel::ResetType::Automatic, "IBtmUserCore:Discovery");
- config_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
- "IBtmUserCore:ConfigEvent");
+ scan_event = Kernel::WritableEvent::CreateEventPair(kernel, "IBtmUserCore:ScanEvent");
+ connection_event =
+ Kernel::WritableEvent::CreateEventPair(kernel, "IBtmUserCore:ConnectionEvent");
+ service_discovery =
+ Kernel::WritableEvent::CreateEventPair(kernel, "IBtmUserCore:Discovery");
+ config_event = Kernel::WritableEvent::CreateEventPair(kernel, "IBtmUserCore:ConfigEvent");
}
private:
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp
index 75dd9043b..1a0214f08 100644
--- a/src/core/hle/service/friend/friend.cpp
+++ b/src/core/hle/service/friend/friend.cpp
@@ -162,7 +162,7 @@ public:
RegisterHandlers(functions);
notification_event = Kernel::WritableEvent::CreateEventPair(
- system.Kernel(), Kernel::ResetType::Manual, "INotificationService:NotifyEvent");
+ system.Kernel(), "INotificationService:NotifyEvent");
}
private:
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 81bd2f3cb..79fff517e 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -174,7 +174,7 @@ void Controller_NPad::OnInit() {
auto& kernel = system.Kernel();
for (std::size_t i = 0; i < styleset_changed_events.size(); i++) {
styleset_changed_events[i] = Kernel::WritableEvent::CreateEventPair(
- kernel, Kernel::ResetType::Manual, fmt::format("npad:NpadStyleSetChanged_{}", i));
+ kernel, fmt::format("npad:NpadStyleSetChanged_{}", i));
}
if (!IsControllerActivated()) {
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index ba1da4181..ecc130f6c 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -203,13 +203,13 @@ Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) {
{120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"},
{121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"},
{122, &Hid::SetNpadJoyAssignmentModeSingleByDefault, "SetNpadJoyAssignmentModeSingleByDefault"},
- {123, nullptr, "SetNpadJoyAssignmentModeSingleByDefault"},
+ {123, &Hid::SetNpadJoyAssignmentModeSingle, "SetNpadJoyAssignmentModeSingle"},
{124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"},
{125, &Hid::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"},
{126, &Hid::StartLrAssignmentMode, "StartLrAssignmentMode"},
{127, &Hid::StopLrAssignmentMode, "StopLrAssignmentMode"},
{128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"},
- {129, nullptr, "GetNpadHandheldActivationMode"},
+ {129, &Hid::GetNpadHandheldActivationMode, "GetNpadHandheldActivationMode"},
{130, &Hid::SwapNpadAssignment, "SwapNpadAssignment"},
{131, nullptr, "IsUnintendedHomeButtonInputProtectionEnabled"},
{132, nullptr, "EnableUnintendedHomeButtonInputProtection"},
@@ -557,10 +557,126 @@ void Hid::SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx
LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", npad_id,
applet_resource_user_id);
+ auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
+ controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Single);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+}
+
+void Hid::SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx) {
+ // TODO: Check the differences between this and SetNpadJoyAssignmentModeSingleByDefault
+ IPC::RequestParser rp{ctx};
+ const auto npad_id{rp.Pop<u32>()};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+ const auto npad_joy_device_type{rp.Pop<u64>()};
+
+ LOG_WARNING(Service_HID,
+ "(STUBBED) called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
+ npad_id, applet_resource_user_id, npad_joy_device_type);
+
+ auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
+ controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Single);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+}
+
+void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto npad_id{rp.Pop<u32>()};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", npad_id,
+ applet_resource_user_id);
+
+ auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
+ controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Dual);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+}
+
+void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto unknown_1{rp.Pop<u32>()};
+ const auto unknown_2{rp.Pop<u32>()};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_WARNING(Service_HID,
+ "(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}",
+ unknown_1, unknown_2, applet_resource_user_id);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+}
+
+void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+ auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
+ controller.StartLRAssignmentMode();
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+}
+
+void Hid::StopLrAssignmentMode(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+ auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
+ controller.StopLRAssignmentMode();
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+}
+
+void Hid::SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+ const auto mode{rp.Pop<u64>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, mode={}",
+ applet_resource_user_id, mode);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+}
+
+void Hid::GetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
+ applet_resource_user_id);
+
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
+void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto npad_1{rp.Pop<u32>()};
+ const auto npad_2{rp.Pop<u32>()};
+ const auto applet_resource_user_id{rp.Pop<u64>()};
+
+ LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, npad_1={}, npad_2={}",
+ applet_resource_user_id, npad_1, npad_2);
+
+ auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
+ IPC::ResponseBuilder rb{ctx, 2};
+ if (controller.SwapNpadAssignment(npad_1, npad_2)) {
+ rb.Push(RESULT_SUCCESS);
+ } else {
+ LOG_ERROR(Service_HID, "Npads are not connected!");
+ rb.Push(ERR_NPAD_NOT_CONNECTED);
+ }
+}
+
void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
@@ -635,47 +751,6 @@ void Hid::GetActualVibrationValue(Kernel::HLERequestContext& ctx) {
applet_resource->GetController<Controller_NPad>(HidController::NPad).GetLastVibration());
}
-void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto npad_id{rp.Pop<u32>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", npad_id,
- applet_resource_user_id);
-
- auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
- controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Dual);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
-}
-
-void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto unknown_1{rp.Pop<u32>()};
- const auto unknown_2{rp.Pop<u32>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- LOG_WARNING(Service_HID,
- "(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}",
- unknown_1, unknown_2, applet_resource_user_id);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
-}
-
-void Hid::SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
- const auto mode{rp.Pop<u64>()};
-
- LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, mode={}",
- applet_resource_user_id, mode);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
-}
-
void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called");
@@ -769,49 +844,6 @@ void Hid::SetPalmaBoostMode(Kernel::HLERequestContext& ctx) {
rb.Push(RESULT_SUCCESS);
}
-void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
- auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
- controller.StartLRAssignmentMode();
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
-}
-
-void Hid::StopLrAssignmentMode(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
- auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
- controller.StopLRAssignmentMode();
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
-}
-
-void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto npad_1{rp.Pop<u32>()};
- const auto npad_2{rp.Pop<u32>()};
- const auto applet_resource_user_id{rp.Pop<u64>()};
-
- LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, npad_1={}, npad_2={}",
- applet_resource_user_id, npad_1, npad_2);
-
- auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
- IPC::ResponseBuilder rb{ctx, 2};
- if (controller.SwapNpadAssignment(npad_1, npad_2)) {
- rb.Push(RESULT_SUCCESS);
- } else {
- LOG_ERROR(Service_HID, "Npads are not connected!");
- rb.Push(ERR_NPAD_NOT_CONNECTED);
- }
-}
-
class HidDbg final : public ServiceFramework<HidDbg> {
public:
explicit HidDbg() : ServiceFramework{"hid:dbg"} {
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 01852e019..f08e036a3 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -106,14 +106,19 @@ private:
void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx);
void GetNpadJoyHoldType(Kernel::HLERequestContext& ctx);
void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx);
+ void SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx);
+ void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx);
+ void MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx);
+ void StartLrAssignmentMode(Kernel::HLERequestContext& ctx);
+ void StopLrAssignmentMode(Kernel::HLERequestContext& ctx);
+ void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx);
+ void GetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx);
+ void SwapNpadAssignment(Kernel::HLERequestContext& ctx);
void BeginPermitVibrationSession(Kernel::HLERequestContext& ctx);
void EndPermitVibrationSession(Kernel::HLERequestContext& ctx);
void SendVibrationValue(Kernel::HLERequestContext& ctx);
void SendVibrationValues(Kernel::HLERequestContext& ctx);
void GetActualVibrationValue(Kernel::HLERequestContext& ctx);
- void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx);
- void MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx);
- void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx);
void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx);
void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx);
void PermitVibration(Kernel::HLERequestContext& ctx);
@@ -123,9 +128,6 @@ private:
void StopSixAxisSensor(Kernel::HLERequestContext& ctx);
void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx);
void SetPalmaBoostMode(Kernel::HLERequestContext& ctx);
- void StartLrAssignmentMode(Kernel::HLERequestContext& ctx);
- void StopLrAssignmentMode(Kernel::HLERequestContext& ctx);
- void SwapNpadAssignment(Kernel::HLERequestContext& ctx);
std::shared_ptr<IAppletResource> applet_resource;
Core::System& system;
diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp
index aa886cd3e..795d7b716 100644
--- a/src/core/hle/service/nfp/nfp.cpp
+++ b/src/core/hle/service/nfp/nfp.cpp
@@ -26,8 +26,7 @@ constexpr ResultCode ERR_NO_APPLICATION_AREA(ErrorModule::NFP, 152);
Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& system, const char* name)
: ServiceFramework(name), module(std::move(module)), system(system) {
auto& kernel = system.Kernel();
- nfc_tag_load = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
- "IUser:NFCTagDetected");
+ nfc_tag_load = Kernel::WritableEvent::CreateEventPair(kernel, "IUser:NFCTagDetected");
}
Module::Interface::~Interface() = default;
@@ -66,10 +65,9 @@ public:
RegisterHandlers(functions);
auto& kernel = system.Kernel();
- deactivate_event = Kernel::WritableEvent::CreateEventPair(
- kernel, Kernel::ResetType::Automatic, "IUser:DeactivateEvent");
- availability_change_event = Kernel::WritableEvent::CreateEventPair(
- kernel, Kernel::ResetType::Automatic, "IUser:AvailabilityChangeEvent");
+ deactivate_event = Kernel::WritableEvent::CreateEventPair(kernel, "IUser:DeactivateEvent");
+ availability_change_event =
+ Kernel::WritableEvent::CreateEventPair(kernel, "IUser:AvailabilityChangeEvent");
}
private:
diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp
index 756a2af57..01d557c7a 100644
--- a/src/core/hle/service/nifm/nifm.cpp
+++ b/src/core/hle/service/nifm/nifm.cpp
@@ -69,10 +69,8 @@ public:
RegisterHandlers(functions);
auto& kernel = system.Kernel();
- event1 = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
- "IRequest:Event1");
- event2 = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
- "IRequest:Event2");
+ event1 = Kernel::WritableEvent::CreateEventPair(kernel, "IRequest:Event1");
+ event2 = Kernel::WritableEvent::CreateEventPair(kernel, "IRequest:Event2");
}
private:
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp
index 75d414952..7d6cf2070 100644
--- a/src/core/hle/service/nim/nim.cpp
+++ b/src/core/hle/service/nim/nim.cpp
@@ -141,8 +141,7 @@ public:
auto& kernel = system.Kernel();
finished_event = Kernel::WritableEvent::CreateEventPair(
- kernel, Kernel::ResetType::Automatic,
- "IEnsureNetworkClockAvailabilityService:FinishEvent");
+ kernel, "IEnsureNetworkClockAvailabilityService:FinishEvent");
}
private:
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp
index 7bfb99e34..cc9cd3fd1 100644
--- a/src/core/hle/service/nvdrv/nvdrv.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv.cpp
@@ -40,8 +40,7 @@ Module::Module(Core::System& system) {
auto& kernel = system.Kernel();
for (u32 i = 0; i < MaxNvEvents; i++) {
std::string event_label = fmt::format("NVDRV::NvEvent_{}", i);
- events_interface.events[i] =
- Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual, event_label);
+ events_interface.events[i] = Kernel::WritableEvent::CreateEventPair(kernel, event_label);
events_interface.status[i] = EventState::Free;
events_interface.registered[i] = false;
}
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp
index 55b68eb0c..1af11e80c 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue.cpp
@@ -16,8 +16,7 @@ namespace Service::NVFlinger {
BufferQueue::BufferQueue(Kernel::KernelCore& kernel, u32 id, u64 layer_id)
: id(id), layer_id(layer_id) {
- buffer_wait_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
- "BufferQueue NativeHandle");
+ buffer_wait_event = Kernel::WritableEvent::CreateEventPair(kernel, "BufferQueue NativeHandle");
}
BufferQueue::~BufferQueue() = default;
diff --git a/src/core/hle/service/vi/display/vi_display.cpp b/src/core/hle/service/vi/display/vi_display.cpp
index 006a6d9ff..07033fb98 100644
--- a/src/core/hle/service/vi/display/vi_display.cpp
+++ b/src/core/hle/service/vi/display/vi_display.cpp
@@ -17,8 +17,8 @@ namespace Service::VI {
Display::Display(u64 id, std::string name, Core::System& system) : id{id}, name{std::move(name)} {
auto& kernel = system.Kernel();
- vsync_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
- fmt::format("Display VSync Event {}", id));
+ vsync_event =
+ Kernel::WritableEvent::CreateEventPair(kernel, fmt::format("Display VSync Event {}", id));
}
Display::~Display() = default;
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 199b30635..611cecc20 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -45,7 +45,7 @@ struct DisplayInfo {
/// Whether or not the display has a limited number of layers.
u8 has_limited_layers{1};
- INSERT_PADDING_BYTES(7){};
+ INSERT_PADDING_BYTES(7);
/// Indicates the total amount of layers supported by the display.
/// @note This is only valid if has_limited_layers is set.
diff --git a/src/video_core/engines/fermi_2d.cpp b/src/video_core/engines/fermi_2d.cpp
index 7ff44f06d..85d308e26 100644
--- a/src/video_core/engines/fermi_2d.cpp
+++ b/src/video_core/engines/fermi_2d.cpp
@@ -28,6 +28,13 @@ void Fermi2D::CallMethod(const GPU::MethodCall& method_call) {
}
}
+std::pair<u32, u32> DelimitLine(u32 src_1, u32 src_2, u32 dst_1, u32 dst_2, u32 src_line) {
+ const u32 line_a = src_2 - src_1;
+ const u32 line_b = dst_2 - dst_1;
+ const u32 excess = std::max<s32>(0, line_a - src_line + src_1);
+ return {line_b - (excess * line_b) / line_a, excess};
+}
+
void Fermi2D::HandleSurfaceCopy() {
LOG_DEBUG(HW_GPU, "Requested a surface copy with operation {}",
static_cast<u32>(regs.operation));
@@ -47,10 +54,27 @@ void Fermi2D::HandleSurfaceCopy() {
src_blit_x2 = static_cast<u32>((regs.blit_src_x >> 32) + regs.blit_dst_width);
src_blit_y2 = static_cast<u32>((regs.blit_src_y >> 32) + regs.blit_dst_height);
}
+ u32 dst_blit_x2 = regs.blit_dst_x + regs.blit_dst_width;
+ u32 dst_blit_y2 = regs.blit_dst_y + regs.blit_dst_height;
+ const auto [new_dst_w, src_excess_x] =
+ DelimitLine(src_blit_x1, src_blit_x2, regs.blit_dst_x, dst_blit_x2, regs.src.width);
+ const auto [new_dst_h, src_excess_y] =
+ DelimitLine(src_blit_y1, src_blit_y2, regs.blit_dst_y, dst_blit_y2, regs.src.height);
+ dst_blit_x2 = new_dst_w + regs.blit_dst_x;
+ src_blit_x2 = src_blit_x2 - src_excess_x;
+ dst_blit_y2 = new_dst_h + regs.blit_dst_y;
+ src_blit_y2 = src_blit_y2 - src_excess_y;
+ const auto [new_src_w, dst_excess_x] =
+ DelimitLine(regs.blit_dst_x, dst_blit_x2, src_blit_x1, src_blit_x2, regs.dst.width);
+ const auto [new_src_h, dst_excess_y] =
+ DelimitLine(regs.blit_dst_y, dst_blit_y2, src_blit_y1, src_blit_y2, regs.dst.height);
+ src_blit_x2 = new_src_w + src_blit_x1;
+ dst_blit_x2 = dst_blit_x2 - dst_excess_x;
+ src_blit_y2 = new_src_h + src_blit_y1;
+ dst_blit_y2 = dst_blit_y2 - dst_excess_y;
const Common::Rectangle<u32> src_rect{src_blit_x1, src_blit_y1, src_blit_x2, src_blit_y2};
- const Common::Rectangle<u32> dst_rect{regs.blit_dst_x, regs.blit_dst_y,
- regs.blit_dst_x + regs.blit_dst_width,
- regs.blit_dst_y + regs.blit_dst_height};
+ const Common::Rectangle<u32> dst_rect{regs.blit_dst_x, regs.blit_dst_y, dst_blit_x2,
+ dst_blit_y2};
Config copy_config;
copy_config.operation = regs.operation;
copy_config.filter = regs.blit_control.filter;
diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h
index 0901cf2fa..dba342c70 100644
--- a/src/video_core/engines/fermi_2d.h
+++ b/src/video_core/engines/fermi_2d.h
@@ -99,19 +99,19 @@ public:
union {
struct {
- INSERT_PADDING_WORDS(0x80);
+ INSERT_UNION_PADDING_WORDS(0x80);
Surface dst;
- INSERT_PADDING_WORDS(2);
+ INSERT_UNION_PADDING_WORDS(2);
Surface src;
- INSERT_PADDING_WORDS(0x15);
+ INSERT_UNION_PADDING_WORDS(0x15);
Operation operation;
- INSERT_PADDING_WORDS(0x177);
+ INSERT_UNION_PADDING_WORDS(0x177);
union {
u32 raw;
@@ -119,7 +119,7 @@ public:
BitField<4, 1, Filter> filter;
} blit_control;
- INSERT_PADDING_WORDS(0x8);
+ INSERT_UNION_PADDING_WORDS(0x8);
u32 blit_dst_x;
u32 blit_dst_y;
@@ -130,7 +130,7 @@ public:
u64 blit_src_x;
u64 blit_src_y;
- INSERT_PADDING_WORDS(0x21);
+ INSERT_UNION_PADDING_WORDS(0x21);
};
std::array<u32, NUM_REGS> reg_array;
};
diff --git a/src/video_core/engines/kepler_compute.h b/src/video_core/engines/kepler_compute.h
index b185c98c7..5259d92bd 100644
--- a/src/video_core/engines/kepler_compute.h
+++ b/src/video_core/engines/kepler_compute.h
@@ -51,7 +51,7 @@ public:
union {
struct {
- INSERT_PADDING_WORDS(0x60);
+ INSERT_UNION_PADDING_WORDS(0x60);
Upload::Registers upload;
@@ -63,7 +63,7 @@ public:
u32 data_upload;
- INSERT_PADDING_WORDS(0x3F);
+ INSERT_UNION_PADDING_WORDS(0x3F);
struct {
u32 address;
@@ -72,11 +72,11 @@ public:
}
} launch_desc_loc;
- INSERT_PADDING_WORDS(0x1);
+ INSERT_UNION_PADDING_WORDS(0x1);
u32 launch;
- INSERT_PADDING_WORDS(0x4A7);
+ INSERT_UNION_PADDING_WORDS(0x4A7);
struct {
u32 address_high;
@@ -88,7 +88,7 @@ public:
}
} tsc;
- INSERT_PADDING_WORDS(0x3);
+ INSERT_UNION_PADDING_WORDS(0x3);
struct {
u32 address_high;
@@ -100,7 +100,7 @@ public:
}
} tic;
- INSERT_PADDING_WORDS(0x22);
+ INSERT_UNION_PADDING_WORDS(0x22);
struct {
u32 address_high;
@@ -111,11 +111,11 @@ public:
}
} code_loc;
- INSERT_PADDING_WORDS(0x3FE);
+ INSERT_UNION_PADDING_WORDS(0x3FE);
u32 tex_cb_index;
- INSERT_PADDING_WORDS(0x374);
+ INSERT_UNION_PADDING_WORDS(0x374);
};
std::array<u32, NUM_REGS> reg_array;
};
@@ -179,7 +179,7 @@ public:
};
INSERT_PADDING_WORDS(0x11);
- } launch_description;
+ } launch_description{};
struct {
u32 write_offset = 0;
diff --git a/src/video_core/engines/kepler_memory.h b/src/video_core/engines/kepler_memory.h
index e0e25c321..396fb6e86 100644
--- a/src/video_core/engines/kepler_memory.h
+++ b/src/video_core/engines/kepler_memory.h
@@ -45,7 +45,7 @@ public:
union {
struct {
- INSERT_PADDING_WORDS(0x60);
+ INSERT_UNION_PADDING_WORDS(0x60);
Upload::Registers upload;
@@ -57,7 +57,7 @@ public:
u32 data;
- INSERT_PADDING_WORDS(0x11);
+ INSERT_UNION_PADDING_WORDS(0x11);
};
std::array<u32, NUM_REGS> reg_array;
};
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 8cc842684..1aa7c274f 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -496,7 +496,7 @@ public:
Equation equation_a;
Factor factor_source_a;
Factor factor_dest_a;
- INSERT_PADDING_WORDS(1);
+ INSERT_UNION_PADDING_WORDS(1);
};
struct RenderTargetConfig {
@@ -517,7 +517,7 @@ public:
};
u32 layer_stride;
u32 base_layer;
- INSERT_PADDING_WORDS(7);
+ INSERT_UNION_PADDING_WORDS(7);
GPUVAddr Address() const {
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
@@ -542,7 +542,7 @@ public:
f32 translate_x;
f32 translate_y;
f32 translate_z;
- INSERT_PADDING_WORDS(2);
+ INSERT_UNION_PADDING_WORDS(2);
Common::Rectangle<s32> GetRect() const {
return {
@@ -606,7 +606,7 @@ public:
union {
struct {
- INSERT_PADDING_WORDS(0x45);
+ INSERT_UNION_PADDING_WORDS(0x45);
struct {
u32 upload_address;
@@ -615,7 +615,7 @@ public:
u32 bind;
} macros;
- INSERT_PADDING_WORDS(0x17);
+ INSERT_UNION_PADDING_WORDS(0x17);
Upload::Registers upload;
struct {
@@ -626,7 +626,7 @@ public:
u32 data_upload;
- INSERT_PADDING_WORDS(0x44);
+ INSERT_UNION_PADDING_WORDS(0x44);
struct {
union {
@@ -636,11 +636,11 @@ public:
};
} sync_info;
- INSERT_PADDING_WORDS(0x11E);
+ INSERT_UNION_PADDING_WORDS(0x11E);
u32 tfb_enabled;
- INSERT_PADDING_WORDS(0x2E);
+ INSERT_UNION_PADDING_WORDS(0x2E);
std::array<RenderTargetConfig, NumRenderTargets> rt;
@@ -648,49 +648,49 @@ public:
std::array<ViewPort, NumViewports> viewports;
- INSERT_PADDING_WORDS(0x1D);
+ INSERT_UNION_PADDING_WORDS(0x1D);
struct {
u32 first;
u32 count;
} vertex_buffer;
- INSERT_PADDING_WORDS(1);
+ INSERT_UNION_PADDING_WORDS(1);
float clear_color[4];
float clear_depth;
- INSERT_PADDING_WORDS(0x3);
+ INSERT_UNION_PADDING_WORDS(0x3);
s32 clear_stencil;
- INSERT_PADDING_WORDS(0x7);
+ INSERT_UNION_PADDING_WORDS(0x7);
u32 polygon_offset_point_enable;
u32 polygon_offset_line_enable;
u32 polygon_offset_fill_enable;
- INSERT_PADDING_WORDS(0xD);
+ INSERT_UNION_PADDING_WORDS(0xD);
std::array<ScissorTest, NumViewports> scissor_test;
- INSERT_PADDING_WORDS(0x15);
+ INSERT_UNION_PADDING_WORDS(0x15);
s32 stencil_back_func_ref;
u32 stencil_back_mask;
u32 stencil_back_func_mask;
- INSERT_PADDING_WORDS(0xC);
+ INSERT_UNION_PADDING_WORDS(0xC);
u32 color_mask_common;
- INSERT_PADDING_WORDS(0x6);
+ INSERT_UNION_PADDING_WORDS(0x6);
u32 rt_separate_frag_data;
f32 depth_bounds[2];
- INSERT_PADDING_WORDS(0xA);
+ INSERT_UNION_PADDING_WORDS(0xA);
struct {
u32 address_high;
@@ -710,7 +710,7 @@ public:
}
} zeta;
- INSERT_PADDING_WORDS(0x41);
+ INSERT_UNION_PADDING_WORDS(0x41);
union {
BitField<0, 4, u32> stencil;
@@ -719,11 +719,11 @@ public:
BitField<12, 4, u32> viewport;
} clear_flags;
- INSERT_PADDING_WORDS(0x19);
+ INSERT_UNION_PADDING_WORDS(0x19);
std::array<VertexAttribute, NumVertexAttributes> vertex_attrib_format;
- INSERT_PADDING_WORDS(0xF);
+ INSERT_UNION_PADDING_WORDS(0xF);
struct {
union {
@@ -746,16 +746,16 @@ public:
}
} rt_control;
- INSERT_PADDING_WORDS(0x2);
+ INSERT_UNION_PADDING_WORDS(0x2);
u32 zeta_width;
u32 zeta_height;
- INSERT_PADDING_WORDS(0x27);
+ INSERT_UNION_PADDING_WORDS(0x27);
u32 depth_test_enable;
- INSERT_PADDING_WORDS(0x5);
+ INSERT_UNION_PADDING_WORDS(0x5);
u32 independent_blend_enable;
@@ -763,7 +763,7 @@ public:
u32 alpha_test_enabled;
- INSERT_PADDING_WORDS(0x6);
+ INSERT_UNION_PADDING_WORDS(0x6);
u32 d3d_cull_mode;
@@ -777,7 +777,7 @@ public:
float b;
float a;
} blend_color;
- INSERT_PADDING_WORDS(0x4);
+ INSERT_UNION_PADDING_WORDS(0x4);
struct {
u32 separate_alpha;
@@ -786,7 +786,7 @@ public:
Blend::Factor factor_dest_rgb;
Blend::Equation equation_a;
Blend::Factor factor_source_a;
- INSERT_PADDING_WORDS(1);
+ INSERT_UNION_PADDING_WORDS(1);
Blend::Factor factor_dest_a;
u32 enable_common;
@@ -802,7 +802,7 @@ public:
u32 stencil_front_func_mask;
u32 stencil_front_mask;
- INSERT_PADDING_WORDS(0x2);
+ INSERT_UNION_PADDING_WORDS(0x2);
u32 frag_color_clamp;
@@ -811,12 +811,12 @@ public:
BitField<4, 1, u32> triangle_rast_flip;
} screen_y_control;
- INSERT_PADDING_WORDS(0x21);
+ INSERT_UNION_PADDING_WORDS(0x21);
u32 vb_element_base;
u32 vb_base_instance;
- INSERT_PADDING_WORDS(0x35);
+ INSERT_UNION_PADDING_WORDS(0x35);
union {
BitField<0, 1, u32> c0;
@@ -829,11 +829,11 @@ public:
BitField<7, 1, u32> c7;
} clip_distance_enabled;
- INSERT_PADDING_WORDS(0x1);
+ INSERT_UNION_PADDING_WORDS(0x1);
float point_size;
- INSERT_PADDING_WORDS(0x7);
+ INSERT_UNION_PADDING_WORDS(0x7);
u32 zeta_enable;
@@ -842,7 +842,7 @@ public:
BitField<4, 1, u32> alpha_to_one;
} multisample_control;
- INSERT_PADDING_WORDS(0x4);
+ INSERT_UNION_PADDING_WORDS(0x4);
struct {
u32 address_high;
@@ -866,11 +866,11 @@ public:
}
} tsc;
- INSERT_PADDING_WORDS(0x1);
+ INSERT_UNION_PADDING_WORDS(0x1);
float polygon_offset_factor;
- INSERT_PADDING_WORDS(0x1);
+ INSERT_UNION_PADDING_WORDS(0x1);
struct {
u32 tic_address_high;
@@ -883,7 +883,7 @@ public:
}
} tic;
- INSERT_PADDING_WORDS(0x5);
+ INSERT_UNION_PADDING_WORDS(0x5);
u32 stencil_two_side_enable;
StencilOp stencil_back_op_fail;
@@ -891,13 +891,13 @@ public:
StencilOp stencil_back_op_zpass;
ComparisonOp stencil_back_func_func;
- INSERT_PADDING_WORDS(0x4);
+ INSERT_UNION_PADDING_WORDS(0x4);
u32 framebuffer_srgb;
float polygon_offset_units;
- INSERT_PADDING_WORDS(0x11);
+ INSERT_UNION_PADDING_WORDS(0x11);
union {
BitField<2, 1, u32> coord_origin;
@@ -913,7 +913,7 @@ public:
(static_cast<GPUVAddr>(code_address_high) << 32) | code_address_low);
}
} code_address;
- INSERT_PADDING_WORDS(1);
+ INSERT_UNION_PADDING_WORDS(1);
struct {
u32 vertex_end_gl;
@@ -925,14 +925,14 @@ public:
};
} draw;
- INSERT_PADDING_WORDS(0xA);
+ INSERT_UNION_PADDING_WORDS(0xA);
struct {
u32 enabled;
u32 index;
} primitive_restart;
- INSERT_PADDING_WORDS(0x5F);
+ INSERT_UNION_PADDING_WORDS(0x5F);
struct {
u32 start_addr_high;
@@ -973,9 +973,9 @@ public:
}
} index_array;
- INSERT_PADDING_WORDS(0x7);
+ INSERT_UNION_PADDING_WORDS(0x7);
- INSERT_PADDING_WORDS(0x1F);
+ INSERT_UNION_PADDING_WORDS(0x1F);
float polygon_offset_clamp;
@@ -989,17 +989,17 @@ public:
}
} instanced_arrays;
- INSERT_PADDING_WORDS(0x6);
+ INSERT_UNION_PADDING_WORDS(0x6);
Cull cull;
u32 pixel_center_integer;
- INSERT_PADDING_WORDS(0x1);
+ INSERT_UNION_PADDING_WORDS(0x1);
u32 viewport_transform_enabled;
- INSERT_PADDING_WORDS(0x3);
+ INSERT_UNION_PADDING_WORDS(0x3);
union {
BitField<0, 1, u32> depth_range_0_1;
@@ -1007,13 +1007,13 @@ public:
BitField<4, 1, u32> depth_clamp_far;
} view_volume_clip_control;
- INSERT_PADDING_WORDS(0x21);
+ INSERT_UNION_PADDING_WORDS(0x21);
struct {
u32 enable;
LogicOperation operation;
} logic_op;
- INSERT_PADDING_WORDS(0x1);
+ INSERT_UNION_PADDING_WORDS(0x1);
union {
u32 raw;
@@ -1026,9 +1026,9 @@ public:
BitField<6, 4, u32> RT;
BitField<10, 11, u32> layer;
} clear_buffers;
- INSERT_PADDING_WORDS(0xB);
+ INSERT_UNION_PADDING_WORDS(0xB);
std::array<ColorMask, NumRenderTargets> color_mask;
- INSERT_PADDING_WORDS(0x38);
+ INSERT_UNION_PADDING_WORDS(0x38);
struct {
u32 query_address_high;
@@ -1050,7 +1050,7 @@ public:
}
} query;
- INSERT_PADDING_WORDS(0x3C);
+ INSERT_UNION_PADDING_WORDS(0x3C);
struct {
union {
@@ -1090,10 +1090,10 @@ public:
BitField<4, 4, ShaderProgram> program;
};
u32 offset;
- INSERT_PADDING_WORDS(14);
+ INSERT_UNION_PADDING_WORDS(14);
} shader_config[MaxShaderProgram];
- INSERT_PADDING_WORDS(0x60);
+ INSERT_UNION_PADDING_WORDS(0x60);
u32 firmware[0x20];
@@ -1110,7 +1110,7 @@ public:
}
} const_buffer;
- INSERT_PADDING_WORDS(0x10);
+ INSERT_UNION_PADDING_WORDS(0x10);
struct {
union {
@@ -1118,14 +1118,14 @@ public:
BitField<0, 1, u32> valid;
BitField<4, 5, u32> index;
};
- INSERT_PADDING_WORDS(7);
+ INSERT_UNION_PADDING_WORDS(7);
} cb_bind[MaxShaderStage];
- INSERT_PADDING_WORDS(0x56);
+ INSERT_UNION_PADDING_WORDS(0x56);
u32 tex_cb_index;
- INSERT_PADDING_WORDS(0x395);
+ INSERT_UNION_PADDING_WORDS(0x395);
struct {
/// Compressed address of a buffer that holds information about bound SSBOs.
@@ -1137,14 +1137,14 @@ public:
}
} ssbo_info;
- INSERT_PADDING_WORDS(0x11);
+ INSERT_UNION_PADDING_WORDS(0x11);
struct {
u32 address[MaxShaderStage];
u32 size[MaxShaderStage];
} tex_info_buffers;
- INSERT_PADDING_WORDS(0xCC);
+ INSERT_UNION_PADDING_WORDS(0xCC);
};
std::array<u32, NUM_REGS> reg_array;
};
diff --git a/src/video_core/engines/maxwell_dma.h b/src/video_core/engines/maxwell_dma.h
index 93808a9bb..4f40d1d1f 100644
--- a/src/video_core/engines/maxwell_dma.h
+++ b/src/video_core/engines/maxwell_dma.h
@@ -94,7 +94,7 @@ public:
union {
struct {
- INSERT_PADDING_WORDS(0xC0);
+ INSERT_UNION_PADDING_WORDS(0xC0);
struct {
union {
@@ -112,7 +112,7 @@ public:
};
} exec;
- INSERT_PADDING_WORDS(0x3F);
+ INSERT_UNION_PADDING_WORDS(0x3F);
struct {
u32 address_high;
@@ -139,7 +139,7 @@ public:
u32 x_count;
u32 y_count;
- INSERT_PADDING_WORDS(0xB8);
+ INSERT_UNION_PADDING_WORDS(0xB8);
u32 const0;
u32 const1;
@@ -162,11 +162,11 @@ public:
Parameters dst_params;
- INSERT_PADDING_WORDS(1);
+ INSERT_UNION_PADDING_WORDS(1);
Parameters src_params;
- INSERT_PADDING_WORDS(0x13);
+ INSERT_UNION_PADDING_WORDS(0x13);
};
std::array<u32, NUM_REGS> reg_array;
};
diff --git a/src/video_core/engines/shader_header.h b/src/video_core/engines/shader_header.h
index e86a7f04a..bc80661d8 100644
--- a/src/video_core/engines/shader_header.h
+++ b/src/video_core/engines/shader_header.h
@@ -38,37 +38,37 @@ struct Header {
BitField<26, 1, u32> does_load_or_store;
BitField<27, 1, u32> does_fp64;
BitField<28, 4, u32> stream_out_mask;
- } common0;
+ } common0{};
union {
BitField<0, 24, u32> shader_local_memory_low_size;
BitField<24, 8, u32> per_patch_attribute_count;
- } common1;
+ } common1{};
union {
BitField<0, 24, u32> shader_local_memory_high_size;
BitField<24, 8, u32> threads_per_input_primitive;
- } common2;
+ } common2{};
union {
BitField<0, 24, u32> shader_local_memory_crs_size;
BitField<24, 4, OutputTopology> output_topology;
BitField<28, 4, u32> reserved;
- } common3;
+ } common3{};
union {
BitField<0, 12, u32> max_output_vertices;
BitField<12, 8, u32> store_req_start; // NOTE: not used by geometry shaders.
BitField<24, 4, u32> reserved;
BitField<12, 8, u32> store_req_end; // NOTE: not used by geometry shaders.
- } common4;
+ } common4{};
union {
struct {
- INSERT_PADDING_BYTES(3); // ImapSystemValuesA
- INSERT_PADDING_BYTES(1); // ImapSystemValuesB
- INSERT_PADDING_BYTES(16); // ImapGenericVector[32]
- INSERT_PADDING_BYTES(2); // ImapColor
+ INSERT_UNION_PADDING_BYTES(3); // ImapSystemValuesA
+ INSERT_UNION_PADDING_BYTES(1); // ImapSystemValuesB
+ INSERT_UNION_PADDING_BYTES(16); // ImapGenericVector[32]
+ INSERT_UNION_PADDING_BYTES(2); // ImapColor
union {
BitField<0, 8, u16> clip_distances;
BitField<8, 1, u16> point_sprite_s;
@@ -79,20 +79,20 @@ struct Header {
BitField<14, 1, u16> instance_id;
BitField<15, 1, u16> vertex_id;
};
- INSERT_PADDING_BYTES(5); // ImapFixedFncTexture[10]
- INSERT_PADDING_BYTES(1); // ImapReserved
- INSERT_PADDING_BYTES(3); // OmapSystemValuesA
- INSERT_PADDING_BYTES(1); // OmapSystemValuesB
- INSERT_PADDING_BYTES(16); // OmapGenericVector[32]
- INSERT_PADDING_BYTES(2); // OmapColor
- INSERT_PADDING_BYTES(2); // OmapSystemValuesC
- INSERT_PADDING_BYTES(5); // OmapFixedFncTexture[10]
- INSERT_PADDING_BYTES(1); // OmapReserved
+ INSERT_UNION_PADDING_BYTES(5); // ImapFixedFncTexture[10]
+ INSERT_UNION_PADDING_BYTES(1); // ImapReserved
+ INSERT_UNION_PADDING_BYTES(3); // OmapSystemValuesA
+ INSERT_UNION_PADDING_BYTES(1); // OmapSystemValuesB
+ INSERT_UNION_PADDING_BYTES(16); // OmapGenericVector[32]
+ INSERT_UNION_PADDING_BYTES(2); // OmapColor
+ INSERT_UNION_PADDING_BYTES(2); // OmapSystemValuesC
+ INSERT_UNION_PADDING_BYTES(5); // OmapFixedFncTexture[10]
+ INSERT_UNION_PADDING_BYTES(1); // OmapReserved
} vtg;
struct {
- INSERT_PADDING_BYTES(3); // ImapSystemValuesA
- INSERT_PADDING_BYTES(1); // ImapSystemValuesB
+ INSERT_UNION_PADDING_BYTES(3); // ImapSystemValuesA
+ INSERT_UNION_PADDING_BYTES(1); // ImapSystemValuesB
union {
BitField<0, 2, AttributeUse> x;
BitField<2, 2, AttributeUse> y;
@@ -100,10 +100,10 @@ struct Header {
BitField<6, 2, AttributeUse> z;
u8 raw;
} imap_generic_vector[32];
- INSERT_PADDING_BYTES(2); // ImapColor
- INSERT_PADDING_BYTES(2); // ImapSystemValuesC
- INSERT_PADDING_BYTES(10); // ImapFixedFncTexture[10]
- INSERT_PADDING_BYTES(2); // ImapReserved
+ INSERT_UNION_PADDING_BYTES(2); // ImapColor
+ INSERT_UNION_PADDING_BYTES(2); // ImapSystemValuesC
+ INSERT_UNION_PADDING_BYTES(10); // ImapFixedFncTexture[10]
+ INSERT_UNION_PADDING_BYTES(2); // ImapReserved
struct {
u32 target;
union {
@@ -139,6 +139,8 @@ struct Header {
return result;
}
} ps;
+
+ std::array<u32, 0xF> raw{};
};
u64 GetLocalMemorySize() const {
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index dbca19f35..ecc338ae9 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -207,7 +207,7 @@ public:
union {
struct {
- INSERT_PADDING_WORDS(0x4);
+ INSERT_UNION_PADDING_WORDS(0x4);
struct {
u32 address_high;
u32 address_low;
@@ -220,12 +220,12 @@ public:
u32 semaphore_sequence;
u32 semaphore_trigger;
- INSERT_PADDING_WORDS(0xC);
+ INSERT_UNION_PADDING_WORDS(0xC);
// The puser and the puller share the reference counter, the pusher only has read
// access
u32 reference_count;
- INSERT_PADDING_WORDS(0x5);
+ INSERT_UNION_PADDING_WORDS(0x5);
u32 semaphore_acquire;
u32 semaphore_release;
@@ -234,7 +234,7 @@ public:
BitField<4, 4, u32> operation;
BitField<8, 8, u32> id;
} fence_action;
- INSERT_PADDING_WORDS(0xE2);
+ INSERT_UNION_PADDING_WORDS(0xE2);
// Puller state
u32 acquire_mode;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index e9abd901e..e560d70d5 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -938,10 +938,9 @@ TextureBufferUsage RasterizerOpenGL::SetupDrawTextures(Maxwell::ShaderStage stag
if (!entry.IsBindless()) {
return maxwell3d.GetStageTexture(stage, entry.GetOffset());
}
- const auto cbuf = entry.GetBindlessCBuf();
- Tegra::Texture::TextureHandle tex_handle;
- Tegra::Engines::ShaderType shader_type = static_cast<Tegra::Engines::ShaderType>(stage);
- tex_handle.raw = maxwell3d.AccessConstBuffer32(shader_type, cbuf.first, cbuf.second);
+ const auto shader_type = static_cast<Tegra::Engines::ShaderType>(stage);
+ const Tegra::Texture::TextureHandle tex_handle =
+ maxwell3d.AccessConstBuffer32(shader_type, entry.GetBuffer(), entry.GetOffset());
return maxwell3d.GetTextureInfo(tex_handle);
}();
@@ -969,10 +968,8 @@ TextureBufferUsage RasterizerOpenGL::SetupComputeTextures(const Shader& kernel)
if (!entry.IsBindless()) {
return compute.GetTexture(entry.GetOffset());
}
- const auto cbuf = entry.GetBindlessCBuf();
- Tegra::Texture::TextureHandle tex_handle;
- tex_handle.raw = compute.AccessConstBuffer32(Tegra::Engines::ShaderType::Compute,
- cbuf.first, cbuf.second);
+ const Tegra::Texture::TextureHandle tex_handle = compute.AccessConstBuffer32(
+ Tegra::Engines::ShaderType::Compute, entry.GetBuffer(), entry.GetOffset());
return compute.GetTextureInfo(tex_handle);
}();
@@ -1015,10 +1012,8 @@ void RasterizerOpenGL::SetupComputeImages(const Shader& shader) {
if (!entry.IsBindless()) {
return compute.GetTexture(entry.GetOffset()).tic;
}
- const auto cbuf = entry.GetBindlessCBuf();
- Tegra::Texture::TextureHandle tex_handle;
- tex_handle.raw = compute.AccessConstBuffer32(Tegra::Engines::ShaderType::Compute,
- cbuf.first, cbuf.second);
+ const Tegra::Texture::TextureHandle tex_handle = compute.AccessConstBuffer32(
+ Tegra::Engines::ShaderType::Compute, entry.GetBuffer(), entry.GetOffset());
return compute.GetTextureInfo(tex_handle).tic;
}();
SetupImage(bindpoint, tic, entry);
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 030550c53..92ee8459e 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -735,7 +735,7 @@ private:
void DeclareImages() {
const auto& images{ir.GetImages()};
- for (const auto& [offset, image] : images) {
+ for (const auto& image : images) {
std::string qualifier = "coherent volatile";
if (image.IsRead() && !image.IsWritten()) {
qualifier += " readonly";
@@ -2466,16 +2466,16 @@ ShaderEntries GetEntries(const VideoCommon::Shader::ShaderIR& ir) {
entries.const_buffers.emplace_back(cbuf.second.GetMaxOffset(), cbuf.second.IsIndirect(),
cbuf.first);
}
+ for (const auto& [base, usage] : ir.GetGlobalMemory()) {
+ entries.global_memory_entries.emplace_back(base.cbuf_index, base.cbuf_offset, usage.is_read,
+ usage.is_written);
+ }
for (const auto& sampler : ir.GetSamplers()) {
entries.samplers.emplace_back(sampler);
}
- for (const auto& [offset, image] : ir.GetImages()) {
+ for (const auto& image : ir.GetImages()) {
entries.images.emplace_back(image);
}
- for (const auto& [base, usage] : ir.GetGlobalMemory()) {
- entries.global_memory_entries.emplace_back(base.cbuf_index, base.cbuf_offset, usage.is_read,
- usage.is_written);
- }
entries.clip_distances = ir.GetClipDistances();
entries.shader_length = ir.GetLength();
return entries;
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.h b/src/video_core/renderer_opengl/gl_shader_decompiler.h
index fead2a51e..b1e75e6cc 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.h
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.h
@@ -82,10 +82,9 @@ private:
struct ShaderEntries {
std::vector<ConstBufferEntry> const_buffers;
+ std::vector<GlobalMemoryEntry> global_memory_entries;
std::vector<SamplerEntry> samplers;
- std::vector<SamplerEntry> bindless_samplers;
std::vector<ImageEntry> images;
- std::vector<GlobalMemoryEntry> global_memory_entries;
std::array<bool, Maxwell::NumClipDistances> clip_distances{};
std::size_t shader_length{};
};
diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp
index b02d2cb95..d2fe4ec5d 100644
--- a/src/video_core/shader/decode/image.cpp
+++ b/src/video_core/shader/decode/image.cpp
@@ -143,39 +143,37 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) {
}
Image& ShaderIR::GetImage(Tegra::Shader::Image image, Tegra::Shader::ImageType type) {
- const auto offset{static_cast<std::size_t>(image.index.Value())};
- if (const auto existing_image = TryUseExistingImage(offset, type)) {
- return *existing_image;
+ const auto offset = static_cast<u32>(image.index.Value());
+
+ const auto it =
+ std::find_if(std::begin(used_images), std::end(used_images),
+ [offset](const Image& entry) { return entry.GetOffset() == offset; });
+ if (it != std::end(used_images)) {
+ ASSERT(!it->IsBindless() && it->GetType() == it->GetType());
+ return *it;
}
- const std::size_t next_index{used_images.size()};
- return used_images.emplace(offset, Image{offset, next_index, type}).first->second;
+ const auto next_index = static_cast<u32>(used_images.size());
+ return used_images.emplace_back(next_index, offset, type);
}
Image& ShaderIR::GetBindlessImage(Tegra::Shader::Register reg, Tegra::Shader::ImageType type) {
- const Node image_register{GetRegister(reg)};
- const auto [base_image, cbuf_index, cbuf_offset]{
- TrackCbuf(image_register, global_code, static_cast<s64>(global_code.size()))};
- const auto cbuf_key{(static_cast<u64>(cbuf_index) << 32) | static_cast<u64>(cbuf_offset)};
-
- if (const auto image = TryUseExistingImage(cbuf_key, type)) {
- return *image;
- }
-
- const std::size_t next_index{used_images.size()};
- return used_images.emplace(cbuf_key, Image{cbuf_index, cbuf_offset, next_index, type})
- .first->second;
-}
-
-Image* ShaderIR::TryUseExistingImage(u64 offset, Tegra::Shader::ImageType type) {
- auto it = used_images.find(offset);
- if (it == used_images.end()) {
- return nullptr;
+ const Node image_register = GetRegister(reg);
+ const auto [base_image, buffer, offset] =
+ TrackCbuf(image_register, global_code, static_cast<s64>(global_code.size()));
+
+ const auto it =
+ std::find_if(std::begin(used_images), std::end(used_images),
+ [buffer = buffer, offset = offset](const Image& entry) {
+ return entry.GetBuffer() == buffer && entry.GetOffset() == offset;
+ });
+ if (it != std::end(used_images)) {
+ ASSERT(it->IsBindless() && it->GetType() == it->GetType());
+ return *it;
}
- auto& image = it->second;
- ASSERT(image.GetType() == type);
- return &image;
+ const auto next_index = static_cast<u32>(used_images.size());
+ return used_images.emplace_back(next_index, offset, buffer, type);
}
} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp
index 4c838c8bb..ca690b58b 100644
--- a/src/video_core/shader/decode/texture.cpp
+++ b/src/video_core/shader/decode/texture.cpp
@@ -262,7 +262,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
break;
}
case OpCode::Id::TLDS: {
- const Tegra::Shader::TextureType texture_type{instr.tlds.GetTextureType()};
+ const TextureType texture_type{instr.tlds.GetTextureType()};
const bool is_array{instr.tlds.IsArrayTexture()};
UNIMPLEMENTED_IF_MSG(instr.tlds.UsesMiscMode(TextureMiscMode::AOFFI),
@@ -293,77 +293,80 @@ const Sampler& ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler,
std::optional<SamplerInfo> sampler_info) {
const auto offset = static_cast<u32>(sampler.index.Value());
- Tegra::Shader::TextureType type;
+ TextureType type;
bool is_array;
bool is_shadow;
if (sampler_info) {
type = sampler_info->type;
is_array = sampler_info->is_array;
is_shadow = sampler_info->is_shadow;
- } else if (auto sampler = locker.ObtainBoundSampler(offset); sampler) {
+ } else if (const auto sampler = locker.ObtainBoundSampler(offset)) {
type = sampler->texture_type.Value();
is_array = sampler->is_array.Value() != 0;
is_shadow = sampler->is_shadow.Value() != 0;
} else {
- type = Tegra::Shader::TextureType::Texture2D;
+ LOG_WARNING(HW_GPU, "Unknown sampler info");
+ type = TextureType::Texture2D;
is_array = false;
is_shadow = false;
}
// If this sampler has already been used, return the existing mapping.
- const auto itr =
+ const auto it =
std::find_if(used_samplers.begin(), used_samplers.end(),
- [&](const Sampler& entry) { return entry.GetOffset() == offset; });
- if (itr != used_samplers.end()) {
- ASSERT(itr->GetType() == type && itr->IsArray() == is_array &&
- itr->IsShadow() == is_shadow);
- return *itr;
+ [offset](const Sampler& entry) { return entry.GetOffset() == offset; });
+ if (it != used_samplers.end()) {
+ ASSERT(!it->IsBindless() && it->GetType() == type && it->IsArray() == is_array &&
+ it->IsShadow() == is_shadow);
+ return *it;
}
// Otherwise create a new mapping for this sampler
- const std::size_t next_index = used_samplers.size();
- const Sampler entry{offset, next_index, type, is_array, is_shadow};
- return *used_samplers.emplace(entry).first;
-} // namespace VideoCommon::Shader
+ const auto next_index = static_cast<u32>(used_samplers.size());
+ return used_samplers.emplace_back(Sampler(next_index, offset, type, is_array, is_shadow));
+}
const Sampler& ShaderIR::GetBindlessSampler(const Tegra::Shader::Register& reg,
std::optional<SamplerInfo> sampler_info) {
const Node sampler_register = GetRegister(reg);
- const auto [base_sampler, cbuf_index, cbuf_offset] =
+ const auto [base_sampler, buffer, offset] =
TrackCbuf(sampler_register, global_code, static_cast<s64>(global_code.size()));
ASSERT(base_sampler != nullptr);
- const auto cbuf_key = (static_cast<u64>(cbuf_index) << 32) | static_cast<u64>(cbuf_offset);
- Tegra::Shader::TextureType type;
+
+ TextureType type;
bool is_array;
bool is_shadow;
if (sampler_info) {
type = sampler_info->type;
is_array = sampler_info->is_array;
is_shadow = sampler_info->is_shadow;
- } else if (auto sampler = locker.ObtainBindlessSampler(cbuf_index, cbuf_offset); sampler) {
+ } else if (const auto sampler = locker.ObtainBindlessSampler(buffer, offset)) {
type = sampler->texture_type.Value();
is_array = sampler->is_array.Value() != 0;
is_shadow = sampler->is_shadow.Value() != 0;
} else {
- type = Tegra::Shader::TextureType::Texture2D;
+ LOG_WARNING(HW_GPU, "Unknown sampler info");
+ type = TextureType::Texture2D;
is_array = false;
is_shadow = false;
}
// If this sampler has already been used, return the existing mapping.
- const auto itr =
+ const auto it =
std::find_if(used_samplers.begin(), used_samplers.end(),
- [&](const Sampler& entry) { return entry.GetOffset() == cbuf_key; });
- if (itr != used_samplers.end()) {
- ASSERT(itr->GetType() == type && itr->IsArray() == is_array &&
- itr->IsShadow() == is_shadow);
- return *itr;
+ [buffer = buffer, offset = offset](const Sampler& entry) {
+ return entry.GetBuffer() == buffer && entry.GetOffset() == offset;
+ });
+ if (it != used_samplers.end()) {
+ ASSERT(it->IsBindless() && it->GetType() == type && it->IsArray() == is_array &&
+ it->IsShadow() == is_shadow);
+ return *it;
}
// Otherwise create a new mapping for this sampler
- const std::size_t next_index = used_samplers.size();
- const Sampler entry{cbuf_index, cbuf_offset, next_index, type, is_array, is_shadow};
- return *used_samplers.emplace(entry).first;
+ const auto next_index = static_cast<u32>(used_samplers.size());
+ return used_samplers.emplace_back(
+ Sampler(next_index, offset, buffer, type, is_array, is_shadow));
}
void ShaderIR::WriteTexInstructionFloat(NodeBlock& bb, Instruction instr, const Node4& components) {
diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h
index 447fb5c1d..4300d9ff4 100644
--- a/src/video_core/shader/node.h
+++ b/src/video_core/shader/node.h
@@ -230,62 +230,49 @@ using NodeBlock = std::vector<Node>;
class Sampler {
public:
/// This constructor is for bound samplers
- explicit Sampler(std::size_t offset, std::size_t index, Tegra::Shader::TextureType type,
- bool is_array, bool is_shadow)
- : offset{offset}, index{index}, type{type}, is_array{is_array}, is_shadow{is_shadow},
- is_bindless{false} {}
+ constexpr explicit Sampler(u32 index, u32 offset, Tegra::Shader::TextureType type,
+ bool is_array, bool is_shadow)
+ : index{index}, offset{offset}, type{type}, is_array{is_array}, is_shadow{is_shadow} {}
/// This constructor is for bindless samplers
- explicit Sampler(u32 cbuf_index, u32 cbuf_offset, std::size_t index,
- Tegra::Shader::TextureType type, bool is_array, bool is_shadow)
- : offset{(static_cast<u64>(cbuf_index) << 32) | cbuf_offset}, index{index}, type{type},
- is_array{is_array}, is_shadow{is_shadow}, is_bindless{true} {}
-
- /// This constructor is for serialization/deserialization
- explicit Sampler(std::size_t offset, std::size_t index, Tegra::Shader::TextureType type,
- bool is_array, bool is_shadow, bool is_bindless)
- : offset{offset}, index{index}, type{type}, is_array{is_array}, is_shadow{is_shadow},
- is_bindless{is_bindless} {}
-
- std::size_t GetOffset() const {
+ constexpr explicit Sampler(u32 index, u32 offset, u32 buffer, Tegra::Shader::TextureType type,
+ bool is_array, bool is_shadow)
+ : index{index}, offset{offset}, buffer{buffer}, type{type}, is_array{is_array},
+ is_shadow{is_shadow}, is_bindless{true} {}
+
+ constexpr u32 GetIndex() const {
+ return index;
+ }
+
+ constexpr u32 GetOffset() const {
return offset;
}
- std::size_t GetIndex() const {
- return index;
+ constexpr u32 GetBuffer() const {
+ return buffer;
}
- Tegra::Shader::TextureType GetType() const {
+ constexpr Tegra::Shader::TextureType GetType() const {
return type;
}
- bool IsArray() const {
+ constexpr bool IsArray() const {
return is_array;
}
- bool IsShadow() const {
+ constexpr bool IsShadow() const {
return is_shadow;
}
- bool IsBindless() const {
+ constexpr bool IsBindless() const {
return is_bindless;
}
- std::pair<u32, u32> GetBindlessCBuf() const {
- return {static_cast<u32>(offset >> 32), static_cast<u32>(offset)};
- }
-
- bool operator<(const Sampler& rhs) const {
- return std::tie(index, offset, type, is_array, is_shadow, is_bindless) <
- std::tie(rhs.index, rhs.offset, rhs.type, rhs.is_array, rhs.is_shadow,
- rhs.is_bindless);
- }
-
private:
- /// Offset in TSC memory from which to read the sampler object, as specified by the sampling
- /// instruction.
- std::size_t offset{};
- std::size_t index{}; ///< Value used to index into the generated GLSL sampler array.
+ u32 index{}; ///< Emulated index given for the this sampler.
+ u32 offset{}; ///< Offset in the const buffer from where the sampler is being read.
+ u32 buffer{}; ///< Buffer where the bindless sampler is being read (unused on bound samplers).
+
Tegra::Shader::TextureType type{}; ///< The type used to sample this texture (Texture2D, etc)
bool is_array{}; ///< Whether the texture is being sampled as an array texture or not.
bool is_shadow{}; ///< Whether the texture is being sampled as a depth texture or not.
@@ -294,18 +281,13 @@ private:
class Image final {
public:
- constexpr explicit Image(std::size_t offset, std::size_t index, Tegra::Shader::ImageType type)
- : offset{offset}, index{index}, type{type}, is_bindless{false} {}
-
- constexpr explicit Image(u32 cbuf_index, u32 cbuf_offset, std::size_t index,
- Tegra::Shader::ImageType type)
- : offset{(static_cast<u64>(cbuf_index) << 32) | cbuf_offset}, index{index}, type{type},
- is_bindless{true} {}
+ /// This constructor is for bound images
+ constexpr explicit Image(u32 index, u32 offset, Tegra::Shader::ImageType type)
+ : index{index}, offset{offset}, type{type} {}
- constexpr explicit Image(std::size_t offset, std::size_t index, Tegra::Shader::ImageType type,
- bool is_bindless, bool is_written, bool is_read, bool is_atomic)
- : offset{offset}, index{index}, type{type}, is_bindless{is_bindless},
- is_written{is_written}, is_read{is_read}, is_atomic{is_atomic} {}
+ /// This constructor is for bindless samplers
+ constexpr explicit Image(u32 index, u32 offset, u32 buffer, Tegra::Shader::ImageType type)
+ : index{index}, offset{offset}, buffer{buffer}, type{type}, is_bindless{true} {}
void MarkWrite() {
is_written = true;
@@ -321,12 +303,16 @@ public:
is_atomic = true;
}
- constexpr std::size_t GetOffset() const {
+ constexpr u32 GetIndex() const {
+ return index;
+ }
+
+ constexpr u32 GetOffset() const {
return offset;
}
- constexpr std::size_t GetIndex() const {
- return index;
+ constexpr u32 GetBuffer() const {
+ return buffer;
}
constexpr Tegra::Shader::ImageType GetType() const {
@@ -349,18 +335,11 @@ public:
return is_atomic;
}
- constexpr std::pair<u32, u32> GetBindlessCBuf() const {
- return {static_cast<u32>(offset >> 32), static_cast<u32>(offset)};
- }
-
- constexpr bool operator<(const Image& rhs) const {
- return std::tie(offset, index, type, is_bindless) <
- std::tie(rhs.offset, rhs.index, rhs.type, rhs.is_bindless);
- }
-
private:
- u64 offset{};
- std::size_t index{};
+ u32 index{};
+ u32 offset{};
+ u32 buffer{};
+
Tegra::Shader::ImageType type{};
bool is_bindless{};
bool is_written{};
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index b5567f54e..26c8fde22 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -5,6 +5,7 @@
#pragma once
#include <array>
+#include <list>
#include <map>
#include <optional>
#include <set>
@@ -95,11 +96,11 @@ public:
return used_cbufs;
}
- const std::set<Sampler>& GetSamplers() const {
+ const std::list<Sampler>& GetSamplers() const {
return used_samplers;
}
- const std::map<u64, Image>& GetImages() const {
+ const std::list<Image>& GetImages() const {
return used_images;
}
@@ -316,9 +317,6 @@ private:
/// Access a bindless image sampler.
Image& GetBindlessImage(Tegra::Shader::Register reg, Tegra::Shader::ImageType type);
- /// Tries to access an existing image, updating it's state as needed
- Image* TryUseExistingImage(u64 offset, Tegra::Shader::ImageType type);
-
/// Extracts a sequence of bits from a node
Node BitfieldExtract(Node value, u32 offset, u32 bits);
@@ -402,8 +400,8 @@ private:
std::set<Tegra::Shader::Attribute::Index> used_input_attributes;
std::set<Tegra::Shader::Attribute::Index> used_output_attributes;
std::map<u32, ConstBuffer> used_cbufs;
- std::set<Sampler> used_samplers;
- std::map<u64, Image> used_images;
+ std::list<Sampler> used_samplers;
+ std::list<Image> used_images;
std::array<bool, Tegra::Engines::Maxwell3D::Regs::NumClipDistances> used_clip_distances{};
std::map<GlobalMemoryBase, GlobalMemoryUsage> used_global_memory;
bool uses_layer{};
diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h
index 0429af9c1..27c8ce975 100644
--- a/src/video_core/textures/texture.h
+++ b/src/video_core/textures/texture.h
@@ -132,6 +132,8 @@ enum class SwizzleSource : u32 {
};
union TextureHandle {
+ TextureHandle(u32 raw) : raw{raw} {}
+
u32 raw;
BitField<0, 20, u32> tic_id;
BitField<20, 12, u32> tsc_id;
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp
index c5b9aa08f..188f798c0 100644
--- a/src/yuzu/debugger/wait_tree.cpp
+++ b/src/yuzu/debugger/wait_tree.cpp
@@ -172,17 +172,6 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeWaitObject::GetChildren() con
return list;
}
-QString WaitTreeWaitObject::GetResetTypeQString(Kernel::ResetType reset_type) {
- switch (reset_type) {
- case Kernel::ResetType::Automatic:
- return tr("automatic reset");
- case Kernel::ResetType::Manual:
- return tr("manual reset");
- }
- UNREACHABLE();
- return {};
-}
-
WaitTreeObjectList::WaitTreeObjectList(
const std::vector<Kernel::SharedPtr<Kernel::WaitObject>>& list, bool w_all)
: object_list(list), wait_all(w_all) {}
@@ -336,16 +325,6 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const {
WaitTreeEvent::WaitTreeEvent(const Kernel::ReadableEvent& object) : WaitTreeWaitObject(object) {}
WaitTreeEvent::~WaitTreeEvent() = default;
-std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeEvent::GetChildren() const {
- std::vector<std::unique_ptr<WaitTreeItem>> list(WaitTreeWaitObject::GetChildren());
-
- list.push_back(std::make_unique<WaitTreeText>(
- tr("reset type = %1")
- .arg(GetResetTypeQString(
- static_cast<const Kernel::ReadableEvent&>(object).GetResetType()))));
- return list;
-}
-
WaitTreeThreadList::WaitTreeThreadList(const std::vector<Kernel::SharedPtr<Kernel::Thread>>& list)
: thread_list(list) {}
WaitTreeThreadList::~WaitTreeThreadList() = default;
diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h
index 62886609d..f2b13be24 100644
--- a/src/yuzu/debugger/wait_tree.h
+++ b/src/yuzu/debugger/wait_tree.h
@@ -111,8 +111,6 @@ public:
protected:
const Kernel::WaitObject& object;
-
- static QString GetResetTypeQString(Kernel::ResetType reset_type);
};
class WaitTreeObjectList : public WaitTreeExpandableItem {
@@ -146,8 +144,6 @@ class WaitTreeEvent : public WaitTreeWaitObject {
public:
explicit WaitTreeEvent(const Kernel::ReadableEvent& object);
~WaitTreeEvent() override;
-
- std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
};
class WaitTreeThreadList : public WaitTreeExpandableItem {
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index d6bb18d24..160613ee1 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -1839,6 +1839,10 @@ void GMainWindow::OnLoadAmiibo() {
return;
}
+ LoadAmiibo(filename);
+}
+
+void GMainWindow::LoadAmiibo(const QString& filename) {
Core::System& system{Core::System::GetInstance()};
Service::SM::ServiceManager& sm = system.ServiceManager();
auto nfc = sm.GetService<Service::NFP::Module::Interface>("nfp:user");
@@ -2189,10 +2193,19 @@ static bool IsSingleFileDropEvent(QDropEvent* event) {
}
void GMainWindow::dropEvent(QDropEvent* event) {
- if (IsSingleFileDropEvent(event) && ConfirmChangeGame()) {
- const QMimeData* mimeData = event->mimeData();
- QString filename = mimeData->urls().at(0).toLocalFile();
- BootGame(filename);
+ if (!IsSingleFileDropEvent(event)) {
+ return;
+ }
+
+ const QMimeData* mime_data = event->mimeData();
+ const QString filename = mime_data->urls().at(0).toLocalFile();
+
+ if (emulation_running && QFileInfo(filename).suffix() == QStringLiteral("bin")) {
+ LoadAmiibo(filename);
+ } else {
+ if (ConfirmChangeGame()) {
+ BootGame(filename);
+ }
}
}
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index fd4b9ccf5..7f46bea2b 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -142,6 +142,7 @@ private:
void ShowTelemetryCallout();
void SetDiscordEnabled(bool state);
+ void LoadAmiibo(const QString& filename);
void SelectAndSetCurrentUser();