1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 10:42:36 +01:00

Merge pull request #1347 from Nekotekina/master

Fixes
This commit is contained in:
Ivan 2015-12-20 16:27:51 +03:00
commit e4631f93bd
54 changed files with 694 additions and 723 deletions

View File

@ -44,6 +44,7 @@ Open the *.SLN* file, and press *Build* > *Clean Solution*, then *Build Solution
If you want to build with LLVM, then LLVM 3.6.2 is required.
`cd rpcs3 && cmake CMakeLists.txt && make && cd ../` then run with `cd bin && ./rpcs3`.
If you are on OSX and want to build with llvm don't forget to add `-DLLVM_DIR=/usr/local/opt/llvm36/lib/llvm-3.6/share/llvm/cmake` (or wherever llvm brew was installed) to cmake invocation.
When using GDB, configure it to ignore SIGSEGV signal (`handle SIGSEGV nostop noprint`).
### Support
* [Donate by PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=MPJ3S9XQXCE3G)

View File

@ -43,14 +43,14 @@ AutoPause::~AutoPause(void)
//This would be able to create in a GUI window.
void AutoPause::Reload(void)
{
if (fs::is_file("pause.bin"))
if (fs::is_file(fs::get_config_dir() + "pause.bin"))
{
m_pause_function.clear();
m_pause_function.reserve(16);
m_pause_syscall.clear();
m_pause_syscall.reserve(16);
fs::file list("pause.bin");
fs::file list(fs::get_config_dir() + "pause.bin");
//System calls ID and Function calls ID are all u32 iirc.
u32 num;
size_t fmax = list.size();

View File

@ -8,7 +8,7 @@
#define GET_API_ERROR static_cast<u64>(GetLastError())
std::unique_ptr<wchar_t[]> to_wchar(const std::string& source)
static std::unique_ptr<wchar_t[]> to_wchar(const std::string& source)
{
const auto length = source.size() + 1; // size + null terminator
@ -24,7 +24,7 @@ std::unique_ptr<wchar_t[]> to_wchar(const std::string& source)
return buffer;
}
void to_utf8(std::string& result, const wchar_t* source)
static void to_utf8(std::string& result, const wchar_t* source)
{
const int length = lstrlenW(source); // source length
@ -48,30 +48,30 @@ void to_utf8(std::string& result, const wchar_t* source)
}
}
time_t to_time_t(const ULARGE_INTEGER& ft)
static time_t to_time(const ULARGE_INTEGER& ft)
{
return ft.QuadPart / 10000000ULL - 11644473600ULL;
}
time_t to_time_t(const LARGE_INTEGER& ft)
static time_t to_time(const LARGE_INTEGER& ft)
{
ULARGE_INTEGER v;
v.LowPart = ft.LowPart;
v.HighPart = ft.HighPart;
return to_time_t(v);
return to_time(v);
}
time_t to_time_t(const FILETIME& ft)
static time_t to_time(const FILETIME& ft)
{
ULARGE_INTEGER v;
v.LowPart = ft.dwLowDateTime;
v.HighPart = ft.dwHighDateTime;
return to_time_t(v);
return to_time(v);
}
bool truncate_file(const std::string& file, u64 length)
static bool truncate_file(const std::string& file, u64 length)
{
// open the file
const auto handle = CreateFileW(to_wchar(file).get(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
@ -105,10 +105,11 @@ bool truncate_file(const std::string& file, u64 length)
#include <unistd.h>
#if defined(__APPLE__) || defined(__FreeBSD__)
#include <copyfile.h>
#include <mach-o/dyld.h>
#else
#include <sys/sendfile.h>
#endif
#include "errno.h"
#include <errno.h>
#define GET_API_ERROR static_cast<u64>(errno)
@ -130,9 +131,9 @@ bool fs::stat(const std::string& path, stat_t& info)
info.is_directory = (attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
info.is_writable = (attrs.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0;
info.size = (u64)attrs.nFileSizeLow | ((u64)attrs.nFileSizeHigh << 32);
info.atime = to_time_t(attrs.ftLastAccessTime);
info.mtime = to_time_t(attrs.ftLastWriteTime);
info.ctime = to_time_t(attrs.ftCreationTime);
info.atime = to_time(attrs.ftLastAccessTime);
info.mtime = to_time(attrs.ftLastWriteTime);
info.ctime = to_time(attrs.ftCreationTime);
#else
struct stat file_info;
if (stat(path.c_str(), &file_info) < 0)
@ -306,7 +307,7 @@ bool fs::rename(const std::string& from, const std::string& to)
#ifndef _WIN32
int OSCopyFile(const char* source, const char* destination, bool overwrite)
static int OSCopyFile(const char* source, const char* destination, bool overwrite)
{
/* Source: http://stackoverflow.com/questions/2180079/how-can-i-copy-a-file-on-unix-using-c */
@ -521,9 +522,9 @@ bool fs::file::stat(stat_t& info) const
info.is_directory = (basic_info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
info.is_writable = (basic_info.FileAttributes & FILE_ATTRIBUTE_READONLY) == 0;
info.size = this->size();
info.atime = to_time_t(basic_info.LastAccessTime);
info.mtime = to_time_t(basic_info.ChangeTime);
info.ctime = to_time_t(basic_info.CreationTime);
info.atime = to_time(basic_info.LastAccessTime);
info.mtime = to_time(basic_info.ChangeTime);
info.ctime = to_time(basic_info.CreationTime);
#else
struct stat file_info;
if (fstat(m_fd, &file_info) < 0)
@ -565,6 +566,7 @@ u64 fs::file::read(void* buffer, u64 count) const
{
g_tls_error = fse::ok;
// TODO (call ReadFile multiple times if count is too big)
const int size = count <= INT_MAX ? static_cast<int>(count) : throw EXCEPTION("Invalid count (0x%llx)", count);
#ifdef _WIN32
@ -584,6 +586,7 @@ u64 fs::file::write(const void* buffer, u64 count) const
{
g_tls_error = fse::ok;
// TODO (call WriteFile multiple times if count is too big)
const int size = count <= INT_MAX ? static_cast<int>(count) : throw EXCEPTION("Invalid count (0x%llx)", count);
#ifdef _WIN32
@ -769,9 +772,9 @@ bool fs::dir::read(std::string& name, stat_t& info)
info.is_directory = (found.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
info.is_writable = (found.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0;
info.size = ((u64)found.nFileSizeHigh << 32) | (u64)found.nFileSizeLow;
info.atime = to_time_t(found.ftLastAccessTime);
info.mtime = to_time_t(found.ftLastWriteTime);
info.ctime = to_time_t(found.ftCreationTime);
info.atime = to_time(found.ftLastAccessTime);
info.mtime = to_time(found.ftLastWriteTime);
info.ctime = to_time(found.ftCreationTime);
#else
const auto found = ::readdir((DIR*)m_dd);
@ -793,3 +796,87 @@ bool fs::dir::read(std::string& name, stat_t& info)
return true;
}
std::string fs::get_config_dir()
{
// Use magic static for dir initialization
static const std::string s_dir = []
{
#ifdef _WIN32
return get_executable_dir(); // ?
#else
std::string dir;
if (const char* home = ::getenv("XDG_CONFIG_HOME"))
dir = home;
else if (const char* home = ::getenv("HOME"))
dir = home + "/.config"s;
else // Just in case
dir = "./config";
dir += "/rpcs3/";
if (::mkdir(dir.c_str(), 0777) == -1 && errno != EEXIST)
{
std::printf("Failed to create configuration directory '%s' (%d).\n", dir.c_str(), errno);
}
return dir;
#endif
}();
return s_dir;
}
std::string fs::get_executable_dir()
{
// Use magic static for dir initialization
static const std::string s_dir = []
{
std::string dir;
#ifdef _WIN32
wchar_t buf[2048];
if (GetModuleFileName(NULL, buf, ::size32(buf)) - 1 >= ::size32(buf) - 1)
{
MessageBoxA(0, fmt::format("GetModuleFileName() failed (0x%x).", GetLastError()).c_str(), "fs::get_config_dir()", MB_ICONERROR);
return dir; // empty
}
to_utf8(dir, buf); // Convert to UTF-8
#elif __APPLE__
char buf[4096];
u32 size = sizeof(buf);
if (_NSGetExecutablePath(buf, &size))
{
std::printf("_NSGetExecutablePath() failed (size=0x%x).\n", size);
return dir; // empty
}
dir = buf;
#else
char buf[4096];
const auto size = ::readlink("/proc/self/exe", buf, sizeof(buf));
if (size <= 0 || size >= sizeof(buf))
{
std::printf("readlink(/proc/self/exe) failed (%d).\n", errno);
return dir; // empty
}
dir = { buf, static_cast<std::size_t>(size) };
#endif
// Replace "\"
for (auto& c : dir)
{
if (c == '\\') c = '/';
}
// Leave only path
dir.resize(dir.rfind('/') + 1);
return dir;
}();
return s_dir;
}

View File

@ -149,6 +149,51 @@ namespace fs
CHECK_ASSERTION(write(str.data(), str.size()) == str.size());
return *this;
}
// Write POD
template<typename T>
std::enable_if_t<std::is_pod<T>::value && !std::is_pointer<T>::value, const file&> operator <<(const T& data) const
{
CHECK_ASSERTION(write(std::addressof(data), sizeof(T)) == sizeof(T));
return *this;
}
// Write POD std::vector
template<typename T>
std::enable_if_t<std::is_pod<T>::value && !std::is_pointer<T>::value, const file&> operator <<(const std::vector<T>& vec) const
{
CHECK_ASSERTION(write(vec.data(), vec.size() * sizeof(T)) == vec.size() * sizeof(T));
return *this;
}
// Read std::string
bool read(std::string& str) const
{
return read(&str[0], str.size()) == str.size();
}
// Read POD
template<typename T>
std::enable_if_t<std::is_pod<T>::value && !std::is_pointer<T>::value, bool> read(T& data) const
{
return read(&data, sizeof(T)) == sizeof(T);
}
// Read POD std::vector
template<typename T>
std::enable_if_t<std::is_pod<T>::value && !std::is_pointer<T>::value, bool> read(std::vector<T>& vec) const
{
return read(vec.data(), sizeof(T) * vec.size()) == sizeof(T) * vec.size();
}
// Convert to std::string
operator std::string() const
{
std::string result;
result.resize(size() - seek(0, fsm::cur));
CHECK_ASSERTION(read(result));
return result;
}
};
class file_ptr final
@ -245,4 +290,10 @@ namespace fs
// Get next directory entry (UTF-8 name and file stat)
bool read(std::string& name, stat_t& info);
};
// Get configuration directory
std::string get_config_dir();
// Get executable directory
std::string get_executable_dir();
}

View File

@ -1,11 +1,13 @@
#include "stdafx.h"
#include "rPlatform.h"
#include "Log.h"
#include "rMsgBox.h"
#include <iostream>
#include <cinttypes>
#include "Thread.h"
#include "File.h"
#include "Log.h"
#ifdef _WIN32
#include <Windows.h>
#endif
using namespace Log;
@ -93,13 +95,17 @@ struct FileListener : LogListener
fs::file mFile;
bool mPrependChannelName;
FileListener(const std::string& name = _PRGNAME_, bool prependChannel = true)
: mFile(rPlatform::getConfigDir() + name + ".log", fom::rewrite)
FileListener(const std::string& name = _PRGNAME_ ".log", bool prependChannel = true)
: mFile(fs::get_config_dir() + name, fom::rewrite)
, mPrependChannelName(prependChannel)
{
if (!mFile)
{
rMessageBox("Can't create log file! (" + name + ".log)", "Error", rICON_ERROR);
#ifdef _WIN32
MessageBoxA(0, ("Can't create log file: " + name).c_str(), "Error", MB_ICONERROR);
#else
std::printf("Can't create log file: %s\n", name.c_str());
#endif
}
}
@ -137,7 +143,7 @@ LogManager::LogManager()
it->addListener(listener);
it++;
}
std::shared_ptr<LogListener> TTYListener(new FileListener("TTY",false));
std::shared_ptr<LogListener> TTYListener(new FileListener("TTY.log", false));
getChannel(TTY).addListener(TTYListener);
#ifdef BUFFERED_LOGGING
mLogConsumer = std::thread(&LogManager::consumeLog, this);
@ -257,20 +263,23 @@ void log_message(Log::LogType type, Log::Severity sev, std::string text)
{
if (g_log_manager)
{
// another msvc bug makes this not work, uncomment this when it's fixed
//g_log_manager->log({logType, severity, text});
Log::LogMessage msg{ type, sev, std::move(text) };
g_log_manager->log(msg);
g_log_manager->log({ type, sev, std::move(text) });
}
else
{
rMessageBox(text,
const auto severity =
sev == Severity::Notice ? "Notice" :
sev == Severity::Warning ? "Warning" :
sev == Severity::Success ? "Success" :
sev == Severity::Error ? "Error" : "Unknown",
sev == Severity::Notice ? rICON_INFORMATION :
sev == Severity::Warning ? rICON_EXCLAMATION :
sev == Severity::Error ? rICON_ERROR : rICON_INFORMATION);
sev == Severity::Error ? "Error" : "Unknown";
#ifdef _WIN32
MessageBoxA(0, text.c_str(), severity,
sev == Severity::Notice ? MB_ICONINFORMATION :
sev == Severity::Warning ? MB_ICONEXCLAMATION :
sev == Severity::Error ? MB_ICONERROR : MB_ICONINFORMATION);
#else
std::printf("[Log:%s] %s\n", severity, text.c_str());
#endif
}
}

View File

@ -19,26 +19,33 @@
#include <ucontext.h>
#endif
static const auto s_terminate_handler_set = std::set_terminate([]()
void report_fatal_error(const std::string& msg)
{
if (std::uncaught_exception())
#ifdef _WIN32
const auto& text = msg + "\n\nPlease report this error to the developers. Press (Ctrl+C) to copy this message.";
MessageBoxA(0, text.c_str(), "Fatal error", MB_ICONERROR); // TODO: unicode message
#else
std::printf("Fatal error: %s\nPlease report this error to the developers.\n", msg.c_str());
#endif
}
[[noreturn]] void catch_all_exceptions()
{
try
{
try
{
throw;
}
catch (const std::exception& ex)
{
std::printf("Unhandled exception: %s\n", ex.what());
}
catch (...)
{
std::printf("Unhandled exception of unknown type.\n");
}
throw;
}
catch (const std::exception& ex)
{
report_fatal_error("Unhandled exception: "s + ex.what());
}
catch (...)
{
report_fatal_error("Unhandled exception (unknown)");
}
std::abort();
});
}
void SetCurrentThreadDebugName(const char* threadName)
{
@ -517,6 +524,9 @@ typedef CONTEXT x64_context;
#define XMMREG(context, reg) (reinterpret_cast<v128*>(&(&(context)->Xmm0)[reg]))
#define EFLAGS(context) ((context)->EFlags)
#define ARG1(context) RCX(context)
#define ARG2(context) RDX(context)
#else
typedef ucontext_t x64_context;
@ -569,11 +579,15 @@ static const decltype(REG_RAX) reg_table[] =
#endif // __APPLE__
#define ARG1(context) RDI(context)
#define ARG2(context) RSI(context)
#endif
#define RAX(c) (*X64REG((c), 0))
#define RCX(c) (*X64REG((c), 1))
#define RDX(c) (*X64REG((c), 2))
#define RSP(c) (*X64REG((c), 4))
#define RSI(c) (*X64REG((c), 6))
#define RDI(c) (*X64REG((c), 7))
#define RIP(c) (*X64REG((c), 16))
@ -1114,31 +1128,32 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
// TODO: allow recovering from a page fault as a feature of PS3 virtual memory
}
#ifdef _WIN32
void _se_translator(unsigned int u, EXCEPTION_POINTERS* pExp)
// Throw virtual memory access violation exception
[[noreturn]] void throw_access_violation(const char* cause, u32 address) // Don't change function definition
{
const u64 addr64 = (u64)pExp->ExceptionRecord->ExceptionInformation[1] - (u64)vm::base(0);
const bool is_writing = pExp->ExceptionRecord->ExceptionInformation[0] != 0;
if (u == EXCEPTION_ACCESS_VIOLATION)
{
if ((u32)addr64 == addr64)
{
throw EXCEPTION("Access violation %s location 0x%llx", is_writing ? "writing" : "reading", addr64);
}
std::printf("Access violation %s location %p at %p\n", is_writing ? "writing" : "reading", (void*)pExp->ExceptionRecord->ExceptionInformation[1], pExp->ExceptionRecord->ExceptionAddress);
std::abort();
}
throw EXCEPTION("Access violation %s location 0x%08x", cause, address);
}
const PVOID exception_handler = (atexit([]{ RemoveVectoredExceptionHandler(exception_handler); }), AddVectoredExceptionHandler(1, [](PEXCEPTION_POINTERS pExp) -> LONG
// Modify context in order to convert hardware exception to C++ exception
void prepare_throw_access_violation(x64_context* context, const char* cause, u32 address)
{
const u64 addr64 = (u64)pExp->ExceptionRecord->ExceptionInformation[1] - (u64)vm::base(0);
// Set throw_access_violation() call args (old register values are lost)
ARG1(context) = (u64)cause;
ARG2(context) = address;
// Push the exception address as a "return" address (throw_access_violation() shall not return)
*--(u64*&)(RSP(context)) = RIP(context);
RIP(context) = (u64)std::addressof(throw_access_violation);
}
#ifdef _WIN32
const auto g_exception_handler = AddVectoredExceptionHandler(1, [](PEXCEPTION_POINTERS pExp) -> LONG
{
const u64 addr64 = pExp->ExceptionRecord->ExceptionInformation[1] - (u64)vm::base(0);
const bool is_writing = pExp->ExceptionRecord->ExceptionInformation[0] != 0;
if (pExp->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION && (u32)addr64 == addr64 && thread_ctrl::get_current() && handle_access_violation((u32)addr64, is_writing, pExp->ContextRecord))
if (pExp->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION && addr64 < 0x100000000ull && thread_ctrl::get_current() && handle_access_violation((u32)addr64, is_writing, pExp->ContextRecord))
{
return EXCEPTION_CONTINUE_EXECUTION;
}
@ -1146,12 +1161,40 @@ const PVOID exception_handler = (atexit([]{ RemoveVectoredExceptionHandler(excep
{
return EXCEPTION_CONTINUE_SEARCH;
}
}));
});
const auto exception_filter = SetUnhandledExceptionFilter([](PEXCEPTION_POINTERS pExp) -> LONG
const auto g_exception_filter = SetUnhandledExceptionFilter([](PEXCEPTION_POINTERS pExp) -> LONG
{
_se_translator(pExp->ExceptionRecord->ExceptionCode, pExp);
std::string msg = fmt::format("Unhandled Win32 exception 0x%08X.\n", pExp->ExceptionRecord->ExceptionCode);
if (pExp->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
{
const u64 addr64 = pExp->ExceptionRecord->ExceptionInformation[1] - (u64)vm::base(0);
const auto cause = pExp->ExceptionRecord->ExceptionInformation[0] != 0 ? "writing" : "reading";
if (addr64 < 0x100000000ull)
{
// Setup throw_access_violation() call on the context
prepare_throw_access_violation(pExp->ContextRecord, cause, (u32)addr64);
return EXCEPTION_CONTINUE_EXECUTION;
}
msg += fmt::format("Access violation %s location %p at %p.\n", cause, pExp->ExceptionRecord->ExceptionInformation[1], pExp->ExceptionRecord->ExceptionAddress);
}
else
{
msg += fmt::format("Exception address: %p.\n", pExp->ExceptionRecord->ExceptionAddress);
for (DWORD i = 0; i < pExp->ExceptionRecord->NumberParameters; i++)
{
msg += fmt::format("ExceptionInformation[0x%x]: %p.\n", i, pExp->ExceptionRecord->ExceptionInformation[i]);
}
}
msg += fmt::format("Image base: %p.", GetModuleHandle(NULL));
// Report fatal error
report_fatal_error(msg);
return EXCEPTION_CONTINUE_SEARCH;
});
@ -1159,31 +1202,35 @@ const auto exception_filter = SetUnhandledExceptionFilter([](PEXCEPTION_POINTERS
void signal_handler(int sig, siginfo_t* info, void* uct)
{
const u64 addr64 = (u64)info->si_addr - (u64)vm::base(0);
x64_context* context = (ucontext_t*)uct;
#ifdef __APPLE__
const bool is_writing = ((ucontext_t*)uct)->uc_mcontext->__es.__err & 0x2;
const bool is_writing = context->uc_mcontext->__es.__err & 0x2;
#else
const bool is_writing = ((ucontext_t*)uct)->uc_mcontext.gregs[REG_ERR] & 0x2;
const bool is_writing = context->uc_mcontext.gregs[REG_ERR] & 0x2;
#endif
if ((u32)addr64 == addr64 && thread_ctrl::get_current())
const u64 addr64 = (u64)info->si_addr - (u64)vm::base(0);
const auto cause = is_writing ? "writing" : "reading";
if (addr64 < 0x100000000ull && thread_ctrl::get_current())
{
if (handle_access_violation((u32)addr64, is_writing, (ucontext_t*)uct))
// Try to process access violation
if (!handle_access_violation((u32)addr64, is_writing, context))
{
return; // proceed execution
// Setup throw_access_violation() call on the context
prepare_throw_access_violation(context, cause, (u32)addr64);
}
// TODO: this may be wrong
throw EXCEPTION("Access violation %s location 0x%llx", is_writing ? "writing" : "reading", addr64);
}
// else some fatal error
std::printf("Access violation %s location %p at %p\n", is_writing ? "writing" : "reading", info->si_addr, RIP((ucontext_t*)uct));
std::abort();
else
{
// TODO (debugger interaction)
report_fatal_error(fmt::format("Access violation %s location %p at %p.", cause, info->si_addr, RIP(context)));
std::abort();
}
}
const int sigaction_result = []() -> int
int setup_signal_handler()
{
struct sigaction sa;
@ -1191,7 +1238,9 @@ const int sigaction_result = []() -> int
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = signal_handler;
return sigaction(SIGSEGV, &sa, NULL);
}();
}
const int g_sigaction_result = setup_signal_handler();
#endif
@ -1205,13 +1254,13 @@ void thread_ctrl::initialize()
SetCurrentThreadDebugName(g_tls_this_thread->m_name().c_str());
#ifdef _WIN32
if (!exception_handler || !exception_filter)
if (!g_exception_handler || !g_exception_filter)
#else
if (sigaction_result == -1)
if (g_sigaction_result == -1)
#endif
{
std::printf("Exceptions handlers are not set correctly.\n");
std::terminate();
report_fatal_error("Exception handler is not set correctly.");
std::abort();
}
// TODO
@ -1243,12 +1292,9 @@ thread_ctrl::~thread_ctrl()
{
m_future.get();
}
catch (const std::exception& ex)
{
LOG_ERROR(GENERAL, "Abandoned exception: %s", ex.what());
}
catch (EmulationStopped)
catch (...)
{
catch_all_exceptions();
}
}
}
@ -1267,7 +1313,7 @@ std::string named_thread_t::get_name() const
void named_thread_t::start()
{
CHECK_ASSERTION(m_thread == nullptr);
CHECK_ASSERTION(!m_thread);
// Get shared_ptr instance (will throw if called from the constructor or the object has been created incorrectly)
auto ptr = shared_from_this();
@ -1305,7 +1351,7 @@ void named_thread_t::start()
}
catch (const std::exception& e)
{
LOG_ERROR(GENERAL, "Exception: %s", e.what());
LOG_ERROR(GENERAL, "Exception: %s\nPlease report this to the developers.", e.what());
Emu.Pause();
}
catch (EmulationStopped)

View File

@ -1,5 +1,8 @@
#pragma once
// Will report exception and call std::abort() if put in catch(...)
[[noreturn]] void catch_all_exceptions();
// Thread control class
class thread_ctrl final
{

View File

@ -163,3 +163,10 @@ std::string config_context_t::to_string() const
return result.str();
}
void config_context_t::from_string(const std::string& str)
{
std::istringstream source(str);
deserialize(source);
}

View File

@ -159,4 +159,5 @@ public:
void set_defaults();
std::string to_string() const;
void from_string(const std::string&);
};

View File

@ -1,38 +0,0 @@
#include "stdafx.h"
#include "restore_new.h"
#pragma warning(push)
#pragma message("TODO: remove wx dependency: <wx/msgdlg.h>")
#pragma warning(disable : 4996)
#include <wx/msgdlg.h>
#pragma warning(pop)
#include "define_new_memleakdetect.h"
#include "rMsgBox.h"
#ifndef QT_UI
rMessageDialog::rMessageDialog(void *parent, const std::string& msg, const std::string& title , long style )
{
handle = reinterpret_cast<void*>(new wxMessageDialog(
reinterpret_cast<wxWindow*>(parent)
, fmt::FromUTF8(msg)
, fmt::FromUTF8(title)
, style
));
}
rMessageDialog::~rMessageDialog()
{
delete reinterpret_cast<wxMessageDialog*>(handle);
}
long rMessageDialog::ShowModal()
{
return reinterpret_cast<wxMessageDialog*>(handle)->ShowModal();
}
long rMessageBox(const std::string& message, const std::string& title, long style)
{
return wxMessageBox(fmt::FromUTF8(message), fmt::FromUTF8(title),style);
}
#endif

View File

@ -1,38 +0,0 @@
#pragma once
enum MsgBoxParams : unsigned long
{
rYES_DEFAULT = 0x0,
rOK_DEFAULT = 0x0,
rCENTRE = 0x1,
rYES = 0x2, //res
rOK = 0x4,
rNO = 0x8, //res
rCANCEL = 0x10,
rYES_NO = 0xA,
rNO_DEFAULT = 0x80,
rICON_EXCLAMATION = 0x100,
rICON_ERROR = 0x200,
rICON_HAND = 0x200,
rICON_QUESTION = 0x400,
rICON_INFORMATION = 0x800,
rHELP = 0x1000,
rID_CANCEL = 0x13ED,
rID_YES = 0x13EF, //resDialog
rSTAY_ON_TOP = 0x8000,
rICON_NONE = 0x40000,
rICON_AUTH_NEEDED = 0x80000,
rCANCEL_DEFAULT = 0x80000000,
};
struct rMessageDialog
{
rMessageDialog(void *parent, const std::string& msg, const std::string& title = "RPCS3", long style = rOK | rCENTRE);
rMessageDialog(const rMessageDialog& other) = delete;
~rMessageDialog();
long ShowModal();
void *handle;
};
long rMessageBox(const std::string& message, const std::string& title,long style);

View File

@ -40,29 +40,3 @@ void rImage::SaveFile(const std::string& name, rImageType type)
throw EXCEPTION("unsupported type");
}
}
std::string rPlatform::getConfigDir()
{
static std::string dir = ".";
if (dir == ".")
{
#ifdef _WIN32
dir = "";
//mkdir(dir.c_str());
#else
if (getenv("XDG_CONFIG_HOME") != NULL)
dir = getenv("XDG_CONFIG_HOME");
else if (getenv("HOME") != NULL)
dir = getenv("HOME") + std::string("/.config");
else // Just in case
dir = "./config";
dir = dir + "/rpcs3/";
if (mkdir(dir.c_str(), 0777) == -1)
{
printf("An error occured during the creation of the configuration directory. (%d)", errno);
}
#endif
}
return dir;
}

View File

@ -1,10 +1,5 @@
#pragma once
struct rPlatform
{
static std::string getConfigDir();
};
/**********************************************************************
*********** RSX Debugger
************************************************************************/

View File

@ -33,7 +33,7 @@ spu_recompiler::spu_recompiler()
LOG_SUCCESS(SPU, "SPU Recompiler (ASMJIT) created...");
fs::file("SPUJIT.log", fom::rewrite) << fmt::format("SPU JIT initialization...\n\nTitle: %s\nTitle ID: %s\n\n", Emu.GetTitle().c_str(), Emu.GetTitleID().c_str());
fs::file(fs::get_config_dir() + "SPUJIT.log", fom::rewrite) << fmt::format("SPU JIT initialization...\n\nTitle: %s\nTitle ID: %s\n\n", Emu.GetTitle().c_str(), Emu.GetTitleID().c_str());
}
void spu_recompiler::compile(spu_function_t& f)
@ -218,7 +218,7 @@ void spu_recompiler::compile(spu_function_t& f)
log += "\n\n\n";
// Append log file
fs::file("SPUJIT.log", fom::write | fom::append) << log;
fs::file(fs::get_config_dir() + "SPUJIT.log", fom::write | fom::append) << log;
}
spu_recompiler::XmmLink spu_recompiler::XmmAlloc() // get empty xmm register

View File

@ -480,7 +480,6 @@ void VFS::Init(const std::string& path)
}
std::string mpath = entry.path;
// TODO: This shouldn't use current dir
// If no value assigned to SysEmulationDirPath in INI, use the path that with executable.
if (rpcs3::config.system.emulation_dir_path_enable.value())
{
@ -488,7 +487,7 @@ void VFS::Init(const std::string& path)
}
else
{
fmt::Replace(mpath, "$(EmulatorDir)", Emu.GetEmulatorPath());
fmt::Replace(mpath, "$(EmulatorDir)", fs::get_executable_dir());
}
fmt::Replace(mpath, "$(GameDir)", cwd);
Mount(entry.mount, mpath, dev);
@ -531,7 +530,7 @@ void VFS::SaveLoadDevices(std::vector<VFSManagerEntry>& res, bool is_load)
if (dir.empty())
{
rpcs3::config.system.emulation_dir_path = Emu.GetEmulatorPath();
rpcs3::config.system.emulation_dir_path = fs::get_executable_dir();
}
if (!fs::is_dir(dir))

View File

@ -335,10 +335,9 @@ namespace fxm
if (pair.second)
{
id_aux_initialize(pair.second.get());
return std::move(pair.second);
}
return nullptr;
return std::move(pair.second);
}
// Create the object unconditionally (old object will be removed if it exists)
@ -356,30 +355,29 @@ namespace fxm
return std::move(pair.second);
}
// Emplace the object
template<typename T>
bool import(const std::shared_ptr<T>& ptr)
// Emplace the object returned by provider() and return it if no object exists
template<typename T, typename F>
auto import(F&& provider) -> decltype(static_cast<std::shared_ptr<T>>(provider()))
{
static const auto size = sizeof(T); // forbid forward declarations
auto pair = add<T, false>(WRAP_EXPR(ptr));
auto pair = add<T, false>(std::forward<F>(provider));
if (pair.second)
{
id_aux_initialize(pair.second.get());
return true;
}
return false;
return std::move(pair.second);
}
// Emplace the object unconditionally (old object will be removed if it exists)
template<typename T>
void import_always(const std::shared_ptr<T>& ptr)
// Emplace the object return by provider() (old object will be removed if it exists)
template<typename T, typename F>
auto import_always(F&& provider) -> decltype(static_cast<std::shared_ptr<T>>(provider()))
{
static const auto size = sizeof(T); // forbid forward declarations
auto pair = add<T, true>(WRAP_EXPR(ptr));
auto pair = add<T, true>(std::forward<F>(provider));
if (pair.first)
{
@ -387,6 +385,7 @@ namespace fxm
}
id_aux_initialize(pair.second.get());
return std::move(pair.second);
}
// Get the object unconditionally (create an object if it doesn't exist)

View File

@ -16,6 +16,7 @@
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
/* OS X uses MAP_ANON instead of MAP_ANONYMOUS */
#ifndef MAP_ANONYMOUS
@ -46,8 +47,8 @@ namespace vm
if (memory_handle == NULL)
{
std::printf("CreateFileMapping() failed\n");
return{};
MessageBoxA(0, fmt::format("CreateFileMapping() failed (0x%x).", GetLastError()).c_str(), "vm::initialize()", MB_ICONERROR);
std::abort();
}
mapped_ptr_t base_addr(static_cast<u8*>(::MapViewOfFile(memory_handle, FILE_MAP_WRITE, 0, 0, 0x100000000)));
@ -59,15 +60,15 @@ namespace vm
if (memory_handle == -1)
{
std::printf("shm_open('/rpcs3_vm') failed\n");
return{};
std::printf("shm_open('/rpcs3_vm') failed (%d).\n", errno);
std::abort();
}
if (::ftruncate(memory_handle, 0x100000000) == -1)
{
std::printf("ftruncate(memory_handle) failed\n");
std::printf("ftruncate(memory_handle) failed (%d).\n", errno);
::shm_unlink("/rpcs3_vm");
return{};
std::abort();
}
mapped_ptr_t base_addr(static_cast<u8*>(::mmap(nullptr, 0x100000000, PROT_NONE, MAP_SHARED, memory_handle, 0)));
@ -76,7 +77,7 @@ namespace vm
::shm_unlink("/rpcs3_vm");
#endif
std::printf("vm: base_addr = %p, priv_addr = %p\n", base_addr.get(), priv_addr.get());
std::printf("vm::g_base_addr = %p\nvm::g_priv_addr = %p\n", base_addr.get(), priv_addr.get());
return{ std::move(base_addr), std::move(priv_addr) };
}

View File

@ -5,7 +5,7 @@
#define MIN2(x, y) ((x) < (y)) ? (x) : (y)
#define MAX2(x, y) ((x) > (y)) ? (x) : (y)
void write_vertex_array_data_to_buffer(void *buffer, u32 first, u32 count, size_t index, const rsx::data_array_format_info &vertex_array_desc) noexcept
void write_vertex_array_data_to_buffer(void *buffer, u32 first, u32 count, size_t index, const rsx::data_array_format_info &vertex_array_desc)
{
assert(vertex_array_desc.array);
@ -62,7 +62,7 @@ void write_vertex_array_data_to_buffer(void *buffer, u32 first, u32 count, size_
namespace
{
template<typename IndexType>
void uploadAsIt(char *dst, u32 address, size_t indexCount, bool is_primitive_restart_enabled, u32 primitive_restart_index, u32 &min_index, u32 &max_index) noexcept
void uploadAsIt(char *dst, u32 address, size_t indexCount, bool is_primitive_restart_enabled, u32 primitive_restart_index, u32 &min_index, u32 &max_index)
{
for (u32 i = 0; i < indexCount; ++i)
{
@ -80,7 +80,7 @@ void uploadAsIt(char *dst, u32 address, size_t indexCount, bool is_primitive_res
// FIXME: expanded primitive type may not support primitive restart correctly
template<typename IndexType>
void expandIndexedTriangleFan(char *dst, u32 address, size_t indexCount, bool is_primitive_restart_enabled, u32 primitive_restart_index, u32 &min_index, u32 &max_index) noexcept
void expandIndexedTriangleFan(char *dst, u32 address, size_t indexCount, bool is_primitive_restart_enabled, u32 primitive_restart_index, u32 &min_index, u32 &max_index)
{
for (unsigned i = 0; i < indexCount - 2; i++)
{
@ -117,7 +117,7 @@ void expandIndexedTriangleFan(char *dst, u32 address, size_t indexCount, bool is
}
template<typename IndexType>
void expandIndexedQuads(char *dst, u32 address, size_t indexCount, bool is_primitive_restart_enabled, u32 primitive_restart_index, u32 &min_index, u32 &max_index) noexcept
void expandIndexedQuads(char *dst, u32 address, size_t indexCount, bool is_primitive_restart_enabled, u32 primitive_restart_index, u32 &min_index, u32 &max_index)
{
for (unsigned i = 0; i < indexCount / 4; i++)
{
@ -168,7 +168,7 @@ void expandIndexedQuads(char *dst, u32 address, size_t indexCount, bool is_primi
}
// Only handle quads and triangle fan now
bool is_primitive_native(unsigned m_draw_mode) noexcept
bool is_primitive_native(unsigned m_draw_mode)
{
switch (m_draw_mode)
{
@ -193,7 +193,7 @@ bool is_primitive_native(unsigned m_draw_mode) noexcept
* see http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/polygon-triangulation-r3334
*/
size_t get_index_count(unsigned m_draw_mode, unsigned initial_index_count) noexcept
size_t get_index_count(unsigned m_draw_mode, unsigned initial_index_count)
{
// Index count
if (is_primitive_native(m_draw_mode))
@ -211,7 +211,7 @@ size_t get_index_count(unsigned m_draw_mode, unsigned initial_index_count) noexc
}
}
size_t get_index_type_size(u32 type) noexcept
size_t get_index_type_size(u32 type)
{
switch (type)
{
@ -221,7 +221,7 @@ size_t get_index_type_size(u32 type) noexcept
}
}
void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst, unsigned draw_mode, unsigned first, unsigned count) noexcept
void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst, unsigned draw_mode, unsigned first, unsigned count)
{
unsigned short *typedDst = (unsigned short *)(dst);
switch (draw_mode)
@ -251,7 +251,7 @@ void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst,
}
}
void write_index_array_data_to_buffer(char* dst, unsigned m_draw_mode, unsigned first, unsigned count, unsigned &min_index, unsigned &max_index) noexcept
void write_index_array_data_to_buffer(char* dst, unsigned m_draw_mode, unsigned first, unsigned count, unsigned &min_index, unsigned &max_index)
{
u32 address = rsx::get_address(rsx::method_registers[NV4097_SET_INDEX_ARRAY_ADDRESS], rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] & 0xf);
u32 type = rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4;
@ -306,14 +306,14 @@ void write_index_array_data_to_buffer(char* dst, unsigned m_draw_mode, unsigned
}
}
void stream_vector(void *dst, u32 x, u32 y, u32 z, u32 w) noexcept
void stream_vector(void *dst, u32 x, u32 y, u32 z, u32 w)
{
__m128i vector = _mm_set_epi32(w, z, y, x);
_mm_stream_si128((__m128i*)dst, vector);
}
void stream_vector_from_memory(void *dst, void *src) noexcept
void stream_vector_from_memory(void *dst, void *src)
{
const __m128i &vector = _mm_loadu_si128((__m128i*)src);
_mm_stream_si128((__m128i*)dst, vector);
}
}

View File

@ -15,41 +15,41 @@ struct VertexBufferFormat
/**
* Write count vertex attributes from index array buffer starting at first, using vertex_array_desc
*/
void write_vertex_array_data_to_buffer(void *buffer, u32 first, u32 count, size_t index, const rsx::data_array_format_info &vertex_array_desc) noexcept;
void write_vertex_array_data_to_buffer(void *buffer, u32 first, u32 count, size_t index, const rsx::data_array_format_info &vertex_array_desc);
/*
* If primitive mode is not supported and need to be emulated (using an index buffer) returns false.
*/
bool is_primitive_native(unsigned m_draw_mode) noexcept;
bool is_primitive_native(unsigned m_draw_mode);
/**
* Returns a fixed index count for emulated primitive, otherwise returns initial_index_count
*/
size_t get_index_count(unsigned m_draw_mode, unsigned initial_index_count) noexcept;
size_t get_index_count(unsigned m_draw_mode, unsigned initial_index_count);
/**
* Returns index type size in byte
*/
size_t get_index_type_size(u32 type) noexcept;
size_t get_index_type_size(u32 type);
/**
* Write count indexes starting at first to dst buffer.
* Returns min/max index found during the process.
* The function expands index buffer for non native primitive type.
*/
void write_index_array_data_to_buffer(char* dst, unsigned m_draw_mode, unsigned first, unsigned count, unsigned &min_index, unsigned &max_index) noexcept;
void write_index_array_data_to_buffer(char* dst, unsigned m_draw_mode, unsigned first, unsigned count, unsigned &min_index, unsigned &max_index);
/**
* Write index data needed to emulate non indexed non native primitive mode.
*/
void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst, unsigned m_draw_mode, unsigned first, unsigned count) noexcept;
void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst, unsigned m_draw_mode, unsigned first, unsigned count);
/**
* Stream a 128 bits vector to dst.
*/
void stream_vector(void *dst, u32 x, u32 y, u32 z, u32 w) noexcept;
void stream_vector(void *dst, u32 x, u32 y, u32 z, u32 w);
/**
* Stream a 128 bits vector from src to dst.
*/
void stream_vector_from_memory(void *dst, void *src) noexcept;
void stream_vector_from_memory(void *dst, void *src);

View File

@ -294,7 +294,7 @@ public:
clear();
}
const typename BackendTraits::VertexProgramData* get_transform_program(const RSXVertexProgram& rsx_vp) const noexcept
const typename BackendTraits::VertexProgramData* get_transform_program(const RSXVertexProgram& rsx_vp) const
{
typename binary2VS::const_iterator It = m_cacheVS.find(rsx_vp.data);
if (It == m_cacheVS.end())
@ -302,7 +302,7 @@ public:
return &It->second;
}
const typename BackendTraits::FragmentProgramData* get_shader_program(const RSXFragmentProgram& rsx_fp) const noexcept
const typename BackendTraits::FragmentProgramData* get_shader_program(const RSXFragmentProgram& rsx_fp) const
{
typename binary2FS::const_iterator It = m_cacheFS.find(vm::base(rsx_fp.addr));
if (It == m_cacheFS.end())
@ -353,7 +353,7 @@ public:
return result;
}
size_t get_fragment_constants_buffer_size(const RSXFragmentProgram *fragmentShader) const noexcept
size_t get_fragment_constants_buffer_size(const RSXFragmentProgram *fragmentShader) const
{
typename binary2FS::const_iterator It = m_cacheFS.find(vm::base(fragmentShader->addr));
if (It != m_cacheFS.end())
@ -362,7 +362,7 @@ public:
return 0;
}
void fill_fragment_constans_buffer(void *buffer, const RSXFragmentProgram *fragment_program) const noexcept
void fill_fragment_constans_buffer(void *buffer, const RSXFragmentProgram *fragment_program) const
{
typename binary2FS::const_iterator It = m_cacheFS.find(vm::base(fragment_program->addr));
if (It == m_cacheFS.end())

View File

@ -14,7 +14,7 @@ namespace
struct texel_rgba
{
template<size_t block_size>
static size_t copy_mipmap_level(void *dst, void *src, size_t row_count, size_t width_in_block, size_t dst_pitch_in_block, size_t src_pitch_in_block) noexcept
static size_t copy_mipmap_level(void *dst, void *src, size_t row_count, size_t width_in_block, size_t dst_pitch_in_block, size_t src_pitch_in_block)
{
for (unsigned row = 0; row < row_count; row++)
memcpy((char*)dst + row * dst_pitch_in_block * block_size, (char*)src + row * src_pitch_in_block * block_size, width_in_block * block_size);
@ -29,7 +29,7 @@ struct texel_rgba
struct texel_16b_swizzled
{
template<size_t block_size>
static size_t copy_mipmap_level(void *dst, void *src, size_t row_count, size_t width_in_block, size_t dst_pitch_in_block, size_t src_pitch_in_block) noexcept
static size_t copy_mipmap_level(void *dst, void *src, size_t row_count, size_t width_in_block, size_t dst_pitch_in_block, size_t src_pitch_in_block)
{
u16 *castedSrc = static_cast<u16*>(src), *castedDst = static_cast<u16*>(dst);
@ -51,7 +51,7 @@ struct texel_16b_swizzled
struct texel_rgba_swizzled
{
template<size_t block_size>
static size_t copy_mipmap_level(void *dst, void *src, size_t row_count, size_t width_in_block, size_t dst_pitch_in_block, size_t src_pitch_in_block) noexcept
static size_t copy_mipmap_level(void *dst, void *src, size_t row_count, size_t width_in_block, size_t dst_pitch_in_block, size_t src_pitch_in_block)
{
u32 *castedSrc, *castedDst;
castedSrc = (u32*)src;
@ -70,7 +70,7 @@ struct texel_rgba_swizzled
*/
struct texel_bc_format {
template<size_t block_size>
static size_t copy_mipmap_level(void *dst, void *src, size_t row_count, size_t width_in_block, size_t dst_pitch_in_block, size_t src_pitch_in_block) noexcept
static size_t copy_mipmap_level(void *dst, void *src, size_t row_count, size_t width_in_block, size_t dst_pitch_in_block, size_t src_pitch_in_block)
{
for (unsigned row = 0; row < row_count; row++)
memcpy((char*)dst + row * dst_pitch_in_block * block_size, (char*)src + row * width_in_block * block_size, width_in_block * block_size);
@ -83,7 +83,7 @@ struct texel_bc_format {
*/
struct texel_16b_format {
template<size_t block_size>
static size_t copy_mipmap_level(void *dst, void *src, size_t row_count, size_t width_in_block, size_t dst_pitch_in_block, size_t src_pitch_in_block) noexcept
static size_t copy_mipmap_level(void *dst, void *src, size_t row_count, size_t width_in_block, size_t dst_pitch_in_block, size_t src_pitch_in_block)
{
unsigned short *castedDst = (unsigned short *)dst, *castedSrc = (unsigned short *)src;
@ -102,7 +102,7 @@ struct texel_16b_format {
*/
struct texel_16bX4_format {
template<size_t block_size>
static size_t copy_mipmap_level(void *dst, void *src, size_t row_count, size_t width_in_block, size_t dst_pitch_in_block, size_t src_pitch_in_block) noexcept
static size_t copy_mipmap_level(void *dst, void *src, size_t row_count, size_t width_in_block, size_t dst_pitch_in_block, size_t src_pitch_in_block)
{
unsigned short *casted_dst = (unsigned short *)dst, *casted_src = (unsigned short *)src;
for (unsigned row = 0; row < row_count; row++)
@ -123,7 +123,7 @@ struct texel_16bX4_format {
* mipmap level (to allow same code for packed/non packed texels)
*/
template <typename T, size_t block_size_in_bytes, size_t block_edge_in_texel = 1>
std::vector<MipmapLevelInfo> copy_texture_data(void *dst, const void *src, size_t widthInBlock, size_t heightInBlock, size_t depth, size_t mipmapCount) noexcept
std::vector<MipmapLevelInfo> copy_texture_data(void *dst, const void *src, size_t widthInBlock, size_t heightInBlock, size_t depth, size_t mipmapCount)
{
std::vector<MipmapLevelInfo> Result;
size_t offsetInDst = 0, offsetInSrc = 0;
@ -157,7 +157,7 @@ std::vector<MipmapLevelInfo> copy_texture_data(void *dst, const void *src, size_
* A texture is stored as an array of blocks, where a block is a pixel for standard texture
* but is a structure containing several pixels for compressed format
*/
size_t get_texture_block_size(u32 format) noexcept
size_t get_texture_block_size(u32 format)
{
switch (format)
{
@ -191,12 +191,12 @@ size_t get_texture_block_size(u32 format) noexcept
case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8:
case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8:
default:
LOG_ERROR(RSX, "Unimplemented Texture format : %x", format);
LOG_ERROR(RSX, "Unimplemented Texture format : 0x%x", format);
return 0;
}
}
size_t get_texture_block_edge(u32 format) noexcept
size_t get_texture_block_edge(u32 format)
{
switch (format)
{
@ -230,14 +230,14 @@ size_t get_texture_block_edge(u32 format) noexcept
case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8:
case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8:
default:
LOG_ERROR(RSX, "Unimplemented Texture format : %x", format);
LOG_ERROR(RSX, "Unimplemented Texture format : 0x%x", format);
return 0;
}
}
}
size_t get_placed_texture_storage_size(const rsx::texture &texture, size_t rowPitchAlignement) noexcept
size_t get_placed_texture_storage_size(const rsx::texture &texture, size_t rowPitchAlignement)
{
size_t w = texture.width(), h = texture.height();
@ -253,7 +253,7 @@ size_t get_placed_texture_storage_size(const rsx::texture &texture, size_t rowPi
return rowPitch * heightInBlocks * (texture.cubemap() ? 6 : 1) * 2; // * 2 for mipmap levels
}
std::vector<MipmapLevelInfo> upload_placed_texture(const rsx::texture &texture, size_t rowPitchAlignement, void* textureData) noexcept
std::vector<MipmapLevelInfo> upload_placed_texture(const rsx::texture &texture, size_t rowPitchAlignement, void* textureData)
{
size_t w = texture.width(), h = texture.height();
size_t depth = texture.depth();
@ -301,7 +301,7 @@ std::vector<MipmapLevelInfo> upload_placed_texture(const rsx::texture &texture,
}
}
size_t get_texture_size(const rsx::texture &texture) noexcept
size_t get_texture_size(const rsx::texture &texture)
{
size_t w = texture.width(), h = texture.height();
@ -314,7 +314,7 @@ size_t get_texture_size(const rsx::texture &texture) noexcept
case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8:
case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8:
default:
LOG_ERROR(RSX, "Unimplemented Texture format : %x", format);
LOG_ERROR(RSX, "Unimplemented Texture format : 0x%x", format);
return 0;
case CELL_GCM_TEXTURE_B8:
return w * h;
@ -367,4 +367,4 @@ size_t get_texture_size(const rsx::texture &texture) noexcept
case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8:
return w * h * 4;
}
}
}

View File

@ -14,16 +14,16 @@ struct MipmapLevelInfo
* Get size to store texture in a linear fashion.
* Storage is assumed to use a rowPitchAlignement boundary for every row of texture.
*/
size_t get_placed_texture_storage_size(const rsx::texture &texture, size_t rowPitchAlignement) noexcept;
size_t get_placed_texture_storage_size(const rsx::texture &texture, size_t rowPitchAlignement);
/**
* Write texture data to textureData.
* Data are not packed, they are stored per rows using rowPitchAlignement.
* Similarly, offset for every mipmaplevel is aligned to rowPitchAlignement boundary.
*/
std::vector<MipmapLevelInfo> upload_placed_texture(const rsx::texture &texture, size_t rowPitchAlignement, void* textureData) noexcept;
std::vector<MipmapLevelInfo> upload_placed_texture(const rsx::texture &texture, size_t rowPitchAlignement, void* textureData);
/**
* Get number of bytes occupied by texture in RSX mem
*/
size_t get_texture_size(const rsx::texture &texture) noexcept;
size_t get_texture_size(const rsx::texture &texture);

View File

@ -20,7 +20,7 @@ D3D12_GPU_VIRTUAL_ADDRESS createVertexBuffer(const rsx::data_array_format_info &
size_t heap_offset = vertex_index_heap.alloc(buffer_size);
void *buffer;
ThrowIfFailed(vertex_index_heap.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), (void**)&buffer));
CHECK_HRESULT(vertex_index_heap.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), (void**)&buffer));
void *bufferMap = (char*)buffer + heap_offset;
memcpy(bufferMap, vertex_data.data(), vertex_data.size());
vertex_index_heap.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
@ -62,7 +62,7 @@ void D3D12GSRender::upload_vertex_attributes(const std::vector<std::pair<u32, u3
size_t heap_offset = m_vertex_index_data.alloc(buffer_size);
void *buffer;
ThrowIfFailed(m_vertex_index_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), (void**)&buffer));
CHECK_HRESULT(m_vertex_index_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), (void**)&buffer));
void *mapped_buffer = (char*)buffer + heap_offset;
for (const auto &range : vertex_ranges)
{
@ -112,7 +112,7 @@ void D3D12GSRender::upload_vertex_attributes(const std::vector<std::pair<u32, u3
size_t heap_offset = m_vertex_index_data.alloc(buffer_size);
void *buffer;
ThrowIfFailed(m_vertex_index_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), (void**)&buffer));
CHECK_HRESULT(m_vertex_index_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), (void**)&buffer));
void *mapped_buffer = (char*)buffer + heap_offset;
memcpy(mapped_buffer, data.data(), data.size());
m_vertex_index_data.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
@ -149,7 +149,7 @@ void D3D12GSRender::upload_and_bind_scale_offset_matrix(size_t descriptorIndex)
// Scale offset buffer
// Separate constant buffer
void *mapped_buffer;
ThrowIfFailed(m_constants_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + 256), &mapped_buffer));
CHECK_HRESULT(m_constants_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + 256), &mapped_buffer));
fill_scale_offset_data((char*)mapped_buffer + heap_offset);
int is_alpha_tested = !!(rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE]);
float alpha_ref = (float&)rsx::method_registers[NV4097_SET_ALPHA_REF];
@ -190,7 +190,7 @@ void D3D12GSRender::upload_and_bind_vertex_shader_constants(size_t descriptor_in
size_t heap_offset = m_constants_data.alloc(buffer_size);
void *mapped_buffer;
ThrowIfFailed(m_constants_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), &mapped_buffer));
CHECK_HRESULT(m_constants_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), &mapped_buffer));
fill_vertex_program_constants_data((char*)mapped_buffer + heap_offset);
m_constants_data.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
@ -215,7 +215,7 @@ void D3D12GSRender::upload_and_bind_fragment_shader_constants(size_t descriptor_
size_t offset = 0;
void *mapped_buffer;
ThrowIfFailed(m_constants_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), &mapped_buffer));
CHECK_HRESULT(m_constants_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), &mapped_buffer));
m_pso_cache.fill_fragment_constans_buffer((char*)mapped_buffer + heap_offset, &fragment_program);
m_constants_data.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
@ -250,7 +250,7 @@ void D3D12GSRender::upload_and_set_vertex_index_data(ID3D12GraphicsCommandList *
size_t heap_offset = m_vertex_index_data.alloc(buffer_size);
void *buffer;
ThrowIfFailed(m_vertex_index_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), (void**)&buffer));
CHECK_HRESULT(m_vertex_index_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), (void**)&buffer));
void *mapped_buffer = (char*)buffer + heap_offset;
size_t first = 0;
for (const auto &pair : m_first_count_pairs)
@ -282,7 +282,7 @@ void D3D12GSRender::upload_and_set_vertex_index_data(ID3D12GraphicsCommandList *
size_t heap_offset = m_vertex_index_data.alloc(buffer_size);
void *buffer;
ThrowIfFailed(m_vertex_index_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), (void**)&buffer));
CHECK_HRESULT(m_vertex_index_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), (void**)&buffer));
void *mapped_buffer = (char*)buffer + heap_offset;
u32 min_index = (u32)-1, max_index = 0;
for (const auto &pair : m_first_count_pairs)

View File

@ -6,7 +6,7 @@
#include "Emu/RSX/GCM.h"
D3D12_BLEND_OP get_blend_op(u16 op) noexcept
D3D12_BLEND_OP get_blend_op(u16 op)
{
switch (op)
{
@ -18,12 +18,12 @@ D3D12_BLEND_OP get_blend_op(u16 op) noexcept
case CELL_GCM_FUNC_ADD_SIGNED:
case CELL_GCM_FUNC_REVERSE_ADD_SIGNED:
case CELL_GCM_FUNC_REVERSE_SUBTRACT_SIGNED:
unreachable("Unsupported blend op used %x, please report this to a developer.", op);
break;
}
unreachable("Unimplemented blend op used %x, please report this to a developer.", op);
throw EXCEPTION("Invalid or unsupported blend op (0x%x)", op);
}
D3D12_BLEND get_blend_factor(u16 factor) noexcept
D3D12_BLEND get_blend_factor(u16 factor)
{
switch (factor)
{
@ -42,12 +42,12 @@ D3D12_BLEND get_blend_factor(u16 factor) noexcept
case CELL_GCM_ONE_MINUS_CONSTANT_COLOR:
case CELL_GCM_CONSTANT_ALPHA:
case CELL_GCM_ONE_MINUS_CONSTANT_ALPHA:
unreachable("Unsupported blend color factor used %x, please report this to a developer.", factor);
break;
}
unreachable("Unimplemented blend color factor used %x, please report this to a developer.", factor);
throw EXCEPTION("Invalid or unsupported blend factor (0x%x)", factor);
}
D3D12_BLEND get_blend_factor_alpha(u16 factor) noexcept
D3D12_BLEND get_blend_factor_alpha(u16 factor)
{
switch (factor)
{
@ -66,15 +66,15 @@ D3D12_BLEND get_blend_factor_alpha(u16 factor) noexcept
case CELL_GCM_ONE_MINUS_CONSTANT_COLOR:
case CELL_GCM_CONSTANT_ALPHA:
case CELL_GCM_ONE_MINUS_CONSTANT_ALPHA:
unreachable("Unsupported blend alpha factor used %x, please report this to a developer.", factor);
break;
}
unreachable("Unimplemented blend alpha factor used %x, please report this to a developer.", factor);
throw EXCEPTION("Invalid or unsupported blend alpha factor (0x%x)", factor);
}
/**
* Convert GCM logic op code to D3D12 one
*/
D3D12_LOGIC_OP get_logic_op(u32 op) noexcept
D3D12_LOGIC_OP get_logic_op(u32 op)
{
switch (op)
{
@ -94,13 +94,13 @@ D3D12_LOGIC_OP get_logic_op(u32 op) noexcept
case CELL_GCM_OR_INVERTED: return D3D12_LOGIC_OP_OR_INVERTED;
case CELL_GCM_NAND: return D3D12_LOGIC_OP_NAND;
}
unreachable("Unimplemented logic op used %x, please report this to a developer.", op);
throw EXCEPTION("Invalid logic op (0x%x)", op);
}
/**
* Convert GCM stencil op code to D3D12 one
*/
D3D12_STENCIL_OP get_stencil_op(u32 op) noexcept
D3D12_STENCIL_OP get_stencil_op(u32 op)
{
switch (op)
{
@ -113,10 +113,10 @@ D3D12_STENCIL_OP get_stencil_op(u32 op) noexcept
case CELL_GCM_INCR_WRAP: return D3D12_STENCIL_OP_INCR;
case CELL_GCM_DECR_WRAP: return D3D12_STENCIL_OP_DECR;
}
unreachable("Unimplemented stencil op used %x, please report this to a developer.", op);
throw EXCEPTION("Invalid stencil op (0x%x)", op);
}
D3D12_COMPARISON_FUNC get_compare_func(u32 op) noexcept
D3D12_COMPARISON_FUNC get_compare_func(u32 op)
{
switch (op)
{
@ -129,12 +129,12 @@ D3D12_COMPARISON_FUNC get_compare_func(u32 op) noexcept
case CELL_GCM_GEQUAL: return D3D12_COMPARISON_FUNC_GREATER_EQUAL;
case CELL_GCM_ALWAYS: return D3D12_COMPARISON_FUNC_ALWAYS;
case CELL_GCM_ZERO:
unreachable("Unsupported compare function used %x, please report this to a developer.", op);
break;
}
unreachable("Unimplemented compare function used %x, please report this to a developer.", op);
throw EXCEPTION("Invalid or unsupported compare func (0x%x)", op);
}
DXGI_FORMAT get_texture_format(int format) noexcept
DXGI_FORMAT get_texture_format(u8 format)
{
switch (format)
{
@ -167,12 +167,12 @@ DXGI_FORMAT get_texture_format(int format) noexcept
case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8:
case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8:
case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8:
unreachable("Unsupported texture format used %x, please report this to a developer.", format);
break;
}
unreachable("Unimplemented texture format used %x, please report this to a developer.", format);
throw EXCEPTION("Invalid or unsupported texture format (0x%x)", format);
}
UINT get_texture_max_aniso(u8 aniso) noexcept
UINT get_texture_max_aniso(u8 aniso)
{
switch (aniso)
{
@ -185,10 +185,10 @@ UINT get_texture_max_aniso(u8 aniso) noexcept
case CELL_GCM_TEXTURE_MAX_ANISO_12: return 12;
case CELL_GCM_TEXTURE_MAX_ANISO_16: return 16;
}
unreachable("Unimplemented texture max aniso used %x, please report this to a developer.", aniso);
throw EXCEPTION("Invalid texture max aniso (0x%x)", aniso);
}
D3D12_TEXTURE_ADDRESS_MODE get_texture_wrap_mode(u8 wrap) noexcept
D3D12_TEXTURE_ADDRESS_MODE get_texture_wrap_mode(u8 wrap)
{
switch (wrap)
{
@ -201,12 +201,12 @@ D3D12_TEXTURE_ADDRESS_MODE get_texture_wrap_mode(u8 wrap) noexcept
case CELL_GCM_TEXTURE_MIRROR_ONCE_BORDER: return D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE;
case CELL_GCM_TEXTURE_MIRROR_ONCE_CLAMP: return D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE;
}
unreachable("Unimplemented texture wrap mode used %x, please report this to a developer.", wrap);
throw EXCEPTION("Invalid texture wrap mode (0x%x)", wrap);
}
namespace
{
void get_min_filter(u8 min_filter, D3D12_FILTER_TYPE &min, D3D12_FILTER_TYPE &mip) noexcept
void get_min_filter(u8 min_filter, D3D12_FILTER_TYPE &min, D3D12_FILTER_TYPE &mip)
{
switch (min_filter)
{
@ -239,21 +239,21 @@ namespace
mip = D3D12_FILTER_TYPE_POINT;
return;
}
unreachable("Unimplemented min filter used %x, please report this to a developer.", min_filter);
throw EXCEPTION("Invalid max filter (0x%x)", min_filter);
}
D3D12_FILTER_TYPE get_mag_filter(u8 mag_filter) noexcept
D3D12_FILTER_TYPE get_mag_filter(u8 mag_filter)
{
switch (mag_filter)
{
case CELL_GCM_TEXTURE_NEAREST: return D3D12_FILTER_TYPE_POINT;
case CELL_GCM_TEXTURE_LINEAR: return D3D12_FILTER_TYPE_LINEAR;
}
unreachable("Unimplemented mag filter used %x, please report this to a developer.", mag_filter);
throw EXCEPTION("Invalid mag filter (0x%x)", mag_filter);
}
}
D3D12_FILTER get_texture_filter(u8 min_filter, u8 mag_filter) noexcept
D3D12_FILTER get_texture_filter(u8 min_filter, u8 mag_filter)
{
D3D12_FILTER_TYPE min, mip;
get_min_filter(min_filter, min, mip);
@ -261,7 +261,7 @@ D3D12_FILTER get_texture_filter(u8 min_filter, u8 mag_filter) noexcept
return D3D12_ENCODE_BASIC_FILTER(min, mag, mip, D3D12_FILTER_REDUCTION_TYPE_STANDARD);
}
D3D12_PRIMITIVE_TOPOLOGY get_primitive_topology(u8 draw_mode) noexcept
D3D12_PRIMITIVE_TOPOLOGY get_primitive_topology(u8 draw_mode)
{
switch (draw_mode)
{
@ -276,10 +276,10 @@ D3D12_PRIMITIVE_TOPOLOGY get_primitive_topology(u8 draw_mode) noexcept
case CELL_GCM_PRIMITIVE_QUAD_STRIP: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
case CELL_GCM_PRIMITIVE_POLYGON: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
}
unreachable("Unimplemented draw mode used %x, please report this to a developer.", draw_mode);
throw EXCEPTION("Invalid draw mode (0x%x)", draw_mode);
}
D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(u8 draw_mode) noexcept
D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(u8 draw_mode)
{
switch (draw_mode)
{
@ -293,12 +293,12 @@ D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(u8 draw_mode) noexcept
case CELL_GCM_PRIMITIVE_QUAD_STRIP: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
case CELL_GCM_PRIMITIVE_POLYGON: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
case CELL_GCM_PRIMITIVE_LINE_LOOP:
unreachable("Unsupported draw mode used %x, please report this to a developer.", draw_mode);
break;
}
unreachable("Unimplemented draw mode used %x, please report this to a developer.", draw_mode);
throw EXCEPTION("Invalid or unsupported draw mode (0x%x)", draw_mode);
}
DXGI_FORMAT get_color_surface_format(u8 format) noexcept
DXGI_FORMAT get_color_surface_format(u8 format)
{
switch (format)
{
@ -307,71 +307,71 @@ DXGI_FORMAT get_color_surface_format(u8 format) noexcept
case CELL_GCM_SURFACE_F_W16Z16Y16X16: return DXGI_FORMAT_R16G16B16A16_FLOAT;
case CELL_GCM_SURFACE_F_X32: return DXGI_FORMAT_R32_FLOAT;
}
unreachable("Unimplemented color surface format used %x, please report this to a developer.", format);
throw EXCEPTION("Invalid format (0x%x)", format);
}
DXGI_FORMAT get_depth_stencil_surface_format(u8 format) noexcept
DXGI_FORMAT get_depth_stencil_surface_format(u8 format)
{
switch (format)
{
case CELL_GCM_SURFACE_Z16: return DXGI_FORMAT_D16_UNORM;
case CELL_GCM_SURFACE_Z24S8: return DXGI_FORMAT_D24_UNORM_S8_UINT;
}
unreachable("Unimplemented depth stencil surface format used %x, please report this to a developer.", format);
throw EXCEPTION("Invalid format (0x%x)", format);
}
DXGI_FORMAT get_depth_stencil_surface_clear_format(u8 format) noexcept
DXGI_FORMAT get_depth_stencil_surface_clear_format(u8 format)
{
switch (format)
{
case CELL_GCM_SURFACE_Z16: return DXGI_FORMAT_D16_UNORM;
case CELL_GCM_SURFACE_Z24S8: return DXGI_FORMAT_D24_UNORM_S8_UINT;
}
unreachable("Unimplemented depth stencil surface format used %x, please report this to a developer.", format);
throw EXCEPTION("Invalid format (0x%x)", format);
}
DXGI_FORMAT get_depth_stencil_typeless_surface_format(u8 format) noexcept
DXGI_FORMAT get_depth_stencil_typeless_surface_format(u8 format)
{
switch (format)
{
case CELL_GCM_SURFACE_Z16: return DXGI_FORMAT_R16_TYPELESS;
case CELL_GCM_SURFACE_Z24S8: return DXGI_FORMAT_R24G8_TYPELESS;
}
unreachable("Unimplemented depth stencil surface format used %x, please report this to a developer.", format);
throw EXCEPTION("Invalid format (0x%x)", format);
}
DXGI_FORMAT get_depth_samplable_surface_format(u8 format) noexcept
DXGI_FORMAT get_depth_samplable_surface_format(u8 format)
{
switch (format)
{
case CELL_GCM_SURFACE_Z16: return DXGI_FORMAT_R16_FLOAT;
case CELL_GCM_SURFACE_Z24S8: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
}
unreachable("Unimplemented depth stencil surface format used %x, please report this to a developer.", format);
throw EXCEPTION("Invalid format (0x%x)", format);
}
BOOL get_front_face_ccw(u32 set_front_face_value) noexcept
BOOL get_front_face_ccw(u32 ffv)
{
switch (set_front_face_value)
switch (ffv)
{
default: // Disgaea 3 pass some garbage value at startup, this is needed to survive.
case CELL_GCM_CW: return FALSE;
case CELL_GCM_CCW: return TRUE;
}
unreachable("Unimplemented front face value used %x, please report this to a developer.", set_front_face_value);
throw EXCEPTION("Invalid front face value (0x%x)", ffv);
}
DXGI_FORMAT get_index_type(u8 index_type) noexcept
DXGI_FORMAT get_index_type(u8 index_type)
{
switch (index_type)
{
case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: return DXGI_FORMAT_R16_UINT;
case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: return DXGI_FORMAT_R32_UINT;
}
unreachable("Unimplemented index type used %x, please report this to a developer.", index_type);
throw EXCEPTION("Invalid index_type (0x%x)", index_type);
}
DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size) noexcept
DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size)
{
switch (type)
{
@ -384,7 +384,7 @@ DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size) noexcept
case 3: return DXGI_FORMAT_R16G16B16A16_SNORM; // No 3 channel type
case 4: return DXGI_FORMAT_R16G16B16A16_SNORM;
}
unreachable("Unimplemented type size used %x, please report this to a developer.", size);
break;
}
case CELL_GCM_VERTEX_F:
{
@ -395,7 +395,7 @@ DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size) noexcept
case 3: return DXGI_FORMAT_R32G32B32_FLOAT;
case 4: return DXGI_FORMAT_R32G32B32A32_FLOAT;
}
unreachable("Unimplemented type size used %x, please report this to a developer.", size);
break;
}
case CELL_GCM_VERTEX_SF:
{
@ -406,7 +406,7 @@ DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size) noexcept
case 3: return DXGI_FORMAT_R16G16B16A16_FLOAT; // No 3 channel type
case 4: return DXGI_FORMAT_R16G16B16A16_FLOAT;
}
unreachable("Unimplemented type size used %x, please report this to a developer.", size);
break;
}
case CELL_GCM_VERTEX_UB:
{
@ -417,7 +417,7 @@ DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size) noexcept
case 3: return DXGI_FORMAT_R8G8B8A8_UNORM; // No 3 channel type
case 4: return DXGI_FORMAT_R8G8B8A8_UNORM;
}
unreachable("Unimplemented type size used %x, please report this to a developer.", size);
break;
}
case CELL_GCM_VERTEX_S32K:
{
@ -428,7 +428,7 @@ DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size) noexcept
case 3: return DXGI_FORMAT_R16G16B16A16_SINT; // No 3 channel type
case 4: return DXGI_FORMAT_R16G16B16A16_SINT;
}
unreachable("Unimplemented type size used %x, please report this to a developer.", size);
break;
}
case CELL_GCM_VERTEX_CMP:
{
@ -439,7 +439,7 @@ DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size) noexcept
case 3: return DXGI_FORMAT_R32G32B32_FLOAT;
case 4: return DXGI_FORMAT_R32G32B32A32_FLOAT;
}
unreachable("Unimplemented type size used %x, please report this to a developer.", size);
break;
}
case CELL_GCM_VERTEX_UB256:
{
@ -450,13 +450,14 @@ DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size) noexcept
case 3: return DXGI_FORMAT_R8G8B8A8_UINT; // No 3 channel type
case 4: return DXGI_FORMAT_R8G8B8A8_UINT;
}
unreachable("Unimplemented type size used %x, please report this to a developer.", size);
break;
}
}
unreachable("Unimplemented type used %x, please report this to a developer.", size);
throw EXCEPTION("Invalid or unsupported type or size (type=0x%x, size=0x%x)", type, size);
}
D3D12_RECT get_scissor(u32 horizontal, u32 vertical) noexcept
D3D12_RECT get_scissor(u32 horizontal, u32 vertical)
{
return{
horizontal & 0xFFFF,

View File

@ -5,105 +5,105 @@
/**
* Convert GCM blend operator code to D3D12 one
*/
D3D12_BLEND_OP get_blend_op(u16 op) noexcept;
D3D12_BLEND_OP get_blend_op(u16 op);
/**
* Convert GCM blend factor code to D3D12 one
*/
D3D12_BLEND get_blend_factor(u16 factor) noexcept;
D3D12_BLEND get_blend_factor(u16 factor);
/**
* Convert GCM blend factor code to D3D12 one for alpha component
*/
D3D12_BLEND get_blend_factor_alpha(u16 factor) noexcept;
D3D12_BLEND get_blend_factor_alpha(u16 factor);
/**
* Convert GCM logic op code to D3D12 one
*/
D3D12_LOGIC_OP get_logic_op(u32 op) noexcept;
D3D12_LOGIC_OP get_logic_op(u32 op);
/**
* Convert GCM stencil op code to D3D12 one
*/
D3D12_STENCIL_OP get_stencil_op(u32 op) noexcept;
D3D12_STENCIL_OP get_stencil_op(u32 op);
/**
* Convert GCM comparison function code to D3D12 one.
*/
D3D12_COMPARISON_FUNC get_compare_func(u32 op) noexcept;
D3D12_COMPARISON_FUNC get_compare_func(u32 op);
/**
* Convert GCM texture format to an equivalent one supported by D3D12.
* Destination format may require a byte swap or data conversion.
*/
DXGI_FORMAT get_texture_format(int format) noexcept;
DXGI_FORMAT get_texture_format(u8 format);
/**
* Convert texture aniso value to UINT.
*/
UINT get_texture_max_aniso(u8 aniso) noexcept;
UINT get_texture_max_aniso(u8 aniso);
/**
* Convert texture wrap mode to D3D12_TEXTURE_ADDRESS_MODE
*/
D3D12_TEXTURE_ADDRESS_MODE get_texture_wrap_mode(u8 wrap) noexcept;
D3D12_TEXTURE_ADDRESS_MODE get_texture_wrap_mode(u8 wrap);
/**
* Convert minify and magnify filter to D3D12_FILTER
*/
D3D12_FILTER get_texture_filter(u8 min_filter, u8 mag_filter) noexcept;
D3D12_FILTER get_texture_filter(u8 min_filter, u8 mag_filter);
/**
* Convert draw mode to D3D12_PRIMITIVE_TOPOLOGY
*/
D3D12_PRIMITIVE_TOPOLOGY get_primitive_topology(u8 draw_mode) noexcept;
D3D12_PRIMITIVE_TOPOLOGY get_primitive_topology(u8 draw_mode);
/**
* Convert draw mode to D3D12_PRIMITIVE_TOPOLOGY_TYPE
*/
D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(u8 draw_mode) noexcept;
D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(u8 draw_mode);
/**
* Convert color surface format to DXGI_FORMAT
*/
DXGI_FORMAT get_color_surface_format(u8 format) noexcept;
DXGI_FORMAT get_color_surface_format(u8 format);
/**
* Convert depth stencil surface format to DXGI_FORMAT
*/
DXGI_FORMAT get_depth_stencil_surface_format(u8 format) noexcept;
DXGI_FORMAT get_depth_stencil_surface_format(u8 format);
/**
*Convert depth stencil surface format to DXGI_FORMAT suited for clear value
*/
DXGI_FORMAT get_depth_stencil_surface_clear_format(u8 format) noexcept;
DXGI_FORMAT get_depth_stencil_surface_clear_format(u8 format);
/**
* Convert depth surface format to a typeless DXGI_FORMAT
*/
DXGI_FORMAT get_depth_stencil_typeless_surface_format(u8 format) noexcept;
DXGI_FORMAT get_depth_stencil_typeless_surface_format(u8 format);
/**
* Convert depth surface format to a DXGI_FORMAT that can be depth sampled
*/
DXGI_FORMAT get_depth_samplable_surface_format(u8 format) noexcept;
DXGI_FORMAT get_depth_samplable_surface_format(u8 format);
/**
* Convert front face value to bool value telling wheter front face is counterclockwise or not
*/
BOOL get_front_face_ccw(u32 set_front_face_value) noexcept;
BOOL get_front_face_ccw(u32 set_front_face_value);
/**
* Convert index type to DXGI_FORMAT
*/
DXGI_FORMAT get_index_type(u8 index_type) noexcept;
DXGI_FORMAT get_index_type(u8 index_type);
/**
* Convert vertex attribute format and size to DXGI_FORMAT
*/
DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size) noexcept;
DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size);
/**
* Convert scissor register value to D3D12_RECT
*/
D3D12_RECT get_scissor(u32 horizontal, u32 vertical) noexcept;
D3D12_RECT get_scissor(u32 horizontal, u32 vertical);

View File

@ -25,15 +25,11 @@ HMODULE D3DCompiler;
void loadD3D12FunctionPointers()
{
D3D12Module = LoadLibrary(L"d3d12.dll");
if (!D3D12Module)
unreachable("Failed to load d3d12.dll");
CHECK_ASSERTION(D3D12Module = LoadLibrary(L"d3d12.dll"));
wrapD3D12CreateDevice = (PFN_D3D12_CREATE_DEVICE)GetProcAddress(D3D12Module, "D3D12CreateDevice");
wrapD3D12GetDebugInterface = (PFN_D3D12_GET_DEBUG_INTERFACE)GetProcAddress(D3D12Module, "D3D12GetDebugInterface");
wrapD3D12SerializeRootSignature = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)GetProcAddress(D3D12Module, "D3D12SerializeRootSignature");
D3D11Module = LoadLibrary(L"d3d11.dll");
if (!D3D11Module)
unreachable("Failed to load d3d11.dll");
CHECK_ASSERTION(D3D11Module = LoadLibrary(L"d3d11.dll"));
wrapD3D11On12CreateDevice = (PFN_D3D11ON12_CREATE_DEVICE)GetProcAddress(D3D11Module, "D3D11On12CreateDevice");
CHECK_ASSERTION(D3DCompiler = LoadLibrary(L"d3dcompiler_47.dll"));
wrapD3DCompile = (pD3DCompile)GetProcAddress(D3DCompiler, "D3DCompile");
@ -52,7 +48,7 @@ void unloadD3D12FunctionPointers()
void wait_for_command_queue(ID3D12Device *device, ID3D12CommandQueue *command_queue)
{
ComPtr<ID3D12Fence> fence;
ThrowIfFailed(device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(fence.GetAddressOf())));
CHECK_HRESULT(device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(fence.GetAddressOf())));
HANDLE handle = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS);
fence->SetEventOnCompletion(1, handle);
command_queue->Signal(fence.Get(), 1);
@ -100,7 +96,7 @@ D3D12GSRender::D3D12GSRender()
gfxHandler = [this](u32 addr) {
bool result = invalidate_address(addr);
if (result)
LOG_WARNING(RSX, "Reporting Cell writing to %x", addr);
LOG_WARNING(RSX, "Reporting Cell writing to 0x%x", addr);
return result;
};
if (rpcs3::config.rsx.d3d12.debug_output.value())
@ -111,15 +107,15 @@ D3D12GSRender::D3D12GSRender()
}
Microsoft::WRL::ComPtr<IDXGIFactory4> dxgi_factory;
ThrowIfFailed(CreateDXGIFactory(IID_PPV_ARGS(&dxgi_factory)));
CHECK_HRESULT(CreateDXGIFactory(IID_PPV_ARGS(&dxgi_factory)));
// Create adapter
ComPtr<IDXGIAdapter> adaptater = nullptr;
ThrowIfFailed(dxgi_factory->EnumAdapters(rpcs3::state.config.rsx.d3d12.adaptater.value(), adaptater.GetAddressOf()));
ThrowIfFailed(wrapD3D12CreateDevice(adaptater.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device)));
CHECK_HRESULT(dxgi_factory->EnumAdapters(rpcs3::state.config.rsx.d3d12.adaptater.value(), adaptater.GetAddressOf()));
CHECK_HRESULT(wrapD3D12CreateDevice(adaptater.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device)));
// Queues
D3D12_COMMAND_QUEUE_DESC graphic_queue_desc = { D3D12_COMMAND_LIST_TYPE_DIRECT };
ThrowIfFailed(m_device->CreateCommandQueue(&graphic_queue_desc, IID_PPV_ARGS(m_command_queue.GetAddressOf())));
CHECK_HRESULT(m_device->CreateCommandQueue(&graphic_queue_desc, IID_PPV_ARGS(m_command_queue.GetAddressOf())));
g_descriptor_stride_srv_cbv_uav = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
g_descriptor_stride_dsv = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
@ -137,7 +133,7 @@ D3D12GSRender::D3D12GSRender()
swap_chain.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
swap_chain.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
ThrowIfFailed(dxgi_factory->CreateSwapChain(m_command_queue.Get(), &swap_chain, (IDXGISwapChain**)m_swap_chain.GetAddressOf()));
CHECK_HRESULT(dxgi_factory->CreateSwapChain(m_command_queue.Get(), &swap_chain, (IDXGISwapChain**)m_swap_chain.GetAddressOf()));
m_swap_chain->GetBuffer(0, IID_PPV_ARGS(&m_backbuffer[0]));
m_swap_chain->GetBuffer(1, IID_PPV_ARGS(&m_backbuffer[1]));
@ -170,7 +166,7 @@ D3D12GSRender::D3D12GSRender()
Microsoft::WRL::ComPtr<ID3DBlob> rootSignatureBlob;
Microsoft::WRL::ComPtr<ID3DBlob> errorBlob;
ThrowIfFailed(wrapD3D12SerializeRootSignature(
CHECK_HRESULT(wrapD3D12SerializeRootSignature(
&CD3DX12_ROOT_SIGNATURE_DESC((texture_count > 0) ? 2 : 1, RP, 0, 0, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT),
D3D_ROOT_SIGNATURE_VERSION_1, &rootSignatureBlob, &errorBlob));
@ -188,7 +184,7 @@ D3D12GSRender::D3D12GSRender()
initConvertShader();
m_output_scaling_pass.Init(m_device.Get(), m_command_queue.Get());
ThrowIfFailed(
CHECK_HRESULT(
m_device->CreateCommittedResource(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
D3D12_HEAP_FLAG_NONE,
@ -368,7 +364,7 @@ void D3D12GSRender::end()
if (rpcs3::config.rsx.d3d12.debug_output.value())
{
ThrowIfFailed(get_current_resource_storage().command_list->Close());
CHECK_HRESULT(get_current_resource_storage().command_list->Close());
m_command_queue->ExecuteCommandLists(1, (ID3D12CommandList**)get_current_resource_storage().command_list.GetAddressOf());
get_current_resource_storage().set_new_command_list();
}
@ -392,7 +388,7 @@ bool is_flip_surface_in_global_memory(u32 color_target)
case CELL_GCM_SURFACE_TARGET_NONE:
return false;
}
unreachable("Wrong color target");
throw EXCEPTION("Wrong color_target (%u)", color_target);
}
}
@ -423,7 +419,7 @@ void D3D12GSRender::flip(int buffer)
size_t heap_offset = m_texture_upload_data.alloc(texture_size);
void *buffer;
ThrowIfFailed(m_texture_upload_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + texture_size), &buffer));
CHECK_HRESULT(m_texture_upload_data.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + texture_size), &buffer));
void *mapped_buffer = (char*)buffer + heap_offset;
for (unsigned row = 0; row < h; row++)
memcpy((char*)mapped_buffer + row * row_pitch, (char*)src_buffer + row * w * 4, w * 4);
@ -431,7 +427,7 @@ void D3D12GSRender::flip(int buffer)
offset = heap_offset;
}
ThrowIfFailed(
CHECK_HRESULT(
m_device->CreateCommittedResource(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
D3D12_HEAP_FLAG_NONE,
@ -540,7 +536,7 @@ void D3D12GSRender::flip(int buffer)
get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_backbuffer[m_swap_chain->GetCurrentBackBufferIndex()].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT));
if (is_flip_surface_in_global_memory(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]) && resource_to_flip != nullptr)
get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(resource_to_flip, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_RENDER_TARGET));
ThrowIfFailed(get_current_resource_storage().command_list->Close());
CHECK_HRESULT(get_current_resource_storage().command_list->Close());
m_command_queue->ExecuteCommandLists(1, (ID3D12CommandList**)get_current_resource_storage().command_list.GetAddressOf());
if(rpcs3::config.rsx.d3d12.overlay.value())
@ -550,7 +546,7 @@ void D3D12GSRender::flip(int buffer)
std::chrono::time_point<std::chrono::system_clock> flip_start = std::chrono::system_clock::now();
ThrowIfFailed(m_swap_chain->Present(rpcs3::state.config.rsx.vsync.value() ? 1 : 0, 0));
CHECK_HRESULT(m_swap_chain->Present(rpcs3::state.config.rsx.vsync.value() ? 1 : 0, 0));
// Add an event signaling queue completion
resource_storage &storage = get_non_current_resource_storage();

View File

@ -4,14 +4,14 @@
#include "D3D12MemoryHelpers.h"
void data_cache::store_and_protect_data(u64 key, u32 start, size_t size, int format, size_t w, size_t h, size_t m, ComPtr<ID3D12Resource> data) noexcept
void data_cache::store_and_protect_data(u64 key, u32 start, size_t size, u8 format, size_t w, size_t h, size_t m, ComPtr<ID3D12Resource> data)
{
std::lock_guard<std::mutex> lock(m_mut);
m_address_to_data[key] = std::make_pair(texture_entry(format, w, h, m), data);
protect_data(key, start, size);
}
void data_cache::protect_data(u64 key, u32 start, size_t size) noexcept
void data_cache::protect_data(u64 key, u32 start, size_t size)
{
/// align start to 4096 byte
u32 protected_range_start = align(start, 4096);
@ -20,7 +20,7 @@ void data_cache::protect_data(u64 key, u32 start, size_t size) noexcept
vm::page_protect(protected_range_start, protected_range_size, 0, 0, vm::page_writable);
}
bool data_cache::invalidate_address(u32 addr) noexcept
bool data_cache::invalidate_address(u32 addr)
{
bool handled = false;
auto It = m_protected_ranges.begin(), E = m_protected_ranges.end();
@ -44,7 +44,7 @@ bool data_cache::invalidate_address(u32 addr) noexcept
return handled;
}
std::pair<texture_entry, ComPtr<ID3D12Resource> > *data_cache::find_data_if_available(u64 key) noexcept
std::pair<texture_entry, ComPtr<ID3D12Resource> > *data_cache::find_data_if_available(u64 key)
{
std::lock_guard<std::mutex> lock(m_mut);
auto It = m_address_to_data.find(key);
@ -53,7 +53,7 @@ std::pair<texture_entry, ComPtr<ID3D12Resource> > *data_cache::find_data_if_avai
return &It->second;
}
void data_cache::unprotect_all() noexcept
void data_cache::unprotect_all()
{
std::lock_guard<std::mutex> lock(m_mut);
for (auto &protectedTexture : m_protected_ranges)
@ -63,7 +63,7 @@ void data_cache::unprotect_all() noexcept
}
}
ComPtr<ID3D12Resource> data_cache::remove_from_cache(u64 key) noexcept
ComPtr<ID3D12Resource> data_cache::remove_from_cache(u64 key)
{
auto result = m_address_to_data[key].second;
m_address_to_data.erase(key);
@ -78,13 +78,13 @@ void resource_storage::reset()
render_targets_descriptors_heap_index = 0;
depth_stencil_descriptor_heap_index = 0;
ThrowIfFailed(command_allocator->Reset());
CHECK_HRESULT(command_allocator->Reset());
set_new_command_list();
}
void resource_storage::set_new_command_list()
{
ThrowIfFailed(command_list->Reset(command_allocator.Get(), nullptr));
CHECK_HRESULT(command_list->Reset(command_allocator.Get(), nullptr));
}
void resource_storage::init(ID3D12Device *device)
@ -93,17 +93,17 @@ void resource_storage::init(ID3D12Device *device)
m_device = device;
ram_framebuffer = nullptr;
// Create a global command allocator
ThrowIfFailed(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(command_allocator.GetAddressOf())));
CHECK_HRESULT(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(command_allocator.GetAddressOf())));
ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, command_allocator.Get(), nullptr, IID_PPV_ARGS(command_list.GetAddressOf())));
ThrowIfFailed(command_list->Close());
CHECK_HRESULT(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, command_allocator.Get(), nullptr, IID_PPV_ARGS(command_list.GetAddressOf())));
CHECK_HRESULT(command_list->Close());
D3D12_DESCRIPTOR_HEAP_DESC descriptor_heap_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 10000, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE };
ThrowIfFailed(device->CreateDescriptorHeap(&descriptor_heap_desc, IID_PPV_ARGS(&descriptors_heap)));
CHECK_HRESULT(device->CreateDescriptorHeap(&descriptor_heap_desc, IID_PPV_ARGS(&descriptors_heap)));
D3D12_DESCRIPTOR_HEAP_DESC sampler_heap_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER , 2048, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE };
ThrowIfFailed(device->CreateDescriptorHeap(&sampler_heap_desc, IID_PPV_ARGS(&sampler_descriptor_heap[0])));
ThrowIfFailed(device->CreateDescriptorHeap(&sampler_heap_desc, IID_PPV_ARGS(&sampler_descriptor_heap[1])));
CHECK_HRESULT(device->CreateDescriptorHeap(&sampler_heap_desc, IID_PPV_ARGS(&sampler_descriptor_heap[0])));
CHECK_HRESULT(device->CreateDescriptorHeap(&sampler_heap_desc, IID_PPV_ARGS(&sampler_descriptor_heap[1])));
D3D12_DESCRIPTOR_HEAP_DESC ds_descriptor_heap_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_DSV , 10000};
device->CreateDescriptorHeap(&ds_descriptor_heap_desc, IID_PPV_ARGS(&depth_stencil_descriptor_heap));
@ -113,7 +113,7 @@ void resource_storage::init(ID3D12Device *device)
frame_finished_handle = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS);
fence_value = 0;
ThrowIfFailed(device->CreateFence(fence_value++, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(frame_finished_fence.GetAddressOf())));
CHECK_HRESULT(device->CreateFence(fence_value++, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(frame_finished_fence.GetAddressOf())));
}
void resource_storage::wait_and_clean()
@ -121,7 +121,7 @@ void resource_storage::wait_and_clean()
if (in_use)
WaitForSingleObjectEx(frame_finished_handle, INFINITE, FALSE);
else
ThrowIfFailed(command_list->Close());
CHECK_HRESULT(command_list->Close());
reset();

View File

@ -19,7 +19,7 @@ struct init_heap<ID3D12Heap>
heap_desc.SizeInBytes = heap_size;
heap_desc.Properties.Type = type;
heap_desc.Flags = flags;
ThrowIfFailed(device->CreateHeap(&heap_desc, IID_PPV_ARGS(&result)));
CHECK_HRESULT(device->CreateHeap(&heap_desc, IID_PPV_ARGS(&result)));
return result;
}
};
@ -32,7 +32,7 @@ struct init_heap<ID3D12Resource>
ID3D12Resource *result;
D3D12_HEAP_PROPERTIES heap_properties = {};
heap_properties.Type = type;
ThrowIfFailed(device->CreateCommittedResource(&heap_properties,
CHECK_HRESULT(device->CreateCommittedResource(&heap_properties,
D3D12_HEAP_FLAG_NONE,
&CD3DX12_RESOURCE_DESC::Buffer(heap_size),
state,
@ -72,7 +72,7 @@ struct data_heap
/**
* Does alloc cross get position ?
*/
bool can_alloc(size_t size) const noexcept
bool can_alloc(size_t size) const
{
size_t alloc_size = align(size, alignment);
if (m_put_pos + alloc_size < m_size)
@ -98,7 +98,7 @@ struct data_heap
}
}
size_t alloc(size_t size) noexcept
size_t alloc(size_t size)
{
assert(can_alloc(size));
size_t alloc_size = align(size, alignment);
@ -115,7 +115,7 @@ struct data_heap
}
}
void release() noexcept
void release()
{
m_heap->Release();
}
@ -123,7 +123,7 @@ struct data_heap
/**
* return current putpos - 1
*/
size_t get_current_put_pos_minus_one() const noexcept
size_t get_current_put_pos_minus_one() const
{
return (m_put_pos - 1 > 0) ? m_put_pos - 1 : m_size - 1;
}
@ -131,16 +131,16 @@ struct data_heap
struct texture_entry
{
int m_format;
u8 m_format;
bool m_is_dirty;
size_t m_width;
size_t m_height;
size_t m_mipmap;
bool m_is_dirty;
texture_entry() : m_format(0), m_width(0), m_height(0), m_is_dirty(true)
{}
texture_entry(int f, size_t w, size_t h, size_t m) : m_format(f), m_width(w), m_height(h), m_is_dirty(false)
texture_entry(u8 f, size_t w, size_t h, size_t m) : m_format(f), m_width(w), m_height(h), m_is_dirty(false)
{}
bool operator==(const texture_entry &other)
@ -165,28 +165,28 @@ private:
std::unordered_map<u64, std::pair<texture_entry, ComPtr<ID3D12Resource>> > m_address_to_data; // Storage
std::list <std::tuple<u64, u32, u32> > m_protected_ranges; // address, start of protected range, size of protected range
public:
void store_and_protect_data(u64 key, u32 start, size_t size, int format, size_t w, size_t h, size_t m, ComPtr<ID3D12Resource> data) noexcept;
void store_and_protect_data(u64 key, u32 start, size_t size, u8 format, size_t w, size_t h, size_t m, ComPtr<ID3D12Resource> data);
/**
* Make memory from start to start + size write protected.
* Associate key to this range so that when a write is detected, data at key is marked dirty.
*/
void protect_data(u64 key, u32 start, size_t size) noexcept;
void protect_data(u64 key, u32 start, size_t size);
/**
* Remove all data containing addr from cache, unprotect them. Returns false if no data is modified.
*/
bool invalidate_address(u32 addr) noexcept;
bool invalidate_address(u32 addr);
std::pair<texture_entry, ComPtr<ID3D12Resource> > *find_data_if_available(u64 key) noexcept;
std::pair<texture_entry, ComPtr<ID3D12Resource> > *find_data_if_available(u64 key);
void unprotect_all() noexcept;
void unprotect_all();
/**
* Remove data stored at key, and returns a ComPtr owning it.
* The caller is responsible for releasing the ComPtr.
*/
ComPtr<ID3D12Resource> remove_from_cache(u64 key) noexcept;
ComPtr<ID3D12Resource> remove_from_cache(u64 key);
};
/**

View File

@ -24,7 +24,7 @@ ComPtr<ID2D1Bitmap1> g_d2d_render_targets[2];
ComPtr<IDWriteTextFormat> g_text_format;
ComPtr<ID2D1SolidColorBrush> g_text_brush;
void draw_strings(const D2D1_SIZE_F &rtSize, size_t backbuffer_id, const std::vector<std::wstring> &strings) noexcept
void draw_strings(const D2D1_SIZE_F &rtSize, size_t backbuffer_id, const std::vector<std::wstring> &strings)
{
// Acquire our wrapped render target resource for the current back buffer.
g_d3d11on12_device->AcquireWrappedResources(g_wrapped_backbuffers[backbuffer_id ].GetAddressOf(), 1);

View File

@ -166,8 +166,7 @@ struct D3D12Traits
}
}
// TODO: This shouldn't use current dir
fs::file("./FragmentProgram" + std::to_string(ID) + ".hlsl", fom::rewrite) << shader;
fs::file(fs::get_config_dir() + "FragmentProgram" + std::to_string(ID) + ".hlsl", fom::rewrite) << shader;
fragmentProgramData.id = (u32)ID;
}
@ -178,8 +177,7 @@ struct D3D12Traits
std::string shaderCode = VS.Decompile();
vertexProgramData.Compile(shaderCode, Shader::SHADER_TYPE::SHADER_TYPE_VERTEX);
vertexProgramData.vertex_shader_inputs = VS.input_slots;
// TODO: This shouldn't use current dir
fs::file("./VertexProgram" + std::to_string(ID) + ".hlsl", fom::rewrite) << shaderCode;
fs::file(fs::get_config_dir() + "VertexProgram" + std::to_string(ID) + ".hlsl", fom::rewrite) << shaderCode;
vertexProgramData.id = (u32)ID;
}

View File

@ -17,7 +17,7 @@
namespace
{
UINT get_num_rtt(u8 color_target) noexcept
UINT get_num_rtt(u8 color_target)
{
switch (color_target)
{
@ -28,10 +28,10 @@ namespace
case CELL_GCM_SURFACE_TARGET_MRT2: return 3;
case CELL_GCM_SURFACE_TARGET_MRT3: return 4;
}
unreachable("Wrong color target");
throw EXCEPTION("Wrong color_target (%d)", color_target);
}
std::vector<u8> get_rtt_indexes(u8 color_target) noexcept
std::vector<u8> get_rtt_indexes(u8 color_target)
{
switch (color_target)
{
@ -42,10 +42,10 @@ namespace
case CELL_GCM_SURFACE_TARGET_MRT2: return{ 0, 1, 2 };
case CELL_GCM_SURFACE_TARGET_MRT3: return{ 0, 1, 2, 3 };
}
unreachable("Wrong color target");
throw EXCEPTION("Wrong color_target (%d)", color_target);
}
std::array<float, 4> get_clear_color(u32 clear_color) noexcept
std::array<float, 4> get_clear_color(u32 clear_color)
{
u8 clear_a = clear_color >> 24;
u8 clear_r = clear_color >> 16;
@ -60,7 +60,7 @@ namespace
};
}
u8 get_clear_stencil(u32 register_value) noexcept
u8 get_clear_stencil(u32 register_value)
{
return register_value & 0xff;
}
@ -113,7 +113,7 @@ void D3D12GSRender::clear_surface(u32 arg)
if (rpcs3::config.rsx.d3d12.debug_output.value())
{
ThrowIfFailed(get_current_resource_storage().command_list->Close());
CHECK_HRESULT(get_current_resource_storage().command_list->Close());
m_command_queue->ExecuteCommandLists(1, (ID3D12CommandList**)get_current_resource_storage().command_list.GetAddressOf());
get_current_resource_storage().set_new_command_list();
}
@ -402,7 +402,7 @@ namespace
{
void *buffer;
// TODO: Use exact range
ThrowIfFailed(readback_heap.m_heap->Map(0, nullptr, &buffer));
CHECK_HRESULT(readback_heap.m_heap->Map(0, nullptr, &buffer));
void *mapped_buffer = (char*)buffer + offset_in_heap;
for (unsigned row = 0; row < height; row++)
{
@ -417,7 +417,7 @@ namespace
void wait_for_command_queue(ID3D12Device *device, ID3D12CommandQueue *command_queue)
{
ComPtr<ID3D12Fence> fence;
ThrowIfFailed(device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(fence.GetAddressOf())));
CHECK_HRESULT(device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(fence.GetAddressOf())));
HANDLE handle = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS);
fence->SetEventOnCompletion(1, handle);
command_queue->Signal(fence.Get(), 1);
@ -474,7 +474,7 @@ void D3D12GSRender::copy_render_target_to_dma_location()
assert(m_uav_heap.can_alloc(uav_size));
size_t heap_offset = m_uav_heap.alloc(uav_size);
ThrowIfFailed(
CHECK_HRESULT(
m_device->CreatePlacedResource(
m_uav_heap.m_heap,
heap_offset,
@ -486,7 +486,7 @@ void D3D12GSRender::copy_render_target_to_dma_location()
);
D3D12_DESCRIPTOR_HEAP_DESC descriptor_heap_desc = { D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV , 2, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE };
ThrowIfFailed(
CHECK_HRESULT(
m_device->CreateDescriptorHeap(&descriptor_heap_desc, IID_PPV_ARGS(descriptor_heap.GetAddressOf()))
);
D3D12_SHADER_RESOURCE_VIEW_DESC shader_resource_view_desc = {};
@ -540,7 +540,7 @@ void D3D12GSRender::copy_render_target_to_dma_location()
}
if (need_transfer)
{
ThrowIfFailed(get_current_resource_storage().command_list->Close());
CHECK_HRESULT(get_current_resource_storage().command_list->Close());
m_command_queue->ExecuteCommandLists(1, (ID3D12CommandList**)get_current_resource_storage().command_list.GetAddressOf());
get_current_resource_storage().set_new_command_list();
}
@ -554,7 +554,7 @@ void D3D12GSRender::copy_render_target_to_dma_location()
char *depth_buffer = (char*)ptr;
void *buffer;
// TODO: Use exact range
ThrowIfFailed(m_readback_resources.m_heap->Map(0, nullptr, &buffer));
CHECK_HRESULT(m_readback_resources.m_heap->Map(0, nullptr, &buffer));
unsigned char *mapped_buffer = (unsigned char*)buffer + depth_buffer_offset_in_heap;
for (unsigned row = 0; row < (unsigned)clip_h; row++)
@ -612,7 +612,7 @@ void D3D12GSRender::copy_render_targets_to_memory(void *buffer, u8 rtt)
{
size_t heap_offset = download_to_readback_buffer(m_device.Get(), get_current_resource_storage().command_list.Get(), m_readback_resources, m_rtts.bound_render_targets[rtt], m_surface.color_format);
ThrowIfFailed(get_current_resource_storage().command_list->Close());
CHECK_HRESULT(get_current_resource_storage().command_list->Close());
m_command_queue->ExecuteCommandLists(1, (ID3D12CommandList**)get_current_resource_storage().command_list.GetAddressOf());
get_current_resource_storage().set_new_command_list();
@ -657,7 +657,7 @@ void D3D12GSRender::copy_depth_buffer_to_memory(void *buffer)
&CD3DX12_TEXTURE_COPY_LOCATION(m_rtts.bound_depth_stencil, 0), nullptr);
get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_rtts.bound_depth_stencil, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE));
ThrowIfFailed(get_current_resource_storage().command_list->Close());
CHECK_HRESULT(get_current_resource_storage().command_list->Close());
m_command_queue->ExecuteCommandLists(1, (ID3D12CommandList**)get_current_resource_storage().command_list.GetAddressOf());
get_current_resource_storage().set_new_command_list();
@ -665,7 +665,7 @@ void D3D12GSRender::copy_depth_buffer_to_memory(void *buffer)
m_readback_resources.m_get_pos = m_readback_resources.get_current_put_pos_minus_one();
void *temp_buffer;
ThrowIfFailed(m_readback_resources.m_heap->Map(0, nullptr, &temp_buffer));
CHECK_HRESULT(m_readback_resources.m_heap->Map(0, nullptr, &temp_buffer));
void *mapped_buffer = (char*)temp_buffer + heap_offset;
for (unsigned row = 0; row < clip_h; row++)
{
@ -695,7 +695,7 @@ void D3D12GSRender::copy_stencil_buffer_to_memory(void *buffer)
&CD3DX12_TEXTURE_COPY_LOCATION(m_rtts.bound_depth_stencil, 1), nullptr);
get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_rtts.bound_depth_stencil, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_DEPTH_WRITE));
ThrowIfFailed(get_current_resource_storage().command_list->Close());
CHECK_HRESULT(get_current_resource_storage().command_list->Close());
m_command_queue->ExecuteCommandLists(1, (ID3D12CommandList**)get_current_resource_storage().command_list.GetAddressOf());
get_current_resource_storage().set_new_command_list();
@ -703,7 +703,7 @@ void D3D12GSRender::copy_stencil_buffer_to_memory(void *buffer)
m_readback_resources.m_get_pos = m_readback_resources.get_current_put_pos_minus_one();
void *temp_buffer;
ThrowIfFailed(m_readback_resources.m_heap->Map(0, nullptr, &temp_buffer));
CHECK_HRESULT(m_readback_resources.m_heap->Map(0, nullptr, &temp_buffer));
void *mapped_buffer = (char*)temp_buffer + heap_offset;
for (unsigned row = 0; row < clip_h; row++)
{

View File

@ -21,7 +21,7 @@ D3D12_COMPARISON_FUNC get_sampler_compare_func[] =
D3D12_COMPARISON_FUNC_ALWAYS
};
D3D12_SAMPLER_DESC get_sampler_desc(const rsx::texture &texture) noexcept
D3D12_SAMPLER_DESC get_sampler_desc(const rsx::texture &texture)
{
D3D12_SAMPLER_DESC samplerDesc = {};
samplerDesc.Filter = get_texture_filter(texture.min_filter(), texture.mag_filter());
@ -55,7 +55,7 @@ ComPtr<ID3D12Resource> upload_single_texture(
size_t depth = texture.depth();
if (texture.cubemap()) depth *= 6;
int format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
const u8 format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
DXGI_FORMAT dxgi_format = get_texture_format(format);
size_t buffer_size = get_placed_texture_storage_size(texture, 256);
@ -63,13 +63,13 @@ ComPtr<ID3D12Resource> upload_single_texture(
size_t heap_offset = texture_buffer_heap.alloc(buffer_size);
void *buffer;
ThrowIfFailed(texture_buffer_heap.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), &buffer));
CHECK_HRESULT(texture_buffer_heap.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), &buffer));
void *mapped_buffer = (char*)buffer + heap_offset;
std::vector<MipmapLevelInfo> mipInfos = upload_placed_texture(texture, 256, mapped_buffer);
texture_buffer_heap.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
ComPtr<ID3D12Resource> result;
ThrowIfFailed(device->CreateCommittedResource(
CHECK_HRESULT(device->CreateCommittedResource(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
D3D12_HEAP_FLAG_NONE,
&CD3DX12_RESOURCE_DESC::Tex2D(dxgi_format, (UINT)w, (UINT)h, depth, texture.mipmap()),
@ -101,7 +101,7 @@ void update_existing_texture(
{
size_t w = texture.width(), h = texture.height();
int format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
const u8 format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
DXGI_FORMAT dxgi_format = get_texture_format(format);
size_t buffer_size = get_placed_texture_storage_size(texture, 256);
@ -109,7 +109,7 @@ void update_existing_texture(
size_t heap_offset = texture_buffer_heap.alloc(buffer_size);
void *buffer;
ThrowIfFailed(texture_buffer_heap.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), &buffer));
CHECK_HRESULT(texture_buffer_heap.m_heap->Map(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size), &buffer));
void *mapped_buffer = (char*)buffer + heap_offset;
std::vector<MipmapLevelInfo> mipInfos = upload_placed_texture(texture, 256, mapped_buffer);
texture_buffer_heap.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
@ -168,7 +168,7 @@ void D3D12GSRender::upload_and_bind_textures(ID3D12GraphicsCommandList *command_
const u32 texaddr = rsx::get_address(textures[i].offset(), textures[i].location());
int format = textures[i].format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
const u8 format = textures[i].format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
bool is_swizzled = !(textures[i].format() & CELL_GCM_TEXTURE_LN);
ID3D12Resource *vram_texture;
@ -224,7 +224,7 @@ void D3D12GSRender::upload_and_bind_textures(ID3D12GraphicsCommandList *command_
case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8:
case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8:
default:
LOG_ERROR(RSX, "Unimplemented Texture format : %x", format);
LOG_ERROR(RSX, "Unimplemented Texture format : 0x%x", format);
break;
case CELL_GCM_TEXTURE_B8:
shared_resource_view_desc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(

View File

@ -177,19 +177,19 @@ void D3D12GSRender::Shader::Init(ID3D12Device *device, ID3D12CommandQueue *gfxco
psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
psoDesc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
ThrowIfFailed(device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_PSO)));
CHECK_HRESULT(device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&m_PSO)));
D3D12_DESCRIPTOR_HEAP_DESC textureHeapDesc = { D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV , 2, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE };
ThrowIfFailed(
CHECK_HRESULT(
device->CreateDescriptorHeap(&textureHeapDesc, IID_PPV_ARGS(&m_textureDescriptorHeap))
);
D3D12_DESCRIPTOR_HEAP_DESC samplerHeapDesc = { D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER , 2, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE };
ThrowIfFailed(
CHECK_HRESULT(
device->CreateDescriptorHeap(&samplerHeapDesc, IID_PPV_ARGS(&m_samplerDescriptorHeap))
);
ComPtr<ID3D12Fence> fence;
ThrowIfFailed(device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(fence.GetAddressOf())));
CHECK_HRESULT(device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(fence.GetAddressOf())));
HANDLE handle = CreateEventEx(nullptr, FALSE, FALSE, EVENT_ALL_ACCESS);
fence->SetEventOnCompletion(1, handle);
@ -201,15 +201,15 @@ void D3D12GSRender::Shader::Init(ID3D12Device *device, ID3D12CommandQueue *gfxco
};
ComPtr<ID3D12CommandAllocator> cmdlistAllocator;
ThrowIfFailed(
CHECK_HRESULT(
device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(cmdlistAllocator.GetAddressOf()))
);
ComPtr<ID3D12GraphicsCommandList> cmdList;
ThrowIfFailed(
CHECK_HRESULT(
device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, cmdlistAllocator.Get(),nullptr, IID_PPV_ARGS(cmdList.GetAddressOf()))
);
ComPtr<ID3D12Resource> intermediateBuffer;
ThrowIfFailed(device->CreateCommittedResource(
CHECK_HRESULT(device->CreateCommittedResource(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
D3D12_HEAP_FLAG_NONE,
&CD3DX12_RESOURCE_DESC::Buffer(16 * sizeof(float)),
@ -218,7 +218,7 @@ void D3D12GSRender::Shader::Init(ID3D12Device *device, ID3D12CommandQueue *gfxco
IID_PPV_ARGS(intermediateBuffer.GetAddressOf())
));
ThrowIfFailed(
CHECK_HRESULT(
device->CreateCommittedResource(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
D3D12_HEAP_FLAG_NONE,
@ -232,7 +232,7 @@ void D3D12GSRender::Shader::Init(ID3D12Device *device, ID3D12CommandQueue *gfxco
UpdateSubresources(cmdList.Get(), m_vertexBuffer, intermediateBuffer.Get(), 0, 0, 1, &vertexData);
cmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_vertexBuffer, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER));
ThrowIfFailed(cmdList->Close());
CHECK_HRESULT(cmdList->Close());
gfxcommandqueue->ExecuteCommandLists(1, CommandListCast(cmdList.GetAddressOf()));
@ -245,7 +245,7 @@ void D3D12GSRender::Shader::Init(ID3D12Device *device, ID3D12CommandQueue *gfxco
void D3D12GSRender::initConvertShader()
{
const auto &p = compileF32toU8CS();
ThrowIfFailed(
CHECK_HRESULT(
m_device->CreateRootSignature(0, p.second->GetBufferPointer(), p.second->GetBufferSize(), IID_PPV_ARGS(&m_convertRootSignature))
);
@ -254,7 +254,7 @@ void D3D12GSRender::initConvertShader()
computePipelineStateDesc.CS.pShaderBytecode = p.first->GetBufferPointer();
computePipelineStateDesc.pRootSignature = m_convertRootSignature;
ThrowIfFailed(
CHECK_HRESULT(
m_device->CreateComputePipelineState(&computePipelineStateDesc, IID_PPV_ARGS(&m_convertPSO))
);
@ -262,13 +262,4 @@ void D3D12GSRender::initConvertShader()
p.second->Release();
}
void unreachable_internal()
{
abort();
#ifdef LLVM_BUILTIN_UNREACHABLE
LLVM_BUILTIN_UNREACHABLE;
#endif
}
#endif

View File

@ -8,79 +8,9 @@
#include "Emu/RSX/GCM.h"
// From llvm Compiler.h
// Need to be set by define
#ifndef __has_builtin
#define __has_builtin(x) 0
#endif
/// \macro LLVM_GNUC_PREREQ
/// \brief Extend the default __GNUC_PREREQ even if glibc's features.h isn't
/// available.
#ifndef LLVM_GNUC_PREREQ
# if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
#define LLVM_GNUC_PREREQ(maj, min, patch) \
((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) + __GNUC_PATCHLEVEL__ >= \
((maj) << 20) + ((min) << 10) + (patch))
# elif defined(__GNUC__) && defined(__GNUC_MINOR__)
#define LLVM_GNUC_PREREQ(maj, min, patch) \
((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10))
#else
#define LLVM_GNUC_PREREQ(maj, min, patch) 0
#endif
#endif
#ifdef __GNUC__
#define LLVM_ATTRIBUTE_NORETURN __attribute__((noreturn))
#elif defined(_MSC_VER)
#define LLVM_ATTRIBUTE_NORETURN __declspec(noreturn)
#else
#define LLVM_ATTRIBUTE_NORETURN
#endif
#if __has_builtin(__builtin_unreachable) || LLVM_GNUC_PREREQ(4, 5, 0)
# define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable()
#elif defined(_MSC_VER)
# define LLVM_BUILTIN_UNREACHABLE __assume(false)
#endif
LLVM_ATTRIBUTE_NORETURN void unreachable_internal();
template<typename... Args>
void unreachable_internal_verbose(const char *file, unsigned line, const Args &...args)
{
LOG_ERROR(RSX, "file %s line %d : %s", file, line, fmt::format(args...));
unreachable_internal();
}
/// Marks that the current location is not supposed to be reachable.
/// In !NDEBUG builds, prints the message and location info to stderr.
/// In NDEBUG builds, becomes an optimizer hint that the current location
/// is not supposed to be reachable. On compilers that don't support
/// such hints, prints a reduced message instead.
///
/// Use this instead of assert(0). It conveys intent more clearly and
/// allows compilers to omit some unnecessary code.
#ifndef NDEBUG
#define unreachable(...) \
unreachable_internal_verbose(__FILE__, __LINE__, ##__VA_ARGS__)
//#elif defined(LLVM_BUILTIN_UNREACHABLE)
//#define unreachable(msg) LLVM_BUILTIN_UNREACHABLE
#else
#define unreachable(msg) unreachable_internal()
#endif
using namespace Microsoft::WRL;
// From DX12 D3D11On12 Sample (MIT Licensed)
inline void ThrowIfFailed(HRESULT hr)
{
if (FAILED(hr))
{
throw;
}
}
#define CHECK_HRESULT(expr) if (HRESULT hr = (expr)) if (FAILED(hr)) throw EXCEPTION("HRESULT = 0x%x", hr)
/**
* Send data to dst pointer without polluting cache.

View File

@ -721,7 +721,7 @@ std::string rsx::get_method_name(const u32 id)
// Various parameter pretty printing function
namespace
{
std::string get_blend_factor(u16 factor) noexcept
std::string get_blend_factor(u16 factor)
{
switch (factor)
{
@ -744,7 +744,7 @@ namespace
return "Error";
}
std::string get_blend_op(u16 op) noexcept
std::string get_blend_op(u16 op)
{
switch (op)
{
@ -760,7 +760,7 @@ namespace
return "Error";
}
std::string get_logic_op(u32 op) noexcept
std::string get_logic_op(u32 op)
{
switch (op)
{
@ -783,7 +783,7 @@ namespace
return "Error";
}
std::string get_compare_func(u32 op) noexcept
std::string get_compare_func(u32 op)
{
switch (op)
{
@ -799,7 +799,7 @@ namespace
return "Error";
}
std::string get_primitive_mode(u8 draw_mode) noexcept
std::string get_primitive_mode(u8 draw_mode)
{
switch (draw_mode)
{
@ -817,12 +817,12 @@ namespace
return "Error";
}
std::string ptr_to_string(u32 ptr) noexcept
std::string ptr_to_string(u32 ptr)
{
return fmt::format("0x%08x", ptr);
}
std::string dma_mode(u32 arg) noexcept
std::string dma_mode(u32 arg)
{
switch (arg)
{
@ -835,7 +835,7 @@ namespace
}
std::string depth_stencil_surface_format(u32 format) noexcept
std::string depth_stencil_surface_format(u32 format)
{
switch (format)
{
@ -845,7 +845,7 @@ namespace
return "Error";
}
std::string color_surface_format(u32 format) noexcept
std::string color_surface_format(u32 format)
{
switch (format)
{
@ -867,7 +867,7 @@ namespace
return "Error";
}
std::string surface_target(u32 target) noexcept
std::string surface_target(u32 target)
{
switch (target)
{
@ -881,7 +881,7 @@ namespace
return "Error";
}
std::string get_clear_color(u32 clear_color) noexcept
std::string get_clear_color(u32 clear_color)
{
u8 clear_a = clear_color >> 24;
u8 clear_r = clear_color >> 16;
@ -890,14 +890,14 @@ namespace
return "A = " + std::to_string(clear_a / 255.0f) + " R = " + std::to_string(clear_r / 255.0f) + " G = " + std::to_string(clear_g / 255.0f) + " B = " + std::to_string(clear_b / 255.0f);
}
static std::string get_zstencil_clear(u32 zstencil) noexcept
static std::string get_zstencil_clear(u32 zstencil)
{
u32 depth = zstencil >> 8;
u32 stencil = zstencil & 0xff;
return "Z = " + std::to_string(depth) + " S = " + std::to_string(stencil);
}
std::string get_stencil_op(u32 op) noexcept
std::string get_stencil_op(u32 op)
{
switch (op)
{
@ -912,7 +912,7 @@ namespace
return "Error";
}
std::string get_vertex_attribute_format(u8 type) noexcept
std::string get_vertex_attribute_format(u8 type)
{
switch (type)
{
@ -927,7 +927,7 @@ namespace
return "Error";
}
std::string unpack_vertex_format(u32 arg) noexcept
std::string unpack_vertex_format(u32 arg)
{
u32 frequency = arg >> 16;
u32 stride = (arg >> 8) & 0xff;
@ -939,7 +939,7 @@ namespace
return "Type = " + get_vertex_attribute_format(type) + " size = " + std::to_string(size) + " stride = " + std::to_string(stride) + " frequency = " + std::to_string(frequency);
}
std::string index_type(u16 arg) noexcept
std::string index_type(u16 arg)
{
switch (arg)
{
@ -949,22 +949,22 @@ namespace
return "Error";
}
std::string transform_constant(size_t index, u32 arg) noexcept
std::string transform_constant(size_t index, u32 arg)
{
return "Transform constant " + std::to_string(index) + ": " + std::to_string(arg) + "/" + std::to_string((float&)arg);
}
std::string texture_offset(size_t index, u32 arg) noexcept
std::string texture_offset(size_t index, u32 arg)
{
return "Texture " + std::to_string(index) + ": Offset @" + ptr_to_string(arg);
}
std::string texture_size(size_t index, u32 arg) noexcept
std::string texture_size(size_t index, u32 arg)
{
return "Texture " + std::to_string(index) + ": width = " + std::to_string(arg & 0xffff) + " height = " + std::to_string(arg >> 16);
}
static std::string get_texture_format_name(u32 format) noexcept
static std::string get_texture_format_name(u32 format)
{
switch (format)
{
@ -999,7 +999,7 @@ namespace
return "Error";
}
std::string texture_format(size_t index, u32 arg) noexcept
std::string texture_format(size_t index, u32 arg)
{
int format = ((arg >> 8) & 0xFF);
return "Texture " + std::to_string(index) + ": location = " + ptr_to_string((arg & 0x3) - 1) +
@ -1012,7 +1012,7 @@ namespace
" mipmap levels = " + std::to_string((arg >> 16) & 0xFFFF);
}
std::string get_texture_wrap_mode(u8 wrap) noexcept
std::string get_texture_wrap_mode(u8 wrap)
{
switch (wrap)
{
@ -1028,7 +1028,7 @@ namespace
return "Error";
}
std::string get_zfunc_name(u8 op) noexcept
std::string get_zfunc_name(u8 op)
{
switch (op)
{
@ -1044,7 +1044,7 @@ namespace
return "Error";
}
std::string texture_address(size_t index, u32 arg) noexcept
std::string texture_address(size_t index, u32 arg)
{
return "Texture " + std::to_string(index) + ": wrap_s = " + get_texture_wrap_mode(arg & 0xF) +
" wrap_t = " + get_texture_wrap_mode((arg >> 8) & 0xF) +
@ -1056,7 +1056,7 @@ namespace
" signed remap = " + std::to_string((arg >> 24) & 0xF);
}
std::string get_texture_max_aniso_name(u8 aniso) noexcept
std::string get_texture_max_aniso_name(u8 aniso)
{
switch (aniso)
{
@ -1072,7 +1072,7 @@ namespace
return "Error";
}
std::string texture_control0(size_t index, u32 arg) noexcept
std::string texture_control0(size_t index, u32 arg)
{
std::string result = "Texture " + std::to_string(index);
if ((arg >> 31) & 0x1)
@ -1087,26 +1087,26 @@ namespace
return result;
}
std::string texture_control1(size_t index, u32 arg) noexcept
std::string texture_control1(size_t index, u32 arg)
{
return "Texture " + std::to_string(index) +
" remap = " + std::to_string(arg);
}
std::string texture_control3(size_t index, u32 arg) noexcept
std::string texture_control3(size_t index, u32 arg)
{
return "Texture " + std::to_string(index) +
" depth = " + std::to_string(arg >> 20) +
" pitch = " + std::to_string(arg & 0xFFFFF);
}
std::string texture_border_color(size_t index, u32 arg) noexcept
std::string texture_border_color(size_t index, u32 arg)
{
return "Texture " + std::to_string(index) +
" border color = " + std::to_string(arg);
}
std::string texture_filter(size_t index, u32 arg) noexcept
std::string texture_filter(size_t index, u32 arg)
{
return "Texture " + std::to_string(index) +
" filter = " + std::to_string(arg);

View File

@ -466,7 +466,7 @@ void GLTexture::save(rsx::texture& tex, const std::string& name)
return;
}
fs::file(name + ".raw", fom::rewrite).write(alldata, texPixelCount * 4);
fs::file(fs::get_config_dir() + name + ".raw", fom::rewrite).write(alldata, texPixelCount * 4);
u8* data = new u8[texPixelCount * 3];
u8* alpha = new u8[texPixelCount];
@ -496,10 +496,10 @@ void GLTexture::save(rsx::texture& tex)
static const std::string& dir_path = "textures";
static const std::string& file_fmt = dir_path + "/" + "tex[%d].png";
if (!fs::exists(dir_path)) fs::create_dir(dir_path);
if (!fs::is_dir(dir_path)) fs::create_dir(dir_path);
u32 count = 0;
while (fs::exists(fmt::format(file_fmt.c_str(), count))) count++;
while (fs::is_file(fmt::format(file_fmt.c_str(), count))) count++;
save(tex, fmt::format(file_fmt.c_str(), count));
}
@ -886,7 +886,7 @@ void GLGSRender::end()
size_t vertex_arrays_offsets[rsx::limits::vertex_count];
#if DUMP_VERTEX_DATA
fs::file dump("VertexDataArray.dump", o_create | o_write);
fs::file dump(fs::get_config_dir() + "VertexDataArray.dump", fom::rewrite);
Emu.Pause();
#endif

View File

@ -18,8 +18,7 @@ struct GLTraits
fragmentProgramData.Compile();
//checkForGlError("m_fragment_prog.Compile");
// TODO: This shouldn't use current dir
fs::file("./FragmentProgram.txt", fom::rewrite) << fragmentProgramData.shader;
fs::file(fs::get_config_dir() + "FragmentProgram.txt", fom::rewrite) << fragmentProgramData.shader;
}
static
@ -29,8 +28,7 @@ struct GLTraits
vertexProgramData.Compile();
//checkForGlError("m_vertex_prog.Compile");
// TODO: This shouldn't use current dir
fs::file("./VertexProgram.txt", fom::rewrite) << vertexProgramData.shader;
fs::file(fs::get_config_dir() + "VertexProgram.txt", fom::rewrite) << vertexProgramData.shader;
}
static

View File

@ -1103,7 +1103,7 @@ namespace rsx
return "rsx::thread"s;
}
void thread::fill_scale_offset_data(void *buffer, bool is_d3d) const noexcept
void thread::fill_scale_offset_data(void *buffer, bool is_d3d) const
{
int clip_w = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16;
int clip_h = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16;
@ -1134,7 +1134,7 @@ namespace rsx
* Fill buffer with vertex program constants.
* Buffer must be at least 512 float4 wide.
*/
void thread::fill_vertex_program_constants_data(void *buffer) noexcept
void thread::fill_vertex_program_constants_data(void *buffer)
{
for (const auto &entry : transform_constants)
local_transform_constants[entry.first] = entry.second;

View File

@ -31,7 +31,7 @@ struct frame_capture_data
std::vector<std::pair<u32, u32> > command_queue;
std::vector<draw_state> draw_calls;
void reset() noexcept
void reset()
{
command_queue.clear();
draw_calls.clear();
@ -345,13 +345,13 @@ namespace rsx
* Vertex shader's position is to be multiplied by this matrix.
* if is_d3d is set, the matrix is modified to use d3d convention.
*/
void fill_scale_offset_data(void *buffer, bool is_d3d = true) const noexcept;
void fill_scale_offset_data(void *buffer, bool is_d3d = true) const;
/**
* Fill buffer with vertex program constants.
* Buffer must be at least 512 float4 wide.
*/
void fill_vertex_program_constants_data(void *buffer) noexcept;
void fill_vertex_program_constants_data(void *buffer);
/**
* Copy rtt values to buffer.

View File

@ -4,18 +4,15 @@
#include "Emu/IdManager.h"
#include "Emu/SysCalls/Modules.h"
#include "Utilities/rMsgBox.h"
#include "Emu/FS/VFS.h"
#include "Emu/FS/vfsFile.h"
#include "Loader/PSF.h"
#include "cellSysutil.h"
#include "cellMsgDialog.h"
#include "cellGame.h"
extern Module<> cellGame;
// Specified as second content_permission_t constructor argument to inform temporary directory
static struct temporary_content_dir_tag_t{} const temporary_content_dir_tag{};
// Normal content directory (if is_temporary is not involved):
// contentInfo = dir
// usrdir = dir + "/USRDIR"
@ -33,14 +30,9 @@ struct content_permission_t final
// true if temporary directory is created and must be moved or deleted
bool is_temporary = false;
content_permission_t(const std::string& dir)
content_permission_t(const std::string& dir, bool is_temp)
: dir(dir)
{
}
content_permission_t(const std::string& dir, const temporary_content_dir_tag_t&)
: dir(dir)
, is_temporary(true)
, is_temporary(is_temp)
{
}
@ -191,7 +183,7 @@ s32 cellGameBootCheck(vm::ptr<u32> type, vm::ptr<u32> attributes, vm::ptr<CellGa
*attributes = 0; // TODO
if (dirName) strcpy_trunc(*dirName, ""); // ???
if (!fxm::make<content_permission_t>("/dev_bdvd/PS3_GAME"))
if (!fxm::make<content_permission_t>("/dev_bdvd/PS3_GAME", false))
{
return CELL_GAME_ERROR_BUSY;
}
@ -203,7 +195,7 @@ s32 cellGameBootCheck(vm::ptr<u32> type, vm::ptr<u32> attributes, vm::ptr<CellGa
*attributes = 0; // TODO
if (dirName) strcpy_trunc(*dirName, titleId);
if (!fxm::make<content_permission_t>("/dev_hdd0/game/" + titleId))
if (!fxm::make<content_permission_t>("/dev_hdd0/game/" + titleId, false))
{
return CELL_GAME_ERROR_BUSY;
}
@ -215,7 +207,7 @@ s32 cellGameBootCheck(vm::ptr<u32> type, vm::ptr<u32> attributes, vm::ptr<CellGa
*attributes = CELL_GAME_ATTRIBUTE_PATCH; // TODO
if (dirName) strcpy_trunc(*dirName, titleId); // ???
if (!fxm::make<content_permission_t>("/dev_bdvd/PS3_GAME"))
if (!fxm::make<content_permission_t>("/dev_bdvd/PS3_GAME", false))
{
return CELL_GAME_ERROR_BUSY;
}
@ -257,7 +249,7 @@ s32 cellGamePatchCheck(vm::ptr<CellGameContentSize> size, vm::ptr<void> reserved
return CELL_GAME_ERROR_NOTPATCH;
}
if (!fxm::make<content_permission_t>("/dev_hdd0/game/" + psf.GetString("TITLE_ID")))
if (!fxm::make<content_permission_t>("/dev_hdd0/game/" + psf.GetString("TITLE_ID"), false))
{
return CELL_GAME_ERROR_BUSY;
}
@ -295,7 +287,7 @@ s32 cellGameDataCheck(u32 type, vm::cptr<char> dirName, vm::ptr<CellGameContentS
return CELL_GAME_RET_NONE;
}
if (!fxm::make<content_permission_t>("/dev_bdvd/PS3_GAME"))
if (!fxm::make<content_permission_t>("/dev_bdvd/PS3_GAME", false))
{
return CELL_GAME_ERROR_BUSY;
}
@ -310,7 +302,7 @@ s32 cellGameDataCheck(u32 type, vm::cptr<char> dirName, vm::ptr<CellGameContentS
return CELL_GAME_RET_NONE;
}
if (!fxm::make<content_permission_t>(dir))
if (!fxm::make<content_permission_t>(dir, false))
{
return CELL_GAME_ERROR_BUSY;
}
@ -487,7 +479,7 @@ s32 cellGameCreateGameData(vm::ptr<CellGameSetInitParams> init, vm::ptr<char[CEL
return CELL_GAME_ERROR_ACCESS_ERROR; // ???
}
if (!fxm::make<content_permission_t>(dir, temporary_content_dir_tag))
if (!fxm::make<content_permission_t>(dir, true))
{
return CELL_GAME_ERROR_BUSY;
}
@ -639,7 +631,23 @@ s32 cellGameContentErrorDialog(s32 type, s32 errNeedSizeKB, vm::cptr<char> dirNa
errorMsg += fmt::format("\nDirectory name: %s", dirName.get_ptr());
}
rMessageBox(errorMsg, "Error", rICON_ERROR | rOK);
const auto dlg = Emu.GetCallbacks().get_msg_dialog();
dlg->type.bg_invisible = true;
dlg->type.button_type = 2; // OK
dlg->type.disable_cancel = true;
const auto p = std::make_shared<std::promise<void>>();
std::future<void> future = p->get_future();
dlg->on_close = [=](s32 status)
{
p->set_value();
};
dlg->Create(errorMsg);
future.get();
return CELL_OK;
}

View File

@ -61,9 +61,9 @@ s32 cellMsgDialogOpen2(u32 type, vm::cptr<char> msgString, vm::ptr<CellMsgDialog
default: return CELL_MSGDIALOG_ERROR_PARAM;
}
const std::shared_ptr<MsgDialogBase> dlg(Emu.GetCallbacks().get_msg_dialog());
const auto dlg = fxm::import<MsgDialogBase>(WRAP_EXPR(Emu.GetCallbacks().get_msg_dialog()));
if (!fxm::import(dlg))
if (!dlg)
{
return CELL_SYSUTIL_ERROR_BUSY;
}

View File

@ -74,7 +74,7 @@ class MsgDialogBase
public:
atomic_t<MsgDialogState> state{ MsgDialogState::Open };
MsgDialogType type;
MsgDialogType type{};
std::function<void(s32 status)> on_close;

View File

@ -34,11 +34,32 @@
#include "Loader/ELF32.h"
#include "../Crypto/unself.h"
#include <fstream>
using namespace PPU_instr;
static const std::string& BreakPointsDBName = "BreakPoints.dat";
static const u16 bpdb_version = 0x1000;
// Draft (not used)
struct bpdb_header_t
{
le_t<u32> magic;
le_t<u32> version;
le_t<u32> count;
le_t<u32> marked;
// POD
bpdb_header_t() = default;
bpdb_header_t(u32 count, u32 marked)
: magic(*reinterpret_cast<const u32*>("BPDB"))
, version(0x00010000)
, count(count)
, marked(marked)
{
}
};
extern std::atomic<u32> g_thread_count;
extern u64 get_system_time();
@ -88,7 +109,7 @@ void Emulator::SetTitle(const std::string& title)
void Emulator::CreateConfig(const std::string& name)
{
const std::string& path = "data/" + name;
const std::string& path = fs::get_config_dir() + "data/" + name;
const std::string& ini_file = path + "/settings.ini";
if (!fs::is_dir("data"))
@ -264,7 +285,7 @@ void Emulator::Load()
{
title_id = title_id.substr(0, 4) + "-" + title_id.substr(4, 5);
CreateConfig(title_id);
rpcs3::config_t custom_config { "data/" + title_id + "/settings.ini" };
rpcs3::config_t custom_config { fs::get_config_dir() + "data/" + title_id + "/settings.ini" };
custom_config.load();
rpcs3::state.config = custom_config;
}
@ -300,7 +321,7 @@ void Emulator::Load()
return;
}
LoadPoints(BreakPointsDBName);
LoadPoints(fs::get_config_dir() + BreakPointsDBName);
GetGSManager().Init();
GetCallbackManager().Init();
@ -458,7 +479,7 @@ void Emulator::Stop()
// TODO: check finalization order
SavePoints(BreakPointsDBName);
SavePoints(fs::get_config_dir() + BreakPointsDBName);
m_break_points.clear();
m_marked_points.clear();
@ -482,84 +503,50 @@ void Emulator::Stop()
void Emulator::SavePoints(const std::string& path)
{
std::ofstream f(path, std::ios::binary | std::ios::trunc);
const u32 break_count = size32(m_break_points);
const u32 marked_count = size32(m_marked_points);
u32 break_count = (u32)m_break_points.size();
u32 marked_count = (u32)m_marked_points.size();
f.write((char*)(&bpdb_version), sizeof(bpdb_version));
f.write((char*)(&break_count), sizeof(break_count));
f.write((char*)(&marked_count), sizeof(marked_count));
if (break_count)
{
f.write((char*)(m_break_points.data()), sizeof(u64) * break_count);
}
if (marked_count)
{
f.write((char*)(m_marked_points.data()), sizeof(u64) * marked_count);
}
fs::file(path, fom::rewrite)
<< bpdb_version
<< break_count
<< marked_count
<< m_break_points
<< m_marked_points;
}
bool Emulator::LoadPoints(const std::string& path)
{
if (!fs::is_file(path)) return false;
std::ifstream f(path, std::ios::binary);
if (!f.is_open())
return false;
f.seekg(0, std::ios::end);
u64 length = (u64)f.tellg();
f.seekg(0, std::ios::beg);
u16 version;
u32 break_count, marked_count;
u64 expected_length = sizeof(bpdb_version) + sizeof(break_count) + sizeof(marked_count);
if (length < expected_length)
if (fs::file f{ path })
{
LOG_ERROR(LOADER,
"'%s' breakpoint db is broken (file is too short, length=0x%x)",
path, length);
return false;
}
u16 version;
u32 break_count;
u32 marked_count;
f.read((char*)(&version), sizeof(version));
if (!f.read(version) || !f.read(break_count) || !f.read(marked_count))
{
LOG_ERROR(LOADER, "BP file '%s' is broken (length=0x%llx)", path, f.size());
return false;
}
if (version != bpdb_version)
{
LOG_ERROR(LOADER,
"'%s' breakpoint db version is unsupported (version=0x%x, length=0x%x)",
path, version, length);
return false;
}
if (version != bpdb_version)
{
LOG_ERROR(LOADER, "BP file '%s' has unsupported version (version=0x%x)", path, version);
return false;
}
f.read((char*)(&break_count), sizeof(break_count));
f.read((char*)(&marked_count), sizeof(marked_count));
expected_length += break_count * sizeof(u64) + marked_count * sizeof(u64);
if (expected_length != length)
{
LOG_ERROR(LOADER,
"'%s' breakpoint db format is incorrect "
"(version=0x%x, break_count=0x%x, marked_count=0x%x, length=0x%x)",
path, version, break_count, marked_count, length);
return false;
}
if (break_count > 0)
{
m_break_points.resize(break_count);
f.read((char*)(m_break_points.data()), sizeof(u64) * break_count);
m_marked_points.resize(marked_count);
if (!f.read(m_break_points) || !f.read(m_marked_points))
{
LOG_ERROR(LOADER, "'BP file %s' is broken (length=0x%llx, break_count=%u, marked_count=%u)", path, f.size(), break_count, marked_count);
return false;
}
return true;
}
if (marked_count > 0)
{
m_marked_points.resize(marked_count);
f.read((char*)(m_marked_points.data()), sizeof(u64) * marked_count);
}
return true;
return false;
}
Emulator Emu;

View File

@ -15,7 +15,7 @@ struct EmuCallbacks
std::function<std::unique_ptr<class PadHandlerBase>()> get_pad_handler;
std::function<std::unique_ptr<class GSFrameBase>(frame_type)> get_gs_frame;
std::function<std::shared_ptr<class GSRender>()> get_gs_render;
std::function<std::unique_ptr<class MsgDialogBase>()> get_msg_dialog;
std::function<std::shared_ptr<class MsgDialogBase>()> get_msg_dialog;
std::function<std::unique_ptr<class SaveDialogBase>()> get_save_dialog;
};
@ -102,7 +102,6 @@ class Emulator final
std::string m_path;
std::string m_elf_path;
std::string m_emu_path;
std::string m_title_id;
std::string m_title;
@ -170,11 +169,6 @@ public:
return m_elf_path;
}
const std::string& GetEmulatorPath() const
{
return m_emu_path;
}
const std::string& GetTitleID() const
{
return m_title_id;
@ -185,11 +179,6 @@ public:
return m_title;
}
void SetEmulatorPath(const std::string& path)
{
m_emu_path = path;
}
u64 GetPauseTime()
{
return m_pause_amend_time;

View File

@ -59,7 +59,7 @@ void AutoPauseManagerDialog::LoadEntries(void)
m_entries.clear();
m_entries.reserve(16);
fs::file list("pause.bin");
fs::file list(fs::get_config_dir() + "pause.bin");
if (list)
{
@ -84,7 +84,7 @@ void AutoPauseManagerDialog::LoadEntries(void)
//This would always use a 0xFFFFFFFF as end of the pause.bin
void AutoPauseManagerDialog::SaveEntries(void)
{
fs::file list("pause.bin", fom::rewrite);
fs::file list(fs::get_config_dir() + "pause.bin", fom::rewrite);
//System calls ID and Function calls ID are all u32 iirc.
u32 num = 0;
CHECK_ASSERTION(list.seek(0) != -1);

View File

@ -1,6 +1,5 @@
#include "stdafx.h"
#include "stdafx_gui.h"
#include "Utilities/rMsgBox.h"
//#include "Emu/Cell/PPUProgramCompiler.h"
//using namespace PPU_opcodes;
@ -390,7 +389,7 @@ void CompilerELF::LoadElf(wxCommandEvent& event)
"All Files (*.*)|*.*",
wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if(ctrl.ShowModal() == rID_CANCEL) return;
if(ctrl.ShowModal() == wxID_CANCEL) return;
LoadElf(fmt::ToUTF8(ctrl.GetPath()));
}

View File

@ -2,7 +2,7 @@
#include "stdafx_gui.h"
#include "Utilities/AutoPause.h"
#include "Utilities/Log.h"
//#include "Utilities/File.h"
#include "Utilities/File.h"
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/FS/VFS.h"
@ -260,7 +260,7 @@ void GameViewer::ConfigureGame(wxCommandEvent& WXUNUSED(event))
if (i < 0) return;
Emu.CreateConfig(m_game_data[i].serial);
rpcs3::config_t custom_config { "data/" + m_game_data[i].serial + "/settings.ini" };
rpcs3::config_t custom_config { fs::get_config_dir() + "data/" + m_game_data[i].serial + "/settings.ini" };
custom_config.load();
LOG_NOTICE(LOADER, "Configure: '%s'", custom_config.path().c_str());
SettingsDialog(this, &custom_config);

View File

@ -571,7 +571,7 @@ void RSXDebugger::GetMemory()
dump += '\n';
}
fs::file("command_dump.log", fom::rewrite) << dump;
fs::file(fs::get_config_dir() + "command_dump.log", fom::rewrite) << dump;
for (u32 i = 0;i < frame_debug.draw_calls.size(); i++)
m_list_captured_draw_calls->InsertItem(i, frame_debug.draw_calls[i].name);

View File

@ -6,6 +6,7 @@
#include "Emu/SysCalls/Modules/cellVideoOut.h"
#include "SettingsDialog.h"
#include "Utilities/Log.h"
#include "Utilities/File.h"
#include <wx/radiobox.h>
#ifdef _WIN32
@ -212,7 +213,7 @@ SettingsDialog::SettingsDialog(wxWindow *parent, rpcs3::config_t* cfg)
//Custom EmulationDir
wxCheckBox* chbox_emulationdir_enable = new wxCheckBox(p_system, wxID_ANY, "Use path below as EmulationDir. (Restart required)");
wxTextCtrl* txt_emulationdir_path = new wxTextCtrl(p_system, wxID_ANY, Emu.GetEmulatorPath());
wxTextCtrl* txt_emulationdir_path = new wxTextCtrl(p_system, wxID_ANY, fs::get_executable_dir());
wxArrayString ppu_decoder_modes;

View File

@ -132,7 +132,7 @@ namespace loader
info.name = std::string(module_info.name, 28);
info.rtoc = module_info.toc + segment.begin.addr();
LOG_WARNING(LOADER, "%s (rtoc=%x):", info.name, info.rtoc);
LOG_WARNING(LOADER, "%s (rtoc=0x%x):", info.name, info.rtoc);
sys_prx_library_info_t lib;
for (u32 e = module_info.exports_start.addr();

View File

@ -1,6 +1,7 @@
#include "stdafx.h"
#include "config.h"
#include <fstream>
#include "Utilities/File.h"
namespace rpcs3
{
@ -32,23 +33,13 @@ namespace rpcs3
void config_t::load()
{
if (!m_path.empty())
{
std::ifstream stream{ m_path };
if (stream)
deserialize(stream);
}
from_string(fs::file(m_path));
}
void config_t::save() const
{
if (!m_path.empty())
{
std::ofstream stream{ m_path };
if (stream)
serialize(stream);
}
fs::file(m_path, fom::rewrite) << to_string();
}
config_t config{ "rpcs3.new.ini" };
config_t config{ fs::get_config_dir() + "rpcs3.new.ini" };
}

View File

@ -63,7 +63,6 @@
<ClCompile Include="..\Utilities\config_context.cpp" />
<ClCompile Include="..\Utilities\Log.cpp" />
<ClCompile Include="..\Utilities\File.cpp" />
<ClCompile Include="..\Utilities\rMsgBox.cpp" />
<ClCompile Include="..\Utilities\rPlatform.cpp" />
<ClCompile Include="..\Utilities\rTime.cpp" />
<ClCompile Include="..\Utilities\rXml.cpp" />
@ -371,7 +370,6 @@
<ClInclude Include="..\Utilities\MTRingbuffer.h" />
<ClInclude Include="..\Utilities\Log.h" />
<ClInclude Include="..\Utilities\File.h" />
<ClInclude Include="..\Utilities\rMsgBox.h" />
<ClInclude Include="..\Utilities\rPlatform.h" />
<ClInclude Include="..\Utilities\rTime.h" />
<ClInclude Include="..\Utilities\rXml.h" />

View File

@ -485,9 +485,6 @@
<ClCompile Include="Emu\SysCalls\LogBase.cpp">
<Filter>Emu\SysCalls</Filter>
</ClCompile>
<ClCompile Include="..\Utilities\rMsgBox.cpp">
<Filter>Utilities</Filter>
</ClCompile>
<ClCompile Include="..\Utilities\rPlatform.cpp">
<Filter>Utilities</Filter>
</ClCompile>
@ -1418,9 +1415,6 @@
<ClInclude Include="..\Utilities\MTRingbuffer.h">
<Filter>Utilities</Filter>
</ClInclude>
<ClInclude Include="..\Utilities\rMsgBox.h">
<Filter>Utilities</Filter>
</ClInclude>
<ClInclude Include="..\Utilities\rPlatform.h">
<Filter>Utilities</Filter>
</ClInclude>

View File

@ -37,8 +37,6 @@
#include "Emu/RSX/D3D12/D3D12GSRender.h"
#endif
#include <wx/stdpaths.h>
#ifdef _WIN32
#include <wx/msw/wrapwin.h>
#endif
@ -147,9 +145,9 @@ bool Rpcs3App::OnInit()
}
};
callbacks.get_msg_dialog = []() -> std::unique_ptr<MsgDialogBase>
callbacks.get_msg_dialog = []() -> std::shared_ptr<MsgDialogBase>
{
return std::make_unique<MsgDialogFrame>();
return std::make_shared<MsgDialogFrame>();
};
callbacks.get_save_dialog = []() -> std::unique_ptr<SaveDialogBase>
@ -163,12 +161,7 @@ bool Rpcs3App::OnInit()
SetAppName(_PRGNAME_);
wxInitAllImageHandlers();
// RPCS3 assumes the current working directory is the folder where it is contained, so we make sure this is true
const wxString executablePath = wxPathOnly(wxStandardPaths::Get().GetExecutablePath());
wxSetWorkingDirectory(executablePath);
Emu.Init();
Emu.SetEmulatorPath(executablePath.ToStdString());
m_MainFrame = new MainFrame();
SetTopWindow(m_MainFrame);