summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
m---------externals/nihstro0
-rw-r--r--src/citra/citra.cpp14
-rw-r--r--src/citra/emu_window/emu_window_sdl2.cpp4
-rw-r--r--src/citra_qt/debugger/graphics_vertex_shader.cpp12
-rw-r--r--src/citra_qt/main.cpp7
-rw-r--r--src/citra_qt/main.h2
-rw-r--r--src/common/CMakeLists.txt1
-rw-r--r--src/common/alignment.h22
-rw-r--r--src/common/common_types.h6
-rw-r--r--src/common/logging/backend.cpp1
-rw-r--r--src/common/logging/log.h1
-rw-r--r--src/core/CMakeLists.txt6
-rw-r--r--src/core/hle/function_wrappers.h1
-rw-r--r--src/core/hle/kernel/event.cpp2
-rw-r--r--src/core/hle/kernel/event.h8
-rw-r--r--src/core/hle/kernel/timer.cpp2
-rw-r--r--src/core/hle/kernel/timer.h2
-rw-r--r--src/core/hle/service/apt/apt.cpp4
-rw-r--r--src/core/hle/service/cam/cam.cpp8
-rw-r--r--src/core/hle/service/dsp_dsp.cpp2
-rw-r--r--src/core/hle/service/hid/hid.cpp12
-rw-r--r--src/core/hle/service/ir/ir.cpp4
-rw-r--r--src/core/hle/service/ndm/ndm.cpp47
-rw-r--r--src/core/hle/service/ndm/ndm.h52
-rw-r--r--src/core/hle/service/ndm/ndm_u.cpp (renamed from src/core/hle/service/ndm_u.cpp)23
-rw-r--r--src/core/hle/service/ndm/ndm_u.h (renamed from src/core/hle/service/ndm_u.h)15
-rw-r--r--src/core/hle/service/nwm_uds.cpp2
-rw-r--r--src/core/hle/service/service.cpp5
-rw-r--r--src/core/hle/service/srv.cpp2
-rw-r--r--src/core/hle/service/y2r_u.cpp2
-rw-r--r--src/core/hle/svc.cpp4
-rw-r--r--src/core/hle/svc.h16
-rw-r--r--src/core/hw/gpu.h8
-rw-r--r--src/core/hw/lcd.h8
-rw-r--r--src/video_core/command_processor.cpp25
-rw-r--r--src/video_core/debug_utils/debug_utils.cpp24
-rw-r--r--src/video_core/pica.h12
-rw-r--r--src/video_core/shader/shader.cpp16
-rw-r--r--src/video_core/shader/shader_interpreter.cpp9
-rw-r--r--src/video_core/shader/shader_jit_x64.cpp68
-rw-r--r--src/video_core/shader/shader_jit_x64.h5
41 files changed, 307 insertions, 157 deletions
diff --git a/externals/nihstro b/externals/nihstro
-Subproject 445cba0b2ff8d348368e32698e4760a670260bf
+Subproject 26a0a04a458df2b9ba6e39608bee183d8a0a00e
diff --git a/src/citra/citra.cpp b/src/citra/citra.cpp
index 415b98a05..40e40f192 100644
--- a/src/citra/citra.cpp
+++ b/src/citra/citra.cpp
@@ -19,6 +19,8 @@
#include "common/logging/log.h"
#include "common/logging/backend.h"
#include "common/logging/filter.h"
+#include "common/make_unique.h"
+#include "common/scope_exit.h"
#include "core/settings.h"
#include "core/system.h"
@@ -64,6 +66,7 @@ int main(int argc, char **argv) {
Log::SetFilter(&log_filter);
MicroProfileOnThreadCreate("EmuThread");
+ SCOPE_EXIT({ MicroProfileShutdown(); });
if (boot_filename.empty()) {
LOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified");
@@ -76,12 +79,13 @@ int main(int argc, char **argv) {
GDBStub::ToggleServer(Settings::values.use_gdbstub);
GDBStub::SetServerPort(static_cast<u32>(Settings::values.gdbstub_port));
- EmuWindow_SDL2* emu_window = new EmuWindow_SDL2;
+ std::unique_ptr<EmuWindow_SDL2> emu_window = Common::make_unique<EmuWindow_SDL2>();
VideoCore::g_hw_renderer_enabled = Settings::values.use_hw_renderer;
VideoCore::g_shader_jit_enabled = Settings::values.use_shader_jit;
- System::Init(emu_window);
+ System::Init(emu_window.get());
+ SCOPE_EXIT({ System::Shutdown(); });
Loader::ResultStatus load_result = Loader::LoadFile(boot_filename);
if (Loader::ResultStatus::Success != load_result) {
@@ -93,11 +97,5 @@ int main(int argc, char **argv) {
Core::RunLoop();
}
- System::Shutdown();
-
- delete emu_window;
-
- MicroProfileShutdown();
-
return 0;
}
diff --git a/src/citra/emu_window/emu_window_sdl2.cpp b/src/citra/emu_window/emu_window_sdl2.cpp
index 1fed82e78..924189f4c 100644
--- a/src/citra/emu_window/emu_window_sdl2.cpp
+++ b/src/citra/emu_window/emu_window_sdl2.cpp
@@ -73,6 +73,10 @@ EmuWindow_SDL2::EmuWindow_SDL2() {
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
std::string window_title = Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc);
render_window = SDL_CreateWindow(window_title.c_str(),
diff --git a/src/citra_qt/debugger/graphics_vertex_shader.cpp b/src/citra_qt/debugger/graphics_vertex_shader.cpp
index 4b676f1b1..d648d4640 100644
--- a/src/citra_qt/debugger/graphics_vertex_shader.cpp
+++ b/src/citra_qt/debugger/graphics_vertex_shader.cpp
@@ -179,9 +179,17 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con
AlignToColumn(kOutputColumnWidth);
print_input(output, src1, swizzle.negate_src1, SelectorToString(swizzle.src1_selector));
AlignToColumn(kInputOperandColumnWidth);
- print_input(output, src2, swizzle.negate_src2, SelectorToString(swizzle.src2_selector));
+ if (src_is_inverted) {
+ print_input(output, src2, swizzle.negate_src2, SelectorToString(swizzle.src2_selector));
+ } else {
+ print_input(output, src2, swizzle.negate_src2, SelectorToString(swizzle.src2_selector), true, instr.mad.AddressRegisterName());
+ }
AlignToColumn(kInputOperandColumnWidth);
- print_input(output, src3, swizzle.negate_src3, SelectorToString(swizzle.src3_selector));
+ if (src_is_inverted) {
+ print_input(output, src3, swizzle.negate_src3, SelectorToString(swizzle.src3_selector), true, instr.mad.AddressRegisterName());
+ } else {
+ print_input(output, src3, swizzle.negate_src3, SelectorToString(swizzle.src3_selector));
+ }
AlignToColumn(kInputOperandColumnWidth);
break;
}
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
index 57adbc136..32cceaf7e 100644
--- a/src/citra_qt/main.cpp
+++ b/src/citra_qt/main.cpp
@@ -310,6 +310,7 @@ bool GMainWindow::LoadROM(const std::string& filename) {
void GMainWindow::BootGame(const std::string& filename) {
LOG_INFO(Frontend, "Citra starting...");
+ StoreRecentFile(filename); // Put the filename on top of the list
if (!InitializeSystem())
return;
@@ -374,11 +375,11 @@ void GMainWindow::ShutdownGame() {
emulation_running = false;
}
-void GMainWindow::StoreRecentFile(const QString& filename)
+void GMainWindow::StoreRecentFile(const std::string& filename)
{
QSettings settings;
QStringList recent_files = settings.value("recentFiles").toStringList();
- recent_files.prepend(filename);
+ recent_files.prepend(QString::fromStdString(filename));
recent_files.removeDuplicates();
while (recent_files.size() > max_recent_files_item) {
recent_files.removeLast();
@@ -426,7 +427,6 @@ void GMainWindow::OnMenuLoadFile() {
QString filename = QFileDialog::getOpenFileName(this, tr("Load File"), rom_path, tr("3DS executable (*.3ds *.3dsx *.elf *.axf *.cci *.cxi)"));
if (!filename.isEmpty()) {
settings.setValue("romsPath", QFileInfo(filename).path());
- StoreRecentFile(filename);
BootGame(filename.toLocal8Bit().data());
}
@@ -462,7 +462,6 @@ void GMainWindow::OnMenuRecentFile() {
QFileInfo file_info(filename);
if (file_info.exists()) {
BootGame(filename.toLocal8Bit().data());
- StoreRecentFile(filename); // Put the filename on top of the list
} else {
// Display an error message and remove the file from the list.
QMessageBox::information(this, tr("File not found"), tr("File \"%1\" not found").arg(filename));
diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h
index 945aea0cd..6e4e56689 100644
--- a/src/citra_qt/main.h
+++ b/src/citra_qt/main.h
@@ -75,7 +75,7 @@ private:
*
* @param filename the filename to store
*/
- void StoreRecentFile(const QString& filename);
+ void StoreRecentFile(const std::string& filename);
/**
* Updates the recent files menu.
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 959084cdf..1c9be718f 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -22,6 +22,7 @@ set(SRCS
)
set(HEADERS
+ alignment.h
assert.h
bit_field.h
bit_set.h
diff --git a/src/common/alignment.h b/src/common/alignment.h
new file mode 100644
index 000000000..b77da4a92
--- /dev/null
+++ b/src/common/alignment.h
@@ -0,0 +1,22 @@
+// This file is under the public domain.
+
+#pragma once
+
+#include <cstddef>
+#include <type_traits>
+
+namespace Common {
+
+template <typename T>
+constexpr T AlignUp(T value, size_t size) {
+ static_assert(std::is_unsigned<T>::value, "T must be an unsigned value.");
+ return static_cast<T>(value + (size - value % size) % size);
+}
+
+template <typename T>
+constexpr T AlignDown(T value, size_t size) {
+ static_assert(std::is_unsigned<T>::value, "T must be an unsigned value.");
+ return static_cast<T>(value - value % size);
+}
+
+} // namespace Common
diff --git a/src/common/common_types.h b/src/common/common_types.h
index fa3e0b8d6..9f51dff18 100644
--- a/src/common/common_types.h
+++ b/src/common/common_types.h
@@ -53,9 +53,9 @@ typedef u32 PAddr; ///< Represents a pointer in the ARM11 physical address space
// An inheritable class to disallow the copy constructor and operator= functions
class NonCopyable {
protected:
- NonCopyable() = default;
+ constexpr NonCopyable() = default;
~NonCopyable() = default;
- NonCopyable(NonCopyable&) = delete;
- NonCopyable& operator=(NonCopyable&) = delete;
+ NonCopyable(const NonCopyable&) = delete;
+ NonCopyable& operator=(const NonCopyable&) = delete;
};
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 54291429a..4c86151ab 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -42,6 +42,7 @@ namespace Log {
SUB(Service, AM) \
SUB(Service, PTM) \
SUB(Service, LDR) \
+ SUB(Service, NDM) \
SUB(Service, NIM) \
SUB(Service, NWM) \
SUB(Service, CAM) \
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index 4b01805ae..e4c39c308 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -57,6 +57,7 @@ enum class Class : ClassType {
Service_AM, ///< The AM (Application manager) service
Service_PTM, ///< The PTM (Power status & misc.) service
Service_LDR, ///< The LDR (3ds dll loader) service
+ Service_NDM, ///< The NDM (Network daemon manager) service
Service_NIM, ///< The NIM (Network interface manager) service
Service_NWM, ///< The NWM (Network wlan manager) service
Service_CAM, ///< The CAM (Camera) service
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 35b61dada..3473e2f5b 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -87,7 +87,8 @@ set(SRCS
hle/service/ir/ir_user.cpp
hle/service/ldr_ro.cpp
hle/service/mic_u.cpp
- hle/service/ndm_u.cpp
+ hle/service/ndm/ndm.cpp
+ hle/service/ndm/ndm_u.cpp
hle/service/news/news.cpp
hle/service/news/news_s.cpp
hle/service/news/news_u.cpp
@@ -218,7 +219,8 @@ set(HEADERS
hle/service/ir/ir_user.h
hle/service/ldr_ro.h
hle/service/mic_u.h
- hle/service/ndm_u.h
+ hle/service/ndm/ndm.h
+ hle/service/ndm/ndm_u.h
hle/service/news/news.h
hle/service/news/news_s.h
hle/service/news/news_u.h
diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h
index 882a51df1..4d718b681 100644
--- a/src/core/hle/function_wrappers.h
+++ b/src/core/hle/function_wrappers.h
@@ -10,6 +10,7 @@
#include "core/memory.h"
#include "core/hle/hle.h"
#include "core/hle/result.h"
+#include "core/hle/svc.h"
namespace HLE {
diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp
index 53feebbc0..2b7c6992a 100644
--- a/src/core/hle/kernel/event.cpp
+++ b/src/core/hle/kernel/event.cpp
@@ -35,7 +35,7 @@ void Event::Acquire() {
ASSERT_MSG(!ShouldWait(), "object unavailable!");
// Release the event if it's not sticky...
- if (reset_type != RESETTYPE_STICKY)
+ if (reset_type != ResetType::Sticky)
signaled = false;
}
diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h
index 89d405236..73d0da419 100644
--- a/src/core/hle/kernel/event.h
+++ b/src/core/hle/kernel/event.h
@@ -7,10 +7,16 @@
#include "common/common_types.h"
#include "core/hle/kernel/kernel.h"
-#include "core/hle/svc.h"
namespace Kernel {
+enum class ResetType {
+ OneShot,
+ Sticky,
+ Pulse,
+};
+
+
class Event final : public WaitObject {
public:
/**
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp
index ce6bbd719..b8daaeede 100644
--- a/src/core/hle/kernel/timer.cpp
+++ b/src/core/hle/kernel/timer.cpp
@@ -43,7 +43,7 @@ bool Timer::ShouldWait() {
void Timer::Acquire() {
ASSERT_MSG( !ShouldWait(), "object unavailable!");
- if (reset_type == RESETTYPE_ONESHOT)
+ if (reset_type == ResetType::OneShot)
signaled = false;
}
diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h
index 540e4e187..b1db60e8f 100644
--- a/src/core/hle/kernel/timer.h
+++ b/src/core/hle/kernel/timer.h
@@ -6,8 +6,8 @@
#include "common/common_types.h"
+#include "core/hle/kernel/event.h"
#include "core/hle/kernel/kernel.h"
-#include "core/hle/svc.h"
namespace Kernel {
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index 98c72fc32..a49365287 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.cpp
@@ -434,8 +434,8 @@ void Init() {
cpu_percent = 0;
// TODO(bunnei): Check if these are created in Initialize or on APT process startup.
- notification_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Notification");
- parameter_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Start");
+ notification_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "APT_U:Notification");
+ parameter_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "APT_U:Start");
next_parameter.signal = static_cast<u32>(SignalType::AppJustStarted);
next_parameter.destination_id = 0x300;
diff --git a/src/core/hle/service/cam/cam.cpp b/src/core/hle/service/cam/cam.cpp
index 4d714037f..9df48a650 100644
--- a/src/core/hle/service/cam/cam.cpp
+++ b/src/core/hle/service/cam/cam.cpp
@@ -293,10 +293,10 @@ void Init() {
AddService(new CAM_S_Interface);
AddService(new CAM_U_Interface);
- completion_event_cam1 = Kernel::Event::Create(RESETTYPE_ONESHOT, "CAM_U::completion_event_cam1");
- completion_event_cam2 = Kernel::Event::Create(RESETTYPE_ONESHOT, "CAM_U::completion_event_cam2");
- interrupt_error_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "CAM_U::interrupt_error_event");
- vsync_interrupt_error_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "CAM_U::vsync_interrupt_error_event");
+ completion_event_cam1 = Kernel::Event::Create(ResetType::OneShot, "CAM_U::completion_event_cam1");
+ completion_event_cam2 = Kernel::Event::Create(ResetType::OneShot, "CAM_U::completion_event_cam2");
+ interrupt_error_event = Kernel::Event::Create(ResetType::OneShot, "CAM_U::interrupt_error_event");
+ vsync_interrupt_error_event = Kernel::Event::Create(ResetType::OneShot, "CAM_U::vsync_interrupt_error_event");
}
void Shutdown() {
diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp
index 3ba24d466..08e437125 100644
--- a/src/core/hle/service/dsp_dsp.cpp
+++ b/src/core/hle/service/dsp_dsp.cpp
@@ -457,7 +457,7 @@ const Interface::FunctionInfo FunctionTable[] = {
// Interface class
Interface::Interface() {
- semaphore_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "DSP_DSP::semaphore_event");
+ semaphore_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "DSP_DSP::semaphore_event");
read_pipe_count = 0;
Register(FunctionTable);
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 11d7e69a1..cb4fd38e2 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -68,7 +68,7 @@ void Update() {
mem->pad.current_state.hex = state.hex;
mem->pad.index = next_pad_index;
- next_touch_index = (next_touch_index + 1) % mem->pad.entries.size();
+ next_pad_index = (next_pad_index + 1) % mem->pad.entries.size();
// Get the previous Pad state
u32 last_entry_index = (mem->pad.index - 1) % mem->pad.entries.size();
@@ -201,11 +201,11 @@ void Init() {
next_touch_index = 0;
// Create event handles
- event_pad_or_touch_1 = Event::Create(RESETTYPE_ONESHOT, "HID:EventPadOrTouch1");
- event_pad_or_touch_2 = Event::Create(RESETTYPE_ONESHOT, "HID:EventPadOrTouch2");
- event_accelerometer = Event::Create(RESETTYPE_ONESHOT, "HID:EventAccelerometer");
- event_gyroscope = Event::Create(RESETTYPE_ONESHOT, "HID:EventGyroscope");
- event_debug_pad = Event::Create(RESETTYPE_ONESHOT, "HID:EventDebugPad");
+ event_pad_or_touch_1 = Event::Create(ResetType::OneShot, "HID:EventPadOrTouch1");
+ event_pad_or_touch_2 = Event::Create(ResetType::OneShot, "HID:EventPadOrTouch2");
+ event_accelerometer = Event::Create(ResetType::OneShot, "HID:EventAccelerometer");
+ event_gyroscope = Event::Create(ResetType::OneShot, "HID:EventGyroscope");
+ event_debug_pad = Event::Create(ResetType::OneShot, "HID:EventDebugPad");
}
void Shutdown() {
diff --git a/src/core/hle/service/ir/ir.cpp b/src/core/hle/service/ir/ir.cpp
index c2121cb2e..505c441c6 100644
--- a/src/core/hle/service/ir/ir.cpp
+++ b/src/core/hle/service/ir/ir.cpp
@@ -99,8 +99,8 @@ void Init() {
transfer_shared_memory = nullptr;
// Create event handle(s)
- handle_event = Event::Create(RESETTYPE_ONESHOT, "IR:HandleEvent");
- conn_status_event = Event::Create(RESETTYPE_ONESHOT, "IR:ConnectionStatusEvent");
+ handle_event = Event::Create(ResetType::OneShot, "IR:HandleEvent");
+ conn_status_event = Event::Create(ResetType::OneShot, "IR:ConnectionStatusEvent");
}
void Shutdown() {
diff --git a/src/core/hle/service/ndm/ndm.cpp b/src/core/hle/service/ndm/ndm.cpp
new file mode 100644
index 000000000..47076a7b8
--- /dev/null
+++ b/src/core/hle/service/ndm/ndm.cpp
@@ -0,0 +1,47 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/common_types.h"
+#include "common/logging/log.h"
+#include "core/hle/service/service.h"
+#include "core/hle/service/ndm/ndm.h"
+#include "core/hle/service/ndm/ndm_u.h"
+
+namespace Service {
+namespace NDM {
+
+void SuspendDaemons(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ LOG_WARNING(Service_NDM, "(STUBBED) bit_mask=0x%08X ", cmd_buff[1]);
+
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+}
+
+void ResumeDaemons(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ LOG_WARNING(Service_NDM, "(STUBBED) bit_mask=0x%08X ", cmd_buff[1]);
+
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+}
+
+void OverrideDefaultDaemons(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ LOG_WARNING(Service_NDM, "(STUBBED) bit_mask=0x%08X ", cmd_buff[1]);
+
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+}
+
+void Init() {
+ AddService(new NDM_U_Interface);
+}
+
+void Shutdown() {
+
+}
+
+}// namespace NDM
+}// namespace Service
diff --git a/src/core/hle/service/ndm/ndm.h b/src/core/hle/service/ndm/ndm.h
new file mode 100644
index 000000000..734730f8c
--- /dev/null
+++ b/src/core/hle/service/ndm/ndm.h
@@ -0,0 +1,52 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "common/common_types.h"
+
+namespace Service {
+
+class Interface;
+
+namespace NDM {
+
+/**
+ * SuspendDaemons
+ * Inputs:
+ * 0 : Command header (0x00020082)
+ * 1 : Daemon bit mask
+ * Outputs:
+ * 1 : Result, 0 on success, otherwise error code
+ */
+void SuspendDaemons(Service::Interface* self);
+
+/**
+ * ResumeDaemons
+ * Inputs:
+ * 0 : Command header (0x00020082)
+ * 1 : Daemon bit mask
+ * Outputs:
+ * 1 : Result, 0 on success, otherwise error code
+ */
+void ResumeDaemons(Service::Interface* self);
+
+/**
+ * OverrideDefaultDaemons
+ * Inputs:
+ * 0 : Command header (0x00020082)
+ * 1 : Daemon bit mask
+ * Outputs:
+ * 1 : Result, 0 on success, otherwise error code
+ */
+void OverrideDefaultDaemons(Service::Interface* self);
+
+/// Initialize NDM service
+void Init();
+
+/// Shutdown NDM service
+void Shutdown();
+
+}// namespace NDM
+}// namespace Service
diff --git a/src/core/hle/service/ndm_u.cpp b/src/core/hle/service/ndm/ndm_u.cpp
index 8fdf1ef90..bf95cc7aa 100644
--- a/src/core/hle/service/ndm_u.cpp
+++ b/src/core/hle/service/ndm/ndm_u.cpp
@@ -2,12 +2,11 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include "core/hle/service/ndm_u.h"
+#include "core/hle/service/ndm/ndm.h"
+#include "core/hle/service/ndm/ndm_u.h"
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// Namespace NDM_U
-
-namespace NDM_U {
+namespace Service {
+namespace NDM {
const Interface::FunctionInfo FunctionTable[] = {
{0x00010042, nullptr, "EnterExclusiveState"},
@@ -15,8 +14,8 @@ const Interface::FunctionInfo FunctionTable[] = {
{0x00030000, nullptr, "QueryExclusiveMode"},
{0x00040002, nullptr, "LockState"},
{0x00050002, nullptr, "UnlockState"},
- {0x00060040, nullptr, "SuspendDaemons"},
- {0x00070040, nullptr, "ResumeDaemons"},
+ {0x00060040, SuspendDaemons, "SuspendDaemons"},
+ {0x00070040, ResumeDaemons, "ResumeDaemons"},
{0x00080040, nullptr, "DisableWifiUsage"},
{0x00090000, nullptr, "EnableWifiUsage"},
{0x000A0000, nullptr, "GetCurrentState"},
@@ -29,17 +28,15 @@ const Interface::FunctionInfo FunctionTable[] = {
{0x00110000, nullptr, "GetScanInterval"},
{0x00120040, nullptr, "SetRetryInterval"},
{0x00130000, nullptr, "GetRetryInterval"},
- {0x00140040, nullptr, "OverrideDefaultDaemons"},
+ {0x00140040, OverrideDefaultDaemons, "OverrideDefaultDaemons"},
{0x00150000, nullptr, "ResetDefaultDaemons"},
{0x00160000, nullptr, "GetDefaultDaemons"},
{0x00170000, nullptr, "ClearHalfAwakeMacFilter"},
};
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// Interface class
-
-Interface::Interface() {
+NDM_U_Interface::NDM_U_Interface() {
Register(FunctionTable);
}
-} // namespace
+} // namespace NDM
+} // namespace Service
diff --git a/src/core/hle/service/ndm_u.h b/src/core/hle/service/ndm/ndm_u.h
index 51c4b3902..d567abc84 100644
--- a/src/core/hle/service/ndm_u.h
+++ b/src/core/hle/service/ndm/ndm_u.h
@@ -6,20 +6,17 @@
#include "core/hle/service/service.h"
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// Namespace NDM
+namespace Service {
+namespace NDM {
-// No idea what this is
-
-namespace NDM_U {
-
-class Interface : public Service::Interface {
+class NDM_U_Interface : public Service::Interface {
public:
- Interface();
+ NDM_U_Interface();
std::string GetPortName() const override {
return "ndm:u";
}
};
-} // namespace
+} // namespace NDM
+} // namespace Service
diff --git a/src/core/hle/service/nwm_uds.cpp b/src/core/hle/service/nwm_uds.cpp
index dc80984b2..ae4640409 100644
--- a/src/core/hle/service/nwm_uds.cpp
+++ b/src/core/hle/service/nwm_uds.cpp
@@ -138,7 +138,7 @@ const Interface::FunctionInfo FunctionTable[] = {
// Interface class
Interface::Interface() {
- handle_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "NWM_UDS::handle_event");
+ handle_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "NWM_UDS::handle_event");
Register(FunctionTable);
}
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 0de0b13a3..35b648409 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -16,7 +16,6 @@
#include "core/hle/service/http_c.h"
#include "core/hle/service/ldr_ro.h"
#include "core/hle/service/mic_u.h"
-#include "core/hle/service/ndm_u.h"
#include "core/hle/service/ns_s.h"
#include "core/hle/service/nwm_uds.h"
#include "core/hle/service/pm_app.h"
@@ -35,6 +34,7 @@
#include "core/hle/service/cfg/cfg.h"
#include "core/hle/service/hid/hid.h"
#include "core/hle/service/ir/ir.h"
+#include "core/hle/service/ndm/ndm.h"
#include "core/hle/service/news/news.h"
#include "core/hle/service/nim/nim.h"
#include "core/hle/service/ptm/ptm.h"
@@ -114,6 +114,7 @@ void Init() {
Service::HID::Init();
Service::IR::Init();
Service::NEWS::Init();
+ Service::NDM::Init();
Service::NIM::Init();
Service::PTM::Init();
@@ -126,7 +127,6 @@ void Init() {
AddService(new HTTP_C::Interface);
AddService(new LDR_RO::Interface);
AddService(new MIC_U::Interface);
- AddService(new NDM_U::Interface);
AddService(new NS_S::Interface);
AddService(new NWM_UDS::Interface);
AddService(new PM_APP::Interface);
@@ -141,6 +141,7 @@ void Init() {
void Shutdown() {
Service::PTM::Shutdown();
+ Service::NDM::Shutdown();
Service::NIM::Shutdown();
Service::NEWS::Shutdown();
Service::IR::Shutdown();
diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp
index 41fc3437b..aae955bf8 100644
--- a/src/core/hle/service/srv.cpp
+++ b/src/core/hle/service/srv.cpp
@@ -25,7 +25,7 @@ static void GetProcSemaphore(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
// TODO(bunnei): Change to a semaphore once these have been implemented
- event_handle = Kernel::Event::Create(RESETTYPE_ONESHOT, "SRV:Event");
+ event_handle = Kernel::Event::Create(Kernel::ResetType::OneShot, "SRV:Event");
event_handle->Clear();
cmd_buff[1] = 0; // No error
diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp
index a495441a4..22f373adf 100644
--- a/src/core/hle/service/y2r_u.cpp
+++ b/src/core/hle/service/y2r_u.cpp
@@ -424,7 +424,7 @@ const Interface::FunctionInfo FunctionTable[] = {
// Interface class
Interface::Interface() {
- completion_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "Y2R:Completed");
+ completion_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "Y2R:Completed");
std::memset(&conversion, 0, sizeof(conversion));
Register(FunctionTable);
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 7a39b101d..ae54afb1c 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -661,7 +661,7 @@ static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, u32
static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) {
using Kernel::Event;
- SharedPtr<Event> evt = Kernel::Event::Create(static_cast<ResetType>(reset_type));
+ SharedPtr<Event> evt = Event::Create(static_cast<Kernel::ResetType>(reset_type));
CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(evt)));
LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X",
@@ -707,7 +707,7 @@ static ResultCode ClearEvent(Handle handle) {
static ResultCode CreateTimer(Handle* out_handle, u32 reset_type) {
using Kernel::Timer;
- SharedPtr<Timer> timer = Timer::Create(static_cast<ResetType>(reset_type));
+ SharedPtr<Timer> timer = Timer::Create(static_cast<Kernel::ResetType>(reset_type));
CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(timer)));
LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X",
diff --git a/src/core/hle/svc.h b/src/core/hle/svc.h
index 4b9c71e06..818973eb6 100644
--- a/src/core/hle/svc.h
+++ b/src/core/hle/svc.h
@@ -20,22 +20,6 @@ struct PageInfo {
u32 flags;
};
-enum ResetType {
- RESETTYPE_ONESHOT,
- RESETTYPE_STICKY,
- RESETTYPE_PULSE,
- RESETTYPE_MAX_BIT = (1u << 31),
-};
-
-enum ArbitrationType {
- ARBITRATIONTYPE_SIGNAL,
- ARBITRATIONTYPE_WAIT_IF_LESS_THAN,
- ARBITRATIONTYPE_DECREMENT_AND_WAIT_IF_LESS_THAN,
- ARBITRATIONTYPE_WAIT_IF_LESS_THAN_WITH_TIMEOUT,
- ARBITRATIONTYPE_DECREMENT_AND_WAIT_IF_LESS_THAN_WITH_TIMEOUT,
- ARBITRATIONTYPE_MAX_BIT = (1u << 31)
-};
-
////////////////////////////////////////////////////////////////////////////////////////////////////
// Namespace SVC
diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h
index 2e3a9f779..a00adbf53 100644
--- a/src/core/hw/gpu.h
+++ b/src/core/hw/gpu.h
@@ -263,17 +263,17 @@ struct Regs {
INSERT_PADDING_WORDS(0x9c3);
- static inline size_t NumIds() {
+ static constexpr size_t NumIds() {
return sizeof(Regs) / sizeof(u32);
}
- u32& operator [] (int index) const {
- u32* content = (u32*)this;
+ const u32& operator [] (int index) const {
+ const u32* content = reinterpret_cast<const u32*>(this);
return content[index];
}
u32& operator [] (int index) {
- u32* content = (u32*)this;
+ u32* content = reinterpret_cast<u32*>(this);
return content[index];
}
diff --git a/src/core/hw/lcd.h b/src/core/hw/lcd.h
index bcce6d8cf..3dd877fbf 100644
--- a/src/core/hw/lcd.h
+++ b/src/core/hw/lcd.h
@@ -38,17 +38,17 @@ struct Regs {
u32 backlight_bottom;
INSERT_PADDING_WORDS(0x16F);
- static inline size_t NumIds() {
+ static constexpr size_t NumIds() {
return sizeof(Regs) / sizeof(u32);
}
- u32& operator [] (int index) const {
- u32* content = (u32*)this;
+ const u32& operator [] (int index) const {
+ const u32* content = reinterpret_cast<const u32*>(this);
return content[index];
}
u32& operator [] (int index) {
- u32* content = (u32*)this;
+ u32* content = reinterpret_cast<u32*>(this);
return content[index];
}
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp
index 2274dfa66..4b59984ad 100644
--- a/src/video_core/command_processor.cpp
+++ b/src/video_core/command_processor.cpp
@@ -5,6 +5,7 @@
#include <cmath>
#include <boost/range/algorithm/fill.hpp>
+#include "common/alignment.h"
#include "common/microprofile.h"
#include "common/profiler.h"
@@ -199,7 +200,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
for (int loader = 0; loader < 12; ++loader) {
const auto& loader_config = attribute_config.attribute_loaders[loader];
- u32 load_address = base_address + loader_config.data_offset;
+ u32 offset = 0;
// TODO: What happens if a loader overwrites a previous one's data?
for (unsigned component = 0; component < loader_config.component_count; ++component) {
@@ -210,15 +211,18 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
u32 attribute_index = loader_config.GetComponent(component);
if (attribute_index < 12) {
- vertex_attribute_sources[attribute_index] = load_address;
+ int element_size = attribute_config.GetElementSizeInBytes(attribute_index);
+ offset = Common::AlignUp(offset, element_size);
+ vertex_attribute_sources[attribute_index] = base_address + loader_config.data_offset + offset;
vertex_attribute_strides[attribute_index] = static_cast<u32>(loader_config.byte_count);
vertex_attribute_formats[attribute_index] = attribute_config.GetFormat(attribute_index);
vertex_attribute_elements[attribute_index] = attribute_config.GetNumElements(attribute_index);
- vertex_attribute_element_size[attribute_index] = attribute_config.GetElementSizeInBytes(attribute_index);
- load_address += attribute_config.GetStride(attribute_index);
+ vertex_attribute_element_size[attribute_index] = element_size;
+ offset += attribute_config.GetStride(attribute_index);
} else if (attribute_index < 16) {
// Attribute ids 12, 13, 14 and 15 signify 4, 8, 12 and 16-byte paddings, respectively
- load_address += (attribute_index - 11) * 4;
+ offset = Common::AlignUp(offset, 4);
+ offset += (attribute_index - 11) * 4;
} else {
UNREACHABLE(); // This is truly unreachable due to the number of bits for each component
}
@@ -230,7 +234,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
const auto& index_info = regs.index_array;
const u8* index_address_8 = Memory::GetPhysicalPointer(base_address + index_info.offset);
- const u16* index_address_16 = (u16*)index_address_8;
+ const u16* index_address_16 = reinterpret_cast<const u16*>(index_address_8);
bool index_u16 = index_info.format != 0;
#if PICA_DUMP_GEOMETRY
@@ -341,10 +345,11 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
: (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::SHORT) ? 2 : 1);
}
- const float srcval = (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::BYTE) ? *(s8*)srcdata :
- (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::UBYTE) ? *(u8*)srcdata :
- (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::SHORT) ? *(s16*)srcdata :
- *(float*)srcdata;
+ const float srcval =
+ (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::BYTE) ? *reinterpret_cast<const s8*>(srcdata) :
+ (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::UBYTE) ? *reinterpret_cast<const u8*>(srcdata) :
+ (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::SHORT) ? *reinterpret_cast<const s16*>(srcdata) :
+ *reinterpret_cast<const float*>(srcdata);
input.attr[i][comp] = float24::FromFloat32(srcval);
LOG_TRACE(HW_GPU, "Loaded component %x of attribute %x for vertex %x (index %x) from 0x%08x + 0x%08x + 0x%04x: %f",
diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp
index 271e81ca1..bac6d69c7 100644
--- a/src/video_core/debug_utils/debug_utils.cpp
+++ b/src/video_core/debug_utils/debug_utils.cpp
@@ -117,13 +117,13 @@ void GeometryDumper::Dump() {
void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, const Shader::ShaderSetup& setup, const Regs::VSOutputAttributes* output_attributes)
{
struct StuffToWrite {
- u8* pointer;
+ const u8* pointer;
u32 size;
};
std::vector<StuffToWrite> writing_queue;
u32 write_offset = 0;
- auto QueueForWriting = [&writing_queue,&write_offset](u8* pointer, u32 size) {
+ auto QueueForWriting = [&writing_queue,&write_offset](const u8* pointer, u32 size) {
writing_queue.push_back({pointer, size});
u32 old_write_offset = write_offset;
write_offset += size;
@@ -228,27 +228,27 @@ void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, c
DVLPHeader dvlp{ DVLPHeader::MAGIC_WORD };
DVLEHeader dvle{ DVLEHeader::MAGIC_WORD };
- QueueForWriting((u8*)&dvlb, sizeof(dvlb));
- u32 dvlp_offset = QueueForWriting((u8*)&dvlp, sizeof(dvlp));
- dvlb.dvle_offset = QueueForWriting((u8*)&dvle, sizeof(dvle));
+ QueueForWriting(reinterpret_cast<const u8*>(&dvlb), sizeof(dvlb));
+ u32 dvlp_offset = QueueForWriting(reinterpret_cast<const u8*>(&dvlp), sizeof(dvlp));
+ dvlb.dvle_offset = QueueForWriting(reinterpret_cast<const u8*>(&dvle), sizeof(dvle));
// TODO: Reduce the amount of binary code written to relevant portions
dvlp.binary_offset = write_offset - dvlp_offset;
dvlp.binary_size_words = setup.program_code.size();
- QueueForWriting((u8*)setup.program_code.data(), setup.program_code.size() * sizeof(u32));
+ QueueForWriting(reinterpret_cast<const u8*>(setup.program_code.data()), setup.program_code.size() * sizeof(u32));
dvlp.swizzle_info_offset = write_offset - dvlp_offset;
dvlp.swizzle_info_num_entries = setup.swizzle_data.size();
u32 dummy = 0;
for (unsigned int i = 0; i < setup.swizzle_data.size(); ++i) {
- QueueForWriting((u8*)&setup.swizzle_data[i], sizeof(setup.swizzle_data[i]));
- QueueForWriting((u8*)&dummy, sizeof(dummy));
+ QueueForWriting(reinterpret_cast<const u8*>(&setup.swizzle_data[i]), sizeof(setup.swizzle_data[i]));
+ QueueForWriting(reinterpret_cast<const u8*>(&dummy), sizeof(dummy));
}
dvle.main_offset_words = config.main_offset;
dvle.output_register_table_offset = write_offset - dvlb.dvle_offset;
dvle.output_register_table_size = static_cast<u32>(output_info_table.size());
- QueueForWriting((u8*)output_info_table.data(), static_cast<u32>(output_info_table.size() * sizeof(OutputRegisterInfo)));
+ QueueForWriting(reinterpret_cast<const u8*>(output_info_table.data()), static_cast<u32>(output_info_table.size() * sizeof(OutputRegisterInfo)));
// TODO: Create a label table for "main"
@@ -292,14 +292,14 @@ void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, c
dvle.constant_table_offset = write_offset - dvlb.dvle_offset;
dvle.constant_table_size = constant_table.size();
for (const auto& constant : constant_table) {
- QueueForWriting((uint8_t*)&constant, sizeof(constant));
+ QueueForWriting(reinterpret_cast<const u8*>(&constant), sizeof(constant));
}
// Write data to file
std::ofstream file(filename, std::ios_base::out | std::ios_base::binary);
- for (auto& chunk : writing_queue) {
- file.write((char*)chunk.pointer, chunk.size);
+ for (const auto& chunk : writing_queue) {
+ file.write(reinterpret_cast<const char*>(chunk.pointer), chunk.size);
}
}
diff --git a/src/video_core/pica.h b/src/video_core/pica.h
index 2e0c33201..337cff8ce 100644
--- a/src/video_core/pica.h
+++ b/src/video_core/pica.h
@@ -117,8 +117,8 @@ struct Regs {
INSERT_PADDING_WORDS(0x11);
union {
- BitField< 0, 16, u32> x;
- BitField<16, 16, u32> y;
+ BitField< 0, 10, s32> x;
+ BitField<16, 10, s32> y;
} viewport_corner;
INSERT_PADDING_WORDS(0x17);
@@ -1221,17 +1221,17 @@ struct Regs {
// Used for debugging purposes, so performance is not an issue here
static std::string GetCommandName(int index);
- static inline size_t NumIds() {
+ static constexpr size_t NumIds() {
return sizeof(Regs) / sizeof(u32);
}
- u32& operator [] (int index) const {
- u32* content = (u32*)this;
+ const u32& operator [] (int index) const {
+ const u32* content = reinterpret_cast<const u32*>(this);
return content[index];
}
u32& operator [] (int index) {
- u32* content = (u32*)this;
+ u32* content = reinterpret_cast<u32*>(this);
return content[index];
}
diff --git a/src/video_core/shader/shader.cpp b/src/video_core/shader/shader.cpp
index 5e8930476..509558fc0 100644
--- a/src/video_core/shader/shader.cpp
+++ b/src/video_core/shader/shader.cpp
@@ -32,6 +32,12 @@ namespace Shader {
static std::unordered_map<u64, CompiledShader*> shader_map;
static JitCompiler jit;
static CompiledShader* jit_shader;
+
+static void ClearCache() {
+ shader_map.clear();
+ jit.Clear();
+ LOG_INFO(HW_GPU, "Shader JIT cache cleared");
+}
#endif // ARCHITECTURE_x86_64
void Setup(UnitState<false>& state) {
@@ -45,6 +51,12 @@ void Setup(UnitState<false>& state) {
if (iter != shader_map.end()) {
jit_shader = iter->second;
} else {
+ // Check if remaining JIT code space is enough for at least one more (massive) shader
+ if (jit.GetSpaceLeft() < jit_shader_size) {
+ // If not, clear the cache of all previously compiled shaders
+ ClearCache();
+ }
+
jit_shader = jit.Compile();
shader_map.emplace(cache_key, jit_shader);
}
@@ -54,7 +66,7 @@ void Setup(UnitState<false>& state) {
void Shutdown() {
#ifdef ARCHITECTURE_x86_64
- shader_map.clear();
+ ClearCache();
#endif // ARCHITECTURE_x86_64
}
@@ -135,7 +147,7 @@ OutputVertex Run(UnitState<false>& state, const InputVertex& input, int num_attr
std::fmin(std::fabs(ret.color[i].ToFloat32()), 1.0f));
}
- LOG_TRACE(Render_Software, "Output vertex: pos(%.2f, %.2f, %.2f, %.2f), quat(%.2f, %.2f, %.2f, %.2f), "
+ LOG_TRACE(HW_GPU, "Output vertex: pos(%.2f, %.2f, %.2f, %.2f), quat(%.2f, %.2f, %.2f, %.2f), "
"col(%.2f, %.2f, %.2f, %.2f), tc0(%.2f, %.2f), view(%.2f, %.2f, %.2f)",
ret.pos.x.ToFloat32(), ret.pos.y.ToFloat32(), ret.pos.z.ToFloat32(), ret.pos.w.ToFloat32(),
ret.quat.x.ToFloat32(), ret.quat.y.ToFloat32(), ret.quat.z.ToFloat32(), ret.quat.w.ToFloat32(),
diff --git a/src/video_core/shader/shader_interpreter.cpp b/src/video_core/shader/shader_interpreter.cpp
index 79fcc56b9..02e1a1cb1 100644
--- a/src/video_core/shader/shader_interpreter.cpp
+++ b/src/video_core/shader/shader_interpreter.cpp
@@ -409,13 +409,16 @@ void RunInterpreter(UnitState<Debug>& state) {
{
if ((instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MAD) ||
(instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI)) {
- const SwizzlePattern& swizzle = *(SwizzlePattern*)&swizzle_data[instr.mad.operand_desc_id];
+ const SwizzlePattern& swizzle = *reinterpret_cast<const SwizzlePattern*>(&swizzle_data[instr.mad.operand_desc_id]);
bool is_inverted = (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI);
+ const int address_offset = (instr.mad.address_register_index == 0)
+ ? 0 : state.address_registers[instr.mad.address_register_index - 1];
+
const float24* src1_ = LookupSourceRegister(instr.mad.GetSrc1(is_inverted));
- const float24* src2_ = LookupSourceRegister(instr.mad.GetSrc2(is_inverted));
- const float24* src3_ = LookupSourceRegister(instr.mad.GetSrc3(is_inverted));
+ const float24* src2_ = LookupSourceRegister(instr.mad.GetSrc2(is_inverted) + (!is_inverted * address_offset));
+ const float24* src3_ = LookupSourceRegister(instr.mad.GetSrc3(is_inverted) + ( is_inverted * address_offset));
const bool negate_src1 = ((bool)swizzle.negate_src1 != false);
const bool negate_src2 = ((bool)swizzle.negate_src2 != false);
diff --git a/src/video_core/shader/shader_jit_x64.cpp b/src/video_core/shader/shader_jit_x64.cpp
index 5083d7e54..dffe051ef 100644
--- a/src/video_core/shader/shader_jit_x64.cpp
+++ b/src/video_core/shader/shader_jit_x64.cpp
@@ -160,40 +160,41 @@ void JitCompiler::Compile_SwizzleSrc(Instruction instr, unsigned src_num, Source
ASSERT_MSG(src_offset == src_offset_disp, "Source register offset too large for int type");
unsigned operand_desc_id;
+
+ const bool is_inverted = (0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed));
+
+ unsigned address_register_index;
+ unsigned offset_src;
+
if (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MAD ||
instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI) {
- // The MAD and MADI instructions do not use the address offset registers, so loading the
- // source is a bit simpler here
-
operand_desc_id = instr.mad.operand_desc_id;
-
- // Load the source
- MOVAPS(dest, MDisp(src_ptr, src_offset_disp));
+ offset_src = is_inverted ? 3 : 2;
+ address_register_index = instr.mad.address_register_index;
} else {
operand_desc_id = instr.common.operand_desc_id;
+ offset_src = is_inverted ? 2 : 1;
+ address_register_index = instr.common.address_register_index;
+ }
- const bool is_inverted = (0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed));
- unsigned offset_src = is_inverted ? 2 : 1;
-
- if (src_num == offset_src && instr.common.address_register_index != 0) {
- switch (instr.common.address_register_index) {
- case 1: // address offset 1
- MOVAPS(dest, MComplex(src_ptr, ADDROFFS_REG_0, SCALE_1, src_offset_disp));
- break;
- case 2: // address offset 2
- MOVAPS(dest, MComplex(src_ptr, ADDROFFS_REG_1, SCALE_1, src_offset_disp));
- break;
- case 3: // address offset 3
- MOVAPS(dest, MComplex(src_ptr, LOOPCOUNT_REG, SCALE_1, src_offset_disp));
- break;
- default:
- UNREACHABLE();
- break;
- }
- } else {
- // Load the source
- MOVAPS(dest, MDisp(src_ptr, src_offset_disp));
+ if (src_num == offset_src && address_register_index != 0) {
+ switch (address_register_index) {
+ case 1: // address offset 1
+ MOVAPS(dest, MComplex(src_ptr, ADDROFFS_REG_0, SCALE_1, src_offset_disp));
+ break;
+ case 2: // address offset 2
+ MOVAPS(dest, MComplex(src_ptr, ADDROFFS_REG_1, SCALE_1, src_offset_disp));
+ break;
+ case 3: // address offset 3
+ MOVAPS(dest, MComplex(src_ptr, LOOPCOUNT_REG, SCALE_1, src_offset_disp));
+ break;
+ default:
+ UNREACHABLE();
+ break;
}
+ } else {
+ // Load the source
+ MOVAPS(dest, MDisp(src_ptr, src_offset_disp));
}
SwizzlePattern swiz = { g_state.vs.swizzle_data[operand_desc_id] };
@@ -644,7 +645,8 @@ void JitCompiler::Compile_MAD(Instruction instr) {
}
void JitCompiler::Compile_IF(Instruction instr) {
- ASSERT_MSG(instr.flow_control.dest_offset > *offset_ptr, "Backwards if-statements not supported");
+ ASSERT_MSG(instr.flow_control.dest_offset > *offset_ptr, "Backwards if-statements (%d -> %d) not supported",
+ *offset_ptr, instr.flow_control.dest_offset.Value());
// Evaluate the "IF" condition
if (instr.opcode.Value() == OpCode::Id::IFU) {
@@ -675,7 +677,8 @@ void JitCompiler::Compile_IF(Instruction instr) {
}
void JitCompiler::Compile_LOOP(Instruction instr) {
- ASSERT_MSG(instr.flow_control.dest_offset > *offset_ptr, "Backwards loops not supported");
+ ASSERT_MSG(instr.flow_control.dest_offset > *offset_ptr, "Backwards loops (%d -> %d) not supported",
+ *offset_ptr, instr.flow_control.dest_offset.Value());
ASSERT_MSG(!looping, "Nested loops not supported");
looping = true;
@@ -703,7 +706,8 @@ void JitCompiler::Compile_LOOP(Instruction instr) {
}
void JitCompiler::Compile_JMP(Instruction instr) {
- ASSERT_MSG(instr.flow_control.dest_offset > *offset_ptr, "Backwards jumps not supported");
+ ASSERT_MSG(instr.flow_control.dest_offset > *offset_ptr, "Backwards jumps (%d -> %d) not supported",
+ *offset_ptr, instr.flow_control.dest_offset.Value());
if (instr.opcode.Value() == OpCode::Id::JMPC)
Compile_EvaluateCondition(instr);
@@ -747,7 +751,7 @@ void JitCompiler::Compile_NextInstr(unsigned* offset) {
} else {
// Unhandled instruction
LOG_CRITICAL(HW_GPU, "Unhandled instruction: 0x%02x (0x%08x)",
- instr.opcode.Value().EffectiveOpCode(), instr.hex);
+ instr.opcode.Value().EffectiveOpCode(), instr.hex);
}
}
@@ -786,7 +790,7 @@ CompiledShader* JitCompiler::Compile() {
}
JitCompiler::JitCompiler() {
- AllocCodeSpace(1024 * 1024 * 4);
+ AllocCodeSpace(jit_cache_size);
}
void JitCompiler::Clear() {
diff --git a/src/video_core/shader/shader_jit_x64.h b/src/video_core/shader/shader_jit_x64.h
index 5ad2d9606..5357c964b 100644
--- a/src/video_core/shader/shader_jit_x64.h
+++ b/src/video_core/shader/shader_jit_x64.h
@@ -19,6 +19,11 @@ namespace Pica {
namespace Shader {
+/// Memory needed to be available to compile the next shader (otherwise, clear the cache)
+constexpr size_t jit_shader_size = 1024 * 512;
+/// Memory allocated for the JIT code space cache
+constexpr size_t jit_cache_size = 1024 * 1024 * 8;
+
using CompiledShader = void(void* registers);
/**