Fix code style
This commit is contained in:
@@ -115,11 +115,9 @@ namespace FlaxEditor.Viewport.Previews
|
||||
var color = Color;
|
||||
if (!EnabledInHierarchy)
|
||||
color *= 0.4f;
|
||||
var sampleValueScale = height / info.NumChannels;
|
||||
|
||||
// Compute the scaled y-value used to render the channel data
|
||||
float sampleYScale = height / info.NumChannels;
|
||||
|
||||
// Compute amount of samples that are contained in the view
|
||||
// Calculate the amount of samples that are contained in the view
|
||||
float unitsPerSecond = UnitsPerSecond * ViewScale;
|
||||
float clipDefaultWidth = length * unitsPerSecond;
|
||||
float clipsInView = width / clipDefaultWidth;
|
||||
@@ -173,7 +171,7 @@ namespace FlaxEditor.Viewport.Previews
|
||||
if (samplesInPixel > 0)
|
||||
{
|
||||
float sampleValueAvg = samplesSum / samplesInPixel;
|
||||
float sampleValueAvgScaled = sampleValueAvg * sampleYScale;
|
||||
float sampleValueAvgScaled = sampleValueAvg * sampleValueScale;
|
||||
if (sampleValueAvgScaled > 0.1f)
|
||||
{
|
||||
Render2D.DrawLine(new Vector2(pixelX, yCenter - sampleValueAvgScaled), new Vector2(pixelX, yCenter + sampleValueAvgScaled), color);
|
||||
|
||||
@@ -300,46 +300,35 @@ float IESLoader::ComputeFilterPos(float value, const Array<float>& sortedValues)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
if (value > sortedValues[endPos])
|
||||
{
|
||||
return static_cast<float>(endPos);
|
||||
}
|
||||
|
||||
// Binary search
|
||||
while (startPos < endPos)
|
||||
{
|
||||
const uint32 testPos = (startPos + endPos + 1) / 2;
|
||||
|
||||
const float testValue = sortedValues[testPos];
|
||||
|
||||
if (value >= testValue)
|
||||
{
|
||||
// Prevent endless loop
|
||||
ASSERT(startPos != testPos);
|
||||
|
||||
startPos = testPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Prevent endless loop
|
||||
ASSERT(endPos != testPos - 1);
|
||||
|
||||
endPos = testPos - 1;
|
||||
}
|
||||
}
|
||||
|
||||
const float leftValue = sortedValues[startPos];
|
||||
|
||||
float fraction = 0.0f;
|
||||
|
||||
if (startPos + 1 < static_cast<uint32>(sortedValues.Count()))
|
||||
{
|
||||
// If not at right border
|
||||
const float rightValue = sortedValues[startPos + 1];
|
||||
const float deltaValue = rightValue - leftValue;
|
||||
|
||||
if (deltaValue > 0.0001f)
|
||||
if (deltaValue > 0.00005f)
|
||||
{
|
||||
fraction = (value - leftValue) / deltaValue;
|
||||
}
|
||||
|
||||
@@ -45,22 +45,13 @@ uint32 Math::FloorLog2(uint32 value)
|
||||
|
||||
Vector3 Math::RotateAboutAxis(const Vector3& normalizedRotationAxis, float angle, const Vector3& positionOnAxis, const Vector3& position)
|
||||
{
|
||||
// Project position onto the rotation axis and find the closest point on the axis to Position
|
||||
const Vector3 closestPointOnAxis = positionOnAxis + normalizedRotationAxis * Vector3::Dot(normalizedRotationAxis, position - positionOnAxis);
|
||||
|
||||
// Construct orthogonal axes in the plane of the rotation
|
||||
const Vector3 axisU = position - closestPointOnAxis;
|
||||
const Vector3 axisV = Vector3::Cross(normalizedRotationAxis, axisU);
|
||||
float cosAngle, sinAngle;
|
||||
Math::SinCos(angle, sinAngle, cosAngle);
|
||||
|
||||
// Rotate using the orthogonal axes
|
||||
const Vector3 rotation = axisU * cosAngle + axisV * sinAngle;
|
||||
|
||||
// Reconstruct the rotated world space position
|
||||
const Vector3 rotatedPosition = closestPointOnAxis + rotation;
|
||||
|
||||
// Convert from position to a position offset
|
||||
return rotatedPosition - position;
|
||||
}
|
||||
|
||||
|
||||
@@ -216,7 +216,6 @@ void Plane::Transform(Plane planes[], int32 planesCount, const Quaternion& rotat
|
||||
const float y = planes[i].Normal.Y;
|
||||
const float z = planes[i].Normal.Z;
|
||||
|
||||
// Factor common arithmetic out of loop
|
||||
planes[i].Normal.X = x * (1.0f - yy - zz) + y * (xy - wz) + z * (xz + wy);
|
||||
planes[i].Normal.Y = x * (xy + wz) + y * (1.0f - xx - zz) + z * (yz - wx);
|
||||
planes[i].Normal.Z = x * (xz - wy) + y * (yz + wx) + z * (1.0f - xx - yy);
|
||||
|
||||
@@ -56,7 +56,6 @@ int32 DateTime::GetDay() const
|
||||
|
||||
DayOfWeek DateTime::GetDayOfWeek() const
|
||||
{
|
||||
// January 1, 0001 was a Monday
|
||||
return static_cast<DayOfWeek>((Ticks / Constants::TicksPerDay) % 7);
|
||||
}
|
||||
|
||||
@@ -64,8 +63,8 @@ int32 DateTime::GetDayOfYear() const
|
||||
{
|
||||
int32 year, month, day;
|
||||
GetDate(year, month, day);
|
||||
for (int32 currentMonth = 1; currentMonth < month; currentMonth++)
|
||||
day += DaysInMonth(year, currentMonth);
|
||||
for (int32 i = 1; i < month; i++)
|
||||
day += DaysInMonth(year, i);
|
||||
return day;
|
||||
}
|
||||
|
||||
@@ -131,13 +130,7 @@ DateTime DateTime::NowUTC()
|
||||
|
||||
bool DateTime::Validate(int32 year, int32 month, int32 day, int32 hour, int32 minute, int32 second, int32 millisecond)
|
||||
{
|
||||
return (year >= 1) && (year <= 9999) &&
|
||||
(month >= 1) && (month <= 12) &&
|
||||
(day >= 1) && (day <= DaysInMonth(year, month)) &&
|
||||
(hour >= 0) && (hour <= 23) &&
|
||||
(minute >= 0) && (minute <= 59) &&
|
||||
(second >= 0) && (second <= 59) &&
|
||||
(millisecond >= 0) && (millisecond <= 999);
|
||||
return year >= 1 && year <= 999999 && month >= 1 && month <= 12 && day >= 1 && day <= DaysInMonth(year, month) && hour >= 0 && hour <= 23 && minute >= 0 && minute <= 59 && second >= 0 && second <= 59 && millisecond >= 0 && millisecond <= 999;
|
||||
}
|
||||
|
||||
String DateTime::ToString() const
|
||||
|
||||
@@ -33,7 +33,7 @@ TimeSpan TimeSpan::FromSeconds(double seconds)
|
||||
return TimeSpan(static_cast<int64>(seconds * Constants::TicksPerSecond));
|
||||
}
|
||||
|
||||
void TimeSpan::Assign(int32 days, int32 hours, int32 minutes, int32 seconds, int32 milliseconds)
|
||||
void TimeSpan::Set(int32 days, int32 hours, int32 minutes, int32 seconds, int32 milliseconds)
|
||||
{
|
||||
const int64 totalMs = 1000 * (60 * 60 * 24 * (int64)days + 60 * 60 * (int64)hours + 60 * (int64)minutes + (int64)seconds) + (int64)milliseconds;
|
||||
ASSERT_LOW_LAYER((totalMs >= MinValue().GetTotalMilliseconds()) && (totalMs <= MaxValue().GetTotalMilliseconds()));
|
||||
|
||||
@@ -49,8 +49,10 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
// Init
|
||||
// @param ticks The number of ticks
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TimeSpan"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="ticks">The ticks in 100 nanoseconds resolution.</param>
|
||||
TimeSpan(int64 ticks)
|
||||
: Ticks(ticks)
|
||||
{
|
||||
@@ -62,7 +64,7 @@ public:
|
||||
// @param Minutes Amount of minutes
|
||||
TimeSpan(int32 days, int32 hours, int32 minutes)
|
||||
{
|
||||
Assign(days, hours, minutes, 0, 0);
|
||||
Set(days, hours, minutes, 0, 0);
|
||||
}
|
||||
|
||||
// Init
|
||||
@@ -72,7 +74,7 @@ public:
|
||||
// @param Seconds Amount of seconds
|
||||
TimeSpan(int32 days, int32 hours, int32 minutes, int32 seconds)
|
||||
{
|
||||
Assign(days, hours, minutes, seconds, 0);
|
||||
Set(days, hours, minutes, seconds, 0);
|
||||
}
|
||||
|
||||
// Init
|
||||
@@ -83,7 +85,7 @@ public:
|
||||
// @param Milliseconds Amount of milliseconds
|
||||
TimeSpan(int32 days, int32 hours, int32 minutes, int32 seconds, int32 milliseconds)
|
||||
{
|
||||
Assign(days, hours, minutes, seconds, milliseconds);
|
||||
Set(days, hours, minutes, seconds, milliseconds);
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -325,7 +327,7 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
void Assign(int32 days, int32 hours, int32 minutes, int32 seconds, int32 milliseconds);
|
||||
void Set(int32 days, int32 hours, int32 minutes, int32 seconds, int32 milliseconds);
|
||||
};
|
||||
|
||||
inline TimeSpan operator*(float scalar, const TimeSpan& timespan)
|
||||
|
||||
@@ -46,13 +46,13 @@ public:
|
||||
{
|
||||
ASSERT(_subresourceState.IsEmpty() && subresourceCount > 0);
|
||||
|
||||
// Allocate space for per-subresource tracking structures
|
||||
if (usePerSubresourceTracking && subresourceCount > 1)
|
||||
_subresourceState.Resize(subresourceCount, false);
|
||||
|
||||
// Initialize state
|
||||
_allSubresourcesSame = true;
|
||||
_resourceState = initialState;
|
||||
|
||||
// Allocate space for per-subresource state tracking
|
||||
if (usePerSubresourceTracking && subresourceCount > 1)
|
||||
_subresourceState.Resize(subresourceCount, false);
|
||||
#if BUILD_DEBUG
|
||||
_subresourceState.SetAll(InvalidState);
|
||||
#endif
|
||||
@@ -124,7 +124,7 @@ public:
|
||||
|
||||
void SetSubresourceState(int32 subresourceIndex, StateType state)
|
||||
{
|
||||
// If setting all subresources, or the resource only has a single subresource, set the per-resource state
|
||||
// Check if use single state for the whole resource
|
||||
if (subresourceIndex == -1 || _subresourceState.Count() <= 1)
|
||||
{
|
||||
SetResourceState(state);
|
||||
@@ -133,16 +133,14 @@ public:
|
||||
{
|
||||
ASSERT(subresourceIndex < static_cast<int32>(_subresourceState.Count()));
|
||||
|
||||
// If state was previously tracked on a per-resource level, then transition to per-subresource tracking
|
||||
// Transition for all sub-resources
|
||||
if (_allSubresourcesSame)
|
||||
{
|
||||
for (int32 i = 0; i < _subresourceState.Count(); i++)
|
||||
{
|
||||
_subresourceState[i] = _resourceState;
|
||||
}
|
||||
|
||||
_allSubresourcesSame = 0;
|
||||
|
||||
#if BUILD_DEBUG
|
||||
_resourceState = InvalidState;
|
||||
#endif
|
||||
|
||||
@@ -23,9 +23,8 @@
|
||||
#define DX11_FORCE_USE_DX10 0
|
||||
#define DX11_FORCE_USE_DX10_1 0
|
||||
|
||||
static bool TryCreateDevice(IDXGIAdapter* adapter, D3D_FEATURE_LEVEL maxFeatureLevel, D3D_FEATURE_LEVEL* outFeatureLevel)
|
||||
static bool TryCreateDevice(IDXGIAdapter* adapter, D3D_FEATURE_LEVEL maxFeatureLevel, D3D_FEATURE_LEVEL* featureLevel)
|
||||
{
|
||||
// Temporary data
|
||||
ID3D11Device* device = nullptr;
|
||||
ID3D11DeviceContext* context = nullptr;
|
||||
uint32 deviceFlags = D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_BGRA_SUPPORT;
|
||||
@@ -33,26 +32,22 @@ static bool TryCreateDevice(IDXGIAdapter* adapter, D3D_FEATURE_LEVEL maxFeatureL
|
||||
deviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
#endif
|
||||
|
||||
D3D_FEATURE_LEVEL requestedFeatureLevels[] =
|
||||
// Pick the first level
|
||||
D3D_FEATURE_LEVEL featureLevels[] =
|
||||
{
|
||||
D3D_FEATURE_LEVEL_11_1,
|
||||
D3D_FEATURE_LEVEL_11_0,
|
||||
D3D_FEATURE_LEVEL_10_1,
|
||||
D3D_FEATURE_LEVEL_10_0
|
||||
};
|
||||
|
||||
int32 firstAllowedFeatureLevel = 0;
|
||||
int32 numAllowedFeatureLevels = ARRAY_COUNT(requestedFeatureLevels);
|
||||
while (firstAllowedFeatureLevel < numAllowedFeatureLevels)
|
||||
int32 levelIndex = 0;
|
||||
while (levelIndex < ARRAY_COUNT(featureLevels))
|
||||
{
|
||||
if (requestedFeatureLevels[firstAllowedFeatureLevel] == maxFeatureLevel)
|
||||
{
|
||||
if (featureLevels[levelIndex] == maxFeatureLevel)
|
||||
break;
|
||||
}
|
||||
firstAllowedFeatureLevel++;
|
||||
levelIndex++;
|
||||
}
|
||||
numAllowedFeatureLevels -= firstAllowedFeatureLevel;
|
||||
if (numAllowedFeatureLevels == 0)
|
||||
if (levelIndex >= ARRAY_COUNT(featureLevels))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -63,18 +58,16 @@ static bool TryCreateDevice(IDXGIAdapter* adapter, D3D_FEATURE_LEVEL maxFeatureL
|
||||
D3D_DRIVER_TYPE_UNKNOWN,
|
||||
NULL,
|
||||
deviceFlags,
|
||||
&requestedFeatureLevels[firstAllowedFeatureLevel],
|
||||
numAllowedFeatureLevels,
|
||||
&featureLevels[levelIndex],
|
||||
ARRAY_COUNT(featureLevels) - levelIndex,
|
||||
D3D11_SDK_VERSION,
|
||||
&device,
|
||||
outFeatureLevel,
|
||||
featureLevel,
|
||||
&context
|
||||
)))
|
||||
{
|
||||
// Release created stuff
|
||||
device->Release();
|
||||
context->Release();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -144,10 +144,8 @@ bool GPUTextureDX12::OnInit()
|
||||
{
|
||||
resourceDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
|
||||
initialState = D3D12_RESOURCE_STATE_DEPTH_WRITE;
|
||||
|
||||
if (!useSRV)
|
||||
{
|
||||
// Only deny shader resources if it's a depth resource that will never be used as SRV
|
||||
resourceDesc.Flags |= D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ void QueryHeapDX12::EndQueryBatchAndResolveQueryData(GPUContextDX12* context)
|
||||
{
|
||||
ASSERT(_currentBatch.Open);
|
||||
|
||||
// Discard empty batches
|
||||
// Skip empty batches
|
||||
if (_currentBatch.Count == 0)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -297,7 +297,7 @@ void CmdBufferManagerVulkan::PrepareForNewActiveCommandBuffer()
|
||||
}
|
||||
}
|
||||
|
||||
// All cmd buffers are being executed still
|
||||
// Always begin fresh command buffer for rendering
|
||||
_activeCmdBuffer = _pool.Create();
|
||||
_activeCmdBuffer->Begin();
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ void DescriptorSetLayoutInfoVulkan::CacheTypesUsageID()
|
||||
|
||||
void DescriptorSetLayoutInfoVulkan::AddDescriptor(int32 descriptorSetIndex, const VkDescriptorSetLayoutBinding& descriptor)
|
||||
{
|
||||
// Increment type usage
|
||||
_layoutTypes[descriptor.descriptorType]++;
|
||||
|
||||
if (descriptorSetIndex >= _setLayouts.Count())
|
||||
@@ -43,7 +42,6 @@ void DescriptorSetLayoutInfoVulkan::AddDescriptor(int32 descriptorSetIndex, cons
|
||||
SetLayout& descSetLayout = _setLayouts[descriptorSetIndex];
|
||||
descSetLayout.LayoutBindings.Add(descriptor);
|
||||
|
||||
// TODO: manual hash update method?
|
||||
_hash = Crc::MemCrc32(&descriptor, sizeof(descriptor), _hash);
|
||||
}
|
||||
|
||||
@@ -116,20 +114,20 @@ void DescriptorSetLayoutVulkan::Compile()
|
||||
DescriptorPoolVulkan::DescriptorPoolVulkan(GPUDeviceVulkan* device, const DescriptorSetLayoutVulkan& layout)
|
||||
: _device(device)
|
||||
, _handle(VK_NULL_HANDLE)
|
||||
, DescriptorSetsMax(0)
|
||||
, AllocatedDescriptorSetsCount(0)
|
||||
, AllocatedDescriptorSetsCountMax(0)
|
||||
, Layout(layout)
|
||||
, _descriptorSetsMax(0)
|
||||
, _allocatedDescriptorSetsCount(0)
|
||||
, _allocatedDescriptorSetsCountMax(0)
|
||||
, _layout(layout)
|
||||
{
|
||||
Array<VkDescriptorPoolSize, FixedAllocation<VULKAN_DESCRIPTOR_TYPE_END + 1>> types;
|
||||
|
||||
// The maximum amount of descriptor sets layout allocations to hold
|
||||
const uint32 MaxSetsAllocations = 256;
|
||||
DescriptorSetsMax = MaxSetsAllocations * (VULKAN_HASH_POOLS_WITH_TYPES_USAGE_ID ? 1 : Layout.GetLayouts().Count());
|
||||
_descriptorSetsMax = MaxSetsAllocations * (VULKAN_HASH_POOLS_WITH_TYPES_USAGE_ID ? 1 : _layout.GetLayouts().Count());
|
||||
for (uint32 typeIndex = VULKAN_DESCRIPTOR_TYPE_BEGIN; typeIndex <= VULKAN_DESCRIPTOR_TYPE_END; typeIndex++)
|
||||
{
|
||||
const VkDescriptorType descriptorType = (VkDescriptorType)typeIndex;
|
||||
const uint32 typesUsed = Layout.GetTypesUsed(descriptorType);
|
||||
const uint32 typesUsed = _layout.GetTypesUsed(descriptorType);
|
||||
if (typesUsed > 0)
|
||||
{
|
||||
VkDescriptorPoolSize& type = types.AddOne();
|
||||
@@ -144,7 +142,7 @@ DescriptorPoolVulkan::DescriptorPoolVulkan(GPUDeviceVulkan* device, const Descri
|
||||
createInfo.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
|
||||
createInfo.poolSizeCount = types.Count();
|
||||
createInfo.pPoolSizes = types.Get();
|
||||
createInfo.maxSets = DescriptorSetsMax;
|
||||
createInfo.maxSets = _descriptorSetsMax;
|
||||
VALIDATE_VULKAN_RESULT(vkCreateDescriptorPool(_device->Device, &createInfo, nullptr, &_handle));
|
||||
}
|
||||
|
||||
@@ -156,16 +154,16 @@ DescriptorPoolVulkan::~DescriptorPoolVulkan()
|
||||
}
|
||||
}
|
||||
|
||||
void DescriptorPoolVulkan::TrackAddUsage(const DescriptorSetLayoutVulkan& layout)
|
||||
void DescriptorPoolVulkan::Track(const DescriptorSetLayoutVulkan& layout)
|
||||
{
|
||||
// Check and increment our current type usage
|
||||
#if !BUILD_RELEASE
|
||||
for (uint32 typeIndex = VULKAN_DESCRIPTOR_TYPE_BEGIN; typeIndex <= VULKAN_DESCRIPTOR_TYPE_END; typeIndex++)
|
||||
{
|
||||
ASSERT(Layout.GetTypesUsed((VkDescriptorType)typeIndex) == layout.GetTypesUsed((VkDescriptorType)typeIndex));
|
||||
ASSERT(_layout.GetTypesUsed((VkDescriptorType)typeIndex) == layout.GetTypesUsed((VkDescriptorType)typeIndex));
|
||||
}
|
||||
|
||||
AllocatedDescriptorSetsCount += layout.GetLayouts().Count();
|
||||
AllocatedDescriptorSetsCountMax = Math::Max(AllocatedDescriptorSetsCount, AllocatedDescriptorSetsCountMax);
|
||||
#endif
|
||||
_allocatedDescriptorSetsCount += layout.GetLayouts().Count();
|
||||
_allocatedDescriptorSetsCountMax = Math::Max(_allocatedDescriptorSetsCount, _allocatedDescriptorSetsCountMax);
|
||||
}
|
||||
|
||||
void DescriptorPoolVulkan::TrackRemoveUsage(const DescriptorSetLayoutVulkan& layout)
|
||||
@@ -173,10 +171,10 @@ void DescriptorPoolVulkan::TrackRemoveUsage(const DescriptorSetLayoutVulkan& lay
|
||||
// Check and increment our current type usage
|
||||
for (uint32 typeIndex = VULKAN_DESCRIPTOR_TYPE_BEGIN; typeIndex <= VULKAN_DESCRIPTOR_TYPE_END; typeIndex++)
|
||||
{
|
||||
ASSERT(Layout.GetTypesUsed((VkDescriptorType)typeIndex) == layout.GetTypesUsed((VkDescriptorType)typeIndex));
|
||||
ASSERT(_layout.GetTypesUsed((VkDescriptorType)typeIndex) == layout.GetTypesUsed((VkDescriptorType)typeIndex));
|
||||
}
|
||||
|
||||
AllocatedDescriptorSetsCount -= layout.GetLayouts().Count();
|
||||
_allocatedDescriptorSetsCount -= layout.GetLayouts().Count();
|
||||
}
|
||||
|
||||
void DescriptorPoolVulkan::Reset()
|
||||
@@ -185,7 +183,7 @@ void DescriptorPoolVulkan::Reset()
|
||||
{
|
||||
VALIDATE_VULKAN_RESULT(vkResetDescriptorPool(_device->Device, _handle, 0));
|
||||
}
|
||||
AllocatedDescriptorSetsCount = 0;
|
||||
_allocatedDescriptorSetsCount = 0;
|
||||
}
|
||||
|
||||
bool DescriptorPoolVulkan::AllocateDescriptorSets(const VkDescriptorSetAllocateInfo& descriptorSetAllocateInfo, VkDescriptorSet* result)
|
||||
@@ -335,8 +333,6 @@ void DescriptorPoolsManagerVulkan::ReleasePoolSet(DescriptorPoolSetContainerVulk
|
||||
void DescriptorPoolsManagerVulkan::GC()
|
||||
{
|
||||
ScopeLock lock(_locker);
|
||||
|
||||
// Pool sets are forward allocated - iterate from the back to increase the chance of finding an unused one
|
||||
for (int32 i = _poolSets.Count() - 1; i >= 0; i--)
|
||||
{
|
||||
const auto poolSet = _poolSets[i];
|
||||
@@ -374,12 +370,12 @@ PipelineLayoutVulkan::~PipelineLayoutVulkan()
|
||||
}
|
||||
}
|
||||
|
||||
uint32 DescriptorSetWriterVulkan::SetupDescriptorWrites(const SpirvShaderDescriptorInfo& info, VkWriteDescriptorSet* writeDescriptors, VkDescriptorImageInfo* imageInfo, VkDescriptorBufferInfo* bufferInfo, uint8* bindingToDynamicOffsetMap)
|
||||
uint32 DescriptorSetWriterVulkan::SetupDescriptorWrites(const SpirvShaderDescriptorInfo& info, VkWriteDescriptorSet* writeDescriptors, VkDescriptorImageInfo* imageInfo, VkDescriptorBufferInfo* bufferInfo, uint8* bindingToDynamicOffset)
|
||||
{
|
||||
ASSERT(info.DescriptorTypesCount <= 64);
|
||||
WriteDescriptors = writeDescriptors;
|
||||
WritesCount = info.DescriptorTypesCount;
|
||||
ASSERT(info.DescriptorTypesCount <= 64 && TEXT("Out of bits for Dirty Mask! More than 64 resources in one descriptor set!"));
|
||||
BindingToDynamicOffsetMap = bindingToDynamicOffsetMap;
|
||||
BindingToDynamicOffset = bindingToDynamicOffset;
|
||||
|
||||
uint32 dynamicOffsetIndex = 0;
|
||||
for (uint32 i = 0; i < info.DescriptorTypesCount; i++)
|
||||
@@ -392,8 +388,8 @@ uint32 DescriptorSetWriterVulkan::SetupDescriptorWrites(const SpirvShaderDescrip
|
||||
switch (writeDescriptors->descriptorType)
|
||||
{
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
|
||||
BindingToDynamicOffsetMap[i] = dynamicOffsetIndex;
|
||||
++dynamicOffsetIndex;
|
||||
BindingToDynamicOffset[i] = dynamicOffsetIndex;
|
||||
dynamicOffsetIndex++;
|
||||
writeDescriptors->pBufferInfo = bufferInfo++;
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
||||
|
||||
@@ -230,16 +230,15 @@ private:
|
||||
GPUDeviceVulkan* _device;
|
||||
VkDescriptorPool _handle;
|
||||
|
||||
uint32 DescriptorSetsMax;
|
||||
uint32 AllocatedDescriptorSetsCount;
|
||||
uint32 AllocatedDescriptorSetsCountMax;
|
||||
uint32 _descriptorSetsMax;
|
||||
uint32 _allocatedDescriptorSetsCount;
|
||||
uint32 _allocatedDescriptorSetsCountMax;
|
||||
|
||||
const DescriptorSetLayoutVulkan& Layout;
|
||||
const DescriptorSetLayoutVulkan& _layout;
|
||||
|
||||
public:
|
||||
|
||||
DescriptorPoolVulkan(GPUDeviceVulkan* device, const DescriptorSetLayoutVulkan& layout);
|
||||
|
||||
~DescriptorPoolVulkan();
|
||||
|
||||
public:
|
||||
@@ -251,25 +250,24 @@ public:
|
||||
|
||||
inline bool IsEmpty() const
|
||||
{
|
||||
return AllocatedDescriptorSetsCount == 0;
|
||||
return _allocatedDescriptorSetsCount == 0;
|
||||
}
|
||||
|
||||
inline bool CanAllocate(const DescriptorSetLayoutVulkan& layout) const
|
||||
{
|
||||
return DescriptorSetsMax > AllocatedDescriptorSetsCount + layout.GetLayouts().Count();
|
||||
return _descriptorSetsMax > _allocatedDescriptorSetsCount + layout.GetLayouts().Count();
|
||||
}
|
||||
|
||||
inline uint32 GetAllocatedDescriptorSetsCount() const
|
||||
{
|
||||
return AllocatedDescriptorSetsCount;
|
||||
return _allocatedDescriptorSetsCount;
|
||||
}
|
||||
|
||||
void TrackAddUsage(const DescriptorSetLayoutVulkan& layout);
|
||||
public:
|
||||
|
||||
void Track(const DescriptorSetLayoutVulkan& layout);
|
||||
void TrackRemoveUsage(const DescriptorSetLayoutVulkan& layout);
|
||||
|
||||
void Reset();
|
||||
|
||||
bool AllocateDescriptorSets(const VkDescriptorSetAllocateInfo& descriptorSetAllocateInfo, VkDescriptorSet* result);
|
||||
};
|
||||
|
||||
@@ -416,14 +414,14 @@ struct DescriptorSetWriteContainerVulkan
|
||||
Array<VkDescriptorImageInfo> DescriptorImageInfo;
|
||||
Array<VkDescriptorBufferInfo> DescriptorBufferInfo;
|
||||
Array<VkWriteDescriptorSet> DescriptorWrites;
|
||||
Array<uint8> BindingToDynamicOffsetMap;
|
||||
Array<byte> BindingToDynamicOffset;
|
||||
|
||||
void Release()
|
||||
{
|
||||
DescriptorImageInfo.Resize(0);
|
||||
DescriptorBufferInfo.Resize(0);
|
||||
DescriptorWrites.Resize(0);
|
||||
BindingToDynamicOffsetMap.Resize(0);
|
||||
BindingToDynamicOffset.Resize(0);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -431,24 +429,14 @@ class DescriptorSetWriterVulkan
|
||||
{
|
||||
public:
|
||||
|
||||
VkWriteDescriptorSet* WriteDescriptors;
|
||||
uint8* BindingToDynamicOffsetMap;
|
||||
uint32* DynamicOffsets;
|
||||
uint32 WritesCount;
|
||||
VkWriteDescriptorSet* WriteDescriptors = nullptr;
|
||||
byte* BindingToDynamicOffset = nullptr;
|
||||
uint32* DynamicOffsets = nullptr;
|
||||
uint32 WritesCount = 0;
|
||||
|
||||
public:
|
||||
|
||||
DescriptorSetWriterVulkan()
|
||||
: WriteDescriptors(nullptr)
|
||||
, BindingToDynamicOffsetMap(nullptr)
|
||||
, DynamicOffsets(nullptr)
|
||||
, WritesCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
uint32 SetupDescriptorWrites(const SpirvShaderDescriptorInfo& info, VkWriteDescriptorSet* writeDescriptors, VkDescriptorImageInfo* imageInfo, VkDescriptorBufferInfo* bufferInfo, uint8* bindingToDynamicOffsetMap);
|
||||
uint32 SetupDescriptorWrites(const SpirvShaderDescriptorInfo& info, VkWriteDescriptorSet* writeDescriptors, VkDescriptorImageInfo* imageInfo, VkDescriptorBufferInfo* bufferInfo, byte* bindingToDynamicOffset);
|
||||
|
||||
bool WriteUniformBuffer(uint32 descriptorIndex, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range) const
|
||||
{
|
||||
@@ -471,7 +459,7 @@ public:
|
||||
bool edited = DescriptorSet::CopyAndReturnNotEqual(bufferInfo->buffer, buffer);
|
||||
edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->offset, offset);
|
||||
edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->range, range);
|
||||
const uint8 dynamicOffsetIndex = BindingToDynamicOffsetMap[descriptorIndex];
|
||||
const byte dynamicOffsetIndex = BindingToDynamicOffset[descriptorIndex];
|
||||
DynamicOffsets[dynamicOffsetIndex] = dynamicOffset;
|
||||
return edited;
|
||||
}
|
||||
|
||||
@@ -146,7 +146,6 @@ void GPUContextVulkan::AddImageBarrier(GPUTextureViewVulkan* handle, VkImageLayo
|
||||
{
|
||||
// Transition entire resource at once
|
||||
const VkImageLayout srcLayout = state.GetSubresourceState(0);
|
||||
|
||||
VkImageSubresourceRange range;
|
||||
range.aspectMask = handle->Info.subresourceRange.aspectMask;
|
||||
range.baseMipLevel = 0;
|
||||
@@ -157,7 +156,7 @@ void GPUContextVulkan::AddImageBarrier(GPUTextureViewVulkan* handle, VkImageLayo
|
||||
}
|
||||
else
|
||||
{
|
||||
// Slow path. Want to transition the entire resource (with multiple subresources). But they aren't in the same state.
|
||||
// Slow path to transition each subresource
|
||||
for (int32 i = 0; i < state.GetSubresourcesCount(); i++)
|
||||
{
|
||||
const VkImageLayout srcLayout = state.GetSubresourceState(i);
|
||||
@@ -174,8 +173,6 @@ void GPUContextVulkan::AddImageBarrier(GPUTextureViewVulkan* handle, VkImageLayo
|
||||
state.SetSubresourceState(i, dstLayout);
|
||||
}
|
||||
}
|
||||
|
||||
// The entire resource should now be in the after state on this command list
|
||||
ASSERT(state.CheckResourceState(dstLayout));
|
||||
}
|
||||
|
||||
@@ -538,7 +535,7 @@ void GPUContextVulkan::UpdateDescriptorSets(GPUPipelineStateVulkan* pipelineStat
|
||||
remainingHasDescriptorsPerStageMask >>= 1;
|
||||
}
|
||||
|
||||
// Allocate sets based on what changed
|
||||
// Allocate sets if need to
|
||||
//if (needsWrite) // TODO: write on change only?
|
||||
{
|
||||
if (!pipelineState->AllocateDescriptorSets())
|
||||
@@ -578,7 +575,7 @@ void GPUContextVulkan::UpdateDescriptorSets(ComputePipelineStateVulkan* pipeline
|
||||
// Update descriptors
|
||||
UpdateDescriptorSets(*pipelineState->DescriptorInfo, pipelineState->DSWriter, needsWrite);
|
||||
|
||||
// Allocate sets based on what changed
|
||||
// Allocate sets if need to
|
||||
//if (needsWrite) // TODO: write on change only?f
|
||||
{
|
||||
if (!pipelineState->AllocateDescriptorSets())
|
||||
|
||||
@@ -149,12 +149,12 @@ static int FindLayerIndex(const Array<LayerExtension>& list, const char* layerNa
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return INVALID_INDEX;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool ContainsLayer(const Array<LayerExtension>& list, const char* layerName)
|
||||
{
|
||||
return FindLayerIndex(list, layerName) != INVALID_INDEX;
|
||||
return FindLayerIndex(list, layerName) != -1;
|
||||
}
|
||||
|
||||
static bool FindLayerExtension(const Array<LayerExtension>& list, const char* extensionName, const char*& foundLayer)
|
||||
@@ -400,7 +400,6 @@ void GPUDeviceVulkan::GetInstanceLayersAndExtensions(Array<const char*>& outInst
|
||||
void GPUDeviceVulkan::GetDeviceExtensionsAndLayers(VkPhysicalDevice gpu, Array<const char*>& outDeviceExtensions, Array<const char*>& outDeviceLayers)
|
||||
{
|
||||
Array<LayerExtension> deviceLayerExtensions;
|
||||
// 0 is reserved for regular device
|
||||
deviceLayerExtensions.AddDefault(1);
|
||||
{
|
||||
uint32 count = 0;
|
||||
@@ -409,10 +408,10 @@ void GPUDeviceVulkan::GetDeviceExtensionsAndLayers(VkPhysicalDevice gpu, Array<c
|
||||
properties.AddZeroed(count);
|
||||
VALIDATE_VULKAN_RESULT(vkEnumerateDeviceLayerProperties(gpu, &count, properties.Get()));
|
||||
ASSERT(count == properties.Count());
|
||||
for (const VkLayerProperties& Property : properties)
|
||||
for (const VkLayerProperties& property : properties)
|
||||
{
|
||||
deviceLayerExtensions.AddDefault(1);
|
||||
deviceLayerExtensions.Last().Layer = Property;
|
||||
deviceLayerExtensions.Last().Layer = property;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -530,7 +529,6 @@ void GPUDeviceVulkan::GetDeviceExtensionsAndLayers(VkPhysicalDevice gpu, Array<c
|
||||
return false;
|
||||
};
|
||||
|
||||
// Now go through the actual requested lists
|
||||
Array<const char*> platformExtensions;
|
||||
VulkanPlatform::GetDeviceExtensions(platformExtensions);
|
||||
for (const char* extension : platformExtensions)
|
||||
|
||||
@@ -345,10 +345,6 @@ DeferredDeletionQueueVulkan::~DeferredDeletionQueueVulkan()
|
||||
void DeferredDeletionQueueVulkan::ReleaseResources(bool deleteImmediately)
|
||||
{
|
||||
ScopeLock lock(&_locker);
|
||||
|
||||
const VkDevice device = _device->Device;
|
||||
|
||||
// Traverse list backwards so the swap switches to elements already tested
|
||||
const uint64 checkFrame = Engine::FrameCount - VULKAN_RESOURCE_DELETE_SAFE_FRAMES_COUNT;
|
||||
for (int32 i = 0; i < _entries.Count(); i++)
|
||||
{
|
||||
@@ -361,24 +357,26 @@ void DeferredDeletionQueueVulkan::ReleaseResources(bool deleteImmediately)
|
||||
{
|
||||
switch (e->StructureType)
|
||||
{
|
||||
#define VK_SWITCH(type) case Type::type: vkDestroy##type(device, (Vk##type)e->Handle, nullptr); break
|
||||
VK_SWITCH(RenderPass);
|
||||
VK_SWITCH(Buffer);
|
||||
VK_SWITCH(BufferView);
|
||||
VK_SWITCH(Image);
|
||||
VK_SWITCH(ImageView);
|
||||
VK_SWITCH(Pipeline);
|
||||
VK_SWITCH(PipelineLayout);
|
||||
VK_SWITCH(Framebuffer);
|
||||
VK_SWITCH(DescriptorSetLayout);
|
||||
VK_SWITCH(Sampler);
|
||||
VK_SWITCH(Semaphore);
|
||||
VK_SWITCH(ShaderModule);
|
||||
VK_SWITCH(Event);
|
||||
VK_SWITCH(QueryPool);
|
||||
#undef VK_SWITCH
|
||||
#define SWITCH_CASE(type) case Type::type: vkDestroy##type(_device->Device, (Vk##type)e->Handle, nullptr); break
|
||||
SWITCH_CASE(RenderPass);
|
||||
SWITCH_CASE(Buffer);
|
||||
SWITCH_CASE(BufferView);
|
||||
SWITCH_CASE(Image);
|
||||
SWITCH_CASE(ImageView);
|
||||
SWITCH_CASE(Pipeline);
|
||||
SWITCH_CASE(PipelineLayout);
|
||||
SWITCH_CASE(Framebuffer);
|
||||
SWITCH_CASE(DescriptorSetLayout);
|
||||
SWITCH_CASE(Sampler);
|
||||
SWITCH_CASE(Semaphore);
|
||||
SWITCH_CASE(ShaderModule);
|
||||
SWITCH_CASE(Event);
|
||||
SWITCH_CASE(QueryPool);
|
||||
#undef SWITCH_CASE
|
||||
default:
|
||||
#if !BUILD_RELEASE
|
||||
CRASH;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1068,23 +1066,10 @@ GPUDeviceVulkan::GPUDeviceVulkan(ShaderProfile shaderProfile, GPUAdapterVulkan*
|
||||
, _renderPasses(512)
|
||||
, _framebuffers(512)
|
||||
, _layouts(4096)
|
||||
, MainContext(nullptr)
|
||||
, Adapter(adapter)
|
||||
, Device(VK_NULL_HANDLE)
|
||||
, DeferredDeletionQueue(this)
|
||||
, StagingManager(this)
|
||||
, HelperResources(this)
|
||||
, GraphicsQueue(nullptr)
|
||||
, ComputeQueue(nullptr)
|
||||
, TransferQueue(nullptr)
|
||||
, PresentQueue(nullptr)
|
||||
, Allocator(VK_NULL_HANDLE)
|
||||
, PipelineCache(VK_NULL_HANDLE)
|
||||
#if VK_EXT_validation_cache
|
||||
, ValidationCache(VK_NULL_HANDLE)
|
||||
#endif
|
||||
, UniformBufferUploader(nullptr)
|
||||
, DescriptorPoolsManager(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1151,7 +1136,7 @@ GPUDevice* GPUDeviceVulkan::Create()
|
||||
}
|
||||
if (result == VK_ERROR_EXTENSION_NOT_PRESENT)
|
||||
{
|
||||
// Check for missing extensions
|
||||
// Extensions error
|
||||
uint32_t propertyCount;
|
||||
vkEnumerateInstanceExtensionProperties(nullptr, &propertyCount, nullptr);
|
||||
Array<VkExtensionProperties> properties;
|
||||
@@ -1159,28 +1144,27 @@ GPUDevice* GPUDeviceVulkan::Create()
|
||||
vkEnumerateInstanceExtensionProperties(nullptr, &propertyCount, properties.Get());
|
||||
for (const char* extension : InstanceExtensions)
|
||||
{
|
||||
bool extensionFound = false;
|
||||
bool found = false;
|
||||
for (uint32_t propertyIndex = 0; propertyIndex < propertyCount; propertyIndex++)
|
||||
{
|
||||
if (!StringUtils::Compare(properties[propertyIndex].extensionName, extension))
|
||||
{
|
||||
extensionFound = true;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!extensionFound)
|
||||
if (!found)
|
||||
{
|
||||
LOG(Warning, "Missing required Vulkan extension: {0}", String(extension));
|
||||
}
|
||||
}
|
||||
|
||||
// Missing extensions
|
||||
auto error = String::Format(TEXT("Vulkan driver doesn't contain specified extensions:\n{0}\nPlease make sure your layers path is set appropriately."));
|
||||
Platform::Error(*error);
|
||||
return nullptr;
|
||||
}
|
||||
if (result != VK_SUCCESS)
|
||||
{
|
||||
// Driver error
|
||||
LOG(Warning, "Vulkan create instance failed with error code: {0}", RenderToolsVulkan::GetVkErrorString(result));
|
||||
Platform::Fatal(TEXT("Vulkan failed to create instance\n\nDo you have a compatible Vulkan driver installed?"));
|
||||
return nullptr;
|
||||
@@ -1560,7 +1544,7 @@ bool GPUDeviceVulkan::Init()
|
||||
_state = DeviceState::Created;
|
||||
const auto gpu = Adapter->Gpu;
|
||||
|
||||
// Query queues properties
|
||||
// Get queues properties
|
||||
uint32 queueCount = 0;
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(gpu, &queueCount, nullptr);
|
||||
ASSERT(queueCount >= 1);
|
||||
@@ -1570,23 +1554,21 @@ bool GPUDeviceVulkan::Init()
|
||||
// Query device features
|
||||
vkGetPhysicalDeviceFeatures(Adapter->Gpu, &PhysicalDeviceFeatures);
|
||||
|
||||
// Setup extension and layer info
|
||||
VkDeviceCreateInfo deviceInfo;
|
||||
RenderToolsVulkan::ZeroStruct(deviceInfo, VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);
|
||||
|
||||
// Get extensions and layers
|
||||
Array<const char*> deviceExtensions;
|
||||
Array<const char*> validationLayers;
|
||||
GetDeviceExtensionsAndLayers(gpu, deviceExtensions, validationLayers);
|
||||
|
||||
ParseOptionalDeviceExtensions(deviceExtensions);
|
||||
|
||||
// Setup device info
|
||||
VkDeviceCreateInfo deviceInfo;
|
||||
RenderToolsVulkan::ZeroStruct(deviceInfo, VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);
|
||||
deviceInfo.enabledExtensionCount = deviceExtensions.Count();
|
||||
deviceInfo.ppEnabledExtensionNames = deviceExtensions.Get();
|
||||
|
||||
deviceInfo.enabledLayerCount = validationLayers.Count();
|
||||
deviceInfo.ppEnabledLayerNames = deviceInfo.enabledLayerCount > 0 ? validationLayers.Get() : nullptr;
|
||||
|
||||
// Setup Queue info
|
||||
// Setup queues info
|
||||
Array<VkDeviceQueueCreateInfo> queueFamilyInfos;
|
||||
int32 graphicsQueueFamilyIndex = -1;
|
||||
int32 computeQueueFamilyIndex = -1;
|
||||
@@ -1655,7 +1637,6 @@ bool GPUDeviceVulkan::Init()
|
||||
numPriorities += curProps.queueCount;
|
||||
LOG(Info, "- queue family {0}: {1} queues{2}", familyIndex, curProps.queueCount, queueTypeInfo);
|
||||
}
|
||||
|
||||
Array<float> queuePriorities;
|
||||
queuePriorities.AddDefault(numPriorities);
|
||||
float* currentPriority = queuePriorities.Get();
|
||||
@@ -1663,14 +1644,12 @@ bool GPUDeviceVulkan::Init()
|
||||
{
|
||||
VkDeviceQueueCreateInfo& queue = queueFamilyInfos[index];
|
||||
queue.pQueuePriorities = currentPriority;
|
||||
|
||||
const VkQueueFamilyProperties& properties = QueueFamilyProps[queue.queueFamilyIndex];
|
||||
for (int32 queueIndex = 0; queueIndex < (int32)properties.queueCount; queueIndex++)
|
||||
{
|
||||
*currentPriority++ = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
deviceInfo.queueCreateInfoCount = queueFamilyInfos.Count();
|
||||
deviceInfo.pQueueCreateInfos = queueFamilyInfos.Get();
|
||||
|
||||
@@ -2129,7 +2108,6 @@ bool FenceManagerVulkan::CheckFenceState(FenceVulkan* fence)
|
||||
|
||||
void FenceManagerVulkan::DestroyFence(FenceVulkan* fence)
|
||||
{
|
||||
// Does not need to go in the deferred deletion queue
|
||||
vkDestroyFence(_device->Device, fence->GetHandle(), nullptr);
|
||||
fence->_handle = VK_NULL_HANDLE;
|
||||
Delete(fence);
|
||||
|
||||
@@ -554,17 +554,17 @@ public:
|
||||
/// <summary>
|
||||
/// The main Vulkan commands context.
|
||||
/// </summary>
|
||||
GPUContextVulkan* MainContext;
|
||||
GPUContextVulkan* MainContext = nullptr;
|
||||
|
||||
/// <summary>
|
||||
/// The Vulkan adapter.
|
||||
/// </summary>
|
||||
GPUAdapterVulkan* Adapter;
|
||||
GPUAdapterVulkan* Adapter = nullptr;
|
||||
|
||||
/// <summary>
|
||||
/// The Vulkan device.
|
||||
/// </summary>
|
||||
VkDevice Device;
|
||||
VkDevice Device = VK_NULL_HANDLE;
|
||||
|
||||
/// <summary>
|
||||
/// The Vulkan device queues family properties.
|
||||
@@ -594,51 +594,51 @@ public:
|
||||
/// <summary>
|
||||
/// The graphics queue.
|
||||
/// </summary>
|
||||
QueueVulkan* GraphicsQueue;
|
||||
QueueVulkan* GraphicsQueue = nullptr;
|
||||
|
||||
/// <summary>
|
||||
/// The compute queue.
|
||||
/// </summary>
|
||||
QueueVulkan* ComputeQueue;
|
||||
QueueVulkan* ComputeQueue = nullptr;
|
||||
|
||||
/// <summary>
|
||||
/// The transfer queue.
|
||||
/// </summary>
|
||||
QueueVulkan* TransferQueue;
|
||||
QueueVulkan* TransferQueue = nullptr;
|
||||
|
||||
/// <summary>
|
||||
/// The present queue.
|
||||
/// </summary>
|
||||
QueueVulkan* PresentQueue;
|
||||
QueueVulkan* PresentQueue = nullptr;
|
||||
|
||||
/// <summary>
|
||||
/// The Vulkan memory allocator.
|
||||
/// </summary>
|
||||
VmaAllocator Allocator;
|
||||
VmaAllocator Allocator = VK_NULL_HANDLE;
|
||||
|
||||
/// <summary>
|
||||
/// The pipeline cache.
|
||||
/// </summary>
|
||||
VkPipelineCache PipelineCache;
|
||||
VkPipelineCache PipelineCache = VK_NULL_HANDLE;
|
||||
|
||||
#if VK_EXT_validation_cache
|
||||
|
||||
/// <summary>
|
||||
/// The optional validation cache.
|
||||
/// </summary>
|
||||
VkValidationCacheEXT ValidationCache;
|
||||
VkValidationCacheEXT ValidationCache = VK_NULL_HANDLE;
|
||||
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// The uniform buffers uploader.
|
||||
/// </summary>
|
||||
UniformBufferUploaderVulkan* UniformBufferUploader;
|
||||
UniformBufferUploaderVulkan* UniformBufferUploader = nullptr;
|
||||
|
||||
/// <summary>
|
||||
/// The descriptor pools manager.
|
||||
/// </summary>
|
||||
DescriptorPoolsManagerVulkan* DescriptorPoolsManager;
|
||||
DescriptorPoolsManagerVulkan* DescriptorPoolsManager = nullptr;
|
||||
|
||||
/// <summary>
|
||||
/// The physical device limits.
|
||||
|
||||
@@ -45,13 +45,10 @@ ComputePipelineStateVulkan* GPUShaderProgramCSVulkan::GetOrCreateState()
|
||||
|
||||
// Setup the state
|
||||
_pipelineState = New<ComputePipelineStateVulkan>(_device, pipeline, layout);
|
||||
|
||||
_pipelineState->DescriptorInfo = &DescriptorInfo;
|
||||
_pipelineState->DescriptorSetsLayout = &layout->GetDescriptorSetLayout();
|
||||
_pipelineState->DescriptorSetHandles.AddZeroed(_pipelineState->DescriptorSetsLayout->GetHandles().Count());
|
||||
|
||||
uint32 totalNumDynamicOffsets = 0;
|
||||
|
||||
uint32 dynamicOffsetsCount = 0;
|
||||
if (DescriptorInfo.DescriptorTypesCount != 0)
|
||||
{
|
||||
_pipelineState->DSWriteContainer.DescriptorWrites.AddZeroed(DescriptorInfo.DescriptorTypesCount);
|
||||
@@ -59,18 +56,18 @@ ComputePipelineStateVulkan* GPUShaderProgramCSVulkan::GetOrCreateState()
|
||||
_pipelineState->DSWriteContainer.DescriptorBufferInfo.AddZeroed(DescriptorInfo.BufferInfosCount);
|
||||
|
||||
ASSERT(DescriptorInfo.DescriptorTypesCount < 255);
|
||||
_pipelineState->DSWriteContainer.BindingToDynamicOffsetMap.AddDefault(DescriptorInfo.DescriptorTypesCount);
|
||||
_pipelineState->DSWriteContainer.BindingToDynamicOffsetMap.SetAll(255);
|
||||
_pipelineState->DSWriteContainer.BindingToDynamicOffset.AddDefault(DescriptorInfo.DescriptorTypesCount);
|
||||
_pipelineState->DSWriteContainer.BindingToDynamicOffset.SetAll(255);
|
||||
|
||||
VkWriteDescriptorSet* currentDescriptorWrite = _pipelineState->DSWriteContainer.DescriptorWrites.Get();
|
||||
VkDescriptorImageInfo* currentImageInfo = _pipelineState->DSWriteContainer.DescriptorImageInfo.Get();
|
||||
VkDescriptorBufferInfo* currentBufferInfo = _pipelineState->DSWriteContainer.DescriptorBufferInfo.Get();
|
||||
uint8* currentBindingToDynamicOffsetMap = _pipelineState->DSWriteContainer.BindingToDynamicOffsetMap.Get();
|
||||
uint8* currentBindingToDynamicOffsetMap = _pipelineState->DSWriteContainer.BindingToDynamicOffset.Get();
|
||||
|
||||
totalNumDynamicOffsets = _pipelineState->DSWriter.SetupDescriptorWrites(DescriptorInfo, currentDescriptorWrite, currentImageInfo, currentBufferInfo, currentBindingToDynamicOffsetMap);
|
||||
dynamicOffsetsCount = _pipelineState->DSWriter.SetupDescriptorWrites(DescriptorInfo, currentDescriptorWrite, currentImageInfo, currentBufferInfo, currentBindingToDynamicOffsetMap);
|
||||
}
|
||||
|
||||
_pipelineState->DynamicOffsets.AddZeroed(totalNumDynamicOffsets);
|
||||
_pipelineState->DynamicOffsets.AddZeroed(dynamicOffsetsCount);
|
||||
_pipelineState->DSWriter.DynamicOffsets = _pipelineState->DynamicOffsets.Get();
|
||||
|
||||
return _pipelineState;
|
||||
@@ -346,26 +343,26 @@ bool GPUPipelineStateVulkan::Init(const Description& desc)
|
||||
DSWriteContainer.DescriptorBufferInfo.AddZeroed(descriptor->BufferInfosCount);
|
||||
|
||||
ASSERT(descriptor->DescriptorTypesCount < 255);
|
||||
DSWriteContainer.BindingToDynamicOffsetMap.AddDefault(descriptor->DescriptorTypesCount);
|
||||
DSWriteContainer.BindingToDynamicOffsetMap.SetAll(255);
|
||||
DSWriteContainer.BindingToDynamicOffset.AddDefault(descriptor->DescriptorTypesCount);
|
||||
DSWriteContainer.BindingToDynamicOffset.SetAll(255);
|
||||
}
|
||||
|
||||
VkWriteDescriptorSet* currentDescriptorWrite = DSWriteContainer.DescriptorWrites.Get();
|
||||
VkDescriptorImageInfo* currentImageInfo = DSWriteContainer.DescriptorImageInfo.Get();
|
||||
VkDescriptorBufferInfo* currentBufferInfo = DSWriteContainer.DescriptorBufferInfo.Get();
|
||||
uint8* currentBindingToDynamicOffsetMap = DSWriteContainer.BindingToDynamicOffsetMap.Get();
|
||||
byte* currentBindingToDynamicOffsetMap = DSWriteContainer.BindingToDynamicOffset.Get();
|
||||
uint32 dynamicOffsetsStart[DescriptorSet::GraphicsStagesCount];
|
||||
uint32 totalNumDynamicOffsets = 0;
|
||||
uint32 dynamicOffsetsCount = 0;
|
||||
for (int32 stage = 0; stage < DescriptorSet::GraphicsStagesCount; stage++)
|
||||
{
|
||||
dynamicOffsetsStart[stage] = totalNumDynamicOffsets;
|
||||
dynamicOffsetsStart[stage] = dynamicOffsetsCount;
|
||||
|
||||
const auto descriptor = DescriptorInfoPerStage[stage];
|
||||
if (descriptor == nullptr || descriptor->DescriptorTypesCount == 0)
|
||||
continue;
|
||||
|
||||
const uint32 numDynamicOffsets = DSWriter[stage].SetupDescriptorWrites(*descriptor, currentDescriptorWrite, currentImageInfo, currentBufferInfo, currentBindingToDynamicOffsetMap);
|
||||
totalNumDynamicOffsets += numDynamicOffsets;
|
||||
dynamicOffsetsCount += numDynamicOffsets;
|
||||
|
||||
currentDescriptorWrite += descriptor->DescriptorTypesCount;
|
||||
currentImageInfo += descriptor->ImageInfosCount;
|
||||
@@ -373,7 +370,7 @@ bool GPUPipelineStateVulkan::Init(const Description& desc)
|
||||
currentBindingToDynamicOffsetMap += descriptor->DescriptorTypesCount;
|
||||
}
|
||||
|
||||
DynamicOffsets.AddZeroed(totalNumDynamicOffsets);
|
||||
DynamicOffsets.AddZeroed(dynamicOffsetsCount);
|
||||
for (int32 stage = 0; stage < DescriptorSet::GraphicsStagesCount; stage++)
|
||||
{
|
||||
DSWriter[stage].DynamicOffsets = dynamicOffsetsStart[stage] + DynamicOffsets.Get();
|
||||
|
||||
@@ -187,10 +187,10 @@ bool GPUSwapChainVulkan::CreateSwapChain(int32 width, int32 height)
|
||||
|
||||
const auto& gpu = _device->Adapter->Gpu;
|
||||
|
||||
// Find pixel format for presentable images
|
||||
// Pick a format for backbuffer
|
||||
PixelFormat resultFormat = GPU_BACK_BUFFER_PIXEL_FORMAT;
|
||||
VkSurfaceFormatKHR curFormat;
|
||||
Platform::MemoryClear(&curFormat, sizeof(curFormat));
|
||||
VkSurfaceFormatKHR result;
|
||||
Platform::MemoryClear(&result, sizeof(result));
|
||||
{
|
||||
uint32 surfaceFormatsCount;
|
||||
VALIDATE_VULKAN_RESULT(vkGetPhysicalDeviceSurfaceFormatsKHR(gpu, _surface, &surfaceFormatsCount, nullptr));
|
||||
@@ -210,7 +210,7 @@ bool GPUSwapChainVulkan::CreateSwapChain(int32 width, int32 height)
|
||||
{
|
||||
if (surfaceFormats[i].format == requested)
|
||||
{
|
||||
curFormat = surfaceFormats[i];
|
||||
result = surfaceFormats[i];
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@@ -240,8 +240,8 @@ bool GPUSwapChainVulkan::CreateSwapChain(int32 width, int32 height)
|
||||
if (surfaceFormats[i].format == RenderToolsVulkan::ToVulkanFormat(static_cast<PixelFormat>(pixelFormat)))
|
||||
{
|
||||
resultFormat = static_cast<PixelFormat>(pixelFormat);
|
||||
curFormat = surfaceFormats[i];
|
||||
LOG(Info, "No swapchain format requested, picking up Vulkan format {0}", (uint32)curFormat.format);
|
||||
result = surfaceFormats[i];
|
||||
LOG(Info, "No swapchain format requested, picking up Vulkan format {0}", (uint32)result.format);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -264,7 +264,7 @@ bool GPUSwapChainVulkan::CreateSwapChain(int32 width, int32 height)
|
||||
if (surfaceFormats[i].format == format)
|
||||
{
|
||||
supported = true;
|
||||
curFormat = surfaceFormats[i];
|
||||
result = surfaceFormats[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -290,13 +290,13 @@ bool GPUSwapChainVulkan::CreateSwapChain(int32 width, int32 height)
|
||||
LOG(Error, "Unable to find a pixel format for the swapchain; swapchain returned {0} Vulkan formats {1}", surfaceFormats.Count(), *msg);
|
||||
}
|
||||
}
|
||||
curFormat.format = RenderToolsVulkan::ToVulkanFormat(resultFormat);
|
||||
result.format = RenderToolsVulkan::ToVulkanFormat(resultFormat);
|
||||
_format = resultFormat;
|
||||
|
||||
// Prepare present queue
|
||||
_device->SetupPresentQueue(_surface);
|
||||
|
||||
// Fetch present mode
|
||||
// Calculate the swap chain present mode
|
||||
VkPresentModeKHR presentMode = VK_PRESENT_MODE_FIFO_KHR;
|
||||
{
|
||||
uint32 presentModesCount = 0;
|
||||
@@ -358,8 +358,8 @@ bool GPUSwapChainVulkan::CreateSwapChain(int32 width, int32 height)
|
||||
RenderToolsVulkan::ZeroStruct(swapChainInfo, VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR);
|
||||
swapChainInfo.surface = _surface;
|
||||
swapChainInfo.minImageCount = VULKAN_BACK_BUFFERS_COUNT;
|
||||
swapChainInfo.imageFormat = curFormat.format;
|
||||
swapChainInfo.imageColorSpace = curFormat.colorSpace;
|
||||
swapChainInfo.imageFormat = result.format;
|
||||
swapChainInfo.imageColorSpace = result.colorSpace;
|
||||
swapChainInfo.imageExtent.width = width;
|
||||
swapChainInfo.imageExtent.height = height;
|
||||
swapChainInfo.imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
|
||||
@@ -78,7 +78,7 @@ protected:
|
||||
{
|
||||
if (this->hasBlock)
|
||||
{
|
||||
// Copy blocking hit to hits
|
||||
// Blocking hits go to hits
|
||||
processTouches(&this->block, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,8 +177,7 @@ bool PhysicsService::Init()
|
||||
// only in non-production builds.
|
||||
|
||||
#if PHYSX_MEMORY_STATS
|
||||
// Want names of PhysX allocations
|
||||
GPhysXFoundation->setReportAllocationNames(true);
|
||||
_foundation->setReportAllocationNames(true);
|
||||
#endif
|
||||
|
||||
// Config
|
||||
|
||||
@@ -767,7 +767,7 @@ void AndroidPlatform::GetSystemTime(int32& year, int32& month, int32& dayOfWeek,
|
||||
|
||||
void AndroidPlatform::GetUTCTime(int32& year, int32& month, int32& dayOfWeek, int32& day, int32& hour, int32& minute, int32& second, int32& millisecond)
|
||||
{
|
||||
// Query for calendar time
|
||||
// Get the calendar time
|
||||
struct timeval time;
|
||||
gettimeofday(&time, nullptr);
|
||||
|
||||
@@ -803,11 +803,11 @@ bool AndroidPlatform::Init()
|
||||
}
|
||||
|
||||
// Set info about the CPU
|
||||
cpu_set_t availableCpusMask;
|
||||
CPU_ZERO(&availableCpusMask);
|
||||
if (sched_getaffinity(0, sizeof(availableCpusMask), &availableCpusMask) == 0)
|
||||
cpu_set_t cpus;
|
||||
CPU_ZERO(&cpus);
|
||||
if (sched_getaffinity(0, sizeof(cpus), &cpus) == 0)
|
||||
{
|
||||
AndroidCpu.ProcessorCoreCount = AndroidCpu.LogicalProcessorCount = CPU_COUNT(&availableCpusMask);
|
||||
AndroidCpu.ProcessorCoreCount = AndroidCpu.LogicalProcessorCount = CPU_COUNT(&cpus);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1277,7 +1277,7 @@ void LinuxPlatform::GetSystemTime(int32& year, int32& month, int32& dayOfWeek, i
|
||||
|
||||
void LinuxPlatform::GetUTCTime(int32& year, int32& month, int32& dayOfWeek, int32& day, int32& hour, int32& minute, int32& second, int32& millisecond)
|
||||
{
|
||||
// Query for calendar time
|
||||
// Get the calendar time
|
||||
struct timeval time;
|
||||
gettimeofday(&time, nullptr);
|
||||
|
||||
@@ -1315,34 +1315,33 @@ bool LinuxPlatform::Init()
|
||||
}
|
||||
|
||||
// Set info about the CPU
|
||||
cpu_set_t availableCpusMask;
|
||||
CPU_ZERO(&availableCpusMask);
|
||||
if (sched_getaffinity(0, sizeof(availableCpusMask), &availableCpusMask) == 0)
|
||||
cpu_set_t cpus;
|
||||
CPU_ZERO(&cpus);
|
||||
if (sched_getaffinity(0, sizeof(cpus), &cpus) == 0)
|
||||
{
|
||||
int32 numberOfCores = 0;
|
||||
struct CpuInfo
|
||||
{
|
||||
int Core;
|
||||
int Package;
|
||||
} cpuInfos[CPU_SETSIZE];
|
||||
|
||||
Platform::MemoryClear(cpuInfos, sizeof(cpuInfos));
|
||||
int maxCoreId = 0;
|
||||
int maxPackageId = 0;
|
||||
int cpuCountAvailable = 0;
|
||||
int32 Core;
|
||||
int32 Package;
|
||||
} cpusInfo[CPU_SETSIZE];
|
||||
Platform::MemoryClear(cpusInfo, sizeof(cpusInfo));
|
||||
int32 maxCoreId = 0;
|
||||
int32 maxPackageId = 0;
|
||||
int32 cpuCountAvailable = 0;
|
||||
|
||||
for (int32 cpuIdx = 0; cpuIdx < CPU_SETSIZE; cpuIdx++)
|
||||
{
|
||||
if (CPU_ISSET(cpuIdx, &availableCpusMask))
|
||||
if (CPU_ISSET(cpuIdx, &cpus))
|
||||
{
|
||||
cpuCountAvailable++;
|
||||
|
||||
sprintf(fileNameBuffer, "/sys/devices/system/cpu/cpu%d/topology/core_id", cpuIdx);
|
||||
if (FILE* coreIdFile = fopen(fileNameBuffer, "r"))
|
||||
{
|
||||
if (fscanf(coreIdFile, "%d", &cpuInfos[cpuIdx].Core) != 1)
|
||||
if (fscanf(coreIdFile, "%d", &cpusInfo[cpuIdx].Core) != 1)
|
||||
{
|
||||
cpuInfos[cpuIdx].Core = 0;
|
||||
cpusInfo[cpuIdx].Core = 0;
|
||||
}
|
||||
fclose(coreIdFile);
|
||||
}
|
||||
@@ -1350,22 +1349,21 @@ bool LinuxPlatform::Init()
|
||||
sprintf(fileNameBuffer, "/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpuIdx);
|
||||
if (FILE* packageIdFile = fopen(fileNameBuffer, "r"))
|
||||
{
|
||||
// physical_package_id can be -1 on embedded devices - treat all CPUs as separate in that case.
|
||||
if (fscanf(packageIdFile, "%d", &cpuInfos[cpuIdx].Package) != 1 || cpuInfos[cpuIdx].Package < 0)
|
||||
if (fscanf(packageIdFile, "%d", &cpusInfo[cpuIdx].Package) != 1 || cpusInfo[cpuIdx].Package < 0)
|
||||
{
|
||||
cpuInfos[cpuIdx].Package = cpuInfos[cpuIdx].Core;
|
||||
cpusInfo[cpuIdx].Package = cpusInfo[cpuIdx].Core;
|
||||
}
|
||||
fclose(packageIdFile);
|
||||
}
|
||||
|
||||
maxCoreId = Math::Max(maxCoreId, cpuInfos[cpuIdx].Core);
|
||||
maxPackageId = Math::Max(maxPackageId, cpuInfos[cpuIdx].Package);
|
||||
maxCoreId = Math::Max(maxCoreId, cpusInfo[cpuIdx].Core);
|
||||
maxPackageId = Math::Max(maxPackageId, cpusInfo[cpuIdx].Package);
|
||||
}
|
||||
}
|
||||
|
||||
int coresCount = maxCoreId + 1;
|
||||
int packagesCount = maxPackageId + 1;
|
||||
int pairsCount = packagesCount * coresCount;
|
||||
int32 coresCount = maxCoreId + 1;
|
||||
int32 packagesCount = maxPackageId + 1;
|
||||
int32 pairsCount = packagesCount * coresCount;
|
||||
|
||||
if (coresCount * 2 < cpuCountAvailable)
|
||||
{
|
||||
@@ -1378,9 +1376,9 @@ bool LinuxPlatform::Init()
|
||||
|
||||
for (int32 cpuIdx = 0; cpuIdx < CPU_SETSIZE; cpuIdx++)
|
||||
{
|
||||
if (CPU_ISSET(cpuIdx, &availableCpusMask))
|
||||
if (CPU_ISSET(cpuIdx, &cpus))
|
||||
{
|
||||
pairs[cpuInfos[cpuIdx].Package * coresCount + cpuInfos[cpuIdx].Core] = 1;
|
||||
pairs[cpusInfo[cpuIdx].Package * coresCount + cpusInfo[cpuIdx].Core] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1394,7 +1392,7 @@ bool LinuxPlatform::Init()
|
||||
|
||||
UnixCpu.ProcessorPackageCount = packagesCount;
|
||||
UnixCpu.ProcessorCoreCount = Math::Max(numberOfCores, 1);
|
||||
UnixCpu.LogicalProcessorCount = CPU_COUNT(&availableCpusMask);
|
||||
UnixCpu.LogicalProcessorCount = CPU_COUNT(&cpus);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -417,13 +417,13 @@ void WindowsWindow::GetScreenInfo(int32& x, int32& y, int32& width, int32& heigh
|
||||
{
|
||||
ASSERT(HasHWND());
|
||||
|
||||
// Grab current monitor data for sizing
|
||||
// Pick the current monitor data for sizing
|
||||
const HMONITOR monitor = MonitorFromWindow(_handle, MONITOR_DEFAULTTONEAREST);
|
||||
MONITORINFO monitorInfo;
|
||||
monitorInfo.cbSize = sizeof(MONITORINFO);
|
||||
GetMonitorInfoW(monitor, &monitorInfo);
|
||||
|
||||
// Return result
|
||||
// Calculate result
|
||||
x = monitorInfo.rcMonitor.left;
|
||||
y = monitorInfo.rcMonitor.top;
|
||||
width = monitorInfo.rcMonitor.right - x;
|
||||
|
||||
@@ -126,12 +126,11 @@ void FontTextureAtlas::CopyDataIntoSlot(const Slot* slot, const Array<byte>& dat
|
||||
}
|
||||
}
|
||||
|
||||
// Copy each row of the texture
|
||||
// Actual data copy
|
||||
for (uint32 row = padding; row < slot->Height - padding; row++)
|
||||
{
|
||||
rowData.SrcRow = row - padding;
|
||||
rowData.DstRow = row;
|
||||
|
||||
copyRow(rowData);
|
||||
}
|
||||
|
||||
|
||||
@@ -1292,7 +1292,7 @@ void Render2D::DrawRectangle(const Rectangle& rect, const Color& color1, const C
|
||||
drawCall.StartIB = IBIndex;
|
||||
drawCall.CountIB = 4 * (6 + 3);
|
||||
|
||||
// The has to match HLSL code
|
||||
// This must be the same as in HLSL code
|
||||
const float filterScale = 1.0f;
|
||||
const float thicknessHalf = (2.82842712f + thickness) * 0.5f + filterScale;
|
||||
|
||||
@@ -1544,10 +1544,8 @@ void DrawLines(const Vector2* points, int32 pointsCount, const Color& color1, co
|
||||
Vector2 p1t, p2t;
|
||||
|
||||
#if RENDER2D_USE_LINE_AA
|
||||
// Half of the width of the filter size to use for anti-aliasing. Increasing this value will increase the fuzziness of line edges.
|
||||
const float filterScale = 1.0f; // Must match HLSL code
|
||||
|
||||
// The amount we increase each side of the line to generate enough pixels
|
||||
// This must be the same as in HLSL code
|
||||
const float filterScale = 1.0f;
|
||||
const float thicknessHalf = (2.82842712f + thickness) * 0.5f + filterScale;
|
||||
|
||||
drawCall.Type = DrawCallType::LineAA;
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
|
||||
#if GENERATE_GF_CACHE
|
||||
|
||||
// This code below (PreIntegratedGF namespace) is based on many Siggraph presentations about BRDF shading:
|
||||
// https://blog.selfshadow.com/publications/s2015-shading-course/
|
||||
// https://blog.selfshadow.com/publications/s2012-shading-course/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
@@ -152,7 +152,7 @@ bool VolumetricFogPass::Init(RenderContext& renderContext, GPUContext* context,
|
||||
_cache.GridSizeZ = 64;
|
||||
_cache.FogJitter = false;
|
||||
_cache.TemporalReprojection = false;
|
||||
_cache.HistoryMissSupersampleCount = 1;
|
||||
_cache.MissedHistorySamplesCount = 1;
|
||||
break;
|
||||
}
|
||||
case Quality::Medium:
|
||||
@@ -161,7 +161,7 @@ bool VolumetricFogPass::Init(RenderContext& renderContext, GPUContext* context,
|
||||
_cache.GridSizeZ = 64;
|
||||
_cache.FogJitter = true;
|
||||
_cache.TemporalReprojection = true;
|
||||
_cache.HistoryMissSupersampleCount = 4;
|
||||
_cache.MissedHistorySamplesCount = 4;
|
||||
break;
|
||||
}
|
||||
case Quality::High:
|
||||
@@ -170,7 +170,7 @@ bool VolumetricFogPass::Init(RenderContext& renderContext, GPUContext* context,
|
||||
_cache.GridSizeZ = 128;
|
||||
_cache.FogJitter = true;
|
||||
_cache.TemporalReprojection = true;
|
||||
_cache.HistoryMissSupersampleCount = 4;
|
||||
_cache.MissedHistorySamplesCount = 4;
|
||||
break;
|
||||
}
|
||||
case Quality::Ultra:
|
||||
@@ -179,7 +179,7 @@ bool VolumetricFogPass::Init(RenderContext& renderContext, GPUContext* context,
|
||||
_cache.GridSizeZ = 256;
|
||||
_cache.FogJitter = true;
|
||||
_cache.TemporalReprojection = true;
|
||||
_cache.HistoryMissSupersampleCount = 8;
|
||||
_cache.MissedHistorySamplesCount = 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -208,7 +208,7 @@ bool VolumetricFogPass::Init(RenderContext& renderContext, GPUContext* context,
|
||||
_cache.Data.InverseSquaredLightDistanceBiasScale = _cache.InverseSquaredLightDistanceBiasScale;
|
||||
_cache.Data.PhaseG = options.ScatteringDistribution;
|
||||
_cache.Data.VolumetricFogMaxDistance = options.Distance;
|
||||
_cache.Data.HistoryMissSuperSampleCount = Math::Clamp(_cache.HistoryMissSupersampleCount, 1, (int32)ARRAY_COUNT(_cache.Data.FrameJitterOffsets));
|
||||
_cache.Data.MissedHistorySamplesCount = Math::Clamp(_cache.MissedHistorySamplesCount, 1, (int32)ARRAY_COUNT(_cache.Data.FrameJitterOffsets));
|
||||
Matrix::Transpose(view.PrevViewProjection, _cache.Data.PrevWorldToClip);
|
||||
_cache.Data.DirectionalLightShadow.NumCascades = 0;
|
||||
_cache.Data.SkyLight.VolumetricScatteringIntensity = 0;
|
||||
@@ -221,7 +221,7 @@ bool VolumetricFogPass::Init(RenderContext& renderContext, GPUContext* context,
|
||||
}
|
||||
if (_cache.FogJitter && _cache.TemporalReprojection)
|
||||
{
|
||||
for (int32 i = 0; i < _cache.HistoryMissSupersampleCount; i++)
|
||||
for (int32 i = 0; i < _cache.MissedHistorySamplesCount; i++)
|
||||
{
|
||||
const uint64 frameNumber = renderContext.Task->LastUsedFrame - i;
|
||||
_cache.Data.FrameJitterOffsets[i] = Vector4(
|
||||
|
||||
@@ -30,7 +30,7 @@ private:
|
||||
float HistoryWeight;
|
||||
|
||||
Vector3 GridSize;
|
||||
uint32 HistoryMissSuperSampleCount;
|
||||
uint32 MissedHistorySamplesCount;
|
||||
|
||||
int32 GridSizeIntX;
|
||||
int32 GridSizeIntY;
|
||||
@@ -105,9 +105,9 @@ private:
|
||||
float HistoryWeight;
|
||||
|
||||
/// <summary>
|
||||
/// Number of lighting samples to compute for voxels whose history value is not available. This reduces noise when panning or on camera cuts, but introduces a variable cost to volumetric fog computation. Valid range [1, 8].
|
||||
/// The amount of lighting samples to compute for voxels whose history value is not available. This reduces noise when panning or on camera cuts, but introduces a variable cost to volumetric fog computation. Valid range [1, 8].
|
||||
/// </summary>
|
||||
int32 HistoryMissSupersampleCount;
|
||||
int32 MissedHistorySamplesCount;
|
||||
|
||||
/// <summary>
|
||||
/// Scales the amount added to the inverse squared falloff denominator. This effectively removes the spike from inverse squared falloff that causes extreme aliasing.
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
#include "Engine/Core/Math/Math.h"
|
||||
#include "Engine/Platform/Platform.h"
|
||||
|
||||
// Use CRC 32 polynomial
|
||||
// Based on the Slicing-by-8 implementation found here:
|
||||
// http://slicing-by-8.sourceforge.net/
|
||||
|
||||
enum { Crc32Poly = 0x04c11db7 };
|
||||
|
||||
uint32 Crc::CachedCRCTablesSB8[8][256] =
|
||||
|
||||
@@ -71,9 +71,9 @@ namespace FlaxEngine.Utilities
|
||||
return Base + noise * NoiseAmount;
|
||||
}
|
||||
|
||||
private float Fade(float T)
|
||||
private float Fade(float t)
|
||||
{
|
||||
return T * T * T * (T * (T * 6 - 15) + 10);
|
||||
return t * t * t * (t * (t * 6 - 15) + 10);
|
||||
}
|
||||
|
||||
private float Grad(int hash, float x, float y)
|
||||
|
||||
@@ -109,8 +109,14 @@ float3 ColorCorrect(float3 color, float luma, float4 saturation, float4 contrast
|
||||
return color;
|
||||
}
|
||||
|
||||
float3 ColorCorrectAll(float3 color)
|
||||
float3 ColorGrade(float3 linearColor)
|
||||
{
|
||||
// Convert into ACEScg color
|
||||
const float3x3 sRGB_2_AP1 = mul(XYZ_2_AP1_MAT, mul(D65_2_D60_CAT, sRGB_2_XYZ_MAT));
|
||||
const float3x3 AP1_2_sRGB = mul(XYZ_2_sRGB_MAT, mul(D60_2_D65_CAT, AP1_2_XYZ_MAT));
|
||||
float3 color = mul(sRGB_2_AP1, linearColor);
|
||||
|
||||
// Perform color grading with CC wheels
|
||||
float luma = dot(color, AP1_RGB2Y);
|
||||
float3 ccColorShadows = ColorCorrect(color, luma, ColorSaturationShadows, ColorContrastShadows, ColorGammaShadows, ColorGainShadows, ColorOffsetShadows);
|
||||
float ccWeightShadows = 1 - smoothstep(0, ColorCorrectionShadowsMax, luma);
|
||||
@@ -118,18 +124,7 @@ float3 ColorCorrectAll(float3 color)
|
||||
float ccWeightHighlights = smoothstep(ColorCorrectionHighlightsMin, 1, luma);
|
||||
float3 ccColorMidtones = ColorCorrect(color, luma, ColorSaturationMidtones, ColorContrastMidtones, ColorGammaMidtones, ColorGainMidtones, ColorOffsetMidtones);
|
||||
float ccWeightMidtones = 1 - ccWeightShadows - ccWeightHighlights;
|
||||
return ccColorShadows * ccWeightShadows + ccColorMidtones * ccWeightMidtones + ccColorHighlights * ccWeightHighlights;
|
||||
}
|
||||
|
||||
float3 ColorGrade(float3 linearColor)
|
||||
{
|
||||
// ACEScg working space
|
||||
const float3x3 sRGB_2_AP1 = mul(XYZ_2_AP1_MAT, mul(D65_2_D60_CAT, sRGB_2_XYZ_MAT));
|
||||
const float3x3 AP1_2_sRGB = mul(XYZ_2_sRGB_MAT, mul(D60_2_D65_CAT, AP1_2_XYZ_MAT));
|
||||
float3 color = mul(sRGB_2_AP1, linearColor);
|
||||
|
||||
// Nuke-style color correct
|
||||
color = ColorCorrectAll(color);
|
||||
color = ccColorShadows * ccWeightShadows + ccColorMidtones * ccWeightMidtones + ccColorHighlights * ccWeightHighlights;
|
||||
|
||||
// Convert back to linear color
|
||||
return mul(AP1_2_sRGB, color);
|
||||
@@ -216,23 +211,20 @@ float4 CombineLUTs(float2 uv, uint layerIndex)
|
||||
{
|
||||
float3 encodedColor;
|
||||
#if USE_VOLUME_LUT
|
||||
// Construct the neutral color from a 3d position volume texture
|
||||
// Calculate the neutral color from 3d position
|
||||
{
|
||||
uv = uv - float2(0.5f / LUTSize, 0.5f / LUTSize);
|
||||
encodedColor = float3(uv * LUTSize / (LUTSize - 1), layerIndex / (LUTSize - 1));
|
||||
}
|
||||
#else
|
||||
// Construct the neutral color from a 2d position in 256x16
|
||||
// Calculate the neutral color from 2d position
|
||||
{
|
||||
uv -= float2(0.49999f / (LUTSize * LUTSize), 0.49999f / LUTSize);
|
||||
|
||||
float3 rgb;
|
||||
rgb.r = frac(uv.x * LUTSize);
|
||||
rgb.b = uv.x - rgb.r / LUTSize;
|
||||
rgb.g = uv.y;
|
||||
|
||||
float scale = LUTSize / (LUTSize - 1);
|
||||
encodedColor = rgb * scale;
|
||||
encodedColor = rgb * (LUTSize / (LUTSize - 1));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ float4 GetExponentialHeightFog(ExponentialHeightFogData exponentialHeightFog, fl
|
||||
float cameraToPosLen = cameraToPosSqr * cameraToPosLenInv;
|
||||
float3 cameraToReceiverNorm = cameraToPos * cameraToPosLenInv;
|
||||
|
||||
float rayOriginTerms = exponentialHeightFog.FogAtViewPosition;
|
||||
float rayOriginTerms = exponentialHeightFog.FogAtViewPosition;
|
||||
float rayLength = cameraToPosLen;
|
||||
float rayDirectionY = cameraToPos.y;
|
||||
|
||||
@@ -48,25 +48,20 @@ float4 GetExponentialHeightFog(ExponentialHeightFogData exponentialHeightFog, fl
|
||||
float excludeIntersectionTime = skipDistance * cameraToPosLenInv;
|
||||
float cameraToExclusionIntersectionY = excludeIntersectionTime * cameraToPos.y;
|
||||
float exclusionIntersectionY = camWS.y + cameraToExclusionIntersectionY;
|
||||
float exclusionIntersectionToReceiverY = cameraToPos.y - cameraToExclusionIntersectionY;
|
||||
|
||||
// Calculate fog off of the ray starting from the exclusion distance, instead of starting from the camera
|
||||
rayLength = (1.0f - excludeIntersectionTime) * cameraToPosLen;
|
||||
rayDirectionY = exclusionIntersectionToReceiverY;
|
||||
|
||||
// Move off the viewer
|
||||
rayDirectionY = cameraToPos.y - cameraToExclusionIntersectionY;
|
||||
float exponent = exponentialHeightFog.FogHeightFalloff * (exclusionIntersectionY - exponentialHeightFog.FogHeight);
|
||||
rayOriginTerms = exponentialHeightFog.FogDensity * exp2(-exponent);
|
||||
}
|
||||
|
||||
// Calculate the line integral of the ray from the camera to the receiver position through the fog density function
|
||||
// Calculate the integral of the ray starting from the view to the object position with the fog density function
|
||||
float falloff = max(-127.0f, exponentialHeightFog.FogHeightFalloff * rayDirectionY);
|
||||
float lineIntegral = (1.0f - exp2(-falloff)) / falloff;
|
||||
float lineIntegralTaylor = log(2.0) - (0.5 * Pow2(log(2.0))) * falloff;
|
||||
float lineIntegralTaylor = log(2.0f) - (0.5f * Pow2(log(2.0f))) * falloff;
|
||||
float exponentialHeightLineIntegralCalc = rayOriginTerms * (abs(falloff) > 0.01f ? lineIntegral : lineIntegralTaylor);
|
||||
float exponentialHeightLineIntegral = exponentialHeightLineIntegralCalc * rayLength;
|
||||
|
||||
// Calculate the amount of light that made it through the fog using the transmission equation
|
||||
// Calculate the light that went through the fog
|
||||
float expFogFactor = max(saturate(exp2(-exponentialHeightLineIntegral)), exponentialHeightFog.FogMinOpacity);
|
||||
|
||||
// Calculate the directional light inscattering
|
||||
@@ -75,17 +70,10 @@ float4 GetExponentialHeightFog(ExponentialHeightFogData exponentialHeightFog, fl
|
||||
BRANCH
|
||||
if (exponentialHeightFog.ApplyDirectionalInscattering > 0)
|
||||
{
|
||||
// Setup a cosine lobe around the light direction to approximate inscattering from the directional light off of the ambient haze
|
||||
float3 directionalLightInscattering = exponentialHeightFog.DirectionalInscatteringColor * pow(saturate(dot(cameraToReceiverNorm, exponentialHeightFog.InscatteringLightDirection)), exponentialHeightFog.DirectionalInscatteringExponent);
|
||||
|
||||
// Calculate the line integral of the eye ray through the haze, using a special starting distance to limit the inscattering to the distance
|
||||
float dirExponentialHeightLineIntegral = exponentialHeightLineIntegralCalc * max(rayLength - exponentialHeightFog.DirectionalInscatteringStartDistance, 0.0f);
|
||||
|
||||
// Calculate the amount of light that made it through the fog using the transmission equation
|
||||
float directionalInscatteringFogFactor = saturate(exp2(-dirExponentialHeightLineIntegral));
|
||||
|
||||
// Final inscattering from the light
|
||||
directionalInscattering = directionalLightInscattering * (1 - directionalInscatteringFogFactor);
|
||||
directionalInscattering = directionalLightInscattering * (1.0f - directionalInscatteringFogFactor);
|
||||
}
|
||||
|
||||
// Disable fog after a certain distance
|
||||
|
||||
@@ -9,24 +9,16 @@ Texture2D Distortion : register(t1);
|
||||
META_PS(true, FEATURE_LEVEL_ES2)
|
||||
float4 PS_ApplyDistortion(Quad_VS2PS input) : SV_Target
|
||||
{
|
||||
// Sample accumulated distortion offset
|
||||
half4 accumDist = Distortion.Sample(SamplerPointClamp, input.TexCoord);
|
||||
|
||||
// Offset = [R-B,G-A]
|
||||
half2 distOffset = (accumDist.rg - accumDist.ba);
|
||||
|
||||
static const half InvDistortionScaleBias = 1 / 4.0f;
|
||||
distOffset *= InvDistortionScaleBias;
|
||||
|
||||
float4 accumDist = Distortion.Sample(SamplerPointClamp, input.TexCoord);
|
||||
float2 distOffset = (accumDist.rg - accumDist.ba) / 4.0f;
|
||||
float2 newTexCoord = input.TexCoord + distOffset;
|
||||
|
||||
// If we're about to sample outside the valid area, set to 0 distortion
|
||||
// Clamp around screen
|
||||
FLATTEN
|
||||
if (newTexCoord.x < 0 || newTexCoord.x > 1 || newTexCoord.y < 0 || newTexCoord.y > 1)
|
||||
{
|
||||
newTexCoord = input.TexCoord;
|
||||
}
|
||||
|
||||
// Sample screen using offset coords
|
||||
return Input.SampleLevel(SamplerPointClamp, newTexCoord, 0);
|
||||
}
|
||||
|
||||
@@ -60,34 +60,18 @@ half3 sRGBToLinear(half3 color)
|
||||
|
||||
float3 LogToLinear(float3 logColor)
|
||||
{
|
||||
const float linearRange = 14;
|
||||
const float linearGrey = 0.18;
|
||||
const float exposureGrey = 444;
|
||||
|
||||
// Using stripped down, 'pure log', formula. Parameterized by grey points and dynamic range covered.
|
||||
float3 linearColor = exp2((logColor - exposureGrey / 1023.0) * linearRange) * linearGrey;
|
||||
//float3 linearColor = 2 * (pow(10.0, ((logColor - 0.616596 - 0.03) / 0.432699)) - 0.037584); // SLog
|
||||
//float3 linearColor = (pow( 10, (1023 * logColor - 685) / 300) - 0.0108) / (1 - 0.0108); // Cineon
|
||||
//linearColor = max(0, linearColor);
|
||||
|
||||
return linearColor;
|
||||
const float linearRange = 14.0f;
|
||||
const float linearGrey = 0.18f;
|
||||
const float exposureGrey = 444.0f;
|
||||
return exp2((logColor - exposureGrey / 1023.0) * linearRange) * linearGrey;
|
||||
}
|
||||
|
||||
float3 LinearToLog(float3 linearColor)
|
||||
{
|
||||
const float linearRange = 14;
|
||||
const float linearGrey = 0.18;
|
||||
const float exposureGrey = 444;
|
||||
|
||||
// Using stripped down, 'pure log', formula. Parameterized by grey points and dynamic range covered.
|
||||
float3 logColor = log2(linearColor) / linearRange - log2(linearGrey) / linearRange + exposureGrey / 1023.0; // scalar: 3log2 3mad
|
||||
//float3 logColor = (log2(linearColor) - log2(linearGrey)) / linearRange + exposureGrey / 1023.0;
|
||||
//float3 logColor = log2(linearColor / linearGrey) / linearRange + exposureGrey / 1023.0;
|
||||
//float3 logColor = (0.432699 * log10(0.5 * linearColor + 0.037584) + 0.616596) + 0.03; // SLog
|
||||
//float3 logColor = (300 * log10(linearColor * (1 - 0.0108) + 0.0108) + 685) / 1023; // Cineon
|
||||
logColor = saturate(logColor);
|
||||
|
||||
return logColor;
|
||||
const float linearRange = 14.0f;
|
||||
const float linearGrey = 0.18f;
|
||||
const float exposureGrey = 444.0f;
|
||||
return saturate(log2(linearColor) / linearRange - log2(linearGrey) / linearRange + exposureGrey / 1023.0f);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -82,19 +82,16 @@ void GetRadialLightAttenuation(
|
||||
BRANCH
|
||||
if (lightData.SourceLength > 0)
|
||||
{
|
||||
// Line segment irradiance
|
||||
float3 L01 = lightData.Direction * lightData.SourceLength;
|
||||
float3 L0 = toLight - 0.5 * L01;
|
||||
float3 L1 = toLight + 0.5 * L01;
|
||||
float LengthL0 = length(L0);
|
||||
float LengthL1 = length(L1);
|
||||
|
||||
distanceAttenuation = rcp((LengthL0 * LengthL1 + dot(L0, L1)) * 0.5 + distanceBiasSqr);
|
||||
NoL = saturate(0.5 * (dot(N, L0) / LengthL0 + dot(N, L1) / LengthL1));
|
||||
float3 l01 = lightData.Direction * lightData.SourceLength;
|
||||
float3 l0 = toLight - 0.5 * l01;
|
||||
float3 l1 = toLight + 0.5 * l01;
|
||||
float lengthL0 = length(l0);
|
||||
float lengthL1 = length(l1);
|
||||
distanceAttenuation = rcp((lengthL0 * lengthL1 + dot(l0, l1)) * 0.5 + distanceBiasSqr);
|
||||
NoL = saturate(0.5 * (dot(N, l0) / lengthL0 + dot(N, l1) / lengthL1));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Sphere irradiance (technically just 1/d^2 but this avoids inf)
|
||||
distanceAttenuation = rcp(distanceSqr + distanceBiasSqr);
|
||||
NoL = saturate(dot(N, L));
|
||||
}
|
||||
|
||||
@@ -98,8 +98,6 @@ Texture2D Input3 : register(t3);
|
||||
Texture2D LensDirt : register(t4);
|
||||
Texture2D LensStar : register(t5);
|
||||
Texture2D LensColor : register(t6);
|
||||
|
||||
// LUT for color grading
|
||||
#if USE_VOLUME_LUT
|
||||
Texture3D ColorGradingLUT : register(t7);
|
||||
#else
|
||||
|
||||
@@ -119,7 +119,7 @@ float SampleShadowMapFixedSizePCF(Texture2DArray shadowMap, float2 shadowMapSize
|
||||
|
||||
if (value != 0.0f)
|
||||
{
|
||||
// Using Gather: xyzw in counter clockwise order starting with the sample to the lower left of the queried location
|
||||
// Gather returns xyzw which is counter clockwise order starting with the sample to the lower left of the queried location
|
||||
#if CAN_USE_GATHER
|
||||
|
||||
v1[(col + FS_2) / 2] = shadowMap.GatherCmp(ShadowSampler, baseUV, sceneDepth, int2(col, row));
|
||||
|
||||
@@ -37,7 +37,7 @@ float3 GlobalEmissive;
|
||||
float HistoryWeight;
|
||||
|
||||
float3 GridSize;
|
||||
uint HistoryMissSuperSampleCount;
|
||||
uint MissedHistorySamplesCount;
|
||||
|
||||
int3 GridSizeInt;
|
||||
float PhaseG;
|
||||
@@ -205,7 +205,7 @@ float4 PS_InjectLight(Quad_GS2PS input) : SV_Target0
|
||||
{
|
||||
historyAlpha = 0;
|
||||
}
|
||||
uint samplesCount = historyAlpha < 0.001f ? HistoryMissSuperSampleCount : 1;
|
||||
uint samplesCount = historyAlpha < 0.001f ? MissedHistorySamplesCount : 1;
|
||||
#else
|
||||
uint samplesCount = 1;
|
||||
#endif
|
||||
@@ -261,7 +261,6 @@ void CS_Initialize(uint3 GroupId : SV_GroupID, uint3 DispatchThreadId : SV_Dispa
|
||||
{
|
||||
uint3 gridCoordinate = DispatchThreadId;
|
||||
|
||||
// Center of the voxel
|
||||
float voxelOffset = 0.5f;
|
||||
float3 positionWS = GetCellPositionWS(gridCoordinate, voxelOffset);
|
||||
|
||||
@@ -272,11 +271,10 @@ void CS_Initialize(uint3 GroupId : SV_GroupID, uint3 DispatchThreadId : SV_Dispa
|
||||
|
||||
// Calculate the global fog density that matches the exponential height fog density
|
||||
float globalDensity = fogDensity * exp2(-fogHeightFalloff * (positionWS.y - fogHeight));
|
||||
float matchFactor = 0.24f;
|
||||
float extinction = max(globalDensity * GlobalExtinctionScale * matchFactor, 0);
|
||||
float extinction = max(0.0f, globalDensity * GlobalExtinctionScale * 0.24f);
|
||||
|
||||
float3 scattering = GlobalAlbedo * extinction;
|
||||
float absorption = max(extinction - Luminance(scattering), 0.0f);
|
||||
float absorption = max(0.0f, extinction - Luminance(scattering));
|
||||
|
||||
if (all((int3)gridCoordinate < GridSizeInt))
|
||||
{
|
||||
@@ -306,7 +304,7 @@ void CS_LightScattering(uint3 GroupId : SV_GroupID, uint3 DispatchThreadId : SV_
|
||||
{
|
||||
uint3 gridCoordinate = DispatchThreadId;
|
||||
float3 lightScattering = 0;
|
||||
uint numSuperSamples = 1;
|
||||
uint samplesCount = 1;
|
||||
|
||||
#if USE_TEMPORAL_REPROJECTION
|
||||
float3 historyUV = GetVolumeUV(GetCellPositionWS(gridCoordinate, 0.5f), PrevWorldToClip);
|
||||
@@ -318,13 +316,11 @@ void CS_LightScattering(uint3 GroupId : SV_GroupID, uint3 DispatchThreadId : SV_
|
||||
{
|
||||
historyAlpha = 0;
|
||||
}
|
||||
|
||||
// Supersample if the history was outside the camera frustum
|
||||
// The compute shader is dispatched with extra threads, make sure those don't supersample
|
||||
numSuperSamples = historyAlpha < 0.001f && all(gridCoordinate < GridSizeInt) ? HistoryMissSuperSampleCount : 1;
|
||||
|
||||
samplesCount = historyAlpha < 0.001f && all(gridCoordinate < GridSizeInt) ? MissedHistorySamplesCount : 1;
|
||||
#endif
|
||||
|
||||
for (uint sampleIndex = 0; sampleIndex < numSuperSamples; sampleIndex++)
|
||||
for (uint sampleIndex = 0; sampleIndex < samplesCount; sampleIndex++)
|
||||
{
|
||||
float3 cellOffset = FrameJitterOffsets[sampleIndex].xyz;
|
||||
//float3 cellOffset = 0.5f;
|
||||
@@ -357,8 +353,7 @@ void CS_LightScattering(uint3 GroupId : SV_GroupID, uint3 DispatchThreadId : SV_
|
||||
lightScattering += skyLighting * SkyLight.VolumetricScatteringIntensity;
|
||||
}
|
||||
}
|
||||
|
||||
lightScattering /= (float)numSuperSamples;
|
||||
lightScattering /= (float)samplesCount;
|
||||
|
||||
// Apply scattering from the point and spot lights
|
||||
lightScattering += LocalShadowedLightScattering[gridCoordinate].rgb;
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace Flax.Deploy
|
||||
}
|
||||
}
|
||||
|
||||
if (TryReadInstallPath("Microsoft\\VisualStudio\\SxS\\VS7", "15.0", "MSBuild\\15.0\\bin\\MSBuild.exe", out toolPath))
|
||||
if (CheckMsBuildPathFromRegistry("Microsoft\\VisualStudio\\SxS\\VS7", "15.0", "MSBuild\\15.0\\bin\\MSBuild.exe", out toolPath))
|
||||
{
|
||||
return toolPath;
|
||||
}
|
||||
@@ -82,17 +82,17 @@ namespace Flax.Deploy
|
||||
return toolPath;
|
||||
}
|
||||
|
||||
if (TryReadInstallPath("Microsoft\\MSBuild\\ToolsVersions\\14.0", "MSBuildToolsPath", "MSBuild.exe", out toolPath))
|
||||
if (CheckMsBuildPathFromRegistry("Microsoft\\MSBuild\\ToolsVersions\\14.0", "MSBuildToolsPath", "MSBuild.exe", out toolPath))
|
||||
{
|
||||
return toolPath;
|
||||
}
|
||||
|
||||
if (TryReadInstallPath("Microsoft\\MSBuild\\ToolsVersions\\12.0", "MSBuildToolsPath", "MSBuild.exe", out toolPath))
|
||||
if (CheckMsBuildPathFromRegistry("Microsoft\\MSBuild\\ToolsVersions\\12.0", "MSBuildToolsPath", "MSBuild.exe", out toolPath))
|
||||
{
|
||||
return toolPath;
|
||||
}
|
||||
|
||||
if (TryReadInstallPath("Microsoft\\MSBuild\\ToolsVersions\\4.0", "MSBuildToolsPath", "MSBuild.exe", out toolPath))
|
||||
if (CheckMsBuildPathFromRegistry("Microsoft\\MSBuild\\ToolsVersions\\4.0", "MSBuildToolsPath", "MSBuild.exe", out toolPath))
|
||||
{
|
||||
return toolPath;
|
||||
}
|
||||
@@ -121,7 +121,7 @@ namespace Flax.Deploy
|
||||
}
|
||||
case TargetPlatform.Windows:
|
||||
{
|
||||
if (TryReadInstallPath("Microsoft\\VisualStudio\\SxS\\VS7", "15.0", "MSBuild\\15.0\\bin\\csc.exe", out toolPath))
|
||||
if (CheckMsBuildPathFromRegistry("Microsoft\\VisualStudio\\SxS\\VS7", "15.0", "MSBuild\\15.0\\bin\\csc.exe", out toolPath))
|
||||
{
|
||||
return toolPath;
|
||||
}
|
||||
@@ -132,17 +132,17 @@ namespace Flax.Deploy
|
||||
return toolPath;
|
||||
}
|
||||
|
||||
if (TryReadInstallPath("Microsoft\\MSBuild\\ToolsVersions\\14.0", "MSBuildToolsPath", "csc.exe", out toolPath))
|
||||
if (CheckMsBuildPathFromRegistry("Microsoft\\MSBuild\\ToolsVersions\\14.0", "MSBuildToolsPath", "csc.exe", out toolPath))
|
||||
{
|
||||
return toolPath;
|
||||
}
|
||||
|
||||
if (TryReadInstallPath("Microsoft\\MSBuild\\ToolsVersions\\12.0", "MSBuildToolsPath", "csc.exe", out toolPath))
|
||||
if (CheckMsBuildPathFromRegistry("Microsoft\\MSBuild\\ToolsVersions\\12.0", "MSBuildToolsPath", "csc.exe", out toolPath))
|
||||
{
|
||||
return toolPath;
|
||||
}
|
||||
|
||||
if (TryReadInstallPath("Microsoft\\MSBuild\\ToolsVersions\\4.0", "MSBuildToolsPath", "csc.exe", out toolPath))
|
||||
if (CheckMsBuildPathFromRegistry("Microsoft\\MSBuild\\ToolsVersions\\4.0", "MSBuildToolsPath", "csc.exe", out toolPath))
|
||||
{
|
||||
return toolPath;
|
||||
}
|
||||
@@ -154,13 +154,9 @@ namespace Flax.Deploy
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queries the registry entries for a certain install directory of the MsBuild.
|
||||
/// </summary>
|
||||
/// <returns>True if found MsBuild tool, otherwise false.</returns>
|
||||
private static bool TryReadInstallPath(string keyRelativePath, string keyName, string msBuildRelativePath, out string outMsBuildPath)
|
||||
private static bool CheckMsBuildPathFromRegistry(string keyRelativePath, string keyName, string msBuildRelativePath, out string outMsBuildPath)
|
||||
{
|
||||
string[] keyBasePaths =
|
||||
string[] prefixes =
|
||||
{
|
||||
@"HKEY_CURRENT_USER\SOFTWARE\",
|
||||
@"HKEY_LOCAL_MACHINE\SOFTWARE\",
|
||||
@@ -168,9 +164,9 @@ namespace Flax.Deploy
|
||||
@"HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\"
|
||||
};
|
||||
|
||||
foreach (string keyBasePath in keyBasePaths)
|
||||
for (var i = 0; i < prefixes.Length; i++)
|
||||
{
|
||||
if (Registry.GetValue(keyBasePath + keyRelativePath, keyName, null) is string value)
|
||||
if (Registry.GetValue(prefixes[i] + keyRelativePath, keyName, null) is string value)
|
||||
{
|
||||
string msBuildPath = Path.Combine(value, msBuildRelativePath);
|
||||
if (File.Exists(msBuildPath))
|
||||
|
||||
Reference in New Issue
Block a user