Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a1a337358a | |||
| 9eadd8b136 | |||
| 35fb767ae3 | |||
| 80eb88d0af | |||
| 3a85c68232 | |||
| 489cfd6f7e | |||
| 26f329d186 | |||
| 5ace4438e2 | |||
| b8e10225f9 | |||
| 224facf3ba | |||
| 9c12d8ff22 | |||
| 3b4339c8e0 | |||
| 8e12c4cb00 | |||
| efe1678088 | |||
| 2f5be3559e | |||
| 960668ecf1 | |||
| 83084467c6 | |||
| 8464ab6a23 | |||
| 74ec128e62 | |||
| 194c6b8bee | |||
| 69272edba6 | |||
| 38531459df | |||
| b3e3c68f15 | |||
| 5029dff73a | |||
| 689dee9944 | |||
| 68f9898171 | |||
| 08622a41b4 | |||
| 669a3277ff | |||
| e6bd681227 | |||
| 0c5cfdddba | |||
| d08ce79d04 | |||
| bab52c132d | |||
| cc1efd2a46 | |||
| 8297d963bf | |||
| a17c41b4e1 | |||
| b055747d4f | |||
| 4ef76866a5 | |||
| 675ccd4510 | |||
| 31a925b4f0 | |||
| d153575e59 | |||
| 3afc62e525 | |||
| f8446b227b | |||
| 8f937bda0f | |||
| 9d1208bf95 | |||
| e7591439f4 | |||
| fef0b1dd46 | |||
| 3281a1982e | |||
| b8486a489d | |||
| f97d791fe8 | |||
| 657a6c9511 | |||
| aa4fb80465 |
+4
-1
@@ -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
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"userBlacklist": [AlexAltea]
|
||||
"userBlacklist": ["AlexAltea"]
|
||||
}
|
||||
+4
-3
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+105
-55
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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__)
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "rPlatform.h"
|
||||
|
||||
+1
-1
@@ -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
@@ -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
@@ -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
@@ -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) */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
@@ -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.
@@ -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();
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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/*"
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,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,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,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; }
|
||||
};
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -89,7 +89,7 @@ void CPUThread::dump_info() const
|
||||
{
|
||||
if (!Emu.IsStopped())
|
||||
{
|
||||
LOG_NOTICE(GENERAL, RegsToString());
|
||||
LOG_NOTICE(GENERAL, "%s", RegsToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
+373
-376
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user