diff --git a/Source/Editor/Scripting/CodeEditors/RiderCodeEditor.cpp b/Source/Editor/Scripting/CodeEditors/RiderCodeEditor.cpp index 8ce1c79bb..d5e65dedc 100644 --- a/Source/Editor/Scripting/CodeEditors/RiderCodeEditor.cpp +++ b/Source/Editor/Scripting/CodeEditors/RiderCodeEditor.cpp @@ -7,14 +7,14 @@ #include "Editor/ProjectInfo.h" #include "Editor/Scripting/ScriptsBuilder.h" #include "Engine/Engine/Globals.h" - -#if PLATFORM_WINDOWS - #include "Engine/Core/Collections/Sorting.h" #include "Engine/Platform/File.h" -#include "Engine/Platform/Win32/IncludeWindowsHeaders.h" #include "Engine/Serialization/Json.h" +#if PLATFORM_WINDOWS +#include "Engine/Platform/Win32/IncludeWindowsHeaders.h" +#endif + namespace { struct RiderInstallation @@ -28,22 +28,7 @@ namespace } }; - bool FindRegistryKeyItems(HKEY hKey, Array& results) - { - Char nameBuffer[256]; - for (int32 i = 0;; i++) - { - const LONG result = RegEnumKeyW(hKey, i, nameBuffer, ARRAY_COUNT(nameBuffer)); - if (result == ERROR_NO_MORE_ITEMS) - break; - if (result != ERROR_SUCCESS) - return false; - results.Add(nameBuffer); - } - return true; - } - - void SearchDirectory(Array* installations, const String& directory) + void SearchDirectory(Array* installations, const String& directory, String launchOverridePath = String::Empty) { if (!FileSystem::DirectoryExists(directory)) return; @@ -77,7 +62,26 @@ namespace if (!launcherPath.HasChars() || !FileSystem::FileExists(exePath)) return; - installations->Add(New(exePath, versionMember->value.GetText())); + if (launchOverridePath != String::Empty) + installations->Add(New(launchOverridePath, versionMember->value.GetText())); + else + installations->Add(New(exePath, versionMember->value.GetText())); + } + +#if PLATFORM_WINDOWS + bool FindRegistryKeyItems(HKEY hKey, Array& results) + { + Char nameBuffer[256]; + for (int32 i = 0;; i++) + { + const LONG result = RegEnumKeyW(hKey, i, nameBuffer, ARRAY_COUNT(nameBuffer)); + if (result == ERROR_NO_MORE_ITEMS) + break; + if (result != ERROR_SUCCESS) + return false; + results.Add(nameBuffer); + } + return true; } void SearchRegistry(Array* installations, HKEY root, const Char* key, const Char* valueName = TEXT("")) @@ -123,6 +127,7 @@ namespace RegCloseKey(keyH); } +#endif } bool sortInstallations(RiderInstallation* const& i1, RiderInstallation* const& i2) @@ -155,8 +160,6 @@ bool sortInstallations(RiderInstallation* const& i1, RiderInstallation* const& i return version1[0] > version2[0]; } -#endif - RiderCodeEditor::RiderCodeEditor(const String& execPath) : _execPath(execPath) , _solutionPath(Globals::ProjectFolder / Editor::Project->Name + TEXT(".sln")) @@ -165,17 +168,13 @@ RiderCodeEditor::RiderCodeEditor(const String& execPath) void RiderCodeEditor::FindEditors(Array* output) { -#if PLATFORM_WINDOWS Array installations; - - // Versions installed via JetBrains Toolbox - String localAppDataPath; Array subDirectories; - FileSystem::GetSpecialFolderPath(SpecialFolder::LocalAppData, localAppDataPath); - FileSystem::GetChildDirectories(subDirectories, localAppDataPath / TEXT("JetBrains\\Toolbox\\apps\\Rider\\ch-0\\")); - for (auto directory : subDirectories) - SearchDirectory(&installations, directory); + String localAppDataPath; + FileSystem::GetSpecialFolderPath(SpecialFolder::LocalAppData, localAppDataPath); + +#if PLATFORM_WINDOWS // Lookup from all known registry locations SearchRegistry(&installations, HKEY_CURRENT_USER, TEXT("SOFTWARE\\WOW6432Node\\JetBrains\\Rider for Unreal Engine")); SearchRegistry(&installations, HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\WOW6432Node\\JetBrains\\Rider for Unreal Engine")); @@ -186,6 +185,32 @@ void RiderCodeEditor::FindEditors(Array* output) SearchRegistry(&installations, HKEY_CURRENT_USER, TEXT("SOFTWARE\\WOW6432Node\\JetBrains\\JetBrains Rider")); SearchRegistry(&installations, HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\WOW6432Node\\JetBrains\\JetBrains Rider")); + // Versions installed via JetBrains Toolbox + FileSystem::GetChildDirectories(subDirectories, localAppDataPath / TEXT("JetBrains\\Toolbox\\apps\\Rider\\ch-0\\")); + FileSystem::GetChildDirectories(subDirectories, localAppDataPath / TEXT("JetBrains\\Toolbox\\apps\\Rider\\ch-1\\")); // Beta versions +#endif +#if PLATFORM_LINUX + // TODO: detect Snap installations + // TODO: detect by reading the jetbrains-rider.desktop file from ~/.local/share/applications and /usr/share/applications? + + FileSystem::GetChildDirectories(subDirectories, TEXT("/usr/share/rider")); + + // Default suggested location for standalone installations + FileSystem::GetChildDirectories(subDirectories, TEXT("/opt/")); + + // Versions installed via JetBrains Toolbox + FileSystem::GetChildDirectories(subDirectories, localAppDataPath / TEXT(".local/share/JetBrains/Toolbox/apps/Rider/ch-0")); + FileSystem::GetChildDirectories(subDirectories, localAppDataPath / TEXT(".local/share/JetBrains/Toolbox/apps/Rider/ch-1")); // Beta versions + + // Detect Flatpak installations + SearchDirectory(&installations, + TEXT("/var/lib/flatpak/app/com.jetbrains.Rider/current/active/files/extra/rider/"), + TEXT("flatpak run com.jetbrains.Rider")); +#endif + + for (auto directory : subDirectories) + SearchDirectory(&installations, directory); + // Sort found installations by version number Sorting::QuickSort(installations.Get(), installations.Count(), &sortInstallations); @@ -194,7 +219,6 @@ void RiderCodeEditor::FindEditors(Array* output) output->Add(New(installation->path)); Delete(installation); } -#endif } CodeEditorTypes RiderCodeEditor::GetType() const diff --git a/Source/Editor/Scripting/CodeEditors/VisualStudioCodeEditor.cpp b/Source/Editor/Scripting/CodeEditors/VisualStudioCodeEditor.cpp index e047b6e6f..1147c4ed8 100644 --- a/Source/Editor/Scripting/CodeEditors/VisualStudioCodeEditor.cpp +++ b/Source/Editor/Scripting/CodeEditors/VisualStudioCodeEditor.cpp @@ -70,6 +70,16 @@ void VisualStudioCodeEditor::FindEditors(Array* output) return; } } + + // Detect Flatpak installations + { + if (Platform::RunProcess(TEXT("/bin/bash -c \"flatpak list --app --columns=application | grep com.visualstudio.code -c\""), String::Empty) == 0) + { + const String runPath(TEXT("flatpak run com.visualstudio.code")); + output->Add(New(runPath, false)); + return; + } + } #endif } diff --git a/Source/Engine/Core/Log.cpp b/Source/Engine/Core/Log.cpp index ea24f5b27..6daf82e37 100644 --- a/Source/Engine/Core/Log.cpp +++ b/Source/Engine/Core/Log.cpp @@ -107,6 +107,8 @@ void Log::Logger::Write(const StringView& msg) { const auto ptr = msg.Get(); const auto length = msg.Length(); + if (length <= 0) + return; LogLocker.Lock(); if (IsDuringLog) @@ -230,6 +232,8 @@ void Log::Logger::ProcessLogMessage(LogType type, const StringView& msg, fmt_fla void Log::Logger::Write(LogType type, const StringView& msg) { + if (msg.Length() <= 0) + return; const bool isError = IsError(type); // Create message for the log file diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.cpp b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.cpp index 1b08c06ec..768cdd883 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.cpp @@ -277,7 +277,9 @@ bool GPUDeviceDX11::Init() && GetModuleHandleA("renderdoc.dll") == nullptr // Disable tearing with RenderDoc (prevents crashing) #endif ) - AllowTearing = true; + { + _allowTearing = true; + } } // Get flags and device type base on current configuration diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.h b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.h index ec2ba0177..5ecd685e6 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.h +++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUDeviceDX11.h @@ -20,7 +20,6 @@ class GPUDeviceDX11 : public GPUDeviceDX { friend GPUContextDX11; friend GPUSwapChainDX11; - private: // Private Stuff @@ -29,6 +28,7 @@ private: IDXGIFactory* _factoryDXGI; GPUContextDX11* _mainContext; + bool _allowTearing = false; // Static Samplers ID3D11SamplerState* _samplerLinearClamp; @@ -45,15 +45,10 @@ private: ID3D11DepthStencilState* DepthStencilStates[9 * 2 * 2]; // Index = ComparisonFunc[0-8] + DepthTestEnable[0?9] + DepthWriteEnable[0?18] public: - static GPUDevice* Create(); GPUDeviceDX11(IDXGIFactory* dxgiFactory, GPUAdapterDX* adapter); ~GPUDeviceDX11(); -public: - - bool AllowTearing = false; - public: // Gets DX11 device @@ -79,8 +74,6 @@ public: return _mainContext; } -public: - ID3D11BlendState* GetBlendState(const BlendingMode& blending); public: diff --git a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUSwapChainDX11.cpp b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUSwapChainDX11.cpp index 2986a15fd..4d8e1535e 100644 --- a/Source/Engine/GraphicsDevice/DirectX/DX11/GPUSwapChainDX11.cpp +++ b/Source/Engine/GraphicsDevice/DirectX/DX11/GPUSwapChainDX11.cpp @@ -16,9 +16,11 @@ GPUSwapChainDX11::GPUSwapChainDX11(GPUDeviceDX11* device, Window* window) , _windowHandle(static_cast(window->GetNativePtr())) #endif , _swapChain(nullptr) - , _backBuffer(nullptr) +#if PLATFORM_WINDOWS , _allowTearing(false) , _isFullscreen(false) +#endif + , _backBuffer(nullptr) { ASSERT(_windowHandle); _window = window; @@ -162,7 +164,7 @@ bool GPUSwapChainDX11::Resize(int32 width, int32 height) _device->WaitForGPU(); GPUDeviceLock lock(_device); #if PLATFORM_WINDOWS - _allowTearing = _device->AllowTearing; + _allowTearing = _device->_allowTearing; #endif _format = GPU_BACK_BUFFER_PIXEL_FORMAT; diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUBufferVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUBufferVulkan.cpp index 6ebfb239a..6e4301c39 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUBufferVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUBufferVulkan.cpp @@ -25,7 +25,8 @@ void GPUBufferViewVulkan::Init(GPUDeviceVulkan* device, GPUBufferVulkan* owner, viewInfo.format = RenderToolsVulkan::ToVulkanFormat(format); viewInfo.offset = 0; viewInfo.range = Size; - ASSERT_LOW_LAYER(viewInfo.format != VK_FORMAT_UNDEFINED); + if (viewInfo.format == VK_FORMAT_UNDEFINED) + return; // Skip for structured buffers that use custom structure type and have unknown format VALIDATE_VULKAN_RESULT(vkCreateBufferView(device->Device, &viewInfo, nullptr, &View)); } } diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp index 702c8afaa..bc768f64c 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUContextVulkan.cpp @@ -1309,6 +1309,11 @@ void GPUContextVulkan::UpdateBuffer(GPUBuffer* buffer, const void* data, uint32 const auto bufferVulkan = static_cast(buffer); + // Memory transfer barrier + // TODO: batch pipeline barriers + const VkMemoryBarrier barrierBefore = { VK_STRUCTURE_TYPE_MEMORY_BARRIER, nullptr, VK_ACCESS_MEMORY_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT }; + vkCmdPipelineBarrier(cmdBuffer->GetHandle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &barrierBefore, 0, nullptr, 0, nullptr); + // Use direct update for small buffers if (size <= 16 * 1024) { @@ -1331,6 +1336,11 @@ void GPUContextVulkan::UpdateBuffer(GPUBuffer* buffer, const void* data, uint32 _device->StagingManager.ReleaseBuffer(cmdBuffer, staging); } + + // Memory transfer barrier + // TODO: batch pipeline barriers + const VkMemoryBarrier barrierAfter = { VK_STRUCTURE_TYPE_MEMORY_BARRIER, nullptr, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT }; + vkCmdPipelineBarrier(cmdBuffer->GetHandle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 1, &barrierAfter, 0, nullptr, 0, nullptr); } void GPUContextVulkan::CopyBuffer(GPUBuffer* dstBuffer, GPUBuffer* srcBuffer, uint32 size, uint32 dstOffset, uint32 srcOffset) diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUSwapChainVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUSwapChainVulkan.cpp index 4c719844f..b16fe6caa 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUSwapChainVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUSwapChainVulkan.cpp @@ -195,6 +195,7 @@ bool GPUSwapChainVulkan::CreateSwapChain(int32 width, int32 height) LOG(Warning, "Failed to create Vulkan surface."); return true; } + _memoryUsage = 1; const auto& gpu = _device->Adapter->Gpu; diff --git a/Source/Engine/Particles/Particles.cpp b/Source/Engine/Particles/Particles.cpp index 042eaa7d8..5a7e776bc 100644 --- a/Source/Engine/Particles/Particles.cpp +++ b/Source/Engine/Particles/Particles.cpp @@ -702,7 +702,6 @@ void DrawEmitterGPU(RenderContext& renderContext, ParticleBuffer* buffer, DrawCa // TODO: model LOD picking for particles? int32 lodIndex = 0; ModelLOD& lod = model->LODs[lodIndex]; - drawCalls += lod.Meshes.Count(); for (int32 meshIndex = 0; meshIndex < lod.Meshes.Count(); meshIndex++) { Mesh& mesh = lod.Meshes[meshIndex]; diff --git a/Source/Engine/Platform/Linux/LinuxWindow.cpp b/Source/Engine/Platform/Linux/LinuxWindow.cpp index 3439fa15d..cabdcd46d 100644 --- a/Source/Engine/Platform/Linux/LinuxWindow.cpp +++ b/Source/Engine/Platform/Linux/LinuxWindow.cpp @@ -6,7 +6,6 @@ #include "Engine/Input/Input.h" #include "Engine/Input/Mouse.h" #include "Engine/Input/Keyboard.h" -#include "Engine/Engine/Engine.h" #include "Engine/Core/Log.h" #include "Engine/Core/Math/Math.h" #include "Engine/Core/Math/Color32.h" @@ -14,9 +13,7 @@ #include "Engine/Core/Collections/Array.h" #include "Engine/Core/Collections/Dictionary.h" #include "Engine/Utilities/StringConverter.h" -#include "Engine/Utilities/StringConverter.h" #include "Engine/Graphics/RenderTask.h" -#include "Engine/Graphics/GPUSwapChain.h" #include "Engine/Graphics/Textures/TextureData.h" // hack using TextureTool in Platform module -> TODO: move texture data sampling to texture data itself #define COMPILE_WITH_TEXTURE_TOOL 1 @@ -207,7 +204,7 @@ LinuxWindow::LinuxWindow(const CreateWindowSettings& settings) X11::Atom wmSateSkipTaskbar = X11::XInternAtom(display, "_NET_WM_STATE_SKIP_TASKBAR", 0); X11::Atom wmStateSkipPager = X11::XInternAtom(display, "_NET_WM_STATE_SKIP_PAGER", 0); X11::Atom wmStateFullscreen = X11::XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", 0); - X11::Atom states[2]; + X11::Atom states[4]; int32 statesCount = 0; if (settings.IsTopmost) {