Merge remote-tracking branch 'upstream/master' into canary-old-update
This commit is contained in:
commit
b619e482da
|
@ -38,11 +38,13 @@ after_build:
|
||||||
- |-
|
- |-
|
||||||
7z a xenia-%appveyor_repo_branch%.zip LICENSE .\build\bin\Windows\Release\xenia-canary.exe
|
7z a xenia-%appveyor_repo_branch%.zip LICENSE .\build\bin\Windows\Release\xenia-canary.exe
|
||||||
7z a xenia-vfs-dump-%appveyor_repo_branch%.zip LICENSE .\build\bin\Windows\Release\xenia-vfs-dump.exe
|
7z a xenia-vfs-dump-%appveyor_repo_branch%.zip LICENSE .\build\bin\Windows\Release\xenia-vfs-dump.exe
|
||||||
|
7z a SDL2.zip %APPVEYOR_BUILD_FOLDER%\build\bin\%PLATFORM%\%CONFIGURATION%\SDL2.dll
|
||||||
|
|
||||||
test: off
|
test: off
|
||||||
|
|
||||||
artifacts:
|
artifacts:
|
||||||
- path: xenia-$(appveyor_repo_branch).zip
|
- path: xenia-$(appveyor_repo_branch).zip
|
||||||
- path: xenia-vfs-dump-$(appveyor_repo_branch).zip
|
- path: xenia-vfs-dump-$(appveyor_repo_branch).zip
|
||||||
|
- path: SDL2.zip
|
||||||
|
|
||||||
deploy: off
|
deploy: off
|
||||||
|
|
|
@ -52,3 +52,6 @@
|
||||||
[submodule "third_party/cxxopts"]
|
[submodule "third_party/cxxopts"]
|
||||||
path = third_party/cxxopts
|
path = third_party/cxxopts
|
||||||
url = https://github.com/jarro2783/cxxopts.git
|
url = https://github.com/jarro2783/cxxopts.git
|
||||||
|
[submodule "third_party/SDL2-devel-VC"]
|
||||||
|
path = third_party/SDL2-devel-VC
|
||||||
|
url = https://github.com/xenia-project/SDL2-devel-VC.git
|
||||||
|
|
|
@ -332,9 +332,8 @@ bool EmulatorWindow::Initialize() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatorWindow::FileDrop(wchar_t* filename) {
|
void EmulatorWindow::FileDrop(const wchar_t* filename) {
|
||||||
std::wstring path = filename;
|
auto result = emulator_->LaunchPath(filename);
|
||||||
auto result = emulator_->LaunchPath(path);
|
|
||||||
if (XFAILED(result)) {
|
if (XFAILED(result)) {
|
||||||
// TODO: Display a message box.
|
// TODO: Display a message box.
|
||||||
XELOGE("Failed to launch target: %.8X", result);
|
XELOGE("Failed to launch target: %.8X", result);
|
||||||
|
|
|
@ -44,7 +44,7 @@ class EmulatorWindow {
|
||||||
|
|
||||||
bool Initialize();
|
bool Initialize();
|
||||||
|
|
||||||
void FileDrop(wchar_t* filename);
|
void FileDrop(const wchar_t* filename);
|
||||||
void FileOpen();
|
void FileOpen();
|
||||||
void RecentListUpdater(std::wstring path);
|
void RecentListUpdater(std::wstring path);
|
||||||
void RecentList(int index);
|
void RecentList(int index);
|
||||||
|
|
|
@ -78,7 +78,7 @@ project("xenia-app")
|
||||||
|
|
||||||
filter("platforms:Windows")
|
filter("platforms:Windows")
|
||||||
links({
|
links({
|
||||||
"delayimp", -- Enable dll delayed loading for msvc
|
"delayimp", -- This library implements delayed loading on Windows, an MSVC exclusive feature.
|
||||||
"xenia-apu-xaudio2",
|
"xenia-apu-xaudio2",
|
||||||
"xenia-gpu-d3d12",
|
"xenia-gpu-d3d12",
|
||||||
"xenia-hid-winkey",
|
"xenia-hid-winkey",
|
||||||
|
@ -96,6 +96,11 @@ project("xenia-app")
|
||||||
"/DELAYLOAD:SDL2.dll", -- SDL is not mandatory since on windows, XInput is the preferred input method
|
"/DELAYLOAD:SDL2.dll", -- SDL is not mandatory since on windows, XInput is the preferred input method
|
||||||
})
|
})
|
||||||
|
|
||||||
|
filter("platforms:Windows")
|
||||||
|
linkoptions({
|
||||||
|
"/DELAYLOAD:SDL2.dll", -- SDL is not mandatory on Windows, implementations using native APIs are prefered.
|
||||||
|
})
|
||||||
|
|
||||||
filter("platforms:Windows")
|
filter("platforms:Windows")
|
||||||
-- Only create the .user file if it doesn't already exist.
|
-- Only create the .user file if it doesn't already exist.
|
||||||
local user_file = project_root.."/build/xenia-app.vcxproj.user"
|
local user_file = project_root.."/build/xenia-app.vcxproj.user"
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Copyright 2019 Ben Vanik. All rights reserved. *
|
* Copyright 2020 Ben Vanik. All rights reserved. *
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -18,13 +18,12 @@ project("xenia-apu-sdl")
|
||||||
filter("platforms:Windows")
|
filter("platforms:Windows")
|
||||||
-- On linux we build against the system version (libsdl2-dev)
|
-- On linux we build against the system version (libsdl2-dev)
|
||||||
includedirs({
|
includedirs({
|
||||||
project_root.."/third_party/SDL2/include/",
|
project_root.."/third_party/SDL2-devel-VC/include/",
|
||||||
})
|
})
|
||||||
libdirs({
|
libdirs({
|
||||||
project_root.."/third_party/SDL2/lib/x64/",
|
project_root.."/third_party/SDL2-devel-VC/lib/x64/",
|
||||||
})
|
})
|
||||||
-- Copy the dll to the output folder
|
-- Copy the dll to the output folder
|
||||||
postbuildcommands({
|
postbuildcommands({
|
||||||
"{COPY} %{prj.basedir}/"..project_root.."/third_party/SDL2/lib/x64/SDL2.dll %{cfg.targetdir}",
|
"{COPY} %{prj.basedir}/"..project_root.."/third_party/SDL2-devel-VC/lib/x64/SDL2.dll %{cfg.targetdir}",
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Copyright 2019 Ben Vanik. All rights reserved. *
|
* Copyright 2020 Ben Vanik. All rights reserved. *
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Copyright 2019 Ben Vanik. All rights reserved. *
|
* Copyright 2020 Ben Vanik. All rights reserved. *
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Copyright 2019 Ben Vanik. All rights reserved. *
|
* Copyright 2020 Ben Vanik. All rights reserved. *
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Copyright 2019 Ben Vanik. All rights reserved. *
|
* Copyright 2020 Ben Vanik. All rights reserved. *
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -155,7 +155,7 @@ class PosixFileHandle : public FileHandle {
|
||||||
|
|
||||||
std::unique_ptr<FileHandle> FileHandle::OpenExisting(std::wstring path,
|
std::unique_ptr<FileHandle> FileHandle::OpenExisting(std::wstring path,
|
||||||
uint32_t desired_access) {
|
uint32_t desired_access) {
|
||||||
int open_access;
|
int open_access = 0;
|
||||||
if (desired_access & FileAccess::kGenericRead) {
|
if (desired_access & FileAccess::kGenericRead) {
|
||||||
open_access |= O_RDONLY;
|
open_access |= O_RDONLY;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,12 +31,14 @@ std::wstring GetExecutableFolder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::wstring GetUserFolder() {
|
std::wstring GetUserFolder() {
|
||||||
wchar_t path[MAX_PATH];
|
std::wstring result;
|
||||||
if (!SUCCEEDED(SHGetFolderPathW(nullptr, CSIDL_MYDOCUMENTS, nullptr,
|
PWSTR path;
|
||||||
SHGFP_TYPE_CURRENT, path))) {
|
if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Documents, KF_FLAG_DEFAULT,
|
||||||
return std::wstring();
|
nullptr, &path))) {
|
||||||
|
result.assign(path);
|
||||||
|
CoTaskMemFree(path);
|
||||||
}
|
}
|
||||||
return std::wstring(path);
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PathExists(const std::wstring& path) {
|
bool PathExists(const std::wstring& path) {
|
||||||
|
|
|
@ -233,12 +233,12 @@ inline bool bit_scan_forward(uint64_t v, uint32_t* out_first_set_index) {
|
||||||
#else
|
#else
|
||||||
inline bool bit_scan_forward(uint32_t v, uint32_t* out_first_set_index) {
|
inline bool bit_scan_forward(uint32_t v, uint32_t* out_first_set_index) {
|
||||||
int i = ffs(v);
|
int i = ffs(v);
|
||||||
*out_first_set_index = i;
|
*out_first_set_index = i - 1;
|
||||||
return i != 0;
|
return i != 0;
|
||||||
}
|
}
|
||||||
inline bool bit_scan_forward(uint64_t v, uint32_t* out_first_set_index) {
|
inline bool bit_scan_forward(uint64_t v, uint32_t* out_first_set_index) {
|
||||||
int i = ffsll(v);
|
int i = ffsll(v);
|
||||||
*out_first_set_index = i;
|
*out_first_set_index = i - 1;
|
||||||
return i != 0;
|
return i != 0;
|
||||||
}
|
}
|
||||||
#endif // XE_PLATFORM_WIN32
|
#endif // XE_PLATFORM_WIN32
|
||||||
|
|
|
@ -95,7 +95,6 @@ namespace xe {
|
||||||
#if XE_PLATFORM_WIN32
|
#if XE_PLATFORM_WIN32
|
||||||
const char kPathSeparator = '\\';
|
const char kPathSeparator = '\\';
|
||||||
const wchar_t kWPathSeparator = L'\\';
|
const wchar_t kWPathSeparator = L'\\';
|
||||||
const size_t kMaxPath = 260; // _MAX_PATH
|
|
||||||
#else
|
#else
|
||||||
const char kPathSeparator = '/';
|
const char kPathSeparator = '/';
|
||||||
const wchar_t kWPathSeparator = L'/';
|
const wchar_t kWPathSeparator = L'/';
|
||||||
|
|
|
@ -155,9 +155,13 @@ std::string::size_type find_first_of_case(const std::string& target,
|
||||||
|
|
||||||
std::wstring to_absolute_path(const std::wstring& path) {
|
std::wstring to_absolute_path(const std::wstring& path) {
|
||||||
#if XE_PLATFORM_WIN32
|
#if XE_PLATFORM_WIN32
|
||||||
wchar_t buffer[kMaxPath];
|
std::wstring result;
|
||||||
_wfullpath(buffer, path.c_str(), sizeof(buffer) / sizeof(wchar_t));
|
wchar_t* buffer = _wfullpath(nullptr, path.c_str(), 0);
|
||||||
return buffer;
|
if (buffer != nullptr) {
|
||||||
|
result.assign(buffer);
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
#else
|
#else
|
||||||
char buffer[kMaxPath];
|
char buffer[kMaxPath];
|
||||||
realpath(xe::to_string(path).c_str(), buffer);
|
realpath(xe::to_string(path).c_str(), buffer);
|
||||||
|
|
|
@ -7,11 +7,13 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "xenia/base/threading.h"
|
|
||||||
|
|
||||||
#include "xenia/base/assert.h"
|
#include "xenia/base/assert.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/platform_win.h"
|
#include "xenia/base/platform_win.h"
|
||||||
|
#include "xenia/base/threading.h"
|
||||||
|
|
||||||
|
typedef HANDLE (*SetThreadDescriptionFn)(HANDLE hThread,
|
||||||
|
PCWSTR lpThreadDescription);
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace threading {
|
namespace threading {
|
||||||
|
@ -39,14 +41,29 @@ struct THREADNAME_INFO {
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
void set_name(DWORD thread_id, const std::string& name) {
|
void set_name(HANDLE thread, const std::string& name) {
|
||||||
|
auto kern = GetModuleHandleW(L"kernel32.dll");
|
||||||
|
if (kern) {
|
||||||
|
auto set_thread_description =
|
||||||
|
(SetThreadDescriptionFn)GetProcAddress(kern, "SetThreadDescription");
|
||||||
|
if (set_thread_description) {
|
||||||
|
int len = MultiByteToWideChar(CP_ACP, 0, name.c_str(), -1, NULL, 0);
|
||||||
|
auto str = (LPWSTR)alloca(len * sizeof(WCHAR));
|
||||||
|
if (str) {
|
||||||
|
MultiByteToWideChar(CP_ACP, 0, name.c_str(), -1, str, len);
|
||||||
|
set_thread_description(thread, str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!IsDebuggerPresent()) {
|
if (!IsDebuggerPresent()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
THREADNAME_INFO info;
|
THREADNAME_INFO info;
|
||||||
info.dwType = 0x1000;
|
info.dwType = 0x1000;
|
||||||
info.szName = name.c_str();
|
info.szName = name.c_str();
|
||||||
info.dwThreadID = thread_id;
|
info.dwThreadID = ::GetThreadId(thread);
|
||||||
info.dwFlags = 0;
|
info.dwFlags = 0;
|
||||||
__try {
|
__try {
|
||||||
RaiseException(0x406D1388, 0, sizeof(info) / sizeof(ULONG_PTR),
|
RaiseException(0x406D1388, 0, sizeof(info) / sizeof(ULONG_PTR),
|
||||||
|
@ -55,13 +72,7 @@ void set_name(DWORD thread_id, const std::string& name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_name(const std::string& name) {
|
void set_name(const std::string& name) { set_name(GetCurrentThread(), name); }
|
||||||
set_name(static_cast<DWORD>(-1), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_name(std::thread::native_handle_type handle, const std::string& name) {
|
|
||||||
set_name(GetThreadId(handle), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaybeYield() {
|
void MaybeYield() {
|
||||||
SwitchToThread();
|
SwitchToThread();
|
||||||
|
|
|
@ -82,7 +82,7 @@ class X64CodeCache : public CodeCache {
|
||||||
// This is picked to be high enough to cover whatever we can reasonably
|
// This is picked to be high enough to cover whatever we can reasonably
|
||||||
// expect. If we hit issues with this it probably means some corner case
|
// expect. If we hit issues with this it probably means some corner case
|
||||||
// in analysis triggering.
|
// in analysis triggering.
|
||||||
static const size_t kMaximumFunctionCount = 50000;
|
static const size_t kMaximumFunctionCount = 100000;
|
||||||
|
|
||||||
struct UnwindReservation {
|
struct UnwindReservation {
|
||||||
size_t data_size = 0;
|
size_t data_size = 0;
|
||||||
|
|
|
@ -863,22 +863,20 @@ int InstrEmit_rldclx(PPCHIRBuilder& f, const InstrData& i) {
|
||||||
// b <- mb[5] || mb[0:4]
|
// b <- mb[5] || mb[0:4]
|
||||||
// m <- MASK(b, 63)
|
// m <- MASK(b, 63)
|
||||||
// rA <- r & m
|
// rA <- r & m
|
||||||
Value* sh =
|
Value* n = f.And(f.Truncate(f.LoadGPR(i.MDS.RB), INT8_TYPE),
|
||||||
f.And(f.Truncate(f.LoadGPR(i.X.RB), INT8_TYPE), f.LoadConstantInt8(0x7F));
|
f.LoadConstantInt8(0x3F));
|
||||||
|
|
||||||
uint32_t mb = (i.MD.MB5 << 5) | i.MD.MB;
|
uint32_t mb = (i.MDS.MB5 << 5) | i.MDS.MB;
|
||||||
uint64_t m = XEMASK(mb, 63);
|
uint64_t m = XEMASK(mb, 63);
|
||||||
Value* v = f.LoadGPR(i.MD.RT);
|
Value* v = f.LoadGPR(i.MDS.RT);
|
||||||
|
|
||||||
if (sh) {
|
v = f.RotateLeft(v, n);
|
||||||
v = f.RotateLeft(v, sh);
|
|
||||||
}
|
|
||||||
if (m != 0xFFFFFFFFFFFFFFFF) {
|
if (m != 0xFFFFFFFFFFFFFFFF) {
|
||||||
v = f.And(v, f.LoadConstantUint64(m));
|
v = f.And(v, f.LoadConstantUint64(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
f.StoreGPR(i.MD.RA, v);
|
f.StoreGPR(i.MDS.RA, v);
|
||||||
if (i.MD.Rc) {
|
if (i.MDS.Rc) {
|
||||||
f.UpdateCR(0, v);
|
f.UpdateCR(0, v);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -890,22 +888,20 @@ int InstrEmit_rldcrx(PPCHIRBuilder& f, const InstrData& i) {
|
||||||
// b <- mb[5] || mb[0:4]
|
// b <- mb[5] || mb[0:4]
|
||||||
// m <- MASK(0, b)
|
// m <- MASK(0, b)
|
||||||
// rA <- r & m
|
// rA <- r & m
|
||||||
Value* sh =
|
Value* n = f.And(f.Truncate(f.LoadGPR(i.MDS.RB), INT8_TYPE),
|
||||||
f.And(f.Truncate(f.LoadGPR(i.X.RB), INT8_TYPE), f.LoadConstantInt8(0x7F));
|
f.LoadConstantInt8(0x3F));
|
||||||
|
|
||||||
uint32_t mb = (i.MD.MB5 << 5) | i.MD.MB;
|
uint32_t mb = (i.MDS.MB5 << 5) | i.MDS.MB;
|
||||||
uint64_t m = XEMASK(0, mb);
|
uint64_t m = XEMASK(0, mb);
|
||||||
Value* v = f.LoadGPR(i.MD.RT);
|
Value* v = f.LoadGPR(i.MDS.RT);
|
||||||
|
|
||||||
if (sh) {
|
v = f.RotateLeft(v, n);
|
||||||
v = f.RotateLeft(v, sh);
|
|
||||||
}
|
|
||||||
if (m != 0xFFFFFFFFFFFFFFFF) {
|
if (m != 0xFFFFFFFFFFFFFFFF) {
|
||||||
v = f.And(v, f.LoadConstantUint64(m));
|
v = f.And(v, f.LoadConstantUint64(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
f.StoreGPR(i.MD.RA, v);
|
f.StoreGPR(i.MDS.RA, v);
|
||||||
if (i.MD.Rc) {
|
if (i.MDS.Rc) {
|
||||||
f.UpdateCR(0, v);
|
f.UpdateCR(0, v);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -181,15 +181,16 @@ void DxbcShaderTranslator::Reset() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DxbcShaderTranslator::DxbcSrc::Write(std::vector<uint32_t>& code,
|
void DxbcShaderTranslator::DxbcSrc::Write(std::vector<uint32_t>& code,
|
||||||
uint32_t dest_write_mask,
|
bool is_integer, uint32_t mask,
|
||||||
bool is_integer) const {
|
bool force_vector) const {
|
||||||
uint32_t operand_token = GetOperandTokenTypeAndIndex();
|
uint32_t operand_token = GetOperandTokenTypeAndIndex();
|
||||||
uint32_t dest_component = DxbcDest::GetMaskSingleComponent(dest_write_mask);
|
uint32_t mask_single_component = DxbcDest::GetMaskSingleComponent(mask);
|
||||||
uint32_t select_component = dest_component != UINT32_MAX ? dest_component : 0;
|
uint32_t select_component =
|
||||||
bool dest_is_vector =
|
mask_single_component != UINT32_MAX ? mask_single_component : 0;
|
||||||
dest_write_mask != 0b0000 && dest_component == UINT32_MAX;
|
bool is_vector =
|
||||||
|
force_vector || (mask != 0b0000 && mask_single_component == UINT32_MAX);
|
||||||
if (type_ == DxbcOperandType::kImmediate32) {
|
if (type_ == DxbcOperandType::kImmediate32) {
|
||||||
if (dest_is_vector) {
|
if (is_vector) {
|
||||||
operand_token |= uint32_t(DxbcOperandDimension::kVector) |
|
operand_token |= uint32_t(DxbcOperandDimension::kVector) |
|
||||||
(uint32_t(DxbcComponentSelection::kSwizzle) << 2) |
|
(uint32_t(DxbcComponentSelection::kSwizzle) << 2) |
|
||||||
(DxbcSrc::kXYZW << 4);
|
(DxbcSrc::kXYZW << 4);
|
||||||
|
@ -197,10 +198,9 @@ void DxbcShaderTranslator::DxbcSrc::Write(std::vector<uint32_t>& code,
|
||||||
operand_token |= uint32_t(DxbcOperandDimension::kScalar);
|
operand_token |= uint32_t(DxbcOperandDimension::kScalar);
|
||||||
}
|
}
|
||||||
code.push_back(operand_token);
|
code.push_back(operand_token);
|
||||||
if (dest_is_vector) {
|
if (is_vector) {
|
||||||
for (uint32_t i = 0; i < 4; ++i) {
|
for (uint32_t i = 0; i < 4; ++i) {
|
||||||
code.push_back((dest_write_mask & (1 << i))
|
code.push_back((mask & (1 << i)) ? GetModifiedImmediate(i, is_integer)
|
||||||
? GetModifiedImmediate(i, is_integer)
|
|
||||||
: 0);
|
: 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -209,7 +209,7 @@ void DxbcShaderTranslator::DxbcSrc::Write(std::vector<uint32_t>& code,
|
||||||
} else {
|
} else {
|
||||||
switch (GetDimension()) {
|
switch (GetDimension()) {
|
||||||
case DxbcOperandDimension::kScalar:
|
case DxbcOperandDimension::kScalar:
|
||||||
if (dest_is_vector) {
|
if (is_vector) {
|
||||||
operand_token |= uint32_t(DxbcOperandDimension::kVector) |
|
operand_token |= uint32_t(DxbcOperandDimension::kVector) |
|
||||||
(uint32_t(DxbcComponentSelection::kSwizzle) << 2) |
|
(uint32_t(DxbcComponentSelection::kSwizzle) << 2) |
|
||||||
(DxbcSrc::kXXXX << 4);
|
(DxbcSrc::kXXXX << 4);
|
||||||
|
@ -219,17 +219,16 @@ void DxbcShaderTranslator::DxbcSrc::Write(std::vector<uint32_t>& code,
|
||||||
break;
|
break;
|
||||||
case DxbcOperandDimension::kVector:
|
case DxbcOperandDimension::kVector:
|
||||||
operand_token |= uint32_t(DxbcOperandDimension::kVector);
|
operand_token |= uint32_t(DxbcOperandDimension::kVector);
|
||||||
if (dest_is_vector) {
|
if (is_vector) {
|
||||||
operand_token |= uint32_t(DxbcComponentSelection::kSwizzle) << 2;
|
operand_token |= uint32_t(DxbcComponentSelection::kSwizzle) << 2;
|
||||||
// Clear swizzle of unused components to a used value to avoid
|
// Clear swizzle of unused components to a used value to avoid
|
||||||
// referencing potentially uninitialized register components.
|
// referencing potentially uninitialized register components.
|
||||||
uint32_t used_component;
|
uint32_t used_component;
|
||||||
if (!xe::bit_scan_forward(dest_write_mask, &used_component)) {
|
if (!xe::bit_scan_forward(mask, &used_component)) {
|
||||||
used_component = 0;
|
used_component = 0;
|
||||||
}
|
}
|
||||||
for (uint32_t i = 0; i < 4; ++i) {
|
for (uint32_t i = 0; i < 4; ++i) {
|
||||||
uint32_t swizzle_index =
|
uint32_t swizzle_index = (mask & (1 << i)) ? i : used_component;
|
||||||
(dest_write_mask & (1 << i)) ? i : used_component;
|
|
||||||
operand_token |=
|
operand_token |=
|
||||||
(((swizzle_ >> (swizzle_index * 2)) & 3) << (4 + i * 2));
|
(((swizzle_ >> (swizzle_index * 2)) & 3) << (4 + i * 2));
|
||||||
}
|
}
|
||||||
|
@ -1388,7 +1387,7 @@ void DxbcShaderTranslator::StartTranslation() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zero general-purpose registers to prevent crashes when the game references
|
// Zero general-purpose registers to prevent crashes when the game references
|
||||||
// them.
|
// them after only initializing them conditionally.
|
||||||
for (uint32_t i = IsDxbcPixelShader() ? kInterpolatorCount : 0;
|
for (uint32_t i = IsDxbcPixelShader() ? kInterpolatorCount : 0;
|
||||||
i < register_count(); ++i) {
|
i < register_count(); ++i) {
|
||||||
DxbcOpMov(
|
DxbcOpMov(
|
||||||
|
|
|
@ -605,10 +605,10 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
||||||
return DxbcDest(DxbcOperandType::kOutputDepth, 0b0001);
|
return DxbcDest(DxbcOperandType::kOutputDepth, 0b0001);
|
||||||
}
|
}
|
||||||
static DxbcDest Null() { return DxbcDest(DxbcOperandType::kNull, 0b0000); }
|
static DxbcDest Null() { return DxbcDest(DxbcOperandType::kNull, 0b0000); }
|
||||||
// Must write to all 4 components.
|
static DxbcDest U(uint32_t index_1d, DxbcIndex index_2d,
|
||||||
static DxbcDest U(uint32_t index_1d, DxbcIndex index_2d) {
|
uint32_t write_mask = 0b1111) {
|
||||||
return DxbcDest(DxbcOperandType::kUnorderedAccessView, 0b1111, index_1d,
|
return DxbcDest(DxbcOperandType::kUnorderedAccessView, write_mask,
|
||||||
index_2d);
|
index_1d, index_2d);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t GetMask() const {
|
uint32_t GetMask() const {
|
||||||
|
@ -792,12 +792,12 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
||||||
return new_src;
|
return new_src;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t GetLength(uint32_t dest_write_mask) const {
|
uint32_t GetLength(uint32_t mask, bool force_vector = false) const {
|
||||||
bool dest_is_vector =
|
bool is_vector = force_vector ||
|
||||||
dest_write_mask != 0b0000 &&
|
(mask != 0b0000 &&
|
||||||
DxbcDest::GetMaskSingleComponent(dest_write_mask) == UINT32_MAX;
|
DxbcDest::GetMaskSingleComponent(mask) == UINT32_MAX);
|
||||||
if (type_ == DxbcOperandType::kImmediate32) {
|
if (type_ == DxbcOperandType::kImmediate32) {
|
||||||
return dest_is_vector ? 5 : 2;
|
return is_vector ? 5 : 2;
|
||||||
}
|
}
|
||||||
return ((absolute_ || negate_) ? 2 : 1) + DxbcOperandAddress::GetLength();
|
return ((absolute_ || negate_) ? 2 : 1) + DxbcOperandAddress::GetLength();
|
||||||
}
|
}
|
||||||
|
@ -828,43 +828,74 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
||||||
immediate_[(swizzle_ >> (swizzle_index * 2)) & 3], is_integer,
|
immediate_[(swizzle_ >> (swizzle_index * 2)) & 3], is_integer,
|
||||||
absolute_, negate_);
|
absolute_, negate_);
|
||||||
}
|
}
|
||||||
void Write(std::vector<uint32_t>& code, uint32_t dest_write_mask,
|
void Write(std::vector<uint32_t>& code, bool is_integer, uint32_t mask,
|
||||||
bool is_integer) const;
|
bool force_vector = false) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// D3D10_SB_OPCODE_TYPE
|
// D3D10_SB_OPCODE_TYPE
|
||||||
enum class DxbcOpcode : uint32_t {
|
enum class DxbcOpcode : uint32_t {
|
||||||
kAdd = 0,
|
kAdd = 0,
|
||||||
kAnd = 1,
|
kAnd = 1,
|
||||||
|
kBreak = 2,
|
||||||
kCall = 4,
|
kCall = 4,
|
||||||
|
kCallC = 5,
|
||||||
|
kCase = 6,
|
||||||
|
kDefault = 10,
|
||||||
|
kDiscard = 13,
|
||||||
kDiv = 14,
|
kDiv = 14,
|
||||||
kElse = 18,
|
kElse = 18,
|
||||||
kEndIf = 21,
|
kEndIf = 21,
|
||||||
kEndLoop = 22,
|
kEndLoop = 22,
|
||||||
kEndSwitch = 23,
|
kEndSwitch = 23,
|
||||||
|
kEq = 24,
|
||||||
|
kFToI = 27,
|
||||||
kFToU = 28,
|
kFToU = 28,
|
||||||
|
kGE = 29,
|
||||||
kIAdd = 30,
|
kIAdd = 30,
|
||||||
kIf = 31,
|
kIf = 31,
|
||||||
|
kIEq = 32,
|
||||||
|
kILT = 34,
|
||||||
kIMAd = 35,
|
kIMAd = 35,
|
||||||
|
kIMax = 36,
|
||||||
|
kIMin = 37,
|
||||||
|
kINE = 39,
|
||||||
kIShL = 41,
|
kIShL = 41,
|
||||||
|
kIToF = 43,
|
||||||
|
kLabel = 44,
|
||||||
|
kLT = 49,
|
||||||
kMAd = 50,
|
kMAd = 50,
|
||||||
kMin = 51,
|
kMin = 51,
|
||||||
kMax = 52,
|
kMax = 52,
|
||||||
kMov = 54,
|
kMov = 54,
|
||||||
kMovC = 55,
|
kMovC = 55,
|
||||||
|
kMul = 56,
|
||||||
|
kNot = 59,
|
||||||
|
kOr = 60,
|
||||||
|
kRet = 62,
|
||||||
kRetC = 63,
|
kRetC = 63,
|
||||||
|
kRoundNE = 64,
|
||||||
|
kSwitch = 76,
|
||||||
|
kULT = 79,
|
||||||
kUGE = 80,
|
kUGE = 80,
|
||||||
kUMul = 81,
|
kUMul = 81,
|
||||||
kUMAd = 82,
|
kUMAd = 82,
|
||||||
|
kUMax = 83,
|
||||||
|
kUMin = 84,
|
||||||
kUShR = 85,
|
kUShR = 85,
|
||||||
|
kUToF = 86,
|
||||||
kXOr = 87,
|
kXOr = 87,
|
||||||
kDerivRTXCoarse = 122,
|
kDerivRTXCoarse = 122,
|
||||||
kDerivRTXFine = 123,
|
kDerivRTXFine = 123,
|
||||||
kDerivRTYCoarse = 124,
|
kDerivRTYCoarse = 124,
|
||||||
kDerivRTYFine = 125,
|
kDerivRTYFine = 125,
|
||||||
|
kF32ToF16 = 130,
|
||||||
|
kF16ToF32 = 131,
|
||||||
|
kFirstBitHi = 135,
|
||||||
kUBFE = 138,
|
kUBFE = 138,
|
||||||
kIBFE = 139,
|
kIBFE = 139,
|
||||||
kBFI = 140,
|
kBFI = 140,
|
||||||
|
kLdUAVTyped = 163,
|
||||||
|
kStoreUAVTyped = 164,
|
||||||
kEvalSampleIndex = 204,
|
kEvalSampleIndex = 204,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -883,7 +914,7 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
||||||
shader_code_.reserve(shader_code_.size() + 1 + operands_length);
|
shader_code_.reserve(shader_code_.size() + 1 + operands_length);
|
||||||
shader_code_.push_back(DxbcOpcodeToken(opcode, operands_length, saturate));
|
shader_code_.push_back(DxbcOpcodeToken(opcode, operands_length, saturate));
|
||||||
dest.Write(shader_code_);
|
dest.Write(shader_code_);
|
||||||
src.Write(shader_code_, dest_write_mask, (src_are_integer & 0b1) != 0);
|
src.Write(shader_code_, (src_are_integer & 0b1) != 0, dest_write_mask);
|
||||||
++stat_.instruction_count;
|
++stat_.instruction_count;
|
||||||
}
|
}
|
||||||
void DxbcEmitAluOp(DxbcOpcode opcode, uint32_t src_are_integer,
|
void DxbcEmitAluOp(DxbcOpcode opcode, uint32_t src_are_integer,
|
||||||
|
@ -896,8 +927,8 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
||||||
shader_code_.reserve(shader_code_.size() + 1 + operands_length);
|
shader_code_.reserve(shader_code_.size() + 1 + operands_length);
|
||||||
shader_code_.push_back(DxbcOpcodeToken(opcode, operands_length, saturate));
|
shader_code_.push_back(DxbcOpcodeToken(opcode, operands_length, saturate));
|
||||||
dest.Write(shader_code_);
|
dest.Write(shader_code_);
|
||||||
src0.Write(shader_code_, dest_write_mask, (src_are_integer & 0b1) != 0);
|
src0.Write(shader_code_, (src_are_integer & 0b1) != 0, dest_write_mask);
|
||||||
src1.Write(shader_code_, dest_write_mask, (src_are_integer & 0b10) != 0);
|
src1.Write(shader_code_, (src_are_integer & 0b10) != 0, dest_write_mask);
|
||||||
++stat_.instruction_count;
|
++stat_.instruction_count;
|
||||||
}
|
}
|
||||||
void DxbcEmitAluOp(DxbcOpcode opcode, uint32_t src_are_integer,
|
void DxbcEmitAluOp(DxbcOpcode opcode, uint32_t src_are_integer,
|
||||||
|
@ -911,9 +942,9 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
||||||
shader_code_.reserve(shader_code_.size() + 1 + operands_length);
|
shader_code_.reserve(shader_code_.size() + 1 + operands_length);
|
||||||
shader_code_.push_back(DxbcOpcodeToken(opcode, operands_length, saturate));
|
shader_code_.push_back(DxbcOpcodeToken(opcode, operands_length, saturate));
|
||||||
dest.Write(shader_code_);
|
dest.Write(shader_code_);
|
||||||
src0.Write(shader_code_, dest_write_mask, (src_are_integer & 0b1) != 0);
|
src0.Write(shader_code_, (src_are_integer & 0b1) != 0, dest_write_mask);
|
||||||
src1.Write(shader_code_, dest_write_mask, (src_are_integer & 0b10) != 0);
|
src1.Write(shader_code_, (src_are_integer & 0b10) != 0, dest_write_mask);
|
||||||
src2.Write(shader_code_, dest_write_mask, (src_are_integer & 0b100) != 0);
|
src2.Write(shader_code_, (src_are_integer & 0b100) != 0, dest_write_mask);
|
||||||
++stat_.instruction_count;
|
++stat_.instruction_count;
|
||||||
}
|
}
|
||||||
void DxbcEmitAluOp(DxbcOpcode opcode, uint32_t src_are_integer,
|
void DxbcEmitAluOp(DxbcOpcode opcode, uint32_t src_are_integer,
|
||||||
|
@ -928,10 +959,10 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
||||||
shader_code_.reserve(shader_code_.size() + 1 + operands_length);
|
shader_code_.reserve(shader_code_.size() + 1 + operands_length);
|
||||||
shader_code_.push_back(DxbcOpcodeToken(opcode, operands_length, saturate));
|
shader_code_.push_back(DxbcOpcodeToken(opcode, operands_length, saturate));
|
||||||
dest.Write(shader_code_);
|
dest.Write(shader_code_);
|
||||||
src0.Write(shader_code_, dest_write_mask, (src_are_integer & 0b1) != 0);
|
src0.Write(shader_code_, (src_are_integer & 0b1) != 0, dest_write_mask);
|
||||||
src1.Write(shader_code_, dest_write_mask, (src_are_integer & 0b10) != 0);
|
src1.Write(shader_code_, (src_are_integer & 0b10) != 0, dest_write_mask);
|
||||||
src2.Write(shader_code_, dest_write_mask, (src_are_integer & 0b100) != 0);
|
src2.Write(shader_code_, (src_are_integer & 0b100) != 0, dest_write_mask);
|
||||||
src3.Write(shader_code_, dest_write_mask, (src_are_integer & 0b1000) != 0);
|
src3.Write(shader_code_, (src_are_integer & 0b1000) != 0, dest_write_mask);
|
||||||
++stat_.instruction_count;
|
++stat_.instruction_count;
|
||||||
}
|
}
|
||||||
void DxbcEmitAluOp(DxbcOpcode opcode, uint32_t src_are_integer,
|
void DxbcEmitAluOp(DxbcOpcode opcode, uint32_t src_are_integer,
|
||||||
|
@ -946,8 +977,8 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
||||||
shader_code_.push_back(DxbcOpcodeToken(opcode, operands_length, saturate));
|
shader_code_.push_back(DxbcOpcodeToken(opcode, operands_length, saturate));
|
||||||
dest0.Write(shader_code_);
|
dest0.Write(shader_code_);
|
||||||
dest1.Write(shader_code_);
|
dest1.Write(shader_code_);
|
||||||
src0.Write(shader_code_, dest_write_mask, (src_are_integer & 0b1) != 0);
|
src0.Write(shader_code_, (src_are_integer & 0b1) != 0, dest_write_mask);
|
||||||
src1.Write(shader_code_, dest_write_mask, (src_are_integer & 0b10) != 0);
|
src1.Write(shader_code_, (src_are_integer & 0b10) != 0, dest_write_mask);
|
||||||
++stat_.instruction_count;
|
++stat_.instruction_count;
|
||||||
}
|
}
|
||||||
void DxbcEmitFlowOp(DxbcOpcode opcode, const DxbcSrc& src,
|
void DxbcEmitFlowOp(DxbcOpcode opcode, const DxbcSrc& src,
|
||||||
|
@ -956,7 +987,17 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
||||||
shader_code_.reserve(shader_code_.size() + 1 + operands_length);
|
shader_code_.reserve(shader_code_.size() + 1 + operands_length);
|
||||||
shader_code_.push_back(DxbcOpcodeToken(opcode, operands_length) |
|
shader_code_.push_back(DxbcOpcodeToken(opcode, operands_length) |
|
||||||
(test ? (1 << 18) : 0));
|
(test ? (1 << 18) : 0));
|
||||||
src.Write(shader_code_, 0b0000, true);
|
src.Write(shader_code_, true, 0b0000);
|
||||||
|
++stat_.instruction_count;
|
||||||
|
}
|
||||||
|
void DxbcEmitFlowOp(DxbcOpcode opcode, const DxbcSrc& src0,
|
||||||
|
const DxbcSrc& src1, bool test = false) {
|
||||||
|
uint32_t operands_length = src0.GetLength(0b0000) + src1.GetLength(0b0000);
|
||||||
|
shader_code_.reserve(shader_code_.size() + 1 + operands_length);
|
||||||
|
shader_code_.push_back(DxbcOpcodeToken(opcode, operands_length) |
|
||||||
|
(test ? (1 << 18) : 0));
|
||||||
|
src0.Write(shader_code_, true, 0b0000);
|
||||||
|
src1.Write(shader_code_, true, 0b0000);
|
||||||
++stat_.instruction_count;
|
++stat_.instruction_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -970,19 +1011,39 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
||||||
DxbcEmitAluOp(DxbcOpcode::kAnd, 0b11, dest, src0, src1);
|
DxbcEmitAluOp(DxbcOpcode::kAnd, 0b11, dest, src0, src1);
|
||||||
++stat_.uint_instruction_count;
|
++stat_.uint_instruction_count;
|
||||||
}
|
}
|
||||||
|
void DxbcOpBreak() {
|
||||||
|
shader_code_.push_back(DxbcOpcodeToken(DxbcOpcode::kBreak, 0));
|
||||||
|
++stat_.instruction_count;
|
||||||
|
}
|
||||||
void DxbcOpCall(const DxbcSrc& label) {
|
void DxbcOpCall(const DxbcSrc& label) {
|
||||||
DxbcEmitFlowOp(DxbcOpcode::kCall, label);
|
DxbcEmitFlowOp(DxbcOpcode::kCall, label);
|
||||||
++stat_.static_flow_control_count;
|
++stat_.static_flow_control_count;
|
||||||
}
|
}
|
||||||
void DxbcOpElse() {
|
void DxbcOpCallC(bool test, const DxbcSrc& src, const DxbcSrc& label) {
|
||||||
shader_code_.push_back(DxbcOpcodeToken(DxbcOpcode::kElse, 0));
|
DxbcEmitFlowOp(DxbcOpcode::kCallC, src, label, test);
|
||||||
|
++stat_.dynamic_flow_control_count;
|
||||||
|
}
|
||||||
|
void DxbcOpCase(const DxbcSrc& src) {
|
||||||
|
DxbcEmitFlowOp(DxbcOpcode::kCase, src);
|
||||||
|
++stat_.static_flow_control_count;
|
||||||
|
}
|
||||||
|
void DxbcOpDefault() {
|
||||||
|
shader_code_.push_back(DxbcOpcodeToken(DxbcOpcode::kDefault, 0));
|
||||||
++stat_.instruction_count;
|
++stat_.instruction_count;
|
||||||
|
++stat_.static_flow_control_count;
|
||||||
|
}
|
||||||
|
void DxbcOpDiscard(bool test, const DxbcSrc& src) {
|
||||||
|
DxbcEmitFlowOp(DxbcOpcode::kDiscard, src, test);
|
||||||
}
|
}
|
||||||
void DxbcOpDiv(const DxbcDest& dest, const DxbcSrc& src0, const DxbcSrc& src1,
|
void DxbcOpDiv(const DxbcDest& dest, const DxbcSrc& src0, const DxbcSrc& src1,
|
||||||
bool saturate = false) {
|
bool saturate = false) {
|
||||||
DxbcEmitAluOp(DxbcOpcode::kDiv, 0b00, dest, src0, src1, saturate);
|
DxbcEmitAluOp(DxbcOpcode::kDiv, 0b00, dest, src0, src1, saturate);
|
||||||
++stat_.float_instruction_count;
|
++stat_.float_instruction_count;
|
||||||
}
|
}
|
||||||
|
void DxbcOpElse() {
|
||||||
|
shader_code_.push_back(DxbcOpcodeToken(DxbcOpcode::kElse, 0));
|
||||||
|
++stat_.instruction_count;
|
||||||
|
}
|
||||||
void DxbcOpEndIf() {
|
void DxbcOpEndIf() {
|
||||||
shader_code_.push_back(DxbcOpcodeToken(DxbcOpcode::kEndIf, 0));
|
shader_code_.push_back(DxbcOpcodeToken(DxbcOpcode::kEndIf, 0));
|
||||||
++stat_.instruction_count;
|
++stat_.instruction_count;
|
||||||
|
@ -995,10 +1056,24 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
||||||
shader_code_.push_back(DxbcOpcodeToken(DxbcOpcode::kEndSwitch, 0));
|
shader_code_.push_back(DxbcOpcodeToken(DxbcOpcode::kEndSwitch, 0));
|
||||||
++stat_.instruction_count;
|
++stat_.instruction_count;
|
||||||
}
|
}
|
||||||
|
void DxbcOpEq(const DxbcDest& dest, const DxbcSrc& src0,
|
||||||
|
const DxbcSrc& src1) {
|
||||||
|
DxbcEmitAluOp(DxbcOpcode::kEq, 0b00, dest, src0, src1);
|
||||||
|
++stat_.float_instruction_count;
|
||||||
|
}
|
||||||
|
void DxbcOpFToI(const DxbcDest& dest, const DxbcSrc& src) {
|
||||||
|
DxbcEmitAluOp(DxbcOpcode::kFToI, 0b0, dest, src);
|
||||||
|
++stat_.conversion_instruction_count;
|
||||||
|
}
|
||||||
void DxbcOpFToU(const DxbcDest& dest, const DxbcSrc& src) {
|
void DxbcOpFToU(const DxbcDest& dest, const DxbcSrc& src) {
|
||||||
DxbcEmitAluOp(DxbcOpcode::kFToU, 0b0, dest, src);
|
DxbcEmitAluOp(DxbcOpcode::kFToU, 0b0, dest, src);
|
||||||
++stat_.conversion_instruction_count;
|
++stat_.conversion_instruction_count;
|
||||||
}
|
}
|
||||||
|
void DxbcOpGE(const DxbcDest& dest, const DxbcSrc& src0,
|
||||||
|
const DxbcSrc& src1) {
|
||||||
|
DxbcEmitAluOp(DxbcOpcode::kGE, 0b00, dest, src0, src1);
|
||||||
|
++stat_.float_instruction_count;
|
||||||
|
}
|
||||||
void DxbcOpIAdd(const DxbcDest& dest, const DxbcSrc& src0,
|
void DxbcOpIAdd(const DxbcDest& dest, const DxbcSrc& src0,
|
||||||
const DxbcSrc& src1) {
|
const DxbcSrc& src1) {
|
||||||
DxbcEmitAluOp(DxbcOpcode::kIAdd, 0b11, dest, src0, src1);
|
DxbcEmitAluOp(DxbcOpcode::kIAdd, 0b11, dest, src0, src1);
|
||||||
|
@ -1008,16 +1083,60 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
||||||
DxbcEmitFlowOp(DxbcOpcode::kIf, src, test);
|
DxbcEmitFlowOp(DxbcOpcode::kIf, src, test);
|
||||||
++stat_.dynamic_flow_control_count;
|
++stat_.dynamic_flow_control_count;
|
||||||
}
|
}
|
||||||
|
void DxbcOpIEq(const DxbcDest& dest, const DxbcSrc& src0,
|
||||||
|
const DxbcSrc& src1) {
|
||||||
|
DxbcEmitAluOp(DxbcOpcode::kIEq, 0b11, dest, src0, src1);
|
||||||
|
++stat_.int_instruction_count;
|
||||||
|
}
|
||||||
|
void DxbcOpILT(const DxbcDest& dest, const DxbcSrc& src0,
|
||||||
|
const DxbcSrc& src1) {
|
||||||
|
DxbcEmitAluOp(DxbcOpcode::kILT, 0b11, dest, src0, src1);
|
||||||
|
++stat_.int_instruction_count;
|
||||||
|
}
|
||||||
void DxbcOpIMAd(const DxbcDest& dest, const DxbcSrc& mul0,
|
void DxbcOpIMAd(const DxbcDest& dest, const DxbcSrc& mul0,
|
||||||
const DxbcSrc& mul1, const DxbcSrc& add) {
|
const DxbcSrc& mul1, const DxbcSrc& add) {
|
||||||
DxbcEmitAluOp(DxbcOpcode::kIMAd, 0b111, dest, mul0, mul1, add);
|
DxbcEmitAluOp(DxbcOpcode::kIMAd, 0b111, dest, mul0, mul1, add);
|
||||||
++stat_.int_instruction_count;
|
++stat_.int_instruction_count;
|
||||||
}
|
}
|
||||||
|
void DxbcOpIMax(const DxbcDest& dest, const DxbcSrc& src0,
|
||||||
|
const DxbcSrc& src1) {
|
||||||
|
DxbcEmitAluOp(DxbcOpcode::kIMax, 0b11, dest, src0, src1);
|
||||||
|
++stat_.int_instruction_count;
|
||||||
|
}
|
||||||
|
void DxbcOpIMin(const DxbcDest& dest, const DxbcSrc& src0,
|
||||||
|
const DxbcSrc& src1) {
|
||||||
|
DxbcEmitAluOp(DxbcOpcode::kIMin, 0b11, dest, src0, src1);
|
||||||
|
++stat_.int_instruction_count;
|
||||||
|
}
|
||||||
|
void DxbcOpINE(const DxbcDest& dest, const DxbcSrc& src0,
|
||||||
|
const DxbcSrc& src1) {
|
||||||
|
DxbcEmitAluOp(DxbcOpcode::kINE, 0b11, dest, src0, src1);
|
||||||
|
++stat_.int_instruction_count;
|
||||||
|
}
|
||||||
void DxbcOpIShL(const DxbcDest& dest, const DxbcSrc& value,
|
void DxbcOpIShL(const DxbcDest& dest, const DxbcSrc& value,
|
||||||
const DxbcSrc& shift) {
|
const DxbcSrc& shift) {
|
||||||
DxbcEmitAluOp(DxbcOpcode::kIShL, 0b11, dest, value, shift);
|
DxbcEmitAluOp(DxbcOpcode::kIShL, 0b11, dest, value, shift);
|
||||||
++stat_.int_instruction_count;
|
++stat_.int_instruction_count;
|
||||||
}
|
}
|
||||||
|
void DxbcOpIToF(const DxbcDest& dest, const DxbcSrc& src) {
|
||||||
|
DxbcEmitAluOp(DxbcOpcode::kIToF, 0b1, dest, src);
|
||||||
|
++stat_.conversion_instruction_count;
|
||||||
|
}
|
||||||
|
void DxbcOpLabel(const DxbcSrc& label) {
|
||||||
|
// The label is source, not destination, for simplicity, to unify it will
|
||||||
|
// call/callc (in DXBC it's just a zero-component label operand).
|
||||||
|
uint32_t operands_length = label.GetLength(0b0000);
|
||||||
|
shader_code_.reserve(shader_code_.size() + 1 + operands_length);
|
||||||
|
shader_code_.push_back(
|
||||||
|
DxbcOpcodeToken(DxbcOpcode::kLabel, operands_length));
|
||||||
|
label.Write(shader_code_, true, 0b0000);
|
||||||
|
// Doesn't count towards stat_.instruction_count.
|
||||||
|
}
|
||||||
|
void DxbcOpLT(const DxbcDest& dest, const DxbcSrc& src0,
|
||||||
|
const DxbcSrc& src1) {
|
||||||
|
DxbcEmitAluOp(DxbcOpcode::kLT, 0b00, dest, src0, src1);
|
||||||
|
++stat_.float_instruction_count;
|
||||||
|
}
|
||||||
void DxbcOpMAd(const DxbcDest& dest, const DxbcSrc& mul0, const DxbcSrc& mul1,
|
void DxbcOpMAd(const DxbcDest& dest, const DxbcSrc& mul0, const DxbcSrc& mul1,
|
||||||
const DxbcSrc& add, bool saturate = false) {
|
const DxbcSrc& add, bool saturate = false) {
|
||||||
DxbcEmitAluOp(DxbcOpcode::kMAd, 0b000, dest, mul0, mul1, add, saturate);
|
DxbcEmitAluOp(DxbcOpcode::kMAd, 0b000, dest, mul0, mul1, add, saturate);
|
||||||
|
@ -1050,10 +1169,43 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
||||||
saturate);
|
saturate);
|
||||||
++stat_.movc_instruction_count;
|
++stat_.movc_instruction_count;
|
||||||
}
|
}
|
||||||
|
void DxbcOpMul(const DxbcDest& dest, const DxbcSrc& src0, const DxbcSrc& src1,
|
||||||
|
bool saturate = false) {
|
||||||
|
DxbcEmitAluOp(DxbcOpcode::kMul, 0b00, dest, src0, src1, saturate);
|
||||||
|
++stat_.float_instruction_count;
|
||||||
|
}
|
||||||
|
void DxbcOpNot(const DxbcDest& dest, const DxbcSrc& src) {
|
||||||
|
DxbcEmitAluOp(DxbcOpcode::kNot, 0b1, dest, src);
|
||||||
|
++stat_.uint_instruction_count;
|
||||||
|
}
|
||||||
|
void DxbcOpOr(const DxbcDest& dest, const DxbcSrc& src0,
|
||||||
|
const DxbcSrc& src1) {
|
||||||
|
DxbcEmitAluOp(DxbcOpcode::kOr, 0b11, dest, src0, src1);
|
||||||
|
++stat_.uint_instruction_count;
|
||||||
|
}
|
||||||
|
void DxbcOpRet() {
|
||||||
|
shader_code_.push_back(DxbcOpcodeToken(DxbcOpcode::kRet, 0));
|
||||||
|
++stat_.instruction_count;
|
||||||
|
++stat_.static_flow_control_count;
|
||||||
|
}
|
||||||
void DxbcOpRetC(bool test, const DxbcSrc& src) {
|
void DxbcOpRetC(bool test, const DxbcSrc& src) {
|
||||||
DxbcEmitFlowOp(DxbcOpcode::kRetC, src, test);
|
DxbcEmitFlowOp(DxbcOpcode::kRetC, src, test);
|
||||||
++stat_.dynamic_flow_control_count;
|
++stat_.dynamic_flow_control_count;
|
||||||
}
|
}
|
||||||
|
void DxbcOpRoundNE(const DxbcDest& dest, const DxbcSrc& src,
|
||||||
|
bool saturate = false) {
|
||||||
|
DxbcEmitAluOp(DxbcOpcode::kRoundNE, 0b0, dest, src, saturate);
|
||||||
|
++stat_.float_instruction_count;
|
||||||
|
}
|
||||||
|
void DxbcOpSwitch(const DxbcSrc& src) {
|
||||||
|
DxbcEmitFlowOp(DxbcOpcode::kSwitch, src);
|
||||||
|
++stat_.dynamic_flow_control_count;
|
||||||
|
}
|
||||||
|
void DxbcOpULT(const DxbcDest& dest, const DxbcSrc& src0,
|
||||||
|
const DxbcSrc& src1) {
|
||||||
|
DxbcEmitAluOp(DxbcOpcode::kULT, 0b11, dest, src0, src1);
|
||||||
|
++stat_.uint_instruction_count;
|
||||||
|
}
|
||||||
void DxbcOpUGE(const DxbcDest& dest, const DxbcSrc& src0,
|
void DxbcOpUGE(const DxbcDest& dest, const DxbcSrc& src0,
|
||||||
const DxbcSrc& src1) {
|
const DxbcSrc& src1) {
|
||||||
DxbcEmitAluOp(DxbcOpcode::kUGE, 0b11, dest, src0, src1);
|
DxbcEmitAluOp(DxbcOpcode::kUGE, 0b11, dest, src0, src1);
|
||||||
|
@ -1069,11 +1221,25 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
||||||
DxbcEmitAluOp(DxbcOpcode::kUMAd, 0b111, dest, mul0, mul1, add);
|
DxbcEmitAluOp(DxbcOpcode::kUMAd, 0b111, dest, mul0, mul1, add);
|
||||||
++stat_.uint_instruction_count;
|
++stat_.uint_instruction_count;
|
||||||
}
|
}
|
||||||
|
void DxbcOpUMax(const DxbcDest& dest, const DxbcSrc& src0,
|
||||||
|
const DxbcSrc& src1) {
|
||||||
|
DxbcEmitAluOp(DxbcOpcode::kUMax, 0b11, dest, src0, src1);
|
||||||
|
++stat_.uint_instruction_count;
|
||||||
|
}
|
||||||
|
void DxbcOpUMin(const DxbcDest& dest, const DxbcSrc& src0,
|
||||||
|
const DxbcSrc& src1) {
|
||||||
|
DxbcEmitAluOp(DxbcOpcode::kUMin, 0b11, dest, src0, src1);
|
||||||
|
++stat_.uint_instruction_count;
|
||||||
|
}
|
||||||
void DxbcOpUShR(const DxbcDest& dest, const DxbcSrc& value,
|
void DxbcOpUShR(const DxbcDest& dest, const DxbcSrc& value,
|
||||||
const DxbcSrc& shift) {
|
const DxbcSrc& shift) {
|
||||||
DxbcEmitAluOp(DxbcOpcode::kUShR, 0b11, dest, value, shift);
|
DxbcEmitAluOp(DxbcOpcode::kUShR, 0b11, dest, value, shift);
|
||||||
++stat_.uint_instruction_count;
|
++stat_.uint_instruction_count;
|
||||||
}
|
}
|
||||||
|
void DxbcOpUToF(const DxbcDest& dest, const DxbcSrc& src) {
|
||||||
|
DxbcEmitAluOp(DxbcOpcode::kUToF, 0b1, dest, src);
|
||||||
|
++stat_.conversion_instruction_count;
|
||||||
|
}
|
||||||
void DxbcOpXOr(const DxbcDest& dest, const DxbcSrc& src0,
|
void DxbcOpXOr(const DxbcDest& dest, const DxbcSrc& src0,
|
||||||
const DxbcSrc& src1) {
|
const DxbcSrc& src1) {
|
||||||
DxbcEmitAluOp(DxbcOpcode::kXOr, 0b11, dest, src0, src1);
|
DxbcEmitAluOp(DxbcOpcode::kXOr, 0b11, dest, src0, src1);
|
||||||
|
@ -1099,6 +1265,18 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
||||||
DxbcEmitAluOp(DxbcOpcode::kDerivRTYFine, 0b0, dest, src, saturate);
|
DxbcEmitAluOp(DxbcOpcode::kDerivRTYFine, 0b0, dest, src, saturate);
|
||||||
++stat_.float_instruction_count;
|
++stat_.float_instruction_count;
|
||||||
}
|
}
|
||||||
|
void DxbcOpF32ToF16(const DxbcDest& dest, const DxbcSrc& src) {
|
||||||
|
DxbcEmitAluOp(DxbcOpcode::kF32ToF16, 0b0, dest, src);
|
||||||
|
++stat_.conversion_instruction_count;
|
||||||
|
}
|
||||||
|
void DxbcOpF16ToF32(const DxbcDest& dest, const DxbcSrc& src) {
|
||||||
|
DxbcEmitAluOp(DxbcOpcode::kF16ToF32, 0b1, dest, src);
|
||||||
|
++stat_.conversion_instruction_count;
|
||||||
|
}
|
||||||
|
void DxbcOpFirstBitHi(const DxbcDest& dest, const DxbcSrc& src) {
|
||||||
|
DxbcEmitAluOp(DxbcOpcode::kFirstBitHi, 0b1, dest, src);
|
||||||
|
++stat_.uint_instruction_count;
|
||||||
|
}
|
||||||
void DxbcOpUBFE(const DxbcDest& dest, const DxbcSrc& width,
|
void DxbcOpUBFE(const DxbcDest& dest, const DxbcSrc& width,
|
||||||
const DxbcSrc& offset, const DxbcSrc& src) {
|
const DxbcSrc& offset, const DxbcSrc& src) {
|
||||||
DxbcEmitAluOp(DxbcOpcode::kUBFE, 0b111, dest, width, offset, src);
|
DxbcEmitAluOp(DxbcOpcode::kUBFE, 0b111, dest, width, offset, src);
|
||||||
|
@ -1115,6 +1293,40 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
||||||
DxbcEmitAluOp(DxbcOpcode::kBFI, 0b1111, dest, width, offset, from, to);
|
DxbcEmitAluOp(DxbcOpcode::kBFI, 0b1111, dest, width, offset, from, to);
|
||||||
++stat_.uint_instruction_count;
|
++stat_.uint_instruction_count;
|
||||||
}
|
}
|
||||||
|
void DxbcOpLdUAVTyped(const DxbcDest& dest, const DxbcSrc& address,
|
||||||
|
uint32_t address_components, const DxbcSrc& uav) {
|
||||||
|
uint32_t dest_write_mask = dest.GetMask();
|
||||||
|
uint32_t address_mask = (1 << address_components) - 1;
|
||||||
|
uint32_t operands_length = dest.GetLength() +
|
||||||
|
address.GetLength(address_mask, true) +
|
||||||
|
uav.GetLength(dest_write_mask, true);
|
||||||
|
shader_code_.reserve(shader_code_.size() + 1 + operands_length);
|
||||||
|
shader_code_.push_back(
|
||||||
|
DxbcOpcodeToken(DxbcOpcode::kLdUAVTyped, operands_length));
|
||||||
|
dest.Write(shader_code_);
|
||||||
|
address.Write(shader_code_, true, address_mask, true);
|
||||||
|
uav.Write(shader_code_, false, dest_write_mask, true);
|
||||||
|
++stat_.instruction_count;
|
||||||
|
++stat_.texture_load_instructions;
|
||||||
|
}
|
||||||
|
void DxbcOpStoreUAVTyped(const DxbcDest& dest, const DxbcSrc& address,
|
||||||
|
uint32_t address_components, const DxbcSrc& value) {
|
||||||
|
uint32_t dest_write_mask = dest.GetMask();
|
||||||
|
// Typed UAV writes don't support write masking.
|
||||||
|
assert_true(dest_write_mask == 0b1111);
|
||||||
|
uint32_t address_mask = (1 << address_components) - 1;
|
||||||
|
uint32_t operands_length = dest.GetLength() +
|
||||||
|
address.GetLength(address_mask, true) +
|
||||||
|
value.GetLength(dest_write_mask);
|
||||||
|
shader_code_.reserve(shader_code_.size() + 1 + operands_length);
|
||||||
|
shader_code_.push_back(
|
||||||
|
DxbcOpcodeToken(DxbcOpcode::kStoreUAVTyped, operands_length));
|
||||||
|
dest.Write(shader_code_);
|
||||||
|
address.Write(shader_code_, true, address_mask, true);
|
||||||
|
value.Write(shader_code_, false, dest_write_mask);
|
||||||
|
++stat_.instruction_count;
|
||||||
|
++stat_.c_texture_store_instructions;
|
||||||
|
}
|
||||||
void DxbcOpEvalSampleIndex(const DxbcDest& dest, const DxbcSrc& value,
|
void DxbcOpEvalSampleIndex(const DxbcDest& dest, const DxbcSrc& value,
|
||||||
const DxbcSrc& sample_index) {
|
const DxbcSrc& sample_index) {
|
||||||
uint32_t dest_write_mask = dest.GetMask();
|
uint32_t dest_write_mask = dest.GetMask();
|
||||||
|
@ -1125,8 +1337,8 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
||||||
shader_code_.push_back(
|
shader_code_.push_back(
|
||||||
DxbcOpcodeToken(DxbcOpcode::kEvalSampleIndex, operands_length));
|
DxbcOpcodeToken(DxbcOpcode::kEvalSampleIndex, operands_length));
|
||||||
dest.Write(shader_code_);
|
dest.Write(shader_code_);
|
||||||
value.Write(shader_code_, dest_write_mask, false);
|
value.Write(shader_code_, false, dest_write_mask);
|
||||||
sample_index.Write(shader_code_, 0b0000, true);
|
sample_index.Write(shader_code_, true, 0b0000);
|
||||||
++stat_.instruction_count;
|
++stat_.instruction_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1444,15 +1656,9 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
||||||
// multiple times.
|
// multiple times.
|
||||||
void ExportToMemory();
|
void ExportToMemory();
|
||||||
void CompleteVertexOrDomainShader();
|
void CompleteVertexOrDomainShader();
|
||||||
// Applies the exponent bias from the constant to one color output.
|
|
||||||
void CompletePixelShader_ApplyColorExpBias(uint32_t rt_index);
|
|
||||||
// Discards the SSAA sample if it fails alpha to coverage.
|
// Discards the SSAA sample if it fails alpha to coverage.
|
||||||
void CompletePixelShader_WriteToRTVs_AlphaToCoverage();
|
void CompletePixelShader_WriteToRTVs_AlphaToCoverage();
|
||||||
void CompletePixelShader_WriteToRTVs();
|
void CompletePixelShader_WriteToRTVs();
|
||||||
// Returns if coverage in system_temp_rov_params_.x is empty.
|
|
||||||
void CompletePixelShader_ROV_CheckAnyCovered(
|
|
||||||
bool check_deferred_stencil_write, uint32_t temp,
|
|
||||||
uint32_t temp_component);
|
|
||||||
// Masks the sample away from system_temp_rov_params_.x if it's not covered.
|
// Masks the sample away from system_temp_rov_params_.x if it's not covered.
|
||||||
void CompletePixelShader_ROV_AlphaToCoverageSample(uint32_t sample_index,
|
void CompletePixelShader_ROV_AlphaToCoverageSample(uint32_t sample_index,
|
||||||
float threshold,
|
float threshold,
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -49,12 +49,21 @@ std::pair<std::string, std::string> Shader::Dump(const std::string& base_path,
|
||||||
xe::filesystem::CreateFolder(target_path);
|
xe::filesystem::CreateFolder(target_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
char txt_file_name[kMaxPath];
|
const std::string file_name_no_extension =
|
||||||
std::snprintf(txt_file_name, xe::countof(txt_file_name),
|
xe::format_string("%s/shader_%s_%.16" PRIX64, base_path.c_str(),
|
||||||
"%s/shader_%s_%.16" PRIX64 ".%s", base_path.c_str(),
|
path_prefix, ucode_data_hash_);
|
||||||
path_prefix, ucode_data_hash_,
|
|
||||||
shader_type_ == ShaderType::kVertex ? "vert" : "frag");
|
std::string txt_file_name, bin_file_name;
|
||||||
FILE* f = fopen(txt_file_name, "wb");
|
|
||||||
|
if (shader_type_ == ShaderType::kVertex) {
|
||||||
|
txt_file_name = file_name_no_extension + ".vert";
|
||||||
|
bin_file_name = file_name_no_extension + ".bin.vert";
|
||||||
|
} else {
|
||||||
|
txt_file_name = file_name_no_extension + ".frag";
|
||||||
|
bin_file_name = file_name_no_extension + ".bin.frag";
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE* f = fopen(txt_file_name.c_str(), "wb");
|
||||||
if (f) {
|
if (f) {
|
||||||
fwrite(translated_binary_.data(), 1, translated_binary_.size(), f);
|
fwrite(translated_binary_.data(), 1, translated_binary_.size(), f);
|
||||||
fprintf(f, "\n\n");
|
fprintf(f, "\n\n");
|
||||||
|
@ -72,18 +81,13 @@ std::pair<std::string, std::string> Shader::Dump(const std::string& base_path,
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
char bin_file_name[kMaxPath];
|
f = fopen(bin_file_name.c_str(), "wb");
|
||||||
std::snprintf(bin_file_name, xe::countof(bin_file_name),
|
|
||||||
"%s/shader_%s_%.16" PRIX64 ".bin.%s", base_path.c_str(),
|
|
||||||
path_prefix, ucode_data_hash_,
|
|
||||||
shader_type_ == ShaderType::kVertex ? "vert" : "frag");
|
|
||||||
f = fopen(bin_file_name, "wb");
|
|
||||||
if (f) {
|
if (f) {
|
||||||
fwrite(ucode_data_.data(), 4, ucode_data_.size(), f);
|
fwrite(ucode_data_.data(), 4, ucode_data_.size(), f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {std::string(txt_file_name), std::string(bin_file_name)};
|
return {std::move(txt_file_name), std::move(bin_file_name)};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace gpu
|
} // namespace gpu
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Copyright 2019 Ben Vanik. All rights reserved. *
|
* Copyright 2020 Ben Vanik. All rights reserved. *
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -19,12 +19,12 @@ project("xenia-hid-sdl")
|
||||||
filter("platforms:Windows")
|
filter("platforms:Windows")
|
||||||
-- On linux we build against the system version (libsdl2-dev)
|
-- On linux we build against the system version (libsdl2-dev)
|
||||||
includedirs({
|
includedirs({
|
||||||
project_root.."/third_party/SDL2/include/",
|
project_root.."/third_party/SDL2-devel-VC/include/",
|
||||||
})
|
})
|
||||||
libdirs({
|
libdirs({
|
||||||
project_root.."/third_party/SDL2/lib/x64/",
|
project_root.."/third_party/SDL2-devel-VC/lib/x64/",
|
||||||
})
|
})
|
||||||
-- Copy the dll to the output folder
|
-- Copy the dll to the output folder
|
||||||
postbuildcommands({
|
postbuildcommands({
|
||||||
"{COPY} %{prj.basedir}/"..project_root.."/third_party/SDL2/lib/x64/SDL2.dll %{cfg.targetdir}",
|
"{COPY} %{prj.basedir}/"..project_root.."/third_party/SDL2-devel-VC/lib/x64/SDL2.dll %{cfg.targetdir}",
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Copyright 2019 Ben Vanik. All rights reserved. *
|
* Copyright 2020 Ben Vanik. All rights reserved. *
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Copyright 2019 Ben Vanik. All rights reserved. *
|
* Copyright 2020 Ben Vanik. All rights reserved. *
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Copyright 2019 Ben Vanik. All rights reserved. *
|
* Copyright 2020 Ben Vanik. All rights reserved. *
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Copyright 2019 Ben Vanik. All rights reserved. *
|
* Copyright 2020 Ben Vanik. All rights reserved. *
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -97,14 +97,13 @@ dword_result_t NtAllocateVirtualMemory(lpdword_t base_addr_ptr,
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t page_size;
|
uint32_t page_size;
|
||||||
|
|
||||||
if (*base_addr_ptr != 0) {
|
if (*base_addr_ptr != 0) {
|
||||||
// TODO(gibbed): ignore specified page size when base address is specified.
|
// ignore specified page size when base address is specified.
|
||||||
auto heap = kernel_memory()->LookupHeap(*base_addr_ptr);
|
auto heap = kernel_memory()->LookupHeap(*base_addr_ptr);
|
||||||
page_size = heap->page_size();
|
page_size = heap->page_size();
|
||||||
} else {
|
} else {
|
||||||
// Adjust size.
|
// Adjust size.
|
||||||
page_size = 4096;
|
page_size = 4 * 1024;
|
||||||
if (alloc_type & X_MEM_LARGE_PAGES) {
|
if (alloc_type & X_MEM_LARGE_PAGES) {
|
||||||
page_size = 64 * 1024;
|
page_size = 64 * 1024;
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ DECLARE_XBOXKRNL_EXPORT1(ObLookupThreadByThreadId, kNone, kImplemented);
|
||||||
dword_result_t ObReferenceObjectByHandle(dword_t handle,
|
dword_result_t ObReferenceObjectByHandle(dword_t handle,
|
||||||
dword_t object_type_ptr,
|
dword_t object_type_ptr,
|
||||||
lpdword_t out_object_ptr) {
|
lpdword_t out_object_ptr) {
|
||||||
const std::pair<XObject::Type, uint32_t> obj_type_match[] = {
|
const static std::unordered_map<XObject::Type, uint32_t> obj_type_match = {
|
||||||
{XObject::kTypeEvent, 0xD00EBEEF},
|
{XObject::kTypeEvent, 0xD00EBEEF},
|
||||||
{XObject::kTypeSemaphore, 0xD017BEEF},
|
{XObject::kTypeSemaphore, 0xD017BEEF},
|
||||||
{XObject::kTypeThread, 0xD01BBEEF}};
|
{XObject::kTypeThread, 0xD01BBEEF}};
|
||||||
|
@ -90,17 +90,12 @@ dword_result_t ObReferenceObjectByHandle(dword_t handle,
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t native_ptr = object->guest_object();
|
uint32_t native_ptr = object->guest_object();
|
||||||
|
auto obj_type = obj_type_match.find(object->type());
|
||||||
|
|
||||||
auto obj_type = std::find_if(
|
if (obj_type != obj_type_match.end()) {
|
||||||
std::begin(obj_type_match), std::end(obj_type_match),
|
if (object_type_ptr && object_type_ptr != obj_type->second) {
|
||||||
[object](const auto& entry) { return entry.first == object->type(); });
|
|
||||||
|
|
||||||
if (obj_type != std::end(obj_type_match)) {
|
|
||||||
if (object_type_ptr) {
|
|
||||||
if (object_type_ptr != obj_type->second) {
|
|
||||||
return X_STATUS_OBJECT_TYPE_MISMATCH;
|
return X_STATUS_OBJECT_TYPE_MISMATCH;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
assert_unhandled_case(object->type());
|
assert_unhandled_case(object->type());
|
||||||
native_ptr = 0xDEADF00D;
|
native_ptr = 0xDEADF00D;
|
||||||
|
|
|
@ -28,14 +28,14 @@ class UIEvent {
|
||||||
|
|
||||||
class FileDropEvent : public UIEvent {
|
class FileDropEvent : public UIEvent {
|
||||||
public:
|
public:
|
||||||
FileDropEvent(Window* target, wchar_t* filename)
|
FileDropEvent(Window* target, const wchar_t* filename)
|
||||||
: UIEvent(target), filename_(filename) {}
|
: UIEvent(target), filename_(filename) {}
|
||||||
~FileDropEvent() override = default;
|
~FileDropEvent() override = default;
|
||||||
|
|
||||||
wchar_t* filename() const { return filename_; }
|
const wchar_t* filename() const { return filename_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
wchar_t* filename_ = nullptr;
|
const wchar_t* filename_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class KeyEvent : public UIEvent {
|
class KeyEvent : public UIEvent {
|
||||||
|
|
|
@ -492,17 +492,20 @@ LRESULT Win32Window::WndProc(HWND hWnd, UINT message, WPARAM wParam,
|
||||||
|
|
||||||
switch (message) {
|
switch (message) {
|
||||||
case WM_DROPFILES: {
|
case WM_DROPFILES: {
|
||||||
TCHAR lpszFile[MAX_PATH] = {0};
|
HDROP hDrop = reinterpret_cast<HDROP>(wParam);
|
||||||
UINT uFiles = 0;
|
std::wstring path;
|
||||||
HDROP hDrop = (HDROP)wParam;
|
|
||||||
// Get number of files dropped
|
// Get required buffer size
|
||||||
uFiles = DragQueryFile(hDrop, -1, NULL, NULL);
|
UINT buf_size = DragQueryFileW(hDrop, 0, nullptr, 0);
|
||||||
|
if (buf_size > 0) {
|
||||||
|
path.resize(buf_size + 1); // Give space for a null terminator
|
||||||
|
|
||||||
// Only getting first file dropped (other files ignored)
|
// Only getting first file dropped (other files ignored)
|
||||||
if (DragQueryFile(hDrop, 0, lpszFile, MAX_PATH)) {
|
if (DragQueryFileW(hDrop, 0, &path[0], buf_size + 1)) {
|
||||||
auto e = FileDropEvent(this, lpszFile);
|
auto e = FileDropEvent(this, path.c_str());
|
||||||
OnFileDrop(&e);
|
OnFileDrop(&e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DragFinish(hDrop);
|
DragFinish(hDrop);
|
||||||
} break;
|
} break;
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit f102d8b36395200682108e88bec54bf9acd1004a
|
|
@ -649,7 +649,7 @@ class BaseBuildCommand(Command):
|
||||||
else:
|
else:
|
||||||
result = subprocess.call([
|
result = subprocess.call([
|
||||||
'make',
|
'make',
|
||||||
'-j' if threads is 0 else '-j%d' % threads,
|
'-j' if threads == 0 else '-j%d' % threads,
|
||||||
'-Cbuild/',
|
'-Cbuild/',
|
||||||
'config=%s_linux' % (args['config']),
|
'config=%s_linux' % (args['config']),
|
||||||
] + pass_args + args['target'], shell=False, env=dict(os.environ))
|
] + pass_args + args['target'], shell=False, env=dict(os.environ))
|
||||||
|
|
Loading…
Reference in New Issue