Linux changes (#3)

* WIP changes for linux

* Missing include.

* Thread names, file dialog, refresh rate detection changes.

---------

Co-authored-by: Mr-Wiseguy <mrwiseguyromhacking@gmail.com>
This commit is contained in:
Darío 2024-04-22 20:11:59 -03:00 committed by GitHub
parent 04a7aa2187
commit 404f38c806
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 109 additions and 28 deletions

View File

@ -331,7 +331,6 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
find_package(X11 REQUIRED)
target_include_directories(rt64 PUBLIC ${X11_INCLUDE_DIR})
target_link_libraries(rt64 ${X11_LIBRARIES})
target_link_libraries(rt64 ${PROJECT_SOURCE_DIR}/src/contrib/dxc/lib/x64/libdxcompiler.so)
endif()
preprocess_shader(rt64 "src/shaders/RasterPS.hlsl")

View File

@ -5,6 +5,7 @@
#include "rt64_thread.h"
#include <cassert>
#include <thread>
#if defined(_WIN64)
# include <Windows.h>

View File

@ -4,6 +4,7 @@
#pragma once
#include <cstdint>
#include <string>
namespace RT64 {

View File

@ -31,14 +31,22 @@ namespace RT64 {
CoTaskMemFree(knownPath);
# elif defined(__linux__)
const char *homedir;
if ((homedir = getenv("HOME")) == nullptr) {
homedir = getpwuid(getuid())->pw_dir;
const char *homeDir = getenv("HOME");
if (homeDir == nullptr) {
homeDir = getpwuid(getuid())->pw_dir;
}
if (homedir != nullptr) {
resultPath = std::filesystem::path{ homedir } / (std::string{ "." } + appId.c_str());
if (homeDir != nullptr) {
// Prefer to store in the .config directory if it exists. Use the home directory otherwise.
const std::string appDirName = std::string(".") + std::string(appId.c_str());
std::filesystem::path homePath = homeDir;
std::filesystem::path configPath = homePath / ".config";
if (std::filesystem::exists(configPath)) {
resultPath = configPath / appDirName;
}
else {
resultPath = homePath / appDirName;
}
}
# endif

@ -1 +1 @@
Subproject commit 2581d4244d227aa208b2339c98dd604b44a6d898
Subproject commit 333f91f8a85dead03a50efb08ffd96dc4ff1202a

View File

@ -1043,7 +1043,7 @@ namespace RT64 {
textureCache.useTexture(callTile.tmemHashOrID, workload.submissionFrame, textureIndex);
texture = textureCache.getTexture(textureIndex);
if (texture != nullptr) {
std::filesystem::path binFilename = FileDialog::getSaveFilename({ FileDialog::Filter(L"BIN Files", L"bin") });
std::filesystem::path binFilename = FileDialog::getSaveFilename({ FileFilter("BIN Files", "bin") });
if (!binFilename.empty()) {
std::ofstream o(binFilename, std::ios_base::out | std::ios_base::binary);
if (o.is_open()) {
@ -1328,7 +1328,7 @@ namespace RT64 {
bool vertexShaderButton = ImGui::Button("Dump Vertex Shader");
if (pixelShaderButton || vertexShaderButton) {
RasterShaderText shaderText = RasterShader::generateShaderText(call.shaderDesc, true);
std::filesystem::path shaderFilename = FileDialog::getSaveFilename({ FileDialog::Filter(L"HLSL", L"hlsl") });
std::filesystem::path shaderFilename = FileDialog::getSaveFilename({ FileFilter("HLSL", "hlsl") });
if (!shaderFilename.empty()) {
std::ofstream o(shaderFilename);
if (o.is_open()) {

View File

@ -4,6 +4,7 @@
#include "rt64_file_dialog.h"
#include <atomic>
#include <cassert>
#include <nfd.h>
@ -21,10 +22,10 @@ namespace RT64 {
NFD_Quit();
}
static std::vector<nfdnfilteritem_t> convertFilters(const std::vector<FileDialog::Filter> &filters) {
static std::vector<nfdnfilteritem_t> convertFilters(const std::vector<FileFilter> &filters) {
std::vector<nfdnfilteritem_t> nfdFilters;
for (const FileDialog::Filter &filter : filters) {
nfdFilters.emplace_back(nfdnfilteritem_t{ filter.first.c_str(), filter.second.c_str() });
for (const FileFilter &filter : filters) {
nfdFilters.emplace_back(nfdnfilteritem_t{ filter.description.c_str(), filter.extensions.c_str() });
}
return nfdFilters;
@ -45,7 +46,7 @@ namespace RT64 {
return path;
}
std::filesystem::path FileDialog::getOpenFilename(const std::vector<Filter> &filters) {
std::filesystem::path FileDialog::getOpenFilename(const std::vector<FileFilter> &filters) {
isOpen = true;
std::filesystem::path path;
@ -61,7 +62,7 @@ namespace RT64 {
return path;
}
std::filesystem::path FileDialog::getSaveFilename(const std::vector<Filter> &filters) {
std::filesystem::path FileDialog::getSaveFilename(const std::vector<FileFilter> &filters) {
isOpen = true;
std::filesystem::path path;

View File

@ -8,15 +8,38 @@
#include <filesystem>
#include <rhi/rt64_render_interface_types.h>
#ifdef _WIN32
# include <utf8conv/utf8conv.h>
#endif
namespace RT64 {
struct FileFilter {
#ifdef _WIN32
std::wstring description;
std::wstring extensions;
FileFilter(const std::string &description, const std::string &extensions) {
this->description = win32::Utf8ToUtf16(description);
this->extensions = win32::Utf8ToUtf16(extensions);
}
#else
std::string description;
std::string extensions;
FileFilter(const std::string &description, const std::string &extensions) {
this->description = description;
this->extensions = extensions;
}
#endif
};
struct FileDialog {
typedef std::pair<std::wstring, std::wstring> Filter;
static std::atomic<bool> isOpen;
static void initialize();
static void finish();
static std::filesystem::path getDirectoryPath();
static std::filesystem::path getOpenFilename(const std::vector<Filter> &filters);
static std::filesystem::path getSaveFilename(const std::vector<Filter> &filters);
static std::filesystem::path getOpenFilename(const std::vector<FileFilter> &filters);
static std::filesystem::path getSaveFilename(const std::vector<FileFilter> &filters);
};
};

View File

@ -259,6 +259,32 @@ namespace RT64 {
return refreshRate;
}
bool ApplicationWindow::detectWindowMoved() {
int32_t newWindowLeft = INT32_MAX;
int32_t newWindowTop = INT32_MAX;
# if defined(_WIN64)
RECT rect;
GetWindowRect(windowHandle, &rect);
newWindowLeft = rect.left;
newWindowTop = rect.top;
# elif defined(__linux__)
XWindowAttributes attributes;
XGetWindowAttributes(windowHandle.display, windowHandle.window, &attributes);
newWindowLeft = attributes.x;
newWindowTop = attributes.y;
# endif
if ((windowLeft != newWindowLeft) || (windowTop != newWindowTop)) {
windowLeft = newWindowLeft;
windowTop = newWindowTop;
return true;
}
else {
return false;
}
}
# ifdef _WIN32
void ApplicationWindow::windowMessage(UINT message, WPARAM wParam, LPARAM lParam) {
if (listener->windowMessageFilter(message, wParam, lParam)) {

View File

@ -42,6 +42,8 @@ namespace RT64 {
bool fullScreen;
bool lastMaximizedState;
bool usingSdl;
int32_t windowLeft = INT32_MAX;
int32_t windowTop = INT32_MAX;
ApplicationWindow();
~ApplicationWindow();
@ -51,6 +53,7 @@ namespace RT64 {
void makeResizable();
void detectRefreshRate();
uint32_t getRefreshRate() const;
bool detectWindowMoved();
# ifdef _WIN32
void windowMessage(UINT message, WPARAM wParam, LPARAM lParam);

View File

@ -426,7 +426,7 @@ namespace RT64 {
}
void PresentQueue::threadLoop() {
Thread::setCurrentThreadName("RT64 Present Queue");
Thread::setCurrentThreadName("RT64 Present");
int processCursor = -1;
bool skipPresent = false;
@ -456,8 +456,11 @@ namespace RT64 {
ext.presentGraphicsWorker->wait();
ext.swapChain->resize();
swapChainFramebuffers.clear();
ext.appWindow->detectRefreshRate();
ext.sharedResources->setSwapChainSize(ext.swapChain->getWidth(), ext.swapChain->getHeight());
}
if (needsResize || ext.appWindow->detectWindowMoved()) {
ext.appWindow->detectRefreshRate();
ext.sharedResources->setSwapChainRate(std::min(ext.appWindow->getRefreshRate(), displayTimingRate));
}

View File

@ -379,7 +379,7 @@ namespace RT64 {
curViewProjIndex = transformsIndex;
uint32_t physicalAddress = projectionMatrixPhysicalAddressStack[projectionMatrixStackSize - 1];
workload.physicalAddressTransformMap.emplace(physicalAddress, drawData.viewProjTransformGroups.size());
workload.physicalAddressTransformMap.emplace(physicalAddress, uint32_t(drawData.viewProjTransformGroups.size()));
drawData.viewTransforms.emplace_back(viewMatrixStack[projectionMatrixStackSize - 1]);
drawData.projTransforms.emplace_back(projMatrixStack[projectionMatrixStackSize - 1]);
drawData.viewProjTransforms.emplace_back(viewProjMatrixStack[projectionMatrixStackSize - 1]);
@ -435,7 +435,7 @@ namespace RT64 {
if (addWorldTransform) {
uint32_t physicalAddress = modelMatrixPhysicalAddressStack[modelMatrixStackSize - 1];
workload.physicalAddressTransformMap.emplace(physicalAddress, worldTransformGroups.size());
workload.physicalAddressTransformMap.emplace(physicalAddress, uint32_t(worldTransformGroups.size()));
worldTransformGroups.emplace_back(extended.curModelMatrixIdGroupIndex);
worldTransformSegmentedAddresses.emplace_back(modelMatrixSegmentedAddressStack[modelMatrixStackSize - 1]);
worldTransformPhysicalAddresses.emplace_back(physicalAddress);

View File

@ -1979,7 +1979,7 @@ namespace RT64 {
ext.rasterShaderCache->stopOfflineDumper();
}
else {
std::filesystem::path savePath = FileDialog::getSaveFilename({ FileDialog::Filter(L"BIN Files", L"bin") });
std::filesystem::path savePath = FileDialog::getSaveFilename({ FileFilter("BIN Files", "bin") });
if (!savePath.empty()) {
ext.rasterShaderCache->startOfflineDumper(savePath);
shaderCacheChanged = true;

View File

@ -789,7 +789,7 @@ namespace RT64 {
}
void WorkloadQueue::renderThreadLoop() {
Thread::setCurrentThreadName("RT64 Workload Queue");
Thread::setCurrentThreadName("RT64 Workload");
WorkloadConfiguration workloadConfig;
int64_t logicalTicks = 0;
@ -1087,7 +1087,7 @@ namespace RT64 {
//
// This workaround is not required if the driver is configured to be at the "Max Performance" power state.
Thread::setCurrentThreadName("RT64 Idle Worker");
Thread::setCurrentThreadName("RT64 Idle");
const ShaderRecord &idle = ext.shaderLibrary->idle;
RenderCommandList *commandList = ext.workloadGraphicsWorker->commandList.get();

View File

@ -102,7 +102,7 @@ namespace RT64 {
renameRequested = false;
}
const FileDialog::Filter jsonFilter(L"JSON", L"json");
const FileFilter jsonFilter("JSON", "json");
if (loadLibrary) {
libraryPath = FileDialog::getOpenFilename({ jsonFilter });
if (!libraryPath.empty()) {

View File

@ -3,6 +3,9 @@
//
#include <cstring>
#include "common/rt64_thread.h"
#include "rt64_buffer_uploader.h"
namespace RT64 {
@ -36,6 +39,8 @@ namespace RT64 {
}
void BufferUploader::threadLoop() {
Thread::setCurrentThreadName("RT64 Buffer");
running = true;
while (running) {

View File

@ -139,6 +139,8 @@ namespace RT64 {
}
void RasterShaderCache::CompilationThread::loop() {
Thread::setCurrentThreadName("RT64 Shader");
// The shader compilation thread should have the lowest priority by default as the application can use the ubershader in the meantime.
Thread::setCurrentThreadPriority(Thread::Priority::Lowest);

View File

@ -4,6 +4,7 @@
#include "xxHash/xxh3.h"
#include "common/rt64_thread.h"
#include "hle/rt64_workload_queue.h"
#include "rt64_texture_cache.h"
@ -213,6 +214,8 @@ namespace RT64 {
}
void TextureCache::uploadThreadLoop() {
Thread::setCurrentThreadName("RT64 Texture");
uploadThreadRunning = true;
std::vector<TextureUpload> queueCopy;

View File

@ -8,8 +8,9 @@
#include "rt64_vulkan.h"
#include <algorithm>
#include <unordered_map>
#include <cmath>
#include <climits>
#include <unordered_map>
#if DLSS_ENABLED
# include "render/rt64_dlss.h"
@ -3197,7 +3198,12 @@ namespace RT64 {
assert(fence != nullptr);
VulkanCommandFence *interfaceFence = static_cast<VulkanCommandFence *>(fence);
vkWaitForFences(device->vk, 1, &interfaceFence->vk, VK_TRUE, UINT64_MAX);
VkResult res = vkWaitForFences(device->vk, 1, &interfaceFence->vk, VK_TRUE, UINT64_MAX);
if (res != VK_SUCCESS) {
fprintf(stderr, "vkWaitForFences failed with error code 0x%X.\n", res);
return;
}
vkResetFences(device->vk, 1, &interfaceFence->vk);
}