Compare commits

...

51 Commits

Author SHA1 Message Date
Zangetsu38 a1a337358a Debug DX12 2016-01-17 01:27:59 +01:00
Zangetsu38 9eadd8b136 d3d12: Update minidx12 SDK on build 10.586. 2016-01-16 19:37:48 +01:00
Zangetsu38 35fb767ae3 Update LLVM with release_37 2016-01-16 19:37:48 +01:00
Zangetsu38 80eb88d0af Fix Xaudio2 for Windows 8 and Windows 10. 2016-01-16 19:37:48 +01:00
Zangetsu38 3a85c68232 Some Change in Gui. 2016-01-16 19:37:48 +01:00
Vincent Lejeune 489cfd6f7e d3d12/gl: Use r1 as depth output.
The "Output_from_h0" flag seems to concern color output.
There might be another flag for depth from half float value.
2016-01-16 19:37:48 +01:00
Vincent Lejeune 26f329d186 d3d12: Fix dsv increment size
Typo.
2016-01-16 18:25:20 +01:00
Vincent Lejeune 5ace4438e2 d3d12: Fix texture proj
I misinterpreted "last component" from glsl doc... it's w, not z.
2016-01-16 18:25:19 +01:00
Vincent Lejeune b8e10225f9 d3d12: Use first color output for alpha discard instead of 0.
Fix Naruto 2 shader miscompilation.
2016-01-16 18:25:18 +01:00
Vincent Lejeune 224facf3ba d3d12: Never pass nullptr as render target descriptor, even if unused.
Function interface doesn't allow this.
2016-01-16 18:25:16 +01:00
B1ackDaemon 9c12d8ff22 Merge pull request #1433 from vlj/rsx
rsx: Use enum class for surface related regs
2016-01-16 01:23:53 +02:00
Vincent Lejeune 3b4339c8e0 rsx: Use enum class for surface related regs 2016-01-15 23:44:27 +01:00
Ivan 8e12c4cb00 Merge pull request #1355 from bentley/malloc-stdlib
Already implemented. Test.
2016-01-14 21:42:38 +03:00
Nekotekina efe1678088 "Build Solution" fix 2016-01-14 20:41:36 +03:00
Nekotekina 2f5be3559e Hotfix 2016-01-14 20:13:41 +03:00
Nekotekina 960668ecf1 For #1355
offsetof() eliminated
OFFSET_32, SIZE_32, ALIGN_32 used
2016-01-14 19:07:27 +03:00
Nekotekina 83084467c6 For #1356 2016-01-14 19:07:26 +03:00
Nekotekina 8464ab6a23 Fixes (#1432)
/dev_bdvd/, rap file loading fix
2016-01-14 19:07:24 +03:00
raven02 74ec128e62 Use CELL_GCM_TEXTURE_CONVOLUTION_MAG for Mag 4 2016-01-14 19:00:16 +03:00
vlj 194c6b8bee Merge pull request #1431 from vlj/gl
gl: Fix warnings and enable treat warning as error.
2016-01-14 00:28:19 +01:00
Vincent Lejeune 69272edba6 gl: Fix warnings and enable trat warning as error. 2016-01-13 23:53:11 +01:00
Nekotekina 38531459df Logging system rewritten
GUI doesn't freeze anymore
Some things simplified
2016-01-13 18:54:57 +03:00
Nekotekina b3e3c68f15 File utility improved
+ minor fixes
2016-01-13 14:12:04 +03:00
B1ackDaemon 5029dff73a Merge pull request #1428 from vlj/rsx
rsx/common/d3d12: Consider separate index range as a whole.
2016-01-13 02:08:23 +02:00
Vincent Lejeune 689dee9944 rsx/common/d3d12: Consider separate index range as a whole.
Fix Wolf of the Battlefield 3
2016-01-13 00:28:48 +01:00
B1ackDaemon 68f9898171 Merge pull request #1415 from vlj/d3d12
D3d12: Factoring
2016-01-12 00:52:45 +02:00
Vincent Lejeune 08622a41b4 d3d12: Use CHECK_HRESULT in D3D12Utils.cpp 2016-01-11 21:17:33 +01:00
Vincent Lejeune 669a3277ff d3d12: Support mag filter 4 2016-01-11 21:17:32 +01:00
Vincent Lejeune e6bd681227 d3d12: factorize render_target code in a template class to be shared with others backends. 2016-01-11 20:47:01 +01:00
Vincent Lejeune 0c5cfdddba d3d12: Gather constant and vtx/idx heap and turn readback heap to buffer 2016-01-11 20:46:58 +01:00
vlj d08ce79d04 Merge pull request #1417 from vlj/rsx
rsx/common/d3d12/gl: Clean ProgramStateCache
2016-01-11 19:45:19 +01:00
Vincent Lejeune bab52c132d rsx/common/d3d12/gl: Clean ProgramStateCache
Use a_b_c format.
Use using =
Use tuple as output
Use RAII to delete program safely
Ensure const correctness.
2016-01-11 19:21:57 +01:00
DHrpcs3 cc1efd2a46 Merge pull request #1419 from RPCS3/minor_fixes
Minor fixes
2016-01-11 00:20:30 +02:00
DHrpcs3 8297d963bf d3d12 texture cache: align to bottom texture address 2016-01-10 23:28:30 +02:00
DHrpcs3 a17c41b4e1 nv4097::get_report: use DMA 2016-01-10 23:22:55 +02:00
B1ackDaemon b055747d4f Merge pull request #1414 from vlj/rsx
Rsx: Fix for vertex buffer filling and for some non IEEE compliant fragment instructions.
2016-01-10 02:44:29 +02:00
Vincent Lejeune 4ef76866a5 rsx/common/d3d12/gl: Support texture lod sampling. 2016-01-10 00:16:26 +01:00
Vincent Lejeune 675ccd4510 rsx/common/d3d12/gl: Mimic divsq and rsq fragment instruction behaviour with 0.
Fix Super Puzzle Turbo HD 2 and SH3 HD
2016-01-09 23:18:05 +01:00
Vincent Lejeune 31a925b4f0 rsx: reenable frame capture
Likely commented out by accident.
2016-01-09 23:18:04 +01:00
Vincent Lejeune d153575e59 rsx/common/d3d12/gl: Support for CMP/non pow of 2 size vertex formats.
Also use class enum for base_vertex_type everywhere.
Fix Bomberman Ultra color and Cubixx HD geometry.
2016-01-09 23:18:03 +01:00
Raul Tambre 3afc62e525 Fix #1368 2016-01-08 08:39:34 +02:00
Raul Tambre f8446b227b Implement inet_ntop and CELL_NET_CTL_INFO_LINK
Also fixed the default address not being set for all cases. Also tried
to fix the Win32 version of CELL_NET_CTL_INFO_IP_ADDRESS failing the
first time around.
2016-01-08 08:39:34 +02:00
Raul Tambre 8f937bda0f Various minor logging improvements
Also changed the default connection state, because chances are, that
you're connected to Internet.
2016-01-08 08:39:33 +02:00
vlj 9d1208bf95 Merge pull request #1394 from vlj/build
Add Guidelines Support Library
2016-01-08 02:09:05 +01:00
Vincent Lejeune e7591439f4 Add Guidelines Support Library 2016-01-08 00:59:08 +01:00
vlj fef0b1dd46 Merge pull request #1409 from vlj/fix-mention-bot
Hopefully fix mention bot's ignore list
2016-01-08 00:51:29 +01:00
Raul Tambre 3281a1982e Hopefully fix mention bot's ignore list 2016-01-07 23:46:32 +01:00
DHrpcs3 b8486a489d Merge pull request #1406 from RPCS3/minor_fixes
Minor fixes
2016-01-07 22:02:35 +02:00
DHrpcs3 f97d791fe8 PSF loader: implemented 0x0004 entry format 2016-01-07 21:22:36 +02:00
DHrpcs3 657a6c9511 elf64 loader: fixed too small primary stack size usage 2016-01-07 18:14:15 +02:00
Anthony J. Bentley aa4fb80465 By definition, malloc() is available in stdlib.h. malloc.h is deprecated. 2015-12-20 03:20:48 -07:00
285 changed files with 9331 additions and 6036 deletions
+4 -1
View File
@@ -12,10 +12,13 @@
[submodule "llvm"]
path = llvm
url = https://github.com/llvm-mirror/llvm
branch = release_36
branch = release_37
[submodule "minidx9"]
path = minidx9
url = https://github.com/hrydgard/minidx9.git
[submodule "rsx_program_decompiler"]
path = rsx_program_decompiler
url = https://github.com/RPCS3/rsx_program_decompiler
[submodule "GSL"]
path = GSL
url = https://github.com/Microsoft/GSL.git
+1 -1
View File
@@ -1,3 +1,3 @@
{
"userBlacklist": [AlexAltea]
"userBlacklist": ["AlexAltea"]
}
+4 -3
View File
@@ -37,7 +37,7 @@ before_install:
sudo apt-get install libwxgtk3.0-dev;
fi;
- if [ "$TRAVIS_OS_NAME" = "linux" ] && [ "$CXX" = "g++" ]; then
export CXX="g++-4.9" CC="gcc-4.9" CXXFLAGS="-Wno-format-security";
export CXX="g++-5" CC="gcc-5" CXXFLAGS="-Wno-format-security";
export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01';
elif [ "$TRAVIS_OS_NAME" = "linux" ]; then
export CXX="clang++-3.6" CC="clang-3.6";
@@ -51,7 +51,7 @@ before_install:
fi;
before_script:
- git submodule update --init asmjit ffmpeg rsx_program_decompiler
- git submodule update --init asmjit ffmpeg rsx_program_decompiler GSL
- mkdir build
- cd build
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then cmake ..; else cmake .. -DLLVM_DIR=/usr/local/opt/llvm36/lib/llvm-3.6/share/llvm/cmake; fi
@@ -78,7 +78,8 @@ addons:
- llvm-3.6
- llvm-3.6-dev
- libedit-dev
- g++-4.9
- g++-5
- gcc-5
- clang-3.6
- libstdc++-4.8-dev
- lib32stdc++6
Submodule
+1
Submodule GSL added at fc5fce4f4f
+1 -1
View File
@@ -25,7 +25,7 @@ __Windows__
* [Python](https://www.python.org/downloads/) (optional, required only for LLVM build; add to PATH)
__Linux__
* GCC 4.9.0+ or Clang 3.5.0+
* GCC 5.1+ or Clang 3.5.0+
* Debian & Ubuntu: `sudo apt-get install libopenal-dev libwxgtk3.0-dev build-essential libglew-dev`
* Arch: `sudo pacman -S glew openal wxgtk cmake llvm`
+489 -316
View File
File diff suppressed because it is too large Load Diff
+105 -55
View File
@@ -1,15 +1,8 @@
#pragma once
enum class fsm : u32 // file seek mode
{
begin,
cur,
end,
};
namespace fom // file open mode
{
enum : u32
enum open_mode : u32
{
read = 1 << 0, // enable reading
write = 1 << 1, // enable writing
@@ -18,19 +11,18 @@ namespace fom // file open mode
trunc = 1 << 4, // clear opened file if it's not empty
excl = 1 << 5, // failure if the file already exists (used with `create`)
rewrite = write | create | trunc, // write + create + trunc
rewrite = write | create | trunc,
};
};
enum class fse : u32 // filesystem (file or dir) error
{
ok, // no error
invalid_arguments,
};
namespace fs
{
thread_local extern fse g_tls_error;
enum seek_mode : u32 // file seek mode
{
seek_set,
seek_cur,
seek_end,
};
struct stat_t
{
@@ -42,6 +34,9 @@ namespace fs
s64 ctime;
};
// Get parent directory for the path (returns empty string on failure)
std::string get_parent_dir(const std::string& path);
// Get file information
bool stat(const std::string& path, stat_t& info);
@@ -49,16 +44,16 @@ namespace fs
bool exists(const std::string& path);
// Check whether the file exists and is NOT a directory
bool is_file(const std::string& file);
bool is_file(const std::string& path);
// Check whether the directory exists and is NOT a file
bool is_dir(const std::string& dir);
bool is_dir(const std::string& path);
// Delete empty directory
bool remove_dir(const std::string& dir);
bool remove_dir(const std::string& path);
// Create directory
bool create_dir(const std::string& dir);
bool create_dir(const std::string& path);
// Create directories
bool create_path(const std::string& path);
@@ -70,10 +65,10 @@ namespace fs
bool copy_file(const std::string& from, const std::string& to, bool overwrite);
// Delete file
bool remove_file(const std::string& file);
bool remove_file(const std::string& path);
// Change file size (possibly appending zeros)
bool truncate_file(const std::string& file, u64 length);
bool truncate_file(const std::string& path, u64 length);
class file final
{
@@ -83,14 +78,15 @@ namespace fs
handle_type m_fd = null;
friend class file_ptr;
friend class file_read_map;
friend class file_write_map;
public:
file() = default;
explicit file(const std::string& filename, u32 mode = fom::read)
explicit file(const std::string& path, u32 mode = fom::read)
{
open(filename, mode);
open(path, mode);
}
file(file&& other)
@@ -120,7 +116,7 @@ namespace fs
}
// Open specified file with specified mode
bool open(const std::string& filename, u32 mode = fom::read);
bool open(const std::string& path, u32 mode = fom::read);
// Change file size (possibly appending zero bytes)
bool trunc(u64 size) const;
@@ -129,7 +125,7 @@ namespace fs
bool stat(stat_t& info) const;
// Close the file explicitly (destructor automatically closes the file)
bool close();
void close();
// Read the data from the file and return the amount of data written in buffer
u64 read(void* buffer, u64 count) const;
@@ -138,92 +134,102 @@ namespace fs
u64 write(const void* buffer, u64 count) const;
// Move file pointer
u64 seek(s64 offset, fsm seek_mode = fsm::begin) const;
u64 seek(s64 offset, seek_mode whence = seek_set) const;
// Get file size
u64 size() const;
// Write std::string
const file& operator <<(const std::string& str) const
// Write std::string unconditionally
const file& write(const std::string& str) const
{
CHECK_ASSERTION(write(str.data(), str.size()) == str.size());
return *this;
}
// Write POD
// Write POD unconditionally
template<typename T>
std::enable_if_t<std::is_pod<T>::value && !std::is_pointer<T>::value, const file&> operator <<(const T& data) const
std::enable_if_t<std::is_pod<T>::value && !std::is_pointer<T>::value, const file&> write(const T& data) const
{
CHECK_ASSERTION(write(std::addressof(data), sizeof(T)) == sizeof(T));
return *this;
}
// Write POD std::vector
// Write POD std::vector unconditionally
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
std::enable_if_t<std::is_pod<T>::value && !std::is_pointer<T>::value, const file&> write(const std::vector<T>& vec) const
{
CHECK_ASSERTION(write(vec.data(), vec.size() * sizeof(T)) == vec.size() * sizeof(T));
return *this;
}
// Read std::string
// Read std::string, size must be set by resize() method
bool read(std::string& str) const
{
return read(&str[0], str.size()) == str.size();
}
// Read POD
// Read POD, sizeof(T) is used
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
// Read POD std::vector, size must be set by resize() method
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
// Read POD (experimental)
template<typename T>
std::enable_if_t<std::is_pod<T>::value && !std::is_pointer<T>::value, T> read() const
{
T result;
CHECK_ASSERTION(read(result));
return result;
}
// Read full file to std::string
std::string to_string() const
{
std::string result;
result.resize(size() - seek(0, fsm::cur));
CHECK_ASSERTION(read(result));
result.resize(size());
CHECK_ASSERTION(seek(0) != -1 && read(result));
return result;
}
};
class file_ptr final
// TODO
class file_read_map final
{
char* m_ptr = nullptr;
u64 m_size;
public:
file_ptr() = default;
file_read_map() = default;
file_ptr(file_ptr&& right)
file_read_map(file_read_map&& right)
: m_ptr(right.m_ptr)
, m_size(right.m_size)
{
right.m_ptr = 0;
}
file_ptr& operator =(file_ptr&& right)
file_read_map& operator =(file_read_map&& right)
{
std::swap(m_ptr, right.m_ptr);
std::swap(m_size, right.m_size);
return *this;
}
file_ptr(const file& f)
file_read_map(const file& f)
{
reset(f);
}
~file_ptr()
~file_read_map()
{
reset();
}
@@ -234,6 +240,52 @@ namespace fs
// Close file mapping
void reset();
// Get pointer
operator const char*() const
{
return m_ptr;
}
};
// TODO
class file_write_map final
{
char* m_ptr = nullptr;
u64 m_size;
public:
file_write_map() = default;
file_write_map(file_write_map&& right)
: m_ptr(right.m_ptr)
, m_size(right.m_size)
{
right.m_ptr = 0;
}
file_write_map& operator =(file_write_map&& right)
{
std::swap(m_ptr, right.m_ptr);
std::swap(m_size, right.m_size);
return *this;
}
file_write_map(const file& f)
{
reset(f);
}
~file_write_map()
{
reset();
}
// Open file mapping
void reset(const file& f);
// Close file mapping
void reset();
// Get pointer
operator char*() const
{
@@ -285,7 +337,7 @@ namespace fs
bool open(const std::string& dirname);
// Close the directory explicitly (destructor automatically closes the directory)
bool close();
void close();
// Get next directory entry (UTF-8 name and file stat)
bool read(std::string& name, stat_t& info);
@@ -318,18 +370,16 @@ namespace fs
return;
}
bool is_ok;
if (mode_ == mode::from_first)
{
is_ok = m_parent->first(m_entry.name, m_entry.info);
m_parent->first(m_entry.name, m_entry.info);
}
else
{
is_ok = m_parent->read(m_entry.name, m_entry.info);
m_parent->read(m_entry.name, m_entry.info);
}
if (!is_ok)
if (m_entry.name.empty())
{
m_parent = nullptr;
}
@@ -364,8 +414,8 @@ namespace fs
};
// Get configuration directory
std::string get_config_dir();
const std::string& get_config_dir();
// Get executable directory
std::string get_executable_dir();
const std::string& get_executable_dir();
}
-4
View File
@@ -35,10 +35,6 @@
#include <stdlib.h>
#include <cstdint>
#ifndef __APPLE__
#include <malloc.h>
#endif
#define _fpclass(x) std::fpclassify(x)
#define INFINITE 0xFFFFFFFF
+121 -256
View File
@@ -1,6 +1,4 @@
#include "stdafx.h"
#include <iostream>
#include <cinttypes>
#include "stdafx.h"
#include "Thread.h"
#include "File.h"
#include "Log.h"
@@ -9,277 +7,144 @@
#include <Windows.h>
#endif
using namespace Log;
std::unique_ptr<LogManager> g_log_manager;
u32 LogMessage::size() const
namespace _log
{
//1 byte for NULL terminator
return (u32)(sizeof(LogMessage::size_type) + sizeof(LogType) + sizeof(Severity) + sizeof(std::string::value_type) * mText.size() + 1);
}
void LogMessage::serialize(char *output) const
{
LogMessage::size_type size = this->size();
memcpy(output, &size, sizeof(LogMessage::size_type));
output += sizeof(LogMessage::size_type);
memcpy(output, &mType, sizeof(LogType));
output += sizeof(LogType);
memcpy(output, &mServerity, sizeof(Severity));
output += sizeof(Severity);
memcpy(output, mText.c_str(), mText.size() );
output += sizeof(std::string::value_type)*mText.size();
*output = '\0';
}
LogMessage LogMessage::deserialize(char *input, u32* size_out)
{
LogMessage msg;
LogMessage::size_type msgSize = *(reinterpret_cast<LogMessage::size_type*>(input));
input += sizeof(LogMessage::size_type);
msg.mType = *(reinterpret_cast<LogType*>(input));
input += sizeof(LogType);
msg.mServerity = *(reinterpret_cast<Severity*>(input));
input += sizeof(Severity);
if (msgSize > 9000)
logger& get_logger()
{
int wtf = 6;
// Use magic static for global logger instance
static logger instance;
return instance;
}
msg.mText.append(input, msgSize - 1 - sizeof(Severity) - sizeof(LogType));
if (size_out){(*size_out) = msgSize;}
return msg;
file_listener g_log_file(_PRGNAME_ ".log");
file_writer g_tty_file("TTY.log");
channel GENERAL("", level::notice);
channel LOADER("LDR", level::notice);
channel MEMORY("MEM", level::notice);
channel RSX("RSX", level::notice);
channel HLE("HLE", level::notice);
channel PPU("PPU", level::notice);
channel SPU("SPU", level::notice);
channel ARMv7("ARMv7");
}
LogChannel::LogChannel() : LogChannel("unknown")
{}
LogChannel::LogChannel(const std::string& name) :
name(name)
, mEnabled(true)
, mLogLevel(Severity::Warning)
{}
void LogChannel::log(const LogMessage &msg)
_log::listener::listener()
{
std::lock_guard<std::mutex> lock(mListenerLock);
for (auto &listener : mListeners)
// Register self
get_logger().add_listener(this);
}
_log::listener::~listener()
{
// Unregister self
get_logger().remove_listener(this);
}
_log::channel::channel(const std::string& name, _log::level init_level)
: name{ name }
, enabled{ init_level }
{
// TODO: register config property "name" associated with "enabled" member
}
void _log::logger::add_listener(_log::listener* listener)
{
std::lock_guard<shared_mutex> lock(m_mutex);
m_listeners.emplace(listener);
}
void _log::logger::remove_listener(_log::listener* listener)
{
std::lock_guard<shared_mutex> lock(m_mutex);
m_listeners.erase(listener);
}
void _log::logger::broadcast(const _log::channel& ch, _log::level sev, const std::string& text) const
{
reader_lock lock(m_mutex);
for (auto listener : m_listeners)
{
listener->log(msg);
listener->log(ch, sev, text);
}
}
void LogChannel::addListener(std::shared_ptr<LogListener> listener)
void _log::broadcast(const _log::channel& ch, _log::level sev, const std::string& text)
{
std::lock_guard<std::mutex> lock(mListenerLock);
mListeners.insert(listener);
}
void LogChannel::removeListener(std::shared_ptr<LogListener> listener)
{
std::lock_guard<std::mutex> lock(mListenerLock);
mListeners.erase(listener);
get_logger().broadcast(ch, sev, text);
}
struct CoutListener : LogListener
_log::file_writer::file_writer(const std::string& name)
{
void log(const LogMessage &msg) override
try
{
std::cerr << msg.mText << std::endl;
}
};
struct FileListener : LogListener
{
fs::file mFile;
bool mPrependChannelName;
FileListener(const std::string& name = _PRGNAME_ ".log", bool prependChannel = true)
: mFile(fs::get_config_dir() + name, fom::rewrite)
, mPrependChannelName(prependChannel)
{
if (!mFile)
if (!m_file.open(fs::get_config_dir() + name, fom::rewrite | fom::append))
{
throw EXCEPTION("Can't create log file %s (error %d)", name, errno);
}
}
catch (const fmt::exception& e)
{
#ifdef _WIN32
MessageBoxA(0, ("Can't create log file: " + name).c_str(), "Error", MB_ICONERROR);
MessageBoxA(0, e.what(), "_log::file_writer() failed", MB_ICONERROR);
#else
std::printf("Can't create log file: %s\n", name.c_str());
#endif
}
}
void log(const LogMessage &msg) override
{
std::string text = msg.mText;
if (mPrependChannelName)
{
text.insert(0, gTypeNameTable[static_cast<u32>(msg.mType)].mName);
if (msg.mType == Log::TTY)
{
text = fmt::escape(text);
if (text[text.length() - 1] != '\n')
{
text += '\n';
}
}
}
mFile << text;
}
};
LogManager::LogManager()
#ifdef BUFFERED_LOGGING
: mExiting(false), mLogConsumer()
#endif
{
auto it = mChannels.begin();
std::shared_ptr<LogListener> listener(new FileListener());
for (const LogTypeName& name : gTypeNameTable)
{
it->name = name.mName;
it->addListener(listener);
it++;
}
std::shared_ptr<LogListener> TTYListener(new FileListener("TTY.log", false));
getChannel(TTY).addListener(TTYListener);
#ifdef BUFFERED_LOGGING
mLogConsumer = std::thread(&LogManager::consumeLog, this);
#endif
}
LogManager::~LogManager()
{
#ifdef BUFFERED_LOGGING
mExiting = true;
mBufferReady.notify_all();
mLogConsumer.join();
}
void LogManager::consumeLog()
{
std::unique_lock<std::mutex> lock(mStatusMut);
while (!mExiting)
{
mBufferReady.wait(lock);
mBuffer.lockGet();
size_t size = mBuffer.size();
std::vector<char> local_messages(size);
mBuffer.popN(&local_messages.front(), size);
mBuffer.unlockGet();
u32 cursor = 0;
u32 removed = 0;
while (cursor < size)
{
Log::LogMessage msg = Log::LogMessage::deserialize(local_messages.data() + cursor, &removed);
cursor += removed;
getChannel(msg.mType).log(msg);
}
}
#endif
}
void LogManager::log(LogMessage msg)
{
//don't do any formatting changes or filtering to the TTY output since we
//use the raw output to do diffs with the output of a real PS3 and some
//programs write text in single bytes to the console
if (msg.mType != TTY)
{
std::string prefix;
switch (msg.mServerity)
{
case Severity::Success:
prefix = "S ";
break;
case Severity::Notice:
prefix = "! ";
break;
case Severity::Warning:
prefix = "W ";
break;
case Severity::Error:
prefix = "E ";
break;
}
if (auto thr = thread_ctrl::get_current())
{
prefix += "{" + thr->get_name() + "} ";
}
msg.mText.insert(0, prefix);
msg.mText.append(1,'\n');
}
#ifdef BUFFERED_LOGGING
size_t size = msg.size();
std::vector<char> temp_buffer(size);
msg.serialize(temp_buffer.data());
mBuffer.pushRange(temp_buffer.begin(), temp_buffer.end());
mBufferReady.notify_one();
#else
mChannels[static_cast<u32>(msg.mType)].log(msg);
#endif
}
void LogManager::addListener(std::shared_ptr<LogListener> listener)
{
for (auto& channel : mChannels)
{
channel.addListener(listener);
}
}
void LogManager::removeListener(std::shared_ptr<LogListener> listener)
{
for (auto& channel : mChannels)
{
channel.removeListener(listener);
}
}
LogManager& LogManager::getInstance()
{
if (!g_log_manager)
{
g_log_manager.reset(new LogManager());
}
return *g_log_manager;
}
LogChannel &LogManager::getChannel(LogType type)
{
return mChannels[static_cast<u32>(type)];
}
void log_message(Log::LogType type, Log::Severity sev, const char* text)
{
log_message(type, sev, std::string(text));
}
void log_message(Log::LogType type, Log::Severity sev, std::string text)
{
if (g_log_manager)
{
g_log_manager->log({ type, sev, std::move(text) });
}
else
{
const auto severity =
sev == Severity::Notice ? "Notice" :
sev == Severity::Warning ? "Warning" :
sev == Severity::Success ? "Success" :
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());
std::printf("_log::file_writer() failed: %s\n", e.what());
#endif
}
}
void _log::file_writer::log(const std::string& text)
{
m_file.write(text);
}
std::size_t _log::file_writer::size() const
{
return m_file.seek(0, fs::seek_cur);
}
void _log::file_listener::log(const _log::channel& ch, _log::level sev, const std::string& text)
{
std::string msg; msg.reserve(text.size() + 200);
// Used character: U+00B7 (Middle Dot)
switch (sev)
{
case level::always: msg = u8"·A "; break;
case level::fatal: msg = u8"·F "; break;
case level::error: msg = u8"·E "; break;
case level::todo: msg = u8"·U "; break;
case level::success: msg = u8"·S "; break;
case level::warning: msg = u8"·W "; break;
case level::notice: msg = u8"·! "; break;
case level::trace: msg = u8"·T "; break;
}
// TODO: print time?
if (auto t = thread_ctrl::get_current())
{
msg += '{';
msg += t->get_name();
msg += "} ";
}
if (ch.name.size())
{
msg += ch.name;
msg += sev == level::todo ? " TODO: " : ": ";
}
else if (sev == level::todo)
{
msg += "TODO: ";
}
msg += text;
msg += '\n';
file_writer::log(msg);
}
+127 -106
View File
@@ -1,134 +1,155 @@
#pragma once
#include "Utilities/MTRingbuffer.h"
//#define BUFFERED_LOGGING 1
#include "SharedMutex.h"
//first parameter is of type Log::LogType and text is of type std::string
#define LOG_SUCCESS(logType, text, ...) log_message(logType, Log::Severity::Success, text, ##__VA_ARGS__)
#define LOG_NOTICE(logType, text, ...) log_message(logType, Log::Severity::Notice, text, ##__VA_ARGS__)
#define LOG_WARNING(logType, text, ...) log_message(logType, Log::Severity::Warning, text, ##__VA_ARGS__)
#define LOG_ERROR(logType, text, ...) log_message(logType, Log::Severity::Error, text, ##__VA_ARGS__)
namespace Log
namespace _log
{
const unsigned int MAX_LOG_BUFFER_LENGTH = 1024*1024;
const unsigned int gBuffSize = 1000;
enum LogType : u32
enum class level : uint
{
GENERAL = 0,
LOADER,
MEMORY,
RSX,
HLE,
PPU,
SPU,
ARMv7,
TTY,
always, // highest level (unused, cannot be disabled)
fatal,
error,
todo,
success,
warning,
notice,
trace, // lowest level (usually disabled)
};
struct channel;
struct listener;
struct LogTypeName
// Log manager
class logger final
{
LogType mType;
std::string mName;
mutable shared_mutex m_mutex;
std::set<listener*> m_listeners;
public:
// Register listener
void add_listener(listener* listener);
// Unregister listener
void remove_listener(listener* listener);
// Send log message to all listeners
void broadcast(const channel& ch, level sev, const std::string& text) const;
};
//well I'd love make_array() but alas manually counting is not the end of the world
static const std::array<LogTypeName, 9> gTypeNameTable = { {
{ GENERAL, "G: " },
{ LOADER, "LDR: " },
{ MEMORY, "MEM: " },
{ RSX, "RSX: " },
{ HLE, "HLE: " },
{ PPU, "PPU: " },
{ SPU, "SPU: " },
{ ARMv7, "ARM: " },
{ TTY, "TTY: " }
} };
// Send log message to global logger instance
void broadcast(const channel& ch, level sev, const std::string& text);
enum class Severity : u32
// Log channel (source)
struct channel
{
Notice = 0,
Warning,
Success,
Error,
// Channel prefix (also used for identification)
const std::string name;
// The lowest logging level enabled for this channel (used for early filtering)
std::atomic<level> enabled;
// Initialization (max level enabled by default)
channel(const std::string& name, level = level::trace);
virtual ~channel() = default;
// Log without formatting
force_inline void log(level sev, const std::string& text) const
{
if (sev <= enabled)
broadcast(*this, sev, text);
}
// Log with formatting
template<typename... Args>
force_inline safe_buffers void format(level sev, const char* fmt, const Args&... args) const
{
if (sev <= enabled)
broadcast(*this, sev, fmt::format(fmt, fmt::do_unveil(args)...));
}
#define GEN_LOG_METHOD(_sev)\
template<typename... Args>\
force_inline void _sev(const char* fmt, const Args&... args)\
{\
return format<Args...>(level::_sev, fmt, args...);\
}
GEN_LOG_METHOD(fatal)
GEN_LOG_METHOD(error)
GEN_LOG_METHOD(todo)
GEN_LOG_METHOD(success)
GEN_LOG_METHOD(warning)
GEN_LOG_METHOD(notice)
GEN_LOG_METHOD(trace)
#undef GEN_LOG_METHOD
};
struct LogMessage
// Log listener (destination)
struct listener
{
using size_type = u32;
LogType mType;
Severity mServerity;
std::string mText;
listener();
virtual ~listener();
u32 size() const;
void serialize(char *output) const;
static LogMessage deserialize(char *input, u32* size_out=nullptr);
virtual void log(const channel& ch, level sev, const std::string& text) = 0;
};
struct LogListener
class file_writer
{
virtual ~LogListener() {};
virtual void log(const LogMessage &msg) = 0;
// Could be memory-mapped file
fs::file m_file;
public:
file_writer(const std::string& name);
virtual ~file_writer() = default;
// Append raw data
void log(const std::string& text);
// Get current file size (may be used by secondary readers)
std::size_t size() const;
};
struct LogChannel
struct file_listener : public file_writer, public listener
{
LogChannel();
LogChannel(const std::string& name);
LogChannel(LogChannel& other) = delete;
void log(const LogMessage &msg);
void addListener(std::shared_ptr<LogListener> listener);
void removeListener(std::shared_ptr<LogListener> listener);
std::string name;
private:
bool mEnabled;
Severity mLogLevel;
std::mutex mListenerLock;
std::set<std::shared_ptr<LogListener>> mListeners;
file_listener(const std::string& name)
: file_writer(name)
, listener()
{
}
// Encode level, current thread name, channel name and write log message
virtual void log(const channel& ch, level sev, const std::string& text) override;
};
struct LogManager
{
LogManager();
~LogManager();
static LogManager& getInstance();
LogChannel& getChannel(LogType type);
void log(LogMessage msg);
void addListener(std::shared_ptr<LogListener> listener);
void removeListener(std::shared_ptr<LogListener> listener);
#ifdef BUFFERED_LOGGING
void consumeLog();
#endif
private:
#ifdef BUFFERED_LOGGING
MTRingbuffer<char, MAX_LOG_BUFFER_LENGTH> mBuffer;
std::condition_variable mBufferReady;
std::mutex mStatusMut;
std::atomic<bool> mExiting;
std::thread mLogConsumer;
#endif
std::array<LogChannel, std::tuple_size<decltype(gTypeNameTable)>::value> mChannels;
//std::array<LogChannel,gTypeNameTable.size()> mChannels; //TODO: use this once Microsoft sorts their shit out
};
// Global variable for RPCS3.log
extern file_listener g_log_file;
// Global variable for TTY.log
extern file_writer g_tty_file;
// Small set of predefined channels:
extern channel GENERAL;
extern channel LOADER;
extern channel MEMORY;
extern channel RSX;
extern channel HLE;
extern channel PPU;
extern channel SPU;
extern channel ARMv7;
}
static struct { inline operator Log::LogType() { return Log::LogType::GENERAL; } } GENERAL;
static struct { inline operator Log::LogType() { return Log::LogType::LOADER; } } LOADER;
static struct { inline operator Log::LogType() { return Log::LogType::MEMORY; } } MEMORY;
static struct { inline operator Log::LogType() { return Log::LogType::RSX; } } RSX;
static struct { inline operator Log::LogType() { return Log::LogType::HLE; } } HLE;
static struct { inline operator Log::LogType() { return Log::LogType::PPU; } } PPU;
static struct { inline operator Log::LogType() { return Log::LogType::SPU; } } SPU;
static struct { inline operator Log::LogType() { return Log::LogType::ARMv7; } } ARMv7;
static struct { inline operator Log::LogType() { return Log::LogType::TTY; } } TTY;
// Legacy:
void log_message(Log::LogType type, Log::Severity sev, const char* text);
void log_message(Log::LogType type, Log::Severity sev, std::string text);
template<typename... Args> never_inline void log_message(Log::LogType type, Log::Severity sev, const char* fmt, Args... args)
{
log_message(type, sev, fmt::format(fmt, fmt::do_unveil(args)...));
}
#define LOG_SUCCESS(ch, fmt, ...) _log::ch.success(fmt, ##__VA_ARGS__)
#define LOG_NOTICE(ch, fmt, ...) _log::ch.notice (fmt, ##__VA_ARGS__)
#define LOG_WARNING(ch, fmt, ...) _log::ch.warning(fmt, ##__VA_ARGS__)
#define LOG_ERROR(ch, fmt, ...) _log::ch.error (fmt, ##__VA_ARGS__)
#define LOG_TODO(ch, fmt, ...) _log::ch.todo (fmt, ##__VA_ARGS__)
#define LOG_TRACE(ch, fmt, ...) _log::ch.trace (fmt, ##__VA_ARGS__)
#define LOG_FATAL(ch, fmt, ...) _log::ch.fatal (fmt, ##__VA_ARGS__)
-155
View File
@@ -1,155 +0,0 @@
#pragma once
//Simple non-resizable FIFO Ringbuffer that can be simultaneously be read from and written to
//if we ever get to use boost please replace this with boost::circular_buffer, there's no reason
//why we would have to keep this amateur attempt at such a fundamental data-structure around
template< typename T, unsigned int MAX_MTRINGBUFFER_BUFFER_SIZE>
class MTRingbuffer{
std::array<T, MAX_MTRINGBUFFER_BUFFER_SIZE> mBuffer;
//this is a recursive mutex because the get methods lock it but the only
//way to be sure that they do not block is to check the size and the only
//way to check the size and use get atomically is to lock this mutex,
//so it goes:
//lock get mutex-->check size-->call get-->lock get mutex-->unlock get mutex-->return from get-->unlock get mutex
std::recursive_mutex mMutGet;
std::mutex mMutPut;
size_t mGet;
size_t mPut;
size_t moveGet(size_t by = 1){ return (mGet + by) % MAX_MTRINGBUFFER_BUFFER_SIZE; }
size_t movePut(size_t by = 1){ return (mPut + by) % MAX_MTRINGBUFFER_BUFFER_SIZE; }
public:
MTRingbuffer() : mGet(0), mPut(0){}
//blocks until there's something to get, so check "spaceLeft()" if you want to avoid blocking
//also lock the get mutex around the spaceLeft() check and the pop if you want to avoid racing
T pop()
{
std::lock_guard<std::recursive_mutex> lock(mMutGet);
while (mGet == mPut)
{
//wait until there's actually something to get
//throwing an exception might be better, blocking here is a little awkward
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
}
size_t ret = mGet;
mGet = moveGet();
return mBuffer[ret];
}
//blocks if the buffer is full until there's enough room
void push(T &putEle)
{
std::lock_guard<std::mutex> lock(mMutPut);
while (movePut() == mGet)
{
//if this is reached a lot it's time to increase the buffer size
//or implement dynamic re-sizing
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
}
mBuffer[mPut] = std::forward(putEle);
mPut = movePut();
}
bool empty()
{
return mGet == mPut;
}
//returns the amount of free places, this is the amount of actual free spaces-1
//since mGet==mPut signals an empty buffer we can't actually use the last free
//space, so we shouldn't report it as free.
size_t spaceLeft() //apparently free() is a macro definition in msvc in some conditions
{
if (mGet < mPut)
{
return mBuffer.size() - (mPut - mGet) - 1;
}
else if (mGet > mPut)
{
return mGet - mPut - 1;
}
else
{
return mBuffer.size() - 1;
}
}
size_t size()
{
//the magic -1 is the same magic 1 that is explained in the spaceLeft() function
return mBuffer.size() - spaceLeft() - 1;
}
//takes random access iterator to T
template<typename IteratorType>
void pushRange(IteratorType from, IteratorType until)
{
std::lock_guard<std::mutex> lock(mMutPut);
size_t length = until - from;
//if whatever we're trying to store is greater than the entire buffer the following loop will be infinite
assert(mBuffer.size() > length);
while (spaceLeft() < length)
{
//if this is reached a lot it's time to increase the buffer size
//or implement dynamic re-sizing
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
}
if (mPut + length <= mBuffer.size())
{
std::copy(from, until, mBuffer.begin() + mPut);
}
else
{
size_t tillEnd = mBuffer.size() - mPut;
std::copy(from, from + tillEnd, mBuffer.begin() + mPut);
std::copy(from + tillEnd, until, mBuffer.begin());
}
mPut = movePut(length);
}
//takes output iterator to T
template<typename IteratorType>
void popN(IteratorType output, size_t n)
{
std::lock_guard<std::recursive_mutex> lock(mMutGet);
//make sure we're not trying to retrieve more than is in
assert(n <= size());
peekN<IteratorType>(output, n);
mGet = moveGet(n);
}
//takes output iterator to T
template<typename IteratorType>
void peekN(IteratorType output, size_t n)
{
size_t lGet = mGet;
if (lGet + n <= mBuffer.size())
{
std::copy_n(mBuffer.begin() + lGet, n, output);
}
else
{
auto next = std::copy(mBuffer.begin() + lGet, mBuffer.end(), output);
std::copy_n(mBuffer.begin(), n - (mBuffer.size() - lGet), next);
}
}
//well this is just asking for trouble
//but the comment above the declaration of mMutGet explains why it's there
//if there's a better way please remove this
void lockGet()
{
mMutGet.lock();
}
//well this is just asking for trouble
//but the comment above the declaration of mMutGet explains why it's there
//if there's a better way please remove this
void unlockGet()
{
mMutGet.unlock();
}
};
+7 -6
View File
@@ -155,19 +155,19 @@ namespace fmt
}
};
template<> struct unveil<char*, false>
template<> struct unveil<const char*, false>
{
using result_type = const char*;
using result_type = const char* const;
force_inline static result_type get_value(const char* arg)
force_inline static result_type get_value(const char* const& arg)
{
return arg;
}
};
template<std::size_t N> struct unveil<const char[N], false>
template<std::size_t N> struct unveil<char[N], false>
{
using result_type = const char*;
using result_type = const char* const;
force_inline static result_type get_value(const char(&arg)[N])
{
@@ -220,7 +220,8 @@ namespace fmt
// vm::ptr, vm::bptr, ... (fmt::do_unveil) (vm_ptr.h) (with appropriate address type, using .addr() can be avoided)
// vm::ref, vm::bref, ... (fmt::do_unveil) (vm_ref.h)
//
template<typename... Args> safe_buffers std::string format(const char* fmt, Args... args)
template<typename... Args>
safe_buffers std::string format(const char* fmt, const Args&... args)
{
// fixed stack buffer for the first attempt
std::array<char, 4096> fixed_buf;
+40 -32
View File
@@ -19,7 +19,7 @@
#include <ucontext.h>
#endif
void report_fatal_error(const std::string& msg)
static 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.";
@@ -1131,7 +1131,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
// Throw virtual memory access violation exception
[[noreturn]] void throw_access_violation(const char* cause, u32 address) // Don't change function definition
{
throw EXCEPTION("Access violation %s location 0x%08x", cause, address);
//throw EXCEPTION("Access violation %s location 0x%08x", cause, address);
}
// Modify context in order to convert hardware exception to C++ exception
@@ -1148,7 +1148,7 @@ void prepare_throw_access_violation(x64_context* context, const char* cause, u32
#ifdef _WIN32
const auto g_exception_handler = AddVectoredExceptionHandler(1, [](PEXCEPTION_POINTERS pExp) -> LONG
static LONG exception_handler(PEXCEPTION_POINTERS pExp)
{
const u64 addr64 = pExp->ExceptionRecord->ExceptionInformation[1] - (u64)vm::base(0);
const bool is_writing = pExp->ExceptionRecord->ExceptionInformation[0] != 0;
@@ -1161,9 +1161,9 @@ const auto g_exception_handler = AddVectoredExceptionHandler(1, [](PEXCEPTION_PO
{
return EXCEPTION_CONTINUE_SEARCH;
}
});
}
const auto g_exception_filter = SetUnhandledExceptionFilter([](PEXCEPTION_POINTERS pExp) -> LONG
static LONG exception_filter(PEXCEPTION_POINTERS pExp)
{
std::string msg = fmt::format("Unhandled Win32 exception 0x%08X.\n", pExp->ExceptionRecord->ExceptionCode);
@@ -1191,16 +1191,36 @@ const auto g_exception_filter = SetUnhandledExceptionFilter([](PEXCEPTION_POINTE
}
}
msg += fmt::format("Instruction address: %p.\n", pExp->ContextRecord->Rip);
msg += fmt::format("Image base: %p.", GetModuleHandle(NULL));
// TODO: print registers and the callstack
// Report fatal error
report_fatal_error(msg);
return EXCEPTION_CONTINUE_SEARCH;
});
}
const bool g_exception_handler_set = []() -> bool
{
if (!AddVectoredExceptionHandler(1, (PVECTORED_EXCEPTION_HANDLER)exception_handler))
{
report_fatal_error("AddVectoredExceptionHandler() failed.");
std::abort();
}
if (!SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)exception_filter))
{
report_fatal_error("SetUnhandledExceptionFilter() failed.");
std::abort();
}
return true;
}();
#else
void signal_handler(int sig, siginfo_t* info, void* uct)
static void signal_handler(int sig, siginfo_t* info, void* uct)
{
x64_context* context = (ucontext_t*)uct;
@@ -1230,17 +1250,21 @@ void signal_handler(int sig, siginfo_t* info, void* uct)
}
}
int setup_signal_handler()
const bool g_exception_handler_set = []() -> bool
{
struct sigaction sa;
struct ::sigaction sa;
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = signal_handler;
return sigaction(SIGSEGV, &sa, NULL);
}
const int g_sigaction_result = setup_signal_handler();
if (::sigaction(SIGSEGV, &sa, NULL) == -1)
{
std::printf("sigaction() failed (0x%x).", errno);
std::abort();
}
return true;
}();
#endif
@@ -1253,16 +1277,6 @@ void thread_ctrl::initialize()
{
SetCurrentThreadDebugName(g_tls_this_thread->m_name().c_str());
#ifdef _WIN32
if (!g_exception_handler || !g_exception_filter)
#else
if (g_sigaction_result == -1)
#endif
{
report_fatal_error("Exception handler is not set correctly.");
std::abort();
}
// TODO
g_thread_count++;
}
@@ -1337,21 +1351,15 @@ void named_thread_t::start()
{
try
{
if (rpcs3::config.misc.log.hle_logging.value())
{
LOG_NOTICE(GENERAL, "Thread started");
}
LOG_TRACE(GENERAL, "Thread started");
thread->on_task();
if (rpcs3::config.misc.log.hle_logging.value())
{
LOG_NOTICE(GENERAL, "Thread ended");
}
LOG_TRACE(GENERAL, "Thread ended");
}
catch (const std::exception& e)
{
LOG_ERROR(GENERAL, "Exception: %s\nPlease report this to the developers.", e.what());
LOG_FATAL(GENERAL, "Exception: %s\nPlease report this to the developers.", e.what());
Emu.Pause();
}
catch (EmulationStopped)
+3 -3
View File
@@ -30,14 +30,14 @@ namespace convert
{
static bool func(const std::string& value)
{
return value == "true" ? true : false;
return value == "true" ? true : value == "false" ? false : throw std::invalid_argument(__FUNCTION__);
}
};
template<>
struct to_impl_t<std::string, char>
struct to_impl_t<std::string, signed char>
{
static std::string func(char value)
static std::string func(signed char value)
{
return std::to_string(value);
}
-1
View File
@@ -10,7 +10,6 @@
#ifndef _WIN32
#include <dirent.h>
#include <errno.h>
#endif
#include "rPlatform.h"
+1 -1
View File
@@ -14,7 +14,7 @@ branches:
before_build:
# until git for win 2.5 release with commit checkout
- git submodule update --init ffmpeg asmjit minidx9 rsx_program_decompiler
- git submodule update --init ffmpeg asmjit minidx9 rsx_program_decompiler GSL
- 7z x wxWidgets.7z -aos -oC:\rpcs3\wxWidgets > null
- if %configuration%==Release (cmake -G "Visual Studio 14 Win64")
else (7z x llvmlibs.7z -aos -oC:\rpcs3 > null && cmake -G "Visual Studio 14 Win64" -DLLVM_DIR=C:/rpcs3/llvm_build/share/llvm/cmake)
+35 -45
View File
@@ -1,10 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug - LLVM|x64">
<Configuration>Debug - LLVM</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug - MemLeak|x64">
<Configuration>Debug - MemLeak</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release - LLVM|x64">
<Configuration>Release - LLVM</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
@@ -71,64 +83,42 @@
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\rpcs3_default.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="..\rpcs3_debug.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - MemLeak|x64'" Label="PropertySheets">
<Import Project="..\rpcs3_debug.props" />
<Import Project="..\rpcs3_memleak.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'" Label="PropertySheets">
<Import Project="..\rpcs3_debug.props" />
<Import Project="..\rpcs3_llvm.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="..\rpcs3_release.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'" Label="PropertySheets">
<Import Project="..\rpcs3_release.props" />
<Import Project="..\rpcs3_llvm.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)lib\$(Configuration)-$(Platform)\</OutDir>
<IntDir>
</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)lib\$(Configuration)-$(Platform)\</OutDir>
<IntDir>
</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ItemDefinitionGroup>
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>ASMJIT_STATIC;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PreprocessorDefinitions>ASMJIT_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>ASMJIT_STATIC;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
+1 -1
Submodule llvm updated: 19ade095e8...33c352b3ed
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+155
View File
@@ -210,15 +210,19 @@ interface ID2D1GeometryRealization
#define ID2D1GeometryRealization_QueryInterface(This, riid, ppv) \
((This)->lpVtbl->Base.Base.QueryInterface((IUnknown *)This, riid, ppv))
#pragma deprecated("ID2D1GeometryRealization_QueryInterface")
#define ID2D1GeometryRealization_AddRef(This) \
((This)->lpVtbl->Base.Base.AddRef((IUnknown *)This))
#pragma deprecated("ID2D1GeometryRealization_AddRef")
#define ID2D1GeometryRealization_Release(This) \
((This)->lpVtbl->Base.Base.Release((IUnknown *)This))
#pragma deprecated("ID2D1GeometryRealization_Release")
#define ID2D1GeometryRealization_GetFactory(This, factory) \
((This)->lpVtbl->Base.GetFactory((ID2D1Resource *)This, factory))
#pragma deprecated("ID2D1GeometryRealization_GetFactory")
typedef interface ID2D1DeviceContext1 ID2D1DeviceContext1;
@@ -259,264 +263,351 @@ interface ID2D1DeviceContext1
#define ID2D1DeviceContext1_QueryInterface(This, riid, ppv) \
((This)->lpVtbl->Base.Base.Base.Base.QueryInterface((IUnknown *)This, riid, ppv))
#pragma deprecated("ID2D1DeviceContext1_QueryInterface")
#define ID2D1DeviceContext1_AddRef(This) \
((This)->lpVtbl->Base.Base.Base.Base.AddRef((IUnknown *)This))
#pragma deprecated("ID2D1DeviceContext1_AddRef")
#define ID2D1DeviceContext1_Release(This) \
((This)->lpVtbl->Base.Base.Base.Base.Release((IUnknown *)This))
#pragma deprecated("ID2D1DeviceContext1_Release")
#define ID2D1DeviceContext1_GetFactory(This, factory) \
((This)->lpVtbl->Base.Base.Base.GetFactory((ID2D1Resource *)This, factory))
#pragma deprecated("ID2D1DeviceContext1_GetFactory")
#define ID2D1DeviceContext1_CreateSharedBitmap(This, riid, data, bitmapProperties, bitmap) \
((This)->lpVtbl->Base.Base.CreateSharedBitmap((ID2D1RenderTarget *)This, riid, data, bitmapProperties, bitmap))
#pragma deprecated("ID2D1DeviceContext1_CreateSharedBitmap")
#define ID2D1DeviceContext1_CreateSolidColorBrush(This, color, brushProperties, solidColorBrush) \
((This)->lpVtbl->Base.Base.CreateSolidColorBrush((ID2D1RenderTarget *)This, color, brushProperties, solidColorBrush))
#pragma deprecated("ID2D1DeviceContext1_CreateSolidColorBrush")
#define ID2D1DeviceContext1_CreateLinearGradientBrush(This, linearGradientBrushProperties, brushProperties, gradientStopCollection, linearGradientBrush) \
((This)->lpVtbl->Base.Base.CreateLinearGradientBrush((ID2D1RenderTarget *)This, linearGradientBrushProperties, brushProperties, gradientStopCollection, linearGradientBrush))
#pragma deprecated("ID2D1DeviceContext1_CreateLinearGradientBrush")
#define ID2D1DeviceContext1_CreateRadialGradientBrush(This, radialGradientBrushProperties, brushProperties, gradientStopCollection, radialGradientBrush) \
((This)->lpVtbl->Base.Base.CreateRadialGradientBrush((ID2D1RenderTarget *)This, radialGradientBrushProperties, brushProperties, gradientStopCollection, radialGradientBrush))
#pragma deprecated("ID2D1DeviceContext1_CreateRadialGradientBrush")
#define ID2D1DeviceContext1_CreateCompatibleRenderTarget(This, desiredSize, desiredPixelSize, desiredFormat, options, bitmapRenderTarget) \
((This)->lpVtbl->Base.Base.CreateCompatibleRenderTarget((ID2D1RenderTarget *)This, desiredSize, desiredPixelSize, desiredFormat, options, bitmapRenderTarget))
#pragma deprecated("ID2D1DeviceContext1_CreateCompatibleRenderTarget")
#define ID2D1DeviceContext1_CreateLayer(This, size, layer) \
((This)->lpVtbl->Base.Base.CreateLayer((ID2D1RenderTarget *)This, size, layer))
#pragma deprecated("ID2D1DeviceContext1_CreateLayer")
#define ID2D1DeviceContext1_CreateMesh(This, mesh) \
((This)->lpVtbl->Base.Base.CreateMesh((ID2D1RenderTarget *)This, mesh))
#pragma deprecated("ID2D1DeviceContext1_CreateMesh")
#define ID2D1DeviceContext1_DrawLine(This, point0, point1, brush, strokeWidth, strokeStyle) \
((This)->lpVtbl->Base.Base.DrawLine((ID2D1RenderTarget *)This, point0, point1, brush, strokeWidth, strokeStyle))
#pragma deprecated("ID2D1DeviceContext1_DrawLine")
#define ID2D1DeviceContext1_DrawRectangle(This, rect, brush, strokeWidth, strokeStyle) \
((This)->lpVtbl->Base.Base.DrawRectangle((ID2D1RenderTarget *)This, rect, brush, strokeWidth, strokeStyle))
#pragma deprecated("ID2D1DeviceContext1_DrawRectangle")
#define ID2D1DeviceContext1_FillRectangle(This, rect, brush) \
((This)->lpVtbl->Base.Base.FillRectangle((ID2D1RenderTarget *)This, rect, brush))
#pragma deprecated("ID2D1DeviceContext1_FillRectangle")
#define ID2D1DeviceContext1_DrawRoundedRectangle(This, roundedRect, brush, strokeWidth, strokeStyle) \
((This)->lpVtbl->Base.Base.DrawRoundedRectangle((ID2D1RenderTarget *)This, roundedRect, brush, strokeWidth, strokeStyle))
#pragma deprecated("ID2D1DeviceContext1_DrawRoundedRectangle")
#define ID2D1DeviceContext1_FillRoundedRectangle(This, roundedRect, brush) \
((This)->lpVtbl->Base.Base.FillRoundedRectangle((ID2D1RenderTarget *)This, roundedRect, brush))
#pragma deprecated("ID2D1DeviceContext1_FillRoundedRectangle")
#define ID2D1DeviceContext1_DrawEllipse(This, ellipse, brush, strokeWidth, strokeStyle) \
((This)->lpVtbl->Base.Base.DrawEllipse((ID2D1RenderTarget *)This, ellipse, brush, strokeWidth, strokeStyle))
#pragma deprecated("ID2D1DeviceContext1_DrawEllipse")
#define ID2D1DeviceContext1_FillEllipse(This, ellipse, brush) \
((This)->lpVtbl->Base.Base.FillEllipse((ID2D1RenderTarget *)This, ellipse, brush))
#pragma deprecated("ID2D1DeviceContext1_FillEllipse")
#define ID2D1DeviceContext1_DrawGeometry(This, geometry, brush, strokeWidth, strokeStyle) \
((This)->lpVtbl->Base.Base.DrawGeometry((ID2D1RenderTarget *)This, geometry, brush, strokeWidth, strokeStyle))
#pragma deprecated("ID2D1DeviceContext1_DrawGeometry")
#define ID2D1DeviceContext1_FillGeometry(This, geometry, brush, opacityBrush) \
((This)->lpVtbl->Base.Base.FillGeometry((ID2D1RenderTarget *)This, geometry, brush, opacityBrush))
#pragma deprecated("ID2D1DeviceContext1_FillGeometry")
#define ID2D1DeviceContext1_FillMesh(This, mesh, brush) \
((This)->lpVtbl->Base.Base.FillMesh((ID2D1RenderTarget *)This, mesh, brush))
#pragma deprecated("ID2D1DeviceContext1_FillMesh")
#define ID2D1DeviceContext1_DrawText(This, string, stringLength, textFormat, layoutRect, defaultForegroundBrush, options, measuringMode) \
((This)->lpVtbl->Base.Base.DrawText((ID2D1RenderTarget *)This, string, stringLength, textFormat, layoutRect, defaultForegroundBrush, options, measuringMode))
#pragma deprecated("ID2D1DeviceContext1_DrawText")
#define ID2D1DeviceContext1_DrawTextLayout(This, origin, textLayout, defaultForegroundBrush, options) \
((This)->lpVtbl->Base.Base.DrawTextLayout((ID2D1RenderTarget *)This, origin, textLayout, defaultForegroundBrush, options))
#pragma deprecated("ID2D1DeviceContext1_DrawTextLayout")
#define ID2D1DeviceContext1_SetTransform(This, transform) \
((This)->lpVtbl->Base.Base.SetTransform((ID2D1RenderTarget *)This, transform))
#pragma deprecated("ID2D1DeviceContext1_SetTransform")
#define ID2D1DeviceContext1_GetTransform(This, transform) \
((This)->lpVtbl->Base.Base.GetTransform((ID2D1RenderTarget *)This, transform))
#pragma deprecated("ID2D1DeviceContext1_GetTransform")
#define ID2D1DeviceContext1_SetAntialiasMode(This, antialiasMode) \
((This)->lpVtbl->Base.Base.SetAntialiasMode((ID2D1RenderTarget *)This, antialiasMode))
#pragma deprecated("ID2D1DeviceContext1_SetAntialiasMode")
#define ID2D1DeviceContext1_GetAntialiasMode(This) \
((This)->lpVtbl->Base.Base.GetAntialiasMode((ID2D1RenderTarget *)This))
#pragma deprecated("ID2D1DeviceContext1_GetAntialiasMode")
#define ID2D1DeviceContext1_SetTextAntialiasMode(This, textAntialiasMode) \
((This)->lpVtbl->Base.Base.SetTextAntialiasMode((ID2D1RenderTarget *)This, textAntialiasMode))
#pragma deprecated("ID2D1DeviceContext1_SetTextAntialiasMode")
#define ID2D1DeviceContext1_GetTextAntialiasMode(This) \
((This)->lpVtbl->Base.Base.GetTextAntialiasMode((ID2D1RenderTarget *)This))
#pragma deprecated("ID2D1DeviceContext1_GetTextAntialiasMode")
#define ID2D1DeviceContext1_SetTextRenderingParams(This, textRenderingParams) \
((This)->lpVtbl->Base.Base.SetTextRenderingParams((ID2D1RenderTarget *)This, textRenderingParams))
#pragma deprecated("ID2D1DeviceContext1_SetTextRenderingParams")
#define ID2D1DeviceContext1_GetTextRenderingParams(This, textRenderingParams) \
((This)->lpVtbl->Base.Base.GetTextRenderingParams((ID2D1RenderTarget *)This, textRenderingParams))
#pragma deprecated("ID2D1DeviceContext1_GetTextRenderingParams")
#define ID2D1DeviceContext1_SetTags(This, tag1, tag2) \
((This)->lpVtbl->Base.Base.SetTags((ID2D1RenderTarget *)This, tag1, tag2))
#pragma deprecated("ID2D1DeviceContext1_SetTags")
#define ID2D1DeviceContext1_GetTags(This, tag1, tag2) \
((This)->lpVtbl->Base.Base.GetTags((ID2D1RenderTarget *)This, tag1, tag2))
#pragma deprecated("ID2D1DeviceContext1_GetTags")
#define ID2D1DeviceContext1_PopLayer(This) \
((This)->lpVtbl->Base.Base.PopLayer((ID2D1RenderTarget *)This))
#pragma deprecated("ID2D1DeviceContext1_PopLayer")
#define ID2D1DeviceContext1_Flush(This, tag1, tag2) \
((This)->lpVtbl->Base.Base.Flush((ID2D1RenderTarget *)This, tag1, tag2))
#pragma deprecated("ID2D1DeviceContext1_Flush")
#define ID2D1DeviceContext1_SaveDrawingState(This, drawingStateBlock) \
((This)->lpVtbl->Base.Base.SaveDrawingState((ID2D1RenderTarget *)This, drawingStateBlock))
#pragma deprecated("ID2D1DeviceContext1_SaveDrawingState")
#define ID2D1DeviceContext1_RestoreDrawingState(This, drawingStateBlock) \
((This)->lpVtbl->Base.Base.RestoreDrawingState((ID2D1RenderTarget *)This, drawingStateBlock))
#pragma deprecated("ID2D1DeviceContext1_RestoreDrawingState")
#define ID2D1DeviceContext1_PushAxisAlignedClip(This, clipRect, antialiasMode) \
((This)->lpVtbl->Base.Base.PushAxisAlignedClip((ID2D1RenderTarget *)This, clipRect, antialiasMode))
#pragma deprecated("ID2D1DeviceContext1_PushAxisAlignedClip")
#define ID2D1DeviceContext1_PopAxisAlignedClip(This) \
((This)->lpVtbl->Base.Base.PopAxisAlignedClip((ID2D1RenderTarget *)This))
#pragma deprecated("ID2D1DeviceContext1_PopAxisAlignedClip")
#define ID2D1DeviceContext1_Clear(This, clearColor) \
((This)->lpVtbl->Base.Base.Clear((ID2D1RenderTarget *)This, clearColor))
#pragma deprecated("ID2D1DeviceContext1_Clear")
#define ID2D1DeviceContext1_BeginDraw(This) \
((This)->lpVtbl->Base.Base.BeginDraw((ID2D1RenderTarget *)This))
#pragma deprecated("ID2D1DeviceContext1_BeginDraw")
#define ID2D1DeviceContext1_EndDraw(This, tag1, tag2) \
((This)->lpVtbl->Base.Base.EndDraw((ID2D1RenderTarget *)This, tag1, tag2))
#pragma deprecated("ID2D1DeviceContext1_EndDraw")
#define ID2D1DeviceContext1_GetPixelFormat(This) \
((This)->lpVtbl->Base.Base.GetPixelFormat((ID2D1RenderTarget *)This))
#pragma deprecated("ID2D1DeviceContext1_GetPixelFormat")
#define ID2D1DeviceContext1_SetDpi(This, dpiX, dpiY) \
((This)->lpVtbl->Base.Base.SetDpi((ID2D1RenderTarget *)This, dpiX, dpiY))
#pragma deprecated("ID2D1DeviceContext1_SetDpi")
#define ID2D1DeviceContext1_GetDpi(This, dpiX, dpiY) \
((This)->lpVtbl->Base.Base.GetDpi((ID2D1RenderTarget *)This, dpiX, dpiY))
#pragma deprecated("ID2D1DeviceContext1_GetDpi")
#define ID2D1DeviceContext1_GetSize(This) \
((This)->lpVtbl->Base.Base.GetSize((ID2D1RenderTarget *)This))
#pragma deprecated("ID2D1DeviceContext1_GetSize")
#define ID2D1DeviceContext1_GetPixelSize(This) \
((This)->lpVtbl->Base.Base.GetPixelSize((ID2D1RenderTarget *)This))
#pragma deprecated("ID2D1DeviceContext1_GetPixelSize")
#define ID2D1DeviceContext1_GetMaximumBitmapSize(This) \
((This)->lpVtbl->Base.Base.GetMaximumBitmapSize((ID2D1RenderTarget *)This))
#pragma deprecated("ID2D1DeviceContext1_GetMaximumBitmapSize")
#define ID2D1DeviceContext1_IsSupported(This, renderTargetProperties) \
((This)->lpVtbl->Base.Base.IsSupported((ID2D1RenderTarget *)This, renderTargetProperties))
#pragma deprecated("ID2D1DeviceContext1_IsSupported")
#define ID2D1DeviceContext1_CreateBitmap(This, size, sourceData, pitch, bitmapProperties, bitmap) \
((This)->lpVtbl->Base.CreateBitmap((ID2D1DeviceContext *)This, size, sourceData, pitch, bitmapProperties, bitmap))
#pragma deprecated("ID2D1DeviceContext1_CreateBitmap")
#define ID2D1DeviceContext1_CreateBitmapFromWicBitmap(This, wicBitmapSource, bitmapProperties, bitmap) \
((This)->lpVtbl->Base.CreateBitmapFromWicBitmap((ID2D1DeviceContext *)This, wicBitmapSource, bitmapProperties, bitmap))
#pragma deprecated("ID2D1DeviceContext1_CreateBitmapFromWicBitmap")
#define ID2D1DeviceContext1_CreateColorContext(This, space, profile, profileSize, colorContext) \
((This)->lpVtbl->Base.CreateColorContext((ID2D1DeviceContext *)This, space, profile, profileSize, colorContext))
#pragma deprecated("ID2D1DeviceContext1_CreateColorContext")
#define ID2D1DeviceContext1_CreateColorContextFromFilename(This, filename, colorContext) \
((This)->lpVtbl->Base.CreateColorContextFromFilename((ID2D1DeviceContext *)This, filename, colorContext))
#pragma deprecated("ID2D1DeviceContext1_CreateColorContextFromFilename")
#define ID2D1DeviceContext1_CreateColorContextFromWicColorContext(This, wicColorContext, colorContext) \
((This)->lpVtbl->Base.CreateColorContextFromWicColorContext((ID2D1DeviceContext *)This, wicColorContext, colorContext))
#pragma deprecated("ID2D1DeviceContext1_CreateColorContextFromWicColorContext")
#define ID2D1DeviceContext1_CreateBitmapFromDxgiSurface(This, surface, bitmapProperties, bitmap) \
((This)->lpVtbl->Base.CreateBitmapFromDxgiSurface((ID2D1DeviceContext *)This, surface, bitmapProperties, bitmap))
#pragma deprecated("ID2D1DeviceContext1_CreateBitmapFromDxgiSurface")
#define ID2D1DeviceContext1_CreateEffect(This, effectId, effect) \
((This)->lpVtbl->Base.CreateEffect((ID2D1DeviceContext *)This, effectId, effect))
#pragma deprecated("ID2D1DeviceContext1_CreateEffect")
#define ID2D1DeviceContext1_CreateGradientStopCollection(This, straightAlphaGradientStops, straightAlphaGradientStopsCount, preInterpolationSpace, postInterpolationSpace, bufferPrecision, extendMode, colorInterpolationMode, gradientStopCollection1) \
((This)->lpVtbl->Base.CreateGradientStopCollection((ID2D1DeviceContext *)This, straightAlphaGradientStops, straightAlphaGradientStopsCount, preInterpolationSpace, postInterpolationSpace, bufferPrecision, extendMode, colorInterpolationMode, gradientStopCollection1))
#pragma deprecated("ID2D1DeviceContext1_CreateGradientStopCollection")
#define ID2D1DeviceContext1_CreateImageBrush(This, image, imageBrushProperties, brushProperties, imageBrush) \
((This)->lpVtbl->Base.CreateImageBrush((ID2D1DeviceContext *)This, image, imageBrushProperties, brushProperties, imageBrush))
#pragma deprecated("ID2D1DeviceContext1_CreateImageBrush")
#define ID2D1DeviceContext1_CreateBitmapBrush(This, bitmap, bitmapBrushProperties, brushProperties, bitmapBrush) \
((This)->lpVtbl->Base.CreateBitmapBrush((ID2D1DeviceContext *)This, bitmap, bitmapBrushProperties, brushProperties, bitmapBrush))
#pragma deprecated("ID2D1DeviceContext1_CreateBitmapBrush")
#define ID2D1DeviceContext1_CreateCommandList(This, commandList) \
((This)->lpVtbl->Base.CreateCommandList((ID2D1DeviceContext *)This, commandList))
#pragma deprecated("ID2D1DeviceContext1_CreateCommandList")
#define ID2D1DeviceContext1_IsDxgiFormatSupported(This, format) \
((This)->lpVtbl->Base.IsDxgiFormatSupported((ID2D1DeviceContext *)This, format))
#pragma deprecated("ID2D1DeviceContext1_IsDxgiFormatSupported")
#define ID2D1DeviceContext1_IsBufferPrecisionSupported(This, bufferPrecision) \
((This)->lpVtbl->Base.IsBufferPrecisionSupported((ID2D1DeviceContext *)This, bufferPrecision))
#pragma deprecated("ID2D1DeviceContext1_IsBufferPrecisionSupported")
#define ID2D1DeviceContext1_GetImageLocalBounds(This, image, localBounds) \
((This)->lpVtbl->Base.GetImageLocalBounds((ID2D1DeviceContext *)This, image, localBounds))
#pragma deprecated("ID2D1DeviceContext1_GetImageLocalBounds")
#define ID2D1DeviceContext1_GetImageWorldBounds(This, image, worldBounds) \
((This)->lpVtbl->Base.GetImageWorldBounds((ID2D1DeviceContext *)This, image, worldBounds))
#pragma deprecated("ID2D1DeviceContext1_GetImageWorldBounds")
#define ID2D1DeviceContext1_GetGlyphRunWorldBounds(This, baselineOrigin, glyphRun, measuringMode, bounds) \
((This)->lpVtbl->Base.GetGlyphRunWorldBounds((ID2D1DeviceContext *)This, baselineOrigin, glyphRun, measuringMode, bounds))
#pragma deprecated("ID2D1DeviceContext1_GetGlyphRunWorldBounds")
#define ID2D1DeviceContext1_GetDevice(This, device) \
((This)->lpVtbl->Base.GetDevice((ID2D1DeviceContext *)This, device))
#pragma deprecated("ID2D1DeviceContext1_GetDevice")
#define ID2D1DeviceContext1_SetTarget(This, image) \
((This)->lpVtbl->Base.SetTarget((ID2D1DeviceContext *)This, image))
#pragma deprecated("ID2D1DeviceContext1_SetTarget")
#define ID2D1DeviceContext1_GetTarget(This, image) \
((This)->lpVtbl->Base.GetTarget((ID2D1DeviceContext *)This, image))
#pragma deprecated("ID2D1DeviceContext1_GetTarget")
#define ID2D1DeviceContext1_SetRenderingControls(This, renderingControls) \
((This)->lpVtbl->Base.SetRenderingControls((ID2D1DeviceContext *)This, renderingControls))
#pragma deprecated("ID2D1DeviceContext1_SetRenderingControls")
#define ID2D1DeviceContext1_GetRenderingControls(This, renderingControls) \
((This)->lpVtbl->Base.GetRenderingControls((ID2D1DeviceContext *)This, renderingControls))
#pragma deprecated("ID2D1DeviceContext1_GetRenderingControls")
#define ID2D1DeviceContext1_SetPrimitiveBlend(This, primitiveBlend) \
((This)->lpVtbl->Base.SetPrimitiveBlend((ID2D1DeviceContext *)This, primitiveBlend))
#pragma deprecated("ID2D1DeviceContext1_SetPrimitiveBlend")
#define ID2D1DeviceContext1_GetPrimitiveBlend(This) \
((This)->lpVtbl->Base.GetPrimitiveBlend((ID2D1DeviceContext *)This))
#pragma deprecated("ID2D1DeviceContext1_GetPrimitiveBlend")
#define ID2D1DeviceContext1_SetUnitMode(This, unitMode) \
((This)->lpVtbl->Base.SetUnitMode((ID2D1DeviceContext *)This, unitMode))
#pragma deprecated("ID2D1DeviceContext1_SetUnitMode")
#define ID2D1DeviceContext1_GetUnitMode(This) \
((This)->lpVtbl->Base.GetUnitMode((ID2D1DeviceContext *)This))
#pragma deprecated("ID2D1DeviceContext1_GetUnitMode")
#define ID2D1DeviceContext1_DrawGlyphRun(This, baselineOrigin, glyphRun, glyphRunDescription, foregroundBrush, measuringMode) \
((This)->lpVtbl->Base.DrawGlyphRun((ID2D1DeviceContext *)This, baselineOrigin, glyphRun, glyphRunDescription, foregroundBrush, measuringMode))
#pragma deprecated("ID2D1DeviceContext1_DrawGlyphRun")
#define ID2D1DeviceContext1_DrawImage(This, image, targetOffset, imageRectangle, interpolationMode, compositeMode) \
((This)->lpVtbl->Base.DrawImage((ID2D1DeviceContext *)This, image, targetOffset, imageRectangle, interpolationMode, compositeMode))
#pragma deprecated("ID2D1DeviceContext1_DrawImage")
#define ID2D1DeviceContext1_DrawGdiMetafile(This, gdiMetafile, targetOffset) \
((This)->lpVtbl->Base.DrawGdiMetafile((ID2D1DeviceContext *)This, gdiMetafile, targetOffset))
#pragma deprecated("ID2D1DeviceContext1_DrawGdiMetafile")
#define ID2D1DeviceContext1_DrawBitmap(This, bitmap, destinationRectangle, opacity, interpolationMode, sourceRectangle, perspectiveTransform) \
((This)->lpVtbl->Base.DrawBitmap((ID2D1DeviceContext *)This, bitmap, destinationRectangle, opacity, interpolationMode, sourceRectangle, perspectiveTransform))
#pragma deprecated("ID2D1DeviceContext1_DrawBitmap")
#define ID2D1DeviceContext1_PushLayer(This, layerParameters, layer) \
((This)->lpVtbl->Base.PushLayer((ID2D1DeviceContext *)This, layerParameters, layer))
#pragma deprecated("ID2D1DeviceContext1_PushLayer")
#define ID2D1DeviceContext1_InvalidateEffectInputRectangle(This, effect, input, inputRectangle) \
((This)->lpVtbl->Base.InvalidateEffectInputRectangle((ID2D1DeviceContext *)This, effect, input, inputRectangle))
#pragma deprecated("ID2D1DeviceContext1_InvalidateEffectInputRectangle")
#define ID2D1DeviceContext1_GetEffectInvalidRectangleCount(This, effect, rectangleCount) \
((This)->lpVtbl->Base.GetEffectInvalidRectangleCount((ID2D1DeviceContext *)This, effect, rectangleCount))
#pragma deprecated("ID2D1DeviceContext1_GetEffectInvalidRectangleCount")
#define ID2D1DeviceContext1_GetEffectInvalidRectangles(This, effect, rectangles, rectanglesCount) \
((This)->lpVtbl->Base.GetEffectInvalidRectangles((ID2D1DeviceContext *)This, effect, rectangles, rectanglesCount))
#pragma deprecated("ID2D1DeviceContext1_GetEffectInvalidRectangles")
#define ID2D1DeviceContext1_GetEffectRequiredInputRectangles(This, renderEffect, renderImageRectangle, inputDescriptions, requiredInputRects, inputCount) \
((This)->lpVtbl->Base.GetEffectRequiredInputRectangles((ID2D1DeviceContext *)This, renderEffect, renderImageRectangle, inputDescriptions, requiredInputRects, inputCount))
#pragma deprecated("ID2D1DeviceContext1_GetEffectRequiredInputRectangles")
#define ID2D1DeviceContext1_FillOpacityMask(This, opacityMask, brush, destinationRectangle, sourceRectangle) \
((This)->lpVtbl->Base.FillOpacityMask((ID2D1DeviceContext *)This, opacityMask, brush, destinationRectangle, sourceRectangle))
#pragma deprecated("ID2D1DeviceContext1_FillOpacityMask")
#define ID2D1DeviceContext1_CreateFilledGeometryRealization(This, geometry, flatteningTolerance, geometryRealization) \
((This)->lpVtbl->CreateFilledGeometryRealization(This, geometry, flatteningTolerance, geometryRealization))
#pragma deprecated("ID2D1DeviceContext1_CreateFilledGeometryRealization")
#define ID2D1DeviceContext1_CreateStrokedGeometryRealization(This, geometry, flatteningTolerance, strokeWidth, strokeStyle, geometryRealization) \
((This)->lpVtbl->CreateStrokedGeometryRealization(This, geometry, flatteningTolerance, strokeWidth, strokeStyle, geometryRealization))
#pragma deprecated("ID2D1DeviceContext1_CreateStrokedGeometryRealization")
#define ID2D1DeviceContext1_DrawGeometryRealization(This, geometryRealization, brush) \
((This)->lpVtbl->DrawGeometryRealization(This, geometryRealization, brush))
#pragma deprecated("ID2D1DeviceContext1_DrawGeometryRealization")
typedef interface ID2D1Device1 ID2D1Device1;
@@ -550,36 +641,47 @@ interface ID2D1Device1
#define ID2D1Device1_QueryInterface(This, riid, ppv) \
((This)->lpVtbl->Base.Base.Base.QueryInterface((IUnknown *)This, riid, ppv))
#pragma deprecated("ID2D1Device1_QueryInterface")
#define ID2D1Device1_AddRef(This) \
((This)->lpVtbl->Base.Base.Base.AddRef((IUnknown *)This))
#pragma deprecated("ID2D1Device1_AddRef")
#define ID2D1Device1_Release(This) \
((This)->lpVtbl->Base.Base.Base.Release((IUnknown *)This))
#pragma deprecated("ID2D1Device1_Release")
#define ID2D1Device1_GetFactory(This, factory) \
((This)->lpVtbl->Base.Base.GetFactory((ID2D1Resource *)This, factory))
#pragma deprecated("ID2D1Device1_GetFactory")
#define ID2D1Device1_CreatePrintControl(This, wicFactory, documentTarget, printControlProperties, printControl) \
((This)->lpVtbl->Base.CreatePrintControl((ID2D1Device *)This, wicFactory, documentTarget, printControlProperties, printControl))
#pragma deprecated("ID2D1Device1_CreatePrintControl")
#define ID2D1Device1_SetMaximumTextureMemory(This, maximumInBytes) \
((This)->lpVtbl->Base.SetMaximumTextureMemory((ID2D1Device *)This, maximumInBytes))
#pragma deprecated("ID2D1Device1_SetMaximumTextureMemory")
#define ID2D1Device1_GetMaximumTextureMemory(This) \
((This)->lpVtbl->Base.GetMaximumTextureMemory((ID2D1Device *)This))
#pragma deprecated("ID2D1Device1_GetMaximumTextureMemory")
#define ID2D1Device1_ClearResources(This, millisecondsSinceUse) \
((This)->lpVtbl->Base.ClearResources((ID2D1Device *)This, millisecondsSinceUse))
#pragma deprecated("ID2D1Device1_ClearResources")
#define ID2D1Device1_GetRenderingPriority(This) \
((This)->lpVtbl->GetRenderingPriority(This))
#pragma deprecated("ID2D1Device1_GetRenderingPriority")
#define ID2D1Device1_SetRenderingPriority(This, renderingPriority) \
((This)->lpVtbl->SetRenderingPriority(This, renderingPriority))
#pragma deprecated("ID2D1Device1_SetRenderingPriority")
#define ID2D1Device1_CreateDeviceContext(This, options, deviceContext1) \
((This)->lpVtbl->CreateDeviceContext(This, options, deviceContext1))
#pragma deprecated("ID2D1Device1_CreateDeviceContext")
typedef interface ID2D1Factory2 ID2D1Factory2;
@@ -604,75 +706,99 @@ interface ID2D1Factory2
#define ID2D1Factory2_QueryInterface(This, riid, ppv) \
((This)->lpVtbl->Base.Base.Base.QueryInterface((IUnknown *)This, riid, ppv))
#pragma deprecated("ID2D1Factory2_QueryInterface")
#define ID2D1Factory2_AddRef(This) \
((This)->lpVtbl->Base.Base.Base.AddRef((IUnknown *)This))
#pragma deprecated("ID2D1Factory2_AddRef")
#define ID2D1Factory2_Release(This) \
((This)->lpVtbl->Base.Base.Base.Release((IUnknown *)This))
#pragma deprecated("ID2D1Factory2_Release")
#define ID2D1Factory2_ReloadSystemMetrics(This) \
((This)->lpVtbl->Base.Base.ReloadSystemMetrics((ID2D1Factory *)This))
#pragma deprecated("ID2D1Factory2_ReloadSystemMetrics")
#define ID2D1Factory2_GetDesktopDpi(This, dpiX, dpiY) \
((This)->lpVtbl->Base.Base.GetDesktopDpi((ID2D1Factory *)This, dpiX, dpiY))
#pragma deprecated("ID2D1Factory2_GetDesktopDpi")
#define ID2D1Factory2_CreateRectangleGeometry(This, rectangle, rectangleGeometry) \
((This)->lpVtbl->Base.Base.CreateRectangleGeometry((ID2D1Factory *)This, rectangle, rectangleGeometry))
#pragma deprecated("ID2D1Factory2_CreateRectangleGeometry")
#define ID2D1Factory2_CreateRoundedRectangleGeometry(This, roundedRectangle, roundedRectangleGeometry) \
((This)->lpVtbl->Base.Base.CreateRoundedRectangleGeometry((ID2D1Factory *)This, roundedRectangle, roundedRectangleGeometry))
#pragma deprecated("ID2D1Factory2_CreateRoundedRectangleGeometry")
#define ID2D1Factory2_CreateEllipseGeometry(This, ellipse, ellipseGeometry) \
((This)->lpVtbl->Base.Base.CreateEllipseGeometry((ID2D1Factory *)This, ellipse, ellipseGeometry))
#pragma deprecated("ID2D1Factory2_CreateEllipseGeometry")
#define ID2D1Factory2_CreateGeometryGroup(This, fillMode, geometries, geometriesCount, geometryGroup) \
((This)->lpVtbl->Base.Base.CreateGeometryGroup((ID2D1Factory *)This, fillMode, geometries, geometriesCount, geometryGroup))
#pragma deprecated("ID2D1Factory2_CreateGeometryGroup")
#define ID2D1Factory2_CreateTransformedGeometry(This, sourceGeometry, transform, transformedGeometry) \
((This)->lpVtbl->Base.Base.CreateTransformedGeometry((ID2D1Factory *)This, sourceGeometry, transform, transformedGeometry))
#pragma deprecated("ID2D1Factory2_CreateTransformedGeometry")
#define ID2D1Factory2_CreateWicBitmapRenderTarget(This, target, renderTargetProperties, renderTarget) \
((This)->lpVtbl->Base.Base.CreateWicBitmapRenderTarget((ID2D1Factory *)This, target, renderTargetProperties, renderTarget))
#pragma deprecated("ID2D1Factory2_CreateWicBitmapRenderTarget")
#define ID2D1Factory2_CreateHwndRenderTarget(This, renderTargetProperties, hwndRenderTargetProperties, hwndRenderTarget) \
((This)->lpVtbl->Base.Base.CreateHwndRenderTarget((ID2D1Factory *)This, renderTargetProperties, hwndRenderTargetProperties, hwndRenderTarget))
#pragma deprecated("ID2D1Factory2_CreateHwndRenderTarget")
#define ID2D1Factory2_CreateDxgiSurfaceRenderTarget(This, dxgiSurface, renderTargetProperties, renderTarget) \
((This)->lpVtbl->Base.Base.CreateDxgiSurfaceRenderTarget((ID2D1Factory *)This, dxgiSurface, renderTargetProperties, renderTarget))
#pragma deprecated("ID2D1Factory2_CreateDxgiSurfaceRenderTarget")
#define ID2D1Factory2_CreateDCRenderTarget(This, renderTargetProperties, dcRenderTarget) \
((This)->lpVtbl->Base.Base.CreateDCRenderTarget((ID2D1Factory *)This, renderTargetProperties, dcRenderTarget))
#pragma deprecated("ID2D1Factory2_CreateDCRenderTarget")
#define ID2D1Factory2_CreateStrokeStyle(This, strokeStyleProperties, dashes, dashesCount, strokeStyle) \
((This)->lpVtbl->Base.CreateStrokeStyle((ID2D1Factory1 *)This, strokeStyleProperties, dashes, dashesCount, strokeStyle))
#pragma deprecated("ID2D1Factory2_CreateStrokeStyle")
#define ID2D1Factory2_CreatePathGeometry(This, pathGeometry) \
((This)->lpVtbl->Base.CreatePathGeometry((ID2D1Factory1 *)This, pathGeometry))
#pragma deprecated("ID2D1Factory2_CreatePathGeometry")
#define ID2D1Factory2_CreateDrawingStateBlock(This, drawingStateDescription, textRenderingParams, drawingStateBlock) \
((This)->lpVtbl->Base.CreateDrawingStateBlock((ID2D1Factory1 *)This, drawingStateDescription, textRenderingParams, drawingStateBlock))
#pragma deprecated("ID2D1Factory2_CreateDrawingStateBlock")
#define ID2D1Factory2_CreateGdiMetafile(This, metafileStream, metafile) \
((This)->lpVtbl->Base.CreateGdiMetafile((ID2D1Factory1 *)This, metafileStream, metafile))
#pragma deprecated("ID2D1Factory2_CreateGdiMetafile")
#define ID2D1Factory2_RegisterEffectFromStream(This, classId, propertyXml, bindings, bindingsCount, effectFactory) \
((This)->lpVtbl->Base.RegisterEffectFromStream((ID2D1Factory1 *)This, classId, propertyXml, bindings, bindingsCount, effectFactory))
#pragma deprecated("ID2D1Factory2_RegisterEffectFromStream")
#define ID2D1Factory2_RegisterEffectFromString(This, classId, propertyXml, bindings, bindingsCount, effectFactory) \
((This)->lpVtbl->Base.RegisterEffectFromString((ID2D1Factory1 *)This, classId, propertyXml, bindings, bindingsCount, effectFactory))
#pragma deprecated("ID2D1Factory2_RegisterEffectFromString")
#define ID2D1Factory2_UnregisterEffect(This, classId) \
((This)->lpVtbl->Base.UnregisterEffect((ID2D1Factory1 *)This, classId))
#pragma deprecated("ID2D1Factory2_UnregisterEffect")
#define ID2D1Factory2_GetRegisteredEffects(This, effects, effectsCount, effectsReturned, effectsRegistered) \
((This)->lpVtbl->Base.GetRegisteredEffects((ID2D1Factory1 *)This, effects, effectsCount, effectsReturned, effectsRegistered))
#pragma deprecated("ID2D1Factory2_GetRegisteredEffects")
#define ID2D1Factory2_GetEffectProperties(This, effectId, properties) \
((This)->lpVtbl->Base.GetEffectProperties((ID2D1Factory1 *)This, effectId, properties))
#pragma deprecated("ID2D1Factory2_GetEffectProperties")
#define ID2D1Factory2_CreateDevice(This, dxgiDevice, d2dDevice1) \
((This)->lpVtbl->CreateDevice(This, dxgiDevice, d2dDevice1))
#pragma deprecated("ID2D1Factory2_CreateDevice")
typedef interface ID2D1CommandSink1 ID2D1CommandSink1;
@@ -696,90 +822,119 @@ interface ID2D1CommandSink1
#define ID2D1CommandSink1_QueryInterface(This, riid, ppv) \
((This)->lpVtbl->Base.Base.QueryInterface((IUnknown *)This, riid, ppv))
#pragma deprecated("ID2D1CommandSink1_QueryInterface")
#define ID2D1CommandSink1_AddRef(This) \
((This)->lpVtbl->Base.Base.AddRef((IUnknown *)This))
#pragma deprecated("ID2D1CommandSink1_AddRef")
#define ID2D1CommandSink1_Release(This) \
((This)->lpVtbl->Base.Base.Release((IUnknown *)This))
#pragma deprecated("ID2D1CommandSink1_Release")
#define ID2D1CommandSink1_BeginDraw(This) \
((This)->lpVtbl->Base.BeginDraw((ID2D1CommandSink *)This))
#pragma deprecated("ID2D1CommandSink1_BeginDraw")
#define ID2D1CommandSink1_EndDraw(This) \
((This)->lpVtbl->Base.EndDraw((ID2D1CommandSink *)This))
#pragma deprecated("ID2D1CommandSink1_EndDraw")
#define ID2D1CommandSink1_SetAntialiasMode(This, antialiasMode) \
((This)->lpVtbl->Base.SetAntialiasMode((ID2D1CommandSink *)This, antialiasMode))
#pragma deprecated("ID2D1CommandSink1_SetAntialiasMode")
#define ID2D1CommandSink1_SetTags(This, tag1, tag2) \
((This)->lpVtbl->Base.SetTags((ID2D1CommandSink *)This, tag1, tag2))
#pragma deprecated("ID2D1CommandSink1_SetTags")
#define ID2D1CommandSink1_SetTextAntialiasMode(This, textAntialiasMode) \
((This)->lpVtbl->Base.SetTextAntialiasMode((ID2D1CommandSink *)This, textAntialiasMode))
#pragma deprecated("ID2D1CommandSink1_SetTextAntialiasMode")
#define ID2D1CommandSink1_SetTextRenderingParams(This, textRenderingParams) \
((This)->lpVtbl->Base.SetTextRenderingParams((ID2D1CommandSink *)This, textRenderingParams))
#pragma deprecated("ID2D1CommandSink1_SetTextRenderingParams")
#define ID2D1CommandSink1_SetTransform(This, transform) \
((This)->lpVtbl->Base.SetTransform((ID2D1CommandSink *)This, transform))
#pragma deprecated("ID2D1CommandSink1_SetTransform")
#define ID2D1CommandSink1_SetPrimitiveBlend(This, primitiveBlend) \
((This)->lpVtbl->Base.SetPrimitiveBlend((ID2D1CommandSink *)This, primitiveBlend))
#pragma deprecated("ID2D1CommandSink1_SetPrimitiveBlend")
#define ID2D1CommandSink1_SetUnitMode(This, unitMode) \
((This)->lpVtbl->Base.SetUnitMode((ID2D1CommandSink *)This, unitMode))
#pragma deprecated("ID2D1CommandSink1_SetUnitMode")
#define ID2D1CommandSink1_Clear(This, color) \
((This)->lpVtbl->Base.Clear((ID2D1CommandSink *)This, color))
#pragma deprecated("ID2D1CommandSink1_Clear")
#define ID2D1CommandSink1_DrawGlyphRun(This, baselineOrigin, glyphRun, glyphRunDescription, foregroundBrush, measuringMode) \
((This)->lpVtbl->Base.DrawGlyphRun((ID2D1CommandSink *)This, baselineOrigin, glyphRun, glyphRunDescription, foregroundBrush, measuringMode))
#pragma deprecated("ID2D1CommandSink1_DrawGlyphRun")
#define ID2D1CommandSink1_DrawLine(This, point0, point1, brush, strokeWidth, strokeStyle) \
((This)->lpVtbl->Base.DrawLine((ID2D1CommandSink *)This, point0, point1, brush, strokeWidth, strokeStyle))
#pragma deprecated("ID2D1CommandSink1_DrawLine")
#define ID2D1CommandSink1_DrawGeometry(This, geometry, brush, strokeWidth, strokeStyle) \
((This)->lpVtbl->Base.DrawGeometry((ID2D1CommandSink *)This, geometry, brush, strokeWidth, strokeStyle))
#pragma deprecated("ID2D1CommandSink1_DrawGeometry")
#define ID2D1CommandSink1_DrawRectangle(This, rect, brush, strokeWidth, strokeStyle) \
((This)->lpVtbl->Base.DrawRectangle((ID2D1CommandSink *)This, rect, brush, strokeWidth, strokeStyle))
#pragma deprecated("ID2D1CommandSink1_DrawRectangle")
#define ID2D1CommandSink1_DrawBitmap(This, bitmap, destinationRectangle, opacity, interpolationMode, sourceRectangle, perspectiveTransform) \
((This)->lpVtbl->Base.DrawBitmap((ID2D1CommandSink *)This, bitmap, destinationRectangle, opacity, interpolationMode, sourceRectangle, perspectiveTransform))
#pragma deprecated("ID2D1CommandSink1_DrawBitmap")
#define ID2D1CommandSink1_DrawImage(This, image, targetOffset, imageRectangle, interpolationMode, compositeMode) \
((This)->lpVtbl->Base.DrawImage((ID2D1CommandSink *)This, image, targetOffset, imageRectangle, interpolationMode, compositeMode))
#pragma deprecated("ID2D1CommandSink1_DrawImage")
#define ID2D1CommandSink1_DrawGdiMetafile(This, gdiMetafile, targetOffset) \
((This)->lpVtbl->Base.DrawGdiMetafile((ID2D1CommandSink *)This, gdiMetafile, targetOffset))
#pragma deprecated("ID2D1CommandSink1_DrawGdiMetafile")
#define ID2D1CommandSink1_FillMesh(This, mesh, brush) \
((This)->lpVtbl->Base.FillMesh((ID2D1CommandSink *)This, mesh, brush))
#pragma deprecated("ID2D1CommandSink1_FillMesh")
#define ID2D1CommandSink1_FillOpacityMask(This, opacityMask, brush, destinationRectangle, sourceRectangle) \
((This)->lpVtbl->Base.FillOpacityMask((ID2D1CommandSink *)This, opacityMask, brush, destinationRectangle, sourceRectangle))
#pragma deprecated("ID2D1CommandSink1_FillOpacityMask")
#define ID2D1CommandSink1_FillGeometry(This, geometry, brush, opacityBrush) \
((This)->lpVtbl->Base.FillGeometry((ID2D1CommandSink *)This, geometry, brush, opacityBrush))
#pragma deprecated("ID2D1CommandSink1_FillGeometry")
#define ID2D1CommandSink1_FillRectangle(This, rect, brush) \
((This)->lpVtbl->Base.FillRectangle((ID2D1CommandSink *)This, rect, brush))
#pragma deprecated("ID2D1CommandSink1_FillRectangle")
#define ID2D1CommandSink1_PushAxisAlignedClip(This, clipRect, antialiasMode) \
((This)->lpVtbl->Base.PushAxisAlignedClip((ID2D1CommandSink *)This, clipRect, antialiasMode))
#pragma deprecated("ID2D1CommandSink1_PushAxisAlignedClip")
#define ID2D1CommandSink1_PushLayer(This, layerParameters1, layer) \
((This)->lpVtbl->Base.PushLayer((ID2D1CommandSink *)This, layerParameters1, layer))
#pragma deprecated("ID2D1CommandSink1_PushLayer")
#define ID2D1CommandSink1_PopAxisAlignedClip(This) \
((This)->lpVtbl->Base.PopAxisAlignedClip((ID2D1CommandSink *)This))
#pragma deprecated("ID2D1CommandSink1_PopAxisAlignedClip")
#define ID2D1CommandSink1_PopLayer(This) \
((This)->lpVtbl->Base.PopLayer((ID2D1CommandSink *)This))
#pragma deprecated("ID2D1CommandSink1_PopLayer")
#define ID2D1CommandSink1_SetPrimitiveBlend1(This, primitiveBlend) \
((This)->lpVtbl->SetPrimitiveBlend1(This, primitiveBlend))
#pragma deprecated("ID2D1CommandSink1_SetPrimitiveBlend1")
#endif
File diff suppressed because it is too large Load Diff
+10
View File
@@ -215,6 +215,16 @@ namespace D2D1
return inkStyleProperties;
}
COM_DECLSPEC_NOTHROW
D2D1FORCEINLINE
D2D1_RECT_U
InfiniteRectU()
{
D2D1_RECT_U rect = { 0u, 0u, UINT_MAX, UINT_MAX };
return rect;
}
} // namespace D2D1
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */
+2
View File
@@ -9661,6 +9661,8 @@ DEFINE_GUID(D3D11_DECODER_PROFILE_MPEG4PT2_VLD_ADVSIMPLE_NOGMC, 0xed418a9f, 0x0
DEFINE_GUID(D3D11_DECODER_PROFILE_MPEG4PT2_VLD_ADVSIMPLE_GMC, 0xab998b5b, 0x4258,0x44a9,0x9f,0xeb,0x94,0xe5,0x97,0xa6,0xba,0xae);
DEFINE_GUID(D3D11_DECODER_PROFILE_HEVC_VLD_MAIN, 0x5b11d51b, 0x2f4c,0x4452,0xbc,0xc3,0x09,0xf2,0xa1,0x16,0x0c,0xc0);
DEFINE_GUID(D3D11_DECODER_PROFILE_HEVC_VLD_MAIN10, 0x107af0e0, 0xef1a,0x4d19,0xab,0xa8,0x67,0xa1,0x63,0x07,0x3d,0x13);
DEFINE_GUID(D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0, 0x463707f8, 0xa1d0, 0x4585, 0x87, 0x6d, 0x83, 0xaa, 0x6d, 0x60, 0xb8, 0x9e);
DEFINE_GUID(D3D11_DECODER_PROFILE_VP8_VLD, 0x90b899ea, 0x3a62, 0x4705, 0x88, 0xb3, 0x8d, 0xf0, 0x4b, 0x27, 0x44, 0xe7);
typedef struct D3D11_VIDEO_DECODER_DESC
{
GUID Guid;
+4 -4
View File
@@ -4523,7 +4523,7 @@ EXTERN_C const IID IID_ID3D12GraphicsCommandList;
virtual void STDMETHODCALLTYPE SetDescriptorHeaps(
_In_ UINT NumDescriptorHeaps,
_In_reads_(NumDescriptorHeaps) ID3D12DescriptorHeap **ppDescriptorHeaps) = 0;
_In_reads_(NumDescriptorHeaps) ID3D12DescriptorHeap *const *ppDescriptorHeaps) = 0;
virtual void STDMETHODCALLTYPE SetComputeRootSignature(
_In_ ID3D12RootSignature *pRootSignature) = 0;
@@ -4600,7 +4600,7 @@ EXTERN_C const IID IID_ID3D12GraphicsCommandList;
virtual void STDMETHODCALLTYPE OMSetRenderTargets(
_In_ UINT NumRenderTargetDescriptors,
_In_ const D3D12_CPU_DESCRIPTOR_HANDLE *pRenderTargetDescriptors,
_In_opt_ const D3D12_CPU_DESCRIPTOR_HANDLE *pRenderTargetDescriptors,
_In_ BOOL RTsSingleHandleToDescriptorRange,
_In_opt_ const D3D12_CPU_DESCRIPTOR_HANDLE *pDepthStencilDescriptor) = 0;
@@ -4840,7 +4840,7 @@ EXTERN_C const IID IID_ID3D12GraphicsCommandList;
void ( STDMETHODCALLTYPE *SetDescriptorHeaps )(
ID3D12GraphicsCommandList * This,
_In_ UINT NumDescriptorHeaps,
_In_reads_(NumDescriptorHeaps) ID3D12DescriptorHeap **ppDescriptorHeaps);
_In_reads_(NumDescriptorHeaps) ID3D12DescriptorHeap *const *ppDescriptorHeaps);
void ( STDMETHODCALLTYPE *SetComputeRootSignature )(
ID3D12GraphicsCommandList * This,
@@ -4935,7 +4935,7 @@ EXTERN_C const IID IID_ID3D12GraphicsCommandList;
void ( STDMETHODCALLTYPE *OMSetRenderTargets )(
ID3D12GraphicsCommandList * This,
_In_ UINT NumRenderTargetDescriptors,
_In_ const D3D12_CPU_DESCRIPTOR_HANDLE *pRenderTargetDescriptors,
_In_opt_ const D3D12_CPU_DESCRIPTOR_HANDLE *pRenderTargetDescriptors,
_In_ BOOL RTsSingleHandleToDescriptorRange,
_In_opt_ const D3D12_CPU_DESCRIPTOR_HANDLE *pDepthStencilDescriptor);
+21 -1
View File
@@ -1459,7 +1459,27 @@ enum D3D12_MESSAGE_ID
D3D12_MESSAGE_ID_UNMAP_INVALID_NULLRANGE = ( D3D12_MESSAGE_ID_MAP_INVALID_NULLRANGE + 1 ) ,
D3D12_MESSAGE_ID_NO_GRAPHICS_API_SUPPORT = ( D3D12_MESSAGE_ID_UNMAP_INVALID_NULLRANGE + 1 ) ,
D3D12_MESSAGE_ID_NO_COMPUTE_API_SUPPORT = ( D3D12_MESSAGE_ID_NO_GRAPHICS_API_SUPPORT + 1 ) ,
D3D12_MESSAGE_ID_D3D12_MESSAGES_END = ( D3D12_MESSAGE_ID_NO_COMPUTE_API_SUPPORT + 1 )
D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_RESOURCE_FLAGS_NOT_SUPPORTED = ( D3D12_MESSAGE_ID_NO_COMPUTE_API_SUPPORT + 1 ) ,
D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_ROOT_ARGUMENT_UNINITIALIZED = ( D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_RESOURCE_FLAGS_NOT_SUPPORTED + 1 ) ,
D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_DESCRIPTOR_HEAP_INDEX_OUT_OF_BOUNDS = ( D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_ROOT_ARGUMENT_UNINITIALIZED + 1 ) ,
D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_DESCRIPTOR_TABLE_REGISTER_INDEX_OUT_OF_BOUNDS = ( D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_DESCRIPTOR_HEAP_INDEX_OUT_OF_BOUNDS + 1 ) ,
D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_DESCRIPTOR_UNINITIALIZED = ( D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_DESCRIPTOR_TABLE_REGISTER_INDEX_OUT_OF_BOUNDS + 1 ) ,
D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_DESCRIPTOR_TYPE_MISMATCH = ( D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_DESCRIPTOR_UNINITIALIZED + 1 ) ,
D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_SRV_RESOURCE_DIMENSION_MISMATCH = ( D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_DESCRIPTOR_TYPE_MISMATCH + 1 ) ,
D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_UAV_RESOURCE_DIMENSION_MISMATCH = ( D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_SRV_RESOURCE_DIMENSION_MISMATCH + 1 ) ,
D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_INCOMPATIBLE_RESOURCE_STATE = ( D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_UAV_RESOURCE_DIMENSION_MISMATCH + 1 ) ,
D3D12_MESSAGE_ID_COPYRESOURCE_NULLDST = ( D3D12_MESSAGE_ID_SHADER_BASED_VALIDATION_INCOMPATIBLE_RESOURCE_STATE + 1 ) ,
D3D12_MESSAGE_ID_COPYRESOURCE_INVALIDDSTRESOURCE = ( D3D12_MESSAGE_ID_COPYRESOURCE_NULLDST + 1 ) ,
D3D12_MESSAGE_ID_COPYRESOURCE_NULLSRC = ( D3D12_MESSAGE_ID_COPYRESOURCE_INVALIDDSTRESOURCE + 1 ) ,
D3D12_MESSAGE_ID_COPYRESOURCE_INVALIDSRCRESOURCE = ( D3D12_MESSAGE_ID_COPYRESOURCE_NULLSRC + 1 ) ,
D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_NULLDST = ( D3D12_MESSAGE_ID_COPYRESOURCE_INVALIDSRCRESOURCE + 1 ) ,
D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_INVALIDDSTRESOURCE = ( D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_NULLDST + 1 ) ,
D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_NULLSRC = ( D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_INVALIDDSTRESOURCE + 1 ) ,
D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_INVALIDSRCRESOURCE = ( D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_NULLSRC + 1 ) ,
D3D12_MESSAGE_ID_PIPELINE_STATE_TYPE_MISMATCH = ( D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_INVALIDSRCRESOURCE + 1 ) ,
D3D12_MESSAGE_ID_COMMAND_LIST_DISPATCH_ROOT_SIGNATURE_NOT_SET = ( D3D12_MESSAGE_ID_PIPELINE_STATE_TYPE_MISMATCH + 1 ) ,
D3D12_MESSAGE_ID_COMMAND_LIST_DISPATCH_ROOT_SIGNATURE_MISMATCH = ( D3D12_MESSAGE_ID_COMMAND_LIST_DISPATCH_ROOT_SIGNATURE_NOT_SET + 1 ) ,
D3D12_MESSAGE_ID_D3D12_MESSAGES_END = ( D3D12_MESSAGE_ID_COMMAND_LIST_DISPATCH_ROOT_SIGNATURE_MISMATCH + 1 )
} D3D12_MESSAGE_ID;
typedef struct D3D12_MESSAGE
+3 -3
View File
@@ -2446,7 +2446,7 @@ enum DWRITE_NUMBER_SUBSTITUTION_METHOD
/// <summary>
/// Holds the appropriate digits and numeric punctuation for a given locale.
/// </summary>
interface DECLSPEC_UUID("14885CC9-BAB0-4f90-B6ED-5C366A2CD03D") DECLSPEC_NOVTABLE IDWriteNumberSubstitution : public IUnknown
interface DWRITE_DECLARE_INTERFACE("14885CC9-BAB0-4f90-B6ED-5C366A2CD03D") IDWriteNumberSubstitution : public IUnknown
{
};
@@ -2511,7 +2511,7 @@ struct DWRITE_SHAPING_GLYPH_PROPERTIES
/// stop prematurely and return a callback error. Rather than return E_NOTIMPL,
/// an application should stub the method and return a constant/null and S_OK.
/// </summary>
interface DECLSPEC_UUID("688e1a58-5094-47c8-adc8-fbcea60ae92b") DECLSPEC_NOVTABLE IDWriteTextAnalysisSource : public IUnknown
interface DWRITE_DECLARE_INTERFACE("688e1a58-5094-47c8-adc8-fbcea60ae92b") IDWriteTextAnalysisSource : public IUnknown
{
/// <summary>
/// Get a block of text starting at the specified text position.
@@ -2620,7 +2620,7 @@ interface DECLSPEC_UUID("688e1a58-5094-47c8-adc8-fbcea60ae92b") DECLSPEC_NOVTABL
/// state of the analysis sink, therefore a Set method call on a range
/// overwrites the previously set analysis result of the same range.
/// </summary>
interface DECLSPEC_UUID("5810cd44-0ca0-4701-b3fa-bec5182ae4f6") DECLSPEC_NOVTABLE IDWriteTextAnalysisSink : public IUnknown
interface DWRITE_DECLARE_INTERFACE("5810cd44-0ca0-4701-b3fa-bec5182ae4f6") IDWriteTextAnalysisSink : public IUnknown
{
/// <summary>
/// Report script analysis for the text range.
+2 -2
View File
@@ -1714,7 +1714,7 @@ interface DWRITE_DECLARE_INTERFACE("80DAD800-E21F-4E83-96CE-BFCCE500DB7C") IDWri
/// If any of these callbacks returns an error, the analysis functions will
/// stop prematurely and return a callback error.
/// </summary>
interface DECLSPEC_UUID("{639CFAD8-0FB4-4B21-A58A-067920120009}") DECLSPEC_NOVTABLE IDWriteTextAnalysisSource1 : public IDWriteTextAnalysisSource
interface DWRITE_DECLARE_INTERFACE("639CFAD8-0FB4-4B21-A58A-067920120009") IDWriteTextAnalysisSource1 : public IDWriteTextAnalysisSource
{
/// <summary>
/// The text analyzer calls back to this to get the desired glyph
@@ -1753,7 +1753,7 @@ interface DECLSPEC_UUID("{639CFAD8-0FB4-4B21-A58A-067920120009}") DECLSPEC_NOVTA
/// The interface implemented by the client to receive the
/// output of the text analyzers.
/// </summary>
interface DECLSPEC_UUID("B0D941A0-85E7-4D8B-9FD3-5CED9934482A") DECLSPEC_NOVTABLE IDWriteTextAnalysisSink1 : public IDWriteTextAnalysisSink
interface DWRITE_DECLARE_INTERFACE("B0D941A0-85E7-4D8B-9FD3-5CED9934482A") IDWriteTextAnalysisSink1 : public IDWriteTextAnalysisSink
{
/// <summary>
/// The text analyzer calls back to this to report the actual orientation
+294
View File
@@ -0,0 +1,294 @@
/*
Copyright (c) Microsoft Corporation. All rights reserved.
Module Name:
sdkddkver.h
Abstract:
Master include file for versioning windows SDK/DDK.
*/
#ifndef _INC_SDKDDKVER
#define _INC_SDKDDKVER
#if (_MSC_VER >= 800)
#if (_MSC_VER >= 1200)
#pragma warning(push)
#pragma warning(disable:4668) /* #if not_defined treated as #if 0 */
#endif
#pragma warning(disable:4001) /* nonstandard extension : single line comment */
#endif
#pragma once
//
// _WIN32_WINNT version constants
//
#define _WIN32_WINNT_NT4 0x0400
#define _WIN32_WINNT_WIN2K 0x0500
#define _WIN32_WINNT_WINXP 0x0501
#define _WIN32_WINNT_WS03 0x0502
#define _WIN32_WINNT_WIN6 0x0600
#define _WIN32_WINNT_VISTA 0x0600
#define _WIN32_WINNT_WS08 0x0600
#define _WIN32_WINNT_LONGHORN 0x0600
#define _WIN32_WINNT_WIN7 0x0601
#define _WIN32_WINNT_WIN8 0x0602
#define _WIN32_WINNT_WINBLUE 0x0603
#define _WIN32_WINNT_WINTHRESHOLD 0x0A00 /* ABRACADABRA_THRESHOLD*/
#define _WIN32_WINNT_WIN10 0x0A00 /* ABRACADABRA_THRESHOLD*/
//
// _WIN32_IE_ version constants
//
#define _WIN32_IE_IE20 0x0200
#define _WIN32_IE_IE30 0x0300
#define _WIN32_IE_IE302 0x0302
#define _WIN32_IE_IE40 0x0400
#define _WIN32_IE_IE401 0x0401
#define _WIN32_IE_IE50 0x0500
#define _WIN32_IE_IE501 0x0501
#define _WIN32_IE_IE55 0x0550
#define _WIN32_IE_IE60 0x0600
#define _WIN32_IE_IE60SP1 0x0601
#define _WIN32_IE_IE60SP2 0x0603
#define _WIN32_IE_IE70 0x0700
#define _WIN32_IE_IE80 0x0800
#define _WIN32_IE_IE90 0x0900
#define _WIN32_IE_IE100 0x0A00
#define _WIN32_IE_IE110 0x0A00 /* ABRACADABRA_THRESHOLD */
//
// IE <-> OS version mapping
//
// NT4 supports IE versions 2.0 -> 6.0 SP1
#define _WIN32_IE_NT4 _WIN32_IE_IE20
#define _WIN32_IE_NT4SP1 _WIN32_IE_IE20
#define _WIN32_IE_NT4SP2 _WIN32_IE_IE20
#define _WIN32_IE_NT4SP3 _WIN32_IE_IE302
#define _WIN32_IE_NT4SP4 _WIN32_IE_IE401
#define _WIN32_IE_NT4SP5 _WIN32_IE_IE401
#define _WIN32_IE_NT4SP6 _WIN32_IE_IE50
// Win98 supports IE versions 4.01 -> 6.0 SP1
#define _WIN32_IE_WIN98 _WIN32_IE_IE401
// Win98SE supports IE versions 5.0 -> 6.0 SP1
#define _WIN32_IE_WIN98SE _WIN32_IE_IE50
// WinME supports IE versions 5.5 -> 6.0 SP1
#define _WIN32_IE_WINME _WIN32_IE_IE55
// Win2k supports IE versions 5.01 -> 6.0 SP1
#define _WIN32_IE_WIN2K _WIN32_IE_IE501
#define _WIN32_IE_WIN2KSP1 _WIN32_IE_IE501
#define _WIN32_IE_WIN2KSP2 _WIN32_IE_IE501
#define _WIN32_IE_WIN2KSP3 _WIN32_IE_IE501
#define _WIN32_IE_WIN2KSP4 _WIN32_IE_IE501
#define _WIN32_IE_XP _WIN32_IE_IE60
#define _WIN32_IE_XPSP1 _WIN32_IE_IE60SP1
#define _WIN32_IE_XPSP2 _WIN32_IE_IE60SP2
#define _WIN32_IE_WS03 0x0602
#define _WIN32_IE_WS03SP1 _WIN32_IE_IE60SP2
#define _WIN32_IE_WIN6 _WIN32_IE_IE70
#define _WIN32_IE_LONGHORN _WIN32_IE_IE70
#define _WIN32_IE_WIN7 _WIN32_IE_IE80
#define _WIN32_IE_WIN8 _WIN32_IE_IE100
#define _WIN32_IE_WINBLUE _WIN32_IE_IE100
#define _WIN32_IE_WINTHRESHOLD _WIN32_IE_IE110 /* ABRACADABRA_THRESHOLD */
#define _WIN32_IE_WIN10 _WIN32_IE_IE110 /* ABRACADABRA_THRESHOLD */
//
// NTDDI version constants
//
#define NTDDI_WIN2K 0x05000000
#define NTDDI_WIN2KSP1 0x05000100
#define NTDDI_WIN2KSP2 0x05000200
#define NTDDI_WIN2KSP3 0x05000300
#define NTDDI_WIN2KSP4 0x05000400
#define NTDDI_WINXP 0x05010000
#define NTDDI_WINXPSP1 0x05010100
#define NTDDI_WINXPSP2 0x05010200
#define NTDDI_WINXPSP3 0x05010300
#define NTDDI_WINXPSP4 0x05010400
#define NTDDI_WS03 0x05020000
#define NTDDI_WS03SP1 0x05020100
#define NTDDI_WS03SP2 0x05020200
#define NTDDI_WS03SP3 0x05020300
#define NTDDI_WS03SP4 0x05020400
#define NTDDI_WIN6 0x06000000
#define NTDDI_WIN6SP1 0x06000100
#define NTDDI_WIN6SP2 0x06000200
#define NTDDI_WIN6SP3 0x06000300
#define NTDDI_WIN6SP4 0x06000400
#define NTDDI_VISTA NTDDI_WIN6
#define NTDDI_VISTASP1 NTDDI_WIN6SP1
#define NTDDI_VISTASP2 NTDDI_WIN6SP2
#define NTDDI_VISTASP3 NTDDI_WIN6SP3
#define NTDDI_VISTASP4 NTDDI_WIN6SP4
#define NTDDI_LONGHORN NTDDI_VISTA
#define NTDDI_WS08 NTDDI_WIN6SP1
#define NTDDI_WS08SP2 NTDDI_WIN6SP2
#define NTDDI_WS08SP3 NTDDI_WIN6SP3
#define NTDDI_WS08SP4 NTDDI_WIN6SP4
#define NTDDI_WIN7 0x06010000
#define NTDDI_WIN8 0x06020000
#define NTDDI_WINBLUE 0x06030000
#define NTDDI_WINTHRESHOLD 0x0A000000 /* ABRACADABRA_THRESHOLD */
#define NTDDI_WIN10 0x0A000000 /* ABRACADABRA_THRESHOLD */
#define NTDDI_WIN10_TH2 0x0A000001 /* ABRACADABRA_WIN10_TH2 */
//
// masks for version macros
//
#define OSVERSION_MASK 0xFFFF0000
#define SPVERSION_MASK 0x0000FF00
#define SUBVERSION_MASK 0x000000FF
//
// macros to extract various version fields from the NTDDI version
//
#define OSVER(Version) ((Version) & OSVERSION_MASK)
#define SPVER(Version) (((Version) & SPVERSION_MASK) >> 8)
#define SUBVER(Version) (((Version) & SUBVERSION_MASK) )
#if defined(DECLSPEC_DEPRECATED_DDK)
// deprecate in 2k or later
#if (NTDDI_VERSION >= NTDDI_WIN2K)
#define DECLSPEC_DEPRECATED_DDK_WIN2K DECLSPEC_DEPRECATED_DDK
#else
#define DECLSPEC_DEPRECATED_DDK_WIN2K
#endif
// deprecate in XP or later
#if (NTDDI_VERSION >= NTDDI_WINXP)
#define DECLSPEC_DEPRECATED_DDK_WINXP DECLSPEC_DEPRECATED_DDK
#else
#define DECLSPEC_DEPRECATED_DDK_WINXP
#endif
// deprecate in WS03 or later
#if (NTDDI_VERSION >= NTDDI_WS03)
#define DECLSPEC_DEPRECATED_DDK_WIN2003 DECLSPEC_DEPRECATED_DDK
#else
#define DECLSPEC_DEPRECATED_DDK_WIN2003
#endif
// deprecate in WIN6 or later
#if (NTDDI_VERSION >= NTDDI_WIN6)
#define DECLSPEC_DEPRECATED_DDK_WIN6 DECLSPEC_DEPRECATED_DDK
#else
#define DECLSPEC_DEPRECATED_DDK_WIN6
#endif
#define DECLSPEC_DEPRECATED_DDK_LONGHORN DECLSPEC_DEPRECATED_DDK_WIN6
#endif // defined(DECLSPEC_DEPRECATED_DDK)
//
// if versions aren't already defined, default to most current
//
#define NTDDI_VERSION_FROM_WIN32_WINNT2(ver) ver##0000
#define NTDDI_VERSION_FROM_WIN32_WINNT(ver) NTDDI_VERSION_FROM_WIN32_WINNT2(ver)
#if !defined(_WIN32_WINNT) && !defined(_CHICAGO_)
#define _WIN32_WINNT 0x0A00
#endif
#ifndef NTDDI_VERSION
#ifdef _WIN32_WINNT
// set NTDDI_VERSION based on _WIN32_WINNT
#define NTDDI_VERSION NTDDI_VERSION_FROM_WIN32_WINNT(_WIN32_WINNT)
#else
#define NTDDI_VERSION 0x0A000001
#endif
#endif
#ifndef WINVER
#ifdef _WIN32_WINNT
// set WINVER based on _WIN32_WINNT
#define WINVER _WIN32_WINNT
#else
#define WINVER 0x0A00
#endif
#endif
#ifndef _WIN32_IE
#ifdef _WIN32_WINNT
// set _WIN32_IE based on _WIN32_WINNT
#if (_WIN32_WINNT <= _WIN32_WINNT_NT4)
#define _WIN32_IE _WIN32_IE_IE50
#elif (_WIN32_WINNT <= _WIN32_WINNT_WIN2K)
#define _WIN32_IE _WIN32_IE_IE501
#elif (_WIN32_WINNT <= _WIN32_WINNT_WINXP)
#define _WIN32_IE _WIN32_IE_IE60
#elif (_WIN32_WINNT <= _WIN32_WINNT_WS03)
#define _WIN32_IE _WIN32_IE_WS03
#elif (_WIN32_WINNT <= _WIN32_WINNT_VISTA)
#define _WIN32_IE _WIN32_IE_LONGHORN
#elif (_WIN32_WINNT <= _WIN32_WINNT_WIN7)
#define _WIN32_IE _WIN32_IE_WIN7
#elif (_WIN32_WINNT <= _WIN32_WINNT_WIN8)
#define _WIN32_IE _WIN32_IE_WIN8
#else
#define _WIN32_IE 0x0A00
#endif
#else
#define _WIN32_IE 0x0A00
#endif
#endif
//
// Sanity check for compatible versions
//
#if defined(_WIN32_WINNT) && !defined(MIDL_PASS) && !defined(RC_INVOKED)
#if (defined(WINVER) && (WINVER < 0x0400) && (_WIN32_WINNT > 0x0400))
#error WINVER setting conflicts with _WIN32_WINNT setting
#endif
#if (((OSVERSION_MASK & NTDDI_VERSION) == NTDDI_WIN2K) && (_WIN32_WINNT != _WIN32_WINNT_WIN2K))
#error NTDDI_VERSION setting conflicts with _WIN32_WINNT setting
#endif
#if (((OSVERSION_MASK & NTDDI_VERSION) == NTDDI_WINXP) && (_WIN32_WINNT != _WIN32_WINNT_WINXP))
#error NTDDI_VERSION setting conflicts with _WIN32_WINNT setting
#endif
#if (((OSVERSION_MASK & NTDDI_VERSION) == NTDDI_WS03) && (_WIN32_WINNT != _WIN32_WINNT_WS03))
#error NTDDI_VERSION setting conflicts with _WIN32_WINNT setting
#endif
#if (((OSVERSION_MASK & NTDDI_VERSION) == NTDDI_VISTA) && (_WIN32_WINNT != _WIN32_WINNT_VISTA))
#error NTDDI_VERSION setting conflicts with _WIN32_WINNT setting
#endif
#if ((_WIN32_WINNT < _WIN32_WINNT_WIN2K) && (_WIN32_IE > _WIN32_IE_IE60SP1))
#error _WIN32_WINNT settings conflicts with _WIN32_IE setting
#endif
#endif // defined(_WIN32_WINNT) && !defined(MIDL_PASS) && !defined(_WINRESRC_)
#if (_MSC_VER >= 800)
#if (_MSC_VER >= 1200)
#pragma warning(pop)
#else
#pragma warning(default:4001) /* nonstandard extension : single line comment */
#endif
#endif
#endif /* !_INC_SDKDDKVER */
+240
View File
@@ -0,0 +1,240 @@
/*
Copyright (c) Microsoft Corporation. All rights reserved.
Module Name:
winapifamily.h
Abstract:
Master include file for API family partitioning.
*/
#ifndef _INC_WINAPIFAMILY
#define _INC_WINAPIFAMILY
#if defined(_MSC_VER) && !defined(MOFCOMP_PASS)
#if _MSC_VER >= 1200
#pragma warning(push)
#pragma warning(disable:4001) /* nonstandard extension 'single line comment' was used */
#endif
#pragma once
#endif // defined(_MSC_VER) && !defined(MOFCOMP_PASS)
#include <winpackagefamily.h>
/*
* When compiling C and C++ code using SDK header files, the development
* environment can specify a target platform by #define-ing the
* pre-processor symbol WINAPI_FAMILY to one of the following values.
* Each FAMILY value denotes an application family for which a different
* subset of the total set of header-file-defined APIs are available.
* Setting the WINAPI_FAMILY value will effectively hide from the
* editing and compilation environments the existence of APIs that
* are not applicable to the family of applications targeting a
* specific platform.
*/
/* In Windows 10, WINAPI_PARTITIONs will be used to add additional
* device specific APIs to a particular WINAPI_FAMILY.
* For example, when writing Windows Universal apps, specifying
* WINAPI_FAMILY_APP will hide phone APIs from compilation.
* However, specifying WINAPI_PARTITION_PHONE_APP=1 additionally, will
* unhide any API hidden behind the partition, to the compiler.
* The following partitions are currently defined:
* WINAPI_PARTITION_DESKTOP // usable for Desktop Win32 apps (but not store apps)
* WINAPI_PARTITION_APP // usable for Windows Universal store apps
* WINAPI_PARTITION_PC_APP // specific to Desktop-only store apps
* WINAPI_PARTITION_PHONE_APP // specific to Phone-only store apps
* WINAPI_PARTITION_SYSTEM // specific to System applications
* The following partitions are indirect partitions and defined in
* winpackagefamily.h. These partitions are related to package based
* partitions. For example, specifying WINAPI_PARTITION_SERVER=1 will light up
* any API hidden behind the package based partitions that are bound to
* WINAPI_PARTITION_SERVER, to the compiler.
* WINAPI_PARTITION_SERVER // specific to Server applications
*/
/*
* The WINAPI_FAMILY values of 0 and 1 are reserved to ensure that
* an error will occur if WINAPI_FAMILY is set to any
* WINAPI_PARTITION value (which must be 0 or 1, see below).
*/
#define WINAPI_FAMILY_PC_APP 2 /* Windows Store Applications */
#define WINAPI_FAMILY_PHONE_APP 3 /* Windows Phone Applications */
#define WINAPI_FAMILY_SYSTEM 4 /* Windows Drivers and Tools */
#define WINAPI_FAMILY_SERVER 5 /* Windows Server Applications */
#define WINAPI_FAMILY_DESKTOP_APP 100 /* Windows Desktop Applications */
/* The value of WINAPI_FAMILY_DESKTOP_APP may change in future SDKs. */
/* Additional WINAPI_FAMILY values may be defined in future SDKs. */
/*
* For compatibility with Windows 8 header files, the following
* synonym for WINAPI_FAMILY_PC_APP is temporarily #define'd.
* Use of this symbol should be considered deprecated.
*/
#define WINAPI_FAMILY_APP WINAPI_FAMILY_PC_APP
/*
* If no WINAPI_FAMILY value is specified, then all APIs available to
* Windows desktop applications are exposed.
*/
#ifndef WINAPI_FAMILY
#define WINAPI_FAMILY WINAPI_FAMILY_DESKTOP_APP
#endif
/*
* API PARTITONs are part of an indirection mechanism for mapping between
* individual APIs and the FAMILYs to which they apply.
* Each PARTITION is a category or subset of named APIs. PARTITIONs
* are permitted to have overlapping membership -- some single API
* might be part of more than one PARTITION. PARTITIONS are each #define-ed
* to be either 1 or 0 or depending on the platform at which the app is targeted.
*/
/*
* The mapping between families and partitions is summarized here.
* An X indicates that the given partition is active for the given
* platform/family.
*
* +-------------------+---+
* | *Partition* | |
* +---+---+---+---+---+---+
* | | | | | | |
* | | | | | | |
* | | | | P | | |
* | | | | H | | |
* | D | | | O | | |
* | E | | P | N | S | S |
* | S | | C | E | Y | E |
* | K | | _ | _ | S | R |
* | T | A | A | A | T | V |
* +-------------------------+----+ O | P | P | P | E | E |
* | *Platform/Family* \| P | P | P | P | M | R |
* +------------------------------+---+---+---+---+---+---+
* | WINAPI_FAMILY_DESKTOP_APP | X | X | X | | | |
* +------------------------------+---+---+---+---+---+---+
* | WINAPI_FAMILY_PC_APP | | X | X | | | |
* +------------------------------+---+---+---+---+---+---+
* | WINAPI_FAMILY_PHONE_APP | | X | | X | | |
* +----------------------------- +---+---+---+---+---+---+
* | WINAPI_FAMILY_SYSTEM | | | | | X | |
* +----------------------------- +---+---+---+---+---+---+
* | WINAPI_FAMILY_SERVER | | | | | X | X |
* +------------------------------+---+---+---+---+---+---+
*
* The table above is encoded in the following expressions,
* each of which evaluates to 1 or 0.
*
* Whenever a new family is added, all of these expressions
* need to be reconsidered.
*/
#if WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP && \
WINAPI_FAMILY != WINAPI_FAMILY_PC_APP && \
WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP && \
WINAPI_FAMILY != WINAPI_FAMILY_SYSTEM && \
WINAPI_FAMILY != WINAPI_FAMILY_SERVER
#error Unknown WINAPI_FAMILY value. Was it defined in terms of a WINAPI_PARTITION_* value?
#endif
#ifndef WINAPI_PARTITION_DESKTOP
#define WINAPI_PARTITION_DESKTOP (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)
#endif
#ifndef WINAPI_PARTITION_APP
#define WINAPI_PARTITION_APP \
(WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP || \
WINAPI_FAMILY == WINAPI_FAMILY_PC_APP || \
WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
#endif
#ifndef WINAPI_PARTITION_PC_APP
#define WINAPI_PARTITION_PC_APP \
(WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP || \
WINAPI_FAMILY == WINAPI_FAMILY_PC_APP)
#endif
#ifndef WINAPI_PARTITION_PHONE_APP
#define WINAPI_PARTITION_PHONE_APP (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
#endif
/*
* SYSTEM is the only partition defined here.
* All other System based editions are defined as packages
* on top of the System partition.
* See winpackagefamily.h for packages level partitions
*/
#ifndef WINAPI_PARTITION_SYSTEM
#define WINAPI_PARTITION_SYSTEM \
(WINAPI_FAMILY == WINAPI_FAMILY_SYSTEM || \
WINAPI_FAMILY == WINAPI_FAMILY_SERVER)
#endif
/*
* For compatibility with Windows Phone 8 header files, the following
* synonym for WINAPI_PARTITION_PHONE_APP is temporarily #define'd.
* Use of this symbol should be regarded as deprecated.
*/
#define WINAPI_PARTITION_PHONE WINAPI_PARTITION_PHONE_APP
/*
* Header files use the WINAPI_FAMILY_PARTITION macro to assign one or
* more declarations to some group of partitions. The macro chooses
* whether the preprocessor will emit or omit a sequence of declarations
* bracketed by an #if/#endif pair. All header file references to the
* WINAPI_PARTITION_* values should be in the form of occurrences of
* WINAPI_FAMILY_PARTITION(...).
*
* For example, the following usage of WINAPI_FAMILY_PARTITION identifies
* a sequence of declarations that are part of both the Windows Desktop
* Partition and the Windows-Phone-Specific Store Partition:
*
* #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_PHONE_APP)
* ...
* #endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_PHONE_APP)
*
* The comment on the closing #endif allow tools as well as people to find the
* matching #ifdef properly.
*
* Usages of WINAPI_FAMILY_PARTITION may be combined, when the partitition definitions are
* related. In particular one might use declarations like
*
* #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
*
* or
*
* #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
*
* Direct references to WINAPI_PARTITION_ values (eg #if !WINAPI_FAMILY_PARTITION_...)
* should not be used.
*/
#define WINAPI_FAMILY_PARTITION(Partitions) (Partitions)
/*
* Macro used to #define or typedef a symbol used for selective deprecation
* of individual methods of a COM interfaces that are otherwise available
* for a given set of partitions.
*/
#define _WINAPI_DEPRECATED_DECLARATION __declspec(deprecated("This API cannot be used in the context of the caller's application type."))
/*
* For compatibility with Windows 8 header files, the following
* symbol is temporarily conditionally #define'd. Additional symbols
* like this should be not defined in winapifamily.h, but rather should be
* introduced locally to the header files of the component that needs them.
*/
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
# define APP_DEPRECATED_HRESULT HRESULT _WINAPI_DEPRECATED_DECLARATION
#endif // WINAPIFAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#if defined(_MSC_VER) && !defined(MOFCOMP_PASS)
#if _MSC_VER >= 1200
#pragma warning(pop)
#endif
#endif
#endif /* !_INC_WINAPIFAMILY */
+81
View File
@@ -0,0 +1,81 @@
/*
Copyright (c) Microsoft Corporation. All rights reserved.
Module Name:
winpackagefamily.h
Abstract:
API family partitioning based on packages.
*/
#ifndef _INC_WINPACKAGEFAMILY
#define _INC_WINPACKAGEFAMILY
#if defined(_MSC_VER) && !defined(MOFCOMP_PASS)
#if _MSC_VER >= 1200
#pragma warning(push)
#pragma warning(disable:4001) /* nonstandard extension 'single line comment' was used */
#endif
#pragma once
#endif // defined(_MSC_VER) && !defined(MOFCOMP_PASS)
#ifndef WINAPI_PARTITION_SERVER
#define WINAPI_PARTITION_SERVER (WINAPI_FAMILY == WINAPI_FAMILY_SERVER)
#endif
/*
* PARTITIONS based on packages are each #undef'ed below, and then will be #define-ed
* to be either 1 or 0 or depending on the active WINAPI_FAMILY.
*/
#undef WINAPI_PARTITION_PKG_WINTRUST
#undef WINAPI_PARTITION_PKG_WEBSERVICES
#undef WINAPI_PARTITION_PKG_EVENTLOGSERVICE
#undef WINAPI_PARTITION_PKG_VHD
#undef WINAPI_PARTITION_PKG_PERFCOUNTER
#undef WINAPI_PARTITION_PKG_SECURESTARTUP
#undef WINAPI_PARTITION_PKG_REMOTEFS
#undef WINAPI_PARTITION_PKG_BOOTABLESKU
#undef WINAPI_PARTITION_PKG_CMD
#undef WINAPI_PARTITION_PKG_CMDTOOLS
#undef WINAPI_PARTITION_PKG_DISM
#undef WINAPI_PARTITION_PKG_CORESETUP
#undef WINAPI_PARTITION_PKG_APPRUNTIME
#undef WINAPI_PARTITION_PKG_ESENT
#undef WINAPI_PARTITION_PKG_WINMGMT
#undef WINAPI_PARTITION_PKG_WNV
#undef WINAPI_PARTITION_PKG_CLUSTER
#undef WINAPI_PARTITION_PKG_VSS
/*
* PARTITIONS for feature packages. Each package might be active for one or more editions
*/
#define WINAPI_PARTITION_PKG_WINTRUST (WINAPI_PARTITION_SERVER == 1)
#define WINAPI_PARTITION_PKG_WEBSERVICES (WINAPI_PARTITION_SERVER == 1)
#define WINAPI_PARTITION_PKG_EVENTLOGSERVICE (WINAPI_PARTITION_SERVER == 1)
#define WINAPI_PARTITION_PKG_VHD (WINAPI_PARTITION_SERVER == 1)
#define WINAPI_PARTITION_PKG_PERFCOUNTER (WINAPI_PARTITION_SERVER == 1)
#define WINAPI_PARTITION_PKG_SECURESTARTUP (WINAPI_PARTITION_SERVER == 1)
#define WINAPI_PARTITION_PKG_REMOTEFS (WINAPI_PARTITION_SERVER == 1)
#define WINAPI_PARTITION_PKG_BOOTABLESKU (WINAPI_PARTITION_SERVER == 1)
#define WINAPI_PARTITION_PKG_CMD (WINAPI_PARTITION_SERVER == 1)
#define WINAPI_PARTITION_PKG_CMDTOOLS (WINAPI_PARTITION_SERVER == 1)
#define WINAPI_PARTITION_PKG_DISM (WINAPI_PARTITION_SERVER == 1)
#define WINAPI_PARTITION_PKG_CORESETUP (WINAPI_PARTITION_SERVER == 1)
#define WINAPI_PARTITION_PKG_APPRUNTIME (WINAPI_PARTITION_SERVER == 1)
#define WINAPI_PARTITION_PKG_ESENT (WINAPI_PARTITION_SERVER == 1)
#define WINAPI_PARTITION_PKG_WINMGMT (WINAPI_PARTITION_SERVER == 1)
#define WINAPI_PARTITION_PKG_WNV (WINAPI_PARTITION_SERVER == 1)
#define WINAPI_PARTITION_PKG_CLUSTER (WINAPI_PARTITION_SERVER == 1)
#define WINAPI_PARTITION_PKG_VSS (WINAPI_PARTITION_SERVER == 1)
#if defined(_MSC_VER) && !defined(MOFCOMP_PASS)
#if _MSC_VER >= 1200
#pragma warning(pop)
#endif
#endif
#endif /* !_INC_WINPACKAGEFAMILY */
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -266,7 +266,7 @@ public:
.setOptLevel(llvm::CodeGenOpt::Aggressive)
.setMCPU("nehalem")
.create();
module_ptr->setDataLayout(execution_engine->getDataLayout());
module_ptr->setDataLayout(*execution_engine->getDataLayout());
execution_engine->finalizeObject();
+2 -2
View File
@@ -47,12 +47,12 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)bin\</OutDir>
<IncludePath>.\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;.\OpenAL\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx9\Include;..\minidx12\Include</IncludePath>
<IncludePath>.\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;.\OpenAL\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx9\Include;..\minidx12\Include;..\GSL\include</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)bin\</OutDir>
<IncludePath>.\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;.\OpenAL\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx9\Include;..\minidx12\Include</IncludePath>
<IncludePath>.\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;.\OpenAL\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx9\Include;..\minidx12\Include;..\GSL\include</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
+6 -17
View File
@@ -139,12 +139,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrc", "wxWidgets\build\msw\
{24C45343-FD20-5C92-81C1-35A2AE841E79} = {24C45343-FD20-5C92-81C1-35A2AE841E79}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "stblib", "stblib", "{9D839DFB-76E6-4F10-8EED-BA2AC7CC3FB6}"
ProjectSection(SolutionItems) = preProject
stblib\stb_image.c = stblib\stb_image.c
stblib\stb_image.h = stblib\stb_image.h
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ribbon", "wxWidgets\build\msw\wx_ribbon.vcxproj", "{87B42A9C-3F5C-53D7-9017-2B1CAE39457D}"
ProjectSection(ProjectDependencies) = postProject
{24C45343-FD20-5C92-81C1-35A2AE841E79} = {24C45343-FD20-5C92-81C1-35A2AE841E79}
@@ -181,8 +175,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_custom_build", "wxWidgets\
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "copy_setup_h", "rpcs3\copy_setup_h.vcxproj", "{00D36322-6188-4A66-B514-3B3F183E998D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GSRender", "GSRender", "{1A43FD7A-C7DD-4D04-A4D6-FAA194AAD9D2}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "D3D12GSRender", "rpcs3\D3D12GSRender.vcxproj", "{FAC9B17B-F4B8-4B75-8AEB-C8C7CB92B078}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rpcs3-tests", "rpcs3-tests\rpcs3-tests.vcxproj", "{AB222E8A-00CA-4ACF-A87E-5251C16C0587}"
@@ -539,18 +531,18 @@ Global
{74827EBD-93DC-5110-BA95-3F2AB029B6B0}.Release - LLVM|x64.Build.0 = Release|x64
{74827EBD-93DC-5110-BA95-3F2AB029B6B0}.Release|x64.ActiveCfg = Release|x64
{74827EBD-93DC-5110-BA95-3F2AB029B6B0}.Release|x64.Build.0 = Release|x64
{AC40FF01-426E-4838-A317-66354CEFAE88}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{AC40FF01-426E-4838-A317-66354CEFAE88}.Debug - LLVM|x64.Build.0 = Debug|x64
{AC40FF01-426E-4838-A317-66354CEFAE88}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{AC40FF01-426E-4838-A317-66354CEFAE88}.Debug - MemLeak|x64.Build.0 = Debug|x64
{AC40FF01-426E-4838-A317-66354CEFAE88}.Debug - LLVM|x64.ActiveCfg = Debug - LLVM|x64
{AC40FF01-426E-4838-A317-66354CEFAE88}.Debug - LLVM|x64.Build.0 = Debug - LLVM|x64
{AC40FF01-426E-4838-A317-66354CEFAE88}.Debug - MemLeak|x64.ActiveCfg = Debug - MemLeak|x64
{AC40FF01-426E-4838-A317-66354CEFAE88}.Debug - MemLeak|x64.Build.0 = Debug - MemLeak|x64
{AC40FF01-426E-4838-A317-66354CEFAE88}.Debug|x64.ActiveCfg = Debug|x64
{AC40FF01-426E-4838-A317-66354CEFAE88}.Debug|x64.Build.0 = Debug|x64
{AC40FF01-426E-4838-A317-66354CEFAE88}.DLL Debug|x64.ActiveCfg = Debug|x64
{AC40FF01-426E-4838-A317-66354CEFAE88}.DLL Debug|x64.Build.0 = Debug|x64
{AC40FF01-426E-4838-A317-66354CEFAE88}.DLL Release|x64.ActiveCfg = Release|x64
{AC40FF01-426E-4838-A317-66354CEFAE88}.DLL Release|x64.Build.0 = Release|x64
{AC40FF01-426E-4838-A317-66354CEFAE88}.Release - LLVM|x64.ActiveCfg = Release|x64
{AC40FF01-426E-4838-A317-66354CEFAE88}.Release - LLVM|x64.Build.0 = Release|x64
{AC40FF01-426E-4838-A317-66354CEFAE88}.Release - LLVM|x64.ActiveCfg = Release - LLVM|x64
{AC40FF01-426E-4838-A317-66354CEFAE88}.Release - LLVM|x64.Build.0 = Release - LLVM|x64
{AC40FF01-426E-4838-A317-66354CEFAE88}.Release|x64.ActiveCfg = Release|x64
{AC40FF01-426E-4838-A317-66354CEFAE88}.Release|x64.Build.0 = Release|x64
{C4A10229-4712-4BD2-B63E-50D93C67A038}.Debug - LLVM|x64.ActiveCfg = Debug - LLVM|x64
@@ -623,9 +615,7 @@ Global
{AB222E8A-00CA-4ACF-A87E-5251C16C0587}.Debug - LLVM|x64.ActiveCfg = Debug|x64
{AB222E8A-00CA-4ACF-A87E-5251C16C0587}.Debug - LLVM|x64.Build.0 = Debug|x64
{AB222E8A-00CA-4ACF-A87E-5251C16C0587}.Debug - MemLeak|x64.ActiveCfg = Debug|x64
{AB222E8A-00CA-4ACF-A87E-5251C16C0587}.Debug - MemLeak|x64.Build.0 = Debug|x64
{AB222E8A-00CA-4ACF-A87E-5251C16C0587}.Debug|x64.ActiveCfg = Debug|x64
{AB222E8A-00CA-4ACF-A87E-5251C16C0587}.Debug|x64.Build.0 = Debug|x64
{AB222E8A-00CA-4ACF-A87E-5251C16C0587}.DLL Debug|x64.ActiveCfg = Debug|x64
{AB222E8A-00CA-4ACF-A87E-5251C16C0587}.DLL Debug|x64.Build.0 = Debug|x64
{AB222E8A-00CA-4ACF-A87E-5251C16C0587}.DLL Release|x64.ActiveCfg = Release|x64
@@ -633,7 +623,6 @@ Global
{AB222E8A-00CA-4ACF-A87E-5251C16C0587}.Release - LLVM|x64.ActiveCfg = Release|x64
{AB222E8A-00CA-4ACF-A87E-5251C16C0587}.Release - LLVM|x64.Build.0 = Release|x64
{AB222E8A-00CA-4ACF-A87E-5251C16C0587}.Release|x64.ActiveCfg = Release|x64
{AB222E8A-00CA-4ACF-A87E-5251C16C0587}.Release|x64.Build.0 = Release|x64
{3384223A-6D97-4799-9862-359F85312892}.Debug - LLVM|x64.ActiveCfg = Debug - LLVM|x64
{3384223A-6D97-4799-9862-359F85312892}.Debug - LLVM|x64.Build.0 = Debug - LLVM|x64
{3384223A-6D97-4799-9862-359F85312892}.Debug - MemLeak|x64.ActiveCfg = Debug - MemLeak|x64
+2
View File
@@ -112,6 +112,7 @@ ${LLVM_INCLUDE_DIRS}
"${RPCS3_SRC_DIR}/.."
"${RPCS3_SRC_DIR}/../asmjit/src/asmjit"
"${RPCS3_SRC_DIR}/../glm"
"${RPCS3_SRC_DIR}/../GSL/include"
"${RPCS3_SRC_DIR}/../rsx_program_decompiler/rsx_decompiler"
"${RPCS3_SRC_DIR}/../rsx_program_decompiler/shader_code"
)
@@ -155,6 +156,7 @@ GLOB_RECURSE
RPCS3_SRC
"${RPCS3_SRC_DIR}/rpcs3.cpp"
"${RPCS3_SRC_DIR}/config.cpp"
"${RPCS3_SRC_DIR}/stb_image.cpp"
"${RPCS3_SRC_DIR}/../Utilities/GNU.cpp"
"${RPCS3_SRC_DIR}/Emu/*"
"${RPCS3_SRC_DIR}/Gui/*"
+3 -2
View File
@@ -820,7 +820,6 @@ int DecryptEDAT(const std::string& input_file_name, const std::string& output_fi
// Prepare the files.
fs::file input(input_file_name);
fs::file output(output_file_name, fom::rewrite);
fs::file rap(rap_file_name);
// Set keys (RIF and DEVKLIC).
unsigned char rifkey[0x10];
@@ -879,8 +878,10 @@ int DecryptEDAT(const std::string& input_file_name, const std::string& output_fi
}
// Read the RAP file, if provided.
if (rap)
if (rap_file_name.size())
{
fs::file rap(rap_file_name);
unsigned char rapkey[0x10];
memset(rapkey, 0, 0x10);
+1 -1
View File
@@ -62,7 +62,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, volatile f64& pr
const std::size_t BUF_SIZE = 8192 * 1024; // 8 MB
// Save current file offset (probably zero)
const u64 start_offset = pkg_f.seek(0, fsm::cur);
const u64 start_offset = pkg_f.seek(0, fs::seek_cur);
// Get basic PKG information
PKGHeader header;
+4 -2
View File
@@ -942,9 +942,9 @@ bool SELFDecrypter::DecryptNPDRM(u8 *metadata, u32 metadata_size)
bool SELFDecrypter::LoadMetadata()
{
aes_context aes;
u32 metadata_info_size = sizeof32(meta_info);
u32 metadata_info_size = SIZE_32(meta_info);
u8 *metadata_info = (u8 *)malloc(metadata_info_size);
u32 metadata_headers_size = sce_hdr.se_hsize - (sizeof32(sce_hdr) + sce_hdr.se_meta + sizeof32(meta_info));
u32 metadata_headers_size = sce_hdr.se_hsize - (SIZE_32(sce_hdr) + sce_hdr.se_meta + SIZE_32(meta_info));
u8 *metadata_headers = (u8 *)malloc(metadata_headers_size);
// Locate and read the encrypted metadata info.
@@ -1330,6 +1330,8 @@ bool CheckDebugSelf(const std::string& self, const std::string& elf)
bool DecryptSelf(const std::string& elf, const std::string& self)
{
LOG_NOTICE(LOADER, "Decrypting %s", self);
// Check for a debug SELF first.
if (!CheckDebugSelf(self, elf))
{
+1 -60
View File
@@ -61,66 +61,7 @@
<Import Project="..\rpcs3_llvm.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - MemLeak|x64'">
<OutDir>$(SolutionDir)lib\$(Configuration)-$(Platform)\</OutDir>
<IntDir>$(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">
<OutDir>$(SolutionDir)lib\$(Configuration)-$(Platform)\</OutDir>
<IntDir>$(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)lib\$(Configuration)-$(Platform)\</OutDir>
<IntDir>$(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)lib\$(Configuration)-$(Platform)\</OutDir>
<IntDir>$(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">
<OutDir>$(SolutionDir)lib\$(Configuration)-$(Platform)\</OutDir>
<IntDir>$(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - MemLeak|x64'">
<Lib>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Lib>
<ClCompile>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">
<Lib>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<AdditionalDependencies />
<AdditionalLibraryDirectories />
</Lib>
<ClCompile>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Lib>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Lib>
<ClCompile>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Lib>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Lib>
<ClCompile>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">
<Lib>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<AdditionalDependencies />
<AdditionalLibraryDirectories />
</Lib>
<ItemDefinitionGroup>
<ClCompile>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
+4 -4
View File
@@ -1125,7 +1125,7 @@ struct ARMv7_op2_table_t
{
if (opcode.code & ~opcode.mask)
{
LOG_ERROR(GENERAL, "%s: wrong opcode mask (mask=0x%04x, code=0x%04x)", opcode.name, opcode.mask >> 16, opcode.code >> 16);
LOG_ERROR(ARMv7, "%s: wrong opcode mask (mask=0x%04x, code=0x%04x)", opcode.name, opcode.mask >> 16, opcode.code >> 16);
}
t2.push_back(&opcode);
@@ -1164,7 +1164,7 @@ struct ARMv7_op4t_table_t
{
if (opcode.code & ~opcode.mask)
{
LOG_ERROR(GENERAL, "%s: wrong opcode mask (mask=0x%04x 0x%04x, code=0x%04x 0x%04x)", opcode.name, opcode.mask >> 16, (u16)opcode.mask, opcode.code >> 16, (u16)opcode.code);
LOG_ERROR(ARMv7, "%s: wrong opcode mask (mask=0x%04x 0x%04x, code=0x%04x 0x%04x)", opcode.name, opcode.mask >> 16, (u16)opcode.mask, opcode.code >> 16, (u16)opcode.code);
}
table.push_back(&opcode);
@@ -1199,7 +1199,7 @@ struct ARMv7_op4arm_table_t
{
if (opcode.code & ~opcode.mask)
{
LOG_ERROR(GENERAL, "%s: wrong opcode mask (mask=0x%08x, code=0x%08x)", opcode.name, opcode.mask, opcode.code);
LOG_ERROR(ARMv7, "%s: wrong opcode mask (mask=0x%08x, code=0x%08x)", opcode.name, opcode.mask, opcode.code);
}
table.push_back(&opcode);
@@ -1365,7 +1365,7 @@ u32 ARMv7Decoder::DecodeMemory(const u32 address)
// "group" decoding algorithm (temporarily disabled)
//execute_main_group(&m_thr);
//// LOG_NOTICE(GENERAL, "%s, %d \n\n", m_thr.m_last_instr_name, m_thr.m_last_instr_size);
//// LOG_NOTICE(ARMv7, "%s, %d \n\n", m_thr.m_last_instr_name, m_thr.m_last_instr_size);
//m_thr.m_last_instr_name = "Unknown";
//return m_thr.m_last_instr_size;
}
+1 -1
View File
@@ -2005,7 +2005,7 @@ static void execute_main_group(ARMv7Thread* thr)
case 0xe: (*g_table_0xe).func(thr, (*g_table_0xe).type); break;
case 0xf: (*g_table_0xf).func(thr, (*g_table_0xf).type); break;
default: LOG_ERROR(GENERAL, "ARMv7Decoder: unknown group 0x%x", (thr->code.code0 & 0xf000) >> 12); Emu.Pause(); break;
default: LOG_ERROR(ARMv7, "ARMv7Decoder: unknown group 0x%x", (thr->code.code0 & 0xf000) >> 12); Emu.Pause(); break;
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
#pragma once
using SceFiosOpCallback = s32(vm::ptr<void> pContext, s32 op, u8 event, s32 err);
using SceFiosVprintfCallback = s32(vm::cptr<char> fmt, va_list ap);
using SceFiosVprintfCallback = s32(vm::cptr<char> fmt, armv7_va_args_t ap /* va_list */);
using SceFiosMemcpyCallback = vm::ptr<void>(vm::ptr<void> dst, vm::cptr<void> src, u32 len);
enum SceFiosWhence : s32
+44 -44
View File
@@ -33,7 +33,7 @@ s32 sceKernelGetMemBlockInfoByAddr(vm::ptr<void> vbase, vm::ptr<SceKernelMemBloc
s32 sceKernelCreateThread(vm::cptr<char> pName, vm::ptr<SceKernelThreadEntry> entry, s32 initPriority, u32 stackSize, u32 attr, s32 cpuAffinityMask, vm::cptr<SceKernelThreadOptParam> pOptParam)
{
sceLibKernel.Warning("sceKernelCreateThread(pName=*0x%x, entry=*0x%x, initPriority=%d, stackSize=0x%x, attr=0x%x, cpuAffinityMask=0x%x, pOptParam=*0x%x)",
sceLibKernel.warning("sceKernelCreateThread(pName=*0x%x, entry=*0x%x, initPriority=%d, stackSize=0x%x, attr=0x%x, cpuAffinityMask=0x%x, pOptParam=*0x%x)",
pName, entry, initPriority, stackSize, attr, cpuAffinityMask, pOptParam);
auto armv7 = idm::make_ptr<ARMv7Thread>(pName.get_ptr());
@@ -48,7 +48,7 @@ s32 sceKernelCreateThread(vm::cptr<char> pName, vm::ptr<SceKernelThreadEntry> en
s32 sceKernelStartThread(s32 threadId, u32 argSize, vm::cptr<void> pArgBlock)
{
sceLibKernel.Warning("sceKernelStartThread(threadId=0x%x, argSize=0x%x, pArgBlock=*0x%x)", threadId, argSize, pArgBlock);
sceLibKernel.warning("sceKernelStartThread(threadId=0x%x, argSize=0x%x, pArgBlock=*0x%x)", threadId, argSize, pArgBlock);
const auto thread = idm::get<ARMv7Thread>(threadId);
@@ -78,7 +78,7 @@ s32 sceKernelStartThread(s32 threadId, u32 argSize, vm::cptr<void> pArgBlock)
s32 sceKernelExitThread(ARMv7Thread& context, s32 exitStatus)
{
sceLibKernel.Warning("sceKernelExitThread(exitStatus=0x%x)", exitStatus);
sceLibKernel.warning("sceKernelExitThread(exitStatus=0x%x)", exitStatus);
// exit status is stored in r0
context.exit();
@@ -88,7 +88,7 @@ s32 sceKernelExitThread(ARMv7Thread& context, s32 exitStatus)
s32 sceKernelDeleteThread(s32 threadId)
{
sceLibKernel.Warning("sceKernelDeleteThread(threadId=0x%x)", threadId);
sceLibKernel.warning("sceKernelDeleteThread(threadId=0x%x)", threadId);
const auto thread = idm::get<ARMv7Thread>(threadId);
@@ -110,7 +110,7 @@ s32 sceKernelDeleteThread(s32 threadId)
s32 sceKernelExitDeleteThread(ARMv7Thread& context, s32 exitStatus)
{
sceLibKernel.Warning("sceKernelExitDeleteThread(exitStatus=0x%x)", exitStatus);
sceLibKernel.warning("sceKernelExitDeleteThread(exitStatus=0x%x)", exitStatus);
// exit status is stored in r0
context.stop();
@@ -123,91 +123,91 @@ s32 sceKernelExitDeleteThread(ARMv7Thread& context, s32 exitStatus)
s32 sceKernelChangeThreadCpuAffinityMask(s32 threadId, s32 cpuAffinityMask)
{
sceLibKernel.Todo("sceKernelChangeThreadCpuAffinityMask(threadId=0x%x, cpuAffinityMask=0x%x)", threadId, cpuAffinityMask);
sceLibKernel.todo("sceKernelChangeThreadCpuAffinityMask(threadId=0x%x, cpuAffinityMask=0x%x)", threadId, cpuAffinityMask);
throw EXCEPTION("");
}
s32 sceKernelGetThreadCpuAffinityMask(s32 threadId)
{
sceLibKernel.Todo("sceKernelGetThreadCpuAffinityMask(threadId=0x%x)", threadId);
sceLibKernel.todo("sceKernelGetThreadCpuAffinityMask(threadId=0x%x)", threadId);
throw EXCEPTION("");
}
s32 sceKernelChangeThreadPriority(s32 threadId, s32 priority)
{
sceLibKernel.Todo("sceKernelChangeThreadPriority(threadId=0x%x, priority=%d)", threadId, priority);
sceLibKernel.todo("sceKernelChangeThreadPriority(threadId=0x%x, priority=%d)", threadId, priority);
throw EXCEPTION("");
}
s32 sceKernelGetThreadCurrentPriority()
{
sceLibKernel.Todo("sceKernelGetThreadCurrentPriority()");
sceLibKernel.todo("sceKernelGetThreadCurrentPriority()");
throw EXCEPTION("");
}
u32 sceKernelGetThreadId(ARMv7Thread& context)
{
sceLibKernel.Log("sceKernelGetThreadId()");
sceLibKernel.trace("sceKernelGetThreadId()");
return context.get_id();
}
s32 sceKernelChangeCurrentThreadAttr(u32 clearAttr, u32 setAttr)
{
sceLibKernel.Todo("sceKernelChangeCurrentThreadAttr()");
sceLibKernel.todo("sceKernelChangeCurrentThreadAttr()");
throw EXCEPTION("");
}
s32 sceKernelGetThreadExitStatus(s32 threadId, vm::ptr<s32> pExitStatus)
{
sceLibKernel.Todo("sceKernelGetThreadExitStatus(threadId=0x%x, pExitStatus=*0x%x)", threadId, pExitStatus);
sceLibKernel.todo("sceKernelGetThreadExitStatus(threadId=0x%x, pExitStatus=*0x%x)", threadId, pExitStatus);
throw EXCEPTION("");
}
s32 sceKernelGetProcessId()
{
sceLibKernel.Todo("sceKernelGetProcessId()");
sceLibKernel.todo("sceKernelGetProcessId()");
throw EXCEPTION("");
}
s32 sceKernelCheckWaitableStatus()
{
sceLibKernel.Todo("sceKernelCheckWaitableStatus()");
sceLibKernel.todo("sceKernelCheckWaitableStatus()");
throw EXCEPTION("");
}
s32 sceKernelGetThreadInfo(s32 threadId, vm::ptr<SceKernelThreadInfo> pInfo)
{
sceLibKernel.Todo("sceKernelGetThreadInfo(threadId=0x%x, pInfo=*0x%x)", threadId, pInfo);
sceLibKernel.todo("sceKernelGetThreadInfo(threadId=0x%x, pInfo=*0x%x)", threadId, pInfo);
throw EXCEPTION("");
}
s32 sceKernelGetThreadRunStatus(vm::ptr<SceKernelThreadRunStatus> pStatus)
{
sceLibKernel.Todo("sceKernelGetThreadRunStatus(pStatus=*0x%x)", pStatus);
sceLibKernel.todo("sceKernelGetThreadRunStatus(pStatus=*0x%x)", pStatus);
throw EXCEPTION("");
}
s32 sceKernelGetSystemInfo(vm::ptr<SceKernelSystemInfo> pInfo)
{
sceLibKernel.Todo("sceKernelGetSystemInfo(pInfo=*0x%x)", pInfo);
sceLibKernel.todo("sceKernelGetSystemInfo(pInfo=*0x%x)", pInfo);
throw EXCEPTION("");
}
s32 sceKernelGetThreadmgrUIDClass(s32 uid)
{
sceLibKernel.Error("sceKernelGetThreadmgrUIDClass(uid=0x%x)", uid);
sceLibKernel.error("sceKernelGetThreadmgrUIDClass(uid=0x%x)", uid);
const auto type = idm::get_type(uid);
@@ -227,35 +227,35 @@ s32 sceKernelGetThreadmgrUIDClass(s32 uid)
s32 sceKernelChangeThreadVfpException(s32 clearMask, s32 setMask)
{
sceLibKernel.Todo("sceKernelChangeThreadVfpException(clearMask=0x%x, setMask=0x%x)", clearMask, setMask);
sceLibKernel.todo("sceKernelChangeThreadVfpException(clearMask=0x%x, setMask=0x%x)", clearMask, setMask);
throw EXCEPTION("");
}
s32 sceKernelGetCurrentThreadVfpException()
{
sceLibKernel.Todo("sceKernelGetCurrentThreadVfpException()");
sceLibKernel.todo("sceKernelGetCurrentThreadVfpException()");
throw EXCEPTION("");
}
s32 sceKernelDelayThread(u32 usec)
{
sceLibKernel.Todo("sceKernelDelayThread()");
sceLibKernel.todo("sceKernelDelayThread()");
throw EXCEPTION("");
}
s32 sceKernelDelayThreadCB(u32 usec)
{
sceLibKernel.Todo("sceKernelDelayThreadCB()");
sceLibKernel.todo("sceKernelDelayThreadCB()");
throw EXCEPTION("");
}
s32 sceKernelWaitThreadEnd(s32 threadId, vm::ptr<s32> pExitStatus, vm::ptr<u32> pTimeout)
{
sceLibKernel.Warning("sceKernelWaitThreadEnd(threadId=0x%x, pExitStatus=*0x%x, pTimeout=*0x%x)", threadId, pExitStatus, pTimeout);
sceLibKernel.warning("sceKernelWaitThreadEnd(threadId=0x%x, pExitStatus=*0x%x, pTimeout=*0x%x)", threadId, pExitStatus, pTimeout);
const auto thread = idm::get<ARMv7Thread>(threadId);
@@ -285,7 +285,7 @@ s32 sceKernelWaitThreadEnd(s32 threadId, vm::ptr<s32> pExitStatus, vm::ptr<u32>
s32 sceKernelWaitThreadEndCB(s32 threadId, vm::ptr<s32> pExitStatus, vm::ptr<u32> pTimeout)
{
sceLibKernel.Todo("sceKernelWaitThreadEndCB(threadId=0x%x, pExitStatus=*0x%x, pTimeout=*0x%x)", threadId, pExitStatus, pTimeout);
sceLibKernel.todo("sceKernelWaitThreadEndCB(threadId=0x%x, pExitStatus=*0x%x, pTimeout=*0x%x)", threadId, pExitStatus, pTimeout);
throw EXCEPTION("");
}
@@ -383,14 +383,14 @@ s32 sceKernelWaitMultipleEventsCB(vm::ptr<SceKernelWaitEvent> pWaitEventList, s3
s32 sceKernelCreateEventFlag(vm::cptr<char> pName, u32 attr, u32 initPattern, vm::cptr<SceKernelEventFlagOptParam> pOptParam)
{
sceLibKernel.Error("sceKernelCreateEventFlag(pName=*0x%x, attr=0x%x, initPattern=0x%x, pOptParam=*0x%x)", pName, attr, initPattern, pOptParam);
sceLibKernel.error("sceKernelCreateEventFlag(pName=*0x%x, attr=0x%x, initPattern=0x%x, pOptParam=*0x%x)", pName, attr, initPattern, pOptParam);
return idm::make<psv_event_flag_t>(pName.get_ptr(), attr, initPattern);
}
s32 sceKernelDeleteEventFlag(s32 evfId)
{
sceLibKernel.Error("sceKernelDeleteEventFlag(evfId=0x%x)", evfId);
sceLibKernel.error("sceKernelDeleteEventFlag(evfId=0x%x)", evfId);
const auto evf = idm::withdraw<psv_event_flag_t>(evfId);
@@ -410,7 +410,7 @@ s32 sceKernelDeleteEventFlag(s32 evfId)
s32 sceKernelOpenEventFlag(vm::cptr<char> pName)
{
sceLibKernel.Error("sceKernelOpenEventFlag(pName=*0x%x)", pName);
sceLibKernel.error("sceKernelOpenEventFlag(pName=*0x%x)", pName);
// For now, go through all objects to find the name
for (const auto& data : idm::get_map<psv_event_flag_t>())
@@ -428,7 +428,7 @@ s32 sceKernelOpenEventFlag(vm::cptr<char> pName)
s32 sceKernelCloseEventFlag(s32 evfId)
{
sceLibKernel.Error("sceKernelCloseEventFlag(evfId=0x%x)", evfId);
sceLibKernel.error("sceKernelCloseEventFlag(evfId=0x%x)", evfId);
const auto evf = idm::withdraw<psv_event_flag_t>(evfId);
@@ -448,7 +448,7 @@ s32 sceKernelCloseEventFlag(s32 evfId)
s32 sceKernelWaitEventFlag(ARMv7Thread& context, s32 evfId, u32 bitPattern, u32 waitMode, vm::ptr<u32> pResultPat, vm::ptr<u32> pTimeout)
{
sceLibKernel.Error("sceKernelWaitEventFlag(evfId=0x%x, bitPattern=0x%x, waitMode=0x%x, pResultPat=*0x%x, pTimeout=*0x%x)", evfId, bitPattern, waitMode, pResultPat, pTimeout);
sceLibKernel.error("sceKernelWaitEventFlag(evfId=0x%x, bitPattern=0x%x, waitMode=0x%x, pResultPat=*0x%x, pTimeout=*0x%x)", evfId, bitPattern, waitMode, pResultPat, pTimeout);
const u64 start_time = pTimeout ? get_system_time() : 0;
const u32 timeout = pTimeout ? pTimeout->value() : 0;
@@ -509,14 +509,14 @@ s32 sceKernelWaitEventFlag(ARMv7Thread& context, s32 evfId, u32 bitPattern, u32
s32 sceKernelWaitEventFlagCB(ARMv7Thread& context, s32 evfId, u32 bitPattern, u32 waitMode, vm::ptr<u32> pResultPat, vm::ptr<u32> pTimeout)
{
sceLibKernel.Todo("sceKernelWaitEventFlagCB(evfId=0x%x, bitPattern=0x%x, waitMode=0x%x, pResultPat=*0x%x, pTimeout=*0x%x)", evfId, bitPattern, waitMode, pResultPat, pTimeout);
sceLibKernel.todo("sceKernelWaitEventFlagCB(evfId=0x%x, bitPattern=0x%x, waitMode=0x%x, pResultPat=*0x%x, pTimeout=*0x%x)", evfId, bitPattern, waitMode, pResultPat, pTimeout);
return sceKernelWaitEventFlag(context, evfId, bitPattern, waitMode, pResultPat, pTimeout);
}
s32 sceKernelPollEventFlag(s32 evfId, u32 bitPattern, u32 waitMode, vm::ptr<u32> pResultPat)
{
sceLibKernel.Error("sceKernelPollEventFlag(evfId=0x%x, bitPattern=0x%x, waitMode=0x%x, pResultPat=*0x%x)", evfId, bitPattern, waitMode, pResultPat);
sceLibKernel.error("sceKernelPollEventFlag(evfId=0x%x, bitPattern=0x%x, waitMode=0x%x, pResultPat=*0x%x)", evfId, bitPattern, waitMode, pResultPat);
const auto evf = idm::get<psv_event_flag_t>(evfId);
@@ -541,7 +541,7 @@ s32 sceKernelPollEventFlag(s32 evfId, u32 bitPattern, u32 waitMode, vm::ptr<u32>
s32 sceKernelSetEventFlag(s32 evfId, u32 bitPattern)
{
sceLibKernel.Error("sceKernelSetEventFlag(evfId=0x%x, bitPattern=0x%x)", evfId, bitPattern);
sceLibKernel.error("sceKernelSetEventFlag(evfId=0x%x, bitPattern=0x%x)", evfId, bitPattern);
const auto evf = idm::get<psv_event_flag_t>(evfId);
@@ -586,7 +586,7 @@ s32 sceKernelSetEventFlag(s32 evfId, u32 bitPattern)
s32 sceKernelClearEventFlag(s32 evfId, u32 bitPattern)
{
sceLibKernel.Error("sceKernelClearEventFlag(evfId=0x%x, bitPattern=0x%x)", evfId, bitPattern);
sceLibKernel.error("sceKernelClearEventFlag(evfId=0x%x, bitPattern=0x%x)", evfId, bitPattern);
const auto evf = idm::get<psv_event_flag_t>(evfId);
@@ -604,7 +604,7 @@ s32 sceKernelClearEventFlag(s32 evfId, u32 bitPattern)
s32 sceKernelCancelEventFlag(s32 evfId, u32 setPattern, vm::ptr<s32> pNumWaitThreads)
{
sceLibKernel.Error("sceKernelCancelEventFlag(evfId=0x%x, setPattern=0x%x, pNumWaitThreads=*0x%x)", evfId, setPattern, pNumWaitThreads);
sceLibKernel.error("sceKernelCancelEventFlag(evfId=0x%x, setPattern=0x%x, pNumWaitThreads=*0x%x)", evfId, setPattern, pNumWaitThreads);
const auto evf = idm::get<psv_event_flag_t>(evfId);
@@ -632,7 +632,7 @@ s32 sceKernelCancelEventFlag(s32 evfId, u32 setPattern, vm::ptr<s32> pNumWaitThr
s32 sceKernelGetEventFlagInfo(s32 evfId, vm::ptr<SceKernelEventFlagInfo> pInfo)
{
sceLibKernel.Error("sceKernelGetEventFlagInfo(evfId=0x%x, pInfo=*0x%x)", evfId, pInfo);
sceLibKernel.error("sceKernelGetEventFlagInfo(evfId=0x%x, pInfo=*0x%x)", evfId, pInfo);
const auto evf = idm::get<psv_event_flag_t>(evfId);
@@ -643,7 +643,7 @@ s32 sceKernelGetEventFlagInfo(s32 evfId, vm::ptr<SceKernelEventFlagInfo> pInfo)
std::lock_guard<std::mutex> lock(evf->mutex);
pInfo->size = sizeof32(SceKernelEventFlagInfo);
pInfo->size = SIZE_32(SceKernelEventFlagInfo);
pInfo->evfId = evfId;
strcpy_trunc(pInfo->name, evf->name);
@@ -660,14 +660,14 @@ s32 sceKernelGetEventFlagInfo(s32 evfId, vm::ptr<SceKernelEventFlagInfo> pInfo)
s32 sceKernelCreateSema(vm::cptr<char> pName, u32 attr, s32 initCount, s32 maxCount, vm::cptr<SceKernelSemaOptParam> pOptParam)
{
sceLibKernel.Error("sceKernelCreateSema(pName=*0x%x, attr=0x%x, initCount=%d, maxCount=%d, pOptParam=*0x%x)", pName, attr, initCount, maxCount, pOptParam);
sceLibKernel.error("sceKernelCreateSema(pName=*0x%x, attr=0x%x, initCount=%d, maxCount=%d, pOptParam=*0x%x)", pName, attr, initCount, maxCount, pOptParam);
return idm::make<psv_semaphore_t>(pName.get_ptr(), attr, initCount, maxCount);
}
s32 sceKernelDeleteSema(s32 semaId)
{
sceLibKernel.Error("sceKernelDeleteSema(semaId=0x%x)", semaId);
sceLibKernel.error("sceKernelDeleteSema(semaId=0x%x)", semaId);
const auto sema = idm::withdraw<psv_semaphore_t>(semaId);
@@ -693,7 +693,7 @@ s32 sceKernelCloseSema(s32 semaId)
s32 sceKernelWaitSema(s32 semaId, s32 needCount, vm::ptr<u32> pTimeout)
{
sceLibKernel.Error("sceKernelWaitSema(semaId=0x%x, needCount=%d, pTimeout=*0x%x)", semaId, needCount, pTimeout);
sceLibKernel.error("sceKernelWaitSema(semaId=0x%x, needCount=%d, pTimeout=*0x%x)", semaId, needCount, pTimeout);
const auto sema = idm::get<psv_semaphore_t>(semaId);
@@ -702,7 +702,7 @@ s32 sceKernelWaitSema(s32 semaId, s32 needCount, vm::ptr<u32> pTimeout)
return SCE_KERNEL_ERROR_INVALID_UID;
}
sceLibKernel.Error("*** name = %s", sema->name);
sceLibKernel.error("*** name = %s", sema->name);
Emu.Pause();
return SCE_OK;
}
@@ -736,14 +736,14 @@ s32 sceKernelGetSemaInfo(s32 semaId, vm::ptr<SceKernelSemaInfo> pInfo)
s32 sceKernelCreateMutex(vm::cptr<char> pName, u32 attr, s32 initCount, vm::cptr<SceKernelMutexOptParam> pOptParam)
{
sceLibKernel.Error("sceKernelCreateMutex(pName=*0x%x, attr=0x%x, initCount=%d, pOptParam=*0x%x)", pName, attr, initCount, pOptParam);
sceLibKernel.error("sceKernelCreateMutex(pName=*0x%x, attr=0x%x, initCount=%d, pOptParam=*0x%x)", pName, attr, initCount, pOptParam);
return idm::make<psv_mutex_t>(pName.get_ptr(), attr, initCount);
}
s32 sceKernelDeleteMutex(s32 mutexId)
{
sceLibKernel.Error("sceKernelDeleteMutex(mutexId=0x%x)", mutexId);
sceLibKernel.error("sceKernelDeleteMutex(mutexId=0x%x)", mutexId);
const auto mutex = idm::withdraw<psv_mutex_t>(mutexId);
@@ -843,7 +843,7 @@ s32 sceKernelGetLwMutexInfoById(s32 lwMutexId, vm::ptr<SceKernelLwMutexInfo> pIn
s32 sceKernelCreateCond(vm::cptr<char> pName, u32 attr, s32 mutexId, vm::cptr<SceKernelCondOptParam> pOptParam)
{
sceLibKernel.Error("sceKernelCreateCond(pName=*0x%x, attr=0x%x, mutexId=0x%x, pOptParam=*0x%x)", pName, attr, mutexId, pOptParam);
sceLibKernel.error("sceKernelCreateCond(pName=*0x%x, attr=0x%x, mutexId=0x%x, pOptParam=*0x%x)", pName, attr, mutexId, pOptParam);
const auto mutex = idm::get<psv_mutex_t>(mutexId);
@@ -857,7 +857,7 @@ s32 sceKernelCreateCond(vm::cptr<char> pName, u32 attr, s32 mutexId, vm::cptr<Sc
s32 sceKernelDeleteCond(s32 condId)
{
sceLibKernel.Error("sceKernelDeleteCond(condId=0x%x)", condId);
sceLibKernel.error("sceKernelDeleteCond(condId=0x%x)", condId);
const auto cond = idm::withdraw<psv_cond_t>(condId);
+16 -16
View File
@@ -150,7 +150,7 @@ namespace sce_libc_func
{
void __cxa_atexit(vm::ptr<atexit_func_t> func, vm::ptr<void> arg, vm::ptr<void> dso)
{
sceLibc.Warning("__cxa_atexit(func=*0x%x, arg=*0x%x, dso=*0x%x)", func, arg, dso);
sceLibc.warning("__cxa_atexit(func=*0x%x, arg=*0x%x, dso=*0x%x)", func, arg, dso);
std::lock_guard<std::mutex> lock(g_atexit_mutex);
@@ -162,7 +162,7 @@ namespace sce_libc_func
void __aeabi_atexit(vm::ptr<void> arg, vm::ptr<atexit_func_t> func, vm::ptr<void> dso)
{
sceLibc.Warning("__aeabi_atexit(arg=*0x%x, func=*0x%x, dso=*0x%x)", arg, func, dso);
sceLibc.warning("__aeabi_atexit(arg=*0x%x, func=*0x%x, dso=*0x%x)", arg, func, dso);
std::lock_guard<std::mutex> lock(g_atexit_mutex);
@@ -174,7 +174,7 @@ namespace sce_libc_func
void exit(ARMv7Thread& context)
{
sceLibc.Warning("exit()");
sceLibc.warning("exit()");
std::lock_guard<std::mutex> lock(g_atexit_mutex);
@@ -185,7 +185,7 @@ namespace sce_libc_func
func(context);
}
sceLibc.Success("Process finished");
sceLibc.success("Process finished");
Emu.CallAfter([]()
{
@@ -202,52 +202,52 @@ namespace sce_libc_func
void printf(ARMv7Thread& context, vm::cptr<char> fmt, armv7_va_args_t va_args)
{
sceLibc.Warning("printf(fmt=*0x%x)", fmt);
sceLibc.Log("*** *fmt = '%s'", fmt.get_ptr());
sceLibc.warning("printf(fmt=*0x%x)", fmt);
sceLibc.trace("*** *fmt = '%s'", fmt.get_ptr());
const std::string& result = armv7_fmt(context, fmt, va_args.g_count, va_args.f_count, va_args.v_count);
sceLibc.Log("*** -> '%s'", result);
sceLibc.trace("*** -> '%s'", result);
LOG_NOTICE(TTY, result);
_log::g_tty_file.log(result);
}
void sprintf(ARMv7Thread& context, vm::ptr<char> str, vm::cptr<char> fmt, armv7_va_args_t va_args)
{
sceLibc.Warning("sprintf(str=*0x%x, fmt=*0x%x)", str, fmt);
sceLibc.Log("*** *fmt = '%s'", fmt.get_ptr());
sceLibc.warning("sprintf(str=*0x%x, fmt=*0x%x)", str, fmt);
sceLibc.trace("*** *fmt = '%s'", fmt.get_ptr());
const std::string& result = armv7_fmt(context, fmt, va_args.g_count, va_args.f_count, va_args.v_count);
sceLibc.Log("*** -> '%s'", result);
sceLibc.trace("*** -> '%s'", result);
::memcpy(str.get_ptr(), result.c_str(), result.size() + 1);
}
void __cxa_set_dso_handle_main(vm::ptr<void> dso)
{
sceLibc.Warning("__cxa_set_dso_handle_main(dso=*0x%x)", dso);
sceLibc.warning("__cxa_set_dso_handle_main(dso=*0x%x)", dso);
g_dso = dso;
}
void memcpy(vm::ptr<void> dst, vm::cptr<void> src, u32 size)
{
sceLibc.Warning("memcpy(dst=*0x%x, src=*0x%x, size=0x%x)", dst, src, size);
sceLibc.warning("memcpy(dst=*0x%x, src=*0x%x, size=0x%x)", dst, src, size);
::memcpy(dst.get_ptr(), src.get_ptr(), size);
}
void memset(vm::ptr<void> dst, s32 value, u32 size)
{
sceLibc.Warning("memset(dst=*0x%x, value=%d, size=0x%x)", dst, value, size);
sceLibc.warning("memset(dst=*0x%x, value=%d, size=0x%x)", dst, value, size);
::memset(dst.get_ptr(), value, size);
}
void _Assert(vm::cptr<char> text, vm::cptr<char> func)
{
sceLibc.Error("_Assert(text=*0x%x, func=*0x%x)", text, func);
sceLibc.error("_Assert(text=*0x%x, func=*0x%x)", text, func);
LOG_ERROR(TTY, "%s : %s\n", func.get_ptr(), text.get_ptr());
LOG_FATAL(HLE, "%s : %s\n", func.get_ptr(), text.get_ptr());
Emu.Pause();
}
}
+9 -9
View File
@@ -8,7 +8,7 @@ extern u64 get_system_time();
s32 scePerfArmPmonReset(ARMv7Thread& context, s32 threadId)
{
scePerf.Warning("scePerfArmPmonReset(threadId=0x%x)", threadId);
scePerf.warning("scePerfArmPmonReset(threadId=0x%x)", threadId);
if (threadId != SCE_PERF_ARM_PMON_THREAD_ID_SELF)
{
@@ -22,7 +22,7 @@ s32 scePerfArmPmonReset(ARMv7Thread& context, s32 threadId)
s32 scePerfArmPmonSelectEvent(ARMv7Thread& context, s32 threadId, u32 counter, u8 eventCode)
{
scePerf.Warning("scePerfArmPmonSelectEvent(threadId=0x%x, counter=0x%x, eventCode=0x%x)", threadId, counter, eventCode);
scePerf.warning("scePerfArmPmonSelectEvent(threadId=0x%x, counter=0x%x, eventCode=0x%x)", threadId, counter, eventCode);
if (threadId != SCE_PERF_ARM_PMON_THREAD_ID_SELF)
{
@@ -74,7 +74,7 @@ s32 scePerfArmPmonSelectEvent(ARMv7Thread& context, s32 threadId, u32 counter, u
s32 scePerfArmPmonStart(ARMv7Thread& context, s32 threadId)
{
scePerf.Warning("scePerfArmPmonStart(threadId=0x%x)", threadId);
scePerf.warning("scePerfArmPmonStart(threadId=0x%x)", threadId);
if (threadId != SCE_PERF_ARM_PMON_THREAD_ID_SELF)
{
@@ -86,7 +86,7 @@ s32 scePerfArmPmonStart(ARMv7Thread& context, s32 threadId)
s32 scePerfArmPmonStop(ARMv7Thread& context, s32 threadId)
{
scePerf.Warning("scePerfArmPmonStop(threadId=0x%x)");
scePerf.warning("scePerfArmPmonStop(threadId=0x%x)");
if (threadId != SCE_PERF_ARM_PMON_THREAD_ID_SELF)
{
@@ -98,7 +98,7 @@ s32 scePerfArmPmonStop(ARMv7Thread& context, s32 threadId)
s32 scePerfArmPmonGetCounterValue(ARMv7Thread& context, s32 threadId, u32 counter, vm::ptr<u32> pValue)
{
scePerf.Warning("scePerfArmPmonGetCounterValue(threadId=0x%x, counter=%d, pValue=*0x%x)", threadId, counter, pValue);
scePerf.warning("scePerfArmPmonGetCounterValue(threadId=0x%x, counter=%d, pValue=*0x%x)", threadId, counter, pValue);
if (threadId != SCE_PERF_ARM_PMON_THREAD_ID_SELF)
{
@@ -124,7 +124,7 @@ s32 scePerfArmPmonGetCounterValue(ARMv7Thread& context, s32 threadId, u32 counte
s32 scePerfArmPmonSoftwareIncrement(ARMv7Thread& context, u32 mask)
{
scePerf.Warning("scePerfArmPmonSoftwareIncrement(mask=0x%x)", mask);
scePerf.warning("scePerfArmPmonSoftwareIncrement(mask=0x%x)", mask);
if (mask > SCE_PERF_ARM_PMON_COUNTER_MASK_ALL)
{
@@ -144,14 +144,14 @@ s32 scePerfArmPmonSoftwareIncrement(ARMv7Thread& context, u32 mask)
u64 scePerfGetTimebaseValue()
{
scePerf.Warning("scePerfGetTimebaseValue()");
scePerf.warning("scePerfGetTimebaseValue()");
return get_system_time();
}
u32 scePerfGetTimebaseFrequency()
{
scePerf.Warning("scePerfGetTimebaseFrequency()");
scePerf.warning("scePerfGetTimebaseFrequency()");
return 1;
}
@@ -198,4 +198,4 @@ psv_log_base scePerf("ScePerf", []()
REG_FUNC(0xC3DE4C0A, sceRazorCpuPushMarker);
REG_FUNC(0xDC3224C3, sceRazorCpuPopMarker);
REG_FUNC(0x4F1385E3, sceRazorCpuSync);
});
});
+3 -3
View File
@@ -6,21 +6,21 @@
s32 sceSysmoduleLoadModule(u16 id)
{
sceSysmodule.Warning("sceSysmoduleLoadModule(id=0x%04x) -> SCE_OK", id);
sceSysmodule.warning("sceSysmoduleLoadModule(id=0x%04x) -> SCE_OK", id);
return SCE_OK; // loading succeeded
}
s32 sceSysmoduleUnloadModule(u16 id)
{
sceSysmodule.Warning("sceSysmoduleUnloadModule(id=0x%04x) -> SCE_OK", id);
sceSysmodule.warning("sceSysmoduleUnloadModule(id=0x%04x) -> SCE_OK", id);
return SCE_OK; // unloading succeeded
}
s32 sceSysmoduleIsLoaded(u16 id)
{
sceSysmodule.Warning("sceSysmoduleIsLoaded(id=0x%04x) -> SCE_OK", id);
sceSysmodule.warning("sceSysmoduleIsLoaded(id=0x%04x) -> SCE_OK", id);
return SCE_OK; // module is loaded
}
+2 -2
View File
@@ -4,14 +4,14 @@
#include "PSVFuncList.h"
psv_log_base::psv_log_base(const std::string& name, init_func_t init)
: m_name(name)
: _log::channel(name)
, m_init(init)
{
on_error = [this](s32 code, psv_func* func)
{
if (code < 0)
{
Error("%s() failed: 0x%08X", func->name, code);
error("%s() failed: 0x%08X", func->name, code);
Emu.Pause();
}
};
+2 -10
View File
@@ -2,16 +2,14 @@
#include "Emu/Memory/Memory.h"
#include "ARMv7Thread.h"
#include "Emu/SysCalls/LogBase.h"
namespace vm { using namespace psv; }
// PSV module class
class psv_log_base : public LogBase
class psv_log_base : public _log::channel
{
using init_func_t = void(*)();
std::string m_name;
init_func_t m_init;
public:
@@ -32,12 +30,6 @@ public:
m_init();
}
virtual const std::string& GetName() const override
{
return m_name;
}
};
using armv7_func_caller = void(*)(ARMv7Thread&);
@@ -321,7 +313,7 @@ namespace psv_func_detail
static const bool is_variadic = std::is_same<std::remove_cv_t<T>, armv7_va_args_t>::value;
static const bool is_general = !is_float && !is_vector && !is_context && !is_variadic;
static const u32 g_align = alignof32(T) > 4 ? alignof32(T) >> 2 : 1;
static const u32 g_align = ALIGN_32(T) > 4 ? ALIGN_32(T) >> 2 : 1;
static const u32 g_value = is_general ? ((g_count + (g_align - 1)) & ~(g_align - 1)) + (g_align) : g_count;
static const u32 f_value = f_count + is_float;
static const u32 v_value = v_count + is_vector;
+1 -15
View File
@@ -1,24 +1,10 @@
#include "stdafx.h"
#include "Emu/System.h"
#include "AudioManager.h"
#include "Emu/state.h"
AudioManager::AudioManager() : m_audio_out(nullptr)
{
}
AudioManager::~AudioManager()
{
Close();
}
void AudioManager::Init()
{
if (m_audio_out) return;
m_audio_info.Init();
m_audio_out = Emu.GetCallbacks().get_audio();
if (!m_audio_out) m_audio_out = Emu.GetCallbacks().get_audio();
}
void AudioManager::Close()
+2 -18
View File
@@ -2,29 +2,13 @@
#include "AudioThread.h"
// it cannot be configured currently, and it must NOT use cellSysutil definitions
struct AudioInfo
{
AudioInfo()
{
}
void Init()
{
}
};
class AudioManager
{
AudioInfo m_audio_info;
std::shared_ptr<AudioThread> m_audio_out;
public:
AudioManager();
~AudioManager();
public:
void Init();
void Close();
AudioThread& GetAudioOut() { assert(m_audio_out); return *m_audio_out; }
AudioInfo& GetInfo() { return m_audio_info; }
AudioThread& GetAudioOut() { return *m_audio_out; }
};
+12 -3
View File
@@ -1,11 +1,20 @@
#pragma once
#ifdef _MSC_VER
#include "minidx12/Include/sdkddkver.h" // Use last SDKDDKVer in SDK 10.586 for Win10
#include "Emu/Audio/AudioThread.h"
#define _WIN32_WINNT 0x0601 // This is to be sure that correct (2.7) header is included
#include "minidx9/Include/XAudio2.h" // XAudio2 2.8 available only on Win8+, used XAudio2 2.7 from dxsdk
#undef _WIN32_WINNT
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) // XAudio2 2.8 and 2.9 available only on Win8+ and Win10.
#include "minidx12/Include/xaudio2.h"
#else
#include "minidx9/Include/XAudio2.h" // XAudio 2.7 for Windows 7 Only
#endif
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN10)
#pragma comment(lib,"../minidx12/Lib/xaudio2.lib") // Lib 2.9 for Only Windows 10
#elif (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
#pragma comment(lib,"../minidx12/Lib/xaudio2_8.lib") // Lib 2.8 for Only Windows 8+
#endif
class XAudio2Thread : public AudioThread
{
+1 -1
View File
@@ -89,7 +89,7 @@ void CPUThread::dump_info() const
{
if (!Emu.IsStopped())
{
LOG_NOTICE(GENERAL, RegsToString());
LOG_NOTICE(GENERAL, "%s", RegsToString());
}
}
+9 -7
View File
@@ -73,12 +73,14 @@ void ppu_interpreter::TWI(PPUThread& CPU, ppu_opcode_t op)
void ppu_interpreter::MFVSCR(PPUThread& CPU, ppu_opcode_t op)
{
throw EXCEPTION("");
CPU.VPR[op.vd]._u32[0] = CPU.VSCR.VSCR;
CPU.VPR[op.vd].clear();
}
void ppu_interpreter::MTVSCR(PPUThread& CPU, ppu_opcode_t op)
{
// ignored (MFVSCR disabled)
CPU.VSCR.VSCR = CPU.VPR[op.vb]._u32[0];
CPU.VSCR.X = CPU.VSCR.Y = 0;
}
void ppu_interpreter::VADDCUW(PPUThread& CPU, ppu_opcode_t op)
@@ -1696,7 +1698,7 @@ void ppu_interpreter::TW(PPUThread& CPU, ppu_opcode_t op)
((u32)a < (u32)b && (op.bo & 0x2)) ||
((u32)a >(u32)b && (op.bo & 0x1)))
{
throw EXCEPTION("");
//throw EXCEPTION("");
}
}
@@ -1778,7 +1780,7 @@ void ppu_interpreter::LWARX(PPUThread& CPU, ppu_opcode_t op)
const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb];
be_t<u32> value;
vm::reservation_acquire(&value, VM_CAST(addr), sizeof32(value));
vm::reservation_acquire(&value, VM_CAST(addr), SIZE_32(value));
CPU.GPR[op.rd] = value;
}
@@ -1949,7 +1951,7 @@ void ppu_interpreter::LDARX(PPUThread& CPU, ppu_opcode_t op)
const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb];
be_t<u64> value;
vm::reservation_acquire(&value, VM_CAST(addr), sizeof32(value));
vm::reservation_acquire(&value, VM_CAST(addr), SIZE_32(value));
CPU.GPR[op.rd] = value;
}
@@ -2079,7 +2081,7 @@ void ppu_interpreter::STWCX_(PPUThread& CPU, ppu_opcode_t op)
const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb];
const be_t<u32> value = (u32)CPU.GPR[op.rs];
CPU.SetCR_EQ(0, vm::reservation_update(VM_CAST(addr), &value, sizeof32(value)));
CPU.SetCR_EQ(0, vm::reservation_update(VM_CAST(addr), &value, SIZE_32(value)));
}
void ppu_interpreter::STWX(PPUThread& CPU, ppu_opcode_t op)
@@ -2139,7 +2141,7 @@ void ppu_interpreter::STDCX_(PPUThread& CPU, ppu_opcode_t op)
const u64 addr = op.ra ? CPU.GPR[op.ra] + CPU.GPR[op.rb] : CPU.GPR[op.rb];
const be_t<u64> value = CPU.GPR[op.rs];
CPU.SetCR_EQ(0, vm::reservation_update(VM_CAST(addr), &value, sizeof32(value)));
CPU.SetCR_EQ(0, vm::reservation_update(VM_CAST(addr), &value, SIZE_32(value)));
}
void ppu_interpreter::STBX(PPUThread& CPU, ppu_opcode_t op)
File diff suppressed because it is too large Load Diff
+7 -8
View File
@@ -13,7 +13,6 @@
#include "llvm/Support/Host.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Analysis/Passes.h"
@@ -64,10 +63,10 @@ std::unique_ptr<Module> Compiler::create_module(LLVMContext &llvm_context)
void Compiler::optimise_module(llvm::Module *module)
{
llvm::FunctionPassManager fpm(module);
llvm::legacy::FunctionPassManager fpm(module);
fpm.add(createNoAAPass());
fpm.add(createBasicAliasAnalysisPass());
fpm.add(createNoTargetTransformInfoPass());
fpm.add(createTargetTransformInfoWrapperPass(TargetIRAnalysis()));
fpm.add(createEarlyCSEPass());
fpm.add(createTailCallEliminationPass());
fpm.add(createReassociatePass());
@@ -78,7 +77,7 @@ void Compiler::optimise_module(llvm::Module *module)
fpm.add(createInstructionCombiningPass());
fpm.add(new MemoryDependenceAnalysis());
fpm.add(createDeadStoreEliminationPass());
fpm.add(new LoopInfo());
fpm.add(new LoopInfoWrapperPass());
fpm.add(new ScalarEvolution());
fpm.add(createSLPVectorizerPass());
fpm.add(createInstructionCombiningPass());
@@ -188,7 +187,7 @@ void ppu_recompiler_llvm::Compiler::translate_to_llvm_ir(llvm::Module *module, c
std::string verify;
raw_string_ostream verify_ostream(verify);
if (verifyFunction(*m_state.function, &verify_ostream)) {
// m_recompilation_engine.Log() << "Verification failed: " << verify_ostream.str() << "\n";
// m_recompilation_engine.trace() << "Verification failed: " << verify_ostream.str() << "\n";
}
m_module = nullptr;
@@ -413,7 +412,7 @@ std::pair<Executable, llvm::ExecutionEngine *> RecompilationEngine::compile(cons
.setOptLevel(llvm::CodeGenOpt::Aggressive)
.setMCPU("nehalem")
.create();
module_ptr->setDataLayout(execution_engine->getDataLayout());
module_ptr->setDataLayout(*execution_engine->getDataLayout());
// Translate to machine code
execution_engine->finalizeObject();
@@ -421,13 +420,13 @@ std::pair<Executable, llvm::ExecutionEngine *> RecompilationEngine::compile(cons
Function *llvm_function = module_ptr->getFunction(name);
void *function = execution_engine->getPointerToFunction(llvm_function);
/* m_recompilation_engine.Log() << "\nDisassembly:\n";
/* m_recompilation_engine.trace() << "\nDisassembly:\n";
auto disassembler = LLVMCreateDisasm(sys::getProcessTriple().c_str(), nullptr, 0, nullptr, nullptr);
for (size_t pc = 0; pc < mci.size();) {
char str[1024];
auto size = LLVMDisasmInstruction(disassembler, ((u8 *)mci.address()) + pc, mci.size() - pc, (uint64_t)(((u8 *)mci.address()) + pc), str, sizeof(str));
m_recompilation_engine.Log() << fmt::format("0x%08X: ", (u64)(((u8 *)mci.address()) + pc)) << str << '\n';
m_recompilation_engine.trace() << fmt::format("0x%08X: ", (u64)(((u8 *)mci.address()) + pc)) << str << '\n';
pc += size;
}
+6 -6
View File
@@ -11,14 +11,14 @@
#ifdef _MSC_VER
#pragma warning(push, 0)
#endif
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/PassManager.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/raw_ostream.h"
#ifdef _MSC_VER
#pragma warning(pop)
#endif
+107 -107
View File
@@ -144,7 +144,7 @@ void Compiler::VADDFP(u32 vd, u32 va, u32 vb) {
void Compiler::VADDSBS(u32 vd, u32 va, u32 vb) {
auto va_v16i8 = GetVrAsIntVec(va, 8);
auto vb_v16i8 = GetVrAsIntVec(vb, 8);
auto sum_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_padds_b), va_v16i8, vb_v16i8);
auto sum_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_padds_b), { va_v16i8, vb_v16i8 });
SetVr(vd, sum_v16i8);
// TODO: Set VSCR.SAT
@@ -153,7 +153,7 @@ void Compiler::VADDSBS(u32 vd, u32 va, u32 vb) {
void Compiler::VADDSHS(u32 vd, u32 va, u32 vb) {
auto va_v8i16 = GetVrAsIntVec(va, 16);
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
auto sum_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_padds_w), va_v8i16, vb_v8i16);
auto sum_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_padds_w), { va_v8i16, vb_v8i16 });
SetVr(vd, sum_v8i16);
// TODO: Set VSCR.SAT
@@ -194,7 +194,7 @@ void Compiler::VADDSWS(u32 vd, u32 va, u32 vb) {
auto tmp3_v16i8 = m_ir_builder->CreateBitCast(tmp3_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16));
// tmp4 is equal to 0xFFFFFFFF if an overflow occured and 0x00000000 otherwise.
auto res_v16i8 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pblendvb), sum_v16i8, tmp1_v16i8, tmp3_v16i8);
auto res_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pblendvb), { sum_v16i8, tmp1_v16i8, tmp3_v16i8 });
SetVr(vd, res_v16i8);
// TODO: Set SAT
@@ -210,7 +210,7 @@ void Compiler::VADDUBM(u32 vd, u32 va, u32 vb) {
void Compiler::VADDUBS(u32 vd, u32 va, u32 vb) {
auto va_v16i8 = GetVrAsIntVec(va, 8);
auto vb_v16i8 = GetVrAsIntVec(vb, 8);
auto sum_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_paddus_b), va_v16i8, vb_v16i8);
auto sum_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_paddus_b), { va_v16i8, vb_v16i8 });
SetVr(vd, sum_v16i8);
// TODO: Set SAT
@@ -226,7 +226,7 @@ void Compiler::VADDUHM(u32 vd, u32 va, u32 vb) {
void Compiler::VADDUHS(u32 vd, u32 va, u32 vb) {
auto va_v8i16 = GetVrAsIntVec(va, 16);
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
auto sum_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_paddus_w), va_v8i16, vb_v8i16);
auto sum_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_paddus_w), { va_v8i16, vb_v8i16 });
SetVr(vd, sum_v8i16);
// TODO: Set SAT
@@ -305,14 +305,14 @@ void Compiler::VAVGSW(u32 vd, u32 va, u32 vb) {
void Compiler::VAVGUB(u32 vd, u32 va, u32 vb) {
auto va_v16i8 = GetVrAsIntVec(va, 8);
auto vb_v16i8 = GetVrAsIntVec(vb, 8);
auto avg_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pavg_b), va_v16i8, vb_v16i8);
auto avg_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pavg_b), { va_v16i8, vb_v16i8 });
SetVr(vd, avg_v16i8);
}
void Compiler::VAVGUH(u32 vd, u32 va, u32 vb) {
auto va_v8i16 = GetVrAsIntVec(va, 16);
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
auto avg_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pavg_w), va_v8i16, vb_v8i16);
auto avg_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pavg_w), { va_v8i16, vb_v8i16 });
SetVr(vd, avg_v8i16);
}
@@ -557,7 +557,7 @@ void Compiler::VCTUXS(u32 vd, u32 uimm5, u32 vb) {
vb_v4f32 = m_ir_builder->CreateFMul(vb_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 1 << uimm5)));
}
auto res_v4f32 = (Value *)m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_max_ps), vb_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 0)));
auto res_v4f32 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_max_ps), { vb_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 0)) });
auto cmp_v4i1 = m_ir_builder->CreateFCmpOGE(res_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 0xFFFFFFFFu)));
auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4));
auto res_v4i32 = m_ir_builder->CreateFPToUI(res_v4f32, VectorType::get(m_ir_builder->getInt32Ty(), 4));
@@ -569,8 +569,8 @@ void Compiler::VCTUXS(u32 vd, u32 uimm5, u32 vb) {
void Compiler::VEXPTEFP(u32 vd, u32 vb) {
auto vb_v4f32 = GetVrAsFloatVec(vb);
auto res_v4f32 = (Value *)m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::pow, VectorType::get(m_ir_builder->getFloatTy(), 4)),
m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 2.0f)), vb_v4f32);
auto res_v4f32 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::pow, VectorType::get(m_ir_builder->getFloatTy(), 4)),
{ m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 2.0f)), vb_v4f32 });
SetVr(vd, res_v4f32);
}
@@ -584,56 +584,56 @@ void Compiler::VMADDFP(u32 vd, u32 va, u32 vc, u32 vb) {
auto va_v4f32 = GetVrAsFloatVec(va);
auto vb_v4f32 = GetVrAsFloatVec(vb);
auto vc_v4f32 = GetVrAsFloatVec(vc);
auto res_v4f32 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, VectorType::get(m_ir_builder->getFloatTy(), 4)), va_v4f32, vc_v4f32, vb_v4f32);
auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, VectorType::get(m_ir_builder->getFloatTy(), 4)), { va_v4f32, vc_v4f32, vb_v4f32 });
SetVr(vd, res_v4f32);
}
void Compiler::VMAXFP(u32 vd, u32 va, u32 vb) {
auto va_v4f32 = GetVrAsFloatVec(va);
auto vb_v4f32 = GetVrAsFloatVec(vb);
auto res_v4f32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_max_ps), va_v4f32, vb_v4f32);
auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_max_ps), { va_v4f32, vb_v4f32 });
SetVr(vd, res_v4f32);
}
void Compiler::VMAXSB(u32 vd, u32 va, u32 vb) {
auto va_v16i8 = GetVrAsIntVec(va, 8);
auto vb_v16i8 = GetVrAsIntVec(vb, 8);
auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxsb), va_v16i8, vb_v16i8);
auto res_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxsb), { va_v16i8, vb_v16i8 });
SetVr(vd, res_v16i8);
}
void Compiler::VMAXSH(u32 vd, u32 va, u32 vb) {
auto va_v8i16 = GetVrAsIntVec(va, 16);
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmaxs_w), va_v8i16, vb_v8i16);
auto res_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmaxs_w), { va_v8i16, vb_v8i16 });
SetVr(vd, res_v8i16);
}
void Compiler::VMAXSW(u32 vd, u32 va, u32 vb) {
auto va_v4i32 = GetVrAsIntVec(va, 32);
auto vb_v4i32 = GetVrAsIntVec(vb, 32);
auto res_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxsd), va_v4i32, vb_v4i32);
auto res_v4i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxsd), { va_v4i32, vb_v4i32 });
SetVr(vd, res_v4i32);
}
void Compiler::VMAXUB(u32 vd, u32 va, u32 vb) {
auto va_v16i8 = GetVrAsIntVec(va, 8);
auto vb_v16i8 = GetVrAsIntVec(vb, 8);
auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmaxu_b), va_v16i8, vb_v16i8);
auto res_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmaxu_b), { va_v16i8, vb_v16i8 });
SetVr(vd, res_v16i8);
}
void Compiler::VMAXUH(u32 vd, u32 va, u32 vb) {
auto va_v8i16 = GetVrAsIntVec(va, 16);
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxuw), va_v8i16, vb_v8i16);
auto res_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxuw), { va_v8i16, vb_v8i16 });
SetVr(vd, res_v8i16);
}
void Compiler::VMAXUW(u32 vd, u32 va, u32 vb) {
auto va_v4i32 = GetVrAsIntVec(va, 32);
auto vb_v4i32 = GetVrAsIntVec(vb, 32);
auto res_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxud), va_v4i32, vb_v4i32);
auto res_v4i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxud), { va_v4i32, vb_v4i32 });
SetVr(vd, res_v4i32);
}
@@ -652,7 +652,7 @@ void Compiler::VMHADDSHS(u32 vd, u32 va, u32 vb, u32 vc) {
auto res1_v4i32 = m_ir_builder->CreateShuffleVector(res_v8i32, UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32));
u32 mask2_v4i32[4] = { 4, 5, 6, 7 };
auto res2_v4i32 = m_ir_builder->CreateShuffleVector(res_v8i32, UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32));
auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packssdw_128), res1_v4i32, res2_v4i32);
auto res_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packssdw_128), { res1_v4i32, res2_v4i32 });
SetVr(vd, res_v8i16);
// TODO: Set VSCR.SAT
@@ -674,7 +674,7 @@ void Compiler::VMHRADDSHS(u32 vd, u32 va, u32 vb, u32 vc) {
auto res1_v4i32 = m_ir_builder->CreateShuffleVector(res_v8i32, UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32));
u32 mask2_v4i32[4] = { 4, 5, 6, 7 };
auto res2_v4i32 = m_ir_builder->CreateShuffleVector(res_v8i32, UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32));
auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packssdw_128), res1_v4i32, res2_v4i32);
auto res_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packssdw_128), { res1_v4i32, res2_v4i32 });
SetVr(vd, res_v8i16);
// TODO: Set VSCR.SAT
@@ -683,49 +683,49 @@ void Compiler::VMHRADDSHS(u32 vd, u32 va, u32 vb, u32 vc) {
void Compiler::VMINFP(u32 vd, u32 va, u32 vb) {
auto va_v4f32 = GetVrAsFloatVec(va);
auto vb_v4f32 = GetVrAsFloatVec(vb);
auto res_v4f32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_min_ps), va_v4f32, vb_v4f32);
auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_min_ps), { va_v4f32, vb_v4f32 });
SetVr(vd, res_v4f32);
}
void Compiler::VMINSB(u32 vd, u32 va, u32 vb) {
auto va_v16i8 = GetVrAsIntVec(va, 8);
auto vb_v16i8 = GetVrAsIntVec(vb, 8);
auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminsb), va_v16i8, vb_v16i8);
auto res_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminsb), { va_v16i8, vb_v16i8 });
SetVr(vd, res_v16i8);
}
void Compiler::VMINSH(u32 vd, u32 va, u32 vb) {
auto va_v8i16 = GetVrAsIntVec(va, 16);
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmins_w), va_v8i16, vb_v8i16);
auto res_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmins_w), { va_v8i16, vb_v8i16 });
SetVr(vd, res_v8i16);
}
void Compiler::VMINSW(u32 vd, u32 va, u32 vb) {
auto va_v4i32 = GetVrAsIntVec(va, 32);
auto vb_v4i32 = GetVrAsIntVec(vb, 32);
auto res_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminsd), va_v4i32, vb_v4i32);
auto res_v4i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminsd), { va_v4i32, vb_v4i32 });
SetVr(vd, res_v4i32);
}
void Compiler::VMINUB(u32 vd, u32 va, u32 vb) {
auto va_v16i8 = GetVrAsIntVec(va, 8);
auto vb_v16i8 = GetVrAsIntVec(vb, 8);
auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pminu_b), va_v16i8, vb_v16i8);
auto res_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pminu_b), { va_v16i8, vb_v16i8 });
SetVr(vd, res_v16i8);
}
void Compiler::VMINUH(u32 vd, u32 va, u32 vb) {
auto va_v8i16 = GetVrAsIntVec(va, 16);
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminuw), va_v8i16, vb_v8i16);
auto res_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminuw), { va_v8i16, vb_v8i16 });
SetVr(vd, res_v8i16);
}
void Compiler::VMINUW(u32 vd, u32 va, u32 vb) {
auto va_v4i32 = GetVrAsIntVec(va, 32);
auto vb_v4i32 = GetVrAsIntVec(vb, 32);
auto res_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminud), va_v4i32, vb_v4i32);
auto res_v4i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminud), { va_v4i32, vb_v4i32 });
SetVr(vd, res_v4i32);
}
@@ -822,7 +822,7 @@ void Compiler::VMSUMSHM(u32 vd, u32 va, u32 vb, u32 vc) {
auto va_v8i16 = GetVrAsIntVec(va, 16);
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
auto vc_v4i32 = GetVrAsIntVec(vc, 32);
auto res_v4i32 = (Value *)m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmadd_wd), va_v8i16, vb_v8i16);
auto res_v4i32 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmadd_wd), { va_v8i16, vb_v8i16 });
res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, vc_v4i32);
SetVr(vd, res_v4i32);
}
@@ -831,7 +831,7 @@ void Compiler::VMSUMSHS(u32 vd, u32 va, u32 vb, u32 vc) {
auto va_v8i16 = GetVrAsIntVec(va, 16);
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
auto vc_v4i32 = GetVrAsIntVec(vc, 32);
auto res_v4i32 = (Value *)m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmadd_wd), va_v8i16, vb_v8i16);
auto res_v4i32 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmadd_wd), { va_v8i16, vb_v8i16 });
auto tmp1_v4i32 = m_ir_builder->CreateLShr(vc_v4i32, 31);
tmp1_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x7FFFFFFF)));
@@ -844,7 +844,7 @@ void Compiler::VMSUMSHS(u32 vd, u32 va, u32 vb, u32 vc) {
tmp3_v4i32 = m_ir_builder->CreateAnd(tmp2_v4i32, tmp3_v4i32);
tmp3_v4i32 = m_ir_builder->CreateAShr(tmp3_v4i32, 31);
auto tmp3_v16i8 = m_ir_builder->CreateBitCast(tmp3_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16));
auto res_v16i8 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pblendvb), sum_v16i8, tmp1_v16i8, tmp3_v16i8);
auto res_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pblendvb), { sum_v16i8, tmp1_v16i8, tmp3_v16i8 });
SetVr(vd, res_v16i8);
// TODO: Set VSCR.SAT
@@ -1015,7 +1015,7 @@ void Compiler::VNMSUBFP(u32 vd, u32 va, u32 vc, u32 vb) {
auto vb_v4f32 = GetVrAsFloatVec(vb);
auto vc_v4f32 = GetVrAsFloatVec(vc);
vc_v4f32 = m_ir_builder->CreateFNeg(vc_v4f32);
auto res_v4f32 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, VectorType::get(m_ir_builder->getFloatTy(), 4)), va_v4f32, vc_v4f32, vb_v4f32);
auto res_v4f32 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, VectorType::get(m_ir_builder->getFloatTy(), 4)), { va_v4f32, vc_v4f32, vb_v4f32 });
SetVr(vd, res_v4f32);
}
@@ -1044,13 +1044,13 @@ void Compiler::VPERM(u32 vd, u32 va, u32 vb, u32 vc) {
auto fifteen_v16i8 = m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(15));
auto vc_le15_v16i8 = m_ir_builder->CreateSub(fifteen_v16i8, vc_v16i8);
auto res_va_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_ssse3_pshuf_b_128), va_v16i8, vc_le15_v16i8);
auto res_va_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_ssse3_pshuf_b_128), { va_v16i8, vc_le15_v16i8 });
auto vc_gt15_v16i8 = m_ir_builder->CreateSub(thrity_one_v16i8, vc_v16i8);
auto cmp_i1 = m_ir_builder->CreateICmpUGT(vc_gt15_v16i8, fifteen_v16i8);
auto cmp_i8 = m_ir_builder->CreateSExt(cmp_i1, VectorType::get(m_ir_builder->getInt8Ty(), 16));
vc_gt15_v16i8 = m_ir_builder->CreateOr(cmp_i8, vc_gt15_v16i8);
auto res_vb_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_ssse3_pshuf_b_128), vb_v16i8, vc_gt15_v16i8);
auto res_vb_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_ssse3_pshuf_b_128), { vb_v16i8, vc_gt15_v16i8 });
auto res_v16i8 = m_ir_builder->CreateOr(res_vb_v16i8, res_va_v16i8);
SetVr(vd, res_v16i8);
@@ -1093,7 +1093,7 @@ void Compiler::VPKPX(u32 vd, u32 va, u32 vb) {
void Compiler::VPKSHSS(u32 vd, u32 va, u32 vb) {
auto va_v8i16 = GetVrAsIntVec(va, 16);
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packsswb_128), vb_v8i16, va_v8i16);
auto res_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packsswb_128), { vb_v8i16, va_v8i16 });
SetVr(vd, res_v16i8);
// TODO: VSCR.SAT
@@ -1102,7 +1102,7 @@ void Compiler::VPKSHSS(u32 vd, u32 va, u32 vb) {
void Compiler::VPKSHUS(u32 vd, u32 va, u32 vb) {
auto va_v8i16 = GetVrAsIntVec(va, 16);
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packuswb_128), vb_v8i16, va_v8i16);
auto res_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packuswb_128), { vb_v8i16, va_v8i16 });
SetVr(vd, res_v16i8);
// TODO: VSCR.SAT
@@ -1111,7 +1111,7 @@ void Compiler::VPKSHUS(u32 vd, u32 va, u32 vb) {
void Compiler::VPKSWSS(u32 vd, u32 va, u32 vb) {
auto va_v4i32 = GetVrAsIntVec(va, 32);
auto vb_v4i32 = GetVrAsIntVec(vb, 32);
auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packssdw_128), vb_v4i32, va_v4i32);
auto res_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packssdw_128), { vb_v4i32, va_v4i32 });
SetVr(vd, res_v8i16);
// TODO: VSCR.SAT
@@ -1120,7 +1120,7 @@ void Compiler::VPKSWSS(u32 vd, u32 va, u32 vb) {
void Compiler::VPKSWUS(u32 vd, u32 va, u32 vb) {
auto va_v4i32 = GetVrAsIntVec(va, 32);
auto vb_v4i32 = GetVrAsIntVec(vb, 32);
auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_packusdw), vb_v4i32, va_v4i32);
auto res_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_packusdw), { vb_v4i32, va_v4i32 });
SetVr(vd, res_v8i16);
// TODO: VSCR.SAT
@@ -1138,8 +1138,8 @@ void Compiler::VPKUHUM(u32 vd, u32 va, u32 vb) {
void Compiler::VPKUHUS(u32 vd, u32 va, u32 vb) {
auto va_v8i16 = GetVrAsIntVec(va, 16);
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
va_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminuw), va_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xFF)));
vb_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminuw), vb_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xFF)));
va_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminuw), { va_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xFF)) });
vb_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminuw), { vb_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xFF)) });
auto va_v16i8 = m_ir_builder->CreateBitCast(va_v8i16, VectorType::get(m_ir_builder->getInt8Ty(), 16));
auto vb_v16i8 = m_ir_builder->CreateBitCast(vb_v8i16, VectorType::get(m_ir_builder->getInt8Ty(), 16));
@@ -1162,8 +1162,8 @@ void Compiler::VPKUWUM(u32 vd, u32 va, u32 vb) {
void Compiler::VPKUWUS(u32 vd, u32 va, u32 vb) {
auto va_v4i32 = GetVrAsIntVec(va, 32);
auto vb_v4i32 = GetVrAsIntVec(vb, 32);
va_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminud), va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFFFF)));
vb_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminud), vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFFFF)));
va_v4i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminud), { va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFFFF)) });
vb_v4i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminud), { vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFFFF)) });
auto va_v8i16 = m_ir_builder->CreateBitCast(va_v4i32, VectorType::get(m_ir_builder->getInt16Ty(), 8));
auto vb_v8i16 = m_ir_builder->CreateBitCast(vb_v4i32, VectorType::get(m_ir_builder->getInt16Ty(), 8));
@@ -1434,7 +1434,7 @@ void Compiler::VSUBFP(u32 vd, u32 va, u32 vb) {
void Compiler::VSUBSBS(u32 vd, u32 va, u32 vb) {
auto va_v16i8 = GetVrAsIntVec(va, 8);
auto vb_v16i8 = GetVrAsIntVec(vb, 8);
auto diff_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubs_b), va_v16i8, vb_v16i8);
auto diff_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubs_b), { va_v16i8, vb_v16i8 });
SetVr(vd, diff_v16i8);
// TODO: Set VSCR.SAT
@@ -1443,7 +1443,7 @@ void Compiler::VSUBSBS(u32 vd, u32 va, u32 vb) {
void Compiler::VSUBSHS(u32 vd, u32 va, u32 vb) {
auto va_v8i16 = GetVrAsIntVec(va, 16);
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
auto diff_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubs_w), va_v8i16, vb_v8i16);
auto diff_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubs_w), { va_v8i16, vb_v8i16 });
SetVr(vd, diff_v8i16);
// TODO: Set VSCR.SAT
@@ -1474,7 +1474,7 @@ void Compiler::VSUBSWS(u32 vd, u32 va, u32 vb) {
auto tmp3_v16i8 = m_ir_builder->CreateBitCast(tmp3_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16));
// tmp4 is equal to 0xFFFFFFFF if an overflow occured and 0x00000000 otherwise.
auto res_v16i8 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pblendvb), diff_v16i8, tmp1_v16i8, tmp3_v16i8);
auto res_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pblendvb), { diff_v16i8, tmp1_v16i8, tmp3_v16i8 });
SetVr(vd, res_v16i8);
// TODO: Set SAT
@@ -1490,7 +1490,7 @@ void Compiler::VSUBUBM(u32 vd, u32 va, u32 vb) {
void Compiler::VSUBUBS(u32 vd, u32 va, u32 vb) {
auto va_v16i8 = GetVrAsIntVec(va, 8);
auto vb_v16i8 = GetVrAsIntVec(vb, 8);
auto diff_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubus_b), va_v16i8, vb_v16i8);
auto diff_v16i8 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubus_b), {va_v16i8, vb_v16i8});
SetVr(vd, diff_v16i8);
// TODO: Set SAT
@@ -1506,7 +1506,7 @@ void Compiler::VSUBUHM(u32 vd, u32 va, u32 vb) {
void Compiler::VSUBUHS(u32 vd, u32 va, u32 vb) {
auto va_v8i16 = GetVrAsIntVec(va, 16);
auto vb_v8i16 = GetVrAsIntVec(vb, 16);
auto diff_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubus_w), va_v8i16, vb_v8i16);
auto diff_v8i16 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubus_w), { va_v8i16, vb_v8i16 });
SetVr(vd, diff_v8i16);
// TODO: Set SAT
@@ -1744,7 +1744,7 @@ void Compiler::SUBFIC(u32 rd, u32 ra, s32 simm16) {
auto ra_i64 = GetGpr(ra);
ra_i64 = m_ir_builder->CreateNeg(ra_i64); // simpler way of doing ~ra + 1
auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, m_ir_builder->getInt64((s64)simm16));
auto res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { ra_i64, m_ir_builder->getInt64((s64)simm16) });
auto diff_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
auto is_zero = m_ir_builder->CreateICmpEQ(ra_i64, m_ir_builder->getInt64(0)); // if ra is zero when ~ra + 1 = 0 sets overflow bit
@@ -1785,7 +1785,7 @@ void Compiler::ADDIC(u32 rd, u32 ra, s32 simm16) {
USE_INTERP_IF_REQUESTED(ADDIC, m_ir_builder->getInt32(rd), m_ir_builder->getInt32(ra), m_ir_builder->getInt32(simm16));
auto ra_i64 = GetGpr(ra);
auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), m_ir_builder->getInt64((s64)simm16), ra_i64);
auto res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { m_ir_builder->getInt64((s64)simm16), ra_i64 });
auto sum_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
SetGpr(rd, sum_i64);
@@ -2337,7 +2337,7 @@ void Compiler::SUBFC(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) {
auto ra_i64 = GetGpr(ra);
ra_i64 = m_ir_builder->CreateNeg(ra_i64);
auto rb_i64 = GetGpr(rb);
auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, rb_i64);
auto res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { ra_i64, rb_i64 });
auto diff_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
SetGpr(rd, diff_i64);
@@ -2356,7 +2356,7 @@ void Compiler::SUBFC(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) {
void Compiler::ADDC(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) {
auto ra_i64 = GetGpr(ra);
auto rb_i64 = GetGpr(rb);
auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, rb_i64);
auto res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { ra_i64, rb_i64 });
auto sum_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
SetGpr(rd, sum_i64);
@@ -2468,7 +2468,7 @@ void Compiler::SLW(u32 ra, u32 rs, u32 rb, u32 rc) {
void Compiler::CNTLZW(u32 ra, u32 rs, u32 rc) {
auto rs_i32 = GetGpr(rs, 32);
auto res_i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::ctlz, m_ir_builder->getInt32Ty()), rs_i32, m_ir_builder->getInt1(false));
auto res_i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::ctlz, m_ir_builder->getInt32Ty()), { rs_i32, m_ir_builder->getInt1(false) });
auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty());
SetGpr(ra, res_i64);
@@ -2618,7 +2618,7 @@ void Compiler::LWZUX(u32 rd, u32 ra, u32 rb) {
void Compiler::CNTLZD(u32 ra, u32 rs, u32 rc) {
auto rs_i64 = GetGpr(rs);
auto res_i64 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::ctlz, m_ir_builder->getInt64Ty()), rs_i64, m_ir_builder->getInt1(false));
auto res_i64 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::ctlz, m_ir_builder->getInt64Ty()), { rs_i64, m_ir_builder->getInt1(false) });
SetGpr(ra, res_i64);
if (rc) {
@@ -2793,10 +2793,10 @@ void Compiler::SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) {
auto ra_i64 = GetGpr(ra);
auto rb_i64 = GetGpr(rb);
ra_i64 = m_ir_builder->CreateNot(ra_i64);
auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64);
auto res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), {ra_i64, ca_i64 });
auto res_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
auto carry1_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), res_i64, rb_i64);
res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { res_i64, rb_i64 });
res_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
auto carry2_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
auto carry_i1 = m_ir_builder->CreateOr(carry1_i1, carry2_i1);
@@ -2817,10 +2817,10 @@ void Compiler::ADDE(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) {
auto ca_i64 = GetXerCa();
auto ra_i64 = GetGpr(ra);
auto rb_i64 = GetGpr(rb);
auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64);
auto res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { ra_i64, ca_i64 });
auto res_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
auto carry1_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), res_i64, rb_i64);
res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { res_i64, rb_i64 });
res_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
auto carry2_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
auto carry_i1 = m_ir_builder->CreateOr(carry1_i1, carry2_i1);
@@ -2954,7 +2954,7 @@ void Compiler::STVEWX(u32 vs, u32 ra, u32 rb) {
void Compiler::ADDZE(u32 rd, u32 ra, u32 oe, u32 rc) {
auto ra_i64 = GetGpr(ra);
auto ca_i64 = GetXerCa();
auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64);
auto res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { ra_i64, ca_i64 });
auto sum_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
SetGpr(rd, sum_i64);
@@ -2974,7 +2974,7 @@ void Compiler::SUBFZE(u32 rd, u32 ra, u32 oe, u32 rc) {
auto ra_i64 = GetGpr(ra);
ra_i64 = m_ir_builder->CreateNot(ra_i64);
auto ca_i64 = GetXerCa();
auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64);
auto res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { ra_i64, ca_i64 });
auto res_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
SetGpr(rd, res_i64);
@@ -3035,10 +3035,10 @@ void Compiler::SUBFME(u32 rd, u32 ra, u32 oe, u32 rc) {
auto ca_i64 = GetXerCa();
auto ra_i64 = GetGpr(ra);
ra_i64 = m_ir_builder->CreateNot(ra_i64);
auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64);
auto res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { ra_i64, ca_i64 });
auto res_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
auto carry1_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), res_i64, m_ir_builder->getInt64((s64)-1));
res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { res_i64, m_ir_builder->getInt64((s64)-1) });
res_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
auto carry2_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
auto carry_i1 = m_ir_builder->CreateOr(carry1_i1, carry2_i1);
@@ -3074,10 +3074,10 @@ void Compiler::MULLD(u32 rd, u32 ra, u32 rb, u32 oe, u32 rc) {
void Compiler::ADDME(u32 rd, u32 ra, u32 oe, u32 rc) {
auto ca_i64 = GetXerCa();
auto ra_i64 = GetGpr(ra);
auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64);
auto res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { ra_i64, ca_i64 });
auto res_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
auto carry1_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), res_i64, m_ir_builder->getInt64((s64)-1));
res_s = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), { res_i64, m_ir_builder->getInt64((s64)-1) });
res_i64 = m_ir_builder->CreateExtractValue(res_s, { 0 });
auto carry2_i1 = m_ir_builder->CreateExtractValue(res_s, { 1 });
auto carry_i1 = m_ir_builder->CreateOr(carry1_i1, carry2_i1);
@@ -3663,8 +3663,8 @@ void Compiler::STVLX(u32 vs, u32 ra, u32 rb) {
auto vs_i8_ptr = m_ir_builder->CreateBitCast(vs_i128_ptr, m_ir_builder->getInt8PtrTy());
Type * types[3] = { m_ir_builder->getInt8PtrTy(), m_ir_builder->getInt8PtrTy(), m_ir_builder->getInt64Ty() };
m_ir_builder->CreateCall5(Intrinsic::getDeclaration(m_module, Intrinsic::memcpy, types),
addr_i8_ptr, vs_i8_ptr, size_i64, m_ir_builder->getInt32(1), m_ir_builder->getInt1(false));
m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::memcpy, types),
{ addr_i8_ptr, vs_i8_ptr, size_i64, m_ir_builder->getInt32(1), m_ir_builder->getInt1(false) });
}
void Compiler::STDBRX(u32 rs, u32 ra, u32 rb) {
@@ -3724,8 +3724,8 @@ void Compiler::STVRX(u32 vs, u32 ra, u32 rb) {
vs_i8_ptr = m_ir_builder->CreateGEP(vs_i8_ptr, index_i64);
Type * types[3] = { m_ir_builder->getInt8PtrTy(), m_ir_builder->getInt8PtrTy(), m_ir_builder->getInt64Ty() };
m_ir_builder->CreateCall5(Intrinsic::getDeclaration(m_module, Intrinsic::memcpy, types),
addr_i8_ptr, vs_i8_ptr, size_i64, m_ir_builder->getInt32(1), m_ir_builder->getInt1(false));
m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::memcpy, types),
{ addr_i8_ptr, vs_i8_ptr, size_i64, m_ir_builder->getInt32(1), m_ir_builder->getInt1(false) });
}
void Compiler::STFSUX(u32 frs, u32 ra, u32 rb) {
@@ -3994,8 +3994,8 @@ void Compiler::DCBZ(u32 ra, u32 rb) {
auto addr_i8_ptr = m_ir_builder->CreateIntToPtr(addr_i64, m_ir_builder->getInt8PtrTy());
std::vector<Type *> types = { (Type *)m_ir_builder->getInt8PtrTy(), (Type *)m_ir_builder->getInt32Ty() };
m_ir_builder->CreateCall5(Intrinsic::getDeclaration(m_module, Intrinsic::memset, types),
addr_i8_ptr, m_ir_builder->getInt8(0), m_ir_builder->getInt32(128), m_ir_builder->getInt32(128), m_ir_builder->getInt1(true));
m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::memset, types),
{ addr_i8_ptr, m_ir_builder->getInt8(0), m_ir_builder->getInt32(128), m_ir_builder->getInt32(128), m_ir_builder->getInt1(true) });
}
void Compiler::LWZ(u32 rd, u32 ra, s32 d) {
@@ -4397,7 +4397,7 @@ void Compiler::FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) {
auto ra_f64 = GetFpr(fra);
auto rb_f64 = GetFpr(frb);
auto rc_f64 = GetFpr(frc);
auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64);
auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), { ra_f64, rc_f64, rb_f64 });
auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy());
SetFpr(frd, res_f32);
@@ -4414,7 +4414,7 @@ void Compiler::FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) {
auto rb_f64 = GetFpr(frb);
auto rc_f64 = GetFpr(frc);
rb_f64 = m_ir_builder->CreateFNeg(rb_f64);
auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64);
auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), { ra_f64, rc_f64, rb_f64 });
auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy());
SetFpr(frd, res_f32);
@@ -4431,7 +4431,7 @@ void Compiler::FNMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) {
auto rb_f64 = GetFpr(frb);
auto rc_f64 = GetFpr(frc);
rb_f64 = m_ir_builder->CreateFNeg(rb_f64);
auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64);
auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), { ra_f64, rc_f64, rb_f64 });
res_f64 = m_ir_builder->CreateFNeg(res_f64);
auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy());
SetFpr(frd, res_f32);
@@ -4448,7 +4448,7 @@ void Compiler::FNMADDS(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) {
auto ra_f64 = GetFpr(fra);
auto rb_f64 = GetFpr(frb);
auto rc_f64 = GetFpr(frc);
auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64);
auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), { ra_f64, rc_f64, rb_f64 });
res_f64 = m_ir_builder->CreateFNeg(res_f64);
auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy());
SetFpr(frd, res_f32);
@@ -4746,7 +4746,7 @@ void Compiler::FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) {
auto rb_f64 = GetFpr(frb);
auto rc_f64 = GetFpr(frc);
rb_f64 = m_ir_builder->CreateFNeg(rb_f64);
auto res_f64 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64);
auto res_f64 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), { ra_f64, rc_f64, rb_f64 });
SetFpr(frd, res_f64);
if (rc) {
@@ -4761,7 +4761,7 @@ void Compiler::FMADD(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) {
auto ra_f64 = GetFpr(fra);
auto rb_f64 = GetFpr(frb);
auto rc_f64 = GetFpr(frc);
auto res_f64 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64);
auto res_f64 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), { ra_f64, rc_f64, rb_f64 });
SetFpr(frd, res_f64);
if (rc) {
@@ -4777,7 +4777,7 @@ void Compiler::FNMSUB(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) {
auto rb_f64 = GetFpr(frb);
auto rc_f64 = GetFpr(frc);
rc_f64 = m_ir_builder->CreateFNeg(rc_f64);
auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64);
auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), { ra_f64, rc_f64, rb_f64 });
SetFpr(frd, res_f64);
if (rc) {
@@ -4794,7 +4794,7 @@ void Compiler::FNMADD(u32 frd, u32 fra, u32 frc, u32 frb, u32 rc) {
auto rc_f64 = GetFpr(frc);
rb_f64 = m_ir_builder->CreateFNeg(rb_f64);
rc_f64 = m_ir_builder->CreateFNeg(rc_f64);
auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64);
auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), { ra_f64, rc_f64, rb_f64 });
SetFpr(frd, res_f64);
if (rc) {
@@ -4983,10 +4983,10 @@ Value * Compiler::GetBit(Value * val, u32 n) {
#ifdef PPU_LLVM_RECOMPILER_USE_BMI
if (val->getType()->isIntegerTy(32)) {
bit = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_32), val, m_ir_builder->getInt32(1 << (31 - n)));
bit = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_32), val, m_ir_builder->getInt32(1 << (31 - n)));
}
else if (val->getType()->isIntegerTy(64)) {
bit = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_64), val, m_ir_builder->getInt64((u64)1 << (63 - n)));
bit = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_64), val, m_ir_builder->getInt64((u64)1 << (63 - n)));
}
else {
#endif
@@ -5030,10 +5030,10 @@ Value * Compiler::GetNibble(Value * val, u32 n) {
#ifdef PPU_LLVM_RECOMPILER_USE_BMI
if (val->getType()->isIntegerTy(32)) {
nibble = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_32), val, m_ir_builder->getInt32((u64)0xF << ((7 - n) * 4)));
nibble = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_32), val, m_ir_builder->getInt32((u64)0xF << ((7 - n) * 4)));
}
else if (val->getType()->isIntegerTy(64)) {
nibble = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_64), val, m_ir_builder->getInt64((u64)0xF << ((15 - n) * 4)));
nibble = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_64), val, m_ir_builder->getInt64((u64)0xF << ((15 - n) * 4)));
}
else {
#endif
@@ -5097,33 +5097,33 @@ Value * Compiler::SetNibble(Value * val, u32 n, Value * b0, Value * b1, Value *
}
Value * Compiler::GetPc() {
auto pc_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, PC));
auto pc_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, PC));
auto pc_i32_ptr = m_ir_builder->CreateBitCast(pc_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo());
return m_ir_builder->CreateAlignedLoad(pc_i32_ptr, 4);
}
void Compiler::SetPc(Value * val_ix) {
auto pc_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, PC));
auto pc_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, PC));
auto pc_i32_ptr = m_ir_builder->CreateBitCast(pc_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo());
auto val_i32 = m_ir_builder->CreateZExtOrTrunc(val_ix, m_ir_builder->getInt32Ty());
m_ir_builder->CreateAlignedStore(val_i32, pc_i32_ptr, 4);
}
Value * Compiler::GetGpr(u32 r, u32 num_bits) {
auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, GPR[r]));
auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, GPR[r]));
auto r_ix_ptr = m_ir_builder->CreateBitCast(r_i8_ptr, m_ir_builder->getIntNTy(num_bits)->getPointerTo());
return m_ir_builder->CreateAlignedLoad(r_ix_ptr, 8);
}
void Compiler::SetGpr(u32 r, Value * val_x64) {
auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, GPR[r]));
auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, GPR[r]));
auto r_i64_ptr = m_ir_builder->CreateBitCast(r_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo());
auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty());
m_ir_builder->CreateAlignedStore(val_i64, r_i64_ptr, 8);
}
Value * Compiler::GetCr() {
auto cr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, CR));
auto cr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, CR));
auto cr_i32_ptr = m_ir_builder->CreateBitCast(cr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo());
return m_ir_builder->CreateAlignedLoad(cr_i32_ptr, 4);
}
@@ -5134,7 +5134,7 @@ Value * Compiler::GetCrField(u32 n) {
void Compiler::SetCr(Value * val_x32) {
auto val_i32 = m_ir_builder->CreateBitCast(val_x32, m_ir_builder->getInt32Ty());
auto cr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, CR));
auto cr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, CR));
auto cr_i32_ptr = m_ir_builder->CreateBitCast(cr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo());
m_ir_builder->CreateAlignedStore(val_i32, cr_i32_ptr, 4);
}
@@ -5176,33 +5176,33 @@ void Compiler::SetCr6AfterVectorCompare(u32 vr) {
}
Value * Compiler::GetLr() {
auto lr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, LR));
auto lr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, LR));
auto lr_i64_ptr = m_ir_builder->CreateBitCast(lr_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo());
return m_ir_builder->CreateAlignedLoad(lr_i64_ptr, 8);
}
void Compiler::SetLr(Value * val_x64) {
auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty());
auto lr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, LR));
auto lr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, LR));
auto lr_i64_ptr = m_ir_builder->CreateBitCast(lr_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo());
m_ir_builder->CreateAlignedStore(val_i64, lr_i64_ptr, 8);
}
Value * Compiler::GetCtr() {
auto ctr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, CTR));
auto ctr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, CTR));
auto ctr_i64_ptr = m_ir_builder->CreateBitCast(ctr_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo());
return m_ir_builder->CreateAlignedLoad(ctr_i64_ptr, 8);
}
void Compiler::SetCtr(Value * val_x64) {
auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty());
auto ctr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, CTR));
auto ctr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, CTR));
auto ctr_i64_ptr = m_ir_builder->CreateBitCast(ctr_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo());
m_ir_builder->CreateAlignedStore(val_i64, ctr_i64_ptr, 8);
}
Value * Compiler::GetXer() {
auto xer_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, XER));
auto xer_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, XER));
auto xer_i64_ptr = m_ir_builder->CreateBitCast(xer_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo());
return m_ir_builder->CreateAlignedLoad(xer_i64_ptr, 8);
}
@@ -5217,7 +5217,7 @@ Value * Compiler::GetXerSo() {
void Compiler::SetXer(Value * val_x64) {
auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty());
auto xer_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, XER));
auto xer_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, XER));
auto xer_i64_ptr = m_ir_builder->CreateBitCast(xer_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo());
m_ir_builder->CreateAlignedStore(val_i64, xer_i64_ptr, 8);
}
@@ -5235,7 +5235,7 @@ void Compiler::SetXerSo(Value * so) {
}
Value * Compiler::GetVrsave() {
auto vrsave_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VRSAVE));
auto vrsave_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, VRSAVE));
auto vrsave_i32_ptr = m_ir_builder->CreateBitCast(vrsave_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo());
auto val_i32 = m_ir_builder->CreateAlignedLoad(vrsave_i32_ptr, 4);
return m_ir_builder->CreateZExtOrTrunc(val_i32, m_ir_builder->getInt64Ty());
@@ -5244,26 +5244,26 @@ Value * Compiler::GetVrsave() {
void Compiler::SetVrsave(Value * val_x64) {
auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty());
auto val_i32 = m_ir_builder->CreateZExtOrTrunc(val_i64, m_ir_builder->getInt32Ty());
auto vrsave_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VRSAVE));
auto vrsave_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, VRSAVE));
auto vrsave_i32_ptr = m_ir_builder->CreateBitCast(vrsave_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo());
m_ir_builder->CreateAlignedStore(val_i32, vrsave_i32_ptr, 8);
}
Value * Compiler::GetFpscr() {
auto fpscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, FPSCR));
auto fpscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, FPSCR));
auto fpscr_i32_ptr = m_ir_builder->CreateBitCast(fpscr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo());
return m_ir_builder->CreateAlignedLoad(fpscr_i32_ptr, 4);
}
void Compiler::SetFpscr(Value * val_x32) {
auto val_i32 = m_ir_builder->CreateBitCast(val_x32, m_ir_builder->getInt32Ty());
auto fpscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, FPSCR));
auto fpscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, FPSCR));
auto fpscr_i32_ptr = m_ir_builder->CreateBitCast(fpscr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo());
m_ir_builder->CreateAlignedStore(val_i32, fpscr_i32_ptr, 4);
}
Value * Compiler::GetFpr(u32 r, u32 bits, bool as_int) {
auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, FPR[r]));
auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, FPR[r]));
if (!as_int) {
auto r_f64_ptr = m_ir_builder->CreateBitCast(r_i8_ptr, m_ir_builder->getDoubleTy()->getPointerTo());
auto r_f64 = m_ir_builder->CreateAlignedLoad(r_f64_ptr, 8);
@@ -5287,7 +5287,7 @@ Value * Compiler::GetFpr(u32 r, u32 bits, bool as_int) {
}
void Compiler::SetFpr(u32 r, Value * val) {
auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, FPR[r]));
auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, FPR[r]));
auto r_f64_ptr = m_ir_builder->CreateBitCast(r_i8_ptr, m_ir_builder->getDoubleTy()->getPointerTo());
Value* val_f64;
@@ -5306,47 +5306,47 @@ void Compiler::SetFpr(u32 r, Value * val) {
}
Value * Compiler::GetVscr() {
auto vscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VSCR));
auto vscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, VSCR));
auto vscr_i32_ptr = m_ir_builder->CreateBitCast(vscr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo());
return m_ir_builder->CreateAlignedLoad(vscr_i32_ptr, 4);
}
void Compiler::SetVscr(Value * val_x32) {
auto val_i32 = m_ir_builder->CreateBitCast(val_x32, m_ir_builder->getInt32Ty());
auto vscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VSCR));
auto vscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, VSCR));
auto vscr_i32_ptr = m_ir_builder->CreateBitCast(vscr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo());
m_ir_builder->CreateAlignedStore(val_i32, vscr_i32_ptr, 4);
}
Value * Compiler::GetVr(u32 vr) {
auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr]));
auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, VPR[vr]));
auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo());
return m_ir_builder->CreateAlignedLoad(vr_i128_ptr, 16);
}
Value * Compiler::GetVrAsIntVec(u32 vr, u32 vec_elt_num_bits) {
auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr]));
auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, VPR[vr]));
auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo());
auto vr_vec_ptr = m_ir_builder->CreateBitCast(vr_i128_ptr, VectorType::get(m_ir_builder->getIntNTy(vec_elt_num_bits), 128 / vec_elt_num_bits)->getPointerTo());
return m_ir_builder->CreateAlignedLoad(vr_vec_ptr, 16);
}
Value * Compiler::GetVrAsFloatVec(u32 vr) {
auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr]));
auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, VPR[vr]));
auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo());
auto vr_v4f32_ptr = m_ir_builder->CreateBitCast(vr_i128_ptr, VectorType::get(m_ir_builder->getFloatTy(), 4)->getPointerTo());
return m_ir_builder->CreateAlignedLoad(vr_v4f32_ptr, 16);
}
Value * Compiler::GetVrAsDoubleVec(u32 vr) {
auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr]));
auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, VPR[vr]));
auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo());
auto vr_v2f64_ptr = m_ir_builder->CreateBitCast(vr_i128_ptr, VectorType::get(m_ir_builder->getDoubleTy(), 2)->getPointerTo());
return m_ir_builder->CreateAlignedLoad(vr_v2f64_ptr, 16);
}
void Compiler::SetVr(u32 vr, Value * val_x128) {
auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr]));
auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], OFFSET_32(PPUThread, VPR[vr]));
auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo());
auto val_i128 = m_ir_builder->CreateBitCast(val_x128, m_ir_builder->getIntNTy(128));
m_ir_builder->CreateAlignedStore(val_i128, vr_i128_ptr, 16);
@@ -5417,7 +5417,7 @@ void Compiler::CreateBranch(llvm::Value * cmp_i1, llvm::Value * target_i32, bool
// Function *fn = m_module->getFunction(fmt::format("function_0x%08X", target_address));
llvm::Value *execStatus;
// if (fn)
// execStatus = m_ir_builder->CreateCall2(fn, m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt64(0));
// execStatus = m_ir_builder->CreateCall(fn, {m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt64(0) });
// else
execStatus = Call<u32>("execute_unknown_function", m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt64(0));
@@ -5451,7 +5451,7 @@ void Compiler::CreateBranch(llvm::Value * cmp_i1, llvm::Value * target_i32, bool
else if (lk) {
BasicBlock *next_block = GetBasicBlockFromAddress(m_state.current_instruction_address + 4);
llvm::Value *execStatus = m_ir_builder->CreateCall2(m_execute_unknown_function, m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt64(0));
llvm::Value *execStatus = m_ir_builder->CreateCall(m_execute_unknown_function, {m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt64(0)});
llvm::BasicBlock *cputhreadexitblock = GetBasicBlockFromAddress(m_state.current_instruction_address, "early_exit");
llvm::Value *isCPUThreadExit = m_ir_builder->CreateICmpEQ(execStatus, m_ir_builder->getInt32(ExecutionStatus::ExecutionStatusPropagateException));
+2 -2
View File
@@ -349,9 +349,9 @@ cpu_thread& ppu_thread::args(std::initializer_list<std::string> values)
assert(argc == 0);
envp.set(vm::alloc(align(sizeof32(*envp), stack_align), vm::main));
envp.set(vm::alloc(align(SIZE_32(*envp), stack_align), vm::main));
*envp = 0;
argv.set(vm::alloc(sizeof32(*argv) * (u32)values.size(), vm::main));
argv.set(vm::alloc(SIZE_32(*argv) * (u32)values.size(), vm::main));
for (auto &arg : values)
{
+3 -1
View File
@@ -1017,6 +1017,8 @@ enum : u32
{
MFF_FORCED_HLE = (1 << 0), // always call HLE function
MFF_NO_RETURN = (1 << 1), // uses EIF_USE_BRANCH flag with LLE, ignored with MFF_FORCED_HLE
MFF_PERFECT = /* 0 */ MFF_FORCED_HLE, // can be set for fully implemented functions with LLE compatibility
};
// flags passed with index
@@ -1026,5 +1028,5 @@ enum : u32
EIF_PERFORM_BLR = (1 << 24), // do BLR after calling HLE/LLE function
EIF_USE_BRANCH = (1 << 23), // do only branch, LLE must be set, last_syscall must be zero
EIF_FLAGS = 0x3800000, // all flags
EIF_FLAGS = 0x3800000, // all flags
};
+1 -1
View File
@@ -60,7 +60,7 @@ bool RawSPUThread::read_reg(const u32 addr, u32& value)
}
}
LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(0x%x): unknown/illegal offset (0x%x)", index, addr, offset);
LOG_ERROR(SPU, "RawSPUThread[%d]: Read32(0x%x): unknown/illegal offset (0x%x)", index, addr, offset);
return false;
}
+16 -18
View File
@@ -15,13 +15,11 @@
#include "asmjit.h"
#define OFFSET_OF(type, x) static_cast<s32>(reinterpret_cast<uintptr_t>(&(((type*)0)->x)))
#define SPU_OFF_128(x) asmjit::host::oword_ptr(*cpu, OFFSET_OF(SPUThread, x))
#define SPU_OFF_64(x) asmjit::host::qword_ptr(*cpu, OFFSET_OF(SPUThread, x))
#define SPU_OFF_32(x) asmjit::host::dword_ptr(*cpu, OFFSET_OF(SPUThread, x))
#define SPU_OFF_16(x) asmjit::host::word_ptr(*cpu, OFFSET_OF(SPUThread, x))
#define SPU_OFF_8(x) asmjit::host::byte_ptr(*cpu, OFFSET_OF(SPUThread, x))
#define SPU_OFF_128(x) asmjit::host::oword_ptr(*cpu, OFFSET_32(SPUThread, x))
#define SPU_OFF_64(x) asmjit::host::qword_ptr(*cpu, OFFSET_32(SPUThread, x))
#define SPU_OFF_32(x) asmjit::host::dword_ptr(*cpu, OFFSET_32(SPUThread, x))
#define SPU_OFF_16(x) asmjit::host::word_ptr(*cpu, OFFSET_32(SPUThread, x))
#define SPU_OFF_8(x) asmjit::host::byte_ptr(*cpu, OFFSET_32(SPUThread, x))
spu_recompiler::spu_recompiler()
: m_jit(std::make_shared<asmjit::JitRuntime>())
@@ -31,7 +29,7 @@ spu_recompiler::spu_recompiler()
LOG_SUCCESS(SPU, "SPU Recompiler (ASMJIT) created...");
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());
fs::file(fs::get_config_dir() + "SPUJIT.log", fom::rewrite).write(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)
@@ -216,7 +214,7 @@ void spu_recompiler::compile(spu_function_t& f)
log += "\n\n\n";
// Append log file
fs::file(fs::get_config_dir() + "SPUJIT.log", fom::write | fom::append) << log;
fs::file(fs::get_config_dir() + "SPUJIT.log", fom::write | fom::append).write(log);
}
spu_recompiler::XmmLink spu_recompiler::XmmAlloc() // get empty xmm register
@@ -918,7 +916,7 @@ void spu_recompiler::BISL(spu_opcode_t op)
void spu_recompiler::IRET(spu_opcode_t op)
{
throw EXCEPTION("Unimplemented instruction");
//throw EXCEPTION("Unimplemented instruction");
}
void spu_recompiler::BISLED(spu_opcode_t op)
@@ -1083,7 +1081,7 @@ void spu_recompiler::CBX(spu_opcode_t op)
const XmmLink& vr = XmmAlloc();
c->movdqa(vr, XmmConst(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f)));
c->movdqa(SPU_OFF_128(gpr[op.rt]), vr);
c->mov(asmjit::host::byte_ptr(*cpu, *addr, 0, OFFSET_OF(SPUThread, gpr[op.rt])), 0x03);
c->mov(asmjit::host::byte_ptr(*cpu, *addr, 0, OFFSET_32(SPUThread, gpr[op.rt])), 0x03);
c->unuse(*addr);
}
@@ -1097,7 +1095,7 @@ void spu_recompiler::CHX(spu_opcode_t op)
const XmmLink& vr = XmmAlloc();
c->movdqa(vr, XmmConst(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f)));
c->movdqa(SPU_OFF_128(gpr[op.rt]), vr);
c->mov(asmjit::host::word_ptr(*cpu, *addr, 0, OFFSET_OF(SPUThread, gpr[op.rt])), 0x0203);
c->mov(asmjit::host::word_ptr(*cpu, *addr, 0, OFFSET_32(SPUThread, gpr[op.rt])), 0x0203);
c->unuse(*addr);
}
@@ -1111,7 +1109,7 @@ void spu_recompiler::CWX(spu_opcode_t op)
const XmmLink& vr = XmmAlloc();
c->movdqa(vr, XmmConst(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f)));
c->movdqa(SPU_OFF_128(gpr[op.rt]), vr);
c->mov(asmjit::host::dword_ptr(*cpu, *addr, 0, OFFSET_OF(SPUThread, gpr[op.rt])), 0x00010203);
c->mov(asmjit::host::dword_ptr(*cpu, *addr, 0, OFFSET_32(SPUThread, gpr[op.rt])), 0x00010203);
c->unuse(*addr);
}
@@ -1126,7 +1124,7 @@ void spu_recompiler::CDX(spu_opcode_t op)
c->movdqa(vr, XmmConst(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f)));
c->movdqa(SPU_OFF_128(gpr[op.rt]), vr);
c->mov(*qw0, asmjit::imm_u(0x0001020304050607));
c->mov(asmjit::host::qword_ptr(*cpu, *addr, 0, OFFSET_OF(SPUThread, gpr[op.rt])), *qw0);
c->mov(asmjit::host::qword_ptr(*cpu, *addr, 0, OFFSET_32(SPUThread, gpr[op.rt])), *qw0);
c->unuse(*addr);
c->unuse(*qw0);
}
@@ -1254,7 +1252,7 @@ void spu_recompiler::CBD(spu_opcode_t op)
const XmmLink& vr = XmmAlloc();
c->movdqa(vr, XmmConst(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f)));
c->movdqa(SPU_OFF_128(gpr[op.rt]), vr);
c->mov(asmjit::host::byte_ptr(*cpu, *addr, 0, OFFSET_OF(SPUThread, gpr[op.rt])), 0x03);
c->mov(asmjit::host::byte_ptr(*cpu, *addr, 0, OFFSET_32(SPUThread, gpr[op.rt])), 0x03);
c->unuse(*addr);
}
@@ -1279,7 +1277,7 @@ void spu_recompiler::CHD(spu_opcode_t op)
const XmmLink& vr = XmmAlloc();
c->movdqa(vr, XmmConst(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f)));
c->movdqa(SPU_OFF_128(gpr[op.rt]), vr);
c->mov(asmjit::host::word_ptr(*cpu, *addr, 0, OFFSET_OF(SPUThread, gpr[op.rt])), 0x0203);
c->mov(asmjit::host::word_ptr(*cpu, *addr, 0, OFFSET_32(SPUThread, gpr[op.rt])), 0x0203);
c->unuse(*addr);
}
@@ -1304,7 +1302,7 @@ void spu_recompiler::CWD(spu_opcode_t op)
const XmmLink& vr = XmmAlloc();
c->movdqa(vr, XmmConst(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f)));
c->movdqa(SPU_OFF_128(gpr[op.rt]), vr);
c->mov(asmjit::host::dword_ptr(*cpu, *addr, 0, OFFSET_OF(SPUThread, gpr[op.rt])), 0x00010203);
c->mov(asmjit::host::dword_ptr(*cpu, *addr, 0, OFFSET_32(SPUThread, gpr[op.rt])), 0x00010203);
c->unuse(*addr);
}
@@ -1330,7 +1328,7 @@ void spu_recompiler::CDD(spu_opcode_t op)
c->movdqa(vr, XmmConst(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f)));
c->movdqa(SPU_OFF_128(gpr[op.rt]), vr);
c->mov(*qw0, asmjit::imm_u(0x0001020304050607));
c->mov(asmjit::host::qword_ptr(*cpu, *addr, 0, OFFSET_OF(SPUThread, gpr[op.rt])), *qw0);
c->mov(asmjit::host::qword_ptr(*cpu, *addr, 0, OFFSET_32(SPUThread, gpr[op.rt])), *qw0);
c->unuse(*addr);
c->unuse(*qw0);
}
+13 -52
View File
@@ -376,10 +376,7 @@ void SPUThread::do_dma_list_cmd(u32 cmd, spu_mfc_arg_t args)
void SPUThread::process_mfc_cmd(u32 cmd)
{
if (rpcs3::config.misc.log.hle_logging.value())
{
LOG_NOTICE(SPU, "DMA %s: cmd=0x%x, lsa=0x%x, ea=0x%llx, tag=0x%x, size=0x%x", get_mfc_cmd_name(cmd), cmd, ch_mfc_args.lsa, ch_mfc_args.ea, ch_mfc_args.tag, ch_mfc_args.size);
}
LOG_TRACE(SPU, "DMA %s: cmd=0x%x, lsa=0x%x, ea=0x%llx, tag=0x%x, size=0x%x", get_mfc_cmd_name(cmd), cmd, ch_mfc_args.lsa, ch_mfc_args.ea, ch_mfc_args.tag, ch_mfc_args.size);
switch (cmd)
{
@@ -576,10 +573,7 @@ void SPUThread::set_interrupt_status(bool enable)
u32 SPUThread::get_ch_count(u32 ch)
{
if (rpcs3::config.misc.log.hle_logging.value())
{
LOG_NOTICE(SPU, "get_ch_count(ch=%d [%s])", ch, ch < 128 ? spu_ch_name[ch] : "???");
}
LOG_TRACE(SPU, "get_ch_count(ch=%d [%s])", ch, ch < 128 ? spu_ch_name[ch] : "???");
switch (ch)
{
@@ -603,10 +597,7 @@ u32 SPUThread::get_ch_count(u32 ch)
u32 SPUThread::get_ch_value(u32 ch)
{
if (rpcs3::config.misc.log.hle_logging.value())
{
LOG_NOTICE(SPU, "get_ch_value(ch=%d [%s])", ch, ch < 128 ? spu_ch_name[ch] : "???");
}
LOG_TRACE(SPU, "get_ch_value(ch=%d [%s])", ch, ch < 128 ? spu_ch_name[ch] : "???");
auto read_channel = [this](spu_channel_t& channel) -> u32
{
@@ -767,10 +758,7 @@ u32 SPUThread::get_ch_value(u32 ch)
void SPUThread::set_ch_value(u32 ch, u32 value)
{
if (rpcs3::config.misc.log.hle_logging.value())
{
LOG_NOTICE(SPU, "set_ch_value(ch=%d [%s], value=0x%x)", ch, ch < 128 ? spu_ch_name[ch] : "???", value);
}
LOG_TRACE(SPU, "set_ch_value(ch=%d [%s], value=0x%x)", ch, ch < 128 ? spu_ch_name[ch] : "???", value);
switch (ch)
{
@@ -826,10 +814,7 @@ void SPUThread::set_ch_value(u32 ch, u32 value)
ch_out_mbox.set_value(data, 0);
if (rpcs3::config.misc.log.hle_logging.value())
{
LOG_NOTICE(SPU, "sys_spu_thread_send_event(spup=%d, data0=0x%x, data1=0x%x)", spup, value & 0x00ffffff, data);
}
LOG_TRACE(SPU, "sys_spu_thread_send_event(spup=%d, data0=0x%x, data1=0x%x)", spup, value & 0x00ffffff, data);
const auto queue = this->spup[spup].lock();
@@ -865,10 +850,7 @@ void SPUThread::set_ch_value(u32 ch, u32 value)
ch_out_mbox.set_value(data, 0);
if (rpcs3::config.misc.log.hle_logging.value())
{
LOG_WARNING(SPU, "sys_spu_thread_throw_event(spup=%d, data0=0x%x, data1=0x%x)", spup, value & 0x00ffffff, data);
}
LOG_TRACE(SPU, "sys_spu_thread_throw_event(spup=%d, data0=0x%x, data1=0x%x)", spup, value & 0x00ffffff, data);
const auto queue = this->spup[spup].lock();
@@ -915,10 +897,7 @@ void SPUThread::set_ch_value(u32 ch, u32 value)
throw EXCEPTION("sys_event_flag_set_bit(id=%d, value=0x%x (flag=%d)): Invalid flag", data, value, flag);
}
if (rpcs3::config.misc.log.hle_logging.value())
{
LOG_WARNING(SPU, "sys_event_flag_set_bit(id=%d, value=0x%x (flag=%d))", data, value, flag);
}
LOG_TRACE(SPU, "sys_event_flag_set_bit(id=%d, value=0x%x (flag=%d))", data, value, flag);
const auto eflag = idm::get<lv2_event_flag_t>(data);
@@ -959,10 +938,7 @@ void SPUThread::set_ch_value(u32 ch, u32 value)
throw EXCEPTION("sys_event_flag_set_bit_impatient(id=%d, value=0x%x (flag=%d)): Invalid flag", data, value, flag);
}
if (rpcs3::config.misc.log.hle_logging.value())
{
LOG_WARNING(SPU, "sys_event_flag_set_bit_impatient(id=%d, value=0x%x (flag=%d))", data, value, flag);
}
LOG_TRACE(SPU, "sys_event_flag_set_bit_impatient(id=%d, value=0x%x (flag=%d))", data, value, flag);
const auto eflag = idm::get<lv2_event_flag_t>(data);
@@ -1158,10 +1134,7 @@ void SPUThread::set_ch_value(u32 ch, u32 value)
void SPUThread::stop_and_signal(u32 code)
{
if (rpcs3::config.misc.log.hle_logging.value())
{
LOG_NOTICE(SPU, "stop_and_signal(code=0x%x)", code);
}
LOG_TRACE(SPU, "stop_and_signal(code=0x%x)", code);
if (m_type == CPU_THREAD_RAW_SPU)
{
@@ -1229,10 +1202,7 @@ void SPUThread::stop_and_signal(u32 code)
ch_out_mbox.set_value(spuq, 0);
if (rpcs3::config.misc.log.hle_logging.value())
{
LOG_NOTICE(SPU, "sys_spu_thread_receive_event(spuq=0x%x)", spuq);
}
LOG_TRACE(SPU, "sys_spu_thread_receive_event(spuq=0x%x)", spuq);
const auto group = tg.lock();
@@ -1355,10 +1325,7 @@ void SPUThread::stop_and_signal(u32 code)
ch_out_mbox.set_value(value, 0);
if (rpcs3::config.misc.log.hle_logging.value())
{
LOG_NOTICE(SPU, "sys_spu_thread_group_exit(status=0x%x)", value);
}
LOG_TRACE(SPU, "sys_spu_thread_group_exit(status=0x%x)", value);
const auto group = tg.lock();
@@ -1394,10 +1361,7 @@ void SPUThread::stop_and_signal(u32 code)
throw EXCEPTION("sys_spu_thread_exit(): Out_MBox is empty");
}
if (rpcs3::config.misc.log.hle_logging.value())
{
LOG_NOTICE(SPU, "sys_spu_thread_exit(status=0x%x)", ch_out_mbox.get_value());
}
LOG_TRACE(SPU, "sys_spu_thread_exit(status=0x%x)", ch_out_mbox.get_value());
const auto group = tg.lock();
@@ -1425,10 +1389,7 @@ void SPUThread::stop_and_signal(u32 code)
void SPUThread::halt()
{
if (rpcs3::config.misc.log.hle_logging.value())
{
LOG_NOTICE(SPU, "halt()");
}
LOG_TRACE(SPU, "halt()");
if (m_type == CPU_THREAD_RAW_SPU)
{
+3 -5
View File
@@ -26,11 +26,9 @@ bool vfsFile::Open(const std::string& path, u32 mode)
return m_stream && m_stream->IsOpened();
}
bool vfsFile::Close()
void vfsFile::Close()
{
m_stream.reset();
return true;
}
u64 vfsFile::GetSize() const
@@ -48,9 +46,9 @@ u64 vfsFile::Read(void* dst, u64 size)
return m_stream->Read(dst, size);
}
u64 vfsFile::Seek(s64 offset, fsm mode)
u64 vfsFile::Seek(s64 offset, fs::seek_mode whence)
{
return m_stream->Seek(offset, mode);
return m_stream->Seek(offset, whence);
}
u64 vfsFile::Tell() const
+2 -2
View File
@@ -12,14 +12,14 @@ public:
vfsFile(const std::string& path, u32 mode = fom::read);
virtual bool Open(const std::string& path, u32 mode = fom::read) override;
virtual bool Close() override;
virtual void Close() override;
virtual u64 GetSize() const override;
virtual u64 Write(const void* src, u64 size) override;
virtual u64 Read(void* dst, u64 size) override;
virtual u64 Seek(s64 offset, fsm seek_mode = fsm::begin) override;
virtual u64 Seek(s64 offset, fs::seek_mode whence = fs::seek_set) override;
virtual u64 Tell() const override;
virtual bool IsOpened() const override;
+2 -3
View File
@@ -20,11 +20,10 @@ bool vfsFileBase::Open(const std::string& path, u32 mode)
return true;
}
bool vfsFileBase::Close()
void vfsFileBase::Close()
{
m_path = "";
return vfsStream::Close();
vfsStream::Close();
}
std::string vfsFileBase::GetPath() const
+1 -1
View File
@@ -16,7 +16,7 @@ public:
virtual ~vfsFileBase() override;
virtual bool Open(const std::string& path, u32 mode);
virtual bool Close() override;
virtual void Close() override;
virtual bool IsOpened() const override { return !m_path.empty(); }
std::string GetPath() const;
+1 -1
View File
@@ -20,7 +20,7 @@ bool vfsLocalDir::Open(const std::string& path)
std::string name;
fs::stat_t file_info;
while (m_dir.read(name, file_info))
while (m_dir.read(name, file_info) && name.size())
{
m_entries.emplace_back();
+6 -5
View File
@@ -12,9 +12,10 @@ bool vfsLocalFile::Open(const std::string& path, u32 mode)
return m_file.open(path, mode) && vfsFileBase::Open(path, mode);
}
bool vfsLocalFile::Close()
void vfsLocalFile::Close()
{
return m_file.close() && vfsFileBase::Close();
m_file.close();
vfsFileBase::Close();
}
u64 vfsLocalFile::GetSize() const
@@ -32,14 +33,14 @@ u64 vfsLocalFile::Read(void* dst, u64 size)
return m_file.read(dst, size);
}
u64 vfsLocalFile::Seek(s64 offset, fsm mode)
u64 vfsLocalFile::Seek(s64 offset, fs::seek_mode whence)
{
return m_file.seek(offset, mode);
return m_file.seek(offset, whence);
}
u64 vfsLocalFile::Tell() const
{
return m_file.seek(0, fsm::cur);
return m_file.seek(0, fs::seek_cur);
}
bool vfsLocalFile::IsOpened() const
+2 -2
View File
@@ -11,14 +11,14 @@ public:
vfsLocalFile(vfsDevice* device);
virtual bool Open(const std::string& path, u32 mode = fom::read) override;
virtual bool Close() override;
virtual void Close() override;
virtual u64 GetSize() const override;
virtual u64 Write(const void* src, u64 size) override;
virtual u64 Read(void* dst, u64 size) override;
virtual u64 Seek(s64 offset, fsm seek_mode = fsm::begin) override;
virtual u64 Seek(s64 offset, fs::seek_mode whence = fs::seek_set) override;
virtual u64 Tell() const override;
virtual bool IsOpened() const override;
+2 -3
View File
@@ -9,9 +9,8 @@ struct vfsStream
Close();
}
virtual bool Close()
virtual void Close()
{
return true;
}
virtual u64 GetSize() const = 0;
@@ -30,7 +29,7 @@ struct vfsStream
return Read(&data, count) == count;
}
virtual u64 Seek(s64 offset, fsm seek_mode = fsm::begin) = 0;
virtual u64 Seek(s64 offset, fs::seek_mode whence = fs::seek_set) = 0;
virtual u64 Tell() const = 0;
+6 -6
View File
@@ -31,16 +31,16 @@ public:
virtual u64 Read(void* dst, u64 count) override;
virtual u64 Seek(s64 offset, fsm seek_mode = fsm::begin) override
virtual u64 Seek(s64 offset, fs::seek_mode whence) override
{
switch (seek_mode)
switch (whence)
{
case fsm::begin: return m_pos = offset;
case fsm::cur: return m_pos += offset;
case fsm::end: return m_pos = m_size + offset;
case fs::seek_set: return m_pos = offset;
case fs::seek_cur: return m_pos += offset;
case fs::seek_end: return m_pos = m_size + offset;
}
throw EXCEPTION("Unknown seek_mode (0x%x)", seek_mode);
throw EXCEPTION("Unknown seek_mode (0x%x)", whence);
}
virtual u64 Tell() const override
+7 -7
View File
@@ -787,16 +787,16 @@ u64 vfsHDD::Read(void* dst, u64 size)
return m_file.Read(dst, size); // ???
}
u64 vfsHDD::Seek(s64 offset, fsm seek_mode)
u64 vfsHDD::Seek(s64 offset, fs::seek_mode whence)
{
switch (seek_mode)
switch (whence)
{
case fsm::begin: return m_file.Seek(offset);
case fsm::cur: return m_file.Seek(Tell() + offset);
case fsm::end: return m_file.Seek(m_file.GetSize() + offset);
case fs::seek_set: return m_file.Seek(offset);
case fs::seek_cur: return m_file.Seek(Tell() + offset);
case fs::seek_end: return m_file.Seek(m_file.GetSize() + offset);
}
throw EXCEPTION("Unknown seek_mode(0x%x)", seek_mode);
throw EXCEPTION("Unknown whence (0x%x)", whence);
}
u64 vfsHDD::Tell() const
@@ -817,4 +817,4 @@ bool vfsHDD::IsOpened() const
u64 vfsHDD::GetSize() const
{
return m_file.GetSize();
}
}
+1 -1
View File
@@ -196,7 +196,7 @@ public:
virtual u64 Read(void* dst, u64 count) override;
virtual u64 Seek(s64 offset, fsm seek_mode = fsm::begin) override;
virtual u64 Seek(s64 offset, fs::seek_mode whence = fs::seek_set) override;
virtual u64 Tell() const override;
+2 -6
View File
@@ -15,7 +15,6 @@
#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
@@ -239,13 +238,10 @@ namespace vm
catch (...)
{
// capture any exception possibly thrown by predicate
pred = [exception = std::current_exception()]
pred = [exception = std::current_exception()]() -> bool
{
// new predicate will throw the captured exception from the original thread
std::rethrow_exception(exception);
// dummy return value, remove when std::rethrow_exception gains [[noreturn]] attribute in MSVC
return true;
};
}
@@ -811,7 +807,7 @@ namespace vm
{
if (used > this->size)
{
throw EXCEPTION("Unexpected memory amount used (0x%x)", used);
//throw EXCEPTION("Unexpected memory amount used (0x%x)", used);
}
if (used + size > this->size)
+1 -1
View File
@@ -213,7 +213,7 @@ namespace vm
// Convert pointer-to-member to a vm address compatible offset
template<typename MT, typename T> inline u32 get_offset(MT T::*const member_ptr)
{
return static_cast<u32>(reinterpret_cast<std::uintptr_t>(&(reinterpret_cast<T*>(0ull)->*member_ptr)));
return static_cast<u32>(reinterpret_cast<std::uintptr_t>(&reinterpret_cast<char const volatile&>(reinterpret_cast<T*>(0ull)->*member_ptr)));
}
template<typename T> struct cast_ptr
+16 -16
View File
@@ -46,7 +46,7 @@ namespace vm
// get vm pointer to a struct member with array subscription
template<typename MT, typename T2, typename ET = std::remove_extent_t<MT>, typename = if_comparable_t<T, T2>> _ptr_base<ET> ptr(MT T2::*const mptr, u32 index) const
{
return{ VM_CAST(m_addr) + get_offset(mptr) + sizeof32(ET) * index, vm::addr };
return{ VM_CAST(m_addr) + get_offset(mptr) + SIZE_32(ET) * index, vm::addr };
}
// get vm reference to a struct member
@@ -58,7 +58,7 @@ namespace vm
// get vm reference to a struct member with array subscription
template<typename MT, typename T2, typename ET = std::remove_extent_t<MT>, typename = if_comparable_t<T, T2>> _ref_base<ET> ref(MT T2::*const mptr, u32 index) const
{
return{ VM_CAST(m_addr) + get_offset(mptr) + sizeof32(ET) * index, vm::addr };
return{ VM_CAST(m_addr) + get_offset(mptr) + SIZE_32(ET) * index, vm::addr };
}
// get vm reference
@@ -98,7 +98,7 @@ namespace vm
{
static_assert(!std::is_void<T>::value, "vm::_ptr_base<> error: operator[] is not available for void pointers");
return *static_cast<T*>(vm::base(VM_CAST(m_addr) + sizeof32(T) * index));
return *static_cast<T*>(vm::base(VM_CAST(m_addr) + SIZE_32(T) * index));
}
// enable only the conversions which are originally possible between pointer types
@@ -128,7 +128,7 @@ namespace vm
{
static_assert(!std::is_void<T>::value, "vm::_ptr_base<> error: aligned() is not available for void pointers");
return aligned(alignof32(T));
return aligned(ALIGN_32(T));
}
// Test address for arbitrary alignment: (addr & (align - 1)) != 0
@@ -143,7 +143,7 @@ namespace vm
static_assert(!std::is_void<T>::value, "vm::_ptr_base<> error: operator++ is not available for void pointers");
const addr_type result = m_addr;
m_addr = VM_CAST(m_addr) + sizeof32(T);
m_addr = VM_CAST(m_addr) + SIZE_32(T);
return{ result, vm::addr };
}
@@ -152,7 +152,7 @@ namespace vm
{
static_assert(!std::is_void<T>::value, "vm::_ptr_base<> error: operator++ is not available for void pointers");
m_addr = VM_CAST(m_addr) + sizeof32(T);
m_addr = VM_CAST(m_addr) + SIZE_32(T);
return *this;
}
@@ -162,7 +162,7 @@ namespace vm
static_assert(!std::is_void<T>::value, "vm::_ptr_base<> error: operator-- is not available for void pointers");
const addr_type result = m_addr;
m_addr = VM_CAST(m_addr) - sizeof32(T);
m_addr = VM_CAST(m_addr) - SIZE_32(T);
return{ result, vm::addr };
}
@@ -171,7 +171,7 @@ namespace vm
{
static_assert(!std::is_void<T>::value, "vm::_ptr_base<> error: operator-- is not available for void pointers");
m_addr = VM_CAST(m_addr) - sizeof32(T);
m_addr = VM_CAST(m_addr) - SIZE_32(T);
return *this;
}
@@ -179,7 +179,7 @@ namespace vm
{
static_assert(!std::is_void<T>::value, "vm::_ptr_base<> error: operator+= is not available for void pointers");
m_addr = VM_CAST(m_addr) + count * sizeof32(T);
m_addr = VM_CAST(m_addr) + count * SIZE_32(T);
return *this;
}
@@ -187,7 +187,7 @@ namespace vm
{
static_assert(!std::is_void<T>::value, "vm::_ptr_base<> error: operator-= is not available for void pointers");
m_addr = VM_CAST(m_addr) - count * sizeof32(T);
m_addr = VM_CAST(m_addr) - count * SIZE_32(T);
return *this;
}
};
@@ -350,13 +350,13 @@ namespace vm
// Call wait_op() for specified vm pointer
template<typename T, typename AT, typename F, typename... Args> inline auto wait_op(named_thread_t& thread, const _ptr_base<T, AT>& ptr, F pred, Args&&... args) -> decltype(static_cast<void>(pred(args...)))
{
return wait_op(thread, ptr.addr(), sizeof32(T), std::move(pred), std::forward<Args>(args)...);
return wait_op(thread, ptr.addr(), SIZE_32(T), std::move(pred), std::forward<Args>(args)...);
}
// Call notify_at() for specified vm pointer
template<typename T, typename AT> inline void notify_at(const vm::_ptr_base<T, AT>& ptr)
{
return notify_at(ptr.addr(), sizeof32(T));
return notify_at(ptr.addr(), SIZE_32(T));
}
}
@@ -375,19 +375,19 @@ template<typename T, typename AT> inline std::enable_if_t<std::is_object<T>::val
// addition operator for vm::_ptr_base (pointer + integer)
template<typename T, typename AT> inline std::enable_if_t<std::is_object<T>::value, vm::_ptr_base<T>> operator +(const vm::_ptr_base<T, AT>& ptr, u32 count)
{
return{ VM_CAST(ptr.addr()) + count * sizeof32(T), vm::addr };
return{ VM_CAST(ptr.addr()) + count * SIZE_32(T), vm::addr };
}
// addition operator for vm::_ptr_base (integer + pointer)
template<typename T, typename AT> inline std::enable_if_t<std::is_object<T>::value, vm::_ptr_base<T>> operator +(u32 count, const vm::_ptr_base<T, AT>& ptr)
{
return{ VM_CAST(ptr.addr()) + count * sizeof32(T), vm::addr };
return{ VM_CAST(ptr.addr()) + count * SIZE_32(T), vm::addr };
}
// subtraction operator for vm::_ptr_base (pointer - integer)
template<typename T, typename AT> inline std::enable_if_t<std::is_object<T>::value, vm::_ptr_base<T>> operator -(const vm::_ptr_base<T, AT>& ptr, u32 count)
{
return{ VM_CAST(ptr.addr()) - count * sizeof32(T), vm::addr };
return{ VM_CAST(ptr.addr()) - count * SIZE_32(T), vm::addr };
}
// pointer difference operator for vm::_ptr_base
@@ -397,7 +397,7 @@ template<typename T1, typename AT1, typename T2, typename AT2> inline std::enabl
std::is_same<std::remove_cv_t<T1>, std::remove_cv_t<T2>>::value,
s32> operator -(const vm::_ptr_base<T1, AT1>& left, const vm::_ptr_base<T2, AT2>& right)
{
return static_cast<s32>(VM_CAST(left.addr()) - VM_CAST(right.addr())) / sizeof32(T1);
return static_cast<s32>(VM_CAST(left.addr()) - VM_CAST(right.addr())) / SIZE_32(T1);
}
// comparison operator for vm::_ptr_base (pointer1 == pointer2)
+8 -8
View File
@@ -103,7 +103,7 @@ namespace vm
public:
// Call the constructor with specified arguments
template<typename... Args, typename = std::enable_if_t<std::is_constructible<T, Args...>::value>> _var_base(Args&&... args)
: pointer(A::alloc(sizeof32(T), alignof32(T)), vm::addr)
: pointer(A::alloc(SIZE_32(T), ALIGN_32(T)), vm::addr)
{
#include "restore_new.h"
new(pointer::get_ptr()) T(std::forward<Args>(args)...);
@@ -118,7 +118,7 @@ namespace vm
pointer::get_ptr()->~T();
// Deallocate memory
A::dealloc(pointer::addr(), sizeof32(T));
A::dealloc(pointer::addr(), SIZE_32(T));
}
// Remove operator []
@@ -135,7 +135,7 @@ namespace vm
public:
// Call the default constructor for each element
_var_base(u32 count)
: pointer(A::alloc(sizeof32(T) * count, alignof32(T)), vm::addr)
: pointer(A::alloc(SIZE_32(T) * count, ALIGN_32(T)), vm::addr)
, m_count(count)
{
#include "restore_new.h"
@@ -145,7 +145,7 @@ namespace vm
// Call the constructor for each element using [it, it + count)
template<typename T2> _var_base(u32 count, T2 it)
: pointer(A::alloc(sizeof32(T) * count, alignof32(T)), vm::addr)
: pointer(A::alloc(SIZE_32(T) * count, ALIGN_32(T)), vm::addr)
, m_count(count)
{
#include "restore_new.h"
@@ -161,7 +161,7 @@ namespace vm
for (u32 i = m_count - 1; ~i; i--) pointer::operator [](i).~T();
// Deallocate memory
A::dealloc(pointer::addr(), sizeof32(T) * m_count);
A::dealloc(pointer::addr(), SIZE_32(T) * m_count);
}
u32 get_count() const
@@ -188,7 +188,7 @@ namespace vm
public:
// Call the default constructor for each element
_var_base()
: pointer(A::alloc(sizeof32(T) * N, alignof32(T)), vm::addr)
: pointer(A::alloc(SIZE_32(T) * N, ALIGN_32(T)), vm::addr)
{
#include "restore_new.h"
new(pointer::get_ptr()) T[N]();
@@ -197,7 +197,7 @@ namespace vm
// Call the constructor for each element using array
template<typename T2> _var_base(const T2(&array)[N])
: pointer(A::alloc(sizeof32(T) * N, alignof32(T)), vm::addr)
: pointer(A::alloc(SIZE_32(T) * N, ALIGN_32(T)), vm::addr)
{
#include "restore_new.h"
for (u32 i = 0; i < N; i++) new(pointer::get_ptr() + i) T(array[i]);
@@ -212,7 +212,7 @@ namespace vm
for (u32 i = N - 1; ~i; i--) pointer::operator [](i).~T();
// Deallocate memory
A::dealloc(pointer::addr(), sizeof32(T) * N);
A::dealloc(pointer::addr(), SIZE_32(T) * N);
}
constexpr u32 get_count() const
+8 -4
View File
@@ -309,7 +309,7 @@ public:
m_arb_shader += fmt::format("#%d ", i) + param_type + param_name + param_semantic + param_const + "\n";
offset += sizeof32(CgBinaryParameter);
offset += SIZE_32(CgBinaryParameter);
}
m_arb_shader += "\n";
@@ -334,7 +334,9 @@ public:
u32 size;
u32 ctrl = (vmfprog.outputFromH0 ? 0 : 0x40) | (vmfprog.depthReplace ? 0xe : 0);
std::vector<texture_dimension> td;
GLFragmentDecompilerThread(m_glsl_shader, param_array, ptr + vmprog.ucode, size, ctrl, td).Task();
RSXFragmentProgram prog;
prog.size = 0, prog.addr = ptr + vmprog.ucode, prog.offset = 0, prog.ctrl = ctrl;
GLFragmentDecompilerThread(m_glsl_shader, param_array, prog, size).Task();
vm::close();
}
}
@@ -364,7 +366,7 @@ public:
m_arb_shader += fmt::format("#%d ", i) + param_type + param_name + param_semantic + param_const + "\n";
offset += sizeof32(CgBinaryParameter);
offset += SIZE_32(CgBinaryParameter);
}
m_arb_shader += "\n";
@@ -383,7 +385,9 @@ public:
}
TaskVP();
GLVertexDecompilerThread(m_data, m_glsl_shader, param_array).Task();
RSXVertexProgram prog;
prog.data = m_data;
GLVertexDecompilerThread(prog, m_glsl_shader, param_array).Task();
}
}
+2 -2
View File
@@ -60,7 +60,7 @@ std::string CgBinaryDisasm::GetDSTDisasm(bool isSca)
default:
if (d3.dst > 15)
LOG_ERROR(RSX, fmt::format("dst index out of range: %u", d3.dst));
LOG_ERROR(RSX, "dst index out of range: %u", d3.dst);
ret += fmt::format("o[%d]", d3.dst) + GetVecMaskDisasm();
break;
@@ -94,7 +94,7 @@ std::string CgBinaryDisasm::GetSRCDisasm(const u32 n)
break;
default:
LOG_ERROR(RSX, fmt::format("Bad src%u reg type: %d", n, u32{ src[n].reg_type }));
LOG_ERROR(RSX, "Bad src%u reg type: %d", n, u32{ src[n].reg_type });
Emu.Pause();
break;
}
+267 -135
View File
@@ -5,6 +5,29 @@
#define MIN2(x, y) ((x) < (y)) ? (x) : (y)
#define MAX2(x, y) ((x) > (y)) ? (x) : (y)
namespace
{
/**
* Convert CMP vector to RGBA16.
* A vector in CMP (compressed) format is stored as X11Y11Z10 and has a W component of 1.
* X11 and Y11 channels are int between -1024 and 1023 interpreted as -1.f, 1.f
* Z10 is int between -512 and 511 interpreted as -1.f, 1.f
*/
std::array<u16, 4> decode_cmp_vector(u32 encoded_vector)
{
u16 Z = encoded_vector >> 22;
Z = Z << 6;
u16 Y = (encoded_vector >> 11) & 0x7FF;
Y = Y << 5;
u16 X = encoded_vector & 0x7FF;
X = X << 5;
return{ X, Y, Z, 1 };
}
}
// FIXME: these functions shouldn't access rsx::method_registers (global)
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.size > 0);
@@ -15,8 +38,7 @@ void write_vertex_array_data_to_buffer(void *buffer, u32 first, u32 count, size_
u32 offset = rsx::method_registers[NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + index];
u32 address = rsx::get_address(offset & 0x7fffffff, offset >> 31);
u32 type_size = rsx::get_vertex_type_size(vertex_array_desc.type);
u32 element_size = type_size * vertex_array_desc.size;
u32 element_size = rsx::get_vertex_type_size_on_host(vertex_array_desc.type, vertex_array_desc.size);
u32 base_offset = rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_OFFSET];
u32 base_index = rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_INDEX];
@@ -26,13 +48,14 @@ void write_vertex_array_data_to_buffer(void *buffer, u32 first, u32 count, size_
auto src = vm::ps3::_ptr<const u8>(address + base_offset + vertex_array_desc.stride * (first + i + base_index));
u8* dst = (u8*)buffer + i * element_size;
switch (type_size)
switch (vertex_array_desc.type)
{
case 1:
case Vertex_base_type::ub:
memcpy(dst, src, vertex_array_desc.size);
break;
case 2:
case Vertex_base_type::s1:
case Vertex_base_type::sf:
{
auto* c_src = (const be_t<u16>*)src;
u16* c_dst = (u16*)dst;
@@ -41,10 +64,14 @@ void write_vertex_array_data_to_buffer(void *buffer, u32 first, u32 count, size_
{
*c_dst++ = *c_src++;
}
if (vertex_array_desc.size * sizeof(u16) < element_size)
*c_dst++ = 0x3800;
break;
}
case 4:
case Vertex_base_type::f:
case Vertex_base_type::s32k:
case Vertex_base_type::ub256:
{
auto* c_src = (const be_t<u32>*)src;
u32* c_dst = (u32*)dst;
@@ -55,137 +82,186 @@ void write_vertex_array_data_to_buffer(void *buffer, u32 first, u32 count, size_
}
break;
}
case Vertex_base_type::cmp:
{
auto* c_src = (const be_t<u32>*)src;
const auto& decoded_vector = decode_cmp_vector(*c_src);
u16* c_dst = (u16*)dst;
c_dst[0] = decoded_vector[0];
c_dst[1] = decoded_vector[1];
c_dst[2] = decoded_vector[2];
c_dst[3] = decoded_vector[3];
break;
}
}
}
}
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)
template<typename T>
std::tuple<T, T> upload_untouched(gsl::span<to_be_t<const T>> src, gsl::span<T> dst, bool is_primitive_restart_enabled, T primitive_restart_index)
{
for (u32 i = 0; i < indexCount; ++i)
T min_index = -1;
T max_index = 0;
Expects(dst.size_bytes() >= src.size_bytes());
size_t dst_idx = 0;
for (T index : src)
{
IndexType index = vm::ps3::_ref<IndexType>(address + i * sizeof(IndexType));
if (is_primitive_restart_enabled && index == (IndexType)primitive_restart_index)
index = (IndexType)-1;
(IndexType&)dst[i * sizeof(IndexType)] = index;
if (is_primitive_restart_enabled && index == (IndexType)-1) // Cut
continue;
max_index = MAX2(max_index, index);
min_index = MIN2(min_index, index);
if (is_primitive_restart_enabled && index == primitive_restart_index)
{
index = -1;
}
else
{
max_index = MAX2(max_index, index);
min_index = MIN2(min_index, index);
}
dst[dst_idx++] = index;
}
return std::make_tuple(min_index, max_index);
}
// 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)
template<typename T>
std::tuple<T, T> expand_indexed_triangle_fan(gsl::span<to_be_t<const T>> src, gsl::span<T> dst, bool is_primitive_restart_enabled, T primitive_restart_index)
{
for (unsigned i = 0; i < indexCount - 2; i++)
T min_index = -1;
T max_index = 0;
Expects(dst.size() >= 3 * (src.size() - 2));
const T index0 = src[0];
if (!is_primitive_restart_enabled || index0 != -1) // Cut
{
IndexType index0 = vm::ps3::_ref<IndexType>(address);
if (index0 == (IndexType)primitive_restart_index)
index0 = (IndexType)-1;
IndexType index1 = vm::ps3::_ref<IndexType>(address + (i + 2 - 1) * sizeof(IndexType));
if (index1 == (IndexType)primitive_restart_index)
index1 = (IndexType)-1;
IndexType index2 = vm::ps3::_ref<IndexType>(address + (i + 2) * sizeof(IndexType));
if (index2 == (IndexType)primitive_restart_index)
index2 = (IndexType)-1;
min_index = MIN2(min_index, index0);
max_index = MAX2(max_index, index0);
}
(IndexType&)dst[(3 * i) * sizeof(IndexType)] = index0;
(IndexType&)dst[(3 * i + 1) * sizeof(IndexType)] = index1;
(IndexType&)dst[(3 * i + 2) * sizeof(IndexType)] = index2;
if (!is_primitive_restart_enabled || index0 != (IndexType)-1) // Cut
size_t dst_idx = 0;
while (src.size() > 2)
{
gsl::span<to_be_t<const T>> tri_indexes = src.subspan(0, 2);
T index1 = tri_indexes[0];
if (is_primitive_restart_enabled && index1 == primitive_restart_index)
{
min_index = MIN2(min_index, index0);
max_index = MAX2(max_index, index0);
index1 = -1;
}
if (!is_primitive_restart_enabled || index1 != (IndexType)-1) // Cut
else
{
min_index = MIN2(min_index, index1);
max_index = MAX2(max_index, index1);
}
if (!is_primitive_restart_enabled || index2 != (IndexType)-1) // Cut
T index2 = tri_indexes[1];
if (is_primitive_restart_enabled && index2 == primitive_restart_index)
{
index2 = -1;
}
else
{
min_index = MIN2(min_index, index2);
max_index = MAX2(max_index, index2);
}
dst[dst_idx++] = index0;
dst[dst_idx++] = index1;
dst[dst_idx++] = index2;
src = src.subspan(2);
}
return std::make_tuple(min_index, max_index);
}
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)
// FIXME: expanded primitive type may not support primitive restart correctly
template<typename T>
std::tuple<T, T> expand_indexed_quads(gsl::span<to_be_t<const T>> src, gsl::span<T> dst, bool is_primitive_restart_enabled, T primitive_restart_index)
{
for (unsigned i = 0; i < indexCount / 4; i++)
T min_index = -1;
T max_index = 0;
Expects(4 * dst.size_bytes() >= 6 * src.size_bytes());
size_t dst_idx = 0;
while (!src.empty())
{
IndexType index0 = vm::ps3::_ref<IndexType>(address + 4 * i * sizeof(IndexType));
if (is_primitive_restart_enabled && index0 == (IndexType)primitive_restart_index)
index0 = (IndexType)-1;
IndexType index1 = vm::ps3::_ref<IndexType>(address + (4 * i + 1) * sizeof(IndexType));
if (is_primitive_restart_enabled && index1 == (IndexType)primitive_restart_index)
index1 = (IndexType)-1;
IndexType index2 = vm::ps3::_ref<IndexType>(address + (4 * i + 2) * sizeof(IndexType));
if (is_primitive_restart_enabled && index2 == (IndexType)primitive_restart_index)
index2 = (IndexType)-1;
IndexType index3 = vm::ps3::_ref<IndexType>(address + (4 * i + 3) * sizeof(IndexType));
if (is_primitive_restart_enabled &&index3 == (IndexType)primitive_restart_index)
index3 = (IndexType)-1;
// First triangle
(IndexType&)dst[(6 * i) * sizeof(IndexType)] = index0;
(IndexType&)dst[(6 * i + 1) * sizeof(IndexType)] = index1;
(IndexType&)dst[(6 * i + 2) * sizeof(IndexType)] = index2;
// Second triangle
(IndexType&)dst[(6 * i + 3) * sizeof(IndexType)] = index2;
(IndexType&)dst[(6 * i + 4) * sizeof(IndexType)] = index3;
(IndexType&)dst[(6 * i + 5) * sizeof(IndexType)] = index0;
if (!is_primitive_restart_enabled || index0 != (IndexType)-1) // Cut
gsl::span<to_be_t<const T>> quad_indexes = src.subspan(0, 4);
T index0 = quad_indexes[0];
if (is_primitive_restart_enabled && index0 == primitive_restart_index)
{
index0 = -1;
}
else
{
min_index = MIN2(min_index, index0);
max_index = MAX2(max_index, index0);
}
if (!is_primitive_restart_enabled || index1 != (IndexType)-1) // Cut
T index1 = quad_indexes[1];
if (is_primitive_restart_enabled && index1 == primitive_restart_index)
{
index1 = -1;
}
else
{
min_index = MIN2(min_index, index1);
max_index = MAX2(max_index, index1);
}
if (!is_primitive_restart_enabled || index2 != (IndexType)-1) // Cut
T index2 = quad_indexes[2];
if (is_primitive_restart_enabled && index2 == primitive_restart_index)
{
index2 = -1;
}
else
{
min_index = MIN2(min_index, index2);
max_index = MAX2(max_index, index2);
}
if (!is_primitive_restart_enabled || index3 != (IndexType)-1) // Cut
T index3 = quad_indexes[3];
if (is_primitive_restart_enabled &&index3 == primitive_restart_index)
{
index3 = -1;
}
else
{
min_index = MIN2(min_index, index3);
max_index = MAX2(max_index, index3);
}
// First triangle
dst[dst_idx++] = index0;
dst[dst_idx++] = index1;
dst[dst_idx++] = index2;
// Second triangle
dst[dst_idx++] = index2;
dst[dst_idx++] = index3;
dst[dst_idx++] = index0;
src = src.subspan(4);
}
return std::make_tuple(min_index, max_index);
}
}
// Only handle quads and triangle fan now
bool is_primitive_native(unsigned m_draw_mode)
bool is_primitive_native(Primitive_type m_draw_mode)
{
switch (m_draw_mode)
{
default:
case CELL_GCM_PRIMITIVE_POINTS:
case CELL_GCM_PRIMITIVE_LINES:
case CELL_GCM_PRIMITIVE_LINE_LOOP:
case CELL_GCM_PRIMITIVE_LINE_STRIP:
case CELL_GCM_PRIMITIVE_TRIANGLES:
case CELL_GCM_PRIMITIVE_TRIANGLE_STRIP:
case CELL_GCM_PRIMITIVE_QUAD_STRIP:
case Primitive_type::points:
case Primitive_type::lines:
case Primitive_type::line_loop:
case Primitive_type::line_strip:
case Primitive_type::triangles:
case Primitive_type::triangle_strip:
case Primitive_type::quad_strip:
return true;
case CELL_GCM_PRIMITIVE_POLYGON:
case CELL_GCM_PRIMITIVE_TRIANGLE_FAN:
case CELL_GCM_PRIMITIVE_QUADS:
case Primitive_type::polygon:
case Primitive_type::triangle_fan:
case Primitive_type::quads:
return false;
}
throw new EXCEPTION("Wrong primitive type");
}
/** We assume that polygon is convex in polygon mode (constraints in OpenGL)
@@ -193,7 +269,7 @@ bool is_primitive_native(unsigned m_draw_mode)
* 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)
size_t get_index_count(Primitive_type m_draw_mode, unsigned initial_index_count)
{
// Index count
if (is_primitive_native(m_draw_mode))
@@ -201,33 +277,33 @@ size_t get_index_count(unsigned m_draw_mode, unsigned initial_index_count)
switch (m_draw_mode)
{
case CELL_GCM_PRIMITIVE_POLYGON:
case CELL_GCM_PRIMITIVE_TRIANGLE_FAN:
case Primitive_type::polygon:
case Primitive_type::triangle_fan:
return (initial_index_count - 2) * 3;
case CELL_GCM_PRIMITIVE_QUADS:
case Primitive_type::quads:
return (6 * initial_index_count) / 4;
default:
return 0;
}
}
size_t get_index_type_size(u32 type)
size_t get_index_type_size(Index_array_type type)
{
switch (type)
{
case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: return 2;
case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: return 4;
default: return 0;
case Index_array_type::unsigned_16b: return 2;
case Index_array_type::unsigned_32b: return 4;
}
throw new EXCEPTION("Wrong index type");
}
void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst, unsigned draw_mode, unsigned first, unsigned count)
void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst, Primitive_type draw_mode, unsigned first, unsigned count)
{
unsigned short *typedDst = (unsigned short *)(dst);
switch (draw_mode)
{
case CELL_GCM_PRIMITIVE_TRIANGLE_FAN:
case CELL_GCM_PRIMITIVE_POLYGON:
case Primitive_type::triangle_fan:
case Primitive_type::polygon:
for (unsigned i = 0; i < (count - 2); i++)
{
typedDst[3 * i] = first;
@@ -235,7 +311,7 @@ void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst,
typedDst[3 * i + 2] = i + 2;
}
return;
case CELL_GCM_PRIMITIVE_QUADS:
case Primitive_type::quads:
for (unsigned i = 0; i < count / 4; i++)
{
// First triangle
@@ -248,62 +324,118 @@ void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst,
typedDst[6 * i + 5] = 4 * i + first;
}
return;
case Primitive_type::points:
case Primitive_type::lines:
case Primitive_type::line_loop:
case Primitive_type::line_strip:
case Primitive_type::triangles:
case Primitive_type::triangle_strip:
case Primitive_type::quad_strip:
throw new EXCEPTION("Native primitive type doesn't require expansion");
}
}
void write_index_array_data_to_buffer(char* dst, unsigned m_draw_mode, unsigned first, unsigned count, unsigned &min_index, unsigned &max_index)
// TODO: Unify indexed and non indexed primitive expansion ?
template<typename T>
std::tuple<T, T> write_index_array_data_to_buffer_impl(gsl::span<T, gsl::dynamic_range> dst, Primitive_type m_draw_mode, const std::vector<std::pair<u32, u32> > &first_count_arguments)
{
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;
Index_array_type type = to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4);
u32 type_size = type == CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32 ? sizeof(u32) : sizeof(u16);
u32 type_size = gsl::narrow<u32>(get_index_type_size(type));
Expects(rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_OFFSET] == 0);
Expects(rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_INDEX] == 0);
u32 base_offset = rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_OFFSET];
u32 base_index = 0;//rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_INDEX];
bool is_primitive_restart_enabled = !!rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE];
u32 primitive_restart_index = rsx::method_registers[NV4097_SET_RESTART_INDEX];
// Disjoint first_counts ranges not supported atm
for (int i = 0; i < first_count_arguments.size() - 1; i++)
{
const std::tuple<u32, u32> &range = first_count_arguments[i];
const std::tuple<u32, u32> &next_range = first_count_arguments[i + 1];
Expects(std::get<0>(range) + std::get<1>(range) == std::get<0>(next_range));
}
u32 first = std::get<0>(first_count_arguments.front());
u32 count = std::get<0>(first_count_arguments.back()) + std::get<1>(first_count_arguments.back()) - first;
auto ptr = vm::ps3::_ptr<const T>(address + first * type_size);
switch (m_draw_mode)
{
case CELL_GCM_PRIMITIVE_POINTS:
case CELL_GCM_PRIMITIVE_LINES:
case CELL_GCM_PRIMITIVE_LINE_LOOP:
case CELL_GCM_PRIMITIVE_LINE_STRIP:
case CELL_GCM_PRIMITIVE_TRIANGLES:
case CELL_GCM_PRIMITIVE_TRIANGLE_STRIP:
case CELL_GCM_PRIMITIVE_QUAD_STRIP:
case CELL_GCM_PRIMITIVE_POLYGON:
switch (type)
{
case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32:
uploadAsIt<u32>(dst, address + (first + base_index) * sizeof(u32), count, is_primitive_restart_enabled, primitive_restart_index, min_index, max_index);
return;
case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16:
uploadAsIt<u16>(dst, address + (first + base_index) * sizeof(u16), count, is_primitive_restart_enabled, primitive_restart_index, min_index, max_index);
return;
}
return;
case CELL_GCM_PRIMITIVE_TRIANGLE_FAN:
switch (type)
{
case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32:
expandIndexedTriangleFan<u32>(dst, address + (first + base_index) * sizeof(u32), count, is_primitive_restart_enabled, primitive_restart_index, min_index, max_index);
return;
case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16:
expandIndexedTriangleFan<u16>(dst, address + (first + base_index) * sizeof(u16), count, is_primitive_restart_enabled, primitive_restart_index, min_index, max_index);
return;
}
case CELL_GCM_PRIMITIVE_QUADS:
switch (type)
{
case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32:
expandIndexedQuads<u32>(dst, address + (first + base_index) * sizeof(u32), count, is_primitive_restart_enabled, primitive_restart_index, min_index, max_index);
return;
case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16:
expandIndexedQuads<u16>(dst, address + (first + base_index) * sizeof(u16), count, is_primitive_restart_enabled, primitive_restart_index, min_index, max_index);
return;
}
case Primitive_type::points:
case Primitive_type::lines:
case Primitive_type::line_loop:
case Primitive_type::line_strip:
case Primitive_type::triangles:
case Primitive_type::triangle_strip:
case Primitive_type::quad_strip:
return upload_untouched<T>({ ptr, count }, dst, is_primitive_restart_enabled, primitive_restart_index);
case Primitive_type::polygon:
case Primitive_type::triangle_fan:
return expand_indexed_triangle_fan<T>({ ptr, count }, dst, is_primitive_restart_enabled, primitive_restart_index);
case Primitive_type::quads:
return expand_indexed_quads<T>({ ptr, count }, dst, is_primitive_restart_enabled, primitive_restart_index);
}
throw new EXCEPTION("Unknow draw mode");
}
std::tuple<u32, u32> write_index_array_data_to_buffer(gsl::span<u32, gsl::dynamic_range> dst, Primitive_type m_draw_mode, const std::vector<std::pair<u32, u32> > &first_count_arguments)
{
return write_index_array_data_to_buffer_impl(dst, m_draw_mode, first_count_arguments);
}
std::tuple<u16, u16> write_index_array_data_to_buffer(gsl::span<u16, gsl::dynamic_range> dst, Primitive_type m_draw_mode, const std::vector<std::pair<u32, u32> > &first_count_arguments)
{
return write_index_array_data_to_buffer_impl(dst, m_draw_mode, first_count_arguments);
}
std::tuple<u32, u32> write_index_array_data_to_buffer_untouched(gsl::span<u32, gsl::dynamic_range> dst, const std::vector<std::pair<u32, u32> > &first_count_arguments)
{
u32 address = rsx::get_address(rsx::method_registers[NV4097_SET_INDEX_ARRAY_ADDRESS], rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] & 0xf);
Index_array_type type = to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4);
u32 type_size = gsl::narrow<u32>(get_index_type_size(type));
bool is_primitive_restart_enabled = !!rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE];
u32 primitive_restart_index = rsx::method_registers[NV4097_SET_RESTART_INDEX];
// Disjoint first_counts ranges not supported atm
for (int i = 0; i < first_count_arguments.size() - 1; i++)
{
const std::tuple<u32, u32> &range = first_count_arguments[i];
const std::tuple<u32, u32> &next_range = first_count_arguments[i + 1];
Expects(std::get<0>(range) + std::get<1>(range) == std::get<0>(next_range));
}
u32 first = std::get<0>(first_count_arguments.front());
u32 count = std::get<0>(first_count_arguments.back()) + std::get<1>(first_count_arguments.back()) - first;
auto ptr = vm::ps3::_ptr<const u32>(address + first * type_size);
return upload_untouched<u32>({ ptr, count }, dst, is_primitive_restart_enabled, primitive_restart_index);
}
std::tuple<u16, u16> write_index_array_data_to_buffer_untouched(gsl::span<u16, gsl::dynamic_range> dst, const std::vector<std::pair<u32, u32> > &first_count_arguments)
{
u32 address = rsx::get_address(rsx::method_registers[NV4097_SET_INDEX_ARRAY_ADDRESS], rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] & 0xf);
Index_array_type type = to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4);
u32 type_size = gsl::narrow<u32>(get_index_type_size(type));
bool is_primitive_restart_enabled = !!rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE];
u16 primitive_restart_index = rsx::method_registers[NV4097_SET_RESTART_INDEX];
// Disjoint first_counts ranges not supported atm
for (int i = 0; i < first_count_arguments.size() - 1; i++)
{
const std::tuple<u32, u32> &range = first_count_arguments[i];
const std::tuple<u32, u32> &next_range = first_count_arguments[i + 1];
Expects(std::get<0>(range) + std::get<1>(range) == std::get<0>(next_range));
}
u32 first = std::get<0>(first_count_arguments.front());
u32 count = std::get<0>(first_count_arguments.back()) + std::get<1>(first_count_arguments.back()) - first;
auto ptr = vm::ps3::_ptr<const u16>(address + first * type_size);
return upload_untouched<u16>({ ptr, count }, dst, is_primitive_restart_enabled, primitive_restart_index);
}
void stream_vector(void *dst, u32 x, u32 y, u32 z, u32 w)
+13 -15
View File
@@ -3,15 +3,6 @@
#include "Emu/Memory/vm.h"
#include "../RSXThread.h"
struct VertexBufferFormat
{
std::pair<size_t, size_t> range;
std::vector<size_t> attributeId;
size_t elementCount;
size_t stride;
};
/**
* Write count vertex attributes from index array buffer starting at first, using vertex_array_desc
*/
@@ -20,29 +11,36 @@ void write_vertex_array_data_to_buffer(void *buffer, u32 first, u32 count, size_
/*
* 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);
bool is_primitive_native(Primitive_type 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);
size_t get_index_count(Primitive_type m_draw_mode, unsigned initial_index_count);
/**
* Returns index type size in byte
*/
size_t get_index_type_size(u32 type);
size_t get_index_type_size(Index_array_type type);
/**
* Write count indexes starting at first to dst buffer.
* Write count indexes using (first, first + count) ranges.
* 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);
std::tuple<u32, u32> write_index_array_data_to_buffer(gsl::span<u32, gsl::dynamic_range> dst, Primitive_type m_draw_mode, const std::vector<std::pair<u32, u32> > &first_count_arguments);
std::tuple<u16, u16> write_index_array_data_to_buffer(gsl::span<u16, gsl::dynamic_range> dst, Primitive_type m_draw_mode, const std::vector<std::pair<u32, u32> > &first_count_arguments);
/**
* Doesn't expand index
*/
std::tuple<u32, u32> write_index_array_data_to_buffer_untouched(gsl::span<u32, gsl::dynamic_range> dst, const std::vector<std::pair<u32, u32> > &first_count_arguments);
std::tuple<u16, u16> write_index_array_data_to_buffer_untouched(gsl::span<u16, gsl::dynamic_range> dst, const std::vector<std::pair<u32, u32> > &first_count_arguments);
/**
* 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);
void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst, Primitive_type m_draw_mode, unsigned first, unsigned count);
/**
* Stream a 128 bits vector to dst.
@@ -4,13 +4,13 @@
#include "FragmentProgramDecompiler.h"
FragmentProgramDecompiler::FragmentProgramDecompiler(u32 addr, u32& size, u32 ctrl, const std::vector<texture_dimension> &texture_dimensions) :
m_addr(addr),
FragmentProgramDecompiler::FragmentProgramDecompiler(const RSXFragmentProgram &prog, u32& size) :
m_addr(prog.addr),
m_size(size),
m_const_index(0),
m_location(0),
m_ctrl(ctrl),
m_texture_dimensions(texture_dimensions)
m_ctrl(prog.ctrl),
m_texture_dimensions(prog.texture_dimensions)
{
m_size = 0;
}
@@ -114,7 +114,7 @@ std::string FragmentProgramDecompiler::AddConst()
return name;
}
auto data = vm::ps3::ptr<u32>::make(m_addr + m_size + 4 * sizeof32(u32));
auto data = vm::ps3::ptr<u32>::make(m_addr + m_size + 4 * SIZE_32(u32));
m_offset = 2 * 4 * sizeof(u32);
u32 x = GetData(data[0]);
@@ -341,7 +341,9 @@ bool FragmentProgramDecompiler::handle_sct(u32 opcode)
{
case RSX_FP_OPCODE_ADD: SetDst("($0 + $1)"); return true;
case RSX_FP_OPCODE_DIV: SetDst("($0 / $1)"); return true;
case RSX_FP_OPCODE_DIVSQ: SetDst("($0 / sqrt($1).xxxx)"); return true;
// Note: DIVSQ is not IEEE compliant. divsq(0, 0) is 0 (Super Puzzle Fighter II Turbo HD Remix).
// sqrt(x, 0) might be equal to some big value (in absolute) whose sign is sign(x) but it has to be proven.
case RSX_FP_OPCODE_DIVSQ: SetDst("divsq_legacy($0, $1)"); return true;
case RSX_FP_OPCODE_DP2: SetDst(getFunction(FUNCTION::FUNCTION_DP2)); return true;
case RSX_FP_OPCODE_DP3: SetDst(getFunction(FUNCTION::FUNCTION_DP3)); return true;
case RSX_FP_OPCODE_DP4: SetDst(getFunction(FUNCTION::FUNCTION_DP4)); return true;
@@ -351,8 +353,11 @@ bool FragmentProgramDecompiler::handle_sct(u32 opcode)
case RSX_FP_OPCODE_MIN: SetDst("min($0, $1)"); return true;
case RSX_FP_OPCODE_MOV: SetDst("$0"); return true;
case RSX_FP_OPCODE_MUL: SetDst("($0 * $1)"); return true;
case RSX_FP_OPCODE_RCP: SetDst("1.0 / $0"); return true;
case RSX_FP_OPCODE_RSQ: SetDst("1.f / sqrt($0)"); return true;
// Note: It's higly likely that RCP is not IEEE compliant but a game that uses rcp(0) has to be found
case RSX_FP_OPCODE_RCP: SetDst("rcp_legacy($0)"); return true;
// Note: RSQ is not IEEE compliant. rsq(0) is some big number (Silent Hill 3 HD)
// It is not know what happens if 0 is negative.
case RSX_FP_OPCODE_RSQ: SetDst("rsq_legacy($0)"); return true;
case RSX_FP_OPCODE_SEQ: SetDst(getFloatTypeName(4) + "(" + compareFunction(COMPARE::FUNCTION_SEQ, "$0", "$1") + ")"); return true;
case RSX_FP_OPCODE_SFL: SetDst(getFunction(FUNCTION::FUNCTION_SFL)); return true;
case RSX_FP_OPCODE_SGE: SetDst(getFloatTypeName(4) + "(" + compareFunction(COMPARE::FUNCTION_SGE, "$0", "$1") + ")"); return true;
@@ -372,7 +377,9 @@ bool FragmentProgramDecompiler::handle_scb(u32 opcode)
case RSX_FP_OPCODE_ADD: SetDst("($0 + $1)"); return true;
case RSX_FP_OPCODE_COS: SetDst("cos($0.xxxx)"); return true;
case RSX_FP_OPCODE_DIV: SetDst("($0 / $1)"); return true;
case RSX_FP_OPCODE_DIVSQ: SetDst("($0 / sqrt($1).xxxx)"); return true;
// Note: DIVSQ is not IEEE compliant. sqrt(0, 0) is 0 (Super Puzzle Fighter II Turbo HD Remix).
// sqrt(x, 0) might be equal to some big value (in absolute) whose sign is sign(x) but it has to be proven.
case RSX_FP_OPCODE_DIVSQ: SetDst("divsq_legacy($0, sqrt($1).xxxx)"); return true;
case RSX_FP_OPCODE_DP2: SetDst(getFunction(FUNCTION::FUNCTION_DP2)); return true;
case RSX_FP_OPCODE_DP3: SetDst(getFunction(FUNCTION::FUNCTION_DP3)); return true;
case RSX_FP_OPCODE_DP4: SetDst(getFunction(FUNCTION::FUNCTION_DP4)); return true;
@@ -453,7 +460,22 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode)
case RSX_FP_OPCODE_TXPBEM: SetDst("textureProj($t, $0.xyz, $1.x)"); return true;
case RSX_FP_OPCODE_TXD: LOG_ERROR(RSX, "Unimplemented TEX_SRB instruction: TXD"); return true;
case RSX_FP_OPCODE_TXB: SetDst("texture($t, $0.xy, $1.x)"); return true;
case RSX_FP_OPCODE_TXL: SetDst("textureLod($t, $0.xy, $1.x)"); return true;
case RSX_FP_OPCODE_TXL:
if (dst.tex_num >= m_texture_dimensions.size())
{
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE_LOD));
return true;
}
switch (m_texture_dimensions[dst.tex_num])
{
case texture_dimension::texture_dimension_2d:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE_LOD));
return true;
case texture_dimension::texture_dimension_cubemap:
SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE_LOD));
return true;
}
return false;
case RSX_FP_OPCODE_UP2: SetDst("unpackSnorm2x16($0)"); return true; // TODO: More testing (Sonic The Hedgehog (NPUB-30442/NPEB-00478))
case RSX_FP_OPCODE_UP4: SetDst("unpackSnorm4x8($0)"); return true; // TODO: More testing (Sonic The Hedgehog (NPUB-30442/NPEB-00478))
case RSX_FP_OPCODE_UP16: LOG_ERROR(RSX, "Unimplemented TEX_SRB instruction: UP16"); return true;
@@ -113,6 +113,8 @@ protected:
virtual void insertMainEnd(std::stringstream &OS) = 0;
public:
ParamArray m_parr;
FragmentProgramDecompiler(u32 addr, u32& size, u32 ctrl, const std::vector<texture_dimension> &texture_dimensions);
FragmentProgramDecompiler(const RSXFragmentProgram &prog, u32& size);
FragmentProgramDecompiler(const FragmentProgramDecompiler&) = delete;
FragmentProgramDecompiler(FragmentProgramDecompiler&&) = delete;
std::string Decompile();
};
+123
View File
@@ -0,0 +1,123 @@
#include "stdafx.h"
#include "ProgramStateCache.h"
using namespace program_hash_util;
size_t vertex_program_hash::operator()(const std::vector<u32> &program) const
{
// 64-bit Fowler/Noll/Vo FNV-1a hash code
size_t hash = 0xCBF29CE484222325ULL;
const qword *instbuffer = (const qword*)program.data();
size_t instIndex = 0;
bool end = false;
for (unsigned i = 0; i < program.size() / 4; i++)
{
const qword inst = instbuffer[instIndex];
hash ^= inst.dword[0];
hash += (hash << 1) + (hash << 4) + (hash << 5) + (hash << 7) + (hash << 8) + (hash << 40);
hash ^= inst.dword[1];
hash += (hash << 1) + (hash << 4) + (hash << 5) + (hash << 7) + (hash << 8) + (hash << 40);
instIndex++;
}
return hash;
}
bool vertex_program_compare::operator()(const std::vector<u32> &binary1, const std::vector<u32> &binary2) const
{
if (binary1.size() != binary2.size()) return false;
const qword *instBuffer1 = (const qword*)binary1.data();
const qword *instBuffer2 = (const qword*)binary2.data();
size_t instIndex = 0;
for (unsigned i = 0; i < binary1.size() / 4; i++)
{
const qword& inst1 = instBuffer1[instIndex];
const qword& inst2 = instBuffer2[instIndex];
if (inst1.dword[0] != inst2.dword[0] || inst1.dword[1] != inst2.dword[1])
return false;
instIndex++;
}
return true;
}
bool fragment_program_utils::is_constant(u32 sourceOperand)
{
return ((sourceOperand >> 8) & 0x3) == 2;
}
size_t fragment_program_utils::get_fragment_program_ucode_size(void *ptr)
{
const qword *instBuffer = (const qword*)ptr;
size_t instIndex = 0;
while (true)
{
const qword& inst = instBuffer[instIndex];
bool isSRC0Constant = is_constant(inst.word[1]);
bool isSRC1Constant = is_constant(inst.word[2]);
bool isSRC2Constant = is_constant(inst.word[3]);
bool end = (inst.word[0] >> 8) & 0x1;
if (isSRC0Constant || isSRC1Constant || isSRC2Constant)
{
instIndex += 2;
if (end)
return instIndex * 4 * 4;
continue;
}
instIndex++;
if (end)
return (instIndex)* 4 * 4;
}
}
size_t fragment_program_hash::operator()(const void *program) const
{
// 64-bit Fowler/Noll/Vo FNV-1a hash code
size_t hash = 0xCBF29CE484222325ULL;
const qword *instbuffer = (const qword*)program;
size_t instIndex = 0;
while (true)
{
const qword& inst = instbuffer[instIndex];
hash ^= inst.dword[0];
hash += (hash << 1) + (hash << 4) + (hash << 5) + (hash << 7) + (hash << 8) + (hash << 40);
hash ^= inst.dword[1];
hash += (hash << 1) + (hash << 4) + (hash << 5) + (hash << 7) + (hash << 8) + (hash << 40);
instIndex++;
// Skip constants
if (fragment_program_utils::is_constant(inst.word[1]) ||
fragment_program_utils::is_constant(inst.word[2]) ||
fragment_program_utils::is_constant(inst.word[3]))
instIndex++;
bool end = (inst.word[0] >> 8) & 0x1;
if (end)
return hash;
}
return 0;
}
bool fragment_program_compare::operator()(const void *binary1, const void *binary2) const
{
const qword *instBuffer1 = (const qword*)binary1;
const qword *instBuffer2 = (const qword*)binary2;
size_t instIndex = 0;
while (true)
{
const qword& inst1 = instBuffer1[instIndex];
const qword& inst2 = instBuffer2[instIndex];
if (inst1.dword[0] != inst2.dword[0] || inst1.dword[1] != inst2.dword[1])
return false;
instIndex++;
// Skip constants
if (fragment_program_utils::is_constant(inst1.word[1]) ||
fragment_program_utils::is_constant(inst1.word[2]) ||
fragment_program_utils::is_constant(inst1.word[3]))
instIndex++;
bool end = ((inst1.word[0] >> 8) & 0x1) && ((inst2.word[0] >> 8) & 0x1);
if (end)
return true;
}
}
+113 -243
View File
@@ -2,6 +2,7 @@
#include "Emu/RSX/RSXFragmentProgram.h"
#include "Emu/RSX/RSXVertexProgram.h"
#include "Emu/Memory/vm.h"
enum class SHADER_TYPE
@@ -10,7 +11,7 @@ enum class SHADER_TYPE
SHADER_TYPE_FRAGMENT
};
namespace ProgramHashUtil
namespace program_hash_util
{
// Based on
// https://github.com/AlexAltea/nucleus/blob/master/nucleus/gpu/rsx_pgraph.cpp
@@ -20,142 +21,34 @@ namespace ProgramHashUtil
u32 word[4];
};
struct HashVertexProgram
struct vertex_program_hash
{
size_t operator()(const std::vector<u32> &program) const
{
// 64-bit Fowler/Noll/Vo FNV-1a hash code
size_t hash = 0xCBF29CE484222325ULL;
const qword *instbuffer = (const qword*)program.data();
size_t instIndex = 0;
bool end = false;
for (unsigned i = 0; i < program.size() / 4; i++)
{
const qword inst = instbuffer[instIndex];
hash ^= inst.dword[0];
hash += (hash << 1) + (hash << 4) + (hash << 5) + (hash << 7) + (hash << 8) + (hash << 40);
hash ^= inst.dword[1];
hash += (hash << 1) + (hash << 4) + (hash << 5) + (hash << 7) + (hash << 8) + (hash << 40);
instIndex++;
}
return hash;
}
size_t operator()(const std::vector<u32> &program) const;
};
struct VertexProgramCompare
struct vertex_program_compare
{
bool operator()(const std::vector<u32> &binary1, const std::vector<u32> &binary2) const
{
if (binary1.size() != binary2.size()) return false;
const qword *instBuffer1 = (const qword*)binary1.data();
const qword *instBuffer2 = (const qword*)binary2.data();
size_t instIndex = 0;
for (unsigned i = 0; i < binary1.size() / 4; i++)
{
const qword& inst1 = instBuffer1[instIndex];
const qword& inst2 = instBuffer2[instIndex];
if (inst1.dword[0] != inst2.dword[0] || inst1.dword[1] != inst2.dword[1])
return false;
instIndex++;
}
return true;
}
bool operator()(const std::vector<u32> &binary1, const std::vector<u32> &binary2) const;
};
struct FragmentProgramUtil
struct fragment_program_utils
{
/**
* returns true if the given source Operand is a constant
*/
static bool isConstant(u32 sourceOperand)
{
return ((sourceOperand >> 8) & 0x3) == 2;
}
static bool is_constant(u32 sourceOperand);
static
size_t getFPBinarySize(void *ptr)
{
const qword *instBuffer = (const qword*)ptr;
size_t instIndex = 0;
while (true)
{
const qword& inst = instBuffer[instIndex];
bool isSRC0Constant = isConstant(inst.word[1]);
bool isSRC1Constant = isConstant(inst.word[2]);
bool isSRC2Constant = isConstant(inst.word[3]);
bool end = (inst.word[0] >> 8) & 0x1;
if (isSRC0Constant || isSRC1Constant || isSRC2Constant)
{
instIndex += 2;
if (end)
return instIndex * 4 * 4;
continue;
}
instIndex++;
if (end)
return (instIndex)* 4 * 4;
}
}
static size_t get_fragment_program_ucode_size(void *ptr);
};
struct HashFragmentProgram
struct fragment_program_hash
{
size_t operator()(const void *program) const
{
// 64-bit Fowler/Noll/Vo FNV-1a hash code
size_t hash = 0xCBF29CE484222325ULL;
const qword *instbuffer = (const qword*)program;
size_t instIndex = 0;
while (true)
{
const qword& inst = instbuffer[instIndex];
hash ^= inst.dword[0];
hash += (hash << 1) + (hash << 4) + (hash << 5) + (hash << 7) + (hash << 8) + (hash << 40);
hash ^= inst.dword[1];
hash += (hash << 1) + (hash << 4) + (hash << 5) + (hash << 7) + (hash << 8) + (hash << 40);
instIndex++;
// Skip constants
if (FragmentProgramUtil::isConstant(inst.word[1]) ||
FragmentProgramUtil::isConstant(inst.word[2]) ||
FragmentProgramUtil::isConstant(inst.word[3]))
instIndex++;
bool end = (inst.word[0] >> 8) & 0x1;
if (end)
return hash;
}
return 0;
}
size_t operator()(const void *program) const;
};
struct FragmentProgramCompare
struct fragment_program_compare
{
bool operator()(const void *binary1, const void *binary2) const
{
const qword *instBuffer1 = (const qword*)binary1;
const qword *instBuffer2 = (const qword*)binary2;
size_t instIndex = 0;
while (true)
{
const qword& inst1 = instBuffer1[instIndex];
const qword& inst2 = instBuffer2[instIndex];
if (inst1.dword[0] != inst2.dword[0] || inst1.dword[1] != inst2.dword[1])
return false;
instIndex++;
// Skip constants
if (FragmentProgramUtil::isConstant(inst1.word[1]) ||
FragmentProgramUtil::isConstant(inst1.word[2]) ||
FragmentProgramUtil::isConstant(inst1.word[3]))
instIndex++;
bool end = ((inst1.word[0] >> 8) & 0x1) && ((inst2.word[0] >> 8) & 0x1);
if (end)
return true;
}
}
bool operator()(const void *binary1, const void *binary2) const;
};
}
@@ -170,193 +63,170 @@ namespace ProgramHashUtil
* - a typedef PipelineProperties to a type that encapsulate various state info relevant to program compilation (alpha test, primitive type,...)
* - a typedef ExtraData type that will be passed to the buildProgram function.
* It should also contains the following function member :
* - static void RecompileFragmentProgram(RSXFragmentProgram *RSXFP, FragmentProgramData& fragmentProgramData, size_t ID);
* - static void RecompileVertexProgram(RSXVertexProgram *RSXVP, VertexProgramData& vertexProgramData, size_t ID);
* - static PipelineData *BuildProgram(VertexProgramData &vertexProgramData, FragmentProgramData &fragmentProgramData, const PipelineProperties &pipelineProperties, const ExtraData& extraData);
* - void DeleteProgram(PipelineData *ptr);
* - static void recompile_fragment_program(RSXFragmentProgram *RSXFP, FragmentProgramData& fragmentProgramData, size_t ID);
* - static void recompile_vertex_program(RSXVertexProgram *RSXVP, VertexProgramData& vertexProgramData, size_t ID);
* - static PipelineData build_program(VertexProgramData &vertexProgramData, FragmentProgramData &fragmentProgramData, const PipelineProperties &pipelineProperties, const ExtraData& extraData);
*/
template<typename BackendTraits>
class ProgramStateCache
template<typename backend_traits>
class program_state_cache
{
private:
typedef std::unordered_map<std::vector<u32>, typename BackendTraits::VertexProgramData, ProgramHashUtil::HashVertexProgram, ProgramHashUtil::VertexProgramCompare> binary2VS;
typedef std::unordered_map<void *, typename BackendTraits::FragmentProgramData, ProgramHashUtil::HashFragmentProgram, ProgramHashUtil::FragmentProgramCompare> binary2FS;
binary2VS m_cacheVS;
binary2FS m_cacheFS;
using pipeline_storage_type = typename backend_traits::pipeline_storage_type;
using pipeline_properties = typename backend_traits::pipeline_properties;
using vertex_program_type = typename backend_traits::vertex_program_type;
using fragment_program_type = typename backend_traits::fragment_program_type;
size_t m_currentShaderId;
std::vector<size_t> dummyFragmentConstantCache;
using binary_to_vertex_program = std::unordered_map<std::vector<u32>, vertex_program_type, program_hash_util::vertex_program_hash, program_hash_util::vertex_program_compare> ;
using binary_to_fragment_program = std::unordered_map<void *, fragment_program_type, program_hash_util::fragment_program_hash, program_hash_util::fragment_program_compare>;
struct PSOKey
struct pipeline_key
{
u32 vpIdx;
u32 fpIdx;
typename BackendTraits::PipelineProperties properties;
u32 vertex_program_id;
u32 fragment_program_id;
pipeline_properties properties;
};
struct PSOKeyHash
struct pipeline_key_hash
{
size_t operator()(const PSOKey &key) const
size_t operator()(const pipeline_key &key) const
{
size_t hashValue = 0;
hashValue ^= std::hash<unsigned>()(key.vpIdx);
hashValue ^= std::hash<unsigned>()(key.fpIdx);
hashValue ^= std::hash<typename BackendTraits::PipelineProperties>()(key.properties);
hashValue ^= std::hash<unsigned>()(key.vertex_program_id);
hashValue ^= std::hash<unsigned>()(key.fragment_program_id);
hashValue ^= std::hash<pipeline_properties>()(key.properties);
return hashValue;
}
};
struct PSOKeyCompare
struct pipeline_key_compare
{
size_t operator()(const PSOKey &key1, const PSOKey &key2) const
bool operator()(const pipeline_key &key1, const pipeline_key &key2) const
{
return (key1.vpIdx == key2.vpIdx) && (key1.fpIdx == key2.fpIdx) && (key1.properties == key2.properties);
return (key1.vertex_program_id == key2.vertex_program_id) && (key1.fragment_program_id == key2.fragment_program_id) && (key1.properties == key2.properties);
}
};
std::unordered_map<PSOKey, typename BackendTraits::PipelineData*, PSOKeyHash, PSOKeyCompare> m_cachePSO;
private:
size_t m_next_id = 0;
binary_to_vertex_program m_vertex_shader_cache;
binary_to_fragment_program m_fragment_shader_cache;
std::unordered_map <pipeline_key, pipeline_storage_type, pipeline_key_hash, pipeline_key_compare> m_storage;
typename BackendTraits::FragmentProgramData& SearchFp(RSXFragmentProgram* rsx_fp, bool& found)
/// bool here to inform that the program was preexisting.
std::tuple<const vertex_program_type&, bool> search_vertex_program(const RSXVertexProgram& rsx_vp)
{
typename binary2FS::iterator It = m_cacheFS.find(vm::base(rsx_fp->addr));
if (It != m_cacheFS.end())
const auto& I = m_vertex_shader_cache.find(rsx_vp.data);
if (I != m_vertex_shader_cache.end())
{
found = true;
return It->second;
return std::forward_as_tuple(I->second, true);
}
found = false;
LOG_WARNING(RSX, "FP not found in buffer!");
size_t actualFPSize = ProgramHashUtil::FragmentProgramUtil::getFPBinarySize(vm::base(rsx_fp->addr));
void *fpShadowCopy = malloc(actualFPSize);
std::memcpy(fpShadowCopy, vm::base(rsx_fp->addr), actualFPSize);
typename BackendTraits::FragmentProgramData &newShader = m_cacheFS[fpShadowCopy];
BackendTraits::RecompileFragmentProgram(rsx_fp, newShader, m_currentShaderId++);
LOG_NOTICE(RSX, "VP not found in buffer!");
vertex_program_type& new_shader = m_vertex_shader_cache[rsx_vp.data];
backend_traits::recompile_vertex_program(rsx_vp, new_shader, m_next_id++);
return newShader;
return std::forward_as_tuple(new_shader, false);
}
typename BackendTraits::VertexProgramData& SearchVp(RSXVertexProgram* rsx_vp, bool &found)
/// bool here to inform that the program was preexisting.
std::tuple<const fragment_program_type&, bool> search_fragment_program(const RSXFragmentProgram& rsx_fp)
{
typename binary2VS::iterator It = m_cacheVS.find(rsx_vp->data);
if (It != m_cacheVS.end())
const auto& I = m_fragment_shader_cache.find(vm::base(rsx_fp.addr));
if (I != m_fragment_shader_cache.end())
{
found = true;
return It->second;
return std::forward_as_tuple(I->second, true);
}
found = false;
LOG_WARNING(RSX, "VP not found in buffer!");
typename BackendTraits::VertexProgramData& newShader = m_cacheVS[rsx_vp->data];
BackendTraits::RecompileVertexProgram(rsx_vp, newShader, m_currentShaderId++);
LOG_NOTICE(RSX, "FP not found in buffer!");
size_t fragment_program_size = program_hash_util::fragment_program_utils::get_fragment_program_ucode_size(vm::base(rsx_fp.addr));
gsl::not_null<void*> fragment_program_ucode_copy = malloc(fragment_program_size);
std::memcpy(fragment_program_ucode_copy, vm::base(rsx_fp.addr), fragment_program_size);
fragment_program_type &new_shader = m_fragment_shader_cache[fragment_program_ucode_copy];
backend_traits::recompile_fragment_program(rsx_fp, new_shader, m_next_id++);
return newShader;
}
typename BackendTraits::PipelineData *GetProg(const PSOKey &psoKey) const
{
typename std::unordered_map<PSOKey, typename BackendTraits::PipelineData *, PSOKeyHash, PSOKeyCompare>::const_iterator It = m_cachePSO.find(psoKey);
if (It == m_cachePSO.end())
return nullptr;
return It->second;
}
void Add(typename BackendTraits::PipelineData *prog, const PSOKey& PSOKey)
{
m_cachePSO.insert(std::make_pair(PSOKey, prog));
return std::forward_as_tuple(new_shader, false);
}
public:
ProgramStateCache() : m_currentShaderId(0) {}
~ProgramStateCache()
program_state_cache() = default;
~program_state_cache() = default;
const vertex_program_type& get_transform_program(const RSXVertexProgram& rsx_vp) const
{
clear();
auto I = m_vertex_shader_cache.find(rsx_vp.data);
if (I == m_vertex_shader_cache.end())
return I->second;
throw new EXCEPTION("Trying to get unknow transform program");
}
const typename BackendTraits::VertexProgramData* get_transform_program(const RSXVertexProgram& rsx_vp) const
const fragment_program_type& get_shader_program(const RSXFragmentProgram& rsx_fp) const
{
typename binary2VS::const_iterator It = m_cacheVS.find(rsx_vp.data);
if (It == m_cacheVS.end())
return nullptr;
return &It->second;
auto I = m_fragment_shader_cache.find(vm::base(rsx_fp.addr));
if (I != m_fragment_shader_cache.end())
return I->second;
throw new EXCEPTION("Trying to get unknow shader program");
}
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())
return nullptr;
return &It->second;
}
void clear()
{
for (auto pair : m_cachePSO)
BackendTraits::DeleteProgram(pair.second);
m_cachePSO.clear();
for (auto pair : m_cacheFS)
free(pair.first);
m_cacheFS.clear();
}
typename BackendTraits::PipelineData *getGraphicPipelineState(
RSXVertexProgram *vertexShader,
RSXFragmentProgram *fragmentShader,
const typename BackendTraits::PipelineProperties &pipelineProperties,
const typename BackendTraits::ExtraData& extraData
template<typename... Args>
pipeline_storage_type& getGraphicPipelineState(
const RSXVertexProgram& vertexShader,
const RSXFragmentProgram& fragmentShader,
const pipeline_properties& pipelineProperties,
Args&& ...args
)
{
typename BackendTraits::PipelineData *result = nullptr;
bool fpFound, vpFound;
typename BackendTraits::VertexProgramData &vertexProg = SearchVp(vertexShader, vpFound);
typename BackendTraits::FragmentProgramData &fragmentProg = SearchFp(fragmentShader, fpFound);
// TODO : use tie and implicit variable declaration syntax with c++17
const auto &vp_search = search_vertex_program(vertexShader);
const auto &fp_search = search_fragment_program(fragmentShader);
const vertex_program_type &vertex_program = std::get<0>(vp_search);
const fragment_program_type &fragment_program = std::get<0>(fp_search);
bool already_existing_fragment_program = std::get<1>(fp_search);
bool already_existing_vertex_program = std::get<1>(vp_search);
if (fpFound && vpFound)
pipeline_key key = { vertex_program.id, fragment_program.id, pipelineProperties };
if (already_existing_fragment_program && already_existing_vertex_program)
{
result = GetProg({ vertexProg.id, fragmentProg.id, pipelineProperties });
const auto I = m_storage.find(key);
if (I != m_storage.end())
return I->second;
}
if (result != nullptr)
return result;
else
{
LOG_WARNING(RSX, "Add program :");
LOG_WARNING(RSX, "*** vp id = %d", vertexProg.id);
LOG_WARNING(RSX, "*** fp id = %d", fragmentProg.id);
LOG_NOTICE(RSX, "Add program :");
LOG_NOTICE(RSX, "*** vp id = %d", vertex_program.id);
LOG_NOTICE(RSX, "*** fp id = %d", fragment_program.id);
result = BackendTraits::BuildProgram(vertexProg, fragmentProg, pipelineProperties, extraData);
Add(result, { vertexProg.id, fragmentProg.id, pipelineProperties });
}
return result;
m_storage[key] = backend_traits::build_pipeline(vertex_program, fragment_program, pipelineProperties, std::forward<Args>(args)...);
return m_storage[key];
}
size_t get_fragment_constants_buffer_size(const RSXFragmentProgram *fragmentShader) const
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())
return It->second.FragmentConstantOffsetCache.size() * 4 * sizeof(float);
const auto I = m_fragment_shader_cache.find(vm::base(fragmentShader.addr));
if (I != m_fragment_shader_cache.end())
return I->second.FragmentConstantOffsetCache.size() * 4 * sizeof(float);
LOG_ERROR(RSX, "Can't retrieve constant offset cache");
return 0;
}
void fill_fragment_constans_buffer(void *buffer, const RSXFragmentProgram *fragment_program) const
void fill_fragment_constans_buffer(gsl::span<f32, gsl::dynamic_range> dst_buffer, const RSXFragmentProgram &fragment_program) const
{
typename binary2FS::const_iterator It = m_cacheFS.find(vm::base(fragment_program->addr));
if (It == m_cacheFS.end())
const auto I = m_fragment_shader_cache.find(vm::base(fragment_program.addr));
if (I == m_fragment_shader_cache.end())
return;
__m128i mask = _mm_set_epi8(0xE, 0xF, 0xC, 0xD,
0xA, 0xB, 0x8, 0x9,
0x6, 0x7, 0x4, 0x5,
0x2, 0x3, 0x0, 0x1);
Expects(dst_buffer.size_bytes() >= gsl::narrow<int>(I->second.FragmentConstantOffsetCache.size()) * 16);
size_t offset = 0;
for (size_t offset_in_fragment_program : It->second.FragmentConstantOffsetCache)
for (size_t offset_in_fragment_program : I->second.FragmentConstantOffsetCache)
{
void *data = vm::base(fragment_program->addr + (u32)offset_in_fragment_program);
void *data = vm::base(fragment_program.addr + (u32)offset_in_fragment_program);
const __m128i &vector = _mm_loadu_si128((__m128i*)data);
const __m128i &shuffled_vector = _mm_shuffle_epi8(vector, mask);
_mm_stream_si128((__m128i*)((char*)buffer + offset), shuffled_vector);
offset += 4 * sizeof(u32);
_mm_stream_si128((__m128i*)dst_buffer.subspan(offset, 4).data(), shuffled_vector);
offset += sizeof(f32);
}
}
};
+2
View File
@@ -15,8 +15,10 @@ enum class FUNCTION {
FUNCTION_DFDY,
FUNCTION_TEXTURE_SAMPLE,
FUNCTION_TEXTURE_SAMPLE_PROJ,
FUNCTION_TEXTURE_SAMPLE_LOD,
FUNCTION_TEXTURE_CUBE_SAMPLE,
FUNCTION_TEXTURE_CUBE_SAMPLE_PROJ,
FUNCTION_TEXTURE_CUBE_SAMPLE_LOD,
};
enum class COMPARE {
@@ -47,7 +47,7 @@ std::string VertexProgramDecompiler::GetDST(bool isSca)
default:
if (d3.dst > 15)
LOG_ERROR(RSX, fmt::format("dst index out of range: %u", d3.dst));
LOG_ERROR(RSX, "dst index out of range: %u", d3.dst);
ret += m_parr.AddParam(PF_PARAM_NONE, getFloatTypeName(4), std::string("dst_reg") + std::to_string(d3.dst), d3.dst == 0 ? getFloatTypeName(4) + "(0.0f, 0.0f, 0.0f, 1.0f)" : getFloatTypeName(4) + "(0.0, 0.0, 0.0, 0.0)");
break;
}
@@ -91,7 +91,7 @@ std::string VertexProgramDecompiler::GetSRC(const u32 n)
break;
default:
LOG_ERROR(RSX, fmt::format("Bad src%u reg type: %d", n, u32{ src[n].reg_type }));
LOG_ERROR(RSX, "Bad src%u reg type: %d", n, u32{ src[n].reg_type });
Emu.Pause();
break;
}
@@ -435,8 +435,8 @@ std::string VertexProgramDecompiler::BuildCode()
return OS.str();
}
VertexProgramDecompiler::VertexProgramDecompiler(std::vector<u32>& data) :
m_data(data)
VertexProgramDecompiler::VertexProgramDecompiler(const RSXVertexProgram& prog) :
m_data(prog.data)
{
m_funcs.emplace_back();
m_funcs[0].offset = 0;
@@ -57,7 +57,7 @@ struct VertexProgramDecompiler
//wxString main;
std::vector<u32>& m_data;
const std::vector<u32>& m_data;
ParamArray m_parr;
std::string GetMask(bool is_sca);
@@ -124,6 +124,6 @@ protected:
*/
virtual void insertMainEnd(std::stringstream &OS) = 0;
public:
VertexProgramDecompiler(std::vector<u32>& data);
VertexProgramDecompiler(const RSXVertexProgram& prog);
std::string Decompile();
};
+65 -110
View File
@@ -8,32 +8,6 @@
#include "D3D12Formats.h"
#include "../rsx_methods.h"
namespace
{
/**
*
*/
D3D12_GPU_VIRTUAL_ADDRESS createVertexBuffer(const rsx::data_array_format_info &vertex_array_desc, const std::vector<u8> &vertex_data, ID3D12Device *device, data_heap<ID3D12Resource, 65536> &vertex_index_heap)
{
size_t buffer_size = vertex_data.size();
assert(vertex_index_heap.can_alloc(buffer_size));
size_t heap_offset = vertex_index_heap.alloc(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));
return vertex_index_heap.m_heap->GetGPUVirtualAddress() + heap_offset;
}
}
void D3D12GSRender::load_vertex_data(u32 first, u32 count)
{
m_first_count_pairs.emplace_back(std::make_pair(first, count));
vertex_draw_count += count;
}
std::vector<D3D12_VERTEX_BUFFER_VIEW> D3D12GSRender::upload_vertex_attributes(const std::vector<std::pair<u32, u32> > &vertex_ranges)
{
@@ -60,26 +34,22 @@ std::vector<D3D12_VERTEX_BUFFER_VIEW> D3D12GSRender::upload_vertex_attributes(co
// Active vertex array
const rsx::data_array_format_info &info = vertex_arrays_info[index];
u32 type_size = rsx::get_vertex_type_size(info.type);
u32 element_size = type_size * info.size;
u32 element_size = rsx::get_vertex_type_size_on_host(info.type, info.size);
size_t buffer_size = element_size * vertex_count;
assert(m_vertex_index_data.can_alloc(buffer_size));
size_t heap_offset = m_vertex_index_data.alloc(buffer_size);
size_t heap_offset = m_buffer_data.alloc<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(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;
void *mapped_buffer = m_buffer_data.map<void>(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
for (const auto &range : vertex_ranges)
{
write_vertex_array_data_to_buffer(mapped_buffer, range.first, range.second, index, info);
mapped_buffer = (char*)mapped_buffer + range.second * element_size;
}
m_vertex_index_data.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
D3D12_VERTEX_BUFFER_VIEW vertex_buffer_view =
{
m_vertex_index_data.m_heap->GetGPUVirtualAddress() + heap_offset,
m_buffer_data.get_heap()->GetGPUVirtualAddress() + heap_offset,
(UINT)buffer_size,
(UINT)element_size
};
@@ -104,21 +74,17 @@ std::vector<D3D12_VERTEX_BUFFER_VIEW> D3D12GSRender::upload_vertex_attributes(co
const std::vector<u8> &data = register_vertex_data[index];
u32 type_size = rsx::get_vertex_type_size(info.type);
u32 element_size = type_size * info.size;
u32 element_size = rsx::get_vertex_type_size_on_host(info.type, info.size);
size_t buffer_size = data.size();
assert(m_vertex_index_data.can_alloc(buffer_size));
size_t heap_offset = m_vertex_index_data.alloc(buffer_size);
size_t heap_offset = m_buffer_data.alloc<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(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;
void *mapped_buffer = m_buffer_data.map<void>(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
memcpy(mapped_buffer, data.data(), data.size());
m_vertex_index_data.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
D3D12_VERTEX_BUFFER_VIEW vertex_buffer_view = {
m_vertex_index_data.m_heap->GetGPUVirtualAddress() + heap_offset,
m_buffer_data.get_heap()->GetGPUVirtualAddress() + heap_offset,
(UINT)buffer_size,
(UINT)element_size
};
@@ -139,24 +105,18 @@ std::vector<D3D12_VERTEX_BUFFER_VIEW> D3D12GSRender::upload_vertex_attributes(co
return vertex_buffer_views;
}
void D3D12GSRender::load_vertex_index_data(u32 first, u32 count)
{
}
void D3D12GSRender::upload_and_bind_scale_offset_matrix(size_t descriptorIndex)
{
assert(m_constants_data.can_alloc(256));
size_t heap_offset = m_constants_data.alloc(256);
size_t heap_offset = m_buffer_data.alloc<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(256);
// Scale offset buffer
// Separate constant buffer
void *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);
void *mapped_buffer = m_buffer_data.map<void>(CD3DX12_RANGE(heap_offset, heap_offset + 256));
fill_scale_offset_data(mapped_buffer);
int is_alpha_tested = !!(rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE]);
float alpha_ref = (float&)rsx::method_registers[NV4097_SET_ALPHA_REF];
memcpy((char*)mapped_buffer + heap_offset + 16 * sizeof(float), &is_alpha_tested, sizeof(int));
memcpy((char*)mapped_buffer + heap_offset + 17 * sizeof(float), &alpha_ref, sizeof(float));
memcpy((char*)mapped_buffer + 16 * sizeof(float), &is_alpha_tested, sizeof(int));
memcpy((char*)mapped_buffer + 17 * sizeof(float), &alpha_ref, sizeof(float));
size_t tex_idx = 0;
for (u32 i = 0; i < rsx::limits::textures_count; ++i)
@@ -164,19 +124,19 @@ void D3D12GSRender::upload_and_bind_scale_offset_matrix(size_t descriptorIndex)
if (!textures[i].enabled())
{
int is_unorm = false;
memcpy((char*)mapped_buffer + heap_offset + (18 + tex_idx++) * sizeof(int), &is_unorm, sizeof(int));
memcpy((char*)mapped_buffer + (18 + tex_idx++) * sizeof(int), &is_unorm, sizeof(int));
continue;
}
size_t w = textures[i].width(), h = textures[i].height();
// if (!w || !h) continue;
int is_unorm = (textures[i].format() & CELL_GCM_TEXTURE_UN);
memcpy((char*)mapped_buffer + heap_offset + (18 + tex_idx++) * sizeof(int), &is_unorm, sizeof(int));
memcpy((char*)mapped_buffer + (18 + tex_idx++) * sizeof(int), &is_unorm, sizeof(int));
}
m_constants_data.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + 256));
m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + 256));
D3D12_CONSTANT_BUFFER_VIEW_DESC constant_buffer_view_desc = {
m_constants_data.m_heap->GetGPUVirtualAddress() + heap_offset,
m_buffer_data.get_heap()->GetGPUVirtualAddress() + heap_offset,
256
};
m_device->CreateConstantBufferView(&constant_buffer_view_desc,
@@ -188,16 +148,14 @@ void D3D12GSRender::upload_and_bind_vertex_shader_constants(size_t descriptor_in
{
size_t buffer_size = 512 * 4 * sizeof(float);
assert(m_constants_data.can_alloc(buffer_size));
size_t heap_offset = m_constants_data.alloc(buffer_size);
size_t heap_offset = m_buffer_data.alloc<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(buffer_size);
void *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));
void *mapped_buffer = m_buffer_data.map<void>(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
fill_vertex_program_constants_data(mapped_buffer);
m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
D3D12_CONSTANT_BUFFER_VIEW_DESC constant_buffer_view_desc = {
m_constants_data.m_heap->GetGPUVirtualAddress() + heap_offset,
m_buffer_data.get_heap()->GetGPUVirtualAddress() + heap_offset,
(UINT)buffer_size
};
m_device->CreateConstantBufferView(&constant_buffer_view_desc,
@@ -208,21 +166,19 @@ void D3D12GSRender::upload_and_bind_vertex_shader_constants(size_t descriptor_in
void D3D12GSRender::upload_and_bind_fragment_shader_constants(size_t descriptor_index)
{
// Get constant from fragment program
size_t buffer_size = m_pso_cache.get_fragment_constants_buffer_size(&fragment_program);
size_t buffer_size = m_pso_cache.get_fragment_constants_buffer_size(fragment_program);
// Multiple of 256 never 0
buffer_size = (buffer_size + 255) & ~255;
assert(m_constants_data.can_alloc(buffer_size));
size_t heap_offset = m_constants_data.alloc(buffer_size);
size_t heap_offset = m_buffer_data.alloc<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(buffer_size);
size_t offset = 0;
void *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));
float *mapped_buffer = m_buffer_data.map<float>(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
m_pso_cache.fill_fragment_constans_buffer({ mapped_buffer, gsl::narrow<int>(buffer_size) }, fragment_program);
m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
D3D12_CONSTANT_BUFFER_VIEW_DESC constant_buffer_view_desc = {
m_constants_data.m_heap->GetGPUVirtualAddress() + heap_offset,
m_buffer_data.get_heap()->GetGPUVirtualAddress() + heap_offset,
(UINT)buffer_size
};
m_device->CreateConstantBufferView(&constant_buffer_view_desc,
@@ -253,22 +209,19 @@ std::tuple<D3D12_VERTEX_BUFFER_VIEW, size_t> D3D12GSRender::upload_inlined_verte
IAElement.InstanceDataStepRate = 0;
m_IASet.push_back(IAElement);
offset += rsx::get_vertex_type_size(info.type) * info.size;
offset += rsx::get_vertex_type_size_on_host(info.type, info.size);
}
// Copy inline buffer
size_t buffer_size = inline_vertex_array.size() * sizeof(int);
assert(m_vertex_index_data.can_alloc(buffer_size));
size_t heap_offset = m_vertex_index_data.alloc(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 heap_offset = m_buffer_data.alloc<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(buffer_size);
void *mapped_buffer = m_buffer_data.map<void>(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
write_inline_array_to_buffer(mapped_buffer);
m_vertex_index_data.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
D3D12_VERTEX_BUFFER_VIEW vertex_buffer_view =
{
m_vertex_index_data.m_heap->GetGPUVirtualAddress() + heap_offset,
m_buffer_data.get_heap()->GetGPUVirtualAddress() + heap_offset,
(UINT)buffer_size,
(UINT)offset
};
@@ -284,12 +237,9 @@ std::tuple<D3D12_INDEX_BUFFER_VIEW, size_t> D3D12GSRender::generate_index_buffer
// Alloc
size_t buffer_size = align(index_count * sizeof(u16), 64);
assert(m_vertex_index_data.can_alloc(buffer_size));
size_t heap_offset = m_vertex_index_data.alloc(buffer_size);
size_t heap_offset = m_buffer_data.alloc<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(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;
void *mapped_buffer = m_buffer_data.map<void>(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
size_t first = 0;
for (const auto &pair : vertex_ranges)
{
@@ -298,9 +248,9 @@ std::tuple<D3D12_INDEX_BUFFER_VIEW, size_t> D3D12GSRender::generate_index_buffer
mapped_buffer = (char*)mapped_buffer + element_count * sizeof(u16);
first += pair.second;
}
m_vertex_index_data.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
D3D12_INDEX_BUFFER_VIEW index_buffer_view = {
m_vertex_index_data.m_heap->GetGPUVirtualAddress() + heap_offset,
m_buffer_data.get_heap()->GetGPUVirtualAddress() + heap_offset,
(UINT)buffer_size,
DXGI_FORMAT_R16_UINT
};
@@ -329,60 +279,65 @@ std::tuple<bool, size_t> D3D12GSRender::upload_and_set_vertex_index_data(ID3D12G
if (draw_command == Draw_command::draw_command_array)
{
const std::vector<D3D12_VERTEX_BUFFER_VIEW> &vertex_buffer_views = upload_vertex_attributes(m_first_count_pairs);
const std::vector<D3D12_VERTEX_BUFFER_VIEW> &vertex_buffer_views = upload_vertex_attributes(first_count_commands);
command_list->IASetVertexBuffers(0, (UINT)vertex_buffer_views.size(), vertex_buffer_views.data());
if (is_primitive_native(draw_mode))
{
// Index count
size_t vertex_count = 0;
for (const auto &pair : m_first_count_pairs)
for (const auto &pair : first_count_commands)
vertex_count += pair.second;
return std::make_tuple(false, vertex_count);
}
D3D12_INDEX_BUFFER_VIEW index_buffer_view;
size_t index_count;
std::tie(index_buffer_view, index_count) = generate_index_buffer_for_emulated_primitives_array(m_first_count_pairs);
std::tie(index_buffer_view, index_count) = generate_index_buffer_for_emulated_primitives_array(first_count_commands);
command_list->IASetIndexBuffer(&index_buffer_view);
return std::make_tuple(true, index_count);
}
assert(draw_command == Draw_command::draw_command_indexed);
u32 indexed_type = rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4;
size_t index_size = get_index_type_size(indexed_type);
// Index count
size_t index_count = 0;
for (const auto &pair : m_first_count_pairs)
index_count += get_index_count(draw_mode, pair.second);
for (const auto &pair : first_count_commands)
index_count += pair.second;
index_count = get_index_count(draw_mode, gsl::narrow<int>(index_count));
Index_array_type indexed_type = to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4);
size_t index_size = get_index_type_size(indexed_type);
// Alloc
size_t buffer_size = align(index_count * index_size, 64);
assert(m_vertex_index_data.can_alloc(buffer_size));
size_t heap_offset = m_vertex_index_data.alloc(buffer_size);
size_t heap_offset = m_buffer_data.alloc<D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT>(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)
void *mapped_buffer = m_buffer_data.map<void>(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
u32 min_index, max_index;
if (indexed_type == Index_array_type::unsigned_16b)
{
size_t element_count = get_index_count(draw_mode, pair.second);
write_index_array_data_to_buffer((char*)mapped_buffer, draw_mode, pair.first, pair.second, min_index, max_index);
mapped_buffer = (char*)mapped_buffer + element_count * index_size;
gsl::span<u16> dst = { (u16*)mapped_buffer, gsl::narrow<int>(buffer_size / index_size) };
std::tie(min_index, max_index) = write_index_array_data_to_buffer(dst, draw_mode, first_count_commands);
}
m_vertex_index_data.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
if (indexed_type == Index_array_type::unsigned_32b)
{
gsl::span<u32> dst = { (u32*)mapped_buffer, gsl::narrow<int>(buffer_size / index_size) };
std::tie(min_index, max_index) = write_index_array_data_to_buffer(dst, draw_mode, first_count_commands);
}
m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
D3D12_INDEX_BUFFER_VIEW index_buffer_view = {
m_vertex_index_data.m_heap->GetGPUVirtualAddress() + heap_offset,
m_buffer_data.get_heap()->GetGPUVirtualAddress() + heap_offset,
(UINT)buffer_size,
get_index_type(indexed_type)
};
m_timers.m_buffer_upload_size += buffer_size;
command_list->IASetIndexBuffer(&index_buffer_view);
const std::vector<D3D12_VERTEX_BUFFER_VIEW> &vertex_buffer_views = upload_vertex_attributes({ std::make_pair(0, max_index + 1) });
const std::vector<D3D12_VERTEX_BUFFER_VIEW> &vertex_buffer_views = upload_vertex_attributes({ std::make_pair(min_index, max_index + 1) });
command_list->IASetVertexBuffers(0, (UINT)vertex_buffer_views.size(), vertex_buffer_views.data());
return std::make_tuple(true, index_count);
@@ -45,11 +45,15 @@ std::string getFunctionImp(FUNCTION f)
case FUNCTION::FUNCTION_TEXTURE_SAMPLE:
return "$t.Sample($tsampler, $0.xy * $t_scale)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE_PROJ:
return "$t.Sample($tsampler, ($0.xy / $0.z) * $t_scale)";
return "$t.Sample($tsampler, ($0.xy / $0.w) * $t_scale)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE_LOD:
return "$t.SampleLevel($tsampler, ($0.xy / $0.w) * $t_scale, $1)";
case FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE:
return "$t.Sample($tsampler, $0.xyz)";
case FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE_PROJ:
return "$t.Sample($tsampler, ($0.xyz / $0.w))";
case FUNCTION::FUNCTION_TEXTURE_CUBE_SAMPLE_LOD:
return "$t.SampleLevel($tsampler, ($0.xyz / $0.w), $1)";
case FUNCTION::FUNCTION_DFDX:
return "ddx($0)";
case FUNCTION::FUNCTION_DFDY:
+70 -63
View File
@@ -40,11 +40,10 @@ D3D12_BLEND get_blend_factor(u16 factor)
case CELL_GCM_SRC_ALPHA_SATURATE: return D3D12_BLEND_SRC_ALPHA_SAT;
case CELL_GCM_CONSTANT_COLOR: return D3D12_BLEND_DEST_COLOR;
case CELL_GCM_ONE_MINUS_CONSTANT_COLOR: return D3D12_BLEND_INV_DEST_COLOR;
case CELL_GCM_CONSTANT_ALPHA:
case CELL_GCM_ONE_MINUS_CONSTANT_ALPHA:
break;
case CELL_GCM_CONSTANT_ALPHA: return D3D12_BLEND_DEST_ALPHA;
case CELL_GCM_ONE_MINUS_CONSTANT_ALPHA: return D3D12_BLEND_INV_DEST_ALPHA;
}
throw EXCEPTION("Invalid or unsupported blend factor (0x%x)", factor);
throw EXCEPTION("Invalid blend factor (0x%x)", factor);
}
D3D12_BLEND get_blend_factor_alpha(u16 factor)
@@ -62,10 +61,10 @@ D3D12_BLEND get_blend_factor_alpha(u16 factor)
case CELL_GCM_DST_COLOR: return D3D12_BLEND_DEST_ALPHA;
case CELL_GCM_ONE_MINUS_DST_COLOR: return D3D12_BLEND_INV_DEST_ALPHA;
case CELL_GCM_SRC_ALPHA_SATURATE: return D3D12_BLEND_SRC_ALPHA_SAT;
case CELL_GCM_CONSTANT_ALPHA: return D3D12_BLEND_DEST_ALPHA;
case CELL_GCM_ONE_MINUS_CONSTANT_ALPHA: return D3D12_BLEND_INV_DEST_ALPHA;
case CELL_GCM_CONSTANT_COLOR:
case CELL_GCM_ONE_MINUS_CONSTANT_COLOR:
case CELL_GCM_CONSTANT_ALPHA:
case CELL_GCM_ONE_MINUS_CONSTANT_ALPHA:
break;
}
throw EXCEPTION("Invalid or unsupported blend alpha factor (0x%x)", factor);
@@ -162,7 +161,7 @@ DXGI_FORMAT get_texture_format(u8 format)
case CELL_GCM_TEXTURE_D8R8G8B8: return DXGI_FORMAT_R8G8B8A8_UNORM;
case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: return DXGI_FORMAT_G8R8_G8B8_UNORM;
case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return DXGI_FORMAT_R8G8_B8G8_UNORM;
case CELL_GCM_TEXTURE_Y16_X16_FLOAT:
case CELL_GCM_TEXTURE_Y16_X16_FLOAT: return DXGI_FORMAT_R16G16_FLOAT;
case CELL_GCM_TEXTURE_COMPRESSED_HILO8:
case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8:
case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8:
@@ -248,6 +247,7 @@ namespace
{
case CELL_GCM_TEXTURE_NEAREST: return D3D12_FILTER_TYPE_POINT;
case CELL_GCM_TEXTURE_LINEAR: return D3D12_FILTER_TYPE_LINEAR;
case CELL_GCM_TEXTURE_CONVOLUTION_MAG: return D3D12_FILTER_TYPE_LINEAR;
}
throw EXCEPTION("Invalid mag filter (0x%x)", mag_filter);
}
@@ -261,92 +261,99 @@ D3D12_FILTER get_texture_filter(u8 min_filter, u8 mag_filter)
return D3D12_ENCODE_BASIC_FILTER(min, mag, mip, D3D12_FILTER_REDUCTION_TYPE_STANDARD);
}
D3D12_PRIMITIVE_TOPOLOGY get_primitive_topology(u8 draw_mode)
D3D12_PRIMITIVE_TOPOLOGY get_primitive_topology(Primitive_type draw_mode)
{
switch (draw_mode)
{
case CELL_GCM_PRIMITIVE_POINTS: return D3D_PRIMITIVE_TOPOLOGY_POINTLIST;
case CELL_GCM_PRIMITIVE_LINES: return D3D_PRIMITIVE_TOPOLOGY_LINELIST;
case CELL_GCM_PRIMITIVE_LINE_LOOP: return D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ;
case CELL_GCM_PRIMITIVE_LINE_STRIP: return D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
case CELL_GCM_PRIMITIVE_TRIANGLES: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
case CELL_GCM_PRIMITIVE_TRIANGLE_STRIP: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
case CELL_GCM_PRIMITIVE_TRIANGLE_FAN: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
case CELL_GCM_PRIMITIVE_QUADS: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
case CELL_GCM_PRIMITIVE_QUAD_STRIP: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
case CELL_GCM_PRIMITIVE_POLYGON: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
case Primitive_type::points: return D3D_PRIMITIVE_TOPOLOGY_POINTLIST;
case Primitive_type::lines: return D3D_PRIMITIVE_TOPOLOGY_LINELIST;
case Primitive_type::line_loop: return D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ;
case Primitive_type::line_strip: return D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
case Primitive_type::triangles: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
case Primitive_type::triangle_strip: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
case Primitive_type::triangle_fan: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
case Primitive_type::quads: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
case Primitive_type::quad_strip: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
case Primitive_type::polygon: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
}
throw EXCEPTION("Invalid draw mode (0x%x)", draw_mode);
}
D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(u8 draw_mode)
D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(Primitive_type draw_mode)
{
switch (draw_mode)
{
case CELL_GCM_PRIMITIVE_POINTS: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
case CELL_GCM_PRIMITIVE_LINES: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
case CELL_GCM_PRIMITIVE_LINE_STRIP: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
case CELL_GCM_PRIMITIVE_TRIANGLES: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
case CELL_GCM_PRIMITIVE_TRIANGLE_STRIP: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
case CELL_GCM_PRIMITIVE_TRIANGLE_FAN: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
case CELL_GCM_PRIMITIVE_QUADS: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
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: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
case Primitive_type::points: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
case Primitive_type::lines: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
case Primitive_type::line_strip: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
case Primitive_type::triangles: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
case Primitive_type::triangle_strip: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
case Primitive_type::triangle_fan: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
case Primitive_type::quads: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
case Primitive_type::quad_strip: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
case Primitive_type::polygon: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
case Primitive_type::line_loop: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
}
throw EXCEPTION("Invalid or unsupported draw mode (0x%x)", draw_mode);
}
DXGI_FORMAT get_color_surface_format(u8 format)
DXGI_FORMAT get_color_surface_format(Surface_color_format format)
{
switch (format)
{
case CELL_GCM_SURFACE_R5G6B5: return DXGI_FORMAT_B5G6R5_UNORM;
case CELL_GCM_SURFACE_X8R8G8B8_O8R8G8B8: return DXGI_FORMAT_B8G8R8X8_UNORM; //BIT.TRIP Runner2 use this
case CELL_GCM_SURFACE_A8R8G8B8: return DXGI_FORMAT_R8G8B8A8_UNORM;
case CELL_GCM_SURFACE_F_W16Z16Y16X16: return DXGI_FORMAT_R16G16B16A16_FLOAT;
case CELL_GCM_SURFACE_F_X32: return DXGI_FORMAT_R32_FLOAT;
case CELL_GCM_SURFACE_A8B8G8R8: return DXGI_FORMAT_R8G8B8A8_UNORM;
case Surface_color_format::r5g6b5: return DXGI_FORMAT_B5G6R5_UNORM;
case Surface_color_format::x8r8g8b8_o8r8g8b8:
case Surface_color_format::x8r8g8b8_z8r8g8b8:
case Surface_color_format::x8b8g8r8_o8b8g8r8:
case Surface_color_format::x8b8g8r8_z8b8g8r8:
return DXGI_FORMAT_B8G8R8X8_UNORM; //BIT.TRIP Runner2 use this
case Surface_color_format::a8b8g8r8:
case Surface_color_format::a8r8g8b8: return DXGI_FORMAT_R8G8B8A8_UNORM;
case Surface_color_format::b8: return DXGI_FORMAT_R8_UNORM;
case Surface_color_format::g8b8: return DXGI_FORMAT_R8G8_UNORM;
case Surface_color_format::w16z16y16x16: return DXGI_FORMAT_R16G16B16A16_FLOAT;
case Surface_color_format::w32z32y32x32: return DXGI_FORMAT_R32G32B32A32_FLOAT;
case Surface_color_format::x32: return DXGI_FORMAT_R32_FLOAT;
}
throw EXCEPTION("Invalid format (0x%x)", format);
}
DXGI_FORMAT get_depth_stencil_surface_format(u8 format)
DXGI_FORMAT get_depth_stencil_surface_format(Surface_depth_format 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;
case Surface_depth_format::z16: return DXGI_FORMAT_D16_UNORM;
case Surface_depth_format::z24s8: return DXGI_FORMAT_D24_UNORM_S8_UINT;
}
throw EXCEPTION("Invalid format (0x%x)", format);
}
DXGI_FORMAT get_depth_stencil_surface_clear_format(u8 format)
DXGI_FORMAT get_depth_stencil_surface_clear_format(Surface_depth_format 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;
case Surface_depth_format::z16: return DXGI_FORMAT_D16_UNORM;
case Surface_depth_format::z24s8: return DXGI_FORMAT_D24_UNORM_S8_UINT;
}
throw EXCEPTION("Invalid format (0x%x)", format);
}
DXGI_FORMAT get_depth_stencil_typeless_surface_format(u8 format)
DXGI_FORMAT get_depth_stencil_typeless_surface_format(Surface_depth_format format)
{
switch (format)
{
case CELL_GCM_SURFACE_Z16: return DXGI_FORMAT_R16_TYPELESS;
case CELL_GCM_SURFACE_Z24S8: return DXGI_FORMAT_R24G8_TYPELESS;
case Surface_depth_format::z16: return DXGI_FORMAT_R16_TYPELESS;
case Surface_depth_format::z24s8: return DXGI_FORMAT_R24G8_TYPELESS;
}
throw EXCEPTION("Invalid format (0x%x)", format);
}
DXGI_FORMAT get_depth_samplable_surface_format(u8 format)
DXGI_FORMAT get_depth_samplable_surface_format(Surface_depth_format 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;
case Surface_depth_format::z16: return DXGI_FORMAT_R16_UNORM;
case Surface_depth_format::z24s8: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
}
throw EXCEPTION("Invalid format (0x%x)", format);
}
@@ -362,21 +369,21 @@ BOOL get_front_face_ccw(u32 ffv)
throw EXCEPTION("Invalid front face value (0x%x)", ffv);
}
DXGI_FORMAT get_index_type(u8 index_type)
DXGI_FORMAT get_index_type(Index_array_type 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;
case Index_array_type::unsigned_16b: return DXGI_FORMAT_R16_UINT;
case Index_array_type::unsigned_32b: return DXGI_FORMAT_R32_UINT;
}
throw EXCEPTION("Invalid index_type (0x%x)", index_type);
}
DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size)
DXGI_FORMAT get_vertex_attribute_format(Vertex_base_type type, u8 size)
{
switch (type)
{
case CELL_GCM_VERTEX_S1:
case Vertex_base_type::s1:
{
switch (size)
{
@@ -387,7 +394,7 @@ DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size)
}
break;
}
case CELL_GCM_VERTEX_F:
case Vertex_base_type::f:
{
switch (size)
{
@@ -398,7 +405,7 @@ DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size)
}
break;
}
case CELL_GCM_VERTEX_SF:
case Vertex_base_type::sf:
{
switch (size)
{
@@ -409,7 +416,7 @@ DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size)
}
break;
}
case CELL_GCM_VERTEX_UB:
case Vertex_base_type::ub:
{
switch (size)
{
@@ -420,7 +427,7 @@ DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size)
}
break;
}
case CELL_GCM_VERTEX_S32K:
case Vertex_base_type::s32k:
{
switch (size)
{
@@ -431,18 +438,18 @@ DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size)
}
break;
}
case CELL_GCM_VERTEX_CMP:
case Vertex_base_type::cmp:
{
switch (size)
{
case 1: return DXGI_FORMAT_R32_FLOAT;
case 2: return DXGI_FORMAT_R32G32_FLOAT;
case 3: return DXGI_FORMAT_R32G32B32_FLOAT;
case 4: return DXGI_FORMAT_R32G32B32A32_FLOAT;
case 1: return DXGI_FORMAT_R16G16B16A16_SNORM;
case 2:
case 3:
case 4: throw EXCEPTION("Unsupported CMP vertex format with size > 1");
}
break;
}
case CELL_GCM_VERTEX_UB256:
case Vertex_base_type::ub256:
{
switch (size)
{
+9 -9
View File
@@ -56,37 +56,37 @@ 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);
D3D12_PRIMITIVE_TOPOLOGY get_primitive_topology(Primitive_type draw_mode);
/**
* Convert draw mode to D3D12_PRIMITIVE_TOPOLOGY_TYPE
*/
D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(u8 draw_mode);
D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(Primitive_type draw_mode);
/**
* Convert color surface format to DXGI_FORMAT
*/
DXGI_FORMAT get_color_surface_format(u8 format);
DXGI_FORMAT get_color_surface_format(Surface_color_format format);
/**
* Convert depth stencil surface format to DXGI_FORMAT
*/
DXGI_FORMAT get_depth_stencil_surface_format(u8 format);
DXGI_FORMAT get_depth_stencil_surface_format(Surface_depth_format format);
/**
*Convert depth stencil surface format to DXGI_FORMAT suited for clear value
*/
DXGI_FORMAT get_depth_stencil_surface_clear_format(u8 format);
DXGI_FORMAT get_depth_stencil_surface_clear_format(Surface_depth_format format);
/**
* Convert depth surface format to a typeless DXGI_FORMAT
*/
DXGI_FORMAT get_depth_stencil_typeless_surface_format(u8 format);
DXGI_FORMAT get_depth_stencil_typeless_surface_format(Surface_depth_format format);
/**
* Convert depth surface format to a DXGI_FORMAT that can be depth sampled
*/
DXGI_FORMAT get_depth_samplable_surface_format(u8 format);
DXGI_FORMAT get_depth_samplable_surface_format(Surface_depth_format format);
/**
* Convert front face value to bool value telling wheter front face is counterclockwise or not
@@ -96,12 +96,12 @@ BOOL get_front_face_ccw(u32 set_front_face_value);
/**
* Convert index type to DXGI_FORMAT
*/
DXGI_FORMAT get_index_type(u8 index_type);
DXGI_FORMAT get_index_type(Index_array_type index_type);
/**
* Convert vertex attribute format and size to DXGI_FORMAT
*/
DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size);
DXGI_FORMAT get_vertex_attribute_format(Vertex_base_type type, u8 size);
/**
* Convert scissor register value to D3D12_RECT
@@ -6,8 +6,8 @@
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
D3D12FragmentDecompiler::D3D12FragmentDecompiler(u32 addr, u32& size, u32 ctrl, const std::vector<texture_dimension> &texture_dimensions) :
FragmentProgramDecompiler(addr, size, ctrl, texture_dimensions)
D3D12FragmentDecompiler::D3D12FragmentDecompiler(const RSXFragmentProgram &prog, u32& size) :
FragmentProgramDecompiler(prog, size)
{
}
@@ -141,12 +141,30 @@ void D3D12FragmentDecompiler::insertConstants(std::stringstream & OS)
void D3D12FragmentDecompiler::insertMainStart(std::stringstream & OS)
{
// "lib" function
// 0.00001 is used as "some non zero very little number"
OS << "float4 divsq_legacy(float4 num, float4 denum)\n";
OS << "{\n";
OS << " return num / sqrt(max(denum.xxxx, 0.00001));\n";
OS << "}\n";
OS << "float4 rcp_legacy(float4 denum)\n";
OS << "{\n";
OS << " return 1. / denum;\n";
OS << "}\n";
OS << "float4 rsq_legacy(float4 denum)\n";
OS << "{\n";
OS << " return 1. / sqrt(max(denum, 0.00001));\n";
OS << "}\n";
const std::set<std::string> output_value =
{
"r0", "r1", "r2", "r3", "r4",
"h0", "h4", "h6", "h8"
"h0", "h2", "h4", "h6", "h8"
};
OS << "void ps_impl(PixelInput In, inout float4 r0, inout float4 h0, inout float4 r1, inout float4 r2, inout float4 h4, inout float4 r3, inout float4 h6, inout float4 r4, inout float4 h8)" << std::endl;
OS << "void ps_impl(PixelInput In, inout float4 r0, inout float4 h0, inout float4 r1, inout float4 h2, inout float4 r2, inout float4 h4, inout float4 r3, inout float4 h6, inout float4 r4, inout float4 h8)" << std::endl;
OS << "{" << std::endl;
for (ParamType PT : m_parr.params[PF_PARAM_IN])
{
@@ -194,7 +212,7 @@ void D3D12FragmentDecompiler::insertMainEnd(std::stringstream & OS)
OS << " float4 h4 = float4(0., 0., 0., 0.);" << std::endl;
OS << " float4 h6 = float4(0., 0., 0., 0.);" << std::endl;
OS << " float4 h8 = float4(0., 0., 0., 0.);" << std::endl;
OS << " ps_impl(In, r0, h0, r1, r2, h4, r3, h6, r4, h8);" << std::endl;
OS << " ps_impl(In, r0, h0, r1, h2, r2, h4, r3, h6, r4, h8);" << std::endl;
const std::pair<std::string, std::string> table[] =
{
@@ -204,21 +222,29 @@ void D3D12FragmentDecompiler::insertMainEnd(std::stringstream & OS)
{ "ocol3", m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS ? "r4" : "h8" },
};
size_t num_output = 0;
std::string first_output_name;
OS << " PixelOutput Out = (PixelOutput)0;" << std::endl;
for (int i = 0; i < sizeof(table) / sizeof(*table); ++i)
{
if (m_parr.HasParam(PF_PARAM_NONE, "float4", table[i].second))
{
OS << " Out." << table[i].first << " = " << table[i].second << ";" << std::endl;
num_output++;
if (first_output_name.empty()) first_output_name = table[i].first;
}
}
if (m_ctrl & CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT)
OS << " Out.depth = " << ((m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS) ? "r1.z;" : "h0.z;") << std::endl;
{
/**
* Note: Naruto Shippuden : Ultimate Ninja Storm 2 sets CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS in a shader
* but it writes depth in r1.z and not h2.z.
* Maybe there's a different flag for depth ?
*/
// OS << " Out.depth = " << ((m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS) ? "r1.z;" : "h2.z;") << std::endl;
OS << " Out.depth = r1.z;\n";
}
// Shaders don't always output colors (for instance if they write to depth only)
if (num_output > 0)
OS << " if (isAlphaTested && Out.ocol0.a <= alphaRef) discard;" << std::endl;
if (!first_output_name.empty())
OS << " if (isAlphaTested && Out." << first_output_name << ".a <= alphaRef) discard;\n";
OS << " return Out;" << std::endl;
OS << "}" << std::endl;
}
@@ -20,5 +20,5 @@ protected:
virtual void insertMainStart(std::stringstream &OS) override;
virtual void insertMainEnd(std::stringstream &OS) override;
public:
D3D12FragmentDecompiler(u32 addr, u32& size, u32 ctrl, const std::vector<texture_dimension> &texture_dimensions);
D3D12FragmentDecompiler(const RSXFragmentProgram &prog, u32& size);
};

Some files were not shown because too many files have changed in this diff Show More