Merge remote-tracking branch 'origin/master' into 1.7

This commit is contained in:
Wojtek Figat
2023-09-20 16:02:48 +02:00
59 changed files with 576 additions and 217 deletions

View File

@@ -3,7 +3,7 @@
"Version": {
"Major": 1,
"Minor": 6,
"Build": 6344
"Build": 6345
},
"Company": "Flax",
"Copyright": "Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.",

View File

@@ -5,6 +5,7 @@
#include "MacPlatformTools.h"
#include "Engine/Platform/File.h"
#include "Engine/Platform/FileSystem.h"
#include "Engine/Platform/CreateProcessSettings.h"
#include "Engine/Platform/Mac/MacPlatformSettings.h"
#include "Engine/Core/Config/GameSettings.h"
#include "Engine/Core/Config/BuildSettings.h"
@@ -124,17 +125,35 @@ bool MacPlatformTools::OnPostProcess(CookingData& data)
LOG(Error, "Failed to export application icon.");
return true;
}
bool failed = Platform::RunProcess(TEXT("sips -z 16 16 icon_1024x1024.png --out icon_16x16.png"), tmpFolderPath);
failed |= Platform::RunProcess(TEXT("sips -z 32 32 icon_1024x1024.png --out icon_16x16@2x.png"), tmpFolderPath);
failed |= Platform::RunProcess(TEXT("sips -z 32 32 icon_1024x1024.png --out icon_32x32.png"), tmpFolderPath);
failed |= Platform::RunProcess(TEXT("sips -z 64 64 icon_1024x1024.png --out icon_32x32@2x.png"), tmpFolderPath);
failed |= Platform::RunProcess(TEXT("sips -z 128 128 icon_1024x1024.png --out icon_128x128.png"), tmpFolderPath);
failed |= Platform::RunProcess(TEXT("sips -z 256 256 icon_1024x1024.png --out icon_128x128@2x.png"), tmpFolderPath);
failed |= Platform::RunProcess(TEXT("sips -z 256 256 icon_1024x1024.png --out icon_256x256.png"), tmpFolderPath);
failed |= Platform::RunProcess(TEXT("sips -z 512 512 icon_1024x1024.png --out icon_256x256@2x.png"), tmpFolderPath);
failed |= Platform::RunProcess(TEXT("sips -z 512 512 icon_1024x1024.png --out icon_512x512.png"), tmpFolderPath);
failed |= Platform::RunProcess(TEXT("sips -z 1024 1024 icon_1024x1024.png --out icon_512x512@2x.png"), tmpFolderPath);
failed |= Platform::RunProcess(TEXT("iconutil -c icns icon.iconset"), iconFolderPath);
CreateProcessSettings procSettings;
procSettings.HiddenWindow = true;
procSettings.FileName = TEXT("/usr/bin/sips");
procSettings.WorkingDirectory = tmpFolderPath;
procSettings.Arguments = TEXT("-z 16 16 icon_1024x1024.png --out icon_16x16.png");
bool failed = false;
failed |= Platform::CreateProcess(procSettings);
procSettings.Arguments = TEXT("-z 32 32 icon_1024x1024.png --out icon_16x16@2x.png");
failed |= Platform::CreateProcess(procSettings);
procSettings.Arguments = TEXT("-z 32 32 icon_1024x1024.png --out icon_32x32.png");
failed |= Platform::CreateProcess(procSettings);
procSettings.Arguments = TEXT("-z 64 64 icon_1024x1024.png --out icon_32x32@2x.png");
failed |= Platform::CreateProcess(procSettings);
procSettings.Arguments = TEXT("-z 128 128 icon_1024x1024.png --out icon_128x128.png");
failed |= Platform::CreateProcess(procSettings);
procSettings.Arguments = TEXT("-z 256 256 icon_1024x1024.png --out icon_128x128@2x.png");
failed |= Platform::CreateProcess(procSettings);
procSettings.Arguments = TEXT("-z 256 256 icon_1024x1024.png --out icon_256x256.png");
failed |= Platform::CreateProcess(procSettings);
procSettings.Arguments = TEXT("-z 512 512 icon_1024x1024.png --out icon_256x256@2x.png");
failed |= Platform::CreateProcess(procSettings);
procSettings.Arguments = TEXT("-z 512 512 icon_1024x1024.png --out icon_512x512.png");
failed |= Platform::CreateProcess(procSettings);
procSettings.Arguments = TEXT("-z 1024 1024 icon_1024x1024.png --out icon_512x512@2x.png");
failed |= Platform::CreateProcess(procSettings);
procSettings.FileName = TEXT("/usr/bin/iconutil");
procSettings.Arguments = TEXT("-c icns icon.iconset");
procSettings.WorkingDirectory = iconFolderPath;
failed |= Platform::CreateProcess(procSettings);
if (failed)
{
LOG(Error, "Failed to export application icon.");
@@ -210,16 +229,22 @@ bool MacPlatformTools::OnPostProcess(CookingData& data)
return false;
GameCooker::PackageFiles();
LOG(Info, "Building app package...");
const String dmgPath = data.OriginalOutputPath / appName + TEXT(".dmg");
const String dmgCommand = String::Format(TEXT("hdiutil create {0}.dmg -volname {0} -fs HFS+ -srcfolder {0}.app"), appName);
const int32 result = Platform::RunProcess(dmgCommand, data.OriginalOutputPath);
if (result != 0)
{
data.Error(String::Format(TEXT("Failed to package app (result code: {0}). See log for more info."), result));
return true;
const String dmgPath = data.OriginalOutputPath / appName + TEXT(".dmg");
CreateProcessSettings procSettings;
procSettings.HiddenWindow = true;
procSettings.WorkingDirectory = data.OriginalOutputPath;
procSettings.FileName = TEXT("/usr/bin/hdiutil");
procSettings.Arguments = String::Format(TEXT("create {0}.dmg -volname {0} -fs HFS+ -srcfolder {0}.app"), appName);
const int32 result = Platform::CreateProcess(procSettings);
if (result != 0)
{
data.Error(String::Format(TEXT("Failed to package app (result code: {0}). See log for more info."), result));
return true;
}
// TODO: sign dmg
LOG(Info, "Output application package: {0} (size: {1} MB)", dmgPath, FileSystem::GetFileSize(dmgPath) / 1024 / 1024);
}
// TODO: sign dmg
LOG(Info, "Output application package: {0} (size: {1} MB)", dmgPath, FileSystem::GetFileSize(dmgPath) / 1024 / 1024);
return false;
}

View File

@@ -545,7 +545,7 @@ namespace FlaxEditor.GUI
Render2D.DrawRectangle(clientRect.MakeExpanded(-2.0f), borderColor);
// Check if has selected item
if (_selectedIndices.Count > 0)
if (_selectedIndices != null && _selectedIndices.Count > 0)
{
string text = _selectedIndices.Count == 1 ? _items[_selectedIndices[0]] : "Multiple Values";

View File

@@ -246,20 +246,17 @@ bool ScriptsBuilder::RunBuildTool(const StringView& args, const StringView& work
Log::FileNotFoundException(monoPath).SetLevel(LogType::Fatal);
return true;
}
//const String monoPath = TEXT("mono");
cmdLine.Append(TEXT("\""));
const String monoPath = TEXT("mono");
cmdLine.Append(monoPath);
cmdLine.Append(TEXT("\" "));
cmdLine.Append(TEXT(" "));
// TODO: Set env var for the mono MONO_GC_PARAMS=nursery-size64m to boost build performance -> profile it
#endif
cmdLine.Append(TEXT("\""));
cmdLine.Append(buildToolPath);
cmdLine.Append(TEXT("\" "));
cmdLine.Append(args.Get(), args.Length());
// Call build tool
CreateProcessSettings procSettings;
procSettings.FileName = StringView(*cmdLine, cmdLine.Length());
procSettings.Arguments = args.Get();
procSettings.WorkingDirectory = workingDir;
const int32 result = Platform::CreateProcess(procSettings);
if (result != 0)

View File

@@ -1,6 +1,7 @@
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
using System;
using System.IO;
using FlaxEngine;
using FlaxEngine.Utilities;
@@ -54,6 +55,13 @@ namespace FlaxEditor.States
}
else if (Editor.Options.Options.General.ForceScriptCompilationOnStartup && !skipCompile)
{
// Generate project files when Cache is missing or was cleared previously
if (!Directory.Exists(Path.Combine(Editor.GameProject?.ProjectFolderPath, "Cache", "Intermediate")) ||
!Directory.Exists(Path.Combine(Editor.GameProject?.ProjectFolderPath, "Cache", "Projects")))
{
var customArgs = Editor.Instance.CodeEditing.SelectedEditor.GenerateProjectCustomArgs;
ScriptsBuilder.GenerateProject(customArgs);
}
// Compile scripts before loading any scenes, then we load them and can open scenes
ScriptsBuilder.Compile();
}

View File

@@ -223,10 +223,10 @@ void Log::Logger::ProcessLogMessage(LogType type, const StringView& msg, fmt_fla
else
{
//w.append(msg.Get(), msg.Get() + msg.Length());
fmt_flax::format(w, TEXT("{}"), (const Char*)msg.Get());
fmt_flax::format(w, TEXT("{}"), msg);
}
#else
fmt_flax::format(w, TEXT("{}"), (const Char*)msg.Get());
fmt_flax::format(w, TEXT("{}"), msg);
#endif
}

View File

@@ -559,6 +559,19 @@ namespace FlaxEngine.Interop
return managedArray.Pointer;
}
[UnmanagedCallersOnly]
internal static IntPtr GetArray(ManagedHandle handle)
{
if (!handle.IsAllocated)
return IntPtr.Zero;
object value = handle.Target;
if (value is ManagedArray)
return (IntPtr)handle;
if (value is Array)
return Invoker.MarshalReturnValueGeneric(value.GetType(), value);
return IntPtr.Zero;
}
[UnmanagedCallersOnly]
internal static int GetArrayLength(ManagedHandle arrayHandle)
{

View File

@@ -76,11 +76,11 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
// Set reflection probe data
EnvironmentProbe* probe = nullptr;
// TODO: optimize env probe searching for a transparent material - use spatial cache for renderer to find it
const Vector3 drawCallOrigin = drawCall.ObjectPosition + view.Origin;
const BoundingSphere objectBoundsWorld(drawCall.ObjectPosition + view.Origin, drawCall.ObjectRadius);
for (int32 i = 0; i < cache->EnvironmentProbes.Count(); i++)
{
const auto p = cache->EnvironmentProbes[i];
if (p->GetSphere().Contains(drawCallOrigin) != ContainmentType::Disjoint)
if (CollisionsHelper::SphereIntersectsSphere(objectBoundsWorld, p->GetSphere()))
{
probe = p;
break;
@@ -99,10 +99,12 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
// Set local lights
data.LocalLightsCount = 0;
const BoundingSphere objectBounds(drawCall.ObjectPosition, drawCall.ObjectRadius);
// TODO: optimize lights searching for a transparent material - use spatial cache for renderer to find it
for (int32 i = 0; i < cache->PointLights.Count() && data.LocalLightsCount < MaxLocalLights; i++)
{
const auto& light = cache->PointLights[i];
if (BoundingSphere(light.Position, light.Radius).Contains(drawCall.ObjectPosition) != ContainmentType::Disjoint)
if (CollisionsHelper::SphereIntersectsSphere(objectBounds, BoundingSphere(light.Position, light.Radius)))
{
light.SetupLightData(&data.LocalLights[data.LocalLightsCount], false);
data.LocalLightsCount++;
@@ -111,7 +113,7 @@ void ForwardShadingFeature::Bind(MaterialShader::BindParameters& params, Span<by
for (int32 i = 0; i < cache->SpotLights.Count() && data.LocalLightsCount < MaxLocalLights; i++)
{
const auto& light = cache->SpotLights[i];
if (BoundingSphere(light.Position, light.Radius).Contains(drawCall.ObjectPosition) != ContainmentType::Disjoint)
if (CollisionsHelper::SphereIntersectsSphere(objectBounds, BoundingSphere(light.Position, light.Radius)))
{
light.SetupLightData(&data.LocalLights[data.LocalLightsCount], false);
data.LocalLightsCount++;

View File

@@ -410,6 +410,7 @@ void Mesh::Draw(const RenderContext& renderContext, MaterialBase* material, cons
drawCall.Material = material;
drawCall.World = world;
drawCall.ObjectPosition = drawCall.World.GetTranslation();
drawCall.ObjectRadius = _sphere.Radius * drawCall.World.GetScaleVector().GetAbsolute().MaxValue();
drawCall.Surface.GeometrySize = _box.GetSize();
drawCall.Surface.PrevWorld = world;
drawCall.Surface.Lightmap = nullptr;
@@ -481,6 +482,7 @@ void Mesh::Draw(const RenderContext& renderContext, const DrawInfo& info, float
drawCall.Material = material;
drawCall.World = *info.World;
drawCall.ObjectPosition = drawCall.World.GetTranslation();
drawCall.ObjectRadius = info.Bounds.Radius; // TODO: should it be kept in sync with ObjectPosition?
drawCall.Surface.GeometrySize = _box.GetSize();
drawCall.Surface.PrevWorld = info.DrawState->PrevWorld;
drawCall.Surface.Lightmap = (info.Flags & StaticFlags::Lightmap) != StaticFlags::None ? info.Lightmap : nullptr;
@@ -546,6 +548,7 @@ void Mesh::Draw(const RenderContextBatch& renderContextBatch, const DrawInfo& in
drawCall.Material = material;
drawCall.World = *info.World;
drawCall.ObjectPosition = drawCall.World.GetTranslation();
drawCall.ObjectRadius = info.Bounds.Radius; // TODO: should it be kept in sync with ObjectPosition?
drawCall.Surface.GeometrySize = _box.GetSize();
drawCall.Surface.PrevWorld = info.DrawState->PrevWorld;
drawCall.Surface.Lightmap = (info.Flags & StaticFlags::Lightmap) != StaticFlags::None ? info.Lightmap : nullptr;

View File

@@ -188,6 +188,7 @@ void SkinnedMesh::Draw(const RenderContext& renderContext, const DrawInfo& info,
drawCall.Material = material;
drawCall.World = *info.World;
drawCall.ObjectPosition = drawCall.World.GetTranslation();
drawCall.ObjectRadius = info.Bounds.Radius; // TODO: should it be kept in sync with ObjectPosition?
drawCall.Surface.GeometrySize = _box.GetSize();
drawCall.Surface.PrevWorld = info.DrawState->PrevWorld;
drawCall.Surface.Lightmap = nullptr;
@@ -236,6 +237,7 @@ void SkinnedMesh::Draw(const RenderContextBatch& renderContextBatch, const DrawI
drawCall.Material = material;
drawCall.World = *info.World;
drawCall.ObjectPosition = drawCall.World.GetTranslation();
drawCall.ObjectRadius = info.Bounds.Radius; // TODO: should it be kept in sync with ObjectPosition?
drawCall.Surface.GeometrySize = _box.GetSize();
drawCall.Surface.PrevWorld = info.DrawState->PrevWorld;
drawCall.Surface.Lightmap = nullptr;

View File

@@ -120,7 +120,7 @@ bool GPUShader::Create(MemoryReadStream& stream)
GPUShaderProgram* shader = CreateGPUShaderProgram(type, initializer, cache, cacheSize, stream);
if (shader == nullptr)
{
LOG(Warning, "Failed to create shader program.");
LOG(Error, "Failed to create {} Shader program '{}'.", ::ToString(type), String(initializer.Name));
return true;
}

View File

@@ -105,7 +105,7 @@ bool GPUBufferDX11::OnInit()
data.SysMemPitch = bufferDesc.ByteWidth;
data.SysMemSlicePitch = 0;
}
VALIDATE_DIRECTX_RESULT(_device->GetDevice()->CreateBuffer(&bufferDesc, _desc.InitData ? &data : nullptr, &_resource));
VALIDATE_DIRECTX_CALL(_device->GetDevice()->CreateBuffer(&bufferDesc, _desc.InitData ? &data : nullptr, &_resource));
// Set state
DX_SET_DEBUG_NAME(_resource, GetName());
@@ -135,7 +135,7 @@ bool GPUBufferDX11::OnInit()
srvDesc.Buffer.NumElements = numElements;
}
ID3D11ShaderResourceView* srv;
VALIDATE_DIRECTX_RESULT(_device->GetDevice()->CreateShaderResourceView(_resource, &srvDesc, &srv));
VALIDATE_DIRECTX_CALL(_device->GetDevice()->CreateShaderResourceView(_resource, &srvDesc, &srv));
_view.SetSRV(srv);
}
if (useUAV)
@@ -156,7 +156,7 @@ bool GPUBufferDX11::OnInit()
else
uavDesc.Format = RenderToolsDX::ToDxgiFormat(PixelFormatExtensions::FindUnorderedAccessFormat(_desc.Format));
ID3D11UnorderedAccessView* uav;
VALIDATE_DIRECTX_RESULT(_device->GetDevice()->CreateUnorderedAccessView(_resource, &uavDesc, &uav));
VALIDATE_DIRECTX_CALL(_device->GetDevice()->CreateUnorderedAccessView(_resource, &uavDesc, &uav));
_view.SetUAV(uav);
}

View File

@@ -143,7 +143,7 @@ GPUDevice* GPUDeviceDX11::Create()
if (tempAdapter && TryCreateDevice(tempAdapter, maxAllowedFeatureLevel, &adapter.MaxFeatureLevel))
{
adapter.Index = index;
VALIDATE_DIRECTX_RESULT(tempAdapter->GetDesc(&adapter.Description));
VALIDATE_DIRECTX_CALL(tempAdapter->GetDesc(&adapter.Description));
uint32 outputs = RenderToolsDX::CountAdapterOutputs(tempAdapter);
LOG(Info, "Adapter {1}: '{0}', DirectX {2}", adapter.Description.Description, index, RenderToolsDX::GetFeatureLevelString(adapter.MaxFeatureLevel));
@@ -163,7 +163,7 @@ GPUDevice* GPUDeviceDX11::Create()
if (tempAdapter && TryCreateDevice(tempAdapter, maxAllowedFeatureLevel, &adapter.MaxFeatureLevel))
{
DXGI_ADAPTER_DESC desc;
VALIDATE_DIRECTX_RESULT(tempAdapter->GetDesc(&desc));
VALIDATE_DIRECTX_CALL(tempAdapter->GetDesc(&desc));
for (int i = 0; i < adapters.Count(); i++)
{
if (adapters[i].Description.AdapterLuid.LowPart == desc.AdapterLuid.LowPart &&
@@ -274,7 +274,7 @@ ID3D11BlendState* GPUDeviceDX11::GetBlendState(const BlendingMode& blending)
#endif
// Create object
VALIDATE_DIRECTX_RESULT(_device->CreateBlendState(&desc, &blendState));
VALIDATE_DIRECTX_CALL(_device->CreateBlendState(&desc, &blendState));
// Cache blend state
BlendStates.Add(blending, blendState);
@@ -333,7 +333,7 @@ bool GPUDeviceDX11::Init()
// Create DirectX device
D3D_FEATURE_LEVEL createdFeatureLevel = static_cast<D3D_FEATURE_LEVEL>(0);
auto targetFeatureLevel = GetD3DFeatureLevel();
VALIDATE_DIRECTX_RESULT(D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, flags, &targetFeatureLevel, 1, D3D11_SDK_VERSION, &_device, &createdFeatureLevel, &_imContext));
VALIDATE_DIRECTX_CALL(D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, flags, &targetFeatureLevel, 1, D3D11_SDK_VERSION, &_device, &createdFeatureLevel, &_imContext));
// Validate result
ASSERT(_device);
@@ -409,7 +409,7 @@ bool GPUDeviceDX11::Init()
// Init debug layer
#if GPU_ENABLE_DIAGNOSTICS
ComPtr<ID3D11InfoQueue> infoQueue;
VALIDATE_DIRECTX_RESULT(_device->QueryInterface(IID_PPV_ARGS(&infoQueue)));
VALIDATE_DIRECTX_CALL(_device->QueryInterface(IID_PPV_ARGS(&infoQueue)));
if (infoQueue)
{
D3D11_INFO_QUEUE_FILTER filter;
@@ -457,7 +457,7 @@ bool GPUDeviceDX11::Init()
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
result = _device->CreateSamplerState(&samplerDesc, &_samplerLinearClamp);
LOG_DIRECTX_RESULT_WITH_RETURN(result);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
// Point Clamp
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
@@ -467,7 +467,7 @@ bool GPUDeviceDX11::Init()
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
result = _device->CreateSamplerState(&samplerDesc, &_samplerPointClamp);
LOG_DIRECTX_RESULT_WITH_RETURN(result);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
// Linear Wrap
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
@@ -477,7 +477,7 @@ bool GPUDeviceDX11::Init()
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
result = _device->CreateSamplerState(&samplerDesc, &_samplerLinearWrap);
LOG_DIRECTX_RESULT_WITH_RETURN(result);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
// Point Wrap
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
@@ -487,7 +487,7 @@ bool GPUDeviceDX11::Init()
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
result = _device->CreateSamplerState(&samplerDesc, &_samplerPointWrap);
LOG_DIRECTX_RESULT_WITH_RETURN(result);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
// Shadow
samplerDesc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT;
@@ -500,7 +500,7 @@ bool GPUDeviceDX11::Init()
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
result = _device->CreateSamplerState(&samplerDesc, &_samplerShadow);
LOG_DIRECTX_RESULT_WITH_RETURN(result);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
// Shadow PCF
samplerDesc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR;
@@ -514,7 +514,7 @@ bool GPUDeviceDX11::Init()
samplerDesc.MinLOD = 0;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
result = _device->CreateSamplerState(&samplerDesc, &_samplerShadowPCF);
LOG_DIRECTX_RESULT_WITH_RETURN(result);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
}
// Rasterizer States
@@ -534,7 +534,7 @@ bool GPUDeviceDX11::Init()
rDesc.AntialiasedLineEnable = !!wireframe; \
rDesc.DepthClipEnable = !!depthClip; \
result = _device->CreateRasterizerState(&rDesc, &RasterizerStates[index]); \
LOG_DIRECTX_RESULT_WITH_RETURN(result)
LOG_DIRECTX_RESULT_WITH_RETURN(result, true)
CREATE_RASTERIZER_STATE(CullMode::Normal, D3D11_CULL_BACK, false, false);
CREATE_RASTERIZER_STATE(CullMode::Inverted, D3D11_CULL_FRONT, false, false);
CREATE_RASTERIZER_STATE(CullMode::TwoSided, D3D11_CULL_NONE, false, false);
@@ -568,7 +568,7 @@ bool GPUDeviceDX11::Init()
dsDesc.DepthFunc = (D3D11_COMPARISON_FUNC)depthFunc; \
index = (int32)depthFunc + (depthEnable ? 0 : 9) + (depthWrite ? 0 : 18); \
HRESULT result = _device->CreateDepthStencilState(&dsDesc, &DepthStencilStates[index]); \
LOG_DIRECTX_RESULT_WITH_RETURN(result); }
LOG_DIRECTX_RESULT_WITH_RETURN(result, true); }
CREATE_DEPTH_STENCIL_STATE(false, false);
CREATE_DEPTH_STENCIL_STATE(false, true);
CREATE_DEPTH_STENCIL_STATE(true, true);
@@ -666,7 +666,7 @@ void GPUDeviceDX11::DrawEnd()
#if GPU_ENABLE_DIAGNOSTICS
// Flush debug messages queue
ComPtr<ID3D11InfoQueue> infoQueue;
VALIDATE_DIRECTX_RESULT(_device->QueryInterface(IID_PPV_ARGS(&infoQueue)));
VALIDATE_DIRECTX_CALL(_device->QueryInterface(IID_PPV_ARGS(&infoQueue)));
if (infoQueue)
{
Array<uint8> data;

View File

@@ -106,7 +106,7 @@ bool GPUSamplerDX11::OnInit()
samplerDesc.MinLOD = _desc.MinMipLevel;
samplerDesc.MaxLOD = _desc.MaxMipLevel;
HRESULT result = _device->GetDevice()->CreateSamplerState(&samplerDesc, &SamplerState);
LOG_DIRECTX_RESULT_WITH_RETURN(result);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
ASSERT(SamplerState != nullptr);
_memoryUsage = sizeof(D3D11_SAMPLER_DESC);

View File

@@ -10,6 +10,7 @@
GPUShaderProgram* GPUShaderDX11::CreateGPUShaderProgram(ShaderStage type, const GPUShaderProgramInitializer& initializer, byte* cacheBytes, uint32 cacheSize, MemoryReadStream& stream)
{
GPUShaderProgram* shader = nullptr;
HRESULT result;
switch (type)
{
case ShaderStage::Vertex:
@@ -90,12 +91,13 @@ GPUShaderProgram* GPUShaderDX11::CreateGPUShaderProgram(ShaderStage type, const
if (inputLayoutSize > 0)
{
// Create input layout
VALIDATE_DIRECTX_RESULT(_device->GetDevice()->CreateInputLayout(inputLayoutDesc, inputLayoutSize, cacheBytes, cacheSize, &inputLayout));
VALIDATE_DIRECTX_CALL(_device->GetDevice()->CreateInputLayout(inputLayoutDesc, inputLayoutSize, cacheBytes, cacheSize, &inputLayout));
}
// Create shader
ID3D11VertexShader* buffer = nullptr;
VALIDATE_DIRECTX_RESULT(_device->GetDevice()->CreateVertexShader(cacheBytes, cacheSize, nullptr, &buffer));
result = _device->GetDevice()->CreateVertexShader(cacheBytes, cacheSize, nullptr, &buffer);
LOG_DIRECTX_RESULT_WITH_RETURN(result, nullptr);
// Create object
shader = New<GPUShaderProgramVSDX11>(initializer, buffer, inputLayout, inputLayoutSize);
@@ -109,7 +111,8 @@ GPUShaderProgram* GPUShaderDX11::CreateGPUShaderProgram(ShaderStage type, const
// Create shader
ID3D11HullShader* buffer = nullptr;
VALIDATE_DIRECTX_RESULT(_device->GetDevice()->CreateHullShader(cacheBytes, cacheSize, nullptr, &buffer));
result = _device->GetDevice()->CreateHullShader(cacheBytes, cacheSize, nullptr, &buffer);
LOG_DIRECTX_RESULT_WITH_RETURN(result, nullptr);
// Create object
shader = New<GPUShaderProgramHSDX11>(initializer, buffer, controlPointsCount);
@@ -119,7 +122,8 @@ GPUShaderProgram* GPUShaderDX11::CreateGPUShaderProgram(ShaderStage type, const
{
// Create shader
ID3D11DomainShader* buffer = nullptr;
VALIDATE_DIRECTX_RESULT(_device->GetDevice()->CreateDomainShader(cacheBytes, cacheSize, nullptr, &buffer));
result = _device->GetDevice()->CreateDomainShader(cacheBytes, cacheSize, nullptr, &buffer);
LOG_DIRECTX_RESULT_WITH_RETURN(result, nullptr);
// Create object
shader = New<GPUShaderProgramDSDX11>(initializer, buffer);
@@ -129,7 +133,8 @@ GPUShaderProgram* GPUShaderDX11::CreateGPUShaderProgram(ShaderStage type, const
{
// Create shader
ID3D11GeometryShader* buffer = nullptr;
VALIDATE_DIRECTX_RESULT(_device->GetDevice()->CreateGeometryShader(cacheBytes, cacheSize, nullptr, &buffer));
result = _device->GetDevice()->CreateGeometryShader(cacheBytes, cacheSize, nullptr, &buffer);
LOG_DIRECTX_RESULT_WITH_RETURN(result, nullptr);
// Create object
shader = New<GPUShaderProgramGSDX11>(initializer, buffer);
@@ -139,7 +144,8 @@ GPUShaderProgram* GPUShaderDX11::CreateGPUShaderProgram(ShaderStage type, const
{
// Create shader
ID3D11PixelShader* buffer = nullptr;
VALIDATE_DIRECTX_RESULT(_device->GetDevice()->CreatePixelShader(cacheBytes, cacheSize, nullptr, &buffer));
result = _device->GetDevice()->CreatePixelShader(cacheBytes, cacheSize, nullptr, &buffer);
LOG_DIRECTX_RESULT_WITH_RETURN(result, nullptr);
// Create object
shader = New<GPUShaderProgramPSDX11>(initializer, buffer);
@@ -149,7 +155,8 @@ GPUShaderProgram* GPUShaderDX11::CreateGPUShaderProgram(ShaderStage type, const
{
// Create shader
ID3D11ComputeShader* buffer = nullptr;
VALIDATE_DIRECTX_RESULT(_device->GetDevice()->CreateComputeShader(cacheBytes, cacheSize, nullptr, &buffer));
result = _device->GetDevice()->CreateComputeShader(cacheBytes, cacheSize, nullptr, &buffer);
LOG_DIRECTX_RESULT_WITH_RETURN(result, nullptr);
// Create object
shader = New<GPUShaderProgramCSDX11>(initializer, buffer);

View File

@@ -28,13 +28,13 @@ GPUSwapChainDX11::GPUSwapChainDX11(GPUDeviceDX11* device, Window* window)
void GPUSwapChainDX11::getBackBuffer()
{
VALIDATE_DIRECTX_RESULT(_swapChain->GetBuffer(0, __uuidof(_backBuffer), reinterpret_cast<void**>(&_backBuffer)));
VALIDATE_DIRECTX_CALL(_swapChain->GetBuffer(0, __uuidof(_backBuffer), reinterpret_cast<void**>(&_backBuffer)));
ID3D11RenderTargetView* rtv;
ID3D11ShaderResourceView* srv;
VALIDATE_DIRECTX_RESULT(_device->GetDevice()->CreateRenderTargetView(_backBuffer, nullptr, &rtv));
VALIDATE_DIRECTX_CALL(_device->GetDevice()->CreateRenderTargetView(_backBuffer, nullptr, &rtv));
#if GPU_USE_WINDOW_SRV
VALIDATE_DIRECTX_RESULT(_device->GetDevice()->CreateShaderResourceView(_backBuffer, nullptr, &srv));
VALIDATE_DIRECTX_CALL(_device->GetDevice()->CreateShaderResourceView(_backBuffer, nullptr, &srv));
#else
srv = nullptr;
#endif
@@ -55,7 +55,7 @@ void GPUSwapChainDX11::OnReleaseGPU()
// Disable fullscreen mode
if (_swapChain)
{
VALIDATE_DIRECTX_RESULT(_swapChain->SetFullscreenState(false, nullptr));
VALIDATE_DIRECTX_CALL(_swapChain->SetFullscreenState(false, nullptr));
}
#endif
@@ -78,7 +78,7 @@ bool GPUSwapChainDX11::IsFullscreen()
// Get state
BOOL state;
VALIDATE_DIRECTX_RESULT(_swapChain->GetFullscreenState(&state, nullptr));
VALIDATE_DIRECTX_CALL(_swapChain->GetFullscreenState(&state, nullptr));
return state == TRUE;
}
@@ -229,21 +229,21 @@ bool GPUSwapChainDX11::Resize(int32 width, int32 height)
// Create swap chain
#if PLATFORM_WINDOWS
auto dxgi = _device->GetDXGIFactory();
VALIDATE_DIRECTX_RESULT(dxgi->CreateSwapChain(_device->GetDevice(), &swapChainDesc, &_swapChain));
VALIDATE_DIRECTX_CALL(dxgi->CreateSwapChain(_device->GetDevice(), &swapChainDesc, &_swapChain));
ASSERT(_swapChain);
// Disable DXGI changes to the window
VALIDATE_DIRECTX_RESULT(dxgi->MakeWindowAssociation(_windowHandle, DXGI_MWA_NO_ALT_ENTER));
VALIDATE_DIRECTX_CALL(dxgi->MakeWindowAssociation(_windowHandle, DXGI_MWA_NO_ALT_ENTER));
#else
auto dxgiFactory = (IDXGIFactory2*)_device->GetDXGIFactory();
VALIDATE_DIRECTX_RESULT(dxgiFactory->CreateSwapChainForCoreWindow(_device->GetDevice(), static_cast<IUnknown*>(_windowHandle), &swapChainDesc, nullptr, &_swapChain));
VALIDATE_DIRECTX_CALL(dxgiFactory->CreateSwapChainForCoreWindow(_device->GetDevice(), static_cast<IUnknown*>(_windowHandle), &swapChainDesc, nullptr, &_swapChain));
ASSERT(_swapChain);
// Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and
// ensures that the application will only render after each VSync, minimizing power consumption.
ComPtr<IDXGIDevice2> dxgiDevice;
VALIDATE_DIRECTX_RESULT(_device->GetDevice()->QueryInterface(IID_PPV_ARGS(&dxgiDevice)));
VALIDATE_DIRECTX_RESULT(dxgiDevice->SetMaximumFrameLatency(1));
VALIDATE_DIRECTX_CALL(_device->GetDevice()->QueryInterface(IID_PPV_ARGS(&dxgiDevice)));
VALIDATE_DIRECTX_CALL(dxgiDevice->SetMaximumFrameLatency(1));
#endif
}
else
@@ -252,10 +252,10 @@ bool GPUSwapChainDX11::Resize(int32 width, int32 height)
#if PLATFORM_WINDOWS
_swapChain->GetDesc(&swapChainDesc);
VALIDATE_DIRECTX_RESULT(_swapChain->ResizeBuffers(swapChainDesc.BufferCount, width, height, swapChainDesc.BufferDesc.Format, swapChainDesc.Flags));
VALIDATE_DIRECTX_CALL(_swapChain->ResizeBuffers(swapChainDesc.BufferCount, width, height, swapChainDesc.BufferDesc.Format, swapChainDesc.Flags));
#else
_swapChain->GetDesc1(&swapChainDesc);
VALIDATE_DIRECTX_RESULT(_swapChain->ResizeBuffers(swapChainDesc.BufferCount, width, height, swapChainDesc.Format, swapChainDesc.Flags));
VALIDATE_DIRECTX_CALL(_swapChain->ResizeBuffers(swapChainDesc.BufferCount, width, height, swapChainDesc.Format, swapChainDesc.Flags));
#endif
}

View File

@@ -87,7 +87,7 @@ bool GPUTextureDX11::OnInit()
result = device->CreateTexture2D(&textureDesc, nullptr, &texture);
_resource = texture;
}
LOG_DIRECTX_RESULT_WITH_RETURN(result);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
ASSERT(_resource != nullptr);
DX_SET_DEBUG_NAME(_resource, GetName());
@@ -135,7 +135,7 @@ void GPUTextureDX11::OnResidentMipsChanged()
}
ID3D11ShaderResourceView* srView = nullptr;
if (mipLevels != 0)
VALIDATE_DIRECTX_RESULT(_device->GetDevice()->CreateShaderResourceView(_resource, &srDesc, &srView));
VALIDATE_DIRECTX_CALL(_device->GetDevice()->CreateShaderResourceView(_resource, &srDesc, &srView));
GPUTextureViewDX11& view = IsVolume() ? _handleVolume : _handlesPerSlice[0];
if (view.GetParent() == nullptr)
view.Init(this, nullptr, srView, nullptr, nullptr, Format(), MultiSampleLevel());
@@ -201,7 +201,7 @@ void GPUTextureDX11::initHandles()
srDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
srDesc.Texture3D.MostDetailedMip = 0;
srDesc.Texture3D.MipLevels = mipLevels;
VALIDATE_DIRECTX_RESULT(device->CreateShaderResourceView(_resource, &srDesc, &srView));
VALIDATE_DIRECTX_CALL(device->CreateShaderResourceView(_resource, &srDesc, &srView));
}
if (useRTV)
{
@@ -209,7 +209,7 @@ void GPUTextureDX11::initHandles()
rtDesc.Texture3D.MipSlice = 0;
rtDesc.Texture3D.FirstWSlice = 0;
rtDesc.Texture3D.WSize = Depth();
VALIDATE_DIRECTX_RESULT(device->CreateRenderTargetView(_resource, &rtDesc, &rtView));
VALIDATE_DIRECTX_CALL(device->CreateRenderTargetView(_resource, &rtDesc, &rtView));
}
if (useUAV)
{
@@ -217,7 +217,7 @@ void GPUTextureDX11::initHandles()
uaDesc.Texture3D.MipSlice = 0;
uaDesc.Texture3D.WSize = Depth();
uaDesc.Texture3D.FirstWSlice = 0;
VALIDATE_DIRECTX_RESULT(device->CreateUnorderedAccessView(_resource, &uaDesc, &uaView));
VALIDATE_DIRECTX_CALL(device->CreateUnorderedAccessView(_resource, &uaDesc, &uaView));
}
_handleVolume.Init(this, rtView, srView, nullptr, uaView, format, msaa);
@@ -232,7 +232,7 @@ void GPUTextureDX11::initHandles()
for (int32 sliceIndex = 0; sliceIndex < Depth(); sliceIndex++)
{
rtDesc.Texture3D.FirstWSlice = sliceIndex;
VALIDATE_DIRECTX_RESULT(device->CreateRenderTargetView(_resource, &rtDesc, &rtView));
VALIDATE_DIRECTX_CALL(device->CreateRenderTargetView(_resource, &rtDesc, &rtView));
_handlesPerSlice[sliceIndex].Init(this, rtView, nullptr, nullptr, nullptr, format, msaa);
}
}
@@ -263,7 +263,7 @@ void GPUTextureDX11::initHandles()
dsDesc.Texture2DArray.FirstArraySlice = arrayIndex;
dsDesc.Texture2DArray.MipSlice = 0;
}
VALIDATE_DIRECTX_RESULT(device->CreateDepthStencilView(_resource, &dsDesc, &dsView));
VALIDATE_DIRECTX_CALL(device->CreateDepthStencilView(_resource, &dsDesc, &dsView));
}
if (useRTV)
{
@@ -281,7 +281,7 @@ void GPUTextureDX11::initHandles()
rtDesc.Texture2DArray.FirstArraySlice = arrayIndex;
rtDesc.Texture2DArray.MipSlice = 0;
}
VALIDATE_DIRECTX_RESULT(device->CreateRenderTargetView(_resource, &rtDesc, &rtView));
VALIDATE_DIRECTX_CALL(device->CreateRenderTargetView(_resource, &rtDesc, &rtView));
}
if (useSRV)
{
@@ -305,7 +305,7 @@ void GPUTextureDX11::initHandles()
srDesc.Texture2DArray.MipLevels = mipLevels;
srDesc.Texture2DArray.MostDetailedMip = 0;
}
VALIDATE_DIRECTX_RESULT(device->CreateShaderResourceView(_resource, &srDesc, &srView));
VALIDATE_DIRECTX_CALL(device->CreateShaderResourceView(_resource, &srDesc, &srView));
}
}
@@ -322,7 +322,7 @@ void GPUTextureDX11::initHandles()
dsDesc.Texture2DArray.ArraySize = arraySize;
dsDesc.Texture2DArray.FirstArraySlice = 0;
dsDesc.Texture2DArray.MipSlice = 0;
VALIDATE_DIRECTX_RESULT(device->CreateDepthStencilView(_resource, &dsDesc, &dsView));
VALIDATE_DIRECTX_CALL(device->CreateDepthStencilView(_resource, &dsDesc, &dsView));
}
if (useRTV)
{
@@ -330,7 +330,7 @@ void GPUTextureDX11::initHandles()
rtDesc.Texture2DArray.ArraySize = arraySize;
rtDesc.Texture2DArray.FirstArraySlice = 0;
rtDesc.Texture2DArray.MipSlice = 0;
VALIDATE_DIRECTX_RESULT(device->CreateRenderTargetView(_resource, &rtDesc, &rtView));
VALIDATE_DIRECTX_CALL(device->CreateRenderTargetView(_resource, &rtDesc, &rtView));
}
if (useSRV)
{
@@ -348,7 +348,7 @@ void GPUTextureDX11::initHandles()
srDesc.Texture2DArray.MipLevels = mipLevels;
srDesc.Texture2DArray.MostDetailedMip = 0;
}
VALIDATE_DIRECTX_RESULT(device->CreateShaderResourceView(_resource, &srDesc, &srView));
VALIDATE_DIRECTX_CALL(device->CreateShaderResourceView(_resource, &srDesc, &srView));
}
if (useUAV)
{
@@ -356,7 +356,7 @@ void GPUTextureDX11::initHandles()
uaDesc.Texture2DArray.MipSlice = 0;
uaDesc.Texture2DArray.ArraySize = arraySize;
uaDesc.Texture2DArray.FirstArraySlice = 0;
VALIDATE_DIRECTX_RESULT(device->CreateUnorderedAccessView(_resource, &uaDesc, &uaView));
VALIDATE_DIRECTX_CALL(device->CreateUnorderedAccessView(_resource, &uaDesc, &uaView));
}
_handleArray.Init(this, rtView, srView, dsView, uaView, format, msaa);
}
@@ -386,7 +386,7 @@ void GPUTextureDX11::initHandles()
dsDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
dsDesc.Texture2D.MipSlice = 0;
}
VALIDATE_DIRECTX_RESULT(device->CreateDepthStencilView(_resource, &dsDesc, &dsView));
VALIDATE_DIRECTX_CALL(device->CreateDepthStencilView(_resource, &dsDesc, &dsView));
}
if (useRTV)
{
@@ -406,7 +406,7 @@ void GPUTextureDX11::initHandles()
rtDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
rtDesc.Texture2D.MipSlice = 0;
}
VALIDATE_DIRECTX_RESULT(device->CreateRenderTargetView(_resource, &rtDesc, &rtView));
VALIDATE_DIRECTX_CALL(device->CreateRenderTargetView(_resource, &rtDesc, &rtView));
}
if (useSRV)
{
@@ -426,13 +426,13 @@ void GPUTextureDX11::initHandles()
srDesc.Texture2D.MostDetailedMip = 0;
srDesc.Texture2D.MipLevels = mipLevels;
}
VALIDATE_DIRECTX_RESULT(device->CreateShaderResourceView(_resource, &srDesc, &srView));
VALIDATE_DIRECTX_CALL(device->CreateShaderResourceView(_resource, &srDesc, &srView));
}
if (useUAV)
{
uaDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
uaDesc.Texture2D.MipSlice = 0;
VALIDATE_DIRECTX_RESULT(device->CreateUnorderedAccessView(_resource, &uaDesc, &uaView));
VALIDATE_DIRECTX_CALL(device->CreateUnorderedAccessView(_resource, &uaDesc, &uaView));
}
_handlesPerSlice[0].Init(this, rtView, srView, dsView, uaView, format, msaa);
}
@@ -521,7 +521,7 @@ void GPUTextureDX11::initHandles()
dsDesc.Flags = D3D11_DSV_READ_ONLY_DEPTH;
if (PixelFormatExtensions::HasStencil(format))
dsDesc.Flags |= D3D11_DSV_READ_ONLY_STENCIL;
VALIDATE_DIRECTX_RESULT(device->CreateDepthStencilView(_resource, &dsDesc, &dsView));
VALIDATE_DIRECTX_CALL(device->CreateDepthStencilView(_resource, &dsDesc, &dsView));
}
ASSERT(!useRTV);
rtView = nullptr;
@@ -543,7 +543,7 @@ void GPUTextureDX11::initHandles()
srDesc.Texture2D.MostDetailedMip = 0;
srDesc.Texture2D.MipLevels = mipLevels;
}
VALIDATE_DIRECTX_RESULT(device->CreateShaderResourceView(_resource, &srDesc, &srView));
VALIDATE_DIRECTX_CALL(device->CreateShaderResourceView(_resource, &srDesc, &srView));
}
_handleReadOnlyDepth.Init(this, rtView, srView, dsView, nullptr, format, msaa);
}

View File

@@ -31,7 +31,7 @@ ID3D12CommandAllocator* CommandAllocatorPoolDX12::RequestAllocator(uint64 comple
if (firstPair.First <= completedFenceValue)
{
allocator = firstPair.Second;
VALIDATE_DIRECTX_RESULT(allocator->Reset());
VALIDATE_DIRECTX_CALL(allocator->Reset());
_ready.RemoveAtKeepOrder(0);
}
}
@@ -39,7 +39,7 @@ ID3D12CommandAllocator* CommandAllocatorPoolDX12::RequestAllocator(uint64 comple
// If no allocators were ready to be reused, create a new one
if (allocator == nullptr)
{
VALIDATE_DIRECTX_RESULT(_device->GetDevice()->CreateCommandAllocator(_type, IID_PPV_ARGS(&allocator)));
VALIDATE_DIRECTX_CALL(_device->GetDevice()->CreateCommandAllocator(_type, IID_PPV_ARGS(&allocator)));
#if GPU_ENABLE_RESOURCE_NAMING
Char name[32];
swprintf(name, 32, L"CommandAllocator %u", _pool.Count());

View File

@@ -111,7 +111,7 @@ bool CommandQueueDX12::Init()
desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
desc.NodeMask = 0;
HRESULT result = _device->GetDevice()->CreateCommandQueue(&desc, IID_PPV_ARGS(&_commandQueue));
LOG_DIRECTX_RESULT_WITH_RETURN(result);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
#if GPU_ENABLE_RESOURCE_NAMING
_commandQueue->SetName(TEXT("CommandQueueDX12::CommandQueue"));
#endif
@@ -148,7 +148,7 @@ void CommandQueueDX12::WaitForGPU()
uint64 CommandQueueDX12::ExecuteCommandList(ID3D12CommandList* list)
{
VALIDATE_DIRECTX_RESULT((static_cast<ID3D12GraphicsCommandList*>(list))->Close());
VALIDATE_DIRECTX_CALL((static_cast<ID3D12GraphicsCommandList*>(list))->Close());
_commandQueue->ExecuteCommandLists(1, &list);

View File

@@ -73,7 +73,7 @@ bool DescriptorHeapWithSlotsDX12::Create(D3D12_DESCRIPTOR_HEAP_TYPE type, uint32
// Create heap
const HRESULT result = _device->GetDevice()->CreateDescriptorHeap(&desc, __uuidof(ID3D12DescriptorHeap), reinterpret_cast<void**>(&_heap));
LOG_DIRECTX_RESULT_WITH_RETURN(result);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
// Setup
_type = type;
@@ -196,7 +196,7 @@ bool DescriptorHeapRingBufferDX12::Init()
desc.Flags = _shaderVisible ? D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE : D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
desc.NodeMask = 0;
const HRESULT result = _device->GetDevice()->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&_heap));
LOG_DIRECTX_RESULT_WITH_RETURN(result);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
// Setup
_firstFree = 0;

View File

@@ -136,7 +136,7 @@ bool GPUBufferDX12::OnInit()
// Create resource
ID3D12Resource* resource;
D3D12_RESOURCE_STATES initialState = D3D12_RESOURCE_STATE_COPY_DEST;
VALIDATE_DIRECTX_RESULT(_device->GetDevice()->CreateCommittedResource(&heapProperties, D3D12_HEAP_FLAG_NONE, &resourceDesc, initialState, nullptr, IID_PPV_ARGS(&resource)));
VALIDATE_DIRECTX_CALL(_device->GetDevice()->CreateCommittedResource(&heapProperties, D3D12_HEAP_FLAG_NONE, &resourceDesc, initialState, nullptr, IID_PPV_ARGS(&resource)));
// Set state
initResource(resource, initialState, 1);

View File

@@ -83,7 +83,7 @@ GPUContextDX12::GPUContextDX12(GPUDeviceDX12* device, D3D12_COMMAND_LIST_TYPE ty
FrameFenceValues[0] = 0;
FrameFenceValues[1] = 0;
_currentAllocator = _device->GetCommandQueue()->RequestAllocator();
VALIDATE_DIRECTX_RESULT(device->GetDevice()->CreateCommandList(0, type, _currentAllocator, nullptr, IID_PPV_ARGS(&_commandList)));
VALIDATE_DIRECTX_CALL(device->GetDevice()->CreateCommandList(0, type, _currentAllocator, nullptr, IID_PPV_ARGS(&_commandList)));
#if GPU_ENABLE_RESOURCE_NAMING
_commandList->SetName(TEXT("GPUContextDX12::CommandList"));
#endif

View File

@@ -77,7 +77,7 @@ GPUDevice* GPUDeviceDX12::Create()
#endif
#ifdef __ID3D12DeviceRemovedExtendedDataSettings_FWD_DEFINED__
ComPtr<ID3D12DeviceRemovedExtendedDataSettings> dredSettings;
VALIDATE_DIRECTX_RESULT(D3D12GetDebugInterface(IID_PPV_ARGS(&dredSettings)));
VALIDATE_DIRECTX_CALL(D3D12GetDebugInterface(IID_PPV_ARGS(&dredSettings)));
if (dredSettings)
{
// Turn on AutoBreadcrumbs and Page Fault reporting
@@ -116,7 +116,7 @@ GPUDevice* GPUDeviceDX12::Create()
{
adapter.Index = index;
adapter.MaxFeatureLevel = D3D_FEATURE_LEVEL_12_0;
VALIDATE_DIRECTX_RESULT(tempAdapter->GetDesc(&adapter.Description));
VALIDATE_DIRECTX_CALL(tempAdapter->GetDesc(&adapter.Description));
uint32 outputs = RenderToolsDX::CountAdapterOutputs(tempAdapter);
// Send that info to the log
@@ -137,7 +137,7 @@ GPUDevice* GPUDeviceDX12::Create()
if (tempAdapter && CheckDX12Support(tempAdapter))
{
DXGI_ADAPTER_DESC desc;
VALIDATE_DIRECTX_RESULT(tempAdapter->GetDesc(&desc));
VALIDATE_DIRECTX_CALL(tempAdapter->GetDesc(&desc));
for (int i = 0; i < adapters.Count(); i++)
{
if (adapters[i].Description.AdapterLuid.LowPart == desc.AdapterLuid.LowPart &&
@@ -254,7 +254,7 @@ bool GPUDeviceDX12::Init()
#if PLATFORM_XBOX_SCARLETT
params.DisableDXR = TRUE;
#endif
VALIDATE_DIRECTX_RESULT(D3D12XboxCreateDevice(nullptr, &params, IID_GRAPHICS_PPV_ARGS(&_device)));
VALIDATE_DIRECTX_CALL(D3D12XboxCreateDevice(nullptr, &params, IID_GRAPHICS_PPV_ARGS(&_device)));
// Setup adapter
D3D12XBOX_GPU_HARDWARE_CONFIGURATION hwConfig = {};
@@ -319,12 +319,12 @@ bool GPUDeviceDX12::Init()
}
// Create DirectX device
VALIDATE_DIRECTX_RESULT(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&_device)));
VALIDATE_DIRECTX_CALL(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&_device)));
// Debug Layer
#if GPU_ENABLE_DIAGNOSTICS
ComPtr<ID3D12InfoQueue> infoQueue;
VALIDATE_DIRECTX_RESULT(_device->QueryInterface(IID_PPV_ARGS(&infoQueue)));
VALIDATE_DIRECTX_CALL(_device->QueryInterface(IID_PPV_ARGS(&infoQueue)));
if (infoQueue)
{
D3D12_INFO_QUEUE_FILTER filter;
@@ -363,7 +363,7 @@ bool GPUDeviceDX12::Init()
// Spawn some info about the hardware
D3D12_FEATURE_DATA_D3D12_OPTIONS options;
VALIDATE_DIRECTX_RESULT(_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options)));
VALIDATE_DIRECTX_CALL(_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options)));
LOG(Info, "Tiled Resources Tier: {0}", (int32)options.TiledResourcesTier);
LOG(Info, "Resource Binding Tier: {0}", (int32)options.ResourceBindingTier);
LOG(Info, "Conservative Rasterization Tier: {0}", (int32)options.ConservativeRasterizationTier);
@@ -662,10 +662,10 @@ bool GPUDeviceDX12::Init()
// Serialize
ComPtr<ID3DBlob> signature;
ComPtr<ID3DBlob> error;
VALIDATE_DIRECTX_RESULT(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error));
VALIDATE_DIRECTX_CALL(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error));
// Create
VALIDATE_DIRECTX_RESULT(_device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&_rootSignature)));
VALIDATE_DIRECTX_CALL(_device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&_rootSignature)));
}
// Upload buffer
@@ -896,14 +896,14 @@ void GPUDeviceDX12::OnResumed()
void GPUDeviceDX12::updateFrameEvents()
{
ComPtr<IDXGIDevice1> dxgiDevice;
VALIDATE_DIRECTX_RESULT(_device->QueryInterface(IID_GRAPHICS_PPV_ARGS(&dxgiDevice)));
VALIDATE_DIRECTX_CALL(_device->QueryInterface(IID_GRAPHICS_PPV_ARGS(&dxgiDevice)));
ComPtr<IDXGIAdapter> dxgiAdapter;
VALIDATE_DIRECTX_RESULT(dxgiDevice->GetAdapter(dxgiAdapter.GetAddressOf()));
VALIDATE_DIRECTX_CALL(dxgiDevice->GetAdapter(dxgiAdapter.GetAddressOf()));
dxgiAdapter->GetDesc(&_adapter->Description);
ComPtr<IDXGIOutput> dxgiOutput;
VALIDATE_DIRECTX_RESULT(dxgiAdapter->EnumOutputs(0, dxgiOutput.GetAddressOf()));
VALIDATE_DIRECTX_RESULT(_device->SetFrameIntervalX(dxgiOutput.Get(), D3D12XBOX_FRAME_INTERVAL_60_HZ, DX12_BACK_BUFFER_COUNT - 1u, D3D12XBOX_FRAME_INTERVAL_FLAG_NONE));
VALIDATE_DIRECTX_RESULT(_device->ScheduleFrameEventX(D3D12XBOX_FRAME_EVENT_ORIGIN, 0U, nullptr, D3D12XBOX_SCHEDULE_FRAME_EVENT_FLAG_NONE));
VALIDATE_DIRECTX_CALL(dxgiAdapter->EnumOutputs(0, dxgiOutput.GetAddressOf()));
VALIDATE_DIRECTX_CALL(_device->SetFrameIntervalX(dxgiOutput.Get(), D3D12XBOX_FRAME_INTERVAL_60_HZ, DX12_BACK_BUFFER_COUNT - 1u, D3D12XBOX_FRAME_INTERVAL_FLAG_NONE));
VALIDATE_DIRECTX_CALL(_device->ScheduleFrameEventX(D3D12XBOX_FRAME_EVENT_ORIGIN, 0U, nullptr, D3D12XBOX_SCHEDULE_FRAME_EVENT_FLAG_NONE));
}
#endif

View File

@@ -66,7 +66,7 @@ void GPUSwapChainDX12::OnReleaseGPU()
// Disable fullscreen mode
if (_swapChain)
{
VALIDATE_DIRECTX_RESULT(_swapChain->SetFullscreenState(false, nullptr));
VALIDATE_DIRECTX_CALL(_swapChain->SetFullscreenState(false, nullptr));
}
#endif
@@ -100,7 +100,7 @@ bool GPUSwapChainDX12::IsFullscreen()
// Get state
BOOL state;
VALIDATE_DIRECTX_RESULT(_swapChain->GetFullscreenState(&state, nullptr));
VALIDATE_DIRECTX_CALL(_swapChain->GetFullscreenState(&state, nullptr));
return state == TRUE;
#endif
}
@@ -221,7 +221,7 @@ bool GPUSwapChainDX12::Resize(int32 width, int32 height)
// Create swap chain (it needs the queue so that it can force a flush on it)
IDXGISwapChain1* swapChain;
auto dxgiFactory = _device->GetDXGIFactory();
VALIDATE_DIRECTX_RESULT(dxgiFactory->CreateSwapChainForHwnd(_device->GetCommandQueueDX12(), _windowHandle, &swapChainDesc, &fullscreenDesc, nullptr, &swapChain));
VALIDATE_DIRECTX_CALL(dxgiFactory->CreateSwapChainForHwnd(_device->GetCommandQueueDX12(), _windowHandle, &swapChainDesc, &fullscreenDesc, nullptr, &swapChain));
_swapChain = static_cast<IDXGISwapChain3*>(swapChain);
ASSERT(_swapChain);
DX_SET_DEBUG_NAME_EX(_swapChain, TEXT("RenderOutput"), TEXT("SwapChain"), TEXT(""));
@@ -229,7 +229,7 @@ bool GPUSwapChainDX12::Resize(int32 width, int32 height)
_backBuffers.Resize(swapChainDesc.BufferCount);
// Disable DXGI changes to the window
VALIDATE_DIRECTX_RESULT(dxgiFactory->MakeWindowAssociation(_windowHandle, DXGI_MWA_NO_ALT_ENTER));
VALIDATE_DIRECTX_CALL(dxgiFactory->MakeWindowAssociation(_windowHandle, DXGI_MWA_NO_ALT_ENTER));
}
else
{
@@ -237,7 +237,7 @@ bool GPUSwapChainDX12::Resize(int32 width, int32 height)
_swapChain->GetDesc1(&swapChainDesc);
VALIDATE_DIRECTX_RESULT(_swapChain->ResizeBuffers(swapChainDesc.BufferCount, width, height, swapChainDesc.Format, swapChainDesc.Flags));
VALIDATE_DIRECTX_CALL(_swapChain->ResizeBuffers(swapChainDesc.BufferCount, width, height, swapChainDesc.Format, swapChainDesc.Flags));
}
_currentFrameIndex = _swapChain->GetCurrentBackBufferIndex();
@@ -316,7 +316,7 @@ void GPUSwapChainDX12::getBackBuffer()
swapChainBufferDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
D3D12_CLEAR_VALUE swapChainOptimizedClearValue = {};
swapChainOptimizedClearValue.Format = swapChainBufferDesc.Format;
VALIDATE_DIRECTX_RESULT(_device->GetDevice()->CreateCommittedResource(
VALIDATE_DIRECTX_CALL(_device->GetDevice()->CreateCommittedResource(
&swapChainHeapProperties,
D3D12_HEAP_FLAG_ALLOW_DISPLAY,
&swapChainBufferDesc,
@@ -324,7 +324,7 @@ void GPUSwapChainDX12::getBackBuffer()
&swapChainOptimizedClearValue,
IID_GRAPHICS_PPV_ARGS(&backbuffer)));
#else
VALIDATE_DIRECTX_RESULT(_swapChain->GetBuffer(i, IID_PPV_ARGS(&backbuffer)));
VALIDATE_DIRECTX_CALL(_swapChain->GetBuffer(i, IID_PPV_ARGS(&backbuffer)));
#endif
DX_SET_DEBUG_NAME_EX(backbuffer, TEXT("RenderOutput"), TEXT("BackBuffer"), i);
_backBuffers[i].Setup(this, backbuffer);
@@ -337,7 +337,7 @@ void GPUSwapChainDX12::Begin(RenderTask* task)
{
// Wait until frame start is signaled
_framePipelineToken = D3D12XBOX_FRAME_PIPELINE_TOKEN_NULL;
VALIDATE_DIRECTX_RESULT(_device->GetDevice()->WaitFrameEventX(D3D12XBOX_FRAME_EVENT_ORIGIN, INFINITE, nullptr, D3D12XBOX_WAIT_FRAME_EVENT_FLAG_NONE, &_framePipelineToken));
VALIDATE_DIRECTX_CALL(_device->GetDevice()->WaitFrameEventX(D3D12XBOX_FRAME_EVENT_ORIGIN, INFINITE, nullptr, D3D12XBOX_WAIT_FRAME_EVENT_FLAG_NONE, &_framePipelineToken));
GPUSwapChain::Begin(task);
}
@@ -366,7 +366,7 @@ void GPUSwapChainDX12::Present(bool vsync)
planeParameters.Token = _framePipelineToken;
planeParameters.ResourceCount = 1;
planeParameters.ppResources = &backBuffer;
VALIDATE_DIRECTX_RESULT(_device->GetCommandQueueDX12()->PresentX(1, &planeParameters, nullptr));
VALIDATE_DIRECTX_CALL(_device->GetCommandQueueDX12()->PresentX(1, &planeParameters, nullptr));
// Base
GPUSwapChain::Present(vsync);

View File

@@ -113,7 +113,7 @@ bool GPUTextureDX12::OnInit()
resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
resourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
auto result = device->CreateCommittedResource(&heapProperties, D3D12_HEAP_FLAG_NONE, &resourceDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&resource));
LOG_DIRECTX_RESULT_WITH_RETURN(result);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
initResource(resource, D3D12_RESOURCE_STATE_COPY_DEST, 1);
DX_SET_DEBUG_NAME(_resource, GetName());
_memoryUsage = totalSize;
@@ -184,7 +184,7 @@ bool GPUTextureDX12::OnInit()
// Create texture
auto result = device->CreateCommittedResource(&heapProperties, D3D12_HEAP_FLAG_NONE, &resourceDesc, initialState, clearValuePtr, IID_PPV_ARGS(&resource));
LOG_DIRECTX_RESULT_WITH_RETURN(result);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
// Set state
bool isRead = useSRV || useUAV;

View File

@@ -37,7 +37,7 @@ void GPUTimerQueryDX12::End()
heap.EndQuery(context, _end);
const auto queue = _device->GetCommandQueue()->GetCommandQueue();
VALIDATE_DIRECTX_RESULT(queue->GetTimestampFrequency(&_gpuFrequency));
VALIDATE_DIRECTX_CALL(queue->GetTimestampFrequency(&_gpuFrequency));
_endCalled = true;
}

View File

@@ -41,7 +41,7 @@ bool QueryHeapDX12::Init()
heapDesc.Count = _queryHeapCount;
heapDesc.NodeMask = 0;
HRESULT result = _device->GetDevice()->CreateQueryHeap(&heapDesc, IID_PPV_ARGS(&_queryHeap));
LOG_DIRECTX_RESULT_WITH_RETURN(result);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
DX_SET_DEBUG_NAME(_queryHeap, "Query Heap");
// Create the result buffer
@@ -64,7 +64,7 @@ bool QueryHeapDX12::Init()
resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
resourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
result = _device->GetDevice()->CreateCommittedResource(&heapProperties, D3D12_HEAP_FLAG_NONE, &resourceDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&_resultBuffer));
LOG_DIRECTX_RESULT_WITH_RETURN(result);
LOG_DIRECTX_RESULT_WITH_RETURN(result, true);
DX_SET_DEBUG_NAME(_resultBuffer, "Query Heap Result Buffer");
// Start out with an open query batch
@@ -181,7 +181,7 @@ void* QueryHeapDX12::ResolveQuery(ElementHandle& handle)
range.Begin = batch.Start * _resultSize;
range.End = range.Begin + batch.Count * _resultSize;
void* mapped = nullptr;
VALIDATE_DIRECTX_RESULT(_resultBuffer->Map(0, &range, &mapped));
VALIDATE_DIRECTX_CALL(_resultBuffer->Map(0, &range, &mapped));
// Copy the results data
Platform::MemoryCopy(_resultData.Get() + range.Begin, (byte*)mapped + range.Begin, batch.Count * _resultSize);

View File

@@ -229,7 +229,7 @@ UploadBufferPageDX12::UploadBufferPageDX12(GPUDeviceDX12* device, uint64 size)
resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
resourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
ID3D12Resource* resource;
VALIDATE_DIRECTX_RESULT(_device->GetDevice()->CreateCommittedResource(&heapProperties, D3D12_HEAP_FLAG_NONE, &resourceDesc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&resource)));
VALIDATE_DIRECTX_CALL(_device->GetDevice()->CreateCommittedResource(&heapProperties, D3D12_HEAP_FLAG_NONE, &resourceDesc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&resource)));
// Set state
initResource(resource, D3D12_RESOURCE_STATE_GENERIC_READ, 1);
@@ -238,7 +238,7 @@ UploadBufferPageDX12::UploadBufferPageDX12(GPUDeviceDX12* device, uint64 size)
GPUAddress = _resource->GetGPUVirtualAddress();
// Map buffer
VALIDATE_DIRECTX_RESULT(_resource->Map(0, nullptr, &CPUAddress));
VALIDATE_DIRECTX_CALL(_resource->Map(0, nullptr, &CPUAddress));
}
void UploadBufferPageDX12::OnReleaseGPU()

View File

@@ -272,15 +272,15 @@ namespace RenderToolsDX
#if GPU_ENABLE_ASSERTION
// DirectX results validation
#define VALIDATE_DIRECTX_RESULT(x) { HRESULT result = x; if (FAILED(result)) RenderToolsDX::ValidateD3DResult(result, __FILE__, __LINE__); }
#define VALIDATE_DIRECTX_CALL(x) { HRESULT result = x; if (FAILED(result)) RenderToolsDX::ValidateD3DResult(result, __FILE__, __LINE__); }
#define LOG_DIRECTX_RESULT(result) if (FAILED(result)) RenderToolsDX::LogD3DResult(result, __FILE__, __LINE__)
#define LOG_DIRECTX_RESULT_WITH_RETURN(result) if (FAILED(result)) { RenderToolsDX::LogD3DResult(result, __FILE__, __LINE__); return true; }
#define LOG_DIRECTX_RESULT_WITH_RETURN(result, returnValue) if (FAILED(result)) { RenderToolsDX::LogD3DResult(result, __FILE__, __LINE__); return returnValue; }
#else
#define VALIDATE_DIRECTX_RESULT(x) x
#define VALIDATE_DIRECTX_CALL(x) x
#define LOG_DIRECTX_RESULT(result) if(FAILED(result)) RenderToolsDX::LogD3DResult(result)
#define LOG_DIRECTX_RESULT_WITH_RETURN(result) if(FAILED(result)) { RenderToolsDX::LogD3DResult(result); return true; }
#define LOG_DIRECTX_RESULT_WITH_RETURN(result, returnValue) if(FAILED(result)) { RenderToolsDX::LogD3DResult(result); return returnValue; }
#endif

View File

@@ -100,6 +100,7 @@ void Skybox::ApplySky(GPUContext* context, RenderContext& renderContext, const M
Platform::MemoryClear(&drawCall, sizeof(DrawCall));
drawCall.World = world;
drawCall.ObjectPosition = drawCall.World.GetTranslation();
drawCall.ObjectRadius = _sphere.Radius;
drawCall.Surface.GeometrySize = _box.GetSize();
drawCall.WorldDeterminantSign = Math::FloatSelect(world.RotDeterminant(), 1, -1);
drawCall.PerInstanceRandom = GetPerInstanceRandom();

View File

@@ -410,6 +410,7 @@ void SplineModel::Draw(RenderContext& renderContext)
const Transform splineTransform = GetTransform();
renderContext.View.GetWorldMatrix(splineTransform, drawCall.World);
drawCall.ObjectPosition = drawCall.World.GetTranslation() + drawCall.Deformable.LocalMatrix.GetTranslation();
drawCall.ObjectRadius = _sphere.Radius; // TODO: use radius for the spline chunk rather than whole spline
const float worldDeterminantSign = drawCall.World.RotDeterminant() * drawCall.Deformable.LocalMatrix.RotDeterminant();
for (int32 segment = 0; segment < _instances.Count(); segment++)
{

View File

@@ -938,7 +938,8 @@ void Particles::DrawParticles(RenderContext& renderContext, ParticleEffect* effe
// Setup a draw call common data
DrawCall drawCall;
drawCall.PerInstanceRandom = effect->GetPerInstanceRandom();
drawCall.ObjectPosition = effect->GetPosition();
drawCall.ObjectPosition = effect->GetSphere().Center - view.Origin;
drawCall.ObjectRadius = effect->GetSphere().Radius;
// Draw all emitters
for (int32 emitterIndex = 0; emitterIndex < effect->Instance.Emitters.Count(); emitterIndex++)

View File

@@ -70,6 +70,46 @@ CFStringRef AppleUtils::ToString(const StringView& str)
return CFStringCreateWithBytes(nullptr, (const UInt8*)str.GetText(), str.Length() * sizeof(Char), kCFStringEncodingUTF16LE, false);
}
NSString* AppleUtils::ToNSString(const StringView& str)
{
NSString* ret = !str.IsEmpty() ? [[NSString alloc] initWithBytes: (const UInt8*)str.Get() length: str.Length() * sizeof(Char) encoding: NSUTF16LittleEndianStringEncoding] : nil;
return ret ? ret : @"";
}
NSString* AppleUtils::ToNSString(const char* string)
{
NSString* ret = string ? [NSString stringWithUTF8String: string] : nil;
return ret ? ret : @"";
}
NSArray* AppleUtils::ParseArguments(NSString* argsString) {
NSMutableArray *argsArray = [NSMutableArray array];
NSScanner *scanner = [NSScanner scannerWithString:argsString];
NSString *currentArg = nil;
BOOL insideQuotes = NO;
while (![scanner isAtEnd]) {
if (insideQuotes) {
[scanner scanUpToString:@"\"" intoString:&currentArg];
[scanner scanString:@"\"" intoString:NULL];
insideQuotes = NO;
} else {
[scanner scanUpToString:@" " intoString:&currentArg];
[scanner scanString:@" " intoString:NULL];
}
if ([currentArg isEqualToString:@"\""]) {
insideQuotes = YES;
} else if (currentArg) {
[argsArray addObject:currentArg];
}
}
return [argsArray copy];
}
typedef uint16_t offset_t;
#define align_mem_up(num, align) (((num) + ((align) - 1)) & ~((align) - 1))

View File

@@ -13,6 +13,9 @@ class AppleUtils
public:
static String ToString(CFStringRef str);
static CFStringRef ToString(const StringView& str);
static NSString* ToNSString(const StringView& str);
static NSString* ToNSString(const char* string);
static NSArray* ParseArguments(NSString* argsString);
#if PLATFORM_MAC
static Float2 PosToCoca(const Float2& pos);
static Float2 CocaToPos(const Float2& pos);

View File

@@ -6,6 +6,8 @@
#include "Windows/WindowsFileSystemWatcher.h"
#elif PLATFORM_LINUX
#include "Linux/LinuxFileSystemWatcher.h"
#elif PLATFORM_MAC
#include "Mac/MacFileSystemWatcher.h"
#else
#include "Base/FileSystemWatcherBase.h"
#endif

View File

@@ -136,7 +136,7 @@ bool LinuxFileSystem::ShowFileExplorer(const StringView& path)
{
const StringAsANSI<> pathAnsi(*path, path.Length());
char cmd[2048];
sprintf(cmd, "nautilus %s &", pathAnsi.Get());
sprintf(cmd, "xdg-open %s &", pathAnsi.Get());
system(cmd);
return false;
}

View File

@@ -132,7 +132,7 @@ bool MacFileSystem::ShowBrowseFolderDialog(Window* parentWindow, const StringVie
bool MacFileSystem::ShowFileExplorer(const StringView& path)
{
return Platform::StartProcess(TEXT("open"), String::Format(TEXT("\"{0}\""), path), StringView::Empty) != 0;
return [[NSWorkspace sharedWorkspace] selectFile: AppleUtils::ToNSString(FileSystem::ConvertRelativePathToAbsolute(path)) inFileViewerRootedAtPath: @""];
}
#endif

View File

@@ -0,0 +1,100 @@
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
#if PLATFORM_MAC
#include "MacFileSystemWatcher.h"
#include "Engine/Platform/Apple/AppleUtils.h"
#include "Engine/Platform/CriticalSection.h"
#include "Engine/Platform/Thread.h"
#include "Engine/Threading/ThreadSpawner.h"
#include "Engine/Core/Collections/Array.h"
#include "Engine/Core/Types/StringView.h"
void DirectoryWatchCallback( ConstFSEventStreamRef StreamRef, void* FileWatcherPtr, size_t EventCount, void* EventPaths, const FSEventStreamEventFlags EventFlags[], const FSEventStreamEventId EventIDs[] )
{
MacFileSystemWatcher* macFileSystemWatcher = (MacFileSystemWatcher*)FileWatcherPtr;
if (macFileSystemWatcher)
{
CFArrayRef EventPathArray = (CFArrayRef)EventPaths;
for( size_t EventIndex = 0; EventIndex < EventCount; ++EventIndex )
{
const FSEventStreamEventFlags Flags = EventFlags[EventIndex];
if( !(Flags & kFSEventStreamEventFlagItemIsFile) && !(Flags & kFSEventStreamEventFlagItemIsDir) )
{
// events about symlinks don't concern us
continue;
}
auto action = FileSystemAction::Unknown;
const bool added = ( Flags & kFSEventStreamEventFlagItemCreated );
const bool renamed = ( Flags & kFSEventStreamEventFlagItemRenamed );
const bool modified = ( Flags & kFSEventStreamEventFlagItemModified );
const bool removed = ( Flags & kFSEventStreamEventFlagItemRemoved );
if (added)
{
action = FileSystemAction::Create;
}
if (renamed || modified)
{
action = FileSystemAction::Delete;
}
if (removed)
{
action = FileSystemAction::Modify;
}
const String resolvedPath = AppleUtils::ToString((CFStringRef)CFArrayGetValueAtIndex(EventPathArray,EventIndex));
macFileSystemWatcher->OnEvent(resolvedPath, action);
}
}
}
MacFileSystemWatcher::MacFileSystemWatcher(const String& directory, bool withSubDirs)
: FileSystemWatcherBase(directory, withSubDirs)
{
CFStringRef FullPathMac = AppleUtils::ToString(StringView(directory));
CFArrayRef PathsToWatch = CFArrayCreate(NULL, (const void**)&FullPathMac, 1, NULL);
CFAbsoluteTime Latency = 0.2;
FSEventStreamContext Context;
Context.version = 0;
Context.info = this;
Context.retain = NULL;
Context.release = NULL;
Context.copyDescription = NULL;
EventStream = FSEventStreamCreate( NULL,
&DirectoryWatchCallback,
&Context,
PathsToWatch,
kFSEventStreamEventIdSinceNow,
Latency,
kFSEventStreamCreateFlagUseCFTypes | kFSEventStreamCreateFlagNoDefer | kFSEventStreamCreateFlagFileEvents
);
CFRelease(PathsToWatch);
CFRelease(FullPathMac);
FSEventStreamScheduleWithRunLoop( EventStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode );
FSEventStreamStart( EventStream );
IsRunning = true;
}
MacFileSystemWatcher::~MacFileSystemWatcher()
{
if (IsRunning)
{
FSEventStreamStop(EventStream);
FSEventStreamUnscheduleFromRunLoop(EventStream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
FSEventStreamInvalidate(EventStream);
FSEventStreamRelease(EventStream);
}
}
#endif

View File

@@ -0,0 +1,39 @@
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
#pragma once
#if PLATFORM_MAC
#include "Engine/Platform/Base/FileSystemWatcherBase.h"
#include <CoreServices/CoreServices.h>
/// <summary>
/// Mac platform implementation of the file system watching object.
/// </summary>
class FLAXENGINE_API MacFileSystemWatcher : public FileSystemWatcherBase
{
public:
/// <summary>
/// Initializes a new instance of the <see cref="MacFileSystemWatcher"/> class.
/// </summary>
/// <param name="directory">The directory to watch.</param>
/// <param name="withSubDirs">True if monitor the directory tree rooted at the specified directory or just a given directory.</param>
MacFileSystemWatcher(const String& directory, bool withSubDirs);
/// <summary>
/// Finalizes an instance of the <see cref="MacFileSystemWatcher"/> class.
/// </summary>
~MacFileSystemWatcher();
public:
private:
FSEventStreamRef EventStream;
bool IsRunning;
};
#endif

View File

@@ -324,13 +324,16 @@ void MacPlatform::BeforeRun()
void MacPlatform::Tick()
{
// Process system events
while (true)
NSEvent* event = nil;
do
{
NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES];
if (event == nil)
break;
[NSApp sendEvent:event];
}
event = [NSApp nextEventMatchingMask: NSEventMaskAny untilDate: nil inMode: NSDefaultRunLoopMode dequeue: YES];
if (event)
{
[NSApp sendEvent:event];
}
} while(event);
ApplePlatform::Tick();
}
@@ -429,13 +432,6 @@ Window* MacPlatform::CreateWindow(const CreateWindowSettings& settings)
int32 MacPlatform::CreateProcess(CreateProcessSettings& settings)
{
LOG(Info, "Command: {0} {1}", settings.FileName, settings.Arguments);
String cwd;
if (settings.WorkingDirectory.HasChars())
{
LOG(Info, "Working directory: {0}", settings.WorkingDirectory);
cwd = Platform::GetWorkingDirectory();
Platform::SetWorkingDirectory(settings.WorkingDirectory);
}
const bool captureStdOut = settings.LogOutput || settings.SaveOutput;
// Special case if filename points to the app package (use actual executable)
@@ -462,47 +458,81 @@ int32 MacPlatform::CreateProcess(CreateProcessSettings& settings)
}
}
// Sanatize the string if the exePath has spaces with properly espcaped spaces for popen
exePath.Replace(TEXT(" "), TEXT("\\ "));
const String cmdLine = exePath + TEXT(" ") + settings.Arguments;
const StringAsANSI<> cmdLineAnsi(*cmdLine, cmdLine.Length());
FILE* pipe = popen(cmdLineAnsi.Get(), "r");
if (cwd.Length() != 0)
{
Platform::SetWorkingDirectory(cwd);
}
if (!pipe)
{
LOG(Warning, "Failed to start process, errno={}", errno);
return -1;
}
// TODO: environment
NSTask *task = [[NSTask alloc] init];
task.launchPath = AppleUtils::ToNSString(exePath);
task.arguments = AppleUtils::ParseArguments(AppleUtils::ToNSString(settings.Arguments));
if (settings.WorkingDirectory.HasChars())
task.currentDirectoryPath = AppleUtils::ToNSString(settings.WorkingDirectory);
int32 returnCode = 0;
if (settings.WaitForEnd)
{
id<NSObject> outputObserver = nil;
if (captureStdOut)
{
char lineBuffer[1024];
while (fgets(lineBuffer, sizeof(lineBuffer), pipe) != NULL)
NSPipe *stdoutPipe = [NSPipe pipe];
[task setStandardOutput:stdoutPipe];
outputObserver = [[NSNotificationCenter defaultCenter]
addObserverForName: NSFileHandleDataAvailableNotification
object: [stdoutPipe fileHandleForReading]
queue: nil
usingBlock:^(NSNotification* notification)
{
char* p = lineBuffer + strlen(lineBuffer) - 1;
if (*p == '\n') *p = 0;
String line(lineBuffer);
if (settings.SaveOutput)
settings.Output.Add(line.Get(), line.Length());
if (settings.LogOutput)
Log::Logger::Write(LogType::Info, line);
NSData* data = [stdoutPipe fileHandleForReading].availableData;
if (data.length)
{
String line((const char*)data.bytes, data.length);
if (settings.SaveOutput)
settings.Output.Add(line.Get(), line.Length());
if (settings.LogOutput)
{
StringView lineView(line);
if (line[line.Length() - 1] == '\n')
lineView = StringView(line.Get(), line.Length() - 1);
Log::Logger::Write(LogType::Info, lineView);
}
[[stdoutPipe fileHandleForReading] waitForDataInBackgroundAndNotify];
}
}
];
[[stdoutPipe fileHandleForReading] waitForDataInBackgroundAndNotify];
}
else
String exception;
@try
{
while (!feof(pipe))
{
sleep(1);
}
[task launch];
[task waitUntilExit];
returnCode = [task terminationStatus];
}
@catch (NSException* e)
{
exception = e.reason.UTF8String;
}
if (!exception.IsEmpty())
{
LOG(Error, "Failed to run command {0} {1} with error {2}", settings.FileName, settings.Arguments, exception);
returnCode = -1;
}
}
else
{
String exception;
@try
{
[task launch];
}
@catch (NSException* e)
{
exception = e.reason.UTF8String;
}
if (!exception.IsEmpty())
{
LOG(Error, "Failed to run command {0} {1} with error {2}", settings.FileName, settings.Arguments, exception);
returnCode = -1;
}
}

View File

@@ -237,8 +237,8 @@ class UnixConditionVariable;
typedef UnixConditionVariable ConditionVariable;
class MacFileSystem;
typedef MacFileSystem FileSystem;
class FileSystemWatcherBase;
typedef FileSystemWatcherBase FileSystemWatcher;
class MacFileSystemWatcher;
typedef MacFileSystemWatcher FileSystemWatcher;
class UnixFile;
typedef UnixFile File;
class MacPlatform;

View File

@@ -258,6 +258,11 @@ struct DrawCall
/// </summary>
Float3 ObjectPosition;
/// <summary>
/// Object bounding sphere radius that contains it whole (sphere at ObjectPosition).
/// </summary>
float ObjectRadius;
/// <summary>
/// The world matrix determinant sign (used for geometry that is two sided or has inverse scale - needs to flip normal vectors and change triangles culling).
/// </summary>

View File

@@ -464,6 +464,7 @@ void GBufferPass::DrawDecals(RenderContext& renderContext, GPUTextureView* light
transform.Scale *= decal->GetSize();
renderContext.View.GetWorldMatrix(transform, drawCall.World);
drawCall.ObjectPosition = drawCall.World.GetTranslation();
drawCall.ObjectRadius = decal->GetSphere().Radius;
context->ResetRenderTarget();

View File

@@ -26,7 +26,7 @@ PACK_STRUCT(struct HistogramData {
GPUBuffer* HistogramPass::Render(RenderContext& renderContext, GPUTexture* colorBuffer)
{
auto device = GPUDevice::Instance;
auto context = device->GetMainContext();;
auto context = device->GetMainContext();
if (checkIfSkipPass() || !_isSupported)
return nullptr;

View File

@@ -855,6 +855,7 @@ DRAW:
{
auto& batch = BatchedDrawCalls.Get()[list.PreBatchedDrawCalls.Get()[i]];
auto drawCall = batch.DrawCall;
drawCall.ObjectRadius = 0.0f;
bindParams.FirstDrawCall = &drawCall;
const auto* instancesData = batch.Instances.Get();

View File

@@ -85,6 +85,7 @@ public:
static MClass* GetClass(MClass* elementKlass);
static int32 GetLength(const MArray* obj);
static void* GetAddress(const MArray* obj);
static MArray* Unbox(MObject* obj);
template<typename T>
FORCE_INLINE static T* GetAddress(const MArray* obj)

View File

@@ -363,11 +363,12 @@ struct MConverter<Array<T>>
void Unbox(Array<T>& result, MObject* data)
{
const int32 length = data ? MCore::Array::GetLength((MArray*)data) : 0;
MArray* array = MCore::Array::Unbox(data);
const int32 length = array ? MCore::Array::GetLength(array) : 0;
result.Resize(length);
MConverter<T> converter;
Span<T> resultSpan(result.Get(), length);
converter.ToNativeArray(resultSpan, (MArray*)data);
converter.ToNativeArray(resultSpan, array);
}
};

View File

@@ -408,6 +408,12 @@ void* MCore::Array::GetAddress(const MArray* obj)
return CallStaticMethod<void*, void*>(GetArrayPointerPtr, (void*)obj);
}
MArray* MCore::Array::Unbox(MObject* obj)
{
static void* GetArrayPtr = GetStaticMethodPointer(TEXT("GetArray"));
return (MArray*)CallStaticMethod<void*, void*>(GetArrayPtr, (void*)obj);
}
MGCHandle MCore::GCHandle::New(MObject* obj, bool pinned)
{
ASSERT(obj);

View File

@@ -804,6 +804,11 @@ void* MCore::Array::GetAddress(const MArray* obj)
return mono_array_addr_with_size((MonoArray*)obj, 0, 0);
}
MArray* MCore::Array::Unbox(MObject* obj)
{
return (MArray*)obj;
}
MGCHandle MCore::GCHandle::New(MObject* obj, bool pinned)
{
return mono_gchandle_new(obj, pinned);

View File

@@ -141,6 +141,11 @@ void* MCore::Array::GetAddress(const MArray* obj)
return nullptr;
}
MArray* MCore::Array::Unbox(MObject* obj)
{
return nullptr;
}
MGCHandle MCore::GCHandle::New(MObject* obj, bool pinned)
{
return (MGCHandle)(uintptr)obj;

View File

@@ -45,7 +45,7 @@ bool TerrainChunk::PrepareDraw(const RenderContext& renderContext)
// Calculate chunk distance to view
const auto lodView = (renderContext.LodProxyView ? renderContext.LodProxyView : &renderContext.View);
const float distance = Float3::Distance(_boundsCenter - lodView->Origin, lodView->Position);
const float distance = Float3::Distance(_sphere.Center - lodView->Origin, lodView->Position);
lod = (int32)Math::Pow(distance / chunkEdgeSize, lodDistribution);
lod += lodBias;
@@ -88,6 +88,7 @@ void TerrainChunk::Draw(const RenderContext& renderContext) const
drawCall.Material = _cachedDrawMaterial;
renderContext.View.GetWorldMatrix(_transform, drawCall.World);
drawCall.ObjectPosition = drawCall.World.GetTranslation();
drawCall.ObjectRadius = _sphere.Radius;
drawCall.Terrain.Patch = _patch;
drawCall.Terrain.HeightmapUVScaleBias = _heightmapUVScaleBias;
drawCall.Terrain.OffsetUV = Vector2((float)(_patch->_x * TerrainPatch::CHUNKS_COUNT_EDGE + _x), (float)(_patch->_z * TerrainPatch::CHUNKS_COUNT_EDGE + _z));
@@ -145,6 +146,7 @@ void TerrainChunk::Draw(const RenderContext& renderContext, MaterialBase* materi
drawCall.Material = material;
renderContext.View.GetWorldMatrix(_transform, drawCall.World);
drawCall.ObjectPosition = drawCall.World.GetTranslation();
drawCall.ObjectRadius = _sphere.Radius;
drawCall.Terrain.Patch = _patch;
drawCall.Terrain.HeightmapUVScaleBias = _heightmapUVScaleBias;
drawCall.Terrain.OffsetUV = Vector2((float)(_patch->_x * TerrainPatch::CHUNKS_COUNT_EDGE + _x), (float)(_patch->_z * TerrainPatch::CHUNKS_COUNT_EDGE + _z));
@@ -202,7 +204,7 @@ void TerrainChunk::UpdateBounds()
OrientedBoundingBox obb(Vector3::Zero, Vector3::One);
obb.Transform(localTransform);
obb.GetBoundingBox(_bounds);
_boundsCenter = _bounds.GetCenter();
BoundingSphere::FromBox(_bounds, _sphere);
_bounds.Minimum -= boundsExtent;
_bounds.Maximum += boundsExtent;

View File

@@ -3,6 +3,7 @@
#pragma once
#include "Engine/Core/Math/BoundingBox.h"
#include "Engine/Core/Math/BoundingSphere.h"
#include "Engine/Core/Math/Matrix.h"
#include "Engine/Core/Math/Transform.h"
#include "Engine/Core/ISerializable.h"
@@ -29,7 +30,7 @@ private:
Float4 _heightmapUVScaleBias;
Transform _transform;
BoundingBox _bounds;
Vector3 _boundsCenter;
BoundingSphere _sphere;
float _perInstanceRandom;
float _yOffset, _yHeight;

View File

@@ -717,13 +717,13 @@ bool ModelTool::ImportDataAssimp(const char* path, ImportedModelData& data, Opti
if (EnumHasAnyFlags(data.Types, ImportDataTypes::Geometry) && context->Scene->HasMeshes())
{
const int meshCount = context->Scene->mNumMeshes;
if (options.SplitObjects && options.ObjectIndex == -1)
if (options.SplitObjects && options.ObjectIndex == -1 && meshCount > 1)
{
// Import the first object within this call
options.SplitObjects = false;
options.ObjectIndex = 0;
if (meshCount > 1 && options.OnSplitImport.IsBinded())
if (options.OnSplitImport.IsBinded())
{
// Split all animations into separate assets
LOG(Info, "Splitting imported {0} meshes", meshCount);
@@ -790,13 +790,13 @@ bool ModelTool::ImportDataAssimp(const char* path, ImportedModelData& data, Opti
if (EnumHasAnyFlags(data.Types, ImportDataTypes::Animations) && context->Scene->HasAnimations())
{
const int32 animCount = (int32)context->Scene->mNumAnimations;
if (options.SplitObjects && options.ObjectIndex == -1)
if (options.SplitObjects && options.ObjectIndex == -1 && animCount > 1)
{
// Import the first object within this call
options.SplitObjects = false;
options.ObjectIndex = 0;
if (animCount > 1 && options.OnSplitImport.IsBinded())
if (options.OnSplitImport.IsBinded())
{
// Split all animations into separate assets
LOG(Info, "Splitting imported {0} animations", animCount);

View File

@@ -1245,13 +1245,13 @@ bool ModelTool::ImportDataOpenFBX(const char* path, ImportedModelData& data, Opt
if (EnumHasAnyFlags(data.Types, ImportDataTypes::Geometry) && context->Scene->getMeshCount() > 0)
{
const int meshCount = context->Scene->getMeshCount();
if (options.SplitObjects && options.ObjectIndex == -1)
if (options.SplitObjects && options.ObjectIndex == -1 && meshCount > 1)
{
// Import the first object within this call
options.SplitObjects = false;
options.ObjectIndex = 0;
if (meshCount > 1 && options.OnSplitImport.IsBinded())
if (options.OnSplitImport.IsBinded())
{
// Split all animations into separate assets
LOG(Info, "Splitting imported {0} meshes", meshCount);
@@ -1328,13 +1328,13 @@ bool ModelTool::ImportDataOpenFBX(const char* path, ImportedModelData& data, Opt
if (EnumHasAnyFlags(data.Types, ImportDataTypes::Animations))
{
const int animCount = context->Scene->getAnimationStackCount();
if (options.SplitObjects && options.ObjectIndex == -1)
if (options.SplitObjects && options.ObjectIndex == -1 && animCount > 1)
{
// Import the first object within this call
options.SplitObjects = false;
options.ObjectIndex = 0;
if (animCount > 1 && options.OnSplitImport.IsBinded())
if (options.OnSplitImport.IsBinded())
{
// Split all animations into separate assets
LOG(Info, "Splitting imported {0} animations", animCount);

View File

@@ -16,6 +16,7 @@
#include "Engine/Graphics/Textures/TextureData.h"
#include "Engine/Graphics/Models/ModelData.h"
#include "Engine/Content/Assets/Model.h"
#include "Engine/Content/Content.h"
#include "Engine/Serialization/MemoryWriteStream.h"
#if USE_EDITOR
#include "Engine/Core/Types/DateTime.h"
@@ -909,6 +910,10 @@ bool ModelTool::ImportModel(const String& path, ModelData& meshData, Options& op
{
auto& texture = data.Textures[i];
// When splitting imported meshes allow only the first mesh to import assets (mesh[0] is imported after all following ones so import assets during mesh[1])
if (!options.SplitObjects && options.ObjectIndex != 1 && options.ObjectIndex != -1)
continue;
// Auto-import textures
if (autoImportOutput.IsEmpty() || (data.Types & ImportDataTypes::Textures) == ImportDataTypes::None || texture.FilePath.IsEmpty())
continue;
@@ -994,6 +999,17 @@ bool ModelTool::ImportModel(const String& path, ModelData& meshData, Options& op
materialOptions.Info.CullMode = CullMode::TwoSided;
if (!Math::IsOne(material.Opacity.Value) || material.Opacity.TextureIndex != -1)
materialOptions.Info.BlendMode = MaterialBlendMode::Transparent;
// When splitting imported meshes allow only the first mesh to import assets (mesh[0] is imported after all following ones so import assets during mesh[1])
if (!options.SplitObjects && options.ObjectIndex != 1 && options.ObjectIndex != -1)
{
// Find that asset create previously
AssetInfo info;
if (Content::GetAssetInfo(assetPath, info))
material.AssetID = info.ID;
continue;
}
AssetsImportingManager::Create(AssetsImportingManager::CreateMaterialTag, assetPath, material.AssetID, &materialOptions);
#endif
}

View File

@@ -366,6 +366,7 @@ void TextRender::Draw(RenderContext& renderContext)
DrawCall drawCall;
drawCall.World = world;
drawCall.ObjectPosition = drawCall.World.GetTranslation();
drawCall.ObjectRadius = _sphere.Radius;
drawCall.Surface.GeometrySize = _localBox.GetSize();
drawCall.Surface.PrevWorld = _drawState.PrevWorld;
drawCall.Surface.Lightmap = nullptr;

View File

@@ -12,6 +12,7 @@ namespace Flax.Build.Tests
[Test, Sequential]
public void TestParseOptionOnly([Values(
"-something",
"something",
" \t \t-\t \tsomething\t ",
"-something=")]
string commandLine)
@@ -25,6 +26,11 @@ namespace Flax.Build.Tests
[Test, Sequential]
public void TestParseOneValue([Values(
"-something=value",
"something=value",
"-something=\"value\"",
"-something=\\\"value\\\"",
"\"-something=\"value\"\"",
"\"-something=\\\"value\\\"\"",
" \t \t-\t \tsomething\t =value ",
"-something=value ")]
string commandLine)

View File

@@ -191,19 +191,12 @@ namespace Flax.Build
}
case TargetPlatform.Linux:
{
// TODO: Support /etc/dotnet/install_location
// Detect custom RID in some distros
rid = Utilities.ReadProcessOutput("dotnet", "--info").Split('\n').FirstOrDefault(x => x.StartsWith(" RID:"), "").Replace("RID:", "").Trim();
ridFallback = $"linux-{arch}";
if (rid == ridFallback)
ridFallback = "";
rid = $"linux-{arch}";
ridFallback = "";
if (string.IsNullOrEmpty(dotnetPath))
{
dotnetPath = "/usr/lib/dotnet/";
if (!Directory.Exists(dotnetPath))
dotnetPath = "/usr/share/dotnet/";
}
dotnetPath ??= SearchForDotnetLocationLinux();
if (dotnetPath == null)
ridFallback = Utilities.ReadProcessOutput("dotnet", "--info").Split('\n').FirstOrDefault(x => x.StartsWith(" RID:"), "").Replace("RID:", "").Trim();
break;
}
case TargetPlatform.Mac:
@@ -211,7 +204,16 @@ namespace Flax.Build
rid = $"osx-{arch}";
ridFallback = "";
if (string.IsNullOrEmpty(dotnetPath))
{
dotnetPath = "/usr/local/share/dotnet/";
if (!Directory.Exists(dotnetPath)) // Officially recommended dotnet location
{
if (Environment.GetEnvironmentVariable("PATH") is string globalBinPath)
dotnetPath = globalBinPath.Split(':').FirstOrDefault(x => File.Exists(Path.Combine(x, "dotnet")));
else
dotnetPath = string.Empty;
}
}
// Use x64 when cross-compiling from ARM64
if (architecture == TargetArchitecture.ARM64 && (Configuration.BuildArchitectures != null && Configuration.BuildArchitectures[0] == TargetArchitecture.x64))
@@ -436,7 +438,8 @@ namespace Flax.Build
version = version.Substring(0, version.IndexOf("-"));
rev = 0;
}
Version ver = new Version(version);
if (!Version.TryParse(version, out var ver))
return null;
return new Version(ver.Major, ver.Minor, ver.Build, rev);
}
@@ -450,5 +453,18 @@ namespace Flax.Build
// TODO: reject 'future' versions like .Net 8?
return versions.OrderByDescending(ParseVersion).FirstOrDefault();
}
private static string SearchForDotnetLocationLinux()
{
if (File.Exists("/etc/dotnet/install_location")) // Officially recommended dotnet location file
return File.ReadAllText("/etc/dotnet/install_location").Trim();
if (File.Exists("/usr/share/dotnet/dotnet")) // Officially recommended dotnet location
return "/usr/share/dotnet";
if (File.Exists("/usr/lib/dotnet/dotnet")) // Deprecated recommended dotnet location
return "/usr/lib/dotnet";
if (Environment.GetEnvironmentVariable("PATH") is string globalBinPath) // Searching for dotnet binary
return globalBinPath.Split(':').FirstOrDefault(x => File.Exists(Path.Combine(x, "dotnet")));
return null;
}
}
}

View File

@@ -249,6 +249,8 @@ namespace Flax.Build
var wholeQuote = commandLine[i] == '\"';
if (wholeQuote)
i++;
if (i == length)
break;
if (commandLine[i] == '-')
i++;
else if (commandLine[i] == '/')
@@ -279,7 +281,7 @@ namespace Flax.Build
});
if (wholeQuote)
i++;
if (i != length && commandLine[i] != '\"')
if (i < length && commandLine[i] != '\"')
i++;
continue;
}
@@ -287,23 +289,36 @@ namespace Flax.Build
// Read value
i++;
int valueStart, valueEnd;
if (commandLine[i] == '\"')
if (commandLine.Length > i + 1 && commandLine[i] == '\\' && commandLine[i + 1] == '\"')
{
valueStart = i + 1;
valueStart = i + 2;
i++;
while (i < length && commandLine[i] != '\"')
while (i + 1 < length && commandLine[i] != '\\' && commandLine[i + 1] != '\"')
i++;
valueEnd = i;
i++;
i += 2;
if (wholeQuote)
{
while (i < length && commandLine[i] != '\"')
i++;
i++;
}
}
else if (commandLine[i] == '\'')
else if (commandLine[i] == '\"' || commandLine[i] == '\'')
{
var quoteChar = commandLine[i];
valueStart = i + 1;
i++;
while (i < length && commandLine[i] != '\'')
while (i < length && commandLine[i] != quoteChar)
i++;
valueEnd = i;
i++;
if (wholeQuote)
{
while (i < length && commandLine[i] != '\"')
i++;
i++;
}
}
else if (wholeQuote)
{
@@ -321,10 +336,13 @@ namespace Flax.Build
valueEnd = i;
}
string value = commandLine.Substring(valueStart, valueEnd - valueStart);
value = value.Trim();
if (value.StartsWith("\\\"") && value.EndsWith("\\\""))
value = value.Substring(2, value.Length - 4);
options.Add(new Option
{
Name = name,
Value = value.Trim()
Value = value
});
}