mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-26 04:32:35 +01:00
commit
e4631f93bd
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
#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()
|
||||
{
|
||||
if (std::uncaught_exception())
|
||||
{
|
||||
try
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
std::printf("Unhandled exception: %s\n", ex.what());
|
||||
report_fatal_error("Unhandled exception: "s + ex.what());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::printf("Unhandled exception of unknown type.\n");
|
||||
}
|
||||
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())
|
||||
{
|
||||
if (handle_access_violation((u32)addr64, is_writing, (ucontext_t*)uct))
|
||||
{
|
||||
return; // proceed execution
|
||||
}
|
||||
const u64 addr64 = (u64)info->si_addr - (u64)vm::base(0);
|
||||
const auto cause = is_writing ? "writing" : "reading";
|
||||
|
||||
// TODO: this may be wrong
|
||||
throw EXCEPTION("Access violation %s location 0x%llx", is_writing ? "writing" : "reading", addr64);
|
||||
if (addr64 < 0x100000000ull && thread_ctrl::get_current())
|
||||
{
|
||||
// Try to process access violation
|
||||
if (!handle_access_violation((u32)addr64, is_writing, context))
|
||||
{
|
||||
// Setup throw_access_violation() call on the context
|
||||
prepare_throw_access_violation(context, cause, (u32)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));
|
||||
}
|
||||
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)
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -159,4 +159,5 @@ public:
|
||||
void set_defaults();
|
||||
|
||||
std::string to_string() const;
|
||||
void from_string(const std::string&);
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -1,10 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
struct rPlatform
|
||||
{
|
||||
static std::string getConfigDir();
|
||||
};
|
||||
|
||||
/**********************************************************************
|
||||
*********** RSX Debugger
|
||||
************************************************************************/
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
|
@ -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) };
|
||||
}
|
||||
|
@ -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,13 +306,13 @@ 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);
|
||||
|
@ -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);
|
||||
|
@ -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())
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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++)
|
||||
{
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ class MsgDialogBase
|
||||
public:
|
||||
atomic_t<MsgDialogState> state{ MsgDialogState::Open };
|
||||
|
||||
MsgDialogType type;
|
||||
MsgDialogType type{};
|
||||
|
||||
std::function<void(s32 status)> on_close;
|
||||
|
||||
|
@ -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);
|
||||
u16 version;
|
||||
u32 break_count;
|
||||
u32 marked_count;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
f.read((char*)(&version), sizeof(version));
|
||||
|
||||
if (version != bpdb_version)
|
||||
{
|
||||
LOG_ERROR(LOADER,
|
||||
"'%s' breakpoint db version is unsupported (version=0x%x, length=0x%x)",
|
||||
path, version, length);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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()));
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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" };
|
||||
}
|
||||
|
@ -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" />
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user