Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e8238b8455 | |||
| cbf35ffdb5 | |||
| f90ddeabd0 | |||
| 372b9f9dc2 | |||
| a58a63aa72 | |||
| 4a220aa518 | |||
| c3a7eac375 | |||
| 82c31a9f73 | |||
| c530e3cf3d | |||
| 8e6fe717ab | |||
| d9350149e2 | |||
| 918a277e62 | |||
| 7a01b2ccb1 | |||
| b0742e08d9 | |||
| 9d635139ed | |||
| 788469a66e | |||
| f2df1da3a1 | |||
| a4fec2de6f | |||
| 56a0a3a608 | |||
| 6060c6a342 | |||
| 29453f6d16 | |||
| 65642c28c6 | |||
| 0ada09bfd3 | |||
| d49ee7886c | |||
| f4f4f16cdc | |||
| c1830965f5 | |||
| 4f14116a04 | |||
| d85dee5be4 | |||
| c2d9a0e512 | |||
| db9b2055ce | |||
| acfae4a34e | |||
| e80afa2b77 | |||
| 357decdfdc | |||
| c958715a19 | |||
| 9aba3e21fd | |||
| 52664cc501 | |||
| a13c875e75 | |||
| c47fb72015 |
@@ -55,6 +55,7 @@ rpcs3/git-version.h
|
||||
|
||||
# Visual Studio Files
|
||||
.vs/*
|
||||
*.ipch
|
||||
*.vspx
|
||||
*.psess
|
||||
*.VC.*
|
||||
|
||||
+2
-3
@@ -8,7 +8,6 @@
|
||||
[submodule "llvm"]
|
||||
path = llvm
|
||||
url = https://github.com/llvm-mirror/llvm
|
||||
branch = release_40
|
||||
[submodule "rsx_program_decompiler"]
|
||||
path = rsx_program_decompiler
|
||||
url = https://github.com/RPCS3/rsx_program_decompiler
|
||||
@@ -17,7 +16,7 @@
|
||||
url = https://github.com/Microsoft/GSL.git
|
||||
[submodule "libpng"]
|
||||
path = 3rdparty/libpng
|
||||
url = https://github.com/RPCS3/libpng
|
||||
url = https://github.com/Zangetsu38/libpng
|
||||
ignore = dirty
|
||||
[submodule "Vulkan/glslang"]
|
||||
path = Vulkan/glslang
|
||||
@@ -42,5 +41,5 @@
|
||||
url = https://github.com/madler/zlib
|
||||
[submodule "3rdparty/hidapi"]
|
||||
path = 3rdparty/hidapi
|
||||
url = https://github.com/RPCS3/hidapi
|
||||
url = https://github.com/Zangetsu38/hidapi
|
||||
branch = master
|
||||
+2
-1
@@ -87,10 +87,11 @@ before_script:
|
||||
./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -bundle-non-qt-libs ;
|
||||
./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -appimage ;
|
||||
find ./appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq ;
|
||||
zip -r9 rpcs3.zip ./RPCS3*.AppImage;
|
||||
if [ -z "$WITHOUT_LLVM" ]; then
|
||||
export LLVM="-LLVM";
|
||||
fi;
|
||||
curl ${UPLOAD_URL}${TRAVIS_COMMIT:0:7}-${TRAVIS_BUILD_NUMBER}${LLVM}_linux64 --upload-file ./RPCS3*.AppImage;
|
||||
curl ${UPLOAD_URL}${TRAVIS_COMMIT:0:7}-${TRAVIS_BUILD_NUMBER}${LLVM}_linux64 --upload-file rpcs3.zip;
|
||||
fi;
|
||||
|
||||
script:
|
||||
|
||||
Vendored
+1
-1
Submodule 3rdparty/hidapi updated: c095a22c53...66eed15b05
Vendored
+1
-1
Submodule 3rdparty/libpng updated: 1dcba4d6eb...bbbcaf1122
@@ -21,15 +21,15 @@ If you want to contribute please take a look at the [Coding Style](https://githu
|
||||
## Dependencies
|
||||
|
||||
### Windows
|
||||
* [Visual Studio 2015](https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx)
|
||||
* [Visual C++ Redistributable Packages for Visual Studio 2015](http://www.microsoft.com/en-us/download/details.aspx?id=48145)
|
||||
* [Visual Studio 2017](https://www.visualstudio.com/downloads/)
|
||||
* [Visual C++ Redistributable Packages for Visual Studio 2017](https://go.microsoft.com/fwlink/?LinkId=746572)
|
||||
* [Cmake 3.1.0+](https://www.cmake.org/download/) (required; add to PATH)
|
||||
* [Python 3.3+](https://www.python.org/downloads/) (required; add to PATH)
|
||||
* [Qt 5.7+](https://www.qt.io/download-open-source/) (required; add QTDIR `<QtInstallFolder>\5.7\msvc2015_64\` environment variable if you do not want to use the Visual Studio Qt Plugin)
|
||||
* [Qt 5.9+](https://www.qt.io/download-open-source/) (required; add QTDIR `<QtInstallFolder>\5.9\msvc2015_64\` environment variable if you do not want to use the Visual Studio Qt Plugin)
|
||||
* [Visual Studio Qt Plugin](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.QtVisualStudioTools2015) (optional; see above)
|
||||
|
||||
### Linux
|
||||
* [Qt 5.7+](https://www.qt.io/download-open-source/)
|
||||
* [Qt 5.9+](https://www.qt.io/download-open-source/)
|
||||
* GCC 5.1+ or Clang 3.5.0+ ([not GCC 6.1](https://github.com/RPCS3/rpcs3/issues/1691))
|
||||
* Debian & Ubuntu: `sudo apt-get install cmake build-essential libasound2-dev libopenal-dev libglew-dev zlib1g-dev libedit-dev libvulkan-dev libudev-dev git qt5-default`
|
||||
* Arch: `sudo pacman -S glew openal cmake llvm qt5-base`
|
||||
@@ -47,10 +47,10 @@ To initialize the repository don't forget to execute `git submodule update --ini
|
||||
### Configuring Qt
|
||||
|
||||
*If you're using Visual Studio 2017 without Qt plugin support (or simply dont want to use it):*
|
||||
1) Add `QTDIR` environment variable and set it to `<QtInstallFolder>\5.7\msvc2015_64\` </br>
|
||||
1) Add `QTDIR` environment variable and set it to `<QtInstallFolder>\5.9\msvc2017_64\` </br>
|
||||
|
||||
*If you wish to use the Visual Studio plugin for Qt:* </br>
|
||||
1) Go to the Qt5 menu and edit Qt5 options. Add the path to your Qt installation with compiler e.g. `C:\Qt\5.7\msvc2015_64`. </br>
|
||||
1) Go to the Qt5 menu and edit Qt5 options. Add the path to your Qt installation with compiler e.g. `C:\Qt\5.8\msvc2015_64`. </br>
|
||||
2) While selecting the rpcs3qt project, go to Qt5->Project Setting and select the version you added.
|
||||
|
||||
### Building the projects
|
||||
|
||||
+11
-39
@@ -12,7 +12,6 @@
|
||||
#include "File.h"
|
||||
#include "Log.h"
|
||||
#include "mutex.h"
|
||||
#include "sysinfo.h"
|
||||
#include "VirtualMemory.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@@ -258,11 +257,11 @@ struct MemoryManager : llvm::RTDyldMemoryManager
|
||||
return RTDyldMemoryManager::registerEHFrames(addr, load_addr, size);
|
||||
}
|
||||
|
||||
virtual void deregisterEHFrames(u8* addr, u64 load_addr, std::size_t size) override
|
||||
virtual void deregisterEHFrames() override
|
||||
{
|
||||
LOG_ERROR(GENERAL, "deregisterEHFrames() called"); // Not expected
|
||||
|
||||
return RTDyldMemoryManager::deregisterEHFrames(addr, load_addr, size);
|
||||
return RTDyldMemoryManager::deregisterEHFrames();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -344,30 +343,22 @@ public:
|
||||
LOG_SUCCESS(GENERAL, "LLVM: Created module: %s", module->getName().data());
|
||||
}
|
||||
|
||||
static std::unique_ptr<llvm::MemoryBuffer> load(const std::string& path)
|
||||
std::unique_ptr<llvm::MemoryBuffer> getObject(const llvm::Module* module) override
|
||||
{
|
||||
if (fs::file cached{path, fs::read})
|
||||
std::string name = m_path;
|
||||
name.append(module->getName());
|
||||
|
||||
if (fs::file cached{name, fs::read})
|
||||
{
|
||||
auto buf = llvm::MemoryBuffer::getNewUninitMemBuffer(cached.size());
|
||||
cached.read(const_cast<char*>(buf->getBufferStart()), buf->getBufferSize());
|
||||
return buf;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<llvm::MemoryBuffer> getObject(const llvm::Module* module) override
|
||||
{
|
||||
std::string path = m_path;
|
||||
path.append(module->getName());
|
||||
|
||||
if (auto buf = load(path))
|
||||
{
|
||||
LOG_SUCCESS(GENERAL, "LLVM: Loaded module: %s", module->getName().data());
|
||||
return buf;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -378,20 +369,6 @@ jit_compiler::jit_compiler(const std::unordered_map<std::string, std::uintptr_t>
|
||||
if (m_cpu.empty())
|
||||
{
|
||||
m_cpu = llvm::sys::getHostCPUName();
|
||||
|
||||
if (m_cpu == "sandybridge" ||
|
||||
m_cpu == "ivybridge" ||
|
||||
m_cpu == "haswell" ||
|
||||
m_cpu == "broadwell" ||
|
||||
m_cpu == "skylake" ||
|
||||
m_cpu == "skylake-avx512" ||
|
||||
m_cpu == "cannonlake")
|
||||
{
|
||||
if (!utils::has_avx())
|
||||
{
|
||||
m_cpu = "nehalem";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string result;
|
||||
@@ -453,11 +430,6 @@ void jit_compiler::add(std::unique_ptr<llvm::Module> module, const std::string&
|
||||
}
|
||||
}
|
||||
|
||||
void jit_compiler::add(const std::string& path)
|
||||
{
|
||||
m_engine->addObjectFile(std::move(llvm::object::ObjectFile::createObjectFile(*ObjectCache::load(path)).get()));
|
||||
}
|
||||
|
||||
void jit_compiler::fin()
|
||||
{
|
||||
m_engine->finalizeObject();
|
||||
|
||||
+1
-4
@@ -49,12 +49,9 @@ public:
|
||||
return m_context;
|
||||
}
|
||||
|
||||
// Add module (path to obj cache dir)
|
||||
// Add module
|
||||
void add(std::unique_ptr<llvm::Module> module, const std::string& path);
|
||||
|
||||
// Add object (path to obj file)
|
||||
void add(const std::string& path);
|
||||
|
||||
// Finalize
|
||||
void fin();
|
||||
|
||||
|
||||
+4
-35
@@ -14,13 +14,9 @@ void fmt_class_string<patch_type>::format(std::string& out, u64 arg)
|
||||
case patch_type::le16: return "le16";
|
||||
case patch_type::le32: return "le32";
|
||||
case patch_type::le64: return "le64";
|
||||
case patch_type::bef32: return "bef32";
|
||||
case patch_type::bef64: return "bef64";
|
||||
case patch_type::be16: return "be16";
|
||||
case patch_type::be32: return "be32";
|
||||
case patch_type::be64: return "be64";
|
||||
case patch_type::lef32: return "lef32";
|
||||
case patch_type::lef64: return "lef64";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
@@ -43,44 +39,23 @@ void patch_engine::append(const std::string& patch)
|
||||
u64 type64 = 0;
|
||||
cfg::try_to_enum_value(&type64, &fmt_class_string<patch_type>::format, patch[0].Scalar());
|
||||
|
||||
struct patch info{};
|
||||
struct patch info;
|
||||
info.type = static_cast<patch_type>(type64);
|
||||
info.offset = patch[1].as<u32>();
|
||||
|
||||
switch (info.type)
|
||||
{
|
||||
case patch_type::bef32:
|
||||
case patch_type::lef32:
|
||||
{
|
||||
info.value_as<f32>() = patch[2].as<f32>();
|
||||
break;
|
||||
}
|
||||
case patch_type::bef64:
|
||||
case patch_type::lef64:
|
||||
{
|
||||
info.value_as<f64>() = patch[2].as<f64>();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
info.value = patch[2].as<u64>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
info.value = patch[2].as<u64>();
|
||||
data.emplace_back(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t patch_engine::apply(const std::string& name, u8* dst) const
|
||||
void patch_engine::apply(const std::string& name, u8* dst) const
|
||||
{
|
||||
const auto found = m_map.find(name);
|
||||
|
||||
if (found == m_map.cend())
|
||||
{
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Apply modifications sequentially
|
||||
@@ -101,13 +76,11 @@ std::size_t patch_engine::apply(const std::string& name, u8* dst) const
|
||||
break;
|
||||
}
|
||||
case patch_type::le32:
|
||||
case patch_type::lef32:
|
||||
{
|
||||
*reinterpret_cast<le_t<u32, 1>*>(ptr) = static_cast<u32>(p.value);
|
||||
break;
|
||||
}
|
||||
case patch_type::le64:
|
||||
case patch_type::lef64:
|
||||
{
|
||||
*reinterpret_cast<le_t<u64, 1>*>(ptr) = static_cast<u64>(p.value);
|
||||
break;
|
||||
@@ -118,19 +91,15 @@ std::size_t patch_engine::apply(const std::string& name, u8* dst) const
|
||||
break;
|
||||
}
|
||||
case patch_type::be32:
|
||||
case patch_type::bef32:
|
||||
{
|
||||
*reinterpret_cast<be_t<u32, 1>*>(ptr) = static_cast<u32>(p.value);
|
||||
break;
|
||||
}
|
||||
case patch_type::be64:
|
||||
case patch_type::bef64:
|
||||
{
|
||||
*reinterpret_cast<be_t<u64, 1>*>(ptr) = static_cast<u64>(p.value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found->second.size();
|
||||
}
|
||||
|
||||
+2
-12
@@ -11,13 +11,9 @@ enum class patch_type
|
||||
le16,
|
||||
le32,
|
||||
le64,
|
||||
lef32,
|
||||
lef64,
|
||||
be16,
|
||||
be32,
|
||||
be64,
|
||||
bef32,
|
||||
bef64,
|
||||
};
|
||||
|
||||
class patch_engine
|
||||
@@ -27,12 +23,6 @@ class patch_engine
|
||||
patch_type type;
|
||||
u32 offset;
|
||||
u64 value;
|
||||
|
||||
template <typename T>
|
||||
T& value_as()
|
||||
{
|
||||
return *reinterpret_cast<T*>(reinterpret_cast<char*>(&value));
|
||||
}
|
||||
};
|
||||
|
||||
// Database
|
||||
@@ -42,6 +32,6 @@ public:
|
||||
// Load from file
|
||||
void append(const std::string& path);
|
||||
|
||||
// Apply patch (returns the number of entries applied)
|
||||
std::size_t apply(const std::string& name, u8* dst) const;
|
||||
// Apply patch
|
||||
void apply(const std::string& name, u8* dst) const;
|
||||
};
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
#include "sysinfo.h"
|
||||
#include "StrFmt.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "windows.h"
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
std::string utils::get_system_info()
|
||||
{
|
||||
std::string result;
|
||||
std::string brand;
|
||||
|
||||
if (get_cpuid(0x80000000, 0)[0] >= 0x80000004)
|
||||
{
|
||||
for (u32 i = 0; i < 3; i++)
|
||||
{
|
||||
brand.append(reinterpret_cast<const char*>(get_cpuid(0x80000002 + i, 0).data()), 16);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
brand = "Unknown CPU";
|
||||
}
|
||||
|
||||
brand.erase(0, brand.find_first_not_of(' '));
|
||||
brand.erase(brand.find_last_not_of(' ') + 1);
|
||||
|
||||
while (auto found = brand.find(" ") + 1)
|
||||
{
|
||||
brand.erase(brand.begin() + found);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
::SYSTEM_INFO sysInfo;
|
||||
::GetNativeSystemInfo(&sysInfo);
|
||||
::MEMORYSTATUSEX memInfo;
|
||||
memInfo.dwLength = sizeof(memInfo);
|
||||
::GlobalMemoryStatusEx(&memInfo);
|
||||
const u32 num_proc = sysInfo.dwNumberOfProcessors;
|
||||
const u64 mem_total = memInfo.ullTotalPhys;
|
||||
#else
|
||||
const u32 num_proc = ::sysconf(_SC_NPROCESSORS_ONLN);
|
||||
const u64 mem_total = ::sysconf(_SC_PHYS_PAGES) * ::sysconf(_SC_PAGE_SIZE);
|
||||
#endif
|
||||
|
||||
fmt::append(result, "%s | %d Threads | %.2f GiB RAM", brand, num_proc, mem_total / (1024.0f * 1024 * 1024));
|
||||
|
||||
if (has_avx())
|
||||
{
|
||||
result += " | AVX";
|
||||
}
|
||||
|
||||
if (has_rtm())
|
||||
{
|
||||
result += " | TSX";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
#include <string>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
inline std::array<u32, 4> get_cpuid(u32 func, u32 subfunc)
|
||||
{
|
||||
int regs[4];
|
||||
#ifdef _MSC_VER
|
||||
__cpuidex(regs, func, subfunc);
|
||||
#else
|
||||
__asm__ volatile("cpuid" : "=a" (regs[0]), "=b" (regs[1]), "=c" (regs[2]), "=d" (regs[3]) : "a" (func), "c" (subfunc));
|
||||
#endif
|
||||
return {0u+regs[0], 0u+regs[1], 0u+regs[2], 0u+regs[3]};
|
||||
}
|
||||
|
||||
inline bool has_ssse3()
|
||||
{
|
||||
return get_cpuid(0, 0)[0] >= 0x1 && get_cpuid(1, 0)[2] & 0x200;
|
||||
}
|
||||
|
||||
inline bool has_avx()
|
||||
{
|
||||
return get_cpuid(0, 0)[0] >= 0x1 && get_cpuid(1, 0)[2] & 0x10000000;
|
||||
}
|
||||
|
||||
inline bool has_rtm()
|
||||
{
|
||||
// Check RTM and MPX extensions in order to filter out TSX on Haswell CPUs
|
||||
return get_cpuid(0, 0)[0] >= 0x7 && (get_cpuid(7, 0)[1] & 0x4800) == 0x4800;
|
||||
}
|
||||
|
||||
inline bool transaction_enter()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
const auto status = _xbegin();
|
||||
|
||||
if (status == _XBEGIN_STARTED)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(status & _XABORT_RETRY))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string get_system_info();
|
||||
}
|
||||
@@ -19,7 +19,7 @@
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@@ -39,20 +39,20 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<NMakeBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
|
||||
<NMakeBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /m</NMakeBuildCommandLine>
|
||||
<NMakeCleanCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
|
||||
<NMakeCleanCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /m</NMakeCleanCommandLine>
|
||||
<NMakeReBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
|
||||
<NMakeReBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /m
|
||||
</NMakeReBuildCommandLine>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<NMakeBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
|
||||
<NMakeBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /m</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
|
||||
<NMakeReBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /m</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
|
||||
<NMakeCleanCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DBUILD_TESTS=OFF -DBUILD_DEMOS=OFF -DBUILD_LAYERS=OFF -DBUILD_VKJSON=OFF ../Vulkan-LoaderAndValidationLayers
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /m</NMakeCleanCommandLine>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@@ -39,24 +39,24 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<NMakeBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
<NMakeBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /m</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
<NMakeReBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /m</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
<NMakeCleanCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /m</NMakeCleanCommandLine>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<NMakeBuildCommandLine>
|
||||
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /m
|
||||
</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>
|
||||
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /m
|
||||
</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine>
|
||||
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /m
|
||||
</NMakeCleanCommandLine>
|
||||
</PropertyGroup>
|
||||
|
||||
+7
-7
@@ -1,6 +1,6 @@
|
||||
version: '0.0.3-{build}'
|
||||
version: '0.0.2-{build}'
|
||||
|
||||
os: Visual Studio 2015
|
||||
os: Visual Studio 2017
|
||||
platform: x64
|
||||
clone_folder: C:\rpcs3
|
||||
clone_depth: 3
|
||||
@@ -15,8 +15,8 @@ before_build:
|
||||
- git submodule update --init 3rdparty/ffmpeg 3rdparty/pugixml asmjit 3rdparty/GSL 3rdparty/libpng Vulkan/glslang Vulkan/Vulkan-LoaderAndValidationLayers Utilities/yaml-cpp 3rdparty/cereal 3rdparty/zlib 3rdparty/hidapi
|
||||
- 7z x zlib.7z -aos -oC:\rpcs3\ > null
|
||||
- 7z x vulkan.7z -aos -oC:\rpcs3\Vulkan > null
|
||||
- if %configuration%==Release (cmake -G "Visual Studio 14 Win64" -DZLIB_ROOT=C:/rpcs3/zlib/ -DVULKAN_PREBUILT=ON)
|
||||
else (7z x llvmlibs.7z -aos -oC:\rpcs3 > null && cmake -G "Visual Studio 14 Win64" -DLLVM_DIR=C:/rpcs3/llvm_build/lib/cmake/llvm -DZLIB_ROOT=C:/rpcs3/zlib/ -DVULKAN_PREBUILT=ON)
|
||||
- if %configuration%==Release (cmake -G "Visual Studio 15 Win64" -DZLIB_ROOT=C:/rpcs3/zlib/ -DVULKAN_PREBUILT=ON)
|
||||
else (7z x llvmlibs.7z -aos -oC:\rpcs3 > null && cmake -G "Visual Studio 15 Win64" -DLLVM_DIR=C:/rpcs3/llvm_build/lib/cmake/llvm -DZLIB_ROOT=C:/rpcs3/zlib/ -DVULKAN_PREBUILT=ON)
|
||||
|
||||
build_script:
|
||||
- cmake --build . --config Release -- /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
||||
@@ -25,14 +25,14 @@ install:
|
||||
- if not exist llvmlibs.7z appveyor DownloadFile "https://drive.google.com/uc?export=download&id=0B8A6NaxhQAGRY2k3Q2Yya05lcm8" -FileName llvmlibs.7z
|
||||
- if not exist vulkan.7z appveyor DownloadFile "https://drive.google.com/uc?export=download&id=0B8A6NaxhQAGRaHYxV3VOS2d0a0U" -FileName vulkan.7z
|
||||
- if not exist zlib.7z appveyor DownloadFile "https://drive.google.com/uc?export=download&id=0B-HVE3xvheVFX05lRFdnZlh5aUU" -FileName zlib.7z
|
||||
- set QTDIR=C:\Qt\5.8\msvc2015_64
|
||||
- set QTDIR=C:\Qt\5.9\msvc2017_64
|
||||
- set OPENALDIR=C:\rpcs3\3rdparty\OpenAL
|
||||
- set PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%QTDIR%;%PATH%
|
||||
- set PATH=C:\Program Files (x86)\MSBuild\15.0\Bin;%QTDIR%;%PATH%
|
||||
- set COMMIT_SHA=%APPVEYOR_REPO_COMMIT:~0,8%
|
||||
|
||||
artifacts:
|
||||
- path: bin
|
||||
name: 'rpcs3-v0.0.3-$(Date)-$(COMMIT_SHA)_win64'
|
||||
name: 'rpcs3-v0.0.2-$(Date)-$(COMMIT_SHA)_win64'
|
||||
type: zip
|
||||
|
||||
cache:
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1
-1
Submodule llvm updated: 4423e35117...be4d3e6292
@@ -18,12 +18,12 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@@ -39,30 +39,30 @@
|
||||
<NMakePreprocessorDefinitions>
|
||||
</NMakePreprocessorDefinitions>
|
||||
<NMakeBuildCommandLine>
|
||||
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /m
|
||||
</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>
|
||||
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /m
|
||||
</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine>
|
||||
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /m
|
||||
</NMakeCleanCommandLine>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<NMakePreprocessorDefinitions />
|
||||
<NMakeBuildCommandLine>
|
||||
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /m
|
||||
</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>
|
||||
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /m
|
||||
</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine>
|
||||
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /m
|
||||
</NMakeCleanCommandLine>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26430.13
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "asmjit", "asmjitsrc\asmjit.vcxproj", "{AC40FF01-426E-4838-A317-66354CEFAE88}"
|
||||
EndProject
|
||||
|
||||
+9
-19
@@ -3,10 +3,9 @@ cmake_minimum_required(VERSION 3.0.2)
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake_modules")
|
||||
set(RES_FILES "")
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
include(CheckCCompilerFlag)
|
||||
|
||||
# Qt section
|
||||
find_package(Qt5 5.7 COMPONENTS Widgets)
|
||||
find_package(Qt5 5.9 COMPONENTS Widgets)
|
||||
if (WIN32)
|
||||
find_package(Qt5WinExtras REQUIRED)
|
||||
set(RPCS3_QT_LIBS Qt5::Widgets Qt5::WinExtras)
|
||||
@@ -18,8 +17,8 @@ endif()
|
||||
|
||||
# Let's make sure we have Qt before we continue
|
||||
if (NOT Qt5Widgets_FOUND)
|
||||
if (Qt5Widgets_VERSION VERSION_LESS 5.7.0)
|
||||
message("Minimum supported Qt5 version is 5.7! You have version ${Qt5Widgets_VERSION} installed, please upgrade!")
|
||||
if (Qt5Widgets_VERSION VERSION_LESS 5.9.0)
|
||||
message("Minimum supported Qt5 version is 5.9! You have version ${Qt5Widgets_VERSION} installed, please upgrade!")
|
||||
if ("${CMAKE_SYSTEM}" MATCHES "Linux")
|
||||
message(FATAL_ERROR "Most distros do not provide an up-to-date version of Qt.
|
||||
If you're on Ubuntu or Linux Mint, there are PPAs you can use to install an up-to-date qt5 version.
|
||||
@@ -38,7 +37,7 @@ before re-running cmake")
|
||||
|
||||
message("CMake was unable to find Qt5!")
|
||||
if (WIN32)
|
||||
message(FATAL_ERROR "Make sure the QTDIR env variable has been set properly. (for example C:\\Qt\\5.8\\msvc2017_64\\)")
|
||||
message(FATAL_ERROR "Make sure the QTDIR env variable has been set properly. (for example C:\\Qt\\5.9\\msvc2017_64\\)")
|
||||
elseif("${CMAKE_SYSTEM}" MATCHES "Linux")
|
||||
message(FATAL_ERROR "Make sure to install your distro's qt5 package!")
|
||||
else()
|
||||
@@ -85,6 +84,9 @@ else()
|
||||
endif()
|
||||
|
||||
if(NOT MSVC)
|
||||
if($ENV{CI})
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O1") # fix for travis gcc OoM crash. Might be fixed with the move to containers.
|
||||
endif()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions")
|
||||
if(WIN32)
|
||||
set(CMAKE_RC_COMPILER_INIT windres)
|
||||
@@ -95,24 +97,13 @@ if(NOT MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--allow-multiple-definition")
|
||||
endif()
|
||||
|
||||
add_compile_options(-msse -msse2 -mcx16 -mssse3 -mrtm)
|
||||
add_compile_options(-msse -msse2 -mcx16 -mssse3)
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
# This fixes 'some' of the st11range issues. See issue #2516
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -image-base=0x10000")
|
||||
endif()
|
||||
|
||||
# Some distros have the compilers set to use PIE by default, but RPCS3 doesn't work with PIE, so we need to disable it.
|
||||
CHECK_C_COMPILER_FLAG("-no-pie" HAS_NO_PIE)
|
||||
if(HAS_NO_PIE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -no-pie")
|
||||
else()
|
||||
CHECK_C_COMPILER_FLAG("-nopie" HAS_NO_PIE)
|
||||
if(HAS_NO_PIE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -nopie")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(GLEW REQUIRED)
|
||||
find_package(ZLIB REQUIRED)
|
||||
else()
|
||||
@@ -280,7 +271,6 @@ endif()
|
||||
# Ignore autogenerated moc_* files if present
|
||||
set (EXCLUDE_FILES ${EXCLUDE_FILES} "moc_")
|
||||
set (EXCLUDE_FILES ${EXCLUDE_FILES} "rpcs3_automoc")
|
||||
set (EXCLUDE_FILES ${EXCLUDE_FILES} "qrc_resources.cpp")
|
||||
|
||||
foreach (TMP_PATH ${RPCS3_SRC})
|
||||
foreach (EXCLUDE_PATH ${EXCLUDE_FILES})
|
||||
@@ -292,7 +282,7 @@ foreach (TMP_PATH ${RPCS3_SRC})
|
||||
endforeach(TMP_PATH)
|
||||
|
||||
# Remove the Qt moc files as part of clean, they are compiled when generating automoc
|
||||
file(GLOB_RECURSE TMP_MOC "${RPCS3_SRC_DIR}/moc_*.cpp" "${RPCS3_SRC_DIR}/rpcs3_automoc.cpp" "${RPCS3_SRC_DIR}/qrc_resources.cpp")
|
||||
file(GLOB_RECURSE TMP_MOC "${RPCS3_SRC_DIR}/moc_*.cpp" "${RPCS3_SRC_DIR}/rpcs3_automoc.cpp")
|
||||
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${TMP_MOC}")
|
||||
|
||||
if (WIN32)
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
||||
+4
-22
@@ -1,12 +1,9 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/sysinfo.h"
|
||||
#include "Emu/Memory/vm.h"
|
||||
#include "Emu/Cell/SPUThread.h"
|
||||
#include "Emu/Cell/lv2/sys_sync.h"
|
||||
#include "MFC.h"
|
||||
|
||||
const bool s_use_rtm = utils::has_rtm();
|
||||
|
||||
template <>
|
||||
void fmt_class_string<MFC>::format(std::string& out, u64 arg)
|
||||
{
|
||||
@@ -148,25 +145,10 @@ void mfc_thread::cpu_task()
|
||||
vm::reservation_acquire(cmd.eal, 128);
|
||||
|
||||
// Store unconditionally
|
||||
if (s_use_rtm && utils::transaction_enter())
|
||||
{
|
||||
if (!vm::reader_lock{vm::try_to_lock})
|
||||
{
|
||||
_xabort(0);
|
||||
}
|
||||
|
||||
data = to_write;
|
||||
vm::reservation_update(cmd.eal, 128);
|
||||
vm::notify(cmd.eal, 128);
|
||||
_xend();
|
||||
}
|
||||
else
|
||||
{
|
||||
vm::writer_lock lock(0);
|
||||
data = to_write;
|
||||
vm::reservation_update(cmd.eal, 128);
|
||||
vm::notify(cmd.eal, 128);
|
||||
}
|
||||
vm::writer_lock lock(0);
|
||||
data = to_write;
|
||||
vm::reservation_update(cmd.eal, 128);
|
||||
vm::notify(cmd.eal, 128);
|
||||
}
|
||||
else if (cmd.cmd & MFC_LIST_MASK)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
#include "Emu/Cell/Modules/cellSysutil.h"
|
||||
|
||||
#include "cellSaveData.h"
|
||||
|
||||
@@ -64,6 +63,7 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
PFuncFile funcFile, u32 container, u32 unknown, vm::ptr<void> userdata, u32 userId, PFuncDone funcDone)
|
||||
{
|
||||
// TODO: check arguments
|
||||
|
||||
std::unique_lock<std::mutex> lock(g_savedata_mutex, std::try_to_lock);
|
||||
|
||||
if (!lock)
|
||||
@@ -82,8 +82,6 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
vm::ptr<CellSaveDataFileGet> fileGet = g_savedata_context.ptr(&savedata_context::fileGet);
|
||||
vm::ptr<CellSaveDataFileSet> fileSet = g_savedata_context.ptr(&savedata_context::fileSet);
|
||||
|
||||
//TODO: get current user ID
|
||||
// userId(0) = CELL_SYSUTIL_USERID_CURRENT
|
||||
// path of the specified user (00000001 by default)
|
||||
const std::string& base_dir = vfs::get(fmt::format("/dev_hdd0/home/%08u/savedata/", userId ? userId : 1u));
|
||||
|
||||
@@ -102,7 +100,6 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
|
||||
const auto prefix_list = fmt::split(setList->dirNamePrefix.get_ptr(), { "|" });
|
||||
|
||||
// get the saves matching the supplied prefix
|
||||
for (const auto& entry : fs::dir(base_dir))
|
||||
{
|
||||
if (!entry.is_directory)
|
||||
@@ -214,15 +211,13 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
|
||||
if (result->result < 0)
|
||||
{
|
||||
//TODO: display dialog
|
||||
cellSaveData.warning("savedata_op(): funcList returned < 0.");
|
||||
return CELL_SAVEDATA_ERROR_CBRESULT;
|
||||
}
|
||||
|
||||
// if the callback has returned ok, lets return OK.
|
||||
// typically used at game launch when no list is actually required.
|
||||
// CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM is only valid for funcFile and funcDone
|
||||
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST)
|
||||
if ((result->result == CELL_SAVEDATA_CBRESULT_OK_LAST) || (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM))
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -241,16 +236,6 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
return true;
|
||||
}), save_entries.end());
|
||||
|
||||
// Add any new data (not currently supported by the UI)
|
||||
//if (listSet->newData)
|
||||
//{
|
||||
// SaveDataEntry *_saveDataEntry = new SaveDataEntry();
|
||||
// _saveDataEntry->dirName = listSet->newData->dirName.get_ptr();
|
||||
|
||||
// save_entry.dirName = listSet->newData->dirName.get_ptr();
|
||||
// save_entries.emplace_back(*_saveDataEntry);
|
||||
//}
|
||||
|
||||
// Focus save data
|
||||
s32 focused = -1;
|
||||
|
||||
@@ -311,8 +296,6 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
}
|
||||
case CELL_SAVEDATA_FOCUSPOS_NEWDATA:
|
||||
{
|
||||
//TODO: If adding the new data to the save_entries vector
|
||||
// to be displayed in the save mangaer UI, it should be focused here
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -356,19 +339,8 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
// Fixed Callback
|
||||
funcFixed(ppu, result, listGet, fixedSet);
|
||||
|
||||
// skip all following steps if OK_LAST
|
||||
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST)
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
if (result->result < 0)
|
||||
{
|
||||
//TODO: Show msgDialog if required
|
||||
// depends on fixedSet->option
|
||||
// 0 = none
|
||||
// 1 = skip confirmation dialog
|
||||
|
||||
cellSaveData.warning("savedata_op(): funcFixed returned < 0.");
|
||||
return CELL_SAVEDATA_ERROR_CBRESULT;
|
||||
}
|
||||
@@ -391,7 +363,10 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
{
|
||||
save_entry.dirName = fixedSet->dirName.get_ptr();
|
||||
}
|
||||
|
||||
if ((result->result == CELL_SAVEDATA_CBRESULT_OK_LAST) || (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM))
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (selected >= 0)
|
||||
@@ -504,11 +479,6 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
return CELL_SAVEDATA_ERROR_CBRESULT;
|
||||
}
|
||||
|
||||
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST)
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
if (statSet->setParam)
|
||||
{
|
||||
// Update PARAM.SFO
|
||||
@@ -528,20 +498,18 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
{ "TITLE", psf::string(128, statSet->setParam->title) },
|
||||
});
|
||||
}
|
||||
//else if (psf.empty())
|
||||
//{
|
||||
// // setParam is specified if something required updating.
|
||||
// // Do not exit. Recreate mode will handle the rest
|
||||
// //return CELL_OK;
|
||||
//}
|
||||
else if (psf.empty())
|
||||
{
|
||||
// setParam is NULL for new savedata: abort operation
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
switch (const u32 mode = statSet->reCreateMode & 0xffff)
|
||||
{
|
||||
case CELL_SAVEDATA_RECREATE_NO:
|
||||
{
|
||||
//CELL_SAVEDATA_RECREATE_NO = overwrite and let the user know, not data is corrupt.
|
||||
//cellSaveData.error("Savedata %s considered broken", save_entry.dirName);
|
||||
//TODO: if this is a save, and it's not auto, then show a dialog
|
||||
cellSaveData.error("Savedata %s considered broken", save_entry.dirName);
|
||||
// fallthrough
|
||||
}
|
||||
|
||||
@@ -553,8 +521,7 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
case CELL_SAVEDATA_RECREATE_YES:
|
||||
case CELL_SAVEDATA_RECREATE_YES_RESET_OWNER:
|
||||
{
|
||||
|
||||
// TODO: Only delete data, not owner info
|
||||
// TODO?
|
||||
for (const auto& entry : fs::dir(dir_path))
|
||||
{
|
||||
if (!entry.is_directory)
|
||||
@@ -563,13 +530,12 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: probably not deleting owner info
|
||||
if (!statSet->setParam)
|
||||
{
|
||||
// Savedata deleted and setParam is NULL: delete directory and abort operation
|
||||
if (fs::remove_dir(dir_path)) cellSaveData.error("savedata_op(): savedata directory %s deleted", save_entry.dirName);
|
||||
|
||||
//return CELL_OK;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -583,13 +549,16 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((result->result == CELL_SAVEDATA_CBRESULT_OK_LAST) || (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM))
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
// Create save directory if necessary
|
||||
if (psf.size() && save_entry.isNew && !fs::create_dir(dir_path))
|
||||
{
|
||||
{
|
||||
// Let's ignore this error for now
|
||||
cellSaveData.warning("savedata_op(): failed to create %s", dir_path);
|
||||
return CELL_SAVEDATA_ERROR_ACCESS_ERROR;
|
||||
}
|
||||
|
||||
// Enter the loop where the save files are read/created/deleted
|
||||
@@ -609,13 +578,9 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
|
||||
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST || result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM)
|
||||
{
|
||||
//todo: display user prompt
|
||||
break;
|
||||
}
|
||||
|
||||
//TODO: Show progress
|
||||
// if it's not an auto load/save
|
||||
|
||||
std::string file_path;
|
||||
|
||||
switch (const u32 type = fileSet->fileType)
|
||||
@@ -716,57 +681,6 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 static NEVER_INLINE save_op_get_list_item(vm::cptr<char> dirName, vm::ptr<CellSaveDataDirStat> dir, vm::ptr<CellSaveDataSystemFileParam> sysFileParam, vm::ptr<u32> bind, vm::ptr<u32> sizeKB, u32 userId)
|
||||
{
|
||||
|
||||
//TODO: accurately get the current user
|
||||
if (userId == 0)
|
||||
{
|
||||
userId = 1u;
|
||||
}
|
||||
std::string save_path = vfs::get(fmt::format("/dev_hdd0/home/%08u/savedata/%s/", userId, dirName.get_ptr()));
|
||||
std::string sfo = save_path + "param.sfo";
|
||||
|
||||
if (!fs::is_dir(save_path) && !fs::is_file(sfo))
|
||||
{
|
||||
cellSaveData.error("cellSaveDataGetListItem(): Savedata at %s does not exist", dirName);
|
||||
return CELL_SAVEDATA_ERROR_NODATA;
|
||||
}
|
||||
|
||||
auto psf = psf::load_object(fs::file(sfo));
|
||||
|
||||
if (sysFileParam)
|
||||
{
|
||||
strcpy_trunc(sysFileParam->listParam, psf.at("SAVEDATA_LIST_PARAM").as_string());
|
||||
strcpy_trunc(sysFileParam->title, psf.at("TITLE").as_string());
|
||||
strcpy_trunc(sysFileParam->subTitle, psf.at("SUB_TITLE").as_string());
|
||||
strcpy_trunc(sysFileParam->detail, psf.at("DETAIL").as_string());
|
||||
}
|
||||
|
||||
if (dir)
|
||||
{
|
||||
fs::stat_t dir_info{};
|
||||
if (!fs::stat(save_path, dir_info))
|
||||
{
|
||||
return CELL_SAVEDATA_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
// get file stats, namely directory
|
||||
strcpy_trunc(dir->dirName, dirName.get_ptr());
|
||||
dir->atime = dir_info.atime;
|
||||
dir->ctime = dir_info.ctime;
|
||||
dir->mtime = dir_info.mtime;
|
||||
}
|
||||
|
||||
if (bind)
|
||||
{
|
||||
//TODO: Set bind in accordance to any problems
|
||||
*bind = 0;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
// Functions
|
||||
s32 cellSaveDataListSave2(ppu_thread& ppu, u32 version, PSetList setList, PSetBuf setBuf, PFuncList funcList,
|
||||
PFuncStat funcStat, PFuncFile funcFile, u32 container, vm::ptr<void> userdata)
|
||||
@@ -1035,8 +949,27 @@ s32 cellSaveDataFixedExport(ppu_thread& ppu, vm::cptr<char> dirName, u32 maxSize
|
||||
s32 cellSaveDataGetListItem(vm::cptr<char> dirName, vm::ptr<CellSaveDataDirStat> dir, vm::ptr<CellSaveDataSystemFileParam> sysFileParam, vm::ptr<u32> bind, vm::ptr<u32> sizeKB)
|
||||
{
|
||||
cellSaveData.warning("cellSavaDataGetListItem(dirName=%s, dir=*0x%x, sysFileParam=*0x%x, bind=*0x%x, sizeKB=*0x%x)", dirName, dir, sysFileParam, bind, sizeKB);
|
||||
|
||||
return save_op_get_list_item(dirName, dir, sysFileParam, bind, sizeKB, 0);
|
||||
|
||||
std::string save_path = vfs::get(fmt::format("/dev_hdd0/home/00000001/savedata/%s/", dirName.get_ptr()));
|
||||
std::string sfo = save_path + "param.sfo";
|
||||
|
||||
if (!fs::is_dir(save_path) && !fs::is_file(sfo))
|
||||
{
|
||||
cellSaveData.error("cellSaveDataGetListItem(): Savedata at %s does not exist", dirName);
|
||||
return CELL_SAVEDATA_ERROR_NODATA;
|
||||
}
|
||||
|
||||
auto psf = psf::load_object(fs::file(sfo));
|
||||
|
||||
if (sysFileParam)
|
||||
{
|
||||
strcpy_trunc(sysFileParam->listParam, psf.at("SAVEDATA_LIST_PARAM").as_string());
|
||||
strcpy_trunc(sysFileParam->title, psf.at("TITLE").as_string());
|
||||
strcpy_trunc(sysFileParam->subTitle, psf.at("SUB_TITLE").as_string());
|
||||
strcpy_trunc(sysFileParam->detail, psf.at("DETAIL").as_string());
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSaveDataUserListDelete(ppu_thread& ppu, u32 userId, PSetList setList, PSetBuf setBuf, PFuncList funcList, PFuncDone funcDone, u32 container, vm::ptr<void> userdata)
|
||||
@@ -1076,9 +1009,9 @@ s32 cellSaveDataUserFixedExport(ppu_thread& ppu, u32 userId, vm::cptr<char> dirN
|
||||
|
||||
s32 cellSaveDataUserGetListItem(u32 userId, vm::cptr<char> dirName, vm::ptr<CellSaveDataDirStat> dir, vm::ptr<CellSaveDataSystemFileParam> sysFileParam, vm::ptr<u32> bind, vm::ptr<u32> sizeKB)
|
||||
{
|
||||
cellSaveData.warning("cellSavaDataGetListItem(dirName=%s, dir=*0x%x, sysFileParam=*0x%x, bind=*0x%x, sizeKB=*0x%x, userID=*0x%x)", dirName, dir, sysFileParam, bind, sizeKB, userId);
|
||||
UNIMPLEMENTED_FUNC(cellSaveData);
|
||||
|
||||
return save_op_get_list_item(dirName, dir, sysFileParam, bind, sizeKB, userId);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
void cellSysutil_SaveData_init()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
namespace vm { using namespace ps3; }
|
||||
|
||||
|
||||
@@ -880,7 +880,7 @@ s32 _spurs::stop_event_helper(ppu_thread& ppu, vm::ptr<CellSpurs> spurs)
|
||||
return CELL_SPURS_CORE_ERROR_STAT;
|
||||
}
|
||||
|
||||
if (sys_event_port_send(ppu, spurs->eventPort, 0, 1, 0) != CELL_OK)
|
||||
if (sys_event_port_send(spurs->eventPort, 0, 1, 0) != CELL_OK)
|
||||
{
|
||||
return CELL_SPURS_CORE_ERROR_STAT;
|
||||
}
|
||||
@@ -2794,7 +2794,7 @@ s32 cellSpursEventFlagSet(ppu_thread& ppu, vm::ptr<CellSpursEventFlag> eventFlag
|
||||
// Signal the PPU thread to be woken up
|
||||
eventFlag->pendingRecvTaskEvents[ppuWaitSlot] = ppuEvents;
|
||||
|
||||
CHECK_SUCCESS(sys_event_port_send(ppu, eventFlag->eventPortId, 0, 0, 0));
|
||||
CHECK_SUCCESS(sys_event_port_send(eventFlag->eventPortId, 0, 0, 0));
|
||||
}
|
||||
|
||||
if (pendingRecv)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
namespace vm { using namespace ps3; }
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
|
||||
@@ -511,9 +511,9 @@ s32 sceNpBasicGetEvent(vm::ptr<s32> event, vm::ptr<SceNpUserInfo> from, vm::ptr<
|
||||
sceNp.warning("sceNpBasicGetEvent(event=*0x%x, from=*0x%x, data=*0x%x, size=*0x%x)", event, from, data, size);
|
||||
|
||||
// TODO: Check for other error and pass other events
|
||||
//*event = SCE_NP_BASIC_EVENT_OFFLINE; // This event only indicates a contact is offline, not the current status of the connection
|
||||
*event = SCE_NP_BASIC_EVENT_OFFLINE;
|
||||
|
||||
return SCE_NP_BASIC_ERROR_NO_EVENT;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpCommerceCreateCtx()
|
||||
@@ -911,6 +911,10 @@ s32 sceNpManagerRegisterCallback(vm::ptr<SceNpManagerCallback> callback, vm::ptr
|
||||
{
|
||||
return SCE_NP_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SCE_NP_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/VirtualMemory.h"
|
||||
#include "Utilities/bin_patch.h"
|
||||
#include "Crypto/sha1.h"
|
||||
#include "Crypto/unself.h"
|
||||
#include "Loader/ELF.h"
|
||||
@@ -955,11 +954,6 @@ void ppu_load_exec(const ppu_exec_object& elf)
|
||||
u32 primary_stacksize = 0x100000;
|
||||
u32 malloc_pagesize = 0x100000;
|
||||
|
||||
// Executable hash
|
||||
sha1_context sha;
|
||||
sha1_starts(&sha);
|
||||
u8 sha1_hash[20];
|
||||
|
||||
// Allocate memory at fixed positions
|
||||
for (const auto& prog : elf.progs)
|
||||
{
|
||||
@@ -970,11 +964,7 @@ void ppu_load_exec(const ppu_exec_object& elf)
|
||||
const u32 size = _seg.size = ::narrow<u32>(prog.p_memsz, "p_memsz" HERE);
|
||||
const u32 type = _seg.type = prog.p_type;
|
||||
const u32 flag = _seg.flags = prog.p_flags;
|
||||
|
||||
// Hash big-endian values
|
||||
sha1_update(&sha, (uchar*)&prog.p_type, sizeof(prog.p_type));
|
||||
sha1_update(&sha, (uchar*)&prog.p_flags, sizeof(prog.p_flags));
|
||||
|
||||
|
||||
if (type == 0x1 /* LOAD */ && prog.p_memsz)
|
||||
{
|
||||
if (prog.bin.size() > size || prog.bin.size() != prog.p_filesz)
|
||||
@@ -983,11 +973,8 @@ void ppu_load_exec(const ppu_exec_object& elf)
|
||||
if (!vm::falloc(addr, size, vm::main))
|
||||
fmt::throw_exception("vm::falloc() failed (addr=0x%x, memsz=0x%x)", addr, size);
|
||||
|
||||
// Copy segment data, hash it
|
||||
// Copy segment data
|
||||
std::memcpy(vm::base(addr), prog.bin.data(), prog.bin.size());
|
||||
sha1_update(&sha, (uchar*)&prog.p_vaddr, sizeof(prog.p_vaddr));
|
||||
sha1_update(&sha, (uchar*)&prog.p_memsz, sizeof(prog.p_memsz));
|
||||
sha1_update(&sha, prog.bin.data(), prog.bin.size());
|
||||
|
||||
// Initialize executable code if necessary
|
||||
if (prog.p_flags & 0x1)
|
||||
@@ -1017,28 +1004,6 @@ void ppu_load_exec(const ppu_exec_object& elf)
|
||||
}
|
||||
}
|
||||
|
||||
sha1_finish(&sha, sha1_hash);
|
||||
|
||||
// Format patch name
|
||||
std::string hash("PPU-0000000000000000000000000000000000000000");
|
||||
for (u32 i = 0; i < sizeof(sha1_hash); i++)
|
||||
{
|
||||
constexpr auto pal = "0123456789abcdef";
|
||||
hash[4 + i * 2] = pal[sha1_hash[i] >> 4];
|
||||
hash[5 + i * 2] = pal[sha1_hash[i] & 15];
|
||||
}
|
||||
|
||||
// Apply the patch
|
||||
auto applied = fxm::check_unlocked<patch_engine>()->apply(hash, vm::g_base_addr);
|
||||
|
||||
if (!Emu.GetTitleID().empty())
|
||||
{
|
||||
// Alternative patch
|
||||
applied += fxm::check_unlocked<patch_engine>()->apply(Emu.GetTitleID() + '-' + hash, vm::g_base_addr);
|
||||
}
|
||||
|
||||
LOG_NOTICE(LOADER, "PPU executable hash: %s (<- %u)", hash, applied);
|
||||
|
||||
// Initialize HLE modules
|
||||
ppu_initialize_modules(link);
|
||||
|
||||
@@ -1203,6 +1168,7 @@ void ppu_load_exec(const ppu_exec_object& elf)
|
||||
{ "cellFont", "libfont.sprx" },
|
||||
{ "cellFontFT", "libfontFT.sprx" },
|
||||
{ "cellFontFT", "libfreetype.sprx" },
|
||||
{ "cellGcmSys", "libgcm_sys.sprx"},
|
||||
{ "cellGifDec", "libgifdec.sprx" },
|
||||
{ "cellGifDec", "libsre.sprx" },
|
||||
{ "cellJpgDec", "libjpgdec.sprx" },
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/VirtualMemory.h"
|
||||
#include "Utilities/sysinfo.h"
|
||||
#include "Crypto/sha1.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/System.h"
|
||||
@@ -54,8 +53,6 @@
|
||||
#include <cfenv>
|
||||
#include "Utilities/GSL.h"
|
||||
|
||||
const bool s_use_rtm = utils::has_rtm();
|
||||
|
||||
extern u64 get_system_time();
|
||||
|
||||
namespace vm { using namespace ps3; }
|
||||
@@ -828,26 +825,6 @@ extern bool ppu_stwcx(ppu_thread& ppu, u32 addr, u32 reg_value)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s_use_rtm && utils::transaction_enter())
|
||||
{
|
||||
if (!vm::reader_lock{vm::try_to_lock})
|
||||
{
|
||||
_xabort(0);
|
||||
}
|
||||
|
||||
const bool result = ppu.rtime == vm::reservation_acquire(addr, sizeof(u32)) && data.compare_and_swap_test(static_cast<u32>(ppu.rdata), reg_value);
|
||||
|
||||
if (result)
|
||||
{
|
||||
vm::reservation_update(addr, sizeof(u32));
|
||||
vm::notify(addr, sizeof(u32));
|
||||
}
|
||||
|
||||
_xend();
|
||||
ppu.raddr = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
vm::writer_lock lock(0);
|
||||
|
||||
const bool result = ppu.rtime == vm::reservation_acquire(addr, sizeof(u32)) && data.compare_and_swap_test(static_cast<u32>(ppu.rdata), reg_value);
|
||||
@@ -872,26 +849,6 @@ extern bool ppu_stdcx(ppu_thread& ppu, u32 addr, u64 reg_value)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s_use_rtm && utils::transaction_enter())
|
||||
{
|
||||
if (!vm::reader_lock{vm::try_to_lock})
|
||||
{
|
||||
_xabort(0);
|
||||
}
|
||||
|
||||
const bool result = ppu.rtime == vm::reservation_acquire(addr, sizeof(u64)) && data.compare_and_swap_test(ppu.rdata, reg_value);
|
||||
|
||||
if (result)
|
||||
{
|
||||
vm::reservation_update(addr, sizeof(u64));
|
||||
vm::notify(addr, sizeof(u64));
|
||||
}
|
||||
|
||||
_xend();
|
||||
ppu.raddr = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
vm::writer_lock lock(0);
|
||||
|
||||
const bool result = ppu.rtime == vm::reservation_acquire(addr, sizeof(u64)) && data.compare_and_swap_test(ppu.rdata, reg_value);
|
||||
@@ -1185,8 +1142,7 @@ extern void ppu_initialize(const ppu_module& info)
|
||||
if (fs::is_file(cache_path + obj_name))
|
||||
{
|
||||
semaphore_lock lock(jmutex);
|
||||
jit->add(cache_path + obj_name);
|
||||
LOG_SUCCESS(PPU, "LLVM: Loaded module %s", obj_name);
|
||||
ppu_initialize2(*jit, part, cache_path, obj_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1217,7 +1173,7 @@ extern void ppu_initialize(const ppu_module& info)
|
||||
|
||||
// Proceed with original JIT instance
|
||||
semaphore_lock lock(jmutex);
|
||||
jit->add(cache_path + obj_name);
|
||||
ppu_initialize2(*jit, part, cache_path, obj_name);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1330,6 +1286,8 @@ static void ppu_initialize2(jit_compiler& jit, const ppu_module& module_part, co
|
||||
|
||||
std::shared_ptr<MsgDialogBase> dlg;
|
||||
|
||||
// Check cached file
|
||||
if (!fs::is_file(cache_path + obj_name))
|
||||
{
|
||||
legacy::FunctionPassManager pm(module.get());
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ PPUTranslator::PPUTranslator(LLVMContext& context, Module* module, const ppu_mod
|
||||
, m_module(module)
|
||||
, m_is_be(false)
|
||||
, m_info(info)
|
||||
, m_pure_attr(AttributeSet::get(m_context, AttributeSet::FunctionIndex, {Attribute::NoUnwind, Attribute::ReadNone}))
|
||||
, m_pure_attr(AttributeList::get(m_context,AttributeList::FunctionIndex, AttrBuilder().addAttribute(Attribute::NoUnwind).addAttribute(Attribute::ReadNone)))
|
||||
{
|
||||
// There is no weak linkage on JIT, so let's create variables with different names for each module part
|
||||
const u32 gsuffix = m_info.name.empty() ? info.funcs[0].addr : info.funcs[0].addr - m_info.segs[0].addr;
|
||||
@@ -133,7 +133,7 @@ Function* PPUTranslator::Translate(const ppu_function& info)
|
||||
const u64 base = m_reloc ? m_reloc->addr : 0;
|
||||
m_addr = info.addr - base;
|
||||
|
||||
m_thread = &*m_function->getArgumentList().begin();
|
||||
m_thread = &*m_function->arg_begin();
|
||||
m_base_loaded = m_ir->CreateLoad(m_base);
|
||||
|
||||
m_body = BasicBlock::Create(m_context, "__body", m_function);
|
||||
|
||||
@@ -120,7 +120,7 @@ class PPUTranslator final //: public CPUTranslator
|
||||
std::map<u64, const ppu_reloc*> m_relocs;
|
||||
|
||||
// Attributes for function calls which are "pure" and may be optimized away if their results are unused
|
||||
const llvm::AttributeSet m_pure_attr;
|
||||
const llvm::AttributeList m_pure_attr;
|
||||
|
||||
// IR builder
|
||||
llvm::IRBuilder<>* m_ir;
|
||||
@@ -404,7 +404,7 @@ public:
|
||||
|
||||
// Call a function with attribute list
|
||||
template<typename... Args>
|
||||
llvm::CallInst* Call(llvm::Type* ret, llvm::AttributeSet attr, llvm::StringRef name, Args... args)
|
||||
llvm::CallInst* Call(llvm::Type* ret, llvm::AttributeList attr, llvm::StringRef name, Args... args)
|
||||
{
|
||||
// Call the function
|
||||
return m_ir->CreateCall(m_module->getOrInsertFunction(name, llvm::FunctionType::get(ret, {args->getType()...}, false), attr), {args...});
|
||||
@@ -414,7 +414,7 @@ public:
|
||||
template<typename... Args>
|
||||
llvm::CallInst* Call(llvm::Type* ret, llvm::StringRef name, Args... args)
|
||||
{
|
||||
return Call(ret, llvm::AttributeSet{}, name, args...);
|
||||
return Call(ret, llvm::AttributeList{}, name, args...);
|
||||
}
|
||||
|
||||
// Handle compilation errors
|
||||
|
||||
@@ -43,27 +43,23 @@ std::shared_ptr<spu_function_t> SPUDatabase::analyse(const be_t<u32>* ls, u32 en
|
||||
|
||||
// Key for multimap
|
||||
const u64 key = entry | u64{ ls[entry / 4] } << 32;
|
||||
const be_t<u32>* base = ls + entry / 4;
|
||||
const u32 block_sz = max_limit - entry;
|
||||
|
||||
{
|
||||
reader_lock lock(m_mutex);
|
||||
|
||||
// Try to find existing function in the database
|
||||
if (auto func = find(base, key, block_sz))
|
||||
if (auto func = find(ls + entry / 4, key, max_limit - entry))
|
||||
{
|
||||
return func;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
writer_lock lock(m_mutex);
|
||||
writer_lock lock(m_mutex);
|
||||
|
||||
// Double-check
|
||||
if (auto func = find(base, key, block_sz))
|
||||
{
|
||||
return func;
|
||||
}
|
||||
// Double-check
|
||||
if (auto func = find(ls + entry / 4, key, max_limit - entry))
|
||||
{
|
||||
return func;
|
||||
}
|
||||
|
||||
// Initialize block entries with the function entry point
|
||||
@@ -85,15 +81,11 @@ std::shared_ptr<spu_function_t> SPUDatabase::analyse(const be_t<u32>* ls, u32 en
|
||||
|
||||
const auto type = s_spu_itype.decode(op.opcode);
|
||||
|
||||
// Find existing function
|
||||
if (pos != entry && find(ls + pos / 4, pos | u64{ op.opcode } << 32, limit - pos))
|
||||
{
|
||||
reader_lock lock(m_mutex);
|
||||
|
||||
// Find existing function
|
||||
if (pos != entry && find(ls + pos / 4, pos | u64{ op.opcode } << 32, limit - pos))
|
||||
{
|
||||
limit = pos;
|
||||
break;
|
||||
}
|
||||
limit = pos;
|
||||
break;
|
||||
}
|
||||
|
||||
// Additional analysis at the beginning of the block
|
||||
@@ -319,16 +311,10 @@ std::shared_ptr<spu_function_t> SPUDatabase::analyse(const be_t<u32>* ls, u32 en
|
||||
// Set whether the function can reset stack
|
||||
func->does_reset_stack = ila_sp_pos < limit;
|
||||
|
||||
// Lock here just before we write to the db
|
||||
// Its is unlikely that the second check will pass anyway so we delay this step since compiling functions is very fast
|
||||
{
|
||||
writer_lock lock(m_mutex);
|
||||
// Add function to the database
|
||||
m_db.emplace(key, func);
|
||||
|
||||
// Add function to the database
|
||||
m_db.emplace(key, func);
|
||||
}
|
||||
|
||||
LOG_NOTICE(SPU, "Function detected [0x%05x-0x%05x] (size=0x%x)", func->addr, func->addr + func->size, func->size);
|
||||
LOG_SUCCESS(SPU, "Function detected [0x%05x-0x%05x] (size=0x%x)", func->addr, func->addr + func->size, func->size);
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "SPUThread.h"
|
||||
#include "SPURecompiler.h"
|
||||
#include "SPUASMJITRecompiler.h"
|
||||
#include <algorithm>
|
||||
|
||||
extern u64 get_system_time();
|
||||
|
||||
@@ -23,15 +22,8 @@ void spu_recompiler_base::enter(SPUThread& spu)
|
||||
// Get SPU LS pointer
|
||||
const auto _ls = vm::ps3::_ptr<u32>(spu.offset);
|
||||
|
||||
// Search if cached data matches
|
||||
auto func = spu.compiled_cache[spu.pc / 4];
|
||||
|
||||
// Check shared db if we dont have a match
|
||||
if (!func || !std::equal(func->data.begin(), func->data.end(), _ls + spu.pc / 4, [](const be_t<u32>& l, const be_t<u32>& r) { return *(u32*)(u8*)&l == *(u32*)(u8*)&r; }))
|
||||
{
|
||||
func = spu.spu_db->analyse(_ls, spu.pc).get();
|
||||
spu.compiled_cache[spu.pc / 4] = func;
|
||||
}
|
||||
// Always validate (TODO)
|
||||
const auto func = spu.spu_db->analyse(_ls, spu.pc);
|
||||
|
||||
// Reset callstack if necessary
|
||||
if ((func->does_reset_stack && spu.recursion_level) || spu.recursion_level >= 128)
|
||||
@@ -40,7 +32,6 @@ void spu_recompiler_base::enter(SPUThread& spu)
|
||||
return;
|
||||
}
|
||||
|
||||
// Compile if needed
|
||||
if (!func->compiled)
|
||||
{
|
||||
if (!spu.spu_rec)
|
||||
|
||||
+10
-129
@@ -1,6 +1,5 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/lockless.h"
|
||||
#include "Utilities/sysinfo.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
@@ -23,8 +22,6 @@
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
const bool s_use_rtm = utils::has_rtm();
|
||||
|
||||
#ifdef _MSC_VER
|
||||
bool operator ==(const u128& lhs, const u128& rhs)
|
||||
{
|
||||
@@ -58,65 +55,6 @@ void fmt_class_string<spu_decoder_type>::format(std::string& out, u64 arg)
|
||||
});
|
||||
}
|
||||
|
||||
namespace spu
|
||||
{
|
||||
namespace scheduler
|
||||
{
|
||||
std::array<std::atomic<u8>, 65536> atomic_instruction_table = {};
|
||||
constexpr u32 native_jiffy_duration_us = 2000000;
|
||||
|
||||
void acquire_pc_address(u32 pc, u32 timeout_ms = 3)
|
||||
{
|
||||
const u8 max_concurrent_instructions = (u8)g_cfg.core.preferred_spu_threads;
|
||||
const u32 pc_offset = pc >> 2;
|
||||
|
||||
if (timeout_ms > 0)
|
||||
{
|
||||
while (timeout_ms--)
|
||||
{
|
||||
if (atomic_instruction_table[pc_offset].load(std::memory_order_consume) >= max_concurrent_instructions)
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
atomic_instruction_table[pc_offset]++;
|
||||
}
|
||||
|
||||
void release_pc_address(u32 pc)
|
||||
{
|
||||
const u32 pc_offset = pc >> 2;
|
||||
|
||||
atomic_instruction_table[pc_offset]--;
|
||||
}
|
||||
|
||||
struct concurrent_execution_watchdog
|
||||
{
|
||||
u32 pc = 0;
|
||||
bool active = false;
|
||||
|
||||
concurrent_execution_watchdog(SPUThread& spu)
|
||||
:pc(spu.pc)
|
||||
{
|
||||
if (g_cfg.core.preferred_spu_threads > 0)
|
||||
{
|
||||
acquire_pc_address(pc, (u32)g_cfg.core.spu_delay_penalty);
|
||||
active = true;
|
||||
}
|
||||
}
|
||||
|
||||
~concurrent_execution_watchdog()
|
||||
{
|
||||
if (active)
|
||||
release_pc_address(pc);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void spu_int_ctrl_t::set(u64 ints)
|
||||
{
|
||||
// leave only enabled interrupts
|
||||
@@ -545,7 +483,6 @@ void SPUThread::do_dma_transfer(const spu_mfc_cmd& args, bool from_mfc)
|
||||
|
||||
void SPUThread::process_mfc_cmd()
|
||||
{
|
||||
spu::scheduler::concurrent_execution_watchdog watchdog(*this);
|
||||
LOG_TRACE(SPU, "DMAC: cmd=%s, lsa=0x%x, ea=0x%llx, tag=0x%x, size=0x%x", ch_mfc_cmd.cmd, ch_mfc_cmd.lsa, ch_mfc_cmd.eal, ch_mfc_cmd.tag, ch_mfc_cmd.size);
|
||||
|
||||
const auto mfc = fxm::check_unlocked<mfc_thread>();
|
||||
@@ -562,7 +499,7 @@ void SPUThread::process_mfc_cmd()
|
||||
}
|
||||
|
||||
// TODO: investigate lost notifications
|
||||
std::this_thread::yield();
|
||||
std::this_thread::sleep_for(0us);
|
||||
_mm_lfence();
|
||||
}
|
||||
};
|
||||
@@ -607,22 +544,9 @@ void SPUThread::process_mfc_cmd()
|
||||
thread_ctrl::wait_for(100);
|
||||
}
|
||||
}
|
||||
else if (s_use_rtm && utils::transaction_enter())
|
||||
{
|
||||
if (!vm::reader_lock{vm::try_to_lock})
|
||||
{
|
||||
_xabort(0);
|
||||
}
|
||||
|
||||
rtime = vm::reservation_acquire(raddr, 128);
|
||||
rdata = data;
|
||||
_xend();
|
||||
|
||||
_ref<decltype(rdata)>(ch_mfc_cmd.lsa & 0x3ffff) = rdata;
|
||||
return ch_atomic_stat.set_value(MFC_GETLLAR_SUCCESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fast path
|
||||
rdata = data;
|
||||
_mm_lfence();
|
||||
}
|
||||
@@ -653,36 +577,15 @@ void SPUThread::process_mfc_cmd()
|
||||
if (raddr == ch_mfc_cmd.eal && rtime == vm::reservation_acquire(raddr, 128) && rdata == data)
|
||||
{
|
||||
// TODO: vm::check_addr
|
||||
if (s_use_rtm && utils::transaction_enter())
|
||||
vm::writer_lock lock;
|
||||
|
||||
if (rtime == vm::reservation_acquire(raddr, 128) && rdata == data)
|
||||
{
|
||||
if (!vm::reader_lock{vm::try_to_lock})
|
||||
{
|
||||
_xabort(0);
|
||||
}
|
||||
data = to_write;
|
||||
result = true;
|
||||
|
||||
if (rtime == vm::reservation_acquire(raddr, 128) && rdata == data)
|
||||
{
|
||||
data = to_write;
|
||||
result = true;
|
||||
|
||||
vm::reservation_update(raddr, 128);
|
||||
vm::notify(raddr, 128);
|
||||
}
|
||||
|
||||
_xend();
|
||||
}
|
||||
else
|
||||
{
|
||||
vm::writer_lock lock;
|
||||
|
||||
if (rtime == vm::reservation_acquire(raddr, 128) && rdata == data)
|
||||
{
|
||||
data = to_write;
|
||||
result = true;
|
||||
|
||||
vm::reservation_update(raddr, 128);
|
||||
vm::notify(raddr, 128);
|
||||
}
|
||||
vm::reservation_update(raddr, 128);
|
||||
vm::notify(raddr, 128);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -718,23 +621,6 @@ void SPUThread::process_mfc_cmd()
|
||||
|
||||
// Store unconditionally
|
||||
// TODO: vm::check_addr
|
||||
|
||||
if (s_use_rtm && utils::transaction_enter())
|
||||
{
|
||||
if (!vm::reader_lock{vm::try_to_lock})
|
||||
{
|
||||
_xabort(0);
|
||||
}
|
||||
|
||||
data = to_write;
|
||||
vm::reservation_update(ch_mfc_cmd.eal, 128);
|
||||
vm::notify(ch_mfc_cmd.eal, 128);
|
||||
_xend();
|
||||
|
||||
ch_atomic_stat.set_value(MFC_PUTLLUC_SUCCESS);
|
||||
return;
|
||||
}
|
||||
|
||||
vm::writer_lock lock(0);
|
||||
data = to_write;
|
||||
vm::reservation_update(ch_mfc_cmd.eal, 128);
|
||||
@@ -1011,7 +897,7 @@ bool SPUThread::get_ch_value(u32 ch, u32& out)
|
||||
if (ctr > 10000)
|
||||
{
|
||||
ctr = 0;
|
||||
std::this_thread::yield();
|
||||
std::this_thread::sleep_for(0us);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1092,11 +978,6 @@ bool SPUThread::get_ch_value(u32 ch, u32& out)
|
||||
case SPU_RdDec:
|
||||
{
|
||||
out = ch_dec_value - (u32)(get_timebased_time() - ch_dec_start_timestamp);
|
||||
|
||||
//Polling: We might as well hint to the scheduler to slot in another thread since this one is counting down
|
||||
if (g_cfg.core.spu_loop_detection && out > spu::scheduler::native_jiffy_duration_us)
|
||||
std::this_thread::yield();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -582,7 +582,6 @@ public:
|
||||
|
||||
std::exception_ptr pending_exception;
|
||||
|
||||
std::array<struct spu_function_t*, 65536> compiled_cache{};
|
||||
std::shared_ptr<class SPUDatabase> spu_db;
|
||||
std::shared_ptr<class spu_recompiler_base> spu_rec;
|
||||
u32 recursion_level = 0;
|
||||
|
||||
@@ -414,7 +414,7 @@ error_code sys_event_port_disconnect(u32 eport_id)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code sys_event_port_send(ppu_thread& ppu, u32 eport_id, u64 data1, u64 data2, u64 data3)
|
||||
error_code sys_event_port_send(u32 eport_id, u64 data1, u64 data2, u64 data3)
|
||||
{
|
||||
sys_event.trace("sys_event_port_send(eport_id=0x%x, data1=0x%llx, data2=0x%llx, data3=0x%llx)", eport_id, data1, data2, data3);
|
||||
|
||||
|
||||
@@ -137,4 +137,4 @@ error_code sys_event_port_create(vm::ps3::ptr<u32> eport_id, s32 port_type, u64
|
||||
error_code sys_event_port_destroy(u32 eport_id);
|
||||
error_code sys_event_port_connect_local(u32 event_port_id, u32 event_queue_id);
|
||||
error_code sys_event_port_disconnect(u32 eport_id);
|
||||
error_code sys_event_port_send(ppu_thread& ppu, u32 event_port_id, u64 data1, u64 data2, u64 data3);
|
||||
error_code sys_event_port_send(u32 event_port_id, u64 data1, u64 data2, u64 data3);
|
||||
|
||||
@@ -25,16 +25,13 @@ static const std::unordered_map<std::string, int> s_prx_ignore
|
||||
{ "/dev_flash/sys/external/libaudio.sprx", 0 },
|
||||
{ "/dev_flash/sys/external/libbeisobmf.sprx", 0 },
|
||||
{ "/dev_flash/sys/external/libcamera.sprx", 0 },
|
||||
{ "/dev_flash/sys/external/libgcm_sys.sprx", 0 },
|
||||
{ "/dev_flash/sys/external/libgem.sprx", 0 },
|
||||
{ "/dev_flash/sys/external/libhttp.sprx", 0 },
|
||||
{ "/dev_flash/sys/external/libio.sprx", 0 },
|
||||
{ "/dev_flash/sys/external/libmedi.sprx", 0 },
|
||||
{ "/dev_flash/sys/external/libmic.sprx", 0 },
|
||||
{ "/dev_flash/sys/external/libnet.sprx", 0 },
|
||||
{ "/dev_flash/sys/external/libnetctl.sprx", 0 },
|
||||
{ "/dev_flash/sys/external/librudp.sprx", 0 },
|
||||
{ "/dev_flash/sys/external/libssl.sprx", 0 },
|
||||
{ "/dev_flash/sys/external/libsysutil.sprx", 0 },
|
||||
{ "/dev_flash/sys/external/libsysutil_ap.sprx", 0 },
|
||||
{ "/dev_flash/sys/external/libsysutil_authdialog.sprx", 0 },
|
||||
|
||||
+303
-31
@@ -1,14 +1,109 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
#include "Emu/RSX/GSRender.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/Cell/ErrorCodes.h"
|
||||
#include "sys_rsx.h"
|
||||
#include "sys_event.h"
|
||||
|
||||
namespace vm { using namespace ps3; }
|
||||
|
||||
logs::channel sys_rsx("sys_rsx");
|
||||
|
||||
extern u64 get_timebased_time();
|
||||
|
||||
struct RsxDriverInfo {
|
||||
be_t<u32> version_driver; // 0x0
|
||||
be_t<u32> version_gpu; // 0x4
|
||||
be_t<u32> memory_size; // 0x8
|
||||
be_t<u32> hardware_channel; // 0xC
|
||||
be_t<u32> nvcore_frequency; // 0x10
|
||||
be_t<u32> memory_frequency; // 0x14
|
||||
be_t<u32> unk1[4]; // 0x18 - 0x24
|
||||
be_t<u32> unk2; // 0x28 -- pgraph stuff
|
||||
be_t<u32> reportsNotifyOffset;// 0x2C offset to notify memory
|
||||
be_t<u32> reportsOffset; // 0x30 offset to reports memory
|
||||
be_t<u32> reportsReportOffset;// 0x34 offset to reports in reports memory
|
||||
be_t<u32> unk3[6]; // 0x38-0x54
|
||||
be_t<u32> systemModeFlags; // 0x54
|
||||
u8 unk4[0x1064]; // 0x10B8
|
||||
struct Head {
|
||||
be_t<u64> lastFlipTime; // 0x0 last flip time
|
||||
be_t<u32> flipFlags; // 0x8 flags to handle flip/queue
|
||||
be_t<u32> unk1; // 0xC
|
||||
be_t<u32> flipBufferId; // 0x10
|
||||
be_t<u32> queuedBufferId; // 0x14 todo: this is definately not this variable but its 'unused' so im using it for queueId to pass to flip handler
|
||||
be_t<u32> unk3; // 0x18
|
||||
be_t<u32> unk6; // 0x18 possible low bits of time stamp? used in getlastVBlankTime
|
||||
be_t<u64> lastSecondVTime; // 0x20 last time for second vhandler freq
|
||||
be_t<u64> unk4; // 0x28
|
||||
be_t<u64> vBlankCount; // 0x30
|
||||
be_t<u32> unk; // 0x38 possible u32, 'flip field', top/bottom for interlaced
|
||||
be_t<u32> unk5; // 0x3C possible high bits of time stamp? used in getlastVBlankTime
|
||||
} head[8]; // size = 0x40, 0x200
|
||||
be_t<u32> unk7; // 0x12B8
|
||||
be_t<u32> unk8; // 0x12BC
|
||||
be_t<u32> handlers; // 0x12C0 -- flags showing which handlers are set
|
||||
be_t<u32> unk9; // 0x12C4
|
||||
be_t<u32> unk10; // 0x12C8
|
||||
be_t<u32> userCmdParam; // 0x12CC
|
||||
be_t<u32> handler_queue; // 0x12D0
|
||||
be_t<u32> unk11; // 0x12D4
|
||||
be_t<u32> unk12; // 0x12D8
|
||||
be_t<u32> unk13; // 0x12DC
|
||||
be_t<u32> unk14; // 0x12E0
|
||||
be_t<u32> unk15; // 0x12E4
|
||||
be_t<u32> unk16; // 0x12E8
|
||||
be_t<u32> unk17; // 0x12F0
|
||||
be_t<u32> lastError; // 0x12F4 error param for cellGcmSetGraphicsHandler
|
||||
// todo: theres more to this
|
||||
};
|
||||
template <size_t S> class Sizer { };
|
||||
Sizer<sizeof(RsxDriverInfo)> foo;
|
||||
static_assert(sizeof(RsxDriverInfo) == 0x12F8, "rsxSizeTest");
|
||||
static_assert(sizeof(RsxDriverInfo::Head) == 0x40, "rsxHeadSizeTest");
|
||||
|
||||
struct RsxDmaControl {
|
||||
u8 resv[0x40];
|
||||
be_t<u32> put;
|
||||
be_t<u32> get;
|
||||
be_t<u32> ref;
|
||||
be_t<u32> unk[2];
|
||||
be_t<u32> unk1;
|
||||
};
|
||||
|
||||
struct RsxSemaphore {
|
||||
be_t<u32> val;
|
||||
be_t<u32> pad;
|
||||
be_t<u64> timestamp;
|
||||
};
|
||||
|
||||
struct RsxNotify {
|
||||
be_t<u64> timestamp;
|
||||
be_t<u64> zero;
|
||||
};
|
||||
|
||||
struct RsxReport {
|
||||
be_t<u64> timestamp;
|
||||
be_t<u32> val;
|
||||
be_t<u32> pad;
|
||||
};
|
||||
|
||||
struct RsxReports {
|
||||
RsxSemaphore semaphore[0x100];
|
||||
RsxNotify notify[64];
|
||||
RsxReport report[2048];
|
||||
};
|
||||
|
||||
be_t<u32> g_rsx_event_port{ 0 };
|
||||
u32 g_driverInfo{ 0 };
|
||||
|
||||
u64 rsxTimeStamp() {
|
||||
return get_timebased_time();
|
||||
}
|
||||
|
||||
s32 sys_rsx_device_open()
|
||||
{
|
||||
sys_rsx.todo("sys_rsx_device_open()");
|
||||
@@ -37,6 +132,9 @@ s32 sys_rsx_memory_allocate(vm::ptr<u32> mem_handle, vm::ptr<u64> mem_addr, u32
|
||||
{
|
||||
sys_rsx.todo("sys_rsx_memory_allocate(mem_handle=*0x%x, mem_addr=*0x%x, size=0x%x, flags=0x%llx, a5=0x%llx, a6=0x%llx, a7=0x%llx)", mem_handle, mem_addr, size, flags, a5, a6, a7);
|
||||
|
||||
*mem_handle = 1;
|
||||
*mem_addr = vm::falloc(0xC0000000, size, vm::video);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -60,10 +158,89 @@ s32 sys_rsx_memory_free(u32 mem_handle)
|
||||
* @param mem_ctx (IN): mem_ctx given by sys_rsx_memory_allocate
|
||||
* @param system_mode (IN):
|
||||
*/
|
||||
s32 sys_rsx_context_allocate(vm::ptr<u32> context_id, vm::ptr<u32> lpar_dma_control, vm::ptr<u32> lpar_driver_info, vm::ptr<u32> lpar_reports, u64 mem_ctx, u64 system_mode)
|
||||
s32 sys_rsx_context_allocate(vm::ptr<u32> context_id, vm::ptr<u64> lpar_dma_control, vm::ptr<u64> lpar_driver_info, vm::ptr<u64> lpar_reports, u64 mem_ctx, u64 system_mode)
|
||||
{
|
||||
sys_rsx.todo("sys_rsx_context_allocate(context_id=*0x%x, lpar_dma_control=*0x%x, lpar_driver_info=*0x%x, lpar_reports=*0x%x, mem_ctx=0x%llx, system_mode=0x%llx)",
|
||||
context_id, lpar_dma_control, lpar_driver_info, lpar_reports, mem_ctx, system_mode);
|
||||
sys_rsx.todo("sys_rsx_context_allocate(context_id=*0x%x, lpar_dma_control=*0x%x, lpar_driver_info=*0x%x, lpar_reports=*0x%x, mem_ctx=0x%llx, system_mode=0x%llx)",
|
||||
context_id, lpar_dma_control, lpar_driver_info, lpar_reports, mem_ctx, system_mode);
|
||||
|
||||
vm::falloc(0x40000000, 0x10000000, vm::rsx_context);
|
||||
|
||||
*context_id = 0x55555555;
|
||||
|
||||
*lpar_dma_control = 0x40100000;
|
||||
*lpar_driver_info = 0x40200000;
|
||||
*lpar_reports = 0x40300000;
|
||||
|
||||
auto &reports = vm::_ref<RsxReports>(*lpar_reports);
|
||||
std::memset(&reports, 0, sizeof(RsxReports));
|
||||
|
||||
for (int i = 0; i < 64; ++i)
|
||||
reports.notify[i].timestamp = (u64)-1;
|
||||
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
reports.semaphore[i].val = 0x1337C0D3;
|
||||
reports.semaphore[i].pad = 0x1337BABE;
|
||||
reports.semaphore[i].timestamp = (u64)-1; // technically different but should be fine
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2048; ++i)
|
||||
reports.report[i].timestamp = (u64)-1;
|
||||
|
||||
auto &sysReports = vm::_ref<RsxSemaphore>(0x40000030);
|
||||
// slight hack for testing....
|
||||
sysReports.val = 1;
|
||||
|
||||
auto &driverInfo = vm::_ref<RsxDriverInfo>(*lpar_driver_info);
|
||||
|
||||
std::memset(&driverInfo, 0, sizeof(RsxDriverInfo));
|
||||
|
||||
driverInfo.version_driver = 0x211;
|
||||
driverInfo.version_gpu = 0x5c;
|
||||
driverInfo.memory_size = 0xFE00000;
|
||||
driverInfo.nvcore_frequency = 500000000; // 0x1DCD6500
|
||||
driverInfo.memory_frequency = 650000000; // 0x26BE3680
|
||||
driverInfo.reportsNotifyOffset = 0x1000;
|
||||
driverInfo.reportsOffset = 0;
|
||||
driverInfo.reportsReportOffset = 0x1400;
|
||||
driverInfo.systemModeFlags = system_mode;
|
||||
driverInfo.hardware_channel = 1; // * i think* this 1 for games, 0 for vsh
|
||||
|
||||
g_driverInfo = *lpar_driver_info;
|
||||
|
||||
auto &dmaControl = vm::_ref<RsxDmaControl>(*lpar_dma_control);
|
||||
dmaControl.get = 0;
|
||||
dmaControl.put = 0;
|
||||
dmaControl.ref = 0xFFFFFFFF;
|
||||
|
||||
if (false/*system_mode == CELL_GCM_SYSTEM_MODE_IOMAP_512MB*/)
|
||||
RSXIOMem.SetRange(0, 0x20000000 /*512MB*/);
|
||||
else
|
||||
RSXIOMem.SetRange(0, 0x10000000 /*256MB*/);
|
||||
|
||||
sys_event_queue_attribute_t attr;
|
||||
attr.protocol = SYS_SYNC_PRIORITY;
|
||||
attr.type = SYS_PPU_QUEUE;
|
||||
auto queueId = vm::make_var<u32>(0);
|
||||
sys_event_queue_create(queueId, vm::make_var(attr), 0, 0x20);
|
||||
driverInfo.handler_queue = queueId->value();
|
||||
|
||||
sys_event_port_create(queueId, SYS_EVENT_PORT_LOCAL, 0);
|
||||
sys_event_port_connect_local(queueId->value(), driverInfo.handler_queue);
|
||||
|
||||
g_rsx_event_port = queueId->value();
|
||||
|
||||
const auto render = fxm::get<GSRender>();
|
||||
render->ctrl = vm::_ptr<CellGcmControl>(*lpar_dma_control);
|
||||
//render->intr_thread = idm::make_ptr<ppu_thread>("_gcm_intr_thread", 1, 0x4000);
|
||||
//render->intr_thread->run();
|
||||
//render->ctxt_addr = 0;
|
||||
render->gcm_buffers.set((vm::alloc(sizeof(CellGcmDisplayInfo) * 8, vm::main)));
|
||||
render->zculls_addr = vm::alloc(sizeof(CellGcmZcullInfo) * 8, vm::main);
|
||||
render->gcm_buffers_count = 0;
|
||||
render->gcm_current_buffer = 0;
|
||||
render->main_mem_addr = 0;
|
||||
render->label_addr = *lpar_reports;
|
||||
render->init(0x30100000, 0x200000, *lpar_dma_control, 0xC0000000);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -90,8 +267,10 @@ s32 sys_rsx_context_free(u32 context_id)
|
||||
s32 sys_rsx_context_iomap(u32 context_id, u32 io, u32 ea, u32 size, u64 flags)
|
||||
{
|
||||
sys_rsx.todo("sys_rsx_context_iomap(context_id=0x%x, io=0x%x, ea=0x%x, size=0x%x, flags=0x%llx)", context_id, io, ea, size, flags);
|
||||
|
||||
return CELL_OK;
|
||||
if (RSXIOMem.Map(ea, size, io))
|
||||
return CELL_OK;
|
||||
LOG_ERROR(RSX, "rsx_iomap failed");
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -101,11 +280,13 @@ s32 sys_rsx_context_iomap(u32 context_id, u32 io, u32 ea, u32 size, u64 flags)
|
||||
* @param io_addr (IN): IO address. E.g. 0x00600000 (Start page 6)
|
||||
* @param size (IN): Size to unmap in byte. E.g. 0x00200000
|
||||
*/
|
||||
s32 sys_rsx_context_iounmap(u32 context_id, u32 a2, u32 io_addr, u32 size)
|
||||
s32 sys_rsx_context_iounmap(u32 context_id, u32 io_addr, u32 a3, u32 size)
|
||||
{
|
||||
sys_rsx.todo("sys_rsx_context_iounmap(context_id=0x%x, a2=0x%x, io_addr=0x%x, size=0x%x)", context_id, a2, io_addr, size);
|
||||
|
||||
return CELL_OK;
|
||||
sys_rsx.todo("sys_rsx_context_iounmap(context_id=0x%x, io_addr=0x%x, a3=0x%x, size=0x%x)", context_id, io_addr, a3, size);
|
||||
if (RSXIOMem.UnmapAddress(io_addr, size))
|
||||
return CELL_OK;
|
||||
LOG_ERROR(RSX, "rsx_iounmap failed");
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -119,40 +300,110 @@ s32 sys_rsx_context_iounmap(u32 context_id, u32 a2, u32 io_addr, u32 size)
|
||||
*/
|
||||
s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u64 a5, u64 a6)
|
||||
{
|
||||
if (package_id != 0xFED)
|
||||
sys_rsx.todo("sys_rsx_context_attribute(context_id=0x%x, package_id=0x%x, a3=0x%llx, a4=0x%llx, a5=0x%llx, a6=0x%llx)", context_id, package_id, a3, a4, a5, a6);
|
||||
|
||||
// hle/lle protection
|
||||
if (g_driverInfo == 0)
|
||||
return CELL_OK;
|
||||
// todo: these event ports probly 'shouldnt' be here as i think its supposed to be interrupts that are sent from rsx somewhere in lv1
|
||||
|
||||
const auto render = fxm::get<GSRender>();
|
||||
auto &driverInfo = vm::_ref<RsxDriverInfo>(g_driverInfo);
|
||||
switch(package_id)
|
||||
{
|
||||
case 0x001: // FIFO
|
||||
render->ctrl->get = a3;
|
||||
render->ctrl->put = a4;
|
||||
break;
|
||||
|
||||
case 0x100: // Display mode set
|
||||
break;
|
||||
|
||||
case 0x101: // Display sync
|
||||
break;
|
||||
break;
|
||||
case 0x101: // Display sync set, cellGcmSetFlipMode
|
||||
break;
|
||||
|
||||
case 0x102: // Display flip
|
||||
driverInfo.head[a3].flipFlags |= 0x80000000;
|
||||
driverInfo.head[a3].lastFlipTime = rsxTimeStamp(); // should rsxthread set this?
|
||||
// lets give this a shot for giving bufferid back to gcm
|
||||
driverInfo.head[a3].flipBufferId = driverInfo.head[a3].queuedBufferId;
|
||||
// seems gcmSysWaitLabel uses this offset, so lets set it to 0 every flip
|
||||
vm::_ref<u32>(0x40300010) = 0;
|
||||
if (a3 == 0)
|
||||
sys_event_port_send(g_rsx_event_port, 0, (1 << 3), 0);
|
||||
if (a3 == 1)
|
||||
sys_event_port_send(g_rsx_event_port, 0, (1 << 4), 0);
|
||||
break;
|
||||
|
||||
case 0x103: // ?
|
||||
case 0x103: // Display Queue
|
||||
driverInfo.head[a3].queuedBufferId = a4;
|
||||
driverInfo.head[a3].flipFlags |= 0x40000000 | (1 << a4);
|
||||
if (a3 == 0)
|
||||
sys_event_port_send(g_rsx_event_port, 0, (1 << 5), 0);
|
||||
if (a3 == 1)
|
||||
sys_event_port_send(g_rsx_event_port, 0, (1 << 6), 0);
|
||||
break;
|
||||
|
||||
case 0x104: // Display buffer
|
||||
break;
|
||||
{
|
||||
u8 id = a3 & 0xFF;
|
||||
u32 width = (a4 >> 32) & 0xFFFFFFFF;
|
||||
u32 height = a4 & 0xFFFFFFFF;
|
||||
u32 pitch = (a5 >> 32) & 0xFFFFFFFF;
|
||||
u32 offset = a5 & 0xFFFFFFFF;
|
||||
if (id > 7)
|
||||
return -17;
|
||||
render->gcm_buffers[id].width = width;
|
||||
render->gcm_buffers[id].height = height;
|
||||
render->gcm_buffers[id].pitch = pitch;
|
||||
render->gcm_buffers[id].offset = offset;
|
||||
|
||||
if (id + 1 > render->gcm_buffers_count)
|
||||
render->gcm_buffers_count = id + 1;
|
||||
}
|
||||
break;
|
||||
case 0x105: // destroy buffer?
|
||||
break;
|
||||
|
||||
case 0x106: // ? (Used by cellGcmInitPerfMon)
|
||||
break;
|
||||
case 0x108: // ? set interrupt freq?
|
||||
break;
|
||||
case 0x10a: // ? Involved in managing flip status through cellGcmResetFlipStatus
|
||||
{
|
||||
if (a3 > 7)
|
||||
return -17;
|
||||
u32 flipStatus = driverInfo.head[a3].flipFlags;
|
||||
flipStatus = (flipStatus & a4) | a5;
|
||||
driverInfo.head[a3].flipFlags = flipStatus;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x10a: // ?
|
||||
break;
|
||||
case 0x10D: // Called by cellGcmInitCursor
|
||||
break;
|
||||
|
||||
case 0x300: // Tiles
|
||||
break;
|
||||
{
|
||||
//a4 high bits = ret.tile = (location + 1) | (bank << 4) | ((offset / 0x10000) << 16) | (location << 31);
|
||||
//a4 low bits = ret.limit = ((offset + size - 1) / 0x10000) << 16 | (location << 31);
|
||||
//a5 high bits = ret.pitch = (pitch / 0x100) << 8;
|
||||
//a5 low bits = ret.format = base | ((base + ((size - 1) / 0x10000)) << 13) | (comp << 26) | (1 << 30);
|
||||
|
||||
auto& tile = render->tiles[a3];
|
||||
tile.location = ((a4 >> 32) & 0xF) - 1;
|
||||
tile.offset = ((((a4 >> 32) & 0xFFFFFFFF) >> 16) * 0x10000);
|
||||
tile.size = ((((a4 & 0x7FFFFFFF) >> 16) + 1) * 0x10000) - tile.offset;
|
||||
tile.pitch = (((a5 >> 32) & 0xFFFFFFFF) >> 8) * 0x100;
|
||||
tile.comp = ((a5 & 0xFFFFFFFF) >> 26) & 0xF;
|
||||
tile.base = (a5 & 0xFFFFFFFF) & 0x7FF;
|
||||
tile.bank = (((a4 >> 32) & 0xFFFFFFFF) >> 4) & 0xF;
|
||||
tile.binded = a5 != 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x301: // Depth-buffer (Z-cull)
|
||||
break;
|
||||
|
||||
case 0x302: // something with zcull
|
||||
break;
|
||||
case 0x600: // Framebuffer setup
|
||||
break;
|
||||
|
||||
@@ -162,6 +413,24 @@ s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u6
|
||||
case 0x602: // Framebuffer blit sync
|
||||
break;
|
||||
|
||||
case 0x603: // Framebuffer close
|
||||
break;
|
||||
|
||||
case 0xFED: // hack: vblank command
|
||||
// todo: this is wrong and should be 'second' vblank handler and freq
|
||||
// although gcmSys seems just hardcoded at 1, so w/e
|
||||
driverInfo.head[a3].vBlankCount++;
|
||||
driverInfo.head[a3].lastSecondVTime = rsxTimeStamp();
|
||||
sys_event_port_send(g_rsx_event_port, 0, (1 << 1), 0);
|
||||
sys_event_port_send(g_rsx_event_port, 0, (1 << 11), 0); // second vhandler
|
||||
break;
|
||||
case 0xFEF: // hack: user command
|
||||
// 'custom' invalid package id for now
|
||||
// as i think we need custom lv1 interrupts to handle this accurately
|
||||
// this also should probly be set by rsxthread
|
||||
driverInfo.userCmdParam = a4;
|
||||
sys_event_port_send(g_rsx_event_port, 0, (1 << 7), 0);
|
||||
break;
|
||||
default:
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
@@ -175,19 +444,19 @@ s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u6
|
||||
* @param a2 (OUT): Unused?
|
||||
* @param dev_id (IN): An immediate value and always 8. (cellGcmInitPerfMon uses 11, 10, 9, 7, 12 successively).
|
||||
*/
|
||||
s32 sys_rsx_device_map(vm::ptr<u32> addr, vm::ptr<u32> a2, u32 dev_id)
|
||||
s32 sys_rsx_device_map(vm::ptr<u64> addr, vm::ptr<u64> a2, u32 dev_id)
|
||||
{
|
||||
sys_rsx.todo("sys_rsx_device_map(addr=*0x%x, a2=*0x%x, dev_id=0x%x)", addr, a2, dev_id);
|
||||
|
||||
if (dev_id > 15) {
|
||||
// TODO: Throw RSX error
|
||||
return CELL_EINVAL;
|
||||
if (dev_id != 8) {
|
||||
// TODO: lv1 related
|
||||
fmt::throw_exception("sys_rsx_device_map: Invalid dev_id %d", dev_id);
|
||||
}
|
||||
|
||||
if (dev_id == 0 || dev_id > 8) {
|
||||
// TODO: lv1 related so we may ignore it.
|
||||
// if (something) { return CELL_EPERM; }
|
||||
}
|
||||
// a2 seems to not be referenced in cellGcmSys
|
||||
*a2 = 0;
|
||||
|
||||
*addr = 0x40000000;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -203,9 +472,12 @@ s32 sys_rsx_device_unmap(u32 dev_id)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_rsx_attribute(u32 a1, u32 a2, u32 a3, u32 a4, u32 a5)
|
||||
/*
|
||||
* lv2 SysCall 677 (0x2A5): sys_rsx_attribute
|
||||
*/
|
||||
s32 sys_rsx_attribute(u32 packageId, u32 a2, u32 a3, u32 a4, u32 a5)
|
||||
{
|
||||
sys_rsx.todo("sys_rsx_attribute(a1=0x%x, a2=0x%x, a3=0x%x, a4=0x%x, a5=0x%x)", a1, a2, a3, a4, a5);
|
||||
sys_rsx.todo("sys_rsx_attribute(packageId=0x%x, a2=0x%x, a3=0x%x, a4=0x%x, a5=0x%x)", packageId, a2, a3, a4, a5);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -5,11 +5,11 @@ s32 sys_rsx_device_open();
|
||||
s32 sys_rsx_device_close();
|
||||
s32 sys_rsx_memory_allocate(vm::ps3::ptr<u32> mem_handle, vm::ps3::ptr<u64> mem_addr, u32 size, u64 flags, u64 a5, u64 a6, u64 a7);
|
||||
s32 sys_rsx_memory_free(u32 mem_handle);
|
||||
s32 sys_rsx_context_allocate(vm::ps3::ptr<u32> context_id, vm::ps3::ptr<u32> lpar_dma_control, vm::ps3::ptr<u32> lpar_driver_info, vm::ps3::ptr<u32> lpar_reports, u64 mem_ctx, u64 system_mode);
|
||||
s32 sys_rsx_context_allocate(vm::ps3::ptr<u32> context_id, vm::ps3::ptr<u64> lpar_dma_control, vm::ps3::ptr<u64> lpar_driver_info, vm::ps3::ptr<u64> lpar_reports, u64 mem_ctx, u64 system_mode);
|
||||
s32 sys_rsx_context_free(u32 context_id);
|
||||
s32 sys_rsx_context_iomap(u32 context_id, u32 io, u32 ea, u32 size, u64 flags);
|
||||
s32 sys_rsx_context_iounmap(u32 context_id, u32 a2, u32 io_addr, u32 size);
|
||||
s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u64 a5, u64 a6);
|
||||
s32 sys_rsx_device_map(vm::ps3::ptr<u32> addr, vm::ps3::ptr<u32> a2, u32 dev_id);
|
||||
s32 sys_rsx_device_map(vm::ps3::ptr<u64> addr, vm::ps3::ptr<u64> a2, u32 dev_id);
|
||||
s32 sys_rsx_device_unmap(u32 dev_id);
|
||||
s32 sys_rsx_attribute(u32 a1, u32 a2, u32 a3, u32 a4, u32 a5);
|
||||
|
||||
@@ -34,13 +34,24 @@ void sys_spu_image::load(const fs::file& stream)
|
||||
|
||||
const u32 addr = this->segs.addr() + 4096;
|
||||
|
||||
sha1_context ctx;
|
||||
u8 output[20];
|
||||
|
||||
sha1_starts(&ctx);
|
||||
sha1_update(&ctx, reinterpret_cast<const u8*>(&obj.header), sizeof(obj.header));
|
||||
|
||||
for (const auto& shdr : obj.shdrs)
|
||||
{
|
||||
sha1_update(&ctx, reinterpret_cast<const u8*>(&shdr), sizeof(spu_exec_object::shdr_t));
|
||||
|
||||
LOG_NOTICE(SPU, "** Section: sh_type=0x%x, addr=0x%llx, size=0x%llx, flags=0x%x", shdr.sh_type, shdr.sh_addr, shdr.sh_size, shdr.sh_flags);
|
||||
}
|
||||
|
||||
for (const auto& prog : obj.progs)
|
||||
{
|
||||
sha1_update(&ctx, reinterpret_cast<const u8*>(&prog), sizeof(spu_exec_object::phdr_t));
|
||||
sha1_update(&ctx, reinterpret_cast<const u8*>(prog.bin.data()), prog.bin.size());
|
||||
|
||||
LOG_NOTICE(SPU, "** Segment: p_type=0x%x, p_vaddr=0x%llx, p_filesz=0x%llx, p_memsz=0x%llx, flags=0x%x", prog.p_type, prog.p_vaddr, prog.p_filesz, prog.p_memsz, prog.p_flags);
|
||||
|
||||
if (prog.p_type == SYS_SPU_SEGMENT_TYPE_COPY)
|
||||
@@ -74,6 +85,22 @@ void sys_spu_image::load(const fs::file& stream)
|
||||
LOG_ERROR(SPU, "Unknown program type (0x%x)", prog.p_type);
|
||||
}
|
||||
}
|
||||
|
||||
sha1_finish(&ctx, output);
|
||||
|
||||
// Format patch name
|
||||
std::string hash("spu-");
|
||||
for (u8 x : output) fmt::append(hash, "%02x", x);
|
||||
LOG_NOTICE(LOADER, "Loaded SPU image: %s", hash);
|
||||
|
||||
// Apply the patch
|
||||
fxm::check_unlocked<patch_engine>()->apply(hash, vm::g_base_addr + addr);
|
||||
|
||||
if (!Emu.GetTitleID().empty())
|
||||
{
|
||||
// Alternative patch
|
||||
fxm::check_unlocked<patch_engine>()->apply(Emu.GetTitleID() + '-' + hash, vm::g_base_addr + addr);
|
||||
}
|
||||
}
|
||||
|
||||
void sys_spu_image::free()
|
||||
@@ -86,29 +113,15 @@ void sys_spu_image::free()
|
||||
|
||||
void sys_spu_image::deploy(u32 loc)
|
||||
{
|
||||
// Segment info dump
|
||||
std::string dump;
|
||||
|
||||
// Executable hash
|
||||
sha1_context sha;
|
||||
sha1_starts(&sha);
|
||||
u8 sha1_hash[20];
|
||||
|
||||
for (int i = 0; i < nsegs; i++)
|
||||
{
|
||||
auto& seg = segs[i];
|
||||
|
||||
fmt::append(dump, "\n\t[%d] t=0x%x, ls=0x%x, size=0x%x, addr=0x%x", i, seg.type, seg.ls, seg.size, seg.addr);
|
||||
|
||||
// Hash big-endian values
|
||||
sha1_update(&sha, (uchar*)&seg.type, sizeof(seg.type));
|
||||
sha1_update(&sha, (uchar*)&seg.size, sizeof(seg.size));
|
||||
LOG_NOTICE(SPU, "*** Deploy: t=0x%x, ls=0x%x, size=0x%x, addr=0x%x", seg.type, seg.ls, seg.size, seg.addr);
|
||||
|
||||
if (seg.type == SYS_SPU_SEGMENT_TYPE_COPY)
|
||||
{
|
||||
std::memcpy(vm::base(loc + seg.ls), vm::base(seg.addr), seg.size);
|
||||
sha1_update(&sha, (uchar*)&seg.ls, sizeof(seg.ls));
|
||||
sha1_update(&sha, vm::g_base_addr + seg.addr, seg.size);
|
||||
}
|
||||
else if (seg.type == SYS_SPU_SEGMENT_TYPE_FILL)
|
||||
{
|
||||
@@ -118,32 +131,8 @@ void sys_spu_image::deploy(u32 loc)
|
||||
}
|
||||
|
||||
std::fill_n(vm::_ptr<u32>(loc + seg.ls), seg.size / 4, seg.addr);
|
||||
sha1_update(&sha, (uchar*)&seg.ls, sizeof(seg.ls));
|
||||
sha1_update(&sha, (uchar*)&seg.addr, sizeof(seg.addr));
|
||||
}
|
||||
}
|
||||
|
||||
sha1_finish(&sha, sha1_hash);
|
||||
|
||||
// Format patch name
|
||||
std::string hash("SPU-0000000000000000000000000000000000000000");
|
||||
for (u32 i = 0; i < sizeof(sha1_hash); i++)
|
||||
{
|
||||
constexpr auto pal = "0123456789abcdef";
|
||||
hash[4 + i * 2] = pal[sha1_hash[i] >> 4];
|
||||
hash[5 + i * 2] = pal[sha1_hash[i] & 15];
|
||||
}
|
||||
|
||||
// Apply the patch
|
||||
auto applied = fxm::check_unlocked<patch_engine>()->apply(hash, vm::g_base_addr + loc);
|
||||
|
||||
if (!Emu.GetTitleID().empty())
|
||||
{
|
||||
// Alternative patch
|
||||
applied += fxm::check_unlocked<patch_engine>()->apply(Emu.GetTitleID() + '-' + hash, vm::g_base_addr + loc);
|
||||
}
|
||||
|
||||
LOG_NOTICE(LOADER, "Loaded SPU image: %s (<- %u)%s", hash, applied, dump);
|
||||
}
|
||||
|
||||
error_code sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu)
|
||||
|
||||
@@ -55,13 +55,13 @@ bool VirtualMemoryBlock::Map(u32 realaddr, u32 size, u32 addr)
|
||||
return false;
|
||||
}
|
||||
|
||||
for (u32 i = 0; i<m_mapped_memory.size(); ++i)
|
||||
/*for (u32 i = 0; i<m_mapped_memory.size(); ++i)
|
||||
{
|
||||
if (addr >= m_mapped_memory[i].addr && addr + size - 1 <= m_mapped_memory[i].addr + m_mapped_memory[i].size - 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
m_mapped_memory.emplace_back(addr, realaddr, size);
|
||||
return true;
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
|
||||
namespace vm
|
||||
{
|
||||
static u8* memory_reserve_4GiB(std::uintptr_t _addr = 0)
|
||||
static u8* memory_reserve_4GiB(std::uintptr_t addr = 0)
|
||||
{
|
||||
for (u64 addr = _addr + 0x100000000;; addr += 0x100000000)
|
||||
for (u64 addr = 0x100000000;; addr += 0x100000000)
|
||||
{
|
||||
if (auto ptr = utils::memory_reserve(0x100000000, (void*)addr))
|
||||
{
|
||||
@@ -783,6 +783,7 @@ namespace vm
|
||||
{
|
||||
std::make_shared<block_t>(0x00010000, 0x1FFF0000), // main
|
||||
std::make_shared<block_t>(0x20000000, 0x10000000), // user
|
||||
std::make_shared<block_t>(0x40000000, 0x30000000), // rsx contexts
|
||||
std::make_shared<block_t>(0xC0000000, 0x10000000), // video
|
||||
std::make_shared<block_t>(0xD0000000, 0x10000000), // stack
|
||||
std::make_shared<block_t>(0xE0000000, 0x20000000), // SPU reserved
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace vm
|
||||
{
|
||||
main,
|
||||
user_space,
|
||||
rsx_context,
|
||||
video,
|
||||
stack,
|
||||
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/sysinfo.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
#include "ARMv7Thread.h"
|
||||
#include "ARMv7Interpreter.h"
|
||||
|
||||
const bool s_use_rtm = utils::has_rtm();
|
||||
|
||||
using namespace arm_code::arm_encoding_alias;
|
||||
|
||||
#define ARG(arg, ...) const u32 arg = args::arg::extract(__VA_ARGS__);
|
||||
@@ -2094,34 +2091,13 @@ void arm_interpreter::STREX(ARMv7Thread& cpu, const u32 op, const u32 cond)
|
||||
return;
|
||||
}
|
||||
|
||||
bool result;
|
||||
vm::writer_lock lock(0);
|
||||
|
||||
if (s_use_rtm && utils::transaction_enter())
|
||||
const bool result = cpu.rtime == vm::reservation_acquire(addr, cpu.rtime) && data.compare_and_swap_test(cpu.rdata, value);
|
||||
|
||||
if (result)
|
||||
{
|
||||
if (!vm::reader_lock{vm::try_to_lock})
|
||||
{
|
||||
_xabort(0);
|
||||
}
|
||||
|
||||
result = cpu.rtime == vm::reservation_acquire(addr, sizeof(u32)) && data.compare_and_swap_test(cpu.rdata, value);
|
||||
|
||||
if (result)
|
||||
{
|
||||
vm::reservation_update(addr, sizeof(u32));
|
||||
}
|
||||
|
||||
_xend();
|
||||
}
|
||||
else
|
||||
{
|
||||
vm::writer_lock lock(0);
|
||||
|
||||
result = cpu.rtime == vm::reservation_acquire(addr, sizeof(u32)) && data.compare_and_swap_test(cpu.rdata, value);
|
||||
|
||||
if (result)
|
||||
{
|
||||
vm::reservation_update(addr, sizeof(u32));
|
||||
}
|
||||
vm::reservation_update(addr, sizeof(u32));
|
||||
}
|
||||
|
||||
cpu.raddr = 0;
|
||||
|
||||
@@ -93,12 +93,7 @@ namespace rsx
|
||||
auto It = m_render_targets_storage.find(address);
|
||||
// TODO: Fix corner cases
|
||||
// This doesn't take overlapping surface(s) into account.
|
||||
|
||||
surface_storage_type old_surface_storage;
|
||||
surface_storage_type new_surface_storage;
|
||||
surface_type old_surface = nullptr;
|
||||
surface_type new_surface = nullptr;
|
||||
|
||||
if (It != m_render_targets_storage.end())
|
||||
{
|
||||
surface_storage_type &rtt = It->second;
|
||||
@@ -109,43 +104,10 @@ namespace rsx
|
||||
}
|
||||
|
||||
old_surface = Traits::get(rtt);
|
||||
old_surface_storage = std::move(rtt);
|
||||
invalidated_resources.push_back(std::move(rtt));
|
||||
m_render_targets_storage.erase(address);
|
||||
}
|
||||
|
||||
//Search invalidated resources for a suitable surface
|
||||
for (auto It = invalidated_resources.begin(); It != invalidated_resources.end(); It++)
|
||||
{
|
||||
auto &rtt = *It;
|
||||
if (Traits::rtt_has_format_width_height(rtt, color_format, width, height, true))
|
||||
{
|
||||
new_surface_storage = std::move(rtt);
|
||||
|
||||
if (old_surface)
|
||||
//Exchange this surface with the invalidated one
|
||||
rtt = std::move(old_surface_storage);
|
||||
else
|
||||
//rtt is now empty - erase it
|
||||
invalidated_resources.erase(It);
|
||||
|
||||
new_surface = Traits::get(new_surface_storage);
|
||||
Traits::invalidate_rtt_surface_contents(command_list, new_surface, old_surface, true);
|
||||
Traits::prepare_rtt_for_drawing(command_list, new_surface);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (old_surface != nullptr && new_surface == nullptr)
|
||||
//This was already determined to be invalid and is excluded from testing above
|
||||
invalidated_resources.push_back(std::move(old_surface_storage));
|
||||
|
||||
if (new_surface != nullptr)
|
||||
{
|
||||
//New surface was found among existing surfaces
|
||||
m_render_targets_storage[address] = std::move(new_surface_storage);
|
||||
return new_surface;
|
||||
}
|
||||
|
||||
m_render_targets_storage[address] = Traits::create_new_surface(address, color_format, width, height, old_surface, std::forward<Args>(extra_params)...);
|
||||
return Traits::get(m_render_targets_storage[address]);
|
||||
}
|
||||
@@ -157,11 +119,7 @@ namespace rsx
|
||||
surface_depth_format depth_format, size_t width, size_t height,
|
||||
Args&&... extra_params)
|
||||
{
|
||||
surface_storage_type old_surface_storage;
|
||||
surface_storage_type new_surface_storage;
|
||||
surface_type old_surface = nullptr;
|
||||
surface_type new_surface = nullptr;
|
||||
|
||||
auto It = m_depth_stencil_storage.find(address);
|
||||
if (It != m_depth_stencil_storage.end())
|
||||
{
|
||||
@@ -173,42 +131,10 @@ namespace rsx
|
||||
}
|
||||
|
||||
old_surface = Traits::get(ds);
|
||||
old_surface_storage = std::move(ds);
|
||||
invalidated_resources.push_back(std::move(ds));
|
||||
m_depth_stencil_storage.erase(address);
|
||||
}
|
||||
|
||||
//Search invalidated resources for a suitable surface
|
||||
for (auto It = invalidated_resources.begin(); It != invalidated_resources.end(); It++)
|
||||
{
|
||||
auto &ds = *It;
|
||||
if (Traits::ds_has_format_width_height(ds, depth_format, width, height, true))
|
||||
{
|
||||
new_surface_storage = std::move(ds);
|
||||
|
||||
if (old_surface)
|
||||
//Exchange this surface with the invalidated one
|
||||
ds = std::move(old_surface_storage);
|
||||
else
|
||||
invalidated_resources.erase(It);
|
||||
|
||||
new_surface = Traits::get(new_surface_storage);
|
||||
Traits::prepare_ds_for_drawing(command_list, new_surface);
|
||||
Traits::invalidate_depth_surface_contents(command_list, new_surface, old_surface, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (old_surface != nullptr && new_surface == nullptr)
|
||||
//This was already determined to be invalid and is excluded from testing above
|
||||
invalidated_resources.push_back(std::move(old_surface_storage));
|
||||
|
||||
if (new_surface != nullptr)
|
||||
{
|
||||
//New surface was found among existing surfaces
|
||||
m_depth_stencil_storage[address] = std::move(new_surface_storage);
|
||||
return new_surface;
|
||||
}
|
||||
|
||||
m_depth_stencil_storage[address] = Traits::create_new_surface(address, depth_format, width, height, old_surface, std::forward<Args>(extra_params)...);
|
||||
return Traits::get(m_depth_stencil_storage[address]);
|
||||
}
|
||||
@@ -432,10 +358,10 @@ namespace rsx
|
||||
void invalidate_surface_cache_data(command_list_type command_list)
|
||||
{
|
||||
for (auto &rtt : m_render_targets_storage)
|
||||
Traits::invalidate_rtt_surface_contents(command_list, Traits::get(std::get<1>(rtt)), nullptr, false);
|
||||
Traits::invalidate_rtt_surface_contents(command_list, Traits::get(std::get<1>(rtt)));
|
||||
|
||||
for (auto &ds : m_depth_stencil_storage)
|
||||
Traits::invalidate_depth_surface_contents(command_list, Traits::get(std::get<1>(ds)), nullptr, true);
|
||||
Traits::invalidate_depth_surface_contents(command_list, Traits::get(std::get<1>(ds)));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -223,8 +223,9 @@ namespace
|
||||
const std::vector<std::pair<u32, u32>>& vertex_ranges, d3d12_data_heap& m_buffer_data)
|
||||
{
|
||||
size_t index_count = std::accumulate(
|
||||
vertex_ranges.begin(), vertex_ranges.end(), 0ll, [](size_t acc, const auto& pair) {
|
||||
return acc + get_index_count(rsx::method_registers.current_draw_clause.primitive, pair.second);
|
||||
vertex_ranges.begin(), vertex_ranges.end(), 0, [](size_t acc, const auto& pair) {
|
||||
return acc + get_index_count(
|
||||
rsx::method_registers.current_draw_clause.primitive, pair.second);
|
||||
});
|
||||
|
||||
// Alloc
|
||||
@@ -235,7 +236,7 @@ namespace
|
||||
void* mapped_buffer =
|
||||
m_buffer_data.map<void>(CD3DX12_RANGE(heap_offset, heap_offset + buffer_size));
|
||||
|
||||
u32 vertex_count = 0;
|
||||
size_t vertex_count = 0;
|
||||
for (const auto& pair : vertex_ranges)
|
||||
vertex_count += pair.second;
|
||||
|
||||
|
||||
@@ -324,17 +324,6 @@ void D3D12GSRender::end()
|
||||
{
|
||||
std::chrono::time_point<steady_clock> start_duration = steady_clock::now();
|
||||
|
||||
std::chrono::time_point<steady_clock> program_load_start = steady_clock::now();
|
||||
load_program();
|
||||
std::chrono::time_point<steady_clock> program_load_end = steady_clock::now();
|
||||
m_timers.program_load_duration += std::chrono::duration_cast<std::chrono::microseconds>(program_load_end - program_load_start).count();
|
||||
|
||||
if (!m_fragment_program.valid)
|
||||
{
|
||||
rsx::thread::end();
|
||||
return;
|
||||
}
|
||||
|
||||
std::chrono::time_point<steady_clock> rtt_duration_start = steady_clock::now();
|
||||
prepare_render_targets(get_current_resource_storage().command_list.Get());
|
||||
|
||||
@@ -355,6 +344,11 @@ void D3D12GSRender::end()
|
||||
std::chrono::time_point<steady_clock> vertex_index_duration_end = steady_clock::now();
|
||||
m_timers.vertex_index_duration += std::chrono::duration_cast<std::chrono::microseconds>(vertex_index_duration_end - vertex_index_duration_start).count();
|
||||
|
||||
std::chrono::time_point<steady_clock> program_load_start = steady_clock::now();
|
||||
load_program();
|
||||
std::chrono::time_point<steady_clock> program_load_end = steady_clock::now();
|
||||
m_timers.program_load_duration += std::chrono::duration_cast<std::chrono::microseconds>(program_load_end - program_load_start).count();
|
||||
|
||||
get_current_resource_storage().command_list->SetGraphicsRootSignature(m_shared_root_signature.Get());
|
||||
get_current_resource_storage().command_list->OMSetStencilRef(rsx::method_registers.stencil_func_ref());
|
||||
|
||||
|
||||
@@ -56,9 +56,6 @@ void D3D12GSRender::load_program()
|
||||
m_vertex_program = get_current_vertex_program();
|
||||
m_fragment_program = get_current_fragment_program(rtt_lookup_func);
|
||||
|
||||
if (!m_fragment_program.valid)
|
||||
return;
|
||||
|
||||
D3D12PipelineProperties prop = {};
|
||||
prop.Topology = get_primitive_topology_type(rsx::method_registers.current_draw_clause.primitive);
|
||||
|
||||
|
||||
@@ -175,9 +175,16 @@ void D3D12GSRender::prepare_render_targets(ID3D12GraphicsCommandList *copycmdlis
|
||||
rsx::method_registers.clear_color_b() / 255.f,
|
||||
rsx::method_registers.clear_color_a() / 255.f,
|
||||
};
|
||||
|
||||
u32 clip_width = rsx::method_registers.surface_clip_width();
|
||||
u32 clip_height = rsx::method_registers.surface_clip_height();
|
||||
|
||||
if (clip_height == 0 || clip_width == 0)
|
||||
return;
|
||||
|
||||
m_rtts.prepare_render_target(copycmdlist,
|
||||
rsx::method_registers.surface_color(), rsx::method_registers.surface_depth_fmt(),
|
||||
rsx::method_registers.surface_clip_width(), rsx::method_registers.surface_clip_height(),
|
||||
clip_width, clip_height,
|
||||
rsx::method_registers.surface_color_target(),
|
||||
get_color_surface_addresses(), get_zeta_surface_address(),
|
||||
m_device.Get(), clear_color, 1.f, 0);
|
||||
|
||||
@@ -116,30 +116,28 @@ struct render_target_traits
|
||||
command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(ds, D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_GENERIC_READ));
|
||||
}
|
||||
|
||||
static
|
||||
void invalidate_rtt_surface_contents(
|
||||
gsl::not_null<ID3D12GraphicsCommandList*>,
|
||||
ID3D12Resource*, ID3D12Resource*, bool)
|
||||
ID3D12Resource*)
|
||||
{}
|
||||
|
||||
static
|
||||
void invalidate_depth_surface_contents(
|
||||
gsl::not_null<ID3D12GraphicsCommandList*>,
|
||||
ID3D12Resource*, ID3D12Resource*, bool)
|
||||
ID3D12Resource*)
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
bool rtt_has_format_width_height(const ComPtr<ID3D12Resource> &rtt, surface_color_format surface_color_format, size_t width, size_t height, bool=false)
|
||||
bool rtt_has_format_width_height(const ComPtr<ID3D12Resource> &rtt, surface_color_format surface_color_format, size_t width, size_t height)
|
||||
{
|
||||
DXGI_FORMAT dxgi_format = get_color_surface_format(surface_color_format);
|
||||
return rtt->GetDesc().Format == dxgi_format && rtt->GetDesc().Width == width && rtt->GetDesc().Height == height;
|
||||
}
|
||||
|
||||
static
|
||||
bool ds_has_format_width_height(const ComPtr<ID3D12Resource> &rtt, surface_depth_format, size_t width, size_t height, bool=false)
|
||||
bool ds_has_format_width_height(const ComPtr<ID3D12Resource> &rtt, surface_depth_format, size_t width, size_t height)
|
||||
{
|
||||
//TODO: Check format
|
||||
return rtt->GetDesc().Width == width && rtt->GetDesc().Height == height;
|
||||
|
||||
+13
-3
@@ -7,11 +7,21 @@
|
||||
|
||||
struct CellGcmControl
|
||||
{
|
||||
atomic_be_t<u32> put;
|
||||
atomic_be_t<u32> get;
|
||||
atomic_be_t<u32> ref;
|
||||
u8 resv[0x40];
|
||||
atomic_be_t<u32> put;
|
||||
atomic_be_t<u32> get;
|
||||
atomic_be_t<u32> ref;
|
||||
be_t<u32> unk[2];
|
||||
be_t<u32> unk1;
|
||||
};
|
||||
|
||||
/*struct CellGcmControl
|
||||
{
|
||||
atomic_be_t<u32> put;
|
||||
atomic_be_t<u32> get;
|
||||
atomic_be_t<u32> ref;
|
||||
};*/
|
||||
|
||||
struct CellGcmConfig
|
||||
{
|
||||
be_t<u32> localAddress;
|
||||
|
||||
@@ -322,15 +322,17 @@ namespace
|
||||
|
||||
void GLGSRender::end()
|
||||
{
|
||||
std::chrono::time_point<steady_clock> program_start = steady_clock::now();
|
||||
//Load program here since it is dependent on vertex state
|
||||
|
||||
if (skip_frame || !framebuffer_status_valid || !load_program())
|
||||
if (skip_frame || !framebuffer_status_valid)
|
||||
{
|
||||
rsx::thread::end();
|
||||
return;
|
||||
}
|
||||
|
||||
std::chrono::time_point<steady_clock> program_start = steady_clock::now();
|
||||
|
||||
//Load program here since it is dependent on vertex state
|
||||
load_program();
|
||||
|
||||
std::chrono::time_point<steady_clock> program_stop = steady_clock::now();
|
||||
m_begin_time += (u32)std::chrono::duration_cast<std::chrono::microseconds>(program_stop - program_start).count();
|
||||
|
||||
@@ -362,80 +364,44 @@ void GLGSRender::end()
|
||||
surface->old_contents = nullptr;
|
||||
};
|
||||
|
||||
//Check if we have any 'recycled' surfaces in memory and if so, clear them
|
||||
std::vector<int> buffers_to_clear;
|
||||
bool clear_all_color = true;
|
||||
bool clear_depth = false;
|
||||
|
||||
for (int index = 0; index < 4; index++)
|
||||
{
|
||||
if (std::get<0>(m_rtts.m_bound_render_targets[index]) != 0)
|
||||
{
|
||||
if (std::get<1>(m_rtts.m_bound_render_targets[index])->cleared())
|
||||
clear_all_color = false;
|
||||
else
|
||||
buffers_to_clear.push_back(index);
|
||||
}
|
||||
}
|
||||
|
||||
gl::render_target *ds = std::get<1>(m_rtts.m_bound_depth_stencil);
|
||||
if (ds && !ds->cleared())
|
||||
{
|
||||
clear_depth = true;
|
||||
}
|
||||
//Temporarily disable pixel tests
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
glClearDepth(1.0);
|
||||
glClearStencil(255);
|
||||
|
||||
//Temporarily disable pixel tests
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
if (clear_depth || buffers_to_clear.size() > 0)
|
||||
{
|
||||
GLenum mask = 0;
|
||||
|
||||
if (clear_depth)
|
||||
if (g_cfg.video.strict_rendering_mode)
|
||||
{
|
||||
glDepthMask(GL_TRUE);
|
||||
glClearDepth(1.0);
|
||||
glClearStencil(255);
|
||||
mask |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
|
||||
//Copy previous data if any
|
||||
if (ds->old_contents != nullptr)
|
||||
copy_rtt_contents(ds);
|
||||
}
|
||||
|
||||
if (clear_all_color)
|
||||
mask |= GL_COLOR_BUFFER_BIT;
|
||||
|
||||
glClear(mask);
|
||||
|
||||
if (buffers_to_clear.size() > 0 && !clear_all_color)
|
||||
{
|
||||
GLfloat colors[] = { 0.f, 0.f, 0.f, 0.f };
|
||||
//It is impossible for the render target to be typa A or B here (clear all would have been flagged)
|
||||
for (auto &i: buffers_to_clear)
|
||||
glClearBufferfv(draw_fbo.id(), i, colors);
|
||||
}
|
||||
|
||||
if (clear_depth)
|
||||
glDepthMask(rsx::method_registers.depth_write_enabled());
|
||||
glDepthMask(rsx::method_registers.depth_write_enabled());
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
|
||||
ds->set_cleared();
|
||||
}
|
||||
|
||||
if (g_cfg.video.strict_rendering_mode)
|
||||
{
|
||||
if (ds->old_contents != nullptr)
|
||||
copy_rtt_contents(ds);
|
||||
|
||||
for (auto &rtt : m_rtts.m_bound_render_targets)
|
||||
{
|
||||
if (std::get<0>(rtt) != 0)
|
||||
{
|
||||
auto surface = std::get<1>(rtt);
|
||||
if (surface->old_contents != nullptr)
|
||||
if (!surface->cleared() && surface->old_contents != nullptr)
|
||||
copy_rtt_contents(surface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
|
||||
std::chrono::time_point<steady_clock> textures_start = steady_clock::now();
|
||||
|
||||
//Setup textures
|
||||
@@ -497,6 +463,7 @@ void GLGSRender::end()
|
||||
}
|
||||
else
|
||||
{
|
||||
//LOG_ERROR(RSX, "No work is needed for this draw call! Muhahahahahahaha");
|
||||
skip_upload = true;
|
||||
}
|
||||
|
||||
@@ -874,10 +841,8 @@ bool GLGSRender::load_program()
|
||||
return std::make_tuple(true, surface->get_native_pitch());
|
||||
};
|
||||
|
||||
RSXFragmentProgram fragment_program = get_current_fragment_program(rtt_lookup_func);
|
||||
if (!fragment_program.valid) return false;
|
||||
|
||||
RSXVertexProgram vertex_program = get_current_vertex_program();
|
||||
RSXFragmentProgram fragment_program = get_current_fragment_program(rtt_lookup_func);
|
||||
|
||||
u32 unnormalized_rtts = 0;
|
||||
|
||||
|
||||
@@ -173,8 +173,6 @@ OPENGL_PROC(PFNGLMULTIDRAWARRAYSPROC, MultiDrawArrays);
|
||||
OPENGL_PROC(PFNGLGETTEXTUREIMAGEEXTPROC, GetTextureImageEXT);
|
||||
OPENGL_PROC(PFNGLGETTEXTUREIMAGEPROC, GetTextureImage);
|
||||
|
||||
OPENGL_PROC(PFNGLCLEARBUFFERFVPROC, ClearBufferfv);
|
||||
|
||||
//Sampler Objects
|
||||
OPENGL_PROC(PFNGLGENSAMPLERSPROC, GenSamplers);
|
||||
OPENGL_PROC(PFNGLDELETESAMPLERSPROC, DeleteSamplers);
|
||||
|
||||
@@ -192,7 +192,6 @@ struct gl_render_target_traits
|
||||
if (old_surface != nullptr && old_surface->get_compatible_internal_format() == internal_fmt)
|
||||
result->old_contents = old_surface;
|
||||
|
||||
result->set_cleared();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -241,25 +240,19 @@ struct gl_render_target_traits
|
||||
static void prepare_ds_for_drawing(void *, gl::render_target*) {}
|
||||
static void prepare_ds_for_sampling(void *, gl::render_target*) {}
|
||||
|
||||
static void invalidate_rtt_surface_contents(void *, gl::render_target *rtt, gl::render_target* /*old*/, bool forced) { if (forced) rtt->set_cleared(false); }
|
||||
static void invalidate_depth_surface_contents(void *, gl::render_target *ds, gl::render_target* /*old*/, bool) { ds->set_cleared(false); }
|
||||
static void invalidate_rtt_surface_contents(void *, gl::render_target*) {}
|
||||
static void invalidate_depth_surface_contents(void *, gl::render_target *ds) { ds->set_cleared(false); }
|
||||
|
||||
static
|
||||
bool rtt_has_format_width_height(const std::unique_ptr<gl::render_target> &rtt, rsx::surface_color_format format, size_t width, size_t height, bool check_refs=false)
|
||||
bool rtt_has_format_width_height(const std::unique_ptr<gl::render_target> &rtt, rsx::surface_color_format format, size_t width, size_t height)
|
||||
{
|
||||
if (check_refs) //TODO
|
||||
return false;
|
||||
|
||||
auto internal_fmt = rsx::internals::sized_internal_format(format);
|
||||
return rtt->get_compatible_internal_format() == internal_fmt && rtt->width() == width && rtt->height() == height;
|
||||
}
|
||||
|
||||
static
|
||||
bool ds_has_format_width_height(const std::unique_ptr<gl::render_target> &rtt, rsx::surface_depth_format, size_t width, size_t height, bool check_refs=false)
|
||||
bool ds_has_format_width_height(const std::unique_ptr<gl::render_target> &rtt, rsx::surface_depth_format, size_t width, size_t height)
|
||||
{
|
||||
if (check_refs) //TODO
|
||||
return false;
|
||||
|
||||
// TODO: check format
|
||||
return rtt->width() == width && rtt->height() == height;
|
||||
}
|
||||
|
||||
@@ -239,8 +239,6 @@ struct RSXFragmentProgram
|
||||
u8 textures_alpha_kill[16];
|
||||
u32 textures_zfunc[16];
|
||||
|
||||
bool valid;
|
||||
|
||||
rsx::texture_dimension_extended get_texture_dimension(u8 id) const
|
||||
{
|
||||
return (rsx::texture_dimension_extended)((texture_dimensions >> (id * 2)) & 0x3);
|
||||
@@ -265,7 +263,6 @@ struct RSXFragmentProgram
|
||||
, ctrl(0)
|
||||
, unnormalized_coords(0)
|
||||
, texture_dimensions(0)
|
||||
, valid(false)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
+41
-28
@@ -5,6 +5,7 @@
|
||||
#include "RSXThread.h"
|
||||
|
||||
#include "Emu/Cell/PPUCallback.h"
|
||||
#include "Emu/Cell/lv2/sys_rsx.h"
|
||||
|
||||
#include "Common/BufferUtils.h"
|
||||
#include "rsx_methods.h"
|
||||
@@ -57,27 +58,43 @@ namespace rsx
|
||||
//}
|
||||
}
|
||||
|
||||
case CELL_GCM_CONTEXT_DMA_TO_MEMORY_GET_REPORT:
|
||||
return 0x100000 + offset; // TODO: Properly implement
|
||||
case CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_LOCAL:
|
||||
return 0x40301400 + offset; // not sure if this should be 0x40300000 or offset to the actual reports, lets try reports for now
|
||||
//return 0x100000 + offset; // TODO: Properly implement
|
||||
|
||||
case CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_MAIN:
|
||||
return 0x800 + offset; // TODO: Properly implement
|
||||
{
|
||||
if (u32 result = RSXIOMem.RealAddr(0x0e000000 + offset))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
fmt::throw_exception("GetAddress(offset=0x%x, location=0x%x): RSXIO memory not mapped" HERE, offset, location);
|
||||
|
||||
//if (fxm::get<GSRender>()->strict_ordering[offset >> 20])
|
||||
//{
|
||||
// _mm_mfence(); // probably doesn't have any effect on current implementation
|
||||
//}
|
||||
}
|
||||
|
||||
case CELL_GCM_CONTEXT_DMA_TO_MEMORY_GET_NOTIFY0:
|
||||
return 0x40 + offset; // TODO: Properly implement
|
||||
fmt::throw_exception("Unimplemented CELL_GCM_CONTEXT_DMA_TO_MEMORY_GET_NOTIFY0 (offset=0x%x, location=0x%x)" HERE, offset, location);
|
||||
|
||||
case CELL_GCM_CONTEXT_DMA_NOTIFY_MAIN_0:
|
||||
fmt::throw_exception("Unimplemented CELL_GCM_CONTEXT_DMA_NOTIFY_MAIN_0 (offset=0x%x, location=0x%x)" HERE, offset, location);
|
||||
|
||||
case CELL_GCM_CONTEXT_DMA_SEMAPHORE_RW:
|
||||
case CELL_GCM_CONTEXT_DMA_SEMAPHORE_R:
|
||||
return 0x100 + offset; // TODO: Properly implement
|
||||
return 0x40300000 + offset; // this offset also doesnt seem like its right, but it works for now so w/e
|
||||
//return 0x100 + offset; // TODO: Properly implement
|
||||
|
||||
case CELL_GCM_CONTEXT_DMA_DEVICE_RW:
|
||||
fmt::throw_exception("Unimplemented CELL_GCM_CONTEXT_DMA_DEVICE_RW (offset=0x%x, location=0x%x)" HERE, offset, location);
|
||||
return 0x40000000 + offset;
|
||||
//fmt::throw_exception("Unimplemented CELL_GCM_CONTEXT_DMA_DEVICE_RW (offset=0x%x, location=0x%x)" HERE, offset, location);
|
||||
|
||||
case CELL_GCM_CONTEXT_DMA_DEVICE_R:
|
||||
fmt::throw_exception("Unimplemented CELL_GCM_CONTEXT_DMA_DEVICE_R (offset=0x%x, location=0x%x)" HERE, offset, location);
|
||||
return 0x40000000 + offset;
|
||||
//fmt::throw_exception("Unimplemented CELL_GCM_CONTEXT_DMA_DEVICE_R (offset=0x%x, location=0x%x)" HERE, offset, location);
|
||||
|
||||
default:
|
||||
fmt::throw_exception("Invalid location (offset=0x%x, location=0x%x)" HERE, offset, location);
|
||||
@@ -386,7 +403,7 @@ namespace rsx
|
||||
if (get_system_time() - start_time > vblank_count * 1000000 / 60)
|
||||
{
|
||||
vblank_count++;
|
||||
|
||||
sys_rsx_context_attribute(0x55555555, 0xFED, 1, 0, 0, 0);
|
||||
if (vblank_handler)
|
||||
{
|
||||
intr_thread->cmd_list
|
||||
@@ -401,6 +418,8 @@ namespace rsx
|
||||
|
||||
continue;
|
||||
}
|
||||
while (Emu.IsPaused())
|
||||
std::this_thread::sleep_for(10ms);
|
||||
|
||||
std::this_thread::sleep_for(1ms); // hack
|
||||
}
|
||||
@@ -500,7 +519,7 @@ namespace rsx
|
||||
u32 reg = ((cmd & RSX_METHOD_NON_INCREMENT_CMD_MASK) == RSX_METHOD_NON_INCREMENT_CMD) ? first_cmd : first_cmd + i;
|
||||
u32 value = args[i];
|
||||
|
||||
//LOG_NOTICE(RSX, "%s(0x%x) = 0x%x", get_method_name(reg).c_str(), reg, value);
|
||||
//LOG_WARNING(RSX, "%s(0x%x) = 0x%x", get_method_name(reg).c_str(), reg, value);
|
||||
|
||||
method_registers.decode(reg, value);
|
||||
|
||||
@@ -974,17 +993,9 @@ namespace rsx
|
||||
RSXFragmentProgram thread::get_current_fragment_program(std::function<std::tuple<bool, u16>(u32, fragment_texture&, bool)> get_surface_info) const
|
||||
{
|
||||
RSXFragmentProgram result = {};
|
||||
|
||||
const u32 shader_program = rsx::method_registers.shader_program_address();
|
||||
if (shader_program == 0)
|
||||
return result;
|
||||
|
||||
const u32 program_location = (shader_program & 0x3) - 1;
|
||||
const u32 program_offset = (shader_program & ~0x3);
|
||||
|
||||
result.offset = program_offset;
|
||||
result.addr = vm::base(rsx::get_address(program_offset, program_location));
|
||||
result.valid = true;
|
||||
u32 shader_program = rsx::method_registers.shader_program_address();
|
||||
result.offset = shader_program & ~0x3;
|
||||
result.addr = vm::base(rsx::get_address(result.offset, (shader_program & 0x3) - 1));
|
||||
result.ctrl = rsx::method_registers.shader_control();
|
||||
result.unnormalized_coords = 0;
|
||||
result.front_back_color_enabled = !rsx::method_registers.two_side_light_en();
|
||||
@@ -1182,26 +1193,26 @@ namespace rsx
|
||||
if (packet.post_upload_func)
|
||||
packet.post_upload_func(packet.dst_span.data(), packet.type, (u8)packet.vector_width, task.vertex_count);
|
||||
|
||||
_mm_sfence();
|
||||
task.remaining_packets--;
|
||||
current_job += step;
|
||||
_mm_sfence();
|
||||
}
|
||||
|
||||
_mm_mfence();
|
||||
|
||||
while (task.remaining_packets > 0 && !Emu.IsStopped())
|
||||
{
|
||||
std::this_thread::yield();
|
||||
_mm_lfence();
|
||||
std::this_thread::sleep_for(0us);
|
||||
}
|
||||
|
||||
task.ready_threads++;
|
||||
_mm_sfence();
|
||||
task.ready_threads++;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::this_thread::yield();
|
||||
}
|
||||
std::this_thread::sleep_for(0us);
|
||||
//thread_ctrl::wait();
|
||||
//busy_wait();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1209,7 +1220,8 @@ namespace rsx
|
||||
|
||||
while (m_vertex_streaming_task.ready_threads != 0 && !Emu.IsStopped())
|
||||
{
|
||||
_mm_pause();
|
||||
_mm_lfence();
|
||||
busy_wait();
|
||||
}
|
||||
|
||||
m_vertex_streaming_task.vertex_count = vertex_count;
|
||||
@@ -1221,7 +1233,8 @@ namespace rsx
|
||||
{
|
||||
while (m_vertex_streaming_task.remaining_packets > 0 && !Emu.IsStopped())
|
||||
{
|
||||
_mm_pause();
|
||||
_mm_lfence();
|
||||
busy_wait();
|
||||
}
|
||||
|
||||
m_vertex_streaming_task.packets.resize(0);
|
||||
|
||||
@@ -142,6 +142,8 @@ namespace rsx
|
||||
u32 gcm_current_buffer;
|
||||
u32 ctxt_addr;
|
||||
u32 label_addr;
|
||||
u32 nv406e_semaphore_addr;
|
||||
u32 nv4097_semaphore_index;
|
||||
|
||||
u32 local_mem_addr, main_mem_addr;
|
||||
bool strict_ordering[0x1000];
|
||||
|
||||
+64
-227
@@ -677,7 +677,6 @@ VKGSRender::~VKGSRender()
|
||||
m_buffer_view_to_clean.clear();
|
||||
m_sampler_to_clean.clear();
|
||||
m_framebuffer_to_clean.clear();
|
||||
m_draw_fbo.reset();
|
||||
|
||||
//Render passes
|
||||
for (auto &render_pass : m_render_passes)
|
||||
@@ -875,17 +874,17 @@ void VKGSRender::begin_render_pass()
|
||||
size_t idx = vk::get_render_pass_location(
|
||||
vk::get_compatible_surface_format(rsx::method_registers.surface_color()).first,
|
||||
vk::get_compatible_depth_surface_format(m_optimal_tiling_supported_formats, rsx::method_registers.surface_depth_fmt()),
|
||||
(u8)m_draw_buffers_count);
|
||||
(u8)vk::get_draw_buffers(rsx::method_registers.surface_color_target()).size());
|
||||
VkRenderPass current_render_pass = m_render_passes[idx];
|
||||
|
||||
VkRenderPassBeginInfo rp_begin = {};
|
||||
rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
rp_begin.renderPass = current_render_pass;
|
||||
rp_begin.framebuffer = m_draw_fbo->value;
|
||||
rp_begin.framebuffer = m_framebuffer_to_clean.back()->value;
|
||||
rp_begin.renderArea.offset.x = 0;
|
||||
rp_begin.renderArea.offset.y = 0;
|
||||
rp_begin.renderArea.extent.width = m_draw_fbo->width();
|
||||
rp_begin.renderArea.extent.height = m_draw_fbo->height();
|
||||
rp_begin.renderArea.extent.width = m_framebuffer_to_clean.back()->width();
|
||||
rp_begin.renderArea.extent.height = m_framebuffer_to_clean.back()->height();
|
||||
|
||||
vkCmdBeginRenderPass(*m_current_command_buffer, &rp_begin, VK_SUBPASS_CONTENTS_INLINE);
|
||||
render_pass_open = true;
|
||||
@@ -942,15 +941,10 @@ void VKGSRender::end()
|
||||
}
|
||||
|
||||
//Load program here since it is dependent on vertex state
|
||||
if (!load_program(is_instanced))
|
||||
{
|
||||
LOG_ERROR(RSX, "No valid program bound to pipeline. Skipping draw");
|
||||
rsx::thread::end();
|
||||
return;
|
||||
}
|
||||
load_program(is_instanced);
|
||||
|
||||
std::chrono::time_point<steady_clock> program_stop = steady_clock::now();
|
||||
//m_setup_time += std::chrono::duration_cast<std::chrono::microseconds>(program_stop - program_start).count();
|
||||
m_setup_time += (u32)std::chrono::duration_cast<std::chrono::microseconds>(program_stop - program_start).count();
|
||||
|
||||
if (is_instanced)
|
||||
{
|
||||
@@ -1005,14 +999,14 @@ void VKGSRender::end()
|
||||
{
|
||||
auto surface = std::get<1>(rtt);
|
||||
|
||||
if (surface->old_contents != nullptr)
|
||||
if (surface->dirty && surface->old_contents != nullptr)
|
||||
copy_rtt_contents(surface);
|
||||
}
|
||||
}
|
||||
|
||||
if (auto ds = std::get<1>(m_rtts.m_bound_depth_stencil))
|
||||
{
|
||||
if (ds->old_contents != nullptr)
|
||||
if (ds->dirty && ds->old_contents != nullptr)
|
||||
copy_rtt_contents(ds);
|
||||
}
|
||||
}
|
||||
@@ -1120,11 +1114,6 @@ void VKGSRender::end()
|
||||
vkCmdBindPipeline(*m_current_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_program->pipeline);
|
||||
vkCmdBindDescriptorSets(*m_current_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &descriptor_sets, 0, nullptr);
|
||||
|
||||
//Clear any 'dirty' surfaces - possible is a recycled cache surface is used
|
||||
std::vector<VkClearAttachment> buffers_to_clear;
|
||||
buffers_to_clear.reserve(4);
|
||||
const auto targets = vk::get_draw_buffers(rsx::method_registers.surface_color_target());
|
||||
|
||||
if (auto ds = std::get<1>(m_rtts.m_bound_depth_stencil))
|
||||
{
|
||||
if (ds->dirty)
|
||||
@@ -1134,41 +1123,28 @@ void VKGSRender::end()
|
||||
depth_clear_value.depthStencil.depth = 1.f;
|
||||
depth_clear_value.depthStencil.stencil = 255;
|
||||
|
||||
VkClearRect clear_rect = { 0, 0, m_framebuffer_to_clean.back()->width(), m_framebuffer_to_clean.back()->height(), 0, 1 };
|
||||
VkClearAttachment clear_desc = { ds->attachment_aspect_flag, 0, depth_clear_value };
|
||||
buffers_to_clear.push_back(clear_desc);
|
||||
vkCmdClearAttachments(*m_current_command_buffer, 1, &clear_desc, 1, &clear_rect);
|
||||
|
||||
ds->dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
for (int index = 0; index < targets.size(); ++index)
|
||||
{
|
||||
if (std::get<0>(m_rtts.m_bound_render_targets[index]) != 0 && std::get<1>(m_rtts.m_bound_render_targets[index])->dirty)
|
||||
{
|
||||
const u32 real_index = (index == 1 && targets.size() == 1) ? 0 : static_cast<u32>(index);
|
||||
buffers_to_clear.push_back({ VK_IMAGE_ASPECT_COLOR_BIT, real_index, {} });
|
||||
|
||||
std::get<1>(m_rtts.m_bound_render_targets[index])->dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (buffers_to_clear.size() > 0)
|
||||
{
|
||||
VkClearRect clear_rect = { 0, 0, m_draw_fbo->width(), m_draw_fbo->height(), 0, 1 };
|
||||
vkCmdClearAttachments(*m_current_command_buffer, static_cast<u32>(buffers_to_clear.size()), buffers_to_clear.data(), 1, &clear_rect);
|
||||
}
|
||||
|
||||
std::optional<std::tuple<VkDeviceSize, VkIndexType> > index_info = std::get<2>(upload_info);
|
||||
|
||||
if (m_attrib_ring_info.mapped)
|
||||
{
|
||||
wait_for_vertex_upload_task();
|
||||
m_attrib_ring_info.unmap();
|
||||
}
|
||||
|
||||
std::chrono::time_point<steady_clock> vertex_end = steady_clock::now();
|
||||
m_vertex_upload_time += std::chrono::duration_cast<std::chrono::microseconds>(vertex_end - textures_end).count();
|
||||
|
||||
if (!index_info)
|
||||
{
|
||||
const auto vertex_count = std::get<1>(upload_info);
|
||||
vkCmdDraw(*m_current_command_buffer, vertex_count, 1, 0, 0);
|
||||
|
||||
m_last_vertex_count = vertex_count;
|
||||
vkCmdDraw(*m_current_command_buffer, std::get<1>(upload_info), 1, 0, 0);
|
||||
m_last_draw_indexed = false;
|
||||
}
|
||||
else
|
||||
@@ -1199,22 +1175,6 @@ void VKGSRender::end()
|
||||
copy_render_targets_to_dma_location();
|
||||
m_draw_calls++;
|
||||
|
||||
if (g_cfg.video.overlay)
|
||||
{
|
||||
if (m_last_vertex_count < 1024)
|
||||
m_uploads_small++;
|
||||
else if (m_last_vertex_count < 2048)
|
||||
m_uploads_1k++;
|
||||
else if (m_last_vertex_count < 4096)
|
||||
m_uploads_2k++;
|
||||
else if (m_last_vertex_count < 8192)
|
||||
m_uploads_4k++;
|
||||
else if (m_last_vertex_count < 16384)
|
||||
m_uploads_8k++;
|
||||
else
|
||||
m_uploads_16k++;
|
||||
}
|
||||
|
||||
rsx::thread::end();
|
||||
}
|
||||
|
||||
@@ -1291,6 +1251,8 @@ void VKGSRender::clear_surface(u32 mask)
|
||||
u32 depth_stencil_mask = 0;
|
||||
|
||||
std::vector<VkClearAttachment> clear_descriptors;
|
||||
std::vector<VkClearRect> clear_regions;
|
||||
|
||||
VkClearValue depth_stencil_clear_values, color_clear_values;
|
||||
|
||||
u16 scissor_x = rsx::method_registers.scissor_origin_x();
|
||||
@@ -1298,8 +1260,8 @@ void VKGSRender::clear_surface(u32 mask)
|
||||
u16 scissor_y = rsx::method_registers.scissor_origin_y();
|
||||
u16 scissor_h = rsx::method_registers.scissor_height();
|
||||
|
||||
const u32 fb_width = m_draw_fbo->width();
|
||||
const u32 fb_height = m_draw_fbo->height();
|
||||
const u32 fb_width = m_framebuffer_to_clean.back()->width();
|
||||
const u32 fb_height = m_framebuffer_to_clean.back()->height();
|
||||
|
||||
//clip region
|
||||
std::tie(scissor_x, scissor_y, scissor_w, scissor_h) = rsx::clip_region<u16>(fb_width, fb_height, scissor_x, scissor_y, scissor_w, scissor_h, true);
|
||||
@@ -1347,8 +1309,8 @@ void VKGSRender::clear_surface(u32 mask)
|
||||
|
||||
for (int index = 0; index < targets.size(); ++index)
|
||||
{
|
||||
const u32 real_index = (index == 1 && targets.size() == 1) ? 0 : static_cast<u32>(index);
|
||||
clear_descriptors.push_back({ VK_IMAGE_ASPECT_COLOR_BIT, real_index, color_clear_values });
|
||||
clear_descriptors.push_back({ VK_IMAGE_ASPECT_COLOR_BIT, (uint32_t)index, color_clear_values });
|
||||
clear_regions.push_back(region);
|
||||
}
|
||||
|
||||
for (auto &rtt : m_rtts.m_bound_render_targets)
|
||||
@@ -1362,10 +1324,13 @@ void VKGSRender::clear_surface(u32 mask)
|
||||
}
|
||||
|
||||
if (mask & 0x3)
|
||||
{
|
||||
clear_descriptors.push_back({ (VkImageAspectFlags)depth_stencil_mask, 0, depth_stencil_clear_values });
|
||||
clear_regions.push_back(region);
|
||||
}
|
||||
|
||||
begin_render_pass();
|
||||
vkCmdClearAttachments(*m_current_command_buffer, (u32)clear_descriptors.size(), clear_descriptors.data(), 1, ®ion);
|
||||
vkCmdClearAttachments(*m_current_command_buffer, (u32)clear_descriptors.size(), clear_descriptors.data(), (u32)clear_regions.size(), clear_regions.data());
|
||||
|
||||
if (mask & 0x3)
|
||||
{
|
||||
@@ -1427,12 +1392,6 @@ void VKGSRender::copy_render_targets_to_dma_location()
|
||||
|
||||
void VKGSRender::flush_command_queue(bool hard_sync)
|
||||
{
|
||||
if (m_attrib_ring_info.mapped)
|
||||
{
|
||||
wait_for_vertex_upload_task();
|
||||
m_attrib_ring_info.unmap();
|
||||
}
|
||||
|
||||
close_render_pass();
|
||||
close_and_submit_command_buffer({}, m_current_command_buffer->submit_fence);
|
||||
|
||||
@@ -1513,7 +1472,7 @@ void VKGSRender::process_swap_request()
|
||||
//Feed back damaged resources to the main texture cache for management...
|
||||
//m_texture_cache.merge_dirty_textures(m_rtts.invalidated_resources);
|
||||
|
||||
m_rtts.free_invalidated();
|
||||
m_rtts.invalidated_resources.clear();
|
||||
m_texture_cache.flush();
|
||||
|
||||
if (g_cfg.video.invalidate_surface_cache_every_frame)
|
||||
@@ -1521,13 +1480,7 @@ void VKGSRender::process_swap_request()
|
||||
|
||||
m_buffer_view_to_clean.clear();
|
||||
m_sampler_to_clean.clear();
|
||||
|
||||
m_framebuffer_to_clean.remove_if([](std::unique_ptr<vk::framebuffer_holder>& fbo)
|
||||
{
|
||||
if (fbo->deref_count >= 2) return true;
|
||||
fbo->deref_count++;
|
||||
return false;
|
||||
});
|
||||
m_framebuffer_to_clean.clear();
|
||||
|
||||
if (g_cfg.video.overlay)
|
||||
{
|
||||
@@ -1592,10 +1545,8 @@ bool VKGSRender::load_program(bool fast_update)
|
||||
return std::make_tuple(true, surface->native_pitch);
|
||||
};
|
||||
|
||||
fragment_program = get_current_fragment_program(rtt_lookup_func);
|
||||
if (!fragment_program.valid) return false;
|
||||
|
||||
vertex_program = get_current_vertex_program();
|
||||
fragment_program = get_current_fragment_program(rtt_lookup_func);
|
||||
|
||||
vk::pipeline_props properties = {};
|
||||
|
||||
@@ -1740,7 +1691,7 @@ bool VKGSRender::load_program(bool fast_update)
|
||||
size_t idx = vk::get_render_pass_location(
|
||||
vk::get_compatible_surface_format(rsx::method_registers.surface_color()).first,
|
||||
vk::get_compatible_depth_surface_format(m_optimal_tiling_supported_formats, rsx::method_registers.surface_depth_fmt()),
|
||||
(u8)m_draw_buffers_count);
|
||||
(u8)vk::get_draw_buffers(rsx::method_registers.surface_color_target()).size());
|
||||
|
||||
properties.render_pass = m_render_passes[idx];
|
||||
|
||||
@@ -1902,7 +1853,6 @@ void VKGSRender::prepare_rtts()
|
||||
{
|
||||
LOG_ERROR(RSX, "Invalid framebuffer setup, w=%d, h=%d", clip_width, clip_height);
|
||||
framebuffer_status_valid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
framebuffer_status_valid = true;
|
||||
@@ -1913,35 +1863,6 @@ void VKGSRender::prepare_rtts()
|
||||
const u32 surface_pitchs[] = { rsx::method_registers.surface_a_pitch(), rsx::method_registers.surface_b_pitch(),
|
||||
rsx::method_registers.surface_c_pitch(), rsx::method_registers.surface_d_pitch() };
|
||||
|
||||
if (m_draw_fbo)
|
||||
{
|
||||
const u32 fb_width = m_draw_fbo->width();
|
||||
const u32 fb_height = m_draw_fbo->height();
|
||||
|
||||
bool really_changed = false;
|
||||
|
||||
if (fb_width == clip_width && fb_height == clip_height)
|
||||
{
|
||||
for (u8 i = 0; i < rsx::limits::color_buffers_count; ++i)
|
||||
{
|
||||
if (m_surface_info[i].address != surface_addresses[i])
|
||||
{
|
||||
really_changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!really_changed)
|
||||
{
|
||||
if (zeta_address == m_depth_surface_info.address)
|
||||
{
|
||||
//Nothing has changed, we're still using the same framebuffer
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_rtts.prepare_render_target(&*m_current_command_buffer,
|
||||
rsx::method_registers.surface_color(), rsx::method_registers.surface_depth_fmt(),
|
||||
clip_width, clip_height,
|
||||
@@ -1965,16 +1886,20 @@ void VKGSRender::prepare_rtts()
|
||||
|
||||
//Bind created rtts as current fbo...
|
||||
std::vector<u8> draw_buffers = vk::get_draw_buffers(rsx::method_registers.surface_color_target());
|
||||
|
||||
//Search old framebuffers for this same configuration
|
||||
bool framebuffer_found = false;
|
||||
|
||||
std::vector<vk::image*> bound_images;
|
||||
bound_images.reserve(5);
|
||||
std::vector<std::unique_ptr<vk::image_view>> fbo_images;
|
||||
|
||||
for (u8 index : draw_buffers)
|
||||
{
|
||||
bound_images.push_back(std::get<1>(m_rtts.m_bound_render_targets[index]));
|
||||
vk::image *raw = std::get<1>(m_rtts.m_bound_render_targets[index]);
|
||||
|
||||
VkImageSubresourceRange subres = {};
|
||||
subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
subres.baseArrayLayer = 0;
|
||||
subres.baseMipLevel = 0;
|
||||
subres.layerCount = 1;
|
||||
subres.levelCount = 1;
|
||||
|
||||
fbo_images.push_back(std::make_unique<vk::image_view>(*m_device, raw->value, VK_IMAGE_VIEW_TYPE_2D, raw->info.format, vk::default_component_map(), subres));
|
||||
|
||||
m_surface_info[index].address = surface_addresses[index];
|
||||
m_surface_info[index].pitch = surface_pitchs[index];
|
||||
@@ -1987,9 +1912,20 @@ void VKGSRender::prepare_rtts()
|
||||
}
|
||||
}
|
||||
|
||||
if (std::get<0>(m_rtts.m_bound_depth_stencil) != 0)
|
||||
m_draw_buffers_count = static_cast<u32>(fbo_images.size());
|
||||
|
||||
if (std::get<1>(m_rtts.m_bound_depth_stencil) != nullptr)
|
||||
{
|
||||
bound_images.push_back(std::get<1>(m_rtts.m_bound_depth_stencil));
|
||||
vk::image *raw = (std::get<1>(m_rtts.m_bound_depth_stencil));
|
||||
|
||||
VkImageSubresourceRange subres = {};
|
||||
subres.aspectMask = (rsx::method_registers.surface_depth_fmt() == rsx::surface_depth_format::z24s8) ? (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) : VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
subres.baseArrayLayer = 0;
|
||||
subres.baseMipLevel = 0;
|
||||
subres.layerCount = 1;
|
||||
subres.levelCount = 1;
|
||||
|
||||
fbo_images.push_back(std::make_unique<vk::image_view>(*m_device, raw->value, VK_IMAGE_VIEW_TYPE_2D, raw->info.format, vk::default_component_map(), subres));
|
||||
|
||||
m_depth_surface_info.address = zeta_address;
|
||||
m_depth_surface_info.pitch = rsx::method_registers.surface_z_pitch();
|
||||
@@ -1998,8 +1934,6 @@ void VKGSRender::prepare_rtts()
|
||||
m_depth_surface_info.pitch = 0;
|
||||
}
|
||||
|
||||
m_draw_buffers_count = static_cast<u32>(draw_buffers.size());
|
||||
|
||||
if (g_cfg.video.write_color_buffers)
|
||||
{
|
||||
for (u8 index : draw_buffers)
|
||||
@@ -2008,7 +1942,7 @@ void VKGSRender::prepare_rtts()
|
||||
const u32 range = m_surface_info[index].pitch * m_surface_info[index].height;
|
||||
|
||||
m_texture_cache.lock_memory_region(std::get<1>(m_rtts.m_bound_render_targets[index]), m_surface_info[index].address, range,
|
||||
m_surface_info[index].width, m_surface_info[index].height);
|
||||
m_surface_info[index].width, m_surface_info[index].height);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2025,59 +1959,10 @@ void VKGSRender::prepare_rtts()
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &fbo : m_framebuffer_to_clean)
|
||||
{
|
||||
if (fbo->matches(bound_images, clip_width, clip_height))
|
||||
{
|
||||
m_draw_fbo.swap(fbo);
|
||||
m_draw_fbo->reset_refs();
|
||||
framebuffer_found = true;
|
||||
//LOG_ERROR(RSX, "Matching framebuffer exists, using that instead");
|
||||
break;
|
||||
}
|
||||
}
|
||||
size_t idx = vk::get_render_pass_location(vk::get_compatible_surface_format(rsx::method_registers.surface_color()).first, vk::get_compatible_depth_surface_format(m_optimal_tiling_supported_formats, rsx::method_registers.surface_depth_fmt()), (u8)draw_buffers.size());
|
||||
VkRenderPass current_render_pass = m_render_passes[idx];
|
||||
|
||||
if (!framebuffer_found)
|
||||
{
|
||||
std::vector<std::unique_ptr<vk::image_view>> fbo_images;
|
||||
fbo_images.reserve(5);
|
||||
|
||||
for (u8 index : draw_buffers)
|
||||
{
|
||||
vk::image *raw = std::get<1>(m_rtts.m_bound_render_targets[index]);
|
||||
|
||||
VkImageSubresourceRange subres = {};
|
||||
subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
subres.baseArrayLayer = 0;
|
||||
subres.baseMipLevel = 0;
|
||||
subres.layerCount = 1;
|
||||
subres.levelCount = 1;
|
||||
|
||||
fbo_images.push_back(std::make_unique<vk::image_view>(*m_device, raw->value, VK_IMAGE_VIEW_TYPE_2D, raw->info.format, vk::default_component_map(), subres));
|
||||
}
|
||||
|
||||
if (std::get<1>(m_rtts.m_bound_depth_stencil) != nullptr)
|
||||
{
|
||||
vk::image *raw = (std::get<1>(m_rtts.m_bound_depth_stencil));
|
||||
|
||||
VkImageSubresourceRange subres = {};
|
||||
subres.aspectMask = (rsx::method_registers.surface_depth_fmt() == rsx::surface_depth_format::z24s8) ? (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) : VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
subres.baseArrayLayer = 0;
|
||||
subres.baseMipLevel = 0;
|
||||
subres.layerCount = 1;
|
||||
subres.levelCount = 1;
|
||||
|
||||
fbo_images.push_back(std::make_unique<vk::image_view>(*m_device, raw->value, VK_IMAGE_VIEW_TYPE_2D, raw->info.format, vk::default_component_map(), subres));
|
||||
}
|
||||
|
||||
size_t idx = vk::get_render_pass_location(vk::get_compatible_surface_format(rsx::method_registers.surface_color()).first, vk::get_compatible_depth_surface_format(m_optimal_tiling_supported_formats, rsx::method_registers.surface_depth_fmt()), (u8)draw_buffers.size());
|
||||
VkRenderPass current_render_pass = m_render_passes[idx];
|
||||
|
||||
if (m_draw_fbo)
|
||||
m_framebuffer_to_clean.push_back(std::move(m_draw_fbo));
|
||||
|
||||
m_draw_fbo.reset(new vk::framebuffer_holder(*m_device, current_render_pass, clip_width, clip_height, std::move(fbo_images)));
|
||||
}
|
||||
m_framebuffer_to_clean.push_back(std::make_unique<vk::framebuffer>(*m_device, current_render_pass, clip_width, clip_height, std::move(fbo_images)));
|
||||
}
|
||||
|
||||
|
||||
@@ -2096,13 +1981,6 @@ void VKGSRender::flip(int buffer)
|
||||
m_setup_time = 0;
|
||||
m_vertex_upload_time = 0;
|
||||
m_textures_upload_time = 0;
|
||||
|
||||
m_uploads_small = 0;
|
||||
m_uploads_1k = 0;
|
||||
m_uploads_2k = 0;
|
||||
m_uploads_4k = 0;
|
||||
m_uploads_8k = 0;
|
||||
m_uploads_16k = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -2182,7 +2060,7 @@ void VKGSRender::flip(int buffer)
|
||||
vk::change_image_layout(*m_current_command_buffer, m_swap_chain->get_swap_chain_image(m_current_present_image), VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, range);
|
||||
}
|
||||
|
||||
std::unique_ptr<vk::framebuffer_holder> direct_fbo;
|
||||
std::unique_ptr<vk::framebuffer> direct_fbo;
|
||||
std::vector<std::unique_ptr<vk::image_view>> swap_image_view;
|
||||
if (g_cfg.video.overlay)
|
||||
{
|
||||
@@ -2204,24 +2082,9 @@ void VKGSRender::flip(int buffer)
|
||||
size_t idx = vk::get_render_pass_location(m_swap_chain->get_surface_format(), VK_FORMAT_UNDEFINED, 1);
|
||||
VkRenderPass single_target_pass = m_render_passes[idx];
|
||||
|
||||
for (auto It = m_framebuffer_to_clean.begin(); It != m_framebuffer_to_clean.end(); It++)
|
||||
{
|
||||
auto &fbo = *It;
|
||||
if (fbo->attachments[0]->info.image == target_image)
|
||||
{
|
||||
direct_fbo.swap(fbo);
|
||||
direct_fbo->reset_refs();
|
||||
m_framebuffer_to_clean.erase(It);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!direct_fbo)
|
||||
{
|
||||
swap_image_view.push_back(std::make_unique<vk::image_view>(*m_device, target_image, VK_IMAGE_VIEW_TYPE_2D, m_swap_chain->get_surface_format(), vk::default_component_map(), subres));
|
||||
direct_fbo.reset(new vk::framebuffer_holder(*m_device, single_target_pass, m_client_width, m_client_height, std::move(swap_image_view)));
|
||||
}
|
||||
|
||||
swap_image_view.push_back(std::make_unique<vk::image_view>(*m_device, target_image, VK_IMAGE_VIEW_TYPE_2D, m_swap_chain->get_surface_format(), vk::default_component_map(), subres));
|
||||
direct_fbo.reset(new vk::framebuffer(*m_device, single_target_pass, m_client_width, m_client_height, std::move(swap_image_view)));
|
||||
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 0, direct_fbo->width(), direct_fbo->height(), "draw calls: " + std::to_string(m_draw_calls) + ", instanced repeats: " + std::to_string(m_instanced_draws));
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 18, direct_fbo->width(), direct_fbo->height(), "draw call setup: " + std::to_string(m_setup_time) + "us");
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 36, direct_fbo->width(), direct_fbo->height(), "vertex upload time: " + std::to_string(m_vertex_upload_time) + "us");
|
||||
@@ -2229,29 +2092,10 @@ void VKGSRender::flip(int buffer)
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 72, direct_fbo->width(), direct_fbo->height(), "draw call execution: " + std::to_string(m_draw_time) + "us");
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 90, direct_fbo->width(), direct_fbo->height(), "submit and flip: " + std::to_string(m_flip_time) + "us");
|
||||
|
||||
//Vertex upload statistics
|
||||
u32 _small, _1k, _2k, _4k, _8k, _16k;
|
||||
if (m_draw_calls > 0)
|
||||
{
|
||||
_small = m_uploads_small * 100 / m_draw_calls;
|
||||
_1k = m_uploads_1k * 100 / m_draw_calls;
|
||||
_2k = m_uploads_2k * 100 / m_draw_calls;
|
||||
_4k = m_uploads_4k * 100 / m_draw_calls;
|
||||
_8k = m_uploads_8k * 100 / m_draw_calls;
|
||||
_16k = m_uploads_16k * 100 / m_draw_calls;
|
||||
}
|
||||
else
|
||||
{
|
||||
_small = _1k = _2k = _4k = _8k = _16k = 0;
|
||||
}
|
||||
|
||||
std::string message = fmt::format("Vertex sizes: < 1k: %d%%, 1k+: %d%%, 2k+: %d%%, 4k+: %d%%, 8k+: %d%%, 16k+: %d%%", _small, _1k, _2k, _4k, _8k, _16k);
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 108, direct_fbo->width(), direct_fbo->height(), message);
|
||||
|
||||
vk::change_image_layout(*m_current_command_buffer, target_image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, subres);
|
||||
m_framebuffer_to_clean.push_back(std::move(direct_fbo));
|
||||
}
|
||||
|
||||
m_framebuffer_to_clean.push_back(std::move(direct_fbo));
|
||||
queue_swap_request();
|
||||
}
|
||||
else
|
||||
@@ -2349,11 +2193,4 @@ void VKGSRender::flip(int buffer)
|
||||
m_setup_time = 0;
|
||||
m_vertex_upload_time = 0;
|
||||
m_textures_upload_time = 0;
|
||||
|
||||
m_uploads_small = 0;
|
||||
m_uploads_1k = 0;
|
||||
m_uploads_2k = 0;
|
||||
m_uploads_4k = 0;
|
||||
m_uploads_8k = 0;
|
||||
m_uploads_16k = 0;
|
||||
}
|
||||
|
||||
@@ -149,26 +149,15 @@ private:
|
||||
vk::descriptor_pool descriptor_pool;
|
||||
|
||||
std::vector<std::unique_ptr<vk::buffer_view> > m_buffer_view_to_clean;
|
||||
std::vector<std::unique_ptr<vk::framebuffer> > m_framebuffer_to_clean;
|
||||
std::vector<std::unique_ptr<vk::sampler> > m_sampler_to_clean;
|
||||
std::list<std::unique_ptr<vk::framebuffer_holder> > m_framebuffer_to_clean;
|
||||
std::unique_ptr<vk::framebuffer_holder> m_draw_fbo;
|
||||
|
||||
u32 m_client_width = 0;
|
||||
u32 m_client_height = 0;
|
||||
|
||||
// Draw call stats
|
||||
u32 m_draw_calls = 0;
|
||||
u32 m_instanced_draws = 0;
|
||||
|
||||
// Vertex buffer usage stats
|
||||
u32 m_uploads_small = 0;
|
||||
u32 m_uploads_1k = 0;
|
||||
u32 m_uploads_2k = 0;
|
||||
u32 m_uploads_4k = 0;
|
||||
u32 m_uploads_8k = 0;
|
||||
u32 m_uploads_16k = 0;
|
||||
|
||||
// Timers
|
||||
s64 m_setup_time = 0;
|
||||
s64 m_vertex_upload_time = 0;
|
||||
s64 m_textures_upload_time = 0;
|
||||
|
||||
@@ -650,17 +650,17 @@ namespace vk
|
||||
{
|
||||
VkFramebuffer value;
|
||||
VkFramebufferCreateInfo info = {};
|
||||
std::vector<std::unique_ptr<vk::image_view>> attachments;
|
||||
std::vector<std::unique_ptr<vk::image_view>> attachements;
|
||||
u32 m_width = 0;
|
||||
u32 m_height = 0;
|
||||
|
||||
public:
|
||||
framebuffer(VkDevice dev, VkRenderPass pass, u32 width, u32 height, std::vector<std::unique_ptr<vk::image_view>> &&atts)
|
||||
: m_device(dev), attachments(std::move(atts))
|
||||
: m_device(dev), attachements(std::move(atts))
|
||||
{
|
||||
std::vector<VkImageView> image_view_array(attachments.size());
|
||||
std::vector<VkImageView> image_view_array(attachements.size());
|
||||
size_t i = 0;
|
||||
for (const auto &att : attachments)
|
||||
for (const auto &att : attachements)
|
||||
{
|
||||
image_view_array[i++] = att->value;
|
||||
}
|
||||
@@ -694,24 +694,6 @@ namespace vk
|
||||
return m_height;
|
||||
}
|
||||
|
||||
bool matches(std::vector<vk::image*> fbo_images, u32 width, u32 height)
|
||||
{
|
||||
if (m_width != width || m_height != height)
|
||||
return false;
|
||||
|
||||
if (fbo_images.size() != attachments.size())
|
||||
return false;
|
||||
|
||||
for (int n = 0; n < fbo_images.size(); ++n)
|
||||
{
|
||||
if (attachments[n]->info.image != fbo_images[n]->value ||
|
||||
attachments[n]->info.format != fbo_images[n]->info.format)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
framebuffer(const framebuffer&) = delete;
|
||||
framebuffer(framebuffer&&) = delete;
|
||||
|
||||
|
||||
@@ -7,16 +7,9 @@
|
||||
#include "../Common/TextureUtils.h"
|
||||
#include "VKFormats.h"
|
||||
|
||||
struct ref_counted
|
||||
{
|
||||
u8 deref_count = 0;
|
||||
|
||||
void reset_refs() { deref_count = 0; }
|
||||
};
|
||||
|
||||
namespace vk
|
||||
{
|
||||
struct render_target : public image, public ref_counted
|
||||
struct render_target : public image
|
||||
{
|
||||
bool dirty = false;
|
||||
u16 native_pitch = 0;
|
||||
@@ -41,17 +34,6 @@ namespace vk
|
||||
mipmaps, layers, samples, initial_layout, tiling, usage, image_flags)
|
||||
{}
|
||||
};
|
||||
|
||||
struct framebuffer_holder: public vk::framebuffer, public ref_counted
|
||||
{
|
||||
framebuffer_holder(VkDevice dev,
|
||||
VkRenderPass pass,
|
||||
u32 width, u32 height,
|
||||
std::vector<std::unique_ptr<vk::image_view>> &&atts)
|
||||
|
||||
: framebuffer(dev, pass, width, height, std::move(atts))
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
||||
namespace rsx
|
||||
@@ -165,9 +147,6 @@ namespace rsx
|
||||
{
|
||||
VkImageSubresourceRange range = vk::get_image_subresource_range(0, 0, 1, 1, surface->attachment_aspect_flag);
|
||||
change_image_layout(*pcmd, surface, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, range);
|
||||
|
||||
//Reset deref count
|
||||
surface->deref_count = 0;
|
||||
}
|
||||
|
||||
static void prepare_rtt_for_sampling(vk::command_buffer* pcmd, vk::render_target *surface)
|
||||
@@ -180,9 +159,6 @@ namespace rsx
|
||||
{
|
||||
VkImageSubresourceRange range = vk::get_image_subresource_range(0, 0, 1, 1, surface->attachment_aspect_flag);
|
||||
change_image_layout(*pcmd, surface, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, range);
|
||||
|
||||
//Reset deref count
|
||||
surface->deref_count = 0;
|
||||
}
|
||||
|
||||
static void prepare_ds_for_sampling(vk::command_buffer* pcmd, vk::render_target *surface)
|
||||
@@ -191,26 +167,15 @@ namespace rsx
|
||||
change_image_layout(*pcmd, surface, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, range);
|
||||
}
|
||||
|
||||
static void invalidate_rtt_surface_contents(vk::command_buffer* pcmd, vk::render_target *rtt, vk::render_target *old_surface, bool forced)
|
||||
{
|
||||
if (forced)
|
||||
{
|
||||
rtt->old_contents = old_surface;
|
||||
rtt->dirty = true;
|
||||
}
|
||||
}
|
||||
static void invalidate_rtt_surface_contents(vk::command_buffer*, vk::render_target*) {}
|
||||
|
||||
static void invalidate_depth_surface_contents(vk::command_buffer* /*pcmd*/, vk::render_target *ds, vk::render_target *old_surface, bool /*forced*/)
|
||||
static void invalidate_depth_surface_contents(vk::command_buffer* /*pcmd*/, vk::render_target *ds)
|
||||
{
|
||||
ds->dirty = true;
|
||||
ds->old_contents = old_surface;
|
||||
}
|
||||
|
||||
static bool rtt_has_format_width_height(const std::unique_ptr<vk::render_target> &rtt, surface_color_format format, size_t width, size_t height, bool check_refs=false)
|
||||
static bool rtt_has_format_width_height(const std::unique_ptr<vk::render_target> &rtt, surface_color_format format, size_t width, size_t height)
|
||||
{
|
||||
if (check_refs && rtt->deref_count == 0) //Surface may still have read refs from data 'copy'
|
||||
return false;
|
||||
|
||||
VkFormat fmt = vk::get_compatible_surface_format(format).first;
|
||||
|
||||
if (rtt->info.format == fmt &&
|
||||
@@ -221,24 +186,15 @@ namespace rsx
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ds_has_format_width_height(const std::unique_ptr<vk::render_target> &ds, surface_depth_format format, size_t width, size_t height, bool check_refs=false)
|
||||
static bool ds_has_format_width_height(const std::unique_ptr<vk::render_target> &ds, surface_depth_format, size_t width, size_t height)
|
||||
{
|
||||
if (check_refs && ds->deref_count == 0) //Surface may still have read refs from data 'copy'
|
||||
return false;
|
||||
// TODO: check format
|
||||
//VkFormat fmt = vk::get_compatible_depth_surface_format(format);
|
||||
|
||||
if (ds->info.extent.width == width &&
|
||||
if (//tex.get_format() == fmt &&
|
||||
ds->info.extent.width == width &&
|
||||
ds->info.extent.height == height)
|
||||
{
|
||||
//Check format
|
||||
switch (ds->info.format)
|
||||
{
|
||||
case VK_FORMAT_D16_UNORM:
|
||||
return format == surface_depth_format::z16;
|
||||
case VK_FORMAT_D24_UNORM_S8_UINT:
|
||||
case VK_FORMAT_D32_SFLOAT_S8_UINT:
|
||||
return format == surface_depth_format::z24s8;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -281,16 +237,5 @@ namespace rsx
|
||||
m_depth_stencil_storage.clear();
|
||||
invalidated_resources.clear();
|
||||
}
|
||||
|
||||
void free_invalidated()
|
||||
{
|
||||
invalidated_resources.remove_if([](std::unique_ptr<vk::render_target> &rtt)
|
||||
{
|
||||
if (rtt->deref_count >= 2) return true;
|
||||
|
||||
rtt->deref_count++;
|
||||
return false;
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -477,7 +477,7 @@ namespace
|
||||
{
|
||||
const auto &vbo = vertex_buffers[i];
|
||||
|
||||
if (vbo.which() == 0 && vertex_count >= (u32)g_cfg.video.mt_vertex_upload_threshold && vertex_buffers.size() > 1 && rsxthr->vertex_upload_task_ready())
|
||||
if (vbo.which() == 0 && vertex_count > 128 && vertex_buffers.size() > 2 && rsxthr->vertex_upload_task_ready())
|
||||
{
|
||||
//vertex array buffer. We can thread this thing heavily
|
||||
const auto& v = vbo.get<rsx::vertex_array_buffer>();
|
||||
|
||||
@@ -146,9 +146,8 @@ void VKVertexDecompilerThread::insertConstants(std::stringstream & OS, const std
|
||||
static const vertex_reg_info reg_table[] =
|
||||
{
|
||||
{ "gl_Position", false, "dst_reg0", "", false },
|
||||
//Technically these two are for both back and front
|
||||
{ "back_diff_color", true, "dst_reg1", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTDIFFUSE },
|
||||
{ "back_spec_color", true, "dst_reg2", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTSPECULAR },
|
||||
{ "back_diff_color", true, "dst_reg1", "", false },
|
||||
{ "back_spec_color", true, "dst_reg2", "", false },
|
||||
{ "front_diff_color", true, "dst_reg3", "", false },
|
||||
{ "front_spec_color", true, "dst_reg4", "", false },
|
||||
{ "fog_c", true, "dst_reg5", ".xxxx", true, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_FOG },
|
||||
@@ -160,15 +159,15 @@ static const vertex_reg_info reg_table[] =
|
||||
{ "gl_ClipDistance[3]", false, "dst_reg6", ".y * userClipFactor[0].w", false, "userClipEnabled[0].w > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC3 },
|
||||
{ "gl_ClipDistance[4]", false, "dst_reg6", ".z * userClipFactor[1].x", false, "userClipEnabled[1].x > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC4 },
|
||||
{ "gl_ClipDistance[5]", false, "dst_reg6", ".w * userClipFactor[1].y", false, "userClipEnabled[1].y > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC5 },
|
||||
{ "tc0", true, "dst_reg7", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX0 },
|
||||
{ "tc1", true, "dst_reg8", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX1 },
|
||||
{ "tc2", true, "dst_reg9", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX2 },
|
||||
{ "tc3", true, "dst_reg10", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX3 },
|
||||
{ "tc4", true, "dst_reg11", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX4 },
|
||||
{ "tc5", true, "dst_reg12", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX5 },
|
||||
{ "tc6", true, "dst_reg13", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX6 },
|
||||
{ "tc7", true, "dst_reg14", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX7 },
|
||||
{ "tc8", true, "dst_reg15", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX8 },
|
||||
{ "tc0", true, "dst_reg7", "", false },
|
||||
{ "tc1", true, "dst_reg8", "", false },
|
||||
{ "tc2", true, "dst_reg9", "", false },
|
||||
{ "tc3", true, "dst_reg10", "", false },
|
||||
{ "tc4", true, "dst_reg11", "", false },
|
||||
{ "tc5", true, "dst_reg12", "", false },
|
||||
{ "tc6", true, "dst_reg13", "", false },
|
||||
{ "tc7", true, "dst_reg14", "", false },
|
||||
{ "tc8", true, "dst_reg15", "", false },
|
||||
{ "tc9", true, "dst_reg6", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX9 } // In this line, dst_reg6 is correct since dst_reg goes from 0 to 15.
|
||||
};
|
||||
|
||||
@@ -196,16 +195,6 @@ void VKVertexDecompilerThread::insertOutputs(std::stringstream & OS, const std::
|
||||
const vk::varying_register_t ® = vk::get_varying_register(i.name);
|
||||
OS << "layout(location=" << reg.reg_location << ") out vec4 " << i.name << ";\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
//Force some outputs to be declared even if unused so we can set default values
|
||||
//NOTE: Registers that can be skept will not have their check_mask_value set
|
||||
if (i.need_declare && (rsx_vertex_program.output_mask & i.check_mask_value) > 0)
|
||||
{
|
||||
const vk::varying_register_t ® = vk::get_varying_register(i.name);
|
||||
OS << "layout(location=" << reg.reg_location << ") out vec4 " << i.name << ";\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (insert_back_diffuse && insert_front_diffuse)
|
||||
|
||||
@@ -968,7 +968,7 @@ rsx::blit_engine::context_dma rsx::blit_engine::to_context_dma(u32 in)
|
||||
{
|
||||
switch (in)
|
||||
{
|
||||
case CELL_GCM_CONTEXT_DMA_TO_MEMORY_GET_REPORT: return rsx::blit_engine::context_dma::to_memory_get_report;
|
||||
case CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_LOCAL: return rsx::blit_engine::context_dma::to_memory_get_report;
|
||||
case CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_MAIN: return rsx::blit_engine::context_dma::report_location_main;
|
||||
case CELL_GCM_CONTEXT_DMA_MEMORY_HOST_BUFFER: return rsx::blit_engine::context_dma::memory_host_buffer;
|
||||
}
|
||||
|
||||
@@ -704,7 +704,7 @@ enum
|
||||
{
|
||||
CELL_GCM_CONTEXT_DMA_MEMORY_FRAME_BUFFER = 0xFEED0000, // Local memory
|
||||
CELL_GCM_CONTEXT_DMA_MEMORY_HOST_BUFFER = 0xFEED0001, // Main memory
|
||||
CELL_GCM_CONTEXT_DMA_TO_MEMORY_GET_REPORT = 0x66626660,
|
||||
CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_LOCAL = 0x66626660,
|
||||
CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_MAIN = 0xBAD68000,
|
||||
CELL_GCM_CONTEXT_DMA_NOTIFY_MAIN_0 = 0x6660420F,
|
||||
|
||||
|
||||
+134
-31
@@ -6,6 +6,7 @@
|
||||
#include "rsx_utils.h"
|
||||
#include "rsx_decode.h"
|
||||
#include "Emu/Cell/PPUCallback.h"
|
||||
#include "Emu/Cell/lv2/sys_rsx.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <cereal/archives/binary.hpp>
|
||||
@@ -58,11 +59,23 @@ namespace rsx
|
||||
rsx->ctrl->ref.exchange(arg);
|
||||
}
|
||||
|
||||
void set_context_dma_semaphore(thread* rsx, u32 _reg, u32 arg)
|
||||
{
|
||||
rsx->nv406e_semaphore_addr = arg;
|
||||
}
|
||||
|
||||
void semaphore_acquire(thread* rsx, u32 _reg, u32 arg)
|
||||
{
|
||||
//TODO: dma
|
||||
while (vm::ps3::read32(rsx->label_addr + method_registers.semaphore_offset_406e()) != arg)
|
||||
//while (vm::ps3::read32(rsx->label_addr + method_registers.semaphore_offset_406e()) != arg)
|
||||
const u32 addr = get_address(method_registers.semaphore_offset_406e(), rsx->nv406e_semaphore_addr);
|
||||
//todo: make me atomic
|
||||
while (vm::ps3::read32(addr) != arg)
|
||||
{
|
||||
// todo: why does this one keep hanging? is it vsh system semaphore? whats actually pushing this to the command buffer?!
|
||||
if (addr == 0x40000030)
|
||||
break;
|
||||
|
||||
if (Emu.IsStopped())
|
||||
break;
|
||||
|
||||
@@ -73,10 +86,35 @@ namespace rsx
|
||||
void semaphore_release(thread* rsx, u32 _reg, u32 arg)
|
||||
{
|
||||
//TODO: dma
|
||||
vm::ps3::write32(rsx->label_addr + method_registers.semaphore_offset_406e(), arg);
|
||||
//vm::ps3::write32(rsx->label_addr + method_registers.semaphore_offset_406e(), arg);
|
||||
const u32 addr = get_address(method_registers.semaphore_offset_406e(), rsx->nv406e_semaphore_addr);
|
||||
vm::ps3::write32(addr, arg);
|
||||
}
|
||||
}
|
||||
|
||||
struct RsxSemaphore {
|
||||
be_t<u32> val;
|
||||
be_t<u32> pad;
|
||||
be_t<u64> timestamp;
|
||||
};
|
||||
|
||||
struct RsxNotify {
|
||||
be_t<u64> timestamp;
|
||||
be_t<u64> zero;
|
||||
};
|
||||
|
||||
struct RsxReport {
|
||||
be_t<u64> timestamp;
|
||||
be_t<u32> val;
|
||||
be_t<u32> pad;
|
||||
};
|
||||
|
||||
struct RsxReports {
|
||||
RsxSemaphore semaphore[0x100];
|
||||
RsxNotify notify[64];
|
||||
RsxReport report[2048];
|
||||
};
|
||||
|
||||
namespace nv4097
|
||||
{
|
||||
void clear(thread* rsx, u32 _reg, u32 arg)
|
||||
@@ -93,6 +131,11 @@ namespace rsx
|
||||
}
|
||||
}
|
||||
|
||||
/*void set_context_dma_semaphore(thread* rsx, u32 _reg, u32 arg)
|
||||
{
|
||||
rsx->nv4097_semaphore_index = arg >> 4;
|
||||
}*/
|
||||
|
||||
void texture_read_semaphore_release(thread* rsx, u32 _reg, u32 arg)
|
||||
{
|
||||
if (!rsx->do_method(NV4097_TEXTURE_READ_SEMAPHORE_RELEASE, arg))
|
||||
@@ -101,7 +144,15 @@ namespace rsx
|
||||
}
|
||||
|
||||
//TODO: dma
|
||||
vm::ps3::write32(rsx->label_addr + method_registers.semaphore_offset_4097(), arg);
|
||||
//vm::ps3::write32(rsx->label_addr + method_registers.semaphore_offset_4097(), arg);
|
||||
//const u32 addr = get_address(method_registers.semaphore_offset_4097(), rsx->nv4097_semaphore_index);
|
||||
//vm::ps3::write32(addr, arg);
|
||||
const u32 index = method_registers.semaphore_offset_4097() >> 4;
|
||||
//LOG_ERROR(RSX, "readrelease: 0x%x, 0x%x, addr:0x%x", arg, index, rsx->label_addr);
|
||||
auto& sema = vm::ps3::_ref<RsxReports>(rsx->label_addr);
|
||||
sema.semaphore[index].val = arg;
|
||||
sema.semaphore[index].pad = 0;
|
||||
sema.semaphore[index].timestamp = rsx->timestamp();
|
||||
}
|
||||
|
||||
void back_end_write_semaphore_release(thread* rsx, u32 _reg, u32 arg)
|
||||
@@ -112,8 +163,18 @@ namespace rsx
|
||||
}
|
||||
|
||||
//TODO: dma
|
||||
vm::ps3::write32(rsx->label_addr + method_registers.semaphore_offset_4097(),
|
||||
(arg & 0xff00ff00) | ((arg & 0xff) << 16) | ((arg >> 16) & 0xff));
|
||||
//vm::ps3::write32(rsx->label_addr + method_registers.semaphore_offset_4097(),
|
||||
// (arg & 0xff00ff00) | ((arg & 0xff) << 16) | ((arg >> 16) & 0xff));
|
||||
//const u32 addr = get_address(method_registers.semaphore_offset_4097(), rsx->nv4097_semaphore_addr);
|
||||
//vm::ps3::write32(addr, (arg & 0xff00ff00) | ((arg & 0xff) << 16) | ((arg >> 16) & 0xff));
|
||||
const u32 index = method_registers.semaphore_offset_4097() >> 4;
|
||||
u32 val = (arg & 0xff00ff00) | ((arg & 0xff) << 16) | ((arg >> 16) & 0xff);
|
||||
//LOG_ERROR(RSX, "wriuterelease: 0x%x, 0x%x, addr:0x%x", val, index, rsx->label_addr);
|
||||
auto& sema = vm::ps3::_ref<RsxReports>(rsx->label_addr);
|
||||
sema.semaphore[index].val = val;
|
||||
sema.semaphore[index].pad = 0;
|
||||
sema.semaphore[index].timestamp = rsx->timestamp();
|
||||
|
||||
}
|
||||
|
||||
template<u32 id, u32 index, int count, typename type>
|
||||
@@ -323,10 +384,10 @@ namespace rsx
|
||||
|
||||
switch (report_dma)
|
||||
{
|
||||
case blit_engine::context_dma::to_memory_get_report: location = CELL_GCM_LOCATION_LOCAL; break;
|
||||
case blit_engine::context_dma::report_location_main:
|
||||
case blit_engine::context_dma::memory_host_buffer:
|
||||
location = CELL_GCM_LOCATION_MAIN; break;
|
||||
case blit_engine::context_dma::to_memory_get_report: location = CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_LOCAL; break;
|
||||
case blit_engine::context_dma::report_location_main: location = CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_MAIN; break;
|
||||
case blit_engine::context_dma::memory_host_buffer: location = CELL_GCM_CONTEXT_DMA_MEMORY_HOST_BUFFER; break;
|
||||
//location = CELL_GCM_LOCATION_MAIN; break;
|
||||
default:
|
||||
LOG_WARNING(RSX, "nv4097::get_report: bad report dma: 0x%x", (u8)report_dma);
|
||||
return;
|
||||
@@ -353,7 +414,7 @@ namespace rsx
|
||||
break;
|
||||
}
|
||||
|
||||
//result->padding = 0;
|
||||
result->padding = 0;
|
||||
}
|
||||
|
||||
void clear_report_value(thread* rsx, u32 _reg, u32 arg)
|
||||
@@ -472,6 +533,7 @@ namespace rsx
|
||||
if (in_origin != blit_engine::transfer_origin::corner)
|
||||
{
|
||||
LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown origin (%d)", (u8)in_origin);
|
||||
return;
|
||||
}
|
||||
|
||||
if (operation != rsx::blit_engine::transfer_operation::srccopy)
|
||||
@@ -845,31 +907,14 @@ namespace rsx
|
||||
}
|
||||
Emu.Pause();
|
||||
}
|
||||
|
||||
double limit = 0.;
|
||||
switch (g_cfg.video.frame_limit)
|
||||
{
|
||||
case frame_limit_type::none: limit = 0.; break;
|
||||
case frame_limit_type::_59_94: limit = 59.94; break;
|
||||
case frame_limit_type::_50: limit = 50.; break;
|
||||
case frame_limit_type::_60: limit = 60.; break;
|
||||
case frame_limit_type::_30: limit = 30.; break;
|
||||
case frame_limit_type::_auto: limit = rsx->fps_limit; break; // TODO
|
||||
}
|
||||
if (limit)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds((s64)(1000.0 / limit - rsx->timer_sync.GetElapsedTimeInMilliSec())));
|
||||
rsx->timer_sync.Start();
|
||||
}
|
||||
|
||||
rsx->gcm_current_buffer = arg;
|
||||
rsx->flip(arg);
|
||||
// After each flip PS3 system is executing a routine that changes registers value to some default.
|
||||
// Some game use this default state (SH3).
|
||||
rsx->reset();
|
||||
//rsx->reset(); // moved to 'actual' rsx flip command
|
||||
|
||||
rsx->last_flip_time = get_system_time() - 1000000;
|
||||
rsx->gcm_current_buffer = arg;
|
||||
rsx->flip_status = CELL_GCM_DISPLAY_FLIP_STATUS_DONE;
|
||||
|
||||
if (rsx->flip_handler)
|
||||
@@ -887,6 +932,7 @@ namespace rsx
|
||||
|
||||
void user_command(thread* rsx, u32, u32 arg)
|
||||
{
|
||||
sys_rsx_context_attribute(0x55555555, 0xFEF, 0, arg, 0, 0);
|
||||
if (rsx->user_handler)
|
||||
{
|
||||
rsx->intr_thread->cmd_list
|
||||
@@ -900,6 +946,46 @@ namespace rsx
|
||||
}
|
||||
}
|
||||
|
||||
namespace gcm
|
||||
{
|
||||
// not entirely sure which one should actually do the flip, or if these should be handled seperately,
|
||||
// so for now lets flip in queue and just let the driver deal with it
|
||||
template<u32 index>
|
||||
struct driver_flip
|
||||
{
|
||||
static void impl(thread* rsx, u32 _reg, u32 arg)
|
||||
{
|
||||
double limit = 0.;
|
||||
switch (g_cfg.video.frame_limit)
|
||||
{
|
||||
case frame_limit_type::none: limit = 0.; break;
|
||||
case frame_limit_type::_59_94: limit = 59.94; break;
|
||||
case frame_limit_type::_50: limit = 50.; break;
|
||||
case frame_limit_type::_60: limit = 60.; break;
|
||||
case frame_limit_type::_30: limit = 30.; break;
|
||||
case frame_limit_type::_auto: limit = rsx->fps_limit; break; // TODO
|
||||
}
|
||||
if (limit)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds((s64)(1000.0 / limit - rsx->timer_sync.GetElapsedTimeInMilliSec())));
|
||||
rsx->timer_sync.Start();
|
||||
}
|
||||
rsx->reset(); // fixes kh, so lets leave it here and see what happens
|
||||
sys_rsx_context_attribute(0x55555555, 0x102, index, arg, 0, 0);
|
||||
}
|
||||
};
|
||||
|
||||
template<u32 index>
|
||||
struct queue_flip
|
||||
{
|
||||
static void impl(thread* rsx, u32 _reg, u32 arg)
|
||||
{
|
||||
flip_command(rsx, _reg, arg);
|
||||
sys_rsx_context_attribute(0x55555555, 0x103, index, arg, 0, 0);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void rsx_state::reset()
|
||||
{
|
||||
//setup method registers
|
||||
@@ -971,7 +1057,7 @@ namespace rsx
|
||||
registers[NV4097_SET_SURFACE_FORMAT] = (8 << 0) | (2 << 5) | (0 << 12) | (1 << 16) | (1 << 24);
|
||||
|
||||
// rsx dma initial values
|
||||
registers[NV4097_SET_CONTEXT_DMA_REPORT] = CELL_GCM_CONTEXT_DMA_TO_MEMORY_GET_REPORT;
|
||||
registers[NV4097_SET_CONTEXT_DMA_REPORT] = CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_LOCAL;
|
||||
registers[NV406E_SET_CONTEXT_DMA_SEMAPHORE] = CELL_GCM_CONTEXT_DMA_SEMAPHORE_RW;
|
||||
registers[NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN] = CELL_GCM_CONTEXT_DMA_MEMORY_FRAME_BUFFER;
|
||||
registers[NV309E_SET_CONTEXT_DMA_IMAGE] = CELL_GCM_CONTEXT_DMA_MEMORY_FRAME_BUFFER;
|
||||
@@ -1081,10 +1167,17 @@ namespace rsx
|
||||
methods[NV4097_SET_SURFACE_COLOR_BOFFSET] = nullptr;
|
||||
methods[NV4097_SET_SURFACE_PITCH_B] = nullptr;
|
||||
methods[NV4097_SET_SURFACE_COLOR_TARGET] = nullptr;
|
||||
methods[0x224 >> 2] = nullptr;
|
||||
methods[0x228 >> 2] = nullptr;
|
||||
methods[0x230 >> 2] = nullptr;
|
||||
methods[NV4097_SET_SURFACE_PITCH_Z] = nullptr;
|
||||
methods[NV4097_INVALIDATE_ZCULL] = nullptr;
|
||||
methods[NV4097_SET_CYLINDRICAL_WRAP] = nullptr;
|
||||
methods[NV4097_SET_CYLINDRICAL_WRAP1] = nullptr;
|
||||
methods[0x240 >> 2] = nullptr;
|
||||
methods[0x244 >> 2] = nullptr;
|
||||
methods[0x248 >> 2] = nullptr;
|
||||
methods[0x24C >> 2] = nullptr;
|
||||
methods[NV4097_SET_SURFACE_PITCH_C] = nullptr;
|
||||
methods[NV4097_SET_SURFACE_PITCH_D] = nullptr;
|
||||
methods[NV4097_SET_SURFACE_COLOR_COFFSET] = nullptr;
|
||||
@@ -1153,6 +1246,7 @@ namespace rsx
|
||||
methods[NV4097_SET_FOG_MODE] = nullptr;
|
||||
methods[NV4097_SET_FOG_PARAMS] = nullptr;
|
||||
methods[NV4097_SET_FOG_PARAMS + 1] = nullptr;
|
||||
methods[0x8d8 >> 2] = nullptr;
|
||||
methods[NV4097_SET_SHADER_PROGRAM] = nullptr;
|
||||
methods[NV4097_SET_VERTEX_TEXTURE_OFFSET] = nullptr;
|
||||
methods[NV4097_SET_VERTEX_TEXTURE_FORMAT] = nullptr;
|
||||
@@ -1236,6 +1330,7 @@ namespace rsx
|
||||
methods[NV4097_SET_TEXTURE_BORDER_COLOR] = nullptr;
|
||||
methods[NV4097_SET_VERTEX_DATA4F_M] = nullptr;
|
||||
methods[NV4097_SET_COLOR_KEY_COLOR] = nullptr;
|
||||
methods[0x1d04 >> 2] = nullptr;
|
||||
methods[NV4097_SET_SHADER_CONTROL] = nullptr;
|
||||
methods[NV4097_SET_INDEXED_CONSTANT_READ_LIMITS] = nullptr;
|
||||
methods[NV4097_SET_SEMAPHORE_OFFSET] = nullptr;
|
||||
@@ -1362,6 +1457,8 @@ namespace rsx
|
||||
bind_array<GCM_FLIP_HEAD, 1, 2, nullptr>();
|
||||
bind_array<GCM_DRIVER_QUEUE, 1, 8, nullptr>();
|
||||
|
||||
bind_array<(0x400 >> 2), 1, 0x10, nullptr>();
|
||||
bind_array<(0x440 >> 2), 1, 0x20, nullptr>();
|
||||
bind_array<NV4097_SET_ANISO_SPREAD, 1, 16, nullptr>();
|
||||
bind_array<NV4097_SET_VERTEX_TEXTURE_OFFSET, 1, 8 * 4, nullptr>();
|
||||
bind_array<NV4097_SET_VERTEX_DATA_SCALED4S_M, 1, 32, nullptr>();
|
||||
@@ -1384,6 +1481,7 @@ namespace rsx
|
||||
|
||||
// NV406E
|
||||
bind<NV406E_SET_REFERENCE, nv406e::set_reference>();
|
||||
bind<NV406E_SET_CONTEXT_DMA_SEMAPHORE, nv406e::set_context_dma_semaphore>();
|
||||
bind<NV406E_SEMAPHORE_ACQUIRE, nv406e::semaphore_acquire>();
|
||||
bind<NV406E_SEMAPHORE_RELEASE, nv406e::semaphore_release>();
|
||||
|
||||
@@ -1398,6 +1496,7 @@ namespace rsx
|
||||
*/
|
||||
|
||||
// NV4097
|
||||
//bind<NV4097_SET_CONTEXT_DMA_SEMAPHORE, nv4097::set_context_dma_semaphore>();
|
||||
bind<NV4097_TEXTURE_READ_SEMAPHORE_RELEASE, nv4097::texture_read_semaphore_release>();
|
||||
bind<NV4097_BACK_END_WRITE_SEMAPHORE_RELEASE, nv4097::back_end_write_semaphore_release>();
|
||||
bind<NV4097_SET_BEGIN_END, nv4097::set_begin_end>();
|
||||
@@ -1455,9 +1554,13 @@ namespace rsx
|
||||
//NV0039
|
||||
bind<NV0039_BUFFER_NOTIFY, nv0039::buffer_notify>();
|
||||
|
||||
// custom methods
|
||||
bind<GCM_FLIP_COMMAND, flip_command>();
|
||||
// lv1 hypervisor
|
||||
bind_array<GCM_SET_USER_COMMAND, 1, 2, user_command>();
|
||||
bind_range<GCM_FLIP_HEAD, 1, 2, gcm::driver_flip>();
|
||||
bind_range<GCM_DRIVER_QUEUE, 1, 8, gcm::queue_flip>();
|
||||
|
||||
// custom
|
||||
bind<GCM_FLIP_COMMAND, flip_command>();
|
||||
|
||||
return true;
|
||||
}();
|
||||
|
||||
+4
-8
@@ -272,9 +272,6 @@ struct cfg_root : cfg::node
|
||||
cfg::_bool lower_spu_priority{this, "Lower SPU thread priority"};
|
||||
cfg::_bool spu_debug{this, "SPU Debug"};
|
||||
cfg::_int<32, 16384> max_spu_immediate_write_size{this, "Maximum immediate DMA write size", 16384}; // Maximum size that an SPU thread can write directly without posting to MFC
|
||||
cfg::_int<0, 6> preferred_spu_threads{this, "Preferred SPU Threads", 0}; //Numnber of hardware threads dedicated to heavy simultaneous spu tasks
|
||||
cfg::_int<0, 16> spu_delay_penalty{this, "SPU delay penalty", 3}; //Number of milliseconds to block a thread if a virtual 'core' isn't free
|
||||
cfg::_bool spu_loop_detection{this, "SPU loop detection", false}; //Try to detect wait loops and trigger thread yield
|
||||
|
||||
cfg::_enum<lib_loading_type> lib_loading{this, "Lib Loader", lib_loading_type::automatic};
|
||||
cfg::_bool hook_functions{this, "Hook static functions"};
|
||||
@@ -323,13 +320,12 @@ struct cfg_root : cfg::node
|
||||
cfg::_bool invalidate_surface_cache_every_frame{this, "Invalidate Cache Every Frame", true};
|
||||
cfg::_bool strict_rendering_mode{this, "Strict Rendering Mode"};
|
||||
|
||||
cfg::_bool batch_instanced_geometry{this, "Batch Instanced Geometry", false}; //Avoid re-uploading geometry if the same draw command is repeated
|
||||
cfg::_int<1, 16> vertex_upload_threads{ this, "Vertex Upload Threads", 1 }; //Max number of threads to use for parallel vertex processing
|
||||
cfg::_int<32, 65536> mt_vertex_upload_threshold{ this, "Multithreaded Vertex Upload Threshold", 4096}; //Minimum vertex count to parallelize
|
||||
cfg::_bool batch_instanced_geometry{this, "Batch Instanced Geometry", false};
|
||||
cfg::_int<1, 16> vertex_upload_threads{ this, "Vertex Upload Threads", 1 };
|
||||
|
||||
cfg::_bool frame_skip_enabled{this, "Enable Frame Skip"};
|
||||
cfg::_int<1, 8> consequtive_frames_to_draw{this, "Consecutive Frames Drawn", 1};
|
||||
cfg::_int<1, 8> consequtive_frames_to_skip{this, "Consecutive Frames Skept", 1};
|
||||
cfg::_int<1, 8> consequtive_frames_to_draw{this, "Consequtive Frames Drawn", 1};
|
||||
cfg::_int<1, 8> consequtive_frames_to_skip{this, "Consequtive Frames Skept", 1};
|
||||
|
||||
struct node_d3d12 : cfg::node
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@@ -95,4 +95,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
+2
-2
@@ -98,13 +98,13 @@ struct elf_phdr<en_t, u32>
|
||||
template<template<typename T> class en_t, typename sz_t>
|
||||
struct elf_prog final : elf_phdr<en_t, sz_t>
|
||||
{
|
||||
std::vector<uchar> bin;
|
||||
std::vector<char> bin;
|
||||
|
||||
using base = elf_phdr<en_t, sz_t>;
|
||||
|
||||
elf_prog() = default;
|
||||
|
||||
elf_prog(u32 type, u32 flags, sz_t vaddr, sz_t memsz, sz_t align, std::vector<uchar>&& bin)
|
||||
elf_prog(u32 type, u32 flags, sz_t vaddr, sz_t memsz, sz_t align, std::vector<char>&& bin)
|
||||
: bin(std::move(bin))
|
||||
{
|
||||
base::p_type = type;
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
@@ -102,13 +102,6 @@
|
||||
<ClCompile Include="..\Utilities\StrFmt.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Utilities\sysinfo.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug - MemLeak|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Utilities\Thread.cpp" />
|
||||
<ClCompile Include="..\Utilities\version.cpp" />
|
||||
<ClCompile Include="..\Utilities\VirtualMemory.cpp" />
|
||||
@@ -433,7 +426,6 @@
|
||||
<ClInclude Include="..\Utilities\rXml.h" />
|
||||
<ClInclude Include="..\Utilities\StrFmt.h" />
|
||||
<ClInclude Include="..\Utilities\StrUtil.h" />
|
||||
<ClInclude Include="..\Utilities\sysinfo.h" />
|
||||
<ClInclude Include="..\Utilities\Thread.h" />
|
||||
<ClInclude Include="..\Utilities\Timer.h" />
|
||||
<ClInclude Include="..\Utilities\types.h" />
|
||||
|
||||
@@ -923,9 +923,6 @@
|
||||
<ClCompile Include="Emu\Cell\lv2\sys_ss.cpp">
|
||||
<Filter>Emu\Cell\lv2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Utilities\sysinfo.cpp">
|
||||
<Filter>Utilities</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Crypto\aes.h">
|
||||
@@ -1780,8 +1777,5 @@
|
||||
<ClInclude Include="..\Utilities\CRC.h">
|
||||
<Filter>Utilities</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Utilities\sysinfo.h">
|
||||
<Filter>Utilities</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -19,13 +19,6 @@ int main(int argc, char** argv)
|
||||
SetProcessDPIAware();
|
||||
WSADATA wsa_data;
|
||||
WSAStartup(MAKEWORD(2, 2), &wsa_data);
|
||||
timeBeginPeriod(1);
|
||||
|
||||
atexit([]
|
||||
{
|
||||
timeEndPeriod(1);
|
||||
WSACleanup();
|
||||
});
|
||||
#else
|
||||
qputenv("QT_AUTO_SCREEN_SCALE_FACTOR", "1");
|
||||
#endif
|
||||
|
||||
+5
-5
@@ -26,7 +26,7 @@
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<PlatformToolSet>v140</PlatformToolSet>
|
||||
<PlatformToolSet>v141</PlatformToolSet>
|
||||
<OutputDirectory>release\</OutputDirectory>
|
||||
<ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
@@ -35,7 +35,7 @@
|
||||
<PrimaryOutput>rpcs3</PrimaryOutput>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'" Label="Configuration">
|
||||
<PlatformToolSet>v140</PlatformToolSet>
|
||||
<PlatformToolSet>v141</PlatformToolSet>
|
||||
<OutputDirectory>release\</OutputDirectory>
|
||||
<ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
@@ -44,7 +44,7 @@
|
||||
<PrimaryOutput>rpcs3</PrimaryOutput>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<PlatformToolSet>v140</PlatformToolSet>
|
||||
<PlatformToolSet>v141</PlatformToolSet>
|
||||
<OutputDirectory>debug\</OutputDirectory>
|
||||
<ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
@@ -53,7 +53,7 @@
|
||||
<PrimaryOutput>rpcs3</PrimaryOutput>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'" Label="Configuration">
|
||||
<PlatformToolSet>v140</PlatformToolSet>
|
||||
<PlatformToolSet>v141</PlatformToolSet>
|
||||
<OutputDirectory>debug\</OutputDirectory>
|
||||
<ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
@@ -924,6 +924,7 @@
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
</CustomBuild>
|
||||
<ClInclude Include="ds4_pad_handler.h" />
|
||||
<ClInclude Include="game_list.h" />
|
||||
<ClInclude Include="keyboard_pad_handler.h" />
|
||||
<CustomBuild Include="rpcs3qt\gs_frame.h">
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing gs_frame.h...</Message>
|
||||
@@ -1201,7 +1202,6 @@
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_QUICK_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DLLVM_AVAILABLE -D_SCL_SECURE_NO_WARNINGS -D_UNICODE "-I.\..\Vulkan\Vulkan-LoaderAndValidationLayers\include" "-I.\.." "-I.\..\3rdparty\minidx12\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtQuick" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtQml" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)\." "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras"</Command>
|
||||
</CustomBuild>
|
||||
<ClInclude Include="rpcs3qt\game_list.h" />
|
||||
<ClInclude Include="rpcs3qt\game_list_grid_delegate.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="rpcs3qt\gl_gs_frame.h" />
|
||||
|
||||
@@ -514,7 +514,7 @@
|
||||
<ClInclude Include="QTGeneratedFiles\ui_welcome_dialog.h">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="rpcs3qt\game_list.h">
|
||||
<ClInclude Include="game_list.h">
|
||||
<Filter>Gui</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
|
||||
+9
-16
@@ -1,6 +1,7 @@
|
||||
#include "rpcs3_app.h"
|
||||
|
||||
#include "rpcs3qt/welcome_dialog.h"
|
||||
#include "rpcs3qt/gui_settings.h"
|
||||
|
||||
#include "Emu/System.h"
|
||||
#include "rpcs3qt/gs_frame.h"
|
||||
@@ -55,10 +56,8 @@ void rpcs3_app::Init()
|
||||
{
|
||||
Emu.Init();
|
||||
|
||||
guiSettings.reset(new gui_settings());
|
||||
|
||||
// Create the main window
|
||||
RPCS3MainWin = new main_window(guiSettings, nullptr);
|
||||
RPCS3MainWin = new main_window(nullptr);
|
||||
|
||||
// Reset the pads -- see the method for why this is currently needed.
|
||||
ResetPads();
|
||||
@@ -77,7 +76,9 @@ void rpcs3_app::Init()
|
||||
// Create the thumbnail toolbar after the main_window is created
|
||||
RPCS3MainWin->CreateThumbnailToolbar();
|
||||
|
||||
if (guiSettings->GetValue(GUI::ib_show_welcome).toBool())
|
||||
// Slightly inneficient to make a gui_settings instance right here.
|
||||
// But, I don't really feel like adding this as a dependency injection into RPCS3MainWin.
|
||||
if (gui_settings().GetValue(GUI::ib_show_welcome).toBool())
|
||||
{
|
||||
welcome_dialog* welcome = new welcome_dialog();
|
||||
welcome->exec();
|
||||
@@ -147,22 +148,14 @@ void rpcs3_app::InitializeCallbacks()
|
||||
extern const std::unordered_map<video_resolution, std::pair<int, int>, value_hash<video_resolution>> g_video_out_resolution_map;
|
||||
|
||||
const auto size = g_video_out_resolution_map.at(g_cfg.video.resolution);
|
||||
int w = size.first;
|
||||
int h = size.second;
|
||||
|
||||
if (guiSettings->GetValue(GUI::gs_resize).toBool())
|
||||
{
|
||||
w = guiSettings->GetValue(GUI::gs_width).toInt();
|
||||
h = guiSettings->GetValue(GUI::gs_height).toInt();
|
||||
}
|
||||
|
||||
switch (video_renderer type = g_cfg.video.renderer)
|
||||
{
|
||||
case video_renderer::null: return std::make_unique<gs_frame>("Null", w, h, RPCS3MainWin->GetAppIcon());
|
||||
case video_renderer::opengl: return std::make_unique<gl_gs_frame>(w, h, RPCS3MainWin->GetAppIcon());
|
||||
case video_renderer::vulkan: return std::make_unique<gs_frame>("Vulkan", w, h, RPCS3MainWin->GetAppIcon());
|
||||
case video_renderer::null: return std::make_unique<gs_frame>("Null", size.first, size.second, RPCS3MainWin->GetAppIcon());
|
||||
case video_renderer::opengl: return std::make_unique<gl_gs_frame>(size.first, size.second, RPCS3MainWin->GetAppIcon());
|
||||
case video_renderer::vulkan: return std::make_unique<gs_frame>("Vulkan", size.first, size.second, RPCS3MainWin->GetAppIcon());
|
||||
#ifdef _MSC_VER
|
||||
case video_renderer::dx12: return std::make_unique<gs_frame>("DirectX 12", w, h, RPCS3MainWin->GetAppIcon());
|
||||
case video_renderer::dx12: return std::make_unique<gs_frame>("DirectX 12", size.first, size.second, RPCS3MainWin->GetAppIcon());
|
||||
#endif
|
||||
default: fmt::throw_exception("Invalid video renderer: %s" HERE, type);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
|
||||
#include "rpcs3qt/msg_dialog_frame.h"
|
||||
#include "rpcs3qt/main_window.h"
|
||||
#include "rpcs3qt/gui_settings.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
@@ -52,6 +51,4 @@ private:
|
||||
std::shared_ptr<basic_mouse_handler> m_basicMouseHandler;
|
||||
|
||||
main_window* RPCS3MainWin;
|
||||
|
||||
std::shared_ptr<gui_settings> guiSettings;
|
||||
};
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
|
||||
namespace rpcs3
|
||||
{
|
||||
const extern utils::version version{ 0, 0, 3, utils::version_type::alpha, 1, RPCS3_GIT_VERSION };
|
||||
const extern utils::version version{ 0, 0, 2, utils::version_type::alpha, 1, RPCS3_GIT_VERSION };
|
||||
}
|
||||
|
||||
@@ -190,6 +190,11 @@ void debugger_frame::UpdateUI()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
g_breakpoints.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void debugger_frame::UpdateUnitList()
|
||||
@@ -383,8 +388,6 @@ void debugger_frame::Show_Val()
|
||||
}
|
||||
m_list->ShowAddr(CentrePc(pc));
|
||||
}
|
||||
|
||||
diag->deleteLater();
|
||||
}
|
||||
|
||||
void debugger_frame::Show_PC()
|
||||
@@ -421,11 +424,6 @@ void debugger_frame::EnableButtons(bool enable)
|
||||
m_btn_run->setEnabled(enable);
|
||||
}
|
||||
|
||||
void debugger_frame::ClearBreakpoints()
|
||||
{
|
||||
g_breakpoints.clear();
|
||||
}
|
||||
|
||||
debugger_list::debugger_list(debugger_frame* parent) : QListWidget(parent)
|
||||
{
|
||||
m_pc = 0;
|
||||
|
||||
@@ -73,7 +73,6 @@ public:
|
||||
void DoUpdate();
|
||||
void WriteRegs();
|
||||
void EnableButtons(bool enable);
|
||||
void ClearBreakpoints();
|
||||
|
||||
void OnUpdate();
|
||||
|
||||
|
||||
@@ -113,9 +113,6 @@ game_list_frame::game_list_frame(std::shared_ptr<gui_settings> settings, const R
|
||||
// Search Bar
|
||||
m_Search_Bar = new QLineEdit(m_Tool_Bar);
|
||||
m_Search_Bar->setPlaceholderText(tr("Search games ..."));
|
||||
m_Search_Bar->setMinimumWidth(m_Tool_Bar->height() * 5);
|
||||
m_Search_Bar->setFrame(false);
|
||||
m_Search_Bar->setStyleSheet("background:transparent;");
|
||||
connect(m_Search_Bar, &QLineEdit::textChanged, [this](const QString& text) {
|
||||
m_searchText = text;
|
||||
Refresh();
|
||||
@@ -125,7 +122,7 @@ game_list_frame::game_list_frame(std::shared_ptr<gui_settings> settings, const R
|
||||
m_Slider_Size = new QSlider(Qt::Horizontal , m_Tool_Bar);
|
||||
m_Slider_Size->setRange(0, GUI::gl_icon_size.size() - 1);
|
||||
m_Slider_Size->setSliderPosition(icon_size_index);
|
||||
m_Slider_Size->setFixedWidth(m_Tool_Bar->height() * 3);
|
||||
m_Slider_Size->setFixedWidth(100);
|
||||
|
||||
m_Tool_Bar->addWidget(m_Search_Bar);
|
||||
m_Tool_Bar->addWidget(new QLabel(" "));
|
||||
|
||||
@@ -52,7 +52,6 @@ namespace GUI
|
||||
const QString logger = "Logger";
|
||||
const QString meta = "Meta";
|
||||
const QString fs = "FileSystem";
|
||||
const QString gs_frame = "GSFrame";
|
||||
|
||||
const QColor mw_tool_bar_color = QColor(227, 227, 227, 255);
|
||||
const QColor mw_tool_icon_color = QColor(64, 64, 64, 255);
|
||||
@@ -87,7 +86,7 @@ namespace GUI
|
||||
const GUI_SAVE cat_disc_game = GUI_SAVE( game_list, "categoryVisibleDiscGame", true );
|
||||
const GUI_SAVE cat_home = GUI_SAVE( game_list, "categoryVisibleHome", true );
|
||||
const GUI_SAVE cat_audio_video = GUI_SAVE( game_list, "categoryVisibleAudioVideo", true );
|
||||
const GUI_SAVE cat_game_data = GUI_SAVE( game_list, "categoryVisibleGameData", false );
|
||||
const GUI_SAVE cat_game_data = GUI_SAVE( game_list, "categoryVisibleGameData", true );
|
||||
const GUI_SAVE cat_unknown = GUI_SAVE( game_list, "categoryVisibleUnknown", true );
|
||||
const GUI_SAVE cat_other = GUI_SAVE( game_list, "categoryVisibleOther", true );
|
||||
|
||||
@@ -114,10 +113,6 @@ namespace GUI
|
||||
|
||||
const GUI_SAVE m_currentConfig = GUI_SAVE(meta, "currentConfig", QObject::tr("CurrentSettings"));
|
||||
const GUI_SAVE m_currentStylesheet = GUI_SAVE(meta, "currentStylesheet", QObject::tr("default"));
|
||||
|
||||
const GUI_SAVE gs_resize = GUI_SAVE(gs_frame, "resize", false);
|
||||
const GUI_SAVE gs_width = GUI_SAVE(gs_frame, "width", 1280);
|
||||
const GUI_SAVE gs_height = GUI_SAVE(gs_frame, "height", 720);
|
||||
}
|
||||
|
||||
/** Class for GUI settings..
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <stdafx.h>
|
||||
#include "rpcs3_version.h"
|
||||
#include "Utilities/sysinfo.h"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QActionGroup>
|
||||
@@ -40,7 +39,7 @@ struct gui_listener : logs::listener
|
||||
read = new packet;
|
||||
last = new packet;
|
||||
read->next = last.load();
|
||||
last->msg = fmt::format("RPCS3 v%s\n%s\n", rpcs3::version.to_string(), utils::get_system_info());
|
||||
last->msg = fmt::format("RPCS3 v%s\n", rpcs3::version.to_string());
|
||||
|
||||
// Self-registration
|
||||
logs::listener::add(this);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMenuBar>
|
||||
#include <QMessageBox>
|
||||
@@ -41,13 +41,12 @@
|
||||
#include "Utilities/StrUtil.h"
|
||||
|
||||
#include "rpcs3_version.h"
|
||||
#include "Utilities/sysinfo.h"
|
||||
|
||||
#include "ui_main_window.h"
|
||||
|
||||
inline std::string sstr(const QString& _in) { return _in.toUtf8().toStdString(); }
|
||||
|
||||
main_window::main_window(std::shared_ptr<gui_settings> guiSettings, QWidget *parent) : QMainWindow(parent), guiSettings(guiSettings), m_sys_menu_opened(false), ui(new Ui::main_window)
|
||||
main_window::main_window(QWidget *parent) : QMainWindow(parent), m_sys_menu_opened(false), ui(new Ui::main_window)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -70,6 +69,8 @@ void main_window::Init()
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
guiSettings.reset(new gui_settings());
|
||||
|
||||
// Load Icons: This needs to happen before any actions or buttons are created
|
||||
RepaintToolBarIcons();
|
||||
appIcon = QIcon(":/rpcs3.ico");
|
||||
@@ -92,13 +93,6 @@ void main_window::Init()
|
||||
ui->toolBar->addSeparator();
|
||||
ui->toolBar->addWidget(ui->searchBar);
|
||||
|
||||
// for highdpi resize toolbar icons and height dynamically
|
||||
// choose factors to mimic Gui-Design in main_window.ui
|
||||
const int toolBarHeight = menuBar()->sizeHint().height() * 2;
|
||||
ui->toolBar->setIconSize(QSize(toolBarHeight, toolBarHeight));
|
||||
ui->sizeSliderContainer->setFixedWidth(toolBarHeight * 5);
|
||||
ui->sizeSlider->setFixedHeight(toolBarHeight * 0.625f);
|
||||
|
||||
CreateActions();
|
||||
CreateDockWindows();
|
||||
|
||||
@@ -111,15 +105,6 @@ void main_window::Init()
|
||||
|
||||
RequestGlobalStylesheetChange(guiSettings->GetCurrentStylesheetPath());
|
||||
ConfigureGuiFromSettings(true);
|
||||
|
||||
if (!utils::has_ssse3())
|
||||
{
|
||||
QMessageBox::critical(this, "SSSE3 Error (with three S, not two)",
|
||||
"Your system does not meet the minimum requirements needed to run RPCS3.\n"
|
||||
"Your CPU does not support SSSE3 (with three S, not two).\n");
|
||||
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void main_window::CreateThumbnailToolbar()
|
||||
@@ -461,19 +446,7 @@ void main_window::InstallPup()
|
||||
updatefilenames.begin(), updatefilenames.end(), [](std::string s) { return s.find("dev_flash_") == std::string::npos; }),
|
||||
updatefilenames.end());
|
||||
|
||||
std::string version_string = pup.get_file(0x100).to_string();
|
||||
version_string.erase(version_string.find('\n'));
|
||||
|
||||
const std::string cur_version = "4.81";
|
||||
|
||||
if (version_string < cur_version &&
|
||||
QMessageBox::question(this, tr("RPCS3 Firmware Installer"), tr("Old firmware detected.\nThe newest firmware version is %1 and you are trying to install version %2\nContinue installation?").arg(QString::fromStdString(cur_version), QString::fromStdString(version_string)),
|
||||
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::No)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QProgressDialog pdlg(tr("Installing firmware version %1\nPlease wait...").arg(QString::fromStdString(version_string)), tr("Cancel"), 0, static_cast<int>(updatefilenames.size()), this);
|
||||
QProgressDialog pdlg(tr("Installing firmware ... please wait ..."), tr("Cancel"), 0, static_cast<int>(updatefilenames.size()), this);
|
||||
pdlg.setWindowTitle(tr("RPCS3 Firmware Installer"));
|
||||
pdlg.setWindowModality(Qt::WindowModal);
|
||||
pdlg.setFixedSize(500, pdlg.height());
|
||||
@@ -559,7 +532,7 @@ void main_window::InstallPup()
|
||||
|
||||
if (progress > 0)
|
||||
{
|
||||
LOG_SUCCESS(GENERAL, "Successfully installed PS3 firmware version %s.", version_string);
|
||||
LOG_SUCCESS(GENERAL, "Successfully installed PS3 firmware.");
|
||||
guiSettings->ShowInfoBox(GUI::ib_pup_success, tr("Success!"), tr("Successfully installed PS3 firmware and LLE Modules!"), this);
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -729,8 +702,6 @@ void main_window::OnEmuPause()
|
||||
void main_window::OnEmuStop()
|
||||
{
|
||||
debuggerFrame->EnableButtons(false);
|
||||
debuggerFrame->ClearBreakpoints();
|
||||
|
||||
ui->sysPauseAct->setText(Emu.IsReady() ? tr("&Start\tCtrl+E") : tr("&Resume\tCtrl+E"));
|
||||
ui->sysPauseAct->setIcon(icon_play);
|
||||
#ifdef _WIN32
|
||||
@@ -1191,6 +1162,10 @@ void main_window::CreateConnects()
|
||||
gameListFrame->SetListMode(isList);
|
||||
categoryVisibleActGroup->setEnabled(isList);
|
||||
});
|
||||
connect(ui->toolBar, &QToolBar::visibilityChanged, [=](bool checked) {
|
||||
ui->showToolBarAct->setChecked(checked);
|
||||
guiSettings->SetValue(GUI::mw_toolBarVisible, checked);
|
||||
});
|
||||
connect(ui->toolbar_disc, &QAction::triggered, this, &main_window::BootGame);
|
||||
connect(ui->toolbar_refresh, &QAction::triggered, [=]() { gameListFrame->Refresh(true); });
|
||||
connect(ui->toolbar_stop, &QAction::triggered, [=]() { Emu.Stop(); });
|
||||
|
||||
@@ -56,7 +56,7 @@ class main_window : public QMainWindow
|
||||
#endif
|
||||
|
||||
public:
|
||||
explicit main_window(std::shared_ptr<gui_settings> guiSettings, QWidget *parent = 0);
|
||||
explicit main_window(QWidget *parent = 0);
|
||||
void Init();
|
||||
~main_window();
|
||||
void CreateThumbnailToolbar();
|
||||
|
||||
@@ -117,7 +117,7 @@ margin-left:14px;</string>
|
||||
<item>
|
||||
<widget class="QSlider" name="sizeSlider">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@@ -148,9 +148,6 @@ margin-left:14px;</string>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::PreventContextMenu</enum>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
<property name="title">
|
||||
<string>File</string>
|
||||
|
||||
@@ -8,9 +8,6 @@
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
#include <QColorDialog>
|
||||
#include <QSpinBox>
|
||||
#include <QApplication>
|
||||
#include <QDesktopWidget>
|
||||
|
||||
#include "settings_dialog.h"
|
||||
|
||||
@@ -112,32 +109,23 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> xSettings, const
|
||||
ui->ppu_fast->setToolTip(json_cpu_ppu["fast"].toString());
|
||||
ui->ppu_llvm->setToolTip(json_cpu_ppu["LLVM"].toString());
|
||||
|
||||
QButtonGroup *ppuBG = new QButtonGroup(this);
|
||||
ppuBG->addButton(ui->ppu_precise, (int)ppu_decoder_type::precise);
|
||||
ppuBG->addButton(ui->ppu_fast, (int)ppu_decoder_type::fast);
|
||||
ppuBG->addButton(ui->ppu_llvm, (int)ppu_decoder_type::llvm);
|
||||
|
||||
{ // PPU Stuff
|
||||
QString selectedPPU = qstr(xemu_settings->GetSetting(emu_settings::PPUDecoder));
|
||||
QStringList ppu_list = xemu_settings->GetSettingOptions(emu_settings::PPUDecoder);
|
||||
|
||||
for (int i = 0; i < ppu_list.count(); i++)
|
||||
for (const auto& button : ui->ppuBG->buttons())
|
||||
{
|
||||
ppuBG->button(i)->setText(ppu_list[i]);
|
||||
|
||||
if (ppu_list[i] == selectedPPU)
|
||||
QString current = button->text();
|
||||
button->setCheckable(true);
|
||||
if (current == selectedPPU)
|
||||
{
|
||||
ppuBG->button(i)->setChecked(true);
|
||||
button->setChecked(true);
|
||||
}
|
||||
|
||||
#ifndef LLVM_AVAILABLE
|
||||
if (ppu_list[i].toLower().contains("llvm"))
|
||||
if (current == "Recompiler (LLVM)")
|
||||
{
|
||||
ppuBG->button(i)->setEnabled(false);
|
||||
button->setEnabled(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
connect(ppuBG->button(i), &QAbstractButton::pressed, [=]() {xemu_settings->SetSetting(emu_settings::PPUDecoder, sstr(ppu_list[i])); });
|
||||
connect(button, &QAbstractButton::pressed, [=]() {xemu_settings->SetSetting(emu_settings::PPUDecoder, sstr(current)); });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,26 +135,21 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> xSettings, const
|
||||
ui->spu_asmjit->setToolTip(json_cpu_spu["ASMJIT"].toString());
|
||||
ui->spu_llvm->setToolTip(json_cpu_spu["LLVM"].toString());
|
||||
|
||||
QButtonGroup *spuBG = new QButtonGroup(this);
|
||||
spuBG->addButton(ui->spu_precise, (int)spu_decoder_type::precise);
|
||||
spuBG->addButton(ui->spu_fast, (int)spu_decoder_type::fast);
|
||||
spuBG->addButton(ui->spu_asmjit, (int)spu_decoder_type::asmjit);
|
||||
spuBG->addButton(ui->spu_llvm, (int)spu_decoder_type::llvm);
|
||||
|
||||
{ // Spu stuff
|
||||
QString selectedSPU = qstr(xemu_settings->GetSetting(emu_settings::SPUDecoder));
|
||||
QStringList spu_list = xemu_settings->GetSettingOptions(emu_settings::SPUDecoder);
|
||||
|
||||
for (int i = 0; i < spu_list.count(); i++)
|
||||
for (const auto& button : ui->spuBG->buttons())
|
||||
{
|
||||
spuBG->button(i)->setText(spu_list[i]);
|
||||
|
||||
if (spu_list[i] == selectedSPU)
|
||||
QString current = button->text();
|
||||
if (current == "Recompiler (LLVM)")
|
||||
{
|
||||
spuBG->button(i)->setChecked(true);
|
||||
button->setEnabled(false);
|
||||
}
|
||||
|
||||
connect(spuBG->button(i), &QAbstractButton::pressed, [=]() {xemu_settings->SetSetting(emu_settings::SPUDecoder, sstr(spu_list[i])); });
|
||||
button->setCheckable(true);
|
||||
if (current == selectedSPU)
|
||||
{
|
||||
button->setChecked(true);
|
||||
}
|
||||
connect(button, &QAbstractButton::pressed, [=]() {xemu_settings->SetSetting(emu_settings::SPUDecoder, sstr(current)); });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,25 +161,22 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> xSettings, const
|
||||
|
||||
// creating this in ui file keeps scrambling the order...
|
||||
QButtonGroup *libModeBG = new QButtonGroup(this);
|
||||
libModeBG->addButton(ui->lib_auto, (int)lib_loading_type::automatic);
|
||||
libModeBG->addButton(ui->lib_manu, (int)lib_loading_type::manual);
|
||||
libModeBG->addButton(ui->lib_both, (int)lib_loading_type::both);
|
||||
libModeBG->addButton(ui->lib_lv2, (int)lib_loading_type::liblv2only);
|
||||
libModeBG->addButton(ui->lib_auto, 0);
|
||||
libModeBG->addButton(ui->lib_manu, 1);
|
||||
libModeBG->addButton(ui->lib_both, 2);
|
||||
libModeBG->addButton(ui->lib_lv2, 3);
|
||||
|
||||
{// Handle lib loading options
|
||||
QString selectedLib = qstr(xemu_settings->GetSetting(emu_settings::LibLoadOptions));
|
||||
QStringList libmode_list = xemu_settings->GetSettingOptions(emu_settings::LibLoadOptions);
|
||||
|
||||
for (int i = 0; i < libmode_list.count(); i++)
|
||||
for (const auto& button : libModeBG->buttons())
|
||||
{
|
||||
libModeBG->button(i)->setText(libmode_list[i]);
|
||||
|
||||
if (libmode_list[i] == selectedLib)
|
||||
QString current = button->text();
|
||||
button->setCheckable(true);
|
||||
if (current == selectedLib)
|
||||
{
|
||||
libModeBG->button(i)->setChecked(true);
|
||||
button->setChecked(true);
|
||||
}
|
||||
|
||||
connect(libModeBG->button(i), &QAbstractButton::pressed, [=]() {xemu_settings->SetSetting(emu_settings::LibLoadOptions, sstr(libmode_list[i])); });
|
||||
connect(button, &QAbstractButton::pressed, [=]() {xemu_settings->SetSetting(emu_settings::LibLoadOptions, sstr(current)); });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,7 +225,7 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> xSettings, const
|
||||
|
||||
auto l_OnLibButtonClicked = [=](int ind)
|
||||
{
|
||||
if (ind == (int)lib_loading_type::manual || ind == (int)lib_loading_type::both)
|
||||
if (ind == 1 || ind == 2)
|
||||
{
|
||||
ui->searchBox->setEnabled(true);
|
||||
ui->lleList->setEnabled(true);
|
||||
@@ -753,37 +733,6 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> xSettings, const
|
||||
addColoredIcon(ui->pb_gl_tool_icon_color, xgui_settings->GetValue(GUI::gl_toolIconColor).value<QColor>(), QIcon(":/Icons/home_blue.png"), GUI::gl_tool_icon_color);
|
||||
addColoredIcon(ui->pb_tool_icon_color, xgui_settings->GetValue(GUI::mw_toolIconColor).value<QColor>(), QIcon(":/Icons/stop.png"), GUI::mw_tool_icon_color);
|
||||
|
||||
bool enableButtons = xgui_settings->GetValue(GUI::gs_resize).toBool();
|
||||
ui->gs_resizeOnBoot->setChecked(enableButtons);
|
||||
ui->gs_width->setEnabled(enableButtons);
|
||||
ui->gs_height->setEnabled(enableButtons);
|
||||
|
||||
QRect rec = QApplication::desktop()->screenGeometry();
|
||||
int width = xgui_settings->GetValue(GUI::gs_width).toInt();
|
||||
int height = xgui_settings->GetValue(GUI::gs_height).toInt();
|
||||
const int max_width = rec.width();
|
||||
const int max_height = rec.height();
|
||||
ui->gs_width->setValue(width < max_width ? width : max_width);
|
||||
ui->gs_height->setValue(height < max_height ? height : max_height);
|
||||
|
||||
connect(ui->gs_resizeOnBoot, &QCheckBox::clicked, [=](bool val) {
|
||||
xgui_settings->SetValue(GUI::gs_resize, val);
|
||||
ui->gs_width->setEnabled(val);
|
||||
ui->gs_height->setEnabled(val);
|
||||
});
|
||||
connect(ui->gs_width, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged), [=](int w) {
|
||||
int width = QApplication::desktop()->screenGeometry().width();
|
||||
w = w > width ? width : w;
|
||||
ui->gs_width->setValue(w);
|
||||
xgui_settings->SetValue(GUI::gs_width, w);
|
||||
});
|
||||
connect(ui->gs_height, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged), [=](int h) {
|
||||
int height = QApplication::desktop()->screenGeometry().height();
|
||||
h = h > height ? height : h;
|
||||
ui->gs_height->setValue(h);
|
||||
xgui_settings->SetValue(GUI::gs_height, h);
|
||||
});
|
||||
|
||||
AddConfigs();
|
||||
AddStylesheets();
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user