Fix code style
This commit is contained in:
BIN
Content/Editor/Camera/M_Camera.flax
(Stored with Git LFS)
BIN
Content/Editor/Camera/M_Camera.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/MaterialWire.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/MaterialWire.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/SelectionOutlineMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/SelectionOutlineMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Highlight Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Highlight Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Icons/IconsMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/Icons/IconsMaterial.flax
(Stored with Git LFS)
Binary file not shown.
@@ -114,8 +114,7 @@ Material GetMaterialPS(MaterialInput input)
|
|||||||
@4
|
@4
|
||||||
}
|
}
|
||||||
|
|
||||||
// Programmatically set the line number after all the material inputs which have a variable number of line endings
|
// Fix line for errors/warnings for shader code from template
|
||||||
// This allows shader error line numbers after this point to be the same regardless of which material is being compiled
|
|
||||||
#line 1000
|
#line 1000
|
||||||
|
|
||||||
// Input macro specified by the material: DECAL_BLEND_MODE
|
// Input macro specified by the material: DECAL_BLEND_MODE
|
||||||
@@ -160,10 +159,7 @@ void PS_Decal(
|
|||||||
float3 positionWS = positionHS.xyz / positionHS.w;
|
float3 positionWS = positionHS.xyz / positionHS.w;
|
||||||
float3 positionOS = mul(float4(positionWS, 1), InvWorld).xyz;
|
float3 positionOS = mul(float4(positionWS, 1), InvWorld).xyz;
|
||||||
|
|
||||||
// Clip content outside the decal
|
|
||||||
clip(0.5 - abs(positionOS.xyz));
|
clip(0.5 - abs(positionOS.xyz));
|
||||||
|
|
||||||
// By default, map textures using the vectors perpendicular to the projection direction
|
|
||||||
float2 decalUVs = positionOS.xz + 0.5f;
|
float2 decalUVs = positionOS.xz + 0.5f;
|
||||||
|
|
||||||
// Setup material input
|
// Setup material input
|
||||||
|
|||||||
@@ -197,8 +197,7 @@ Material GetMaterialPS(MaterialInput input)
|
|||||||
@4
|
@4
|
||||||
}
|
}
|
||||||
|
|
||||||
// Programmatically set the line number after all the material inputs which have a variable number of line endings
|
// Fix line for errors/warnings for shader code from template
|
||||||
// This allows shader error line numbers after this point to be the same regardless of which material is being compiled
|
|
||||||
#line 1000
|
#line 1000
|
||||||
|
|
||||||
// Vertex Shader function for GUI materials rendering
|
// Vertex Shader function for GUI materials rendering
|
||||||
|
|||||||
@@ -330,8 +330,7 @@ Material GetMaterialPS(MaterialInput input)
|
|||||||
@4
|
@4
|
||||||
}
|
}
|
||||||
|
|
||||||
// Programmatically set the line number after all the material inputs which have a variable number of line endings
|
// Fix line for errors/warnings for shader code from template
|
||||||
// This allows shader error line numbers after this point to be the same regardless of which material is being compiled
|
|
||||||
#line 1000
|
#line 1000
|
||||||
|
|
||||||
// Calculates the transform matrix from mesh tangent space to local space
|
// Calculates the transform matrix from mesh tangent space to local space
|
||||||
@@ -834,7 +833,7 @@ float4 PS_Distortion(PixelInput input) : SV_Target0
|
|||||||
// Scale up for better precision in low/subtle refractions at the expense of artefacts at higher refraction
|
// Scale up for better precision in low/subtle refractions at the expense of artefacts at higher refraction
|
||||||
distortion *= 4.0f;
|
distortion *= 4.0f;
|
||||||
|
|
||||||
// Store positive and negative offsets separately
|
// Use separate storage for positive and negative offsets
|
||||||
float2 addOffset = max(distortion, 0);
|
float2 addOffset = max(distortion, 0);
|
||||||
float2 subOffset = abs(min(distortion, 0));
|
float2 subOffset = abs(min(distortion, 0));
|
||||||
return float4(addOffset.x, addOffset.y, subOffset.x, subOffset.y);
|
return float4(addOffset.x, addOffset.y, subOffset.x, subOffset.y);
|
||||||
|
|||||||
@@ -134,8 +134,7 @@ Material GetMaterialPS(MaterialInput input)
|
|||||||
@4
|
@4
|
||||||
}
|
}
|
||||||
|
|
||||||
// Programmatically set the line number after all the material inputs which have a variable number of line endings
|
// Fix line for errors/warnings for shader code from template
|
||||||
// This allows shader error line numbers after this point to be the same regardless of which material is being compiled
|
|
||||||
#line 1000
|
#line 1000
|
||||||
|
|
||||||
// Pixel Shader function for PostFx materials rendering
|
// Pixel Shader function for PostFx materials rendering
|
||||||
|
|||||||
@@ -340,8 +340,7 @@ Material GetMaterialPS(MaterialInput input)
|
|||||||
@4
|
@4
|
||||||
}
|
}
|
||||||
|
|
||||||
// Programmatically set the line number after all the material inputs which have a variable number of line endings
|
// Fix line for errors/warnings for shader code from template
|
||||||
// This allows shader error line numbers after this point to be the same regardless of which material is being compiled
|
|
||||||
#line 1000
|
#line 1000
|
||||||
|
|
||||||
// Calculates the transform matrix from mesh tangent space to local space
|
// Calculates the transform matrix from mesh tangent space to local space
|
||||||
@@ -500,7 +499,7 @@ float3x4 GetBoneMatrix(int index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calculates the transposed transform matrix for the given vertex (uses blending)
|
// Calculates the transposed transform matrix for the given vertex (uses blending)
|
||||||
float3x4 CalcBoneMatrix(ModelInput_Skinned input)
|
float3x4 GetBoneMatrix(ModelInput_Skinned input)
|
||||||
{
|
{
|
||||||
float3x4 boneMatrix = input.BlendWeights.x * GetBoneMatrix(input.BlendIndices.x);
|
float3x4 boneMatrix = input.BlendWeights.x * GetBoneMatrix(input.BlendIndices.x);
|
||||||
boneMatrix += input.BlendWeights.y * GetBoneMatrix(input.BlendIndices.y);
|
boneMatrix += input.BlendWeights.y * GetBoneMatrix(input.BlendIndices.y);
|
||||||
@@ -549,7 +548,7 @@ VertexOutput VS_Skinned(ModelInput_Skinned input)
|
|||||||
|
|
||||||
// Perform skinning
|
// Perform skinning
|
||||||
SkinningData data;
|
SkinningData data;
|
||||||
data.BlendMatrix = CalcBoneMatrix(input);
|
data.BlendMatrix = GetBoneMatrix(input);
|
||||||
float3 position = SkinPosition(input, data);
|
float3 position = SkinPosition(input, data);
|
||||||
float3x3 tangentToLocal = SkinTangents(input, data);
|
float3x3 tangentToLocal = SkinTangents(input, data);
|
||||||
|
|
||||||
@@ -808,7 +807,6 @@ TessalationDSToPS DS(TessalationPatch constantData, float3 barycentricCoords : S
|
|||||||
#define COPY(thing) output.thing = input[0].thing
|
#define COPY(thing) output.thing = input[0].thing
|
||||||
INTERPOLATE(Position);
|
INTERPOLATE(Position);
|
||||||
#if MATERIAL_TESSELLATION == MATERIAL_TESSELLATION_PN
|
#if MATERIAL_TESSELLATION == MATERIAL_TESSELLATION_PN
|
||||||
// Precompute squares and squares * 3
|
|
||||||
float UU = U * U;
|
float UU = U * U;
|
||||||
float VV = V * V;
|
float VV = V * V;
|
||||||
float WW = W * W;
|
float WW = W * W;
|
||||||
|
|||||||
@@ -337,8 +337,7 @@ Material GetMaterialPS(MaterialInput input)
|
|||||||
@4
|
@4
|
||||||
}
|
}
|
||||||
|
|
||||||
// Programmatically set the line number after all the material inputs which have a variable number of line endings
|
// Fix line for errors/warnings for shader code from template
|
||||||
// This allows shader error line numbers after this point to be the same regardless of which material is being compiled
|
|
||||||
#line 1000
|
#line 1000
|
||||||
|
|
||||||
// Calculates the transform matrix from mesh tangent space to local space
|
// Calculates the transform matrix from mesh tangent space to local space
|
||||||
@@ -474,7 +473,7 @@ float3x4 GetBoneMatrix(int index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calculates the transposed transform matrix for the given vertex (uses blending)
|
// Calculates the transposed transform matrix for the given vertex (uses blending)
|
||||||
float3x4 CalcBoneMatrix(ModelInput_Skinned input)
|
float3x4 GetBoneMatrix(ModelInput_Skinned input)
|
||||||
{
|
{
|
||||||
float3x4 boneMatrix = input.BlendWeights.x * GetBoneMatrix(input.BlendIndices.x);
|
float3x4 boneMatrix = input.BlendWeights.x * GetBoneMatrix(input.BlendIndices.x);
|
||||||
boneMatrix += input.BlendWeights.y * GetBoneMatrix(input.BlendIndices.y);
|
boneMatrix += input.BlendWeights.y * GetBoneMatrix(input.BlendIndices.y);
|
||||||
@@ -521,7 +520,7 @@ VertexOutput VS_Skinned(ModelInput_Skinned input)
|
|||||||
|
|
||||||
// Perform skinning
|
// Perform skinning
|
||||||
SkinningData data;
|
SkinningData data;
|
||||||
data.BlendMatrix = CalcBoneMatrix(input);
|
data.BlendMatrix = GetBoneMatrix(input);
|
||||||
float3 position = SkinPosition(input, data);
|
float3 position = SkinPosition(input, data);
|
||||||
half3x3 tangentToLocal = SkinTangents(input, data);
|
half3x3 tangentToLocal = SkinTangents(input, data);
|
||||||
|
|
||||||
@@ -755,7 +754,6 @@ TessalationDSToPS DS(TessalationPatch constantData, float3 barycentricCoords : S
|
|||||||
#define COPY(thing) output.thing = input[0].thing
|
#define COPY(thing) output.thing = input[0].thing
|
||||||
INTERPOLATE(Position);
|
INTERPOLATE(Position);
|
||||||
#if MATERIAL_TESSELLATION == MATERIAL_TESSELLATION_PN
|
#if MATERIAL_TESSELLATION == MATERIAL_TESSELLATION_PN
|
||||||
// Precompute squares and squares * 3
|
|
||||||
float UU = U * U;
|
float UU = U * U;
|
||||||
float VV = V * V;
|
float VV = V * V;
|
||||||
float WW = W * W;
|
float WW = W * W;
|
||||||
@@ -978,7 +976,7 @@ float4 PS_Distortion(PixelInput input) : SV_Target0
|
|||||||
// Scale up for better precision in low/subtle refractions at the expense of artefacts at higher refraction
|
// Scale up for better precision in low/subtle refractions at the expense of artefacts at higher refraction
|
||||||
distortion *= 4.0f;
|
distortion *= 4.0f;
|
||||||
|
|
||||||
// Store positive and negative offsets separately
|
// Use separate storage for positive and negative offsets
|
||||||
float2 addOffset = max(distortion, 0);
|
float2 addOffset = max(distortion, 0);
|
||||||
float2 subOffset = abs(min(distortion, 0));
|
float2 subOffset = abs(min(distortion, 0));
|
||||||
return float4(addOffset.x, addOffset.y, subOffset.x, subOffset.y);
|
return float4(addOffset.x, addOffset.y, subOffset.x, subOffset.y);
|
||||||
|
|||||||
@@ -234,8 +234,7 @@ Material GetMaterialPS(MaterialInput input)
|
|||||||
@4
|
@4
|
||||||
}
|
}
|
||||||
|
|
||||||
// Programmatically set the line number after all the material inputs which have a variable number of line endings
|
// Fix line for errors/warnings for shader code from template
|
||||||
// This allows shader error line numbers after this point to be the same regardless of which material is being compiled
|
|
||||||
#line 1000
|
#line 1000
|
||||||
|
|
||||||
// Calculates LOD value (with fractional part for blending)
|
// Calculates LOD value (with fractional part for blending)
|
||||||
@@ -595,7 +594,6 @@ TessalationDSToPS DS(TessalationPatch constantData, float3 barycentricCoords : S
|
|||||||
#define COPY(thing) output.thing = input[0].thing
|
#define COPY(thing) output.thing = input[0].thing
|
||||||
INTERPOLATE(Position);
|
INTERPOLATE(Position);
|
||||||
#if MATERIAL_TESSELLATION == MATERIAL_TESSELLATION_PN
|
#if MATERIAL_TESSELLATION == MATERIAL_TESSELLATION_PN
|
||||||
// Precompute squares and squares * 3
|
|
||||||
float UU = U * U;
|
float UU = U * U;
|
||||||
float VV = V * V;
|
float VV = V * V;
|
||||||
float WW = W * W;
|
float WW = W * W;
|
||||||
|
|||||||
BIN
Content/Editor/Particles/Smoke Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Particles/Smoke Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Wires Debug Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Wires Debug Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/DefaultMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/DefaultMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/DefaultTerrainMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/DefaultTerrainMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/ColorGrading.flax
(Stored with Git LFS)
BIN
Content/Shaders/ColorGrading.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/Forward.flax
(Stored with Git LFS)
BIN
Content/Shaders/Forward.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/PostProcessing.flax
(Stored with Git LFS)
BIN
Content/Shaders/PostProcessing.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/VolumetricFog.flax
(Stored with Git LFS)
BIN
Content/Shaders/VolumetricFog.flax
(Stored with Git LFS)
Binary file not shown.
@@ -115,11 +115,9 @@ namespace FlaxEditor.Viewport.Previews
|
|||||||
var color = Color;
|
var color = Color;
|
||||||
if (!EnabledInHierarchy)
|
if (!EnabledInHierarchy)
|
||||||
color *= 0.4f;
|
color *= 0.4f;
|
||||||
|
var sampleValueScale = height / info.NumChannels;
|
||||||
|
|
||||||
// Compute the scaled y-value used to render the channel data
|
// Calculate the amount of samples that are contained in the view
|
||||||
float sampleYScale = height / info.NumChannels;
|
|
||||||
|
|
||||||
// Compute amount of samples that are contained in the view
|
|
||||||
float unitsPerSecond = UnitsPerSecond * ViewScale;
|
float unitsPerSecond = UnitsPerSecond * ViewScale;
|
||||||
float clipDefaultWidth = length * unitsPerSecond;
|
float clipDefaultWidth = length * unitsPerSecond;
|
||||||
float clipsInView = width / clipDefaultWidth;
|
float clipsInView = width / clipDefaultWidth;
|
||||||
@@ -173,7 +171,7 @@ namespace FlaxEditor.Viewport.Previews
|
|||||||
if (samplesInPixel > 0)
|
if (samplesInPixel > 0)
|
||||||
{
|
{
|
||||||
float sampleValueAvg = samplesSum / samplesInPixel;
|
float sampleValueAvg = samplesSum / samplesInPixel;
|
||||||
float sampleValueAvgScaled = sampleValueAvg * sampleYScale;
|
float sampleValueAvgScaled = sampleValueAvg * sampleValueScale;
|
||||||
if (sampleValueAvgScaled > 0.1f)
|
if (sampleValueAvgScaled > 0.1f)
|
||||||
{
|
{
|
||||||
Render2D.DrawLine(new Vector2(pixelX, yCenter - sampleValueAvgScaled), new Vector2(pixelX, yCenter + sampleValueAvgScaled), color);
|
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;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value > sortedValues[endPos])
|
if (value > sortedValues[endPos])
|
||||||
{
|
{
|
||||||
return static_cast<float>(endPos);
|
return static_cast<float>(endPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Binary search
|
|
||||||
while (startPos < endPos)
|
while (startPos < endPos)
|
||||||
{
|
{
|
||||||
const uint32 testPos = (startPos + endPos + 1) / 2;
|
const uint32 testPos = (startPos + endPos + 1) / 2;
|
||||||
|
|
||||||
const float testValue = sortedValues[testPos];
|
const float testValue = sortedValues[testPos];
|
||||||
|
|
||||||
if (value >= testValue)
|
if (value >= testValue)
|
||||||
{
|
{
|
||||||
// Prevent endless loop
|
|
||||||
ASSERT(startPos != testPos);
|
ASSERT(startPos != testPos);
|
||||||
|
|
||||||
startPos = testPos;
|
startPos = testPos;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Prevent endless loop
|
|
||||||
ASSERT(endPos != testPos - 1);
|
ASSERT(endPos != testPos - 1);
|
||||||
|
|
||||||
endPos = testPos - 1;
|
endPos = testPos - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const float leftValue = sortedValues[startPos];
|
const float leftValue = sortedValues[startPos];
|
||||||
|
|
||||||
float fraction = 0.0f;
|
float fraction = 0.0f;
|
||||||
|
|
||||||
if (startPos + 1 < static_cast<uint32>(sortedValues.Count()))
|
if (startPos + 1 < static_cast<uint32>(sortedValues.Count()))
|
||||||
{
|
{
|
||||||
// If not at right border
|
|
||||||
const float rightValue = sortedValues[startPos + 1];
|
const float rightValue = sortedValues[startPos + 1];
|
||||||
const float deltaValue = rightValue - leftValue;
|
const float deltaValue = rightValue - leftValue;
|
||||||
|
if (deltaValue > 0.00005f)
|
||||||
if (deltaValue > 0.0001f)
|
|
||||||
{
|
{
|
||||||
fraction = (value - leftValue) / deltaValue;
|
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)
|
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);
|
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 axisU = position - closestPointOnAxis;
|
||||||
const Vector3 axisV = Vector3::Cross(normalizedRotationAxis, axisU);
|
const Vector3 axisV = Vector3::Cross(normalizedRotationAxis, axisU);
|
||||||
float cosAngle, sinAngle;
|
float cosAngle, sinAngle;
|
||||||
Math::SinCos(angle, sinAngle, cosAngle);
|
Math::SinCos(angle, sinAngle, cosAngle);
|
||||||
|
|
||||||
// Rotate using the orthogonal axes
|
|
||||||
const Vector3 rotation = axisU * cosAngle + axisV * sinAngle;
|
const Vector3 rotation = axisU * cosAngle + axisV * sinAngle;
|
||||||
|
|
||||||
// Reconstruct the rotated world space position
|
|
||||||
const Vector3 rotatedPosition = closestPointOnAxis + rotation;
|
const Vector3 rotatedPosition = closestPointOnAxis + rotation;
|
||||||
|
|
||||||
// Convert from position to a position offset
|
|
||||||
return rotatedPosition - position;
|
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 y = planes[i].Normal.Y;
|
||||||
const float z = planes[i].Normal.Z;
|
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.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.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);
|
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
|
DayOfWeek DateTime::GetDayOfWeek() const
|
||||||
{
|
{
|
||||||
// January 1, 0001 was a Monday
|
|
||||||
return static_cast<DayOfWeek>((Ticks / Constants::TicksPerDay) % 7);
|
return static_cast<DayOfWeek>((Ticks / Constants::TicksPerDay) % 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,8 +63,8 @@ int32 DateTime::GetDayOfYear() const
|
|||||||
{
|
{
|
||||||
int32 year, month, day;
|
int32 year, month, day;
|
||||||
GetDate(year, month, day);
|
GetDate(year, month, day);
|
||||||
for (int32 currentMonth = 1; currentMonth < month; currentMonth++)
|
for (int32 i = 1; i < month; i++)
|
||||||
day += DaysInMonth(year, currentMonth);
|
day += DaysInMonth(year, i);
|
||||||
return day;
|
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)
|
bool DateTime::Validate(int32 year, int32 month, int32 day, int32 hour, int32 minute, int32 second, int32 millisecond)
|
||||||
{
|
{
|
||||||
return (year >= 1) && (year <= 9999) &&
|
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;
|
||||||
(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
|
String DateTime::ToString() const
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ TimeSpan TimeSpan::FromSeconds(double seconds)
|
|||||||
return TimeSpan(static_cast<int64>(seconds * Constants::TicksPerSecond));
|
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;
|
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()));
|
ASSERT_LOW_LAYER((totalMs >= MinValue().GetTotalMilliseconds()) && (totalMs <= MaxValue().GetTotalMilliseconds()));
|
||||||
|
|||||||
@@ -49,8 +49,10 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init
|
/// <summary>
|
||||||
// @param ticks The number of ticks
|
/// Initializes a new instance of the <see cref="TimeSpan"/> struct.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ticks">The ticks in 100 nanoseconds resolution.</param>
|
||||||
TimeSpan(int64 ticks)
|
TimeSpan(int64 ticks)
|
||||||
: Ticks(ticks)
|
: Ticks(ticks)
|
||||||
{
|
{
|
||||||
@@ -62,7 +64,7 @@ public:
|
|||||||
// @param Minutes Amount of minutes
|
// @param Minutes Amount of minutes
|
||||||
TimeSpan(int32 days, int32 hours, int32 minutes)
|
TimeSpan(int32 days, int32 hours, int32 minutes)
|
||||||
{
|
{
|
||||||
Assign(days, hours, minutes, 0, 0);
|
Set(days, hours, minutes, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init
|
// Init
|
||||||
@@ -72,7 +74,7 @@ public:
|
|||||||
// @param Seconds Amount of seconds
|
// @param Seconds Amount of seconds
|
||||||
TimeSpan(int32 days, int32 hours, int32 minutes, int32 seconds)
|
TimeSpan(int32 days, int32 hours, int32 minutes, int32 seconds)
|
||||||
{
|
{
|
||||||
Assign(days, hours, minutes, seconds, 0);
|
Set(days, hours, minutes, seconds, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init
|
// Init
|
||||||
@@ -83,7 +85,7 @@ public:
|
|||||||
// @param Milliseconds Amount of milliseconds
|
// @param Milliseconds Amount of milliseconds
|
||||||
TimeSpan(int32 days, int32 hours, int32 minutes, int32 seconds, int32 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:
|
public:
|
||||||
@@ -325,7 +327,7 @@ public:
|
|||||||
|
|
||||||
private:
|
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)
|
inline TimeSpan operator*(float scalar, const TimeSpan& timespan)
|
||||||
|
|||||||
@@ -46,13 +46,13 @@ public:
|
|||||||
{
|
{
|
||||||
ASSERT(_subresourceState.IsEmpty() && subresourceCount > 0);
|
ASSERT(_subresourceState.IsEmpty() && subresourceCount > 0);
|
||||||
|
|
||||||
// Allocate space for per-subresource tracking structures
|
|
||||||
if (usePerSubresourceTracking && subresourceCount > 1)
|
|
||||||
_subresourceState.Resize(subresourceCount, false);
|
|
||||||
|
|
||||||
// Initialize state
|
// Initialize state
|
||||||
_allSubresourcesSame = true;
|
_allSubresourcesSame = true;
|
||||||
_resourceState = initialState;
|
_resourceState = initialState;
|
||||||
|
|
||||||
|
// Allocate space for per-subresource state tracking
|
||||||
|
if (usePerSubresourceTracking && subresourceCount > 1)
|
||||||
|
_subresourceState.Resize(subresourceCount, false);
|
||||||
#if BUILD_DEBUG
|
#if BUILD_DEBUG
|
||||||
_subresourceState.SetAll(InvalidState);
|
_subresourceState.SetAll(InvalidState);
|
||||||
#endif
|
#endif
|
||||||
@@ -124,7 +124,7 @@ public:
|
|||||||
|
|
||||||
void SetSubresourceState(int32 subresourceIndex, StateType state)
|
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)
|
if (subresourceIndex == -1 || _subresourceState.Count() <= 1)
|
||||||
{
|
{
|
||||||
SetResourceState(state);
|
SetResourceState(state);
|
||||||
@@ -133,16 +133,14 @@ public:
|
|||||||
{
|
{
|
||||||
ASSERT(subresourceIndex < static_cast<int32>(_subresourceState.Count()));
|
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)
|
if (_allSubresourcesSame)
|
||||||
{
|
{
|
||||||
for (int32 i = 0; i < _subresourceState.Count(); i++)
|
for (int32 i = 0; i < _subresourceState.Count(); i++)
|
||||||
{
|
{
|
||||||
_subresourceState[i] = _resourceState;
|
_subresourceState[i] = _resourceState;
|
||||||
}
|
}
|
||||||
|
|
||||||
_allSubresourcesSame = 0;
|
_allSubresourcesSame = 0;
|
||||||
|
|
||||||
#if BUILD_DEBUG
|
#if BUILD_DEBUG
|
||||||
_resourceState = InvalidState;
|
_resourceState = InvalidState;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -23,9 +23,8 @@
|
|||||||
#define DX11_FORCE_USE_DX10 0
|
#define DX11_FORCE_USE_DX10 0
|
||||||
#define DX11_FORCE_USE_DX10_1 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;
|
ID3D11Device* device = nullptr;
|
||||||
ID3D11DeviceContext* context = nullptr;
|
ID3D11DeviceContext* context = nullptr;
|
||||||
uint32 deviceFlags = D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_BGRA_SUPPORT;
|
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;
|
deviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
D3D_FEATURE_LEVEL requestedFeatureLevels[] =
|
// Pick the first level
|
||||||
|
D3D_FEATURE_LEVEL featureLevels[] =
|
||||||
{
|
{
|
||||||
D3D_FEATURE_LEVEL_11_1,
|
D3D_FEATURE_LEVEL_11_1,
|
||||||
D3D_FEATURE_LEVEL_11_0,
|
D3D_FEATURE_LEVEL_11_0,
|
||||||
D3D_FEATURE_LEVEL_10_1,
|
D3D_FEATURE_LEVEL_10_1,
|
||||||
D3D_FEATURE_LEVEL_10_0
|
D3D_FEATURE_LEVEL_10_0
|
||||||
};
|
};
|
||||||
|
int32 levelIndex = 0;
|
||||||
int32 firstAllowedFeatureLevel = 0;
|
while (levelIndex < ARRAY_COUNT(featureLevels))
|
||||||
int32 numAllowedFeatureLevels = ARRAY_COUNT(requestedFeatureLevels);
|
|
||||||
while (firstAllowedFeatureLevel < numAllowedFeatureLevels)
|
|
||||||
{
|
|
||||||
if (requestedFeatureLevels[firstAllowedFeatureLevel] == maxFeatureLevel)
|
|
||||||
{
|
{
|
||||||
|
if (featureLevels[levelIndex] == maxFeatureLevel)
|
||||||
break;
|
break;
|
||||||
|
levelIndex++;
|
||||||
}
|
}
|
||||||
firstAllowedFeatureLevel++;
|
if (levelIndex >= ARRAY_COUNT(featureLevels))
|
||||||
}
|
|
||||||
numAllowedFeatureLevels -= firstAllowedFeatureLevel;
|
|
||||||
if (numAllowedFeatureLevels == 0)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -63,18 +58,16 @@ static bool TryCreateDevice(IDXGIAdapter* adapter, D3D_FEATURE_LEVEL maxFeatureL
|
|||||||
D3D_DRIVER_TYPE_UNKNOWN,
|
D3D_DRIVER_TYPE_UNKNOWN,
|
||||||
NULL,
|
NULL,
|
||||||
deviceFlags,
|
deviceFlags,
|
||||||
&requestedFeatureLevels[firstAllowedFeatureLevel],
|
&featureLevels[levelIndex],
|
||||||
numAllowedFeatureLevels,
|
ARRAY_COUNT(featureLevels) - levelIndex,
|
||||||
D3D11_SDK_VERSION,
|
D3D11_SDK_VERSION,
|
||||||
&device,
|
&device,
|
||||||
outFeatureLevel,
|
featureLevel,
|
||||||
&context
|
&context
|
||||||
)))
|
)))
|
||||||
{
|
{
|
||||||
// Release created stuff
|
|
||||||
device->Release();
|
device->Release();
|
||||||
context->Release();
|
context->Release();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -144,10 +144,8 @@ bool GPUTextureDX12::OnInit()
|
|||||||
{
|
{
|
||||||
resourceDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
|
resourceDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
|
||||||
initialState = D3D12_RESOURCE_STATE_DEPTH_WRITE;
|
initialState = D3D12_RESOURCE_STATE_DEPTH_WRITE;
|
||||||
|
|
||||||
if (!useSRV)
|
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;
|
resourceDesc.Flags |= D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ void QueryHeapDX12::EndQueryBatchAndResolveQueryData(GPUContextDX12* context)
|
|||||||
{
|
{
|
||||||
ASSERT(_currentBatch.Open);
|
ASSERT(_currentBatch.Open);
|
||||||
|
|
||||||
// Discard empty batches
|
// Skip empty batches
|
||||||
if (_currentBatch.Count == 0)
|
if (_currentBatch.Count == 0)
|
||||||
{
|
{
|
||||||
return;
|
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 = _pool.Create();
|
||||||
_activeCmdBuffer->Begin();
|
_activeCmdBuffer->Begin();
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ void DescriptorSetLayoutInfoVulkan::CacheTypesUsageID()
|
|||||||
|
|
||||||
void DescriptorSetLayoutInfoVulkan::AddDescriptor(int32 descriptorSetIndex, const VkDescriptorSetLayoutBinding& descriptor)
|
void DescriptorSetLayoutInfoVulkan::AddDescriptor(int32 descriptorSetIndex, const VkDescriptorSetLayoutBinding& descriptor)
|
||||||
{
|
{
|
||||||
// Increment type usage
|
|
||||||
_layoutTypes[descriptor.descriptorType]++;
|
_layoutTypes[descriptor.descriptorType]++;
|
||||||
|
|
||||||
if (descriptorSetIndex >= _setLayouts.Count())
|
if (descriptorSetIndex >= _setLayouts.Count())
|
||||||
@@ -43,7 +42,6 @@ void DescriptorSetLayoutInfoVulkan::AddDescriptor(int32 descriptorSetIndex, cons
|
|||||||
SetLayout& descSetLayout = _setLayouts[descriptorSetIndex];
|
SetLayout& descSetLayout = _setLayouts[descriptorSetIndex];
|
||||||
descSetLayout.LayoutBindings.Add(descriptor);
|
descSetLayout.LayoutBindings.Add(descriptor);
|
||||||
|
|
||||||
// TODO: manual hash update method?
|
|
||||||
_hash = Crc::MemCrc32(&descriptor, sizeof(descriptor), _hash);
|
_hash = Crc::MemCrc32(&descriptor, sizeof(descriptor), _hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,20 +114,20 @@ void DescriptorSetLayoutVulkan::Compile()
|
|||||||
DescriptorPoolVulkan::DescriptorPoolVulkan(GPUDeviceVulkan* device, const DescriptorSetLayoutVulkan& layout)
|
DescriptorPoolVulkan::DescriptorPoolVulkan(GPUDeviceVulkan* device, const DescriptorSetLayoutVulkan& layout)
|
||||||
: _device(device)
|
: _device(device)
|
||||||
, _handle(VK_NULL_HANDLE)
|
, _handle(VK_NULL_HANDLE)
|
||||||
, DescriptorSetsMax(0)
|
, _descriptorSetsMax(0)
|
||||||
, AllocatedDescriptorSetsCount(0)
|
, _allocatedDescriptorSetsCount(0)
|
||||||
, AllocatedDescriptorSetsCountMax(0)
|
, _allocatedDescriptorSetsCountMax(0)
|
||||||
, Layout(layout)
|
, _layout(layout)
|
||||||
{
|
{
|
||||||
Array<VkDescriptorPoolSize, FixedAllocation<VULKAN_DESCRIPTOR_TYPE_END + 1>> types;
|
Array<VkDescriptorPoolSize, FixedAllocation<VULKAN_DESCRIPTOR_TYPE_END + 1>> types;
|
||||||
|
|
||||||
// The maximum amount of descriptor sets layout allocations to hold
|
// The maximum amount of descriptor sets layout allocations to hold
|
||||||
const uint32 MaxSetsAllocations = 256;
|
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++)
|
for (uint32 typeIndex = VULKAN_DESCRIPTOR_TYPE_BEGIN; typeIndex <= VULKAN_DESCRIPTOR_TYPE_END; typeIndex++)
|
||||||
{
|
{
|
||||||
const VkDescriptorType descriptorType = (VkDescriptorType)typeIndex;
|
const VkDescriptorType descriptorType = (VkDescriptorType)typeIndex;
|
||||||
const uint32 typesUsed = Layout.GetTypesUsed(descriptorType);
|
const uint32 typesUsed = _layout.GetTypesUsed(descriptorType);
|
||||||
if (typesUsed > 0)
|
if (typesUsed > 0)
|
||||||
{
|
{
|
||||||
VkDescriptorPoolSize& type = types.AddOne();
|
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.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
|
||||||
createInfo.poolSizeCount = types.Count();
|
createInfo.poolSizeCount = types.Count();
|
||||||
createInfo.pPoolSizes = types.Get();
|
createInfo.pPoolSizes = types.Get();
|
||||||
createInfo.maxSets = DescriptorSetsMax;
|
createInfo.maxSets = _descriptorSetsMax;
|
||||||
VALIDATE_VULKAN_RESULT(vkCreateDescriptorPool(_device->Device, &createInfo, nullptr, &_handle));
|
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++)
|
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));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
AllocatedDescriptorSetsCount += layout.GetLayouts().Count();
|
_allocatedDescriptorSetsCount += layout.GetLayouts().Count();
|
||||||
AllocatedDescriptorSetsCountMax = Math::Max(AllocatedDescriptorSetsCount, AllocatedDescriptorSetsCountMax);
|
_allocatedDescriptorSetsCountMax = Math::Max(_allocatedDescriptorSetsCount, _allocatedDescriptorSetsCountMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorPoolVulkan::TrackRemoveUsage(const DescriptorSetLayoutVulkan& layout)
|
void DescriptorPoolVulkan::TrackRemoveUsage(const DescriptorSetLayoutVulkan& layout)
|
||||||
@@ -173,10 +171,10 @@ void DescriptorPoolVulkan::TrackRemoveUsage(const DescriptorSetLayoutVulkan& lay
|
|||||||
// Check and increment our current type usage
|
// Check and increment our current type usage
|
||||||
for (uint32 typeIndex = VULKAN_DESCRIPTOR_TYPE_BEGIN; typeIndex <= VULKAN_DESCRIPTOR_TYPE_END; typeIndex++)
|
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()
|
void DescriptorPoolVulkan::Reset()
|
||||||
@@ -185,7 +183,7 @@ void DescriptorPoolVulkan::Reset()
|
|||||||
{
|
{
|
||||||
VALIDATE_VULKAN_RESULT(vkResetDescriptorPool(_device->Device, _handle, 0));
|
VALIDATE_VULKAN_RESULT(vkResetDescriptorPool(_device->Device, _handle, 0));
|
||||||
}
|
}
|
||||||
AllocatedDescriptorSetsCount = 0;
|
_allocatedDescriptorSetsCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DescriptorPoolVulkan::AllocateDescriptorSets(const VkDescriptorSetAllocateInfo& descriptorSetAllocateInfo, VkDescriptorSet* result)
|
bool DescriptorPoolVulkan::AllocateDescriptorSets(const VkDescriptorSetAllocateInfo& descriptorSetAllocateInfo, VkDescriptorSet* result)
|
||||||
@@ -335,8 +333,6 @@ void DescriptorPoolsManagerVulkan::ReleasePoolSet(DescriptorPoolSetContainerVulk
|
|||||||
void DescriptorPoolsManagerVulkan::GC()
|
void DescriptorPoolsManagerVulkan::GC()
|
||||||
{
|
{
|
||||||
ScopeLock lock(_locker);
|
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--)
|
for (int32 i = _poolSets.Count() - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
const auto poolSet = _poolSets[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;
|
WriteDescriptors = writeDescriptors;
|
||||||
WritesCount = info.DescriptorTypesCount;
|
WritesCount = info.DescriptorTypesCount;
|
||||||
ASSERT(info.DescriptorTypesCount <= 64 && TEXT("Out of bits for Dirty Mask! More than 64 resources in one descriptor set!"));
|
BindingToDynamicOffset = bindingToDynamicOffset;
|
||||||
BindingToDynamicOffsetMap = bindingToDynamicOffsetMap;
|
|
||||||
|
|
||||||
uint32 dynamicOffsetIndex = 0;
|
uint32 dynamicOffsetIndex = 0;
|
||||||
for (uint32 i = 0; i < info.DescriptorTypesCount; i++)
|
for (uint32 i = 0; i < info.DescriptorTypesCount; i++)
|
||||||
@@ -392,8 +388,8 @@ uint32 DescriptorSetWriterVulkan::SetupDescriptorWrites(const SpirvShaderDescrip
|
|||||||
switch (writeDescriptors->descriptorType)
|
switch (writeDescriptors->descriptorType)
|
||||||
{
|
{
|
||||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
|
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
|
||||||
BindingToDynamicOffsetMap[i] = dynamicOffsetIndex;
|
BindingToDynamicOffset[i] = dynamicOffsetIndex;
|
||||||
++dynamicOffsetIndex;
|
dynamicOffsetIndex++;
|
||||||
writeDescriptors->pBufferInfo = bufferInfo++;
|
writeDescriptors->pBufferInfo = bufferInfo++;
|
||||||
break;
|
break;
|
||||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
||||||
|
|||||||
@@ -230,16 +230,15 @@ private:
|
|||||||
GPUDeviceVulkan* _device;
|
GPUDeviceVulkan* _device;
|
||||||
VkDescriptorPool _handle;
|
VkDescriptorPool _handle;
|
||||||
|
|
||||||
uint32 DescriptorSetsMax;
|
uint32 _descriptorSetsMax;
|
||||||
uint32 AllocatedDescriptorSetsCount;
|
uint32 _allocatedDescriptorSetsCount;
|
||||||
uint32 AllocatedDescriptorSetsCountMax;
|
uint32 _allocatedDescriptorSetsCountMax;
|
||||||
|
|
||||||
const DescriptorSetLayoutVulkan& Layout;
|
const DescriptorSetLayoutVulkan& _layout;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DescriptorPoolVulkan(GPUDeviceVulkan* device, const DescriptorSetLayoutVulkan& layout);
|
DescriptorPoolVulkan(GPUDeviceVulkan* device, const DescriptorSetLayoutVulkan& layout);
|
||||||
|
|
||||||
~DescriptorPoolVulkan();
|
~DescriptorPoolVulkan();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -251,25 +250,24 @@ public:
|
|||||||
|
|
||||||
inline bool IsEmpty() const
|
inline bool IsEmpty() const
|
||||||
{
|
{
|
||||||
return AllocatedDescriptorSetsCount == 0;
|
return _allocatedDescriptorSetsCount == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool CanAllocate(const DescriptorSetLayoutVulkan& layout) const
|
inline bool CanAllocate(const DescriptorSetLayoutVulkan& layout) const
|
||||||
{
|
{
|
||||||
return DescriptorSetsMax > AllocatedDescriptorSetsCount + layout.GetLayouts().Count();
|
return _descriptorSetsMax > _allocatedDescriptorSetsCount + layout.GetLayouts().Count();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint32 GetAllocatedDescriptorSetsCount() const
|
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 TrackRemoveUsage(const DescriptorSetLayoutVulkan& layout);
|
||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
bool AllocateDescriptorSets(const VkDescriptorSetAllocateInfo& descriptorSetAllocateInfo, VkDescriptorSet* result);
|
bool AllocateDescriptorSets(const VkDescriptorSetAllocateInfo& descriptorSetAllocateInfo, VkDescriptorSet* result);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -416,14 +414,14 @@ struct DescriptorSetWriteContainerVulkan
|
|||||||
Array<VkDescriptorImageInfo> DescriptorImageInfo;
|
Array<VkDescriptorImageInfo> DescriptorImageInfo;
|
||||||
Array<VkDescriptorBufferInfo> DescriptorBufferInfo;
|
Array<VkDescriptorBufferInfo> DescriptorBufferInfo;
|
||||||
Array<VkWriteDescriptorSet> DescriptorWrites;
|
Array<VkWriteDescriptorSet> DescriptorWrites;
|
||||||
Array<uint8> BindingToDynamicOffsetMap;
|
Array<byte> BindingToDynamicOffset;
|
||||||
|
|
||||||
void Release()
|
void Release()
|
||||||
{
|
{
|
||||||
DescriptorImageInfo.Resize(0);
|
DescriptorImageInfo.Resize(0);
|
||||||
DescriptorBufferInfo.Resize(0);
|
DescriptorBufferInfo.Resize(0);
|
||||||
DescriptorWrites.Resize(0);
|
DescriptorWrites.Resize(0);
|
||||||
BindingToDynamicOffsetMap.Resize(0);
|
BindingToDynamicOffset.Resize(0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -431,24 +429,14 @@ class DescriptorSetWriterVulkan
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
VkWriteDescriptorSet* WriteDescriptors;
|
VkWriteDescriptorSet* WriteDescriptors = nullptr;
|
||||||
uint8* BindingToDynamicOffsetMap;
|
byte* BindingToDynamicOffset = nullptr;
|
||||||
uint32* DynamicOffsets;
|
uint32* DynamicOffsets = nullptr;
|
||||||
uint32 WritesCount;
|
uint32 WritesCount = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DescriptorSetWriterVulkan()
|
uint32 SetupDescriptorWrites(const SpirvShaderDescriptorInfo& info, VkWriteDescriptorSet* writeDescriptors, VkDescriptorImageInfo* imageInfo, VkDescriptorBufferInfo* bufferInfo, byte* bindingToDynamicOffset);
|
||||||
: WriteDescriptors(nullptr)
|
|
||||||
, BindingToDynamicOffsetMap(nullptr)
|
|
||||||
, DynamicOffsets(nullptr)
|
|
||||||
, WritesCount(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
uint32 SetupDescriptorWrites(const SpirvShaderDescriptorInfo& info, VkWriteDescriptorSet* writeDescriptors, VkDescriptorImageInfo* imageInfo, VkDescriptorBufferInfo* bufferInfo, uint8* bindingToDynamicOffsetMap);
|
|
||||||
|
|
||||||
bool WriteUniformBuffer(uint32 descriptorIndex, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range) const
|
bool WriteUniformBuffer(uint32 descriptorIndex, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range) const
|
||||||
{
|
{
|
||||||
@@ -471,7 +459,7 @@ public:
|
|||||||
bool edited = DescriptorSet::CopyAndReturnNotEqual(bufferInfo->buffer, buffer);
|
bool edited = DescriptorSet::CopyAndReturnNotEqual(bufferInfo->buffer, buffer);
|
||||||
edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->offset, offset);
|
edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->offset, offset);
|
||||||
edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->range, range);
|
edited |= DescriptorSet::CopyAndReturnNotEqual(bufferInfo->range, range);
|
||||||
const uint8 dynamicOffsetIndex = BindingToDynamicOffsetMap[descriptorIndex];
|
const byte dynamicOffsetIndex = BindingToDynamicOffset[descriptorIndex];
|
||||||
DynamicOffsets[dynamicOffsetIndex] = dynamicOffset;
|
DynamicOffsets[dynamicOffsetIndex] = dynamicOffset;
|
||||||
return edited;
|
return edited;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,7 +146,6 @@ void GPUContextVulkan::AddImageBarrier(GPUTextureViewVulkan* handle, VkImageLayo
|
|||||||
{
|
{
|
||||||
// Transition entire resource at once
|
// Transition entire resource at once
|
||||||
const VkImageLayout srcLayout = state.GetSubresourceState(0);
|
const VkImageLayout srcLayout = state.GetSubresourceState(0);
|
||||||
|
|
||||||
VkImageSubresourceRange range;
|
VkImageSubresourceRange range;
|
||||||
range.aspectMask = handle->Info.subresourceRange.aspectMask;
|
range.aspectMask = handle->Info.subresourceRange.aspectMask;
|
||||||
range.baseMipLevel = 0;
|
range.baseMipLevel = 0;
|
||||||
@@ -157,7 +156,7 @@ void GPUContextVulkan::AddImageBarrier(GPUTextureViewVulkan* handle, VkImageLayo
|
|||||||
}
|
}
|
||||||
else
|
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++)
|
for (int32 i = 0; i < state.GetSubresourcesCount(); i++)
|
||||||
{
|
{
|
||||||
const VkImageLayout srcLayout = state.GetSubresourceState(i);
|
const VkImageLayout srcLayout = state.GetSubresourceState(i);
|
||||||
@@ -174,8 +173,6 @@ void GPUContextVulkan::AddImageBarrier(GPUTextureViewVulkan* handle, VkImageLayo
|
|||||||
state.SetSubresourceState(i, dstLayout);
|
state.SetSubresourceState(i, dstLayout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The entire resource should now be in the after state on this command list
|
|
||||||
ASSERT(state.CheckResourceState(dstLayout));
|
ASSERT(state.CheckResourceState(dstLayout));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -538,7 +535,7 @@ void GPUContextVulkan::UpdateDescriptorSets(GPUPipelineStateVulkan* pipelineStat
|
|||||||
remainingHasDescriptorsPerStageMask >>= 1;
|
remainingHasDescriptorsPerStageMask >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate sets based on what changed
|
// Allocate sets if need to
|
||||||
//if (needsWrite) // TODO: write on change only?
|
//if (needsWrite) // TODO: write on change only?
|
||||||
{
|
{
|
||||||
if (!pipelineState->AllocateDescriptorSets())
|
if (!pipelineState->AllocateDescriptorSets())
|
||||||
@@ -578,7 +575,7 @@ void GPUContextVulkan::UpdateDescriptorSets(ComputePipelineStateVulkan* pipeline
|
|||||||
// Update descriptors
|
// Update descriptors
|
||||||
UpdateDescriptorSets(*pipelineState->DescriptorInfo, pipelineState->DSWriter, needsWrite);
|
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 (needsWrite) // TODO: write on change only?f
|
||||||
{
|
{
|
||||||
if (!pipelineState->AllocateDescriptorSets())
|
if (!pipelineState->AllocateDescriptorSets())
|
||||||
|
|||||||
@@ -149,12 +149,12 @@ static int FindLayerIndex(const Array<LayerExtension>& list, const char* layerNa
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return INVALID_INDEX;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ContainsLayer(const Array<LayerExtension>& list, const char* layerName)
|
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)
|
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)
|
void GPUDeviceVulkan::GetDeviceExtensionsAndLayers(VkPhysicalDevice gpu, Array<const char*>& outDeviceExtensions, Array<const char*>& outDeviceLayers)
|
||||||
{
|
{
|
||||||
Array<LayerExtension> deviceLayerExtensions;
|
Array<LayerExtension> deviceLayerExtensions;
|
||||||
// 0 is reserved for regular device
|
|
||||||
deviceLayerExtensions.AddDefault(1);
|
deviceLayerExtensions.AddDefault(1);
|
||||||
{
|
{
|
||||||
uint32 count = 0;
|
uint32 count = 0;
|
||||||
@@ -409,10 +408,10 @@ void GPUDeviceVulkan::GetDeviceExtensionsAndLayers(VkPhysicalDevice gpu, Array<c
|
|||||||
properties.AddZeroed(count);
|
properties.AddZeroed(count);
|
||||||
VALIDATE_VULKAN_RESULT(vkEnumerateDeviceLayerProperties(gpu, &count, properties.Get()));
|
VALIDATE_VULKAN_RESULT(vkEnumerateDeviceLayerProperties(gpu, &count, properties.Get()));
|
||||||
ASSERT(count == properties.Count());
|
ASSERT(count == properties.Count());
|
||||||
for (const VkLayerProperties& Property : properties)
|
for (const VkLayerProperties& property : properties)
|
||||||
{
|
{
|
||||||
deviceLayerExtensions.AddDefault(1);
|
deviceLayerExtensions.AddDefault(1);
|
||||||
deviceLayerExtensions.Last().Layer = Property;
|
deviceLayerExtensions.Last().Layer = property;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -530,7 +529,6 @@ void GPUDeviceVulkan::GetDeviceExtensionsAndLayers(VkPhysicalDevice gpu, Array<c
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Now go through the actual requested lists
|
|
||||||
Array<const char*> platformExtensions;
|
Array<const char*> platformExtensions;
|
||||||
VulkanPlatform::GetDeviceExtensions(platformExtensions);
|
VulkanPlatform::GetDeviceExtensions(platformExtensions);
|
||||||
for (const char* extension : platformExtensions)
|
for (const char* extension : platformExtensions)
|
||||||
|
|||||||
@@ -345,10 +345,6 @@ DeferredDeletionQueueVulkan::~DeferredDeletionQueueVulkan()
|
|||||||
void DeferredDeletionQueueVulkan::ReleaseResources(bool deleteImmediately)
|
void DeferredDeletionQueueVulkan::ReleaseResources(bool deleteImmediately)
|
||||||
{
|
{
|
||||||
ScopeLock lock(&_locker);
|
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;
|
const uint64 checkFrame = Engine::FrameCount - VULKAN_RESOURCE_DELETE_SAFE_FRAMES_COUNT;
|
||||||
for (int32 i = 0; i < _entries.Count(); i++)
|
for (int32 i = 0; i < _entries.Count(); i++)
|
||||||
{
|
{
|
||||||
@@ -361,24 +357,26 @@ void DeferredDeletionQueueVulkan::ReleaseResources(bool deleteImmediately)
|
|||||||
{
|
{
|
||||||
switch (e->StructureType)
|
switch (e->StructureType)
|
||||||
{
|
{
|
||||||
#define VK_SWITCH(type) case Type::type: vkDestroy##type(device, (Vk##type)e->Handle, nullptr); break
|
#define SWITCH_CASE(type) case Type::type: vkDestroy##type(_device->Device, (Vk##type)e->Handle, nullptr); break
|
||||||
VK_SWITCH(RenderPass);
|
SWITCH_CASE(RenderPass);
|
||||||
VK_SWITCH(Buffer);
|
SWITCH_CASE(Buffer);
|
||||||
VK_SWITCH(BufferView);
|
SWITCH_CASE(BufferView);
|
||||||
VK_SWITCH(Image);
|
SWITCH_CASE(Image);
|
||||||
VK_SWITCH(ImageView);
|
SWITCH_CASE(ImageView);
|
||||||
VK_SWITCH(Pipeline);
|
SWITCH_CASE(Pipeline);
|
||||||
VK_SWITCH(PipelineLayout);
|
SWITCH_CASE(PipelineLayout);
|
||||||
VK_SWITCH(Framebuffer);
|
SWITCH_CASE(Framebuffer);
|
||||||
VK_SWITCH(DescriptorSetLayout);
|
SWITCH_CASE(DescriptorSetLayout);
|
||||||
VK_SWITCH(Sampler);
|
SWITCH_CASE(Sampler);
|
||||||
VK_SWITCH(Semaphore);
|
SWITCH_CASE(Semaphore);
|
||||||
VK_SWITCH(ShaderModule);
|
SWITCH_CASE(ShaderModule);
|
||||||
VK_SWITCH(Event);
|
SWITCH_CASE(Event);
|
||||||
VK_SWITCH(QueryPool);
|
SWITCH_CASE(QueryPool);
|
||||||
#undef VK_SWITCH
|
#undef SWITCH_CASE
|
||||||
default:
|
default:
|
||||||
|
#if !BUILD_RELEASE
|
||||||
CRASH;
|
CRASH;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1068,23 +1066,10 @@ GPUDeviceVulkan::GPUDeviceVulkan(ShaderProfile shaderProfile, GPUAdapterVulkan*
|
|||||||
, _renderPasses(512)
|
, _renderPasses(512)
|
||||||
, _framebuffers(512)
|
, _framebuffers(512)
|
||||||
, _layouts(4096)
|
, _layouts(4096)
|
||||||
, MainContext(nullptr)
|
|
||||||
, Adapter(adapter)
|
, Adapter(adapter)
|
||||||
, Device(VK_NULL_HANDLE)
|
|
||||||
, DeferredDeletionQueue(this)
|
, DeferredDeletionQueue(this)
|
||||||
, StagingManager(this)
|
, StagingManager(this)
|
||||||
, HelperResources(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)
|
if (result == VK_ERROR_EXTENSION_NOT_PRESENT)
|
||||||
{
|
{
|
||||||
// Check for missing extensions
|
// Extensions error
|
||||||
uint32_t propertyCount;
|
uint32_t propertyCount;
|
||||||
vkEnumerateInstanceExtensionProperties(nullptr, &propertyCount, nullptr);
|
vkEnumerateInstanceExtensionProperties(nullptr, &propertyCount, nullptr);
|
||||||
Array<VkExtensionProperties> properties;
|
Array<VkExtensionProperties> properties;
|
||||||
@@ -1159,28 +1144,27 @@ GPUDevice* GPUDeviceVulkan::Create()
|
|||||||
vkEnumerateInstanceExtensionProperties(nullptr, &propertyCount, properties.Get());
|
vkEnumerateInstanceExtensionProperties(nullptr, &propertyCount, properties.Get());
|
||||||
for (const char* extension : InstanceExtensions)
|
for (const char* extension : InstanceExtensions)
|
||||||
{
|
{
|
||||||
bool extensionFound = false;
|
bool found = false;
|
||||||
for (uint32_t propertyIndex = 0; propertyIndex < propertyCount; propertyIndex++)
|
for (uint32_t propertyIndex = 0; propertyIndex < propertyCount; propertyIndex++)
|
||||||
{
|
{
|
||||||
if (!StringUtils::Compare(properties[propertyIndex].extensionName, extension))
|
if (!StringUtils::Compare(properties[propertyIndex].extensionName, extension))
|
||||||
{
|
{
|
||||||
extensionFound = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!extensionFound)
|
if (!found)
|
||||||
{
|
{
|
||||||
LOG(Warning, "Missing required Vulkan extension: {0}", String(extension));
|
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."));
|
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);
|
Platform::Error(*error);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
{
|
{
|
||||||
|
// Driver error
|
||||||
LOG(Warning, "Vulkan create instance failed with error code: {0}", RenderToolsVulkan::GetVkErrorString(result));
|
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?"));
|
Platform::Fatal(TEXT("Vulkan failed to create instance\n\nDo you have a compatible Vulkan driver installed?"));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -1560,7 +1544,7 @@ bool GPUDeviceVulkan::Init()
|
|||||||
_state = DeviceState::Created;
|
_state = DeviceState::Created;
|
||||||
const auto gpu = Adapter->Gpu;
|
const auto gpu = Adapter->Gpu;
|
||||||
|
|
||||||
// Query queues properties
|
// Get queues properties
|
||||||
uint32 queueCount = 0;
|
uint32 queueCount = 0;
|
||||||
vkGetPhysicalDeviceQueueFamilyProperties(gpu, &queueCount, nullptr);
|
vkGetPhysicalDeviceQueueFamilyProperties(gpu, &queueCount, nullptr);
|
||||||
ASSERT(queueCount >= 1);
|
ASSERT(queueCount >= 1);
|
||||||
@@ -1570,23 +1554,21 @@ bool GPUDeviceVulkan::Init()
|
|||||||
// Query device features
|
// Query device features
|
||||||
vkGetPhysicalDeviceFeatures(Adapter->Gpu, &PhysicalDeviceFeatures);
|
vkGetPhysicalDeviceFeatures(Adapter->Gpu, &PhysicalDeviceFeatures);
|
||||||
|
|
||||||
// Setup extension and layer info
|
// Get extensions and layers
|
||||||
VkDeviceCreateInfo deviceInfo;
|
|
||||||
RenderToolsVulkan::ZeroStruct(deviceInfo, VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);
|
|
||||||
|
|
||||||
Array<const char*> deviceExtensions;
|
Array<const char*> deviceExtensions;
|
||||||
Array<const char*> validationLayers;
|
Array<const char*> validationLayers;
|
||||||
GetDeviceExtensionsAndLayers(gpu, deviceExtensions, validationLayers);
|
GetDeviceExtensionsAndLayers(gpu, deviceExtensions, validationLayers);
|
||||||
|
|
||||||
ParseOptionalDeviceExtensions(deviceExtensions);
|
ParseOptionalDeviceExtensions(deviceExtensions);
|
||||||
|
|
||||||
|
// Setup device info
|
||||||
|
VkDeviceCreateInfo deviceInfo;
|
||||||
|
RenderToolsVulkan::ZeroStruct(deviceInfo, VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);
|
||||||
deviceInfo.enabledExtensionCount = deviceExtensions.Count();
|
deviceInfo.enabledExtensionCount = deviceExtensions.Count();
|
||||||
deviceInfo.ppEnabledExtensionNames = deviceExtensions.Get();
|
deviceInfo.ppEnabledExtensionNames = deviceExtensions.Get();
|
||||||
|
|
||||||
deviceInfo.enabledLayerCount = validationLayers.Count();
|
deviceInfo.enabledLayerCount = validationLayers.Count();
|
||||||
deviceInfo.ppEnabledLayerNames = deviceInfo.enabledLayerCount > 0 ? validationLayers.Get() : nullptr;
|
deviceInfo.ppEnabledLayerNames = deviceInfo.enabledLayerCount > 0 ? validationLayers.Get() : nullptr;
|
||||||
|
|
||||||
// Setup Queue info
|
// Setup queues info
|
||||||
Array<VkDeviceQueueCreateInfo> queueFamilyInfos;
|
Array<VkDeviceQueueCreateInfo> queueFamilyInfos;
|
||||||
int32 graphicsQueueFamilyIndex = -1;
|
int32 graphicsQueueFamilyIndex = -1;
|
||||||
int32 computeQueueFamilyIndex = -1;
|
int32 computeQueueFamilyIndex = -1;
|
||||||
@@ -1655,7 +1637,6 @@ bool GPUDeviceVulkan::Init()
|
|||||||
numPriorities += curProps.queueCount;
|
numPriorities += curProps.queueCount;
|
||||||
LOG(Info, "- queue family {0}: {1} queues{2}", familyIndex, curProps.queueCount, queueTypeInfo);
|
LOG(Info, "- queue family {0}: {1} queues{2}", familyIndex, curProps.queueCount, queueTypeInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
Array<float> queuePriorities;
|
Array<float> queuePriorities;
|
||||||
queuePriorities.AddDefault(numPriorities);
|
queuePriorities.AddDefault(numPriorities);
|
||||||
float* currentPriority = queuePriorities.Get();
|
float* currentPriority = queuePriorities.Get();
|
||||||
@@ -1663,14 +1644,12 @@ bool GPUDeviceVulkan::Init()
|
|||||||
{
|
{
|
||||||
VkDeviceQueueCreateInfo& queue = queueFamilyInfos[index];
|
VkDeviceQueueCreateInfo& queue = queueFamilyInfos[index];
|
||||||
queue.pQueuePriorities = currentPriority;
|
queue.pQueuePriorities = currentPriority;
|
||||||
|
|
||||||
const VkQueueFamilyProperties& properties = QueueFamilyProps[queue.queueFamilyIndex];
|
const VkQueueFamilyProperties& properties = QueueFamilyProps[queue.queueFamilyIndex];
|
||||||
for (int32 queueIndex = 0; queueIndex < (int32)properties.queueCount; queueIndex++)
|
for (int32 queueIndex = 0; queueIndex < (int32)properties.queueCount; queueIndex++)
|
||||||
{
|
{
|
||||||
*currentPriority++ = 1.0f;
|
*currentPriority++ = 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deviceInfo.queueCreateInfoCount = queueFamilyInfos.Count();
|
deviceInfo.queueCreateInfoCount = queueFamilyInfos.Count();
|
||||||
deviceInfo.pQueueCreateInfos = queueFamilyInfos.Get();
|
deviceInfo.pQueueCreateInfos = queueFamilyInfos.Get();
|
||||||
|
|
||||||
@@ -2129,7 +2108,6 @@ bool FenceManagerVulkan::CheckFenceState(FenceVulkan* fence)
|
|||||||
|
|
||||||
void FenceManagerVulkan::DestroyFence(FenceVulkan* fence)
|
void FenceManagerVulkan::DestroyFence(FenceVulkan* fence)
|
||||||
{
|
{
|
||||||
// Does not need to go in the deferred deletion queue
|
|
||||||
vkDestroyFence(_device->Device, fence->GetHandle(), nullptr);
|
vkDestroyFence(_device->Device, fence->GetHandle(), nullptr);
|
||||||
fence->_handle = VK_NULL_HANDLE;
|
fence->_handle = VK_NULL_HANDLE;
|
||||||
Delete(fence);
|
Delete(fence);
|
||||||
|
|||||||
@@ -554,17 +554,17 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The main Vulkan commands context.
|
/// The main Vulkan commands context.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
GPUContextVulkan* MainContext;
|
GPUContextVulkan* MainContext = nullptr;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Vulkan adapter.
|
/// The Vulkan adapter.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
GPUAdapterVulkan* Adapter;
|
GPUAdapterVulkan* Adapter = nullptr;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Vulkan device.
|
/// The Vulkan device.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
VkDevice Device;
|
VkDevice Device = VK_NULL_HANDLE;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Vulkan device queues family properties.
|
/// The Vulkan device queues family properties.
|
||||||
@@ -594,51 +594,51 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The graphics queue.
|
/// The graphics queue.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
QueueVulkan* GraphicsQueue;
|
QueueVulkan* GraphicsQueue = nullptr;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The compute queue.
|
/// The compute queue.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
QueueVulkan* ComputeQueue;
|
QueueVulkan* ComputeQueue = nullptr;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The transfer queue.
|
/// The transfer queue.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
QueueVulkan* TransferQueue;
|
QueueVulkan* TransferQueue = nullptr;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The present queue.
|
/// The present queue.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
QueueVulkan* PresentQueue;
|
QueueVulkan* PresentQueue = nullptr;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Vulkan memory allocator.
|
/// The Vulkan memory allocator.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
VmaAllocator Allocator;
|
VmaAllocator Allocator = VK_NULL_HANDLE;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The pipeline cache.
|
/// The pipeline cache.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
VkPipelineCache PipelineCache;
|
VkPipelineCache PipelineCache = VK_NULL_HANDLE;
|
||||||
|
|
||||||
#if VK_EXT_validation_cache
|
#if VK_EXT_validation_cache
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The optional validation cache.
|
/// The optional validation cache.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
VkValidationCacheEXT ValidationCache;
|
VkValidationCacheEXT ValidationCache = VK_NULL_HANDLE;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The uniform buffers uploader.
|
/// The uniform buffers uploader.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
UniformBufferUploaderVulkan* UniformBufferUploader;
|
UniformBufferUploaderVulkan* UniformBufferUploader = nullptr;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The descriptor pools manager.
|
/// The descriptor pools manager.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
DescriptorPoolsManagerVulkan* DescriptorPoolsManager;
|
DescriptorPoolsManagerVulkan* DescriptorPoolsManager = nullptr;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The physical device limits.
|
/// The physical device limits.
|
||||||
|
|||||||
@@ -45,13 +45,10 @@ ComputePipelineStateVulkan* GPUShaderProgramCSVulkan::GetOrCreateState()
|
|||||||
|
|
||||||
// Setup the state
|
// Setup the state
|
||||||
_pipelineState = New<ComputePipelineStateVulkan>(_device, pipeline, layout);
|
_pipelineState = New<ComputePipelineStateVulkan>(_device, pipeline, layout);
|
||||||
|
|
||||||
_pipelineState->DescriptorInfo = &DescriptorInfo;
|
_pipelineState->DescriptorInfo = &DescriptorInfo;
|
||||||
_pipelineState->DescriptorSetsLayout = &layout->GetDescriptorSetLayout();
|
_pipelineState->DescriptorSetsLayout = &layout->GetDescriptorSetLayout();
|
||||||
_pipelineState->DescriptorSetHandles.AddZeroed(_pipelineState->DescriptorSetsLayout->GetHandles().Count());
|
_pipelineState->DescriptorSetHandles.AddZeroed(_pipelineState->DescriptorSetsLayout->GetHandles().Count());
|
||||||
|
uint32 dynamicOffsetsCount = 0;
|
||||||
uint32 totalNumDynamicOffsets = 0;
|
|
||||||
|
|
||||||
if (DescriptorInfo.DescriptorTypesCount != 0)
|
if (DescriptorInfo.DescriptorTypesCount != 0)
|
||||||
{
|
{
|
||||||
_pipelineState->DSWriteContainer.DescriptorWrites.AddZeroed(DescriptorInfo.DescriptorTypesCount);
|
_pipelineState->DSWriteContainer.DescriptorWrites.AddZeroed(DescriptorInfo.DescriptorTypesCount);
|
||||||
@@ -59,18 +56,18 @@ ComputePipelineStateVulkan* GPUShaderProgramCSVulkan::GetOrCreateState()
|
|||||||
_pipelineState->DSWriteContainer.DescriptorBufferInfo.AddZeroed(DescriptorInfo.BufferInfosCount);
|
_pipelineState->DSWriteContainer.DescriptorBufferInfo.AddZeroed(DescriptorInfo.BufferInfosCount);
|
||||||
|
|
||||||
ASSERT(DescriptorInfo.DescriptorTypesCount < 255);
|
ASSERT(DescriptorInfo.DescriptorTypesCount < 255);
|
||||||
_pipelineState->DSWriteContainer.BindingToDynamicOffsetMap.AddDefault(DescriptorInfo.DescriptorTypesCount);
|
_pipelineState->DSWriteContainer.BindingToDynamicOffset.AddDefault(DescriptorInfo.DescriptorTypesCount);
|
||||||
_pipelineState->DSWriteContainer.BindingToDynamicOffsetMap.SetAll(255);
|
_pipelineState->DSWriteContainer.BindingToDynamicOffset.SetAll(255);
|
||||||
|
|
||||||
VkWriteDescriptorSet* currentDescriptorWrite = _pipelineState->DSWriteContainer.DescriptorWrites.Get();
|
VkWriteDescriptorSet* currentDescriptorWrite = _pipelineState->DSWriteContainer.DescriptorWrites.Get();
|
||||||
VkDescriptorImageInfo* currentImageInfo = _pipelineState->DSWriteContainer.DescriptorImageInfo.Get();
|
VkDescriptorImageInfo* currentImageInfo = _pipelineState->DSWriteContainer.DescriptorImageInfo.Get();
|
||||||
VkDescriptorBufferInfo* currentBufferInfo = _pipelineState->DSWriteContainer.DescriptorBufferInfo.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();
|
_pipelineState->DSWriter.DynamicOffsets = _pipelineState->DynamicOffsets.Get();
|
||||||
|
|
||||||
return _pipelineState;
|
return _pipelineState;
|
||||||
@@ -346,26 +343,26 @@ bool GPUPipelineStateVulkan::Init(const Description& desc)
|
|||||||
DSWriteContainer.DescriptorBufferInfo.AddZeroed(descriptor->BufferInfosCount);
|
DSWriteContainer.DescriptorBufferInfo.AddZeroed(descriptor->BufferInfosCount);
|
||||||
|
|
||||||
ASSERT(descriptor->DescriptorTypesCount < 255);
|
ASSERT(descriptor->DescriptorTypesCount < 255);
|
||||||
DSWriteContainer.BindingToDynamicOffsetMap.AddDefault(descriptor->DescriptorTypesCount);
|
DSWriteContainer.BindingToDynamicOffset.AddDefault(descriptor->DescriptorTypesCount);
|
||||||
DSWriteContainer.BindingToDynamicOffsetMap.SetAll(255);
|
DSWriteContainer.BindingToDynamicOffset.SetAll(255);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkWriteDescriptorSet* currentDescriptorWrite = DSWriteContainer.DescriptorWrites.Get();
|
VkWriteDescriptorSet* currentDescriptorWrite = DSWriteContainer.DescriptorWrites.Get();
|
||||||
VkDescriptorImageInfo* currentImageInfo = DSWriteContainer.DescriptorImageInfo.Get();
|
VkDescriptorImageInfo* currentImageInfo = DSWriteContainer.DescriptorImageInfo.Get();
|
||||||
VkDescriptorBufferInfo* currentBufferInfo = DSWriteContainer.DescriptorBufferInfo.Get();
|
VkDescriptorBufferInfo* currentBufferInfo = DSWriteContainer.DescriptorBufferInfo.Get();
|
||||||
uint8* currentBindingToDynamicOffsetMap = DSWriteContainer.BindingToDynamicOffsetMap.Get();
|
byte* currentBindingToDynamicOffsetMap = DSWriteContainer.BindingToDynamicOffset.Get();
|
||||||
uint32 dynamicOffsetsStart[DescriptorSet::GraphicsStagesCount];
|
uint32 dynamicOffsetsStart[DescriptorSet::GraphicsStagesCount];
|
||||||
uint32 totalNumDynamicOffsets = 0;
|
uint32 dynamicOffsetsCount = 0;
|
||||||
for (int32 stage = 0; stage < DescriptorSet::GraphicsStagesCount; stage++)
|
for (int32 stage = 0; stage < DescriptorSet::GraphicsStagesCount; stage++)
|
||||||
{
|
{
|
||||||
dynamicOffsetsStart[stage] = totalNumDynamicOffsets;
|
dynamicOffsetsStart[stage] = dynamicOffsetsCount;
|
||||||
|
|
||||||
const auto descriptor = DescriptorInfoPerStage[stage];
|
const auto descriptor = DescriptorInfoPerStage[stage];
|
||||||
if (descriptor == nullptr || descriptor->DescriptorTypesCount == 0)
|
if (descriptor == nullptr || descriptor->DescriptorTypesCount == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const uint32 numDynamicOffsets = DSWriter[stage].SetupDescriptorWrites(*descriptor, currentDescriptorWrite, currentImageInfo, currentBufferInfo, currentBindingToDynamicOffsetMap);
|
const uint32 numDynamicOffsets = DSWriter[stage].SetupDescriptorWrites(*descriptor, currentDescriptorWrite, currentImageInfo, currentBufferInfo, currentBindingToDynamicOffsetMap);
|
||||||
totalNumDynamicOffsets += numDynamicOffsets;
|
dynamicOffsetsCount += numDynamicOffsets;
|
||||||
|
|
||||||
currentDescriptorWrite += descriptor->DescriptorTypesCount;
|
currentDescriptorWrite += descriptor->DescriptorTypesCount;
|
||||||
currentImageInfo += descriptor->ImageInfosCount;
|
currentImageInfo += descriptor->ImageInfosCount;
|
||||||
@@ -373,7 +370,7 @@ bool GPUPipelineStateVulkan::Init(const Description& desc)
|
|||||||
currentBindingToDynamicOffsetMap += descriptor->DescriptorTypesCount;
|
currentBindingToDynamicOffsetMap += descriptor->DescriptorTypesCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
DynamicOffsets.AddZeroed(totalNumDynamicOffsets);
|
DynamicOffsets.AddZeroed(dynamicOffsetsCount);
|
||||||
for (int32 stage = 0; stage < DescriptorSet::GraphicsStagesCount; stage++)
|
for (int32 stage = 0; stage < DescriptorSet::GraphicsStagesCount; stage++)
|
||||||
{
|
{
|
||||||
DSWriter[stage].DynamicOffsets = dynamicOffsetsStart[stage] + DynamicOffsets.Get();
|
DSWriter[stage].DynamicOffsets = dynamicOffsetsStart[stage] + DynamicOffsets.Get();
|
||||||
|
|||||||
@@ -187,10 +187,10 @@ bool GPUSwapChainVulkan::CreateSwapChain(int32 width, int32 height)
|
|||||||
|
|
||||||
const auto& gpu = _device->Adapter->Gpu;
|
const auto& gpu = _device->Adapter->Gpu;
|
||||||
|
|
||||||
// Find pixel format for presentable images
|
// Pick a format for backbuffer
|
||||||
PixelFormat resultFormat = GPU_BACK_BUFFER_PIXEL_FORMAT;
|
PixelFormat resultFormat = GPU_BACK_BUFFER_PIXEL_FORMAT;
|
||||||
VkSurfaceFormatKHR curFormat;
|
VkSurfaceFormatKHR result;
|
||||||
Platform::MemoryClear(&curFormat, sizeof(curFormat));
|
Platform::MemoryClear(&result, sizeof(result));
|
||||||
{
|
{
|
||||||
uint32 surfaceFormatsCount;
|
uint32 surfaceFormatsCount;
|
||||||
VALIDATE_VULKAN_RESULT(vkGetPhysicalDeviceSurfaceFormatsKHR(gpu, _surface, &surfaceFormatsCount, nullptr));
|
VALIDATE_VULKAN_RESULT(vkGetPhysicalDeviceSurfaceFormatsKHR(gpu, _surface, &surfaceFormatsCount, nullptr));
|
||||||
@@ -210,7 +210,7 @@ bool GPUSwapChainVulkan::CreateSwapChain(int32 width, int32 height)
|
|||||||
{
|
{
|
||||||
if (surfaceFormats[i].format == requested)
|
if (surfaceFormats[i].format == requested)
|
||||||
{
|
{
|
||||||
curFormat = surfaceFormats[i];
|
result = surfaceFormats[i];
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -240,8 +240,8 @@ bool GPUSwapChainVulkan::CreateSwapChain(int32 width, int32 height)
|
|||||||
if (surfaceFormats[i].format == RenderToolsVulkan::ToVulkanFormat(static_cast<PixelFormat>(pixelFormat)))
|
if (surfaceFormats[i].format == RenderToolsVulkan::ToVulkanFormat(static_cast<PixelFormat>(pixelFormat)))
|
||||||
{
|
{
|
||||||
resultFormat = static_cast<PixelFormat>(pixelFormat);
|
resultFormat = static_cast<PixelFormat>(pixelFormat);
|
||||||
curFormat = surfaceFormats[i];
|
result = surfaceFormats[i];
|
||||||
LOG(Info, "No swapchain format requested, picking up Vulkan format {0}", (uint32)curFormat.format);
|
LOG(Info, "No swapchain format requested, picking up Vulkan format {0}", (uint32)result.format);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -264,7 +264,7 @@ bool GPUSwapChainVulkan::CreateSwapChain(int32 width, int32 height)
|
|||||||
if (surfaceFormats[i].format == format)
|
if (surfaceFormats[i].format == format)
|
||||||
{
|
{
|
||||||
supported = true;
|
supported = true;
|
||||||
curFormat = surfaceFormats[i];
|
result = surfaceFormats[i];
|
||||||
break;
|
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);
|
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;
|
_format = resultFormat;
|
||||||
|
|
||||||
// Prepare present queue
|
// Prepare present queue
|
||||||
_device->SetupPresentQueue(_surface);
|
_device->SetupPresentQueue(_surface);
|
||||||
|
|
||||||
// Fetch present mode
|
// Calculate the swap chain present mode
|
||||||
VkPresentModeKHR presentMode = VK_PRESENT_MODE_FIFO_KHR;
|
VkPresentModeKHR presentMode = VK_PRESENT_MODE_FIFO_KHR;
|
||||||
{
|
{
|
||||||
uint32 presentModesCount = 0;
|
uint32 presentModesCount = 0;
|
||||||
@@ -358,8 +358,8 @@ bool GPUSwapChainVulkan::CreateSwapChain(int32 width, int32 height)
|
|||||||
RenderToolsVulkan::ZeroStruct(swapChainInfo, VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR);
|
RenderToolsVulkan::ZeroStruct(swapChainInfo, VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR);
|
||||||
swapChainInfo.surface = _surface;
|
swapChainInfo.surface = _surface;
|
||||||
swapChainInfo.minImageCount = VULKAN_BACK_BUFFERS_COUNT;
|
swapChainInfo.minImageCount = VULKAN_BACK_BUFFERS_COUNT;
|
||||||
swapChainInfo.imageFormat = curFormat.format;
|
swapChainInfo.imageFormat = result.format;
|
||||||
swapChainInfo.imageColorSpace = curFormat.colorSpace;
|
swapChainInfo.imageColorSpace = result.colorSpace;
|
||||||
swapChainInfo.imageExtent.width = width;
|
swapChainInfo.imageExtent.width = width;
|
||||||
swapChainInfo.imageExtent.height = height;
|
swapChainInfo.imageExtent.height = height;
|
||||||
swapChainInfo.imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
swapChainInfo.imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ protected:
|
|||||||
{
|
{
|
||||||
if (this->hasBlock)
|
if (this->hasBlock)
|
||||||
{
|
{
|
||||||
// Copy blocking hit to hits
|
// Blocking hits go to hits
|
||||||
processTouches(&this->block, 1);
|
processTouches(&this->block, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -177,8 +177,7 @@ bool PhysicsService::Init()
|
|||||||
// only in non-production builds.
|
// only in non-production builds.
|
||||||
|
|
||||||
#if PHYSX_MEMORY_STATS
|
#if PHYSX_MEMORY_STATS
|
||||||
// Want names of PhysX allocations
|
_foundation->setReportAllocationNames(true);
|
||||||
GPhysXFoundation->setReportAllocationNames(true);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Config
|
// 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)
|
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;
|
struct timeval time;
|
||||||
gettimeofday(&time, nullptr);
|
gettimeofday(&time, nullptr);
|
||||||
|
|
||||||
@@ -803,11 +803,11 @@ bool AndroidPlatform::Init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set info about the CPU
|
// Set info about the CPU
|
||||||
cpu_set_t availableCpusMask;
|
cpu_set_t cpus;
|
||||||
CPU_ZERO(&availableCpusMask);
|
CPU_ZERO(&cpus);
|
||||||
if (sched_getaffinity(0, sizeof(availableCpusMask), &availableCpusMask) == 0)
|
if (sched_getaffinity(0, sizeof(cpus), &cpus) == 0)
|
||||||
{
|
{
|
||||||
AndroidCpu.ProcessorCoreCount = AndroidCpu.LogicalProcessorCount = CPU_COUNT(&availableCpusMask);
|
AndroidCpu.ProcessorCoreCount = AndroidCpu.LogicalProcessorCount = CPU_COUNT(&cpus);
|
||||||
}
|
}
|
||||||
else
|
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)
|
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;
|
struct timeval time;
|
||||||
gettimeofday(&time, nullptr);
|
gettimeofday(&time, nullptr);
|
||||||
|
|
||||||
@@ -1315,34 +1315,33 @@ bool LinuxPlatform::Init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set info about the CPU
|
// Set info about the CPU
|
||||||
cpu_set_t availableCpusMask;
|
cpu_set_t cpus;
|
||||||
CPU_ZERO(&availableCpusMask);
|
CPU_ZERO(&cpus);
|
||||||
if (sched_getaffinity(0, sizeof(availableCpusMask), &availableCpusMask) == 0)
|
if (sched_getaffinity(0, sizeof(cpus), &cpus) == 0)
|
||||||
{
|
{
|
||||||
int32 numberOfCores = 0;
|
int32 numberOfCores = 0;
|
||||||
struct CpuInfo
|
struct CpuInfo
|
||||||
{
|
{
|
||||||
int Core;
|
int32 Core;
|
||||||
int Package;
|
int32 Package;
|
||||||
} cpuInfos[CPU_SETSIZE];
|
} cpusInfo[CPU_SETSIZE];
|
||||||
|
Platform::MemoryClear(cpusInfo, sizeof(cpusInfo));
|
||||||
Platform::MemoryClear(cpuInfos, sizeof(cpuInfos));
|
int32 maxCoreId = 0;
|
||||||
int maxCoreId = 0;
|
int32 maxPackageId = 0;
|
||||||
int maxPackageId = 0;
|
int32 cpuCountAvailable = 0;
|
||||||
int cpuCountAvailable = 0;
|
|
||||||
|
|
||||||
for (int32 cpuIdx = 0; cpuIdx < CPU_SETSIZE; cpuIdx++)
|
for (int32 cpuIdx = 0; cpuIdx < CPU_SETSIZE; cpuIdx++)
|
||||||
{
|
{
|
||||||
if (CPU_ISSET(cpuIdx, &availableCpusMask))
|
if (CPU_ISSET(cpuIdx, &cpus))
|
||||||
{
|
{
|
||||||
cpuCountAvailable++;
|
cpuCountAvailable++;
|
||||||
|
|
||||||
sprintf(fileNameBuffer, "/sys/devices/system/cpu/cpu%d/topology/core_id", cpuIdx);
|
sprintf(fileNameBuffer, "/sys/devices/system/cpu/cpu%d/topology/core_id", cpuIdx);
|
||||||
if (FILE* coreIdFile = fopen(fileNameBuffer, "r"))
|
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);
|
fclose(coreIdFile);
|
||||||
}
|
}
|
||||||
@@ -1350,22 +1349,21 @@ bool LinuxPlatform::Init()
|
|||||||
sprintf(fileNameBuffer, "/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpuIdx);
|
sprintf(fileNameBuffer, "/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpuIdx);
|
||||||
if (FILE* packageIdFile = fopen(fileNameBuffer, "r"))
|
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", &cpusInfo[cpuIdx].Package) != 1 || cpusInfo[cpuIdx].Package < 0)
|
||||||
if (fscanf(packageIdFile, "%d", &cpuInfos[cpuIdx].Package) != 1 || cpuInfos[cpuIdx].Package < 0)
|
|
||||||
{
|
{
|
||||||
cpuInfos[cpuIdx].Package = cpuInfos[cpuIdx].Core;
|
cpusInfo[cpuIdx].Package = cpusInfo[cpuIdx].Core;
|
||||||
}
|
}
|
||||||
fclose(packageIdFile);
|
fclose(packageIdFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
maxCoreId = Math::Max(maxCoreId, cpuInfos[cpuIdx].Core);
|
maxCoreId = Math::Max(maxCoreId, cpusInfo[cpuIdx].Core);
|
||||||
maxPackageId = Math::Max(maxPackageId, cpuInfos[cpuIdx].Package);
|
maxPackageId = Math::Max(maxPackageId, cpusInfo[cpuIdx].Package);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int coresCount = maxCoreId + 1;
|
int32 coresCount = maxCoreId + 1;
|
||||||
int packagesCount = maxPackageId + 1;
|
int32 packagesCount = maxPackageId + 1;
|
||||||
int pairsCount = packagesCount * coresCount;
|
int32 pairsCount = packagesCount * coresCount;
|
||||||
|
|
||||||
if (coresCount * 2 < cpuCountAvailable)
|
if (coresCount * 2 < cpuCountAvailable)
|
||||||
{
|
{
|
||||||
@@ -1378,9 +1376,9 @@ bool LinuxPlatform::Init()
|
|||||||
|
|
||||||
for (int32 cpuIdx = 0; cpuIdx < CPU_SETSIZE; cpuIdx++)
|
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.ProcessorPackageCount = packagesCount;
|
||||||
UnixCpu.ProcessorCoreCount = Math::Max(numberOfCores, 1);
|
UnixCpu.ProcessorCoreCount = Math::Max(numberOfCores, 1);
|
||||||
UnixCpu.LogicalProcessorCount = CPU_COUNT(&availableCpusMask);
|
UnixCpu.LogicalProcessorCount = CPU_COUNT(&cpus);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -417,13 +417,13 @@ void WindowsWindow::GetScreenInfo(int32& x, int32& y, int32& width, int32& heigh
|
|||||||
{
|
{
|
||||||
ASSERT(HasHWND());
|
ASSERT(HasHWND());
|
||||||
|
|
||||||
// Grab current monitor data for sizing
|
// Pick the current monitor data for sizing
|
||||||
const HMONITOR monitor = MonitorFromWindow(_handle, MONITOR_DEFAULTTONEAREST);
|
const HMONITOR monitor = MonitorFromWindow(_handle, MONITOR_DEFAULTTONEAREST);
|
||||||
MONITORINFO monitorInfo;
|
MONITORINFO monitorInfo;
|
||||||
monitorInfo.cbSize = sizeof(MONITORINFO);
|
monitorInfo.cbSize = sizeof(MONITORINFO);
|
||||||
GetMonitorInfoW(monitor, &monitorInfo);
|
GetMonitorInfoW(monitor, &monitorInfo);
|
||||||
|
|
||||||
// Return result
|
// Calculate result
|
||||||
x = monitorInfo.rcMonitor.left;
|
x = monitorInfo.rcMonitor.left;
|
||||||
y = monitorInfo.rcMonitor.top;
|
y = monitorInfo.rcMonitor.top;
|
||||||
width = monitorInfo.rcMonitor.right - x;
|
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++)
|
for (uint32 row = padding; row < slot->Height - padding; row++)
|
||||||
{
|
{
|
||||||
rowData.SrcRow = row - padding;
|
rowData.SrcRow = row - padding;
|
||||||
rowData.DstRow = row;
|
rowData.DstRow = row;
|
||||||
|
|
||||||
copyRow(rowData);
|
copyRow(rowData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1292,7 +1292,7 @@ void Render2D::DrawRectangle(const Rectangle& rect, const Color& color1, const C
|
|||||||
drawCall.StartIB = IBIndex;
|
drawCall.StartIB = IBIndex;
|
||||||
drawCall.CountIB = 4 * (6 + 3);
|
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 filterScale = 1.0f;
|
||||||
const float thicknessHalf = (2.82842712f + thickness) * 0.5f + filterScale;
|
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;
|
Vector2 p1t, p2t;
|
||||||
|
|
||||||
#if RENDER2D_USE_LINE_AA
|
#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.
|
// This must be the same as in HLSL code
|
||||||
const float filterScale = 1.0f; // Must match HLSL code
|
const float filterScale = 1.0f;
|
||||||
|
|
||||||
// The amount we increase each side of the line to generate enough pixels
|
|
||||||
const float thicknessHalf = (2.82842712f + thickness) * 0.5f + filterScale;
|
const float thicknessHalf = (2.82842712f + thickness) * 0.5f + filterScale;
|
||||||
|
|
||||||
drawCall.Type = DrawCallType::LineAA;
|
drawCall.Type = DrawCallType::LineAA;
|
||||||
|
|||||||
@@ -12,6 +12,10 @@
|
|||||||
|
|
||||||
#if GENERATE_GF_CACHE
|
#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 <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ bool VolumetricFogPass::Init(RenderContext& renderContext, GPUContext* context,
|
|||||||
_cache.GridSizeZ = 64;
|
_cache.GridSizeZ = 64;
|
||||||
_cache.FogJitter = false;
|
_cache.FogJitter = false;
|
||||||
_cache.TemporalReprojection = false;
|
_cache.TemporalReprojection = false;
|
||||||
_cache.HistoryMissSupersampleCount = 1;
|
_cache.MissedHistorySamplesCount = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Quality::Medium:
|
case Quality::Medium:
|
||||||
@@ -161,7 +161,7 @@ bool VolumetricFogPass::Init(RenderContext& renderContext, GPUContext* context,
|
|||||||
_cache.GridSizeZ = 64;
|
_cache.GridSizeZ = 64;
|
||||||
_cache.FogJitter = true;
|
_cache.FogJitter = true;
|
||||||
_cache.TemporalReprojection = true;
|
_cache.TemporalReprojection = true;
|
||||||
_cache.HistoryMissSupersampleCount = 4;
|
_cache.MissedHistorySamplesCount = 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Quality::High:
|
case Quality::High:
|
||||||
@@ -170,7 +170,7 @@ bool VolumetricFogPass::Init(RenderContext& renderContext, GPUContext* context,
|
|||||||
_cache.GridSizeZ = 128;
|
_cache.GridSizeZ = 128;
|
||||||
_cache.FogJitter = true;
|
_cache.FogJitter = true;
|
||||||
_cache.TemporalReprojection = true;
|
_cache.TemporalReprojection = true;
|
||||||
_cache.HistoryMissSupersampleCount = 4;
|
_cache.MissedHistorySamplesCount = 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Quality::Ultra:
|
case Quality::Ultra:
|
||||||
@@ -179,7 +179,7 @@ bool VolumetricFogPass::Init(RenderContext& renderContext, GPUContext* context,
|
|||||||
_cache.GridSizeZ = 256;
|
_cache.GridSizeZ = 256;
|
||||||
_cache.FogJitter = true;
|
_cache.FogJitter = true;
|
||||||
_cache.TemporalReprojection = true;
|
_cache.TemporalReprojection = true;
|
||||||
_cache.HistoryMissSupersampleCount = 8;
|
_cache.MissedHistorySamplesCount = 8;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -208,7 +208,7 @@ bool VolumetricFogPass::Init(RenderContext& renderContext, GPUContext* context,
|
|||||||
_cache.Data.InverseSquaredLightDistanceBiasScale = _cache.InverseSquaredLightDistanceBiasScale;
|
_cache.Data.InverseSquaredLightDistanceBiasScale = _cache.InverseSquaredLightDistanceBiasScale;
|
||||||
_cache.Data.PhaseG = options.ScatteringDistribution;
|
_cache.Data.PhaseG = options.ScatteringDistribution;
|
||||||
_cache.Data.VolumetricFogMaxDistance = options.Distance;
|
_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);
|
Matrix::Transpose(view.PrevViewProjection, _cache.Data.PrevWorldToClip);
|
||||||
_cache.Data.DirectionalLightShadow.NumCascades = 0;
|
_cache.Data.DirectionalLightShadow.NumCascades = 0;
|
||||||
_cache.Data.SkyLight.VolumetricScatteringIntensity = 0;
|
_cache.Data.SkyLight.VolumetricScatteringIntensity = 0;
|
||||||
@@ -221,7 +221,7 @@ bool VolumetricFogPass::Init(RenderContext& renderContext, GPUContext* context,
|
|||||||
}
|
}
|
||||||
if (_cache.FogJitter && _cache.TemporalReprojection)
|
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;
|
const uint64 frameNumber = renderContext.Task->LastUsedFrame - i;
|
||||||
_cache.Data.FrameJitterOffsets[i] = Vector4(
|
_cache.Data.FrameJitterOffsets[i] = Vector4(
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ private:
|
|||||||
float HistoryWeight;
|
float HistoryWeight;
|
||||||
|
|
||||||
Vector3 GridSize;
|
Vector3 GridSize;
|
||||||
uint32 HistoryMissSuperSampleCount;
|
uint32 MissedHistorySamplesCount;
|
||||||
|
|
||||||
int32 GridSizeIntX;
|
int32 GridSizeIntX;
|
||||||
int32 GridSizeIntY;
|
int32 GridSizeIntY;
|
||||||
@@ -105,9 +105,9 @@ private:
|
|||||||
float HistoryWeight;
|
float HistoryWeight;
|
||||||
|
|
||||||
/// <summary>
|
/// <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>
|
/// </summary>
|
||||||
int32 HistoryMissSupersampleCount;
|
int32 MissedHistorySamplesCount;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Scales the amount added to the inverse squared falloff denominator. This effectively removes the spike from inverse squared falloff that causes extreme aliasing.
|
/// 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/Core/Math/Math.h"
|
||||||
#include "Engine/Platform/Platform.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 };
|
enum { Crc32Poly = 0x04c11db7 };
|
||||||
|
|
||||||
uint32 Crc::CachedCRCTablesSB8[8][256] =
|
uint32 Crc::CachedCRCTablesSB8[8][256] =
|
||||||
|
|||||||
@@ -71,9 +71,9 @@ namespace FlaxEngine.Utilities
|
|||||||
return Base + noise * NoiseAmount;
|
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)
|
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;
|
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);
|
float luma = dot(color, AP1_RGB2Y);
|
||||||
float3 ccColorShadows = ColorCorrect(color, luma, ColorSaturationShadows, ColorContrastShadows, ColorGammaShadows, ColorGainShadows, ColorOffsetShadows);
|
float3 ccColorShadows = ColorCorrect(color, luma, ColorSaturationShadows, ColorContrastShadows, ColorGammaShadows, ColorGainShadows, ColorOffsetShadows);
|
||||||
float ccWeightShadows = 1 - smoothstep(0, ColorCorrectionShadowsMax, luma);
|
float ccWeightShadows = 1 - smoothstep(0, ColorCorrectionShadowsMax, luma);
|
||||||
@@ -118,18 +124,7 @@ float3 ColorCorrectAll(float3 color)
|
|||||||
float ccWeightHighlights = smoothstep(ColorCorrectionHighlightsMin, 1, luma);
|
float ccWeightHighlights = smoothstep(ColorCorrectionHighlightsMin, 1, luma);
|
||||||
float3 ccColorMidtones = ColorCorrect(color, luma, ColorSaturationMidtones, ColorContrastMidtones, ColorGammaMidtones, ColorGainMidtones, ColorOffsetMidtones);
|
float3 ccColorMidtones = ColorCorrect(color, luma, ColorSaturationMidtones, ColorContrastMidtones, ColorGammaMidtones, ColorGainMidtones, ColorOffsetMidtones);
|
||||||
float ccWeightMidtones = 1 - ccWeightShadows - ccWeightHighlights;
|
float ccWeightMidtones = 1 - ccWeightShadows - ccWeightHighlights;
|
||||||
return ccColorShadows * ccWeightShadows + ccColorMidtones * ccWeightMidtones + ccColorHighlights * ccWeightHighlights;
|
color = 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);
|
|
||||||
|
|
||||||
// Convert back to linear color
|
// Convert back to linear color
|
||||||
return mul(AP1_2_sRGB, color);
|
return mul(AP1_2_sRGB, color);
|
||||||
@@ -216,23 +211,20 @@ float4 CombineLUTs(float2 uv, uint layerIndex)
|
|||||||
{
|
{
|
||||||
float3 encodedColor;
|
float3 encodedColor;
|
||||||
#if USE_VOLUME_LUT
|
#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);
|
uv = uv - float2(0.5f / LUTSize, 0.5f / LUTSize);
|
||||||
encodedColor = float3(uv * LUTSize / (LUTSize - 1), layerIndex / (LUTSize - 1));
|
encodedColor = float3(uv * LUTSize / (LUTSize - 1), layerIndex / (LUTSize - 1));
|
||||||
}
|
}
|
||||||
#else
|
#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);
|
uv -= float2(0.49999f / (LUTSize * LUTSize), 0.49999f / LUTSize);
|
||||||
|
|
||||||
float3 rgb;
|
float3 rgb;
|
||||||
rgb.r = frac(uv.x * LUTSize);
|
rgb.r = frac(uv.x * LUTSize);
|
||||||
rgb.b = uv.x - rgb.r / LUTSize;
|
rgb.b = uv.x - rgb.r / LUTSize;
|
||||||
rgb.g = uv.y;
|
rgb.g = uv.y;
|
||||||
|
encodedColor = rgb * (LUTSize / (LUTSize - 1));
|
||||||
float scale = LUTSize / (LUTSize - 1);
|
|
||||||
encodedColor = rgb * scale;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -48,25 +48,20 @@ float4 GetExponentialHeightFog(ExponentialHeightFogData exponentialHeightFog, fl
|
|||||||
float excludeIntersectionTime = skipDistance * cameraToPosLenInv;
|
float excludeIntersectionTime = skipDistance * cameraToPosLenInv;
|
||||||
float cameraToExclusionIntersectionY = excludeIntersectionTime * cameraToPos.y;
|
float cameraToExclusionIntersectionY = excludeIntersectionTime * cameraToPos.y;
|
||||||
float exclusionIntersectionY = camWS.y + cameraToExclusionIntersectionY;
|
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;
|
rayLength = (1.0f - excludeIntersectionTime) * cameraToPosLen;
|
||||||
rayDirectionY = exclusionIntersectionToReceiverY;
|
rayDirectionY = cameraToPos.y - cameraToExclusionIntersectionY;
|
||||||
|
|
||||||
// Move off the viewer
|
|
||||||
float exponent = exponentialHeightFog.FogHeightFalloff * (exclusionIntersectionY - exponentialHeightFog.FogHeight);
|
float exponent = exponentialHeightFog.FogHeightFalloff * (exclusionIntersectionY - exponentialHeightFog.FogHeight);
|
||||||
rayOriginTerms = exponentialHeightFog.FogDensity * exp2(-exponent);
|
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 falloff = max(-127.0f, exponentialHeightFog.FogHeightFalloff * rayDirectionY);
|
||||||
float lineIntegral = (1.0f - exp2(-falloff)) / falloff;
|
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 exponentialHeightLineIntegralCalc = rayOriginTerms * (abs(falloff) > 0.01f ? lineIntegral : lineIntegralTaylor);
|
||||||
float exponentialHeightLineIntegral = exponentialHeightLineIntegralCalc * rayLength;
|
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);
|
float expFogFactor = max(saturate(exp2(-exponentialHeightLineIntegral)), exponentialHeightFog.FogMinOpacity);
|
||||||
|
|
||||||
// Calculate the directional light inscattering
|
// Calculate the directional light inscattering
|
||||||
@@ -75,17 +70,10 @@ float4 GetExponentialHeightFog(ExponentialHeightFogData exponentialHeightFog, fl
|
|||||||
BRANCH
|
BRANCH
|
||||||
if (exponentialHeightFog.ApplyDirectionalInscattering > 0)
|
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);
|
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);
|
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));
|
float directionalInscatteringFogFactor = saturate(exp2(-dirExponentialHeightLineIntegral));
|
||||||
|
directionalInscattering = directionalLightInscattering * (1.0f - directionalInscatteringFogFactor);
|
||||||
// Final inscattering from the light
|
|
||||||
directionalInscattering = directionalLightInscattering * (1 - directionalInscatteringFogFactor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable fog after a certain distance
|
// Disable fog after a certain distance
|
||||||
|
|||||||
@@ -9,24 +9,16 @@ Texture2D Distortion : register(t1);
|
|||||||
META_PS(true, FEATURE_LEVEL_ES2)
|
META_PS(true, FEATURE_LEVEL_ES2)
|
||||||
float4 PS_ApplyDistortion(Quad_VS2PS input) : SV_Target
|
float4 PS_ApplyDistortion(Quad_VS2PS input) : SV_Target
|
||||||
{
|
{
|
||||||
// Sample accumulated distortion offset
|
float4 accumDist = Distortion.Sample(SamplerPointClamp, input.TexCoord);
|
||||||
half4 accumDist = Distortion.Sample(SamplerPointClamp, input.TexCoord);
|
float2 distOffset = (accumDist.rg - accumDist.ba) / 4.0f;
|
||||||
|
|
||||||
// Offset = [R-B,G-A]
|
|
||||||
half2 distOffset = (accumDist.rg - accumDist.ba);
|
|
||||||
|
|
||||||
static const half InvDistortionScaleBias = 1 / 4.0f;
|
|
||||||
distOffset *= InvDistortionScaleBias;
|
|
||||||
|
|
||||||
float2 newTexCoord = input.TexCoord + distOffset;
|
float2 newTexCoord = input.TexCoord + distOffset;
|
||||||
|
|
||||||
// If we're about to sample outside the valid area, set to 0 distortion
|
// Clamp around screen
|
||||||
FLATTEN
|
FLATTEN
|
||||||
if (newTexCoord.x < 0 || newTexCoord.x > 1 || newTexCoord.y < 0 || newTexCoord.y > 1)
|
if (newTexCoord.x < 0 || newTexCoord.x > 1 || newTexCoord.y < 0 || newTexCoord.y > 1)
|
||||||
{
|
{
|
||||||
newTexCoord = input.TexCoord;
|
newTexCoord = input.TexCoord;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sample screen using offset coords
|
|
||||||
return Input.SampleLevel(SamplerPointClamp, newTexCoord, 0);
|
return Input.SampleLevel(SamplerPointClamp, newTexCoord, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,34 +60,18 @@ half3 sRGBToLinear(half3 color)
|
|||||||
|
|
||||||
float3 LogToLinear(float3 logColor)
|
float3 LogToLinear(float3 logColor)
|
||||||
{
|
{
|
||||||
const float linearRange = 14;
|
const float linearRange = 14.0f;
|
||||||
const float linearGrey = 0.18;
|
const float linearGrey = 0.18f;
|
||||||
const float exposureGrey = 444;
|
const float exposureGrey = 444.0f;
|
||||||
|
return exp2((logColor - exposureGrey / 1023.0) * linearRange) * linearGrey;
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float3 LinearToLog(float3 linearColor)
|
float3 LinearToLog(float3 linearColor)
|
||||||
{
|
{
|
||||||
const float linearRange = 14;
|
const float linearRange = 14.0f;
|
||||||
const float linearGrey = 0.18;
|
const float linearGrey = 0.18f;
|
||||||
const float exposureGrey = 444;
|
const float exposureGrey = 444.0f;
|
||||||
|
return saturate(log2(linearColor) / linearRange - log2(linearGrey) / linearRange + exposureGrey / 1023.0f);
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -82,19 +82,16 @@ void GetRadialLightAttenuation(
|
|||||||
BRANCH
|
BRANCH
|
||||||
if (lightData.SourceLength > 0)
|
if (lightData.SourceLength > 0)
|
||||||
{
|
{
|
||||||
// Line segment irradiance
|
float3 l01 = lightData.Direction * lightData.SourceLength;
|
||||||
float3 L01 = lightData.Direction * lightData.SourceLength;
|
float3 l0 = toLight - 0.5 * l01;
|
||||||
float3 L0 = toLight - 0.5 * L01;
|
float3 l1 = toLight + 0.5 * l01;
|
||||||
float3 L1 = toLight + 0.5 * L01;
|
float lengthL0 = length(l0);
|
||||||
float LengthL0 = length(L0);
|
float lengthL1 = length(l1);
|
||||||
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));
|
||||||
distanceAttenuation = rcp((LengthL0 * LengthL1 + dot(L0, L1)) * 0.5 + distanceBiasSqr);
|
|
||||||
NoL = saturate(0.5 * (dot(N, L0) / LengthL0 + dot(N, L1) / LengthL1));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Sphere irradiance (technically just 1/d^2 but this avoids inf)
|
|
||||||
distanceAttenuation = rcp(distanceSqr + distanceBiasSqr);
|
distanceAttenuation = rcp(distanceSqr + distanceBiasSqr);
|
||||||
NoL = saturate(dot(N, L));
|
NoL = saturate(dot(N, L));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,8 +98,6 @@ Texture2D Input3 : register(t3);
|
|||||||
Texture2D LensDirt : register(t4);
|
Texture2D LensDirt : register(t4);
|
||||||
Texture2D LensStar : register(t5);
|
Texture2D LensStar : register(t5);
|
||||||
Texture2D LensColor : register(t6);
|
Texture2D LensColor : register(t6);
|
||||||
|
|
||||||
// LUT for color grading
|
|
||||||
#if USE_VOLUME_LUT
|
#if USE_VOLUME_LUT
|
||||||
Texture3D ColorGradingLUT : register(t7);
|
Texture3D ColorGradingLUT : register(t7);
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ float SampleShadowMapFixedSizePCF(Texture2DArray shadowMap, float2 shadowMapSize
|
|||||||
|
|
||||||
if (value != 0.0f)
|
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
|
#if CAN_USE_GATHER
|
||||||
|
|
||||||
v1[(col + FS_2) / 2] = shadowMap.GatherCmp(ShadowSampler, baseUV, sceneDepth, int2(col, row));
|
v1[(col + FS_2) / 2] = shadowMap.GatherCmp(ShadowSampler, baseUV, sceneDepth, int2(col, row));
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ float3 GlobalEmissive;
|
|||||||
float HistoryWeight;
|
float HistoryWeight;
|
||||||
|
|
||||||
float3 GridSize;
|
float3 GridSize;
|
||||||
uint HistoryMissSuperSampleCount;
|
uint MissedHistorySamplesCount;
|
||||||
|
|
||||||
int3 GridSizeInt;
|
int3 GridSizeInt;
|
||||||
float PhaseG;
|
float PhaseG;
|
||||||
@@ -205,7 +205,7 @@ float4 PS_InjectLight(Quad_GS2PS input) : SV_Target0
|
|||||||
{
|
{
|
||||||
historyAlpha = 0;
|
historyAlpha = 0;
|
||||||
}
|
}
|
||||||
uint samplesCount = historyAlpha < 0.001f ? HistoryMissSuperSampleCount : 1;
|
uint samplesCount = historyAlpha < 0.001f ? MissedHistorySamplesCount : 1;
|
||||||
#else
|
#else
|
||||||
uint samplesCount = 1;
|
uint samplesCount = 1;
|
||||||
#endif
|
#endif
|
||||||
@@ -261,7 +261,6 @@ void CS_Initialize(uint3 GroupId : SV_GroupID, uint3 DispatchThreadId : SV_Dispa
|
|||||||
{
|
{
|
||||||
uint3 gridCoordinate = DispatchThreadId;
|
uint3 gridCoordinate = DispatchThreadId;
|
||||||
|
|
||||||
// Center of the voxel
|
|
||||||
float voxelOffset = 0.5f;
|
float voxelOffset = 0.5f;
|
||||||
float3 positionWS = GetCellPositionWS(gridCoordinate, voxelOffset);
|
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
|
// Calculate the global fog density that matches the exponential height fog density
|
||||||
float globalDensity = fogDensity * exp2(-fogHeightFalloff * (positionWS.y - fogHeight));
|
float globalDensity = fogDensity * exp2(-fogHeightFalloff * (positionWS.y - fogHeight));
|
||||||
float matchFactor = 0.24f;
|
float extinction = max(0.0f, globalDensity * GlobalExtinctionScale * 0.24f);
|
||||||
float extinction = max(globalDensity * GlobalExtinctionScale * matchFactor, 0);
|
|
||||||
|
|
||||||
float3 scattering = GlobalAlbedo * extinction;
|
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))
|
if (all((int3)gridCoordinate < GridSizeInt))
|
||||||
{
|
{
|
||||||
@@ -306,7 +304,7 @@ void CS_LightScattering(uint3 GroupId : SV_GroupID, uint3 DispatchThreadId : SV_
|
|||||||
{
|
{
|
||||||
uint3 gridCoordinate = DispatchThreadId;
|
uint3 gridCoordinate = DispatchThreadId;
|
||||||
float3 lightScattering = 0;
|
float3 lightScattering = 0;
|
||||||
uint numSuperSamples = 1;
|
uint samplesCount = 1;
|
||||||
|
|
||||||
#if USE_TEMPORAL_REPROJECTION
|
#if USE_TEMPORAL_REPROJECTION
|
||||||
float3 historyUV = GetVolumeUV(GetCellPositionWS(gridCoordinate, 0.5f), PrevWorldToClip);
|
float3 historyUV = GetVolumeUV(GetCellPositionWS(gridCoordinate, 0.5f), PrevWorldToClip);
|
||||||
@@ -319,12 +317,10 @@ void CS_LightScattering(uint3 GroupId : SV_GroupID, uint3 DispatchThreadId : SV_
|
|||||||
historyAlpha = 0;
|
historyAlpha = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Supersample if the history was outside the camera frustum
|
samplesCount = historyAlpha < 0.001f && all(gridCoordinate < GridSizeInt) ? MissedHistorySamplesCount : 1;
|
||||||
// The compute shader is dispatched with extra threads, make sure those don't supersample
|
|
||||||
numSuperSamples = historyAlpha < 0.001f && all(gridCoordinate < GridSizeInt) ? HistoryMissSuperSampleCount : 1;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (uint sampleIndex = 0; sampleIndex < numSuperSamples; sampleIndex++)
|
for (uint sampleIndex = 0; sampleIndex < samplesCount; sampleIndex++)
|
||||||
{
|
{
|
||||||
float3 cellOffset = FrameJitterOffsets[sampleIndex].xyz;
|
float3 cellOffset = FrameJitterOffsets[sampleIndex].xyz;
|
||||||
//float3 cellOffset = 0.5f;
|
//float3 cellOffset = 0.5f;
|
||||||
@@ -357,8 +353,7 @@ void CS_LightScattering(uint3 GroupId : SV_GroupID, uint3 DispatchThreadId : SV_
|
|||||||
lightScattering += skyLighting * SkyLight.VolumetricScatteringIntensity;
|
lightScattering += skyLighting * SkyLight.VolumetricScatteringIntensity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lightScattering /= (float)samplesCount;
|
||||||
lightScattering /= (float)numSuperSamples;
|
|
||||||
|
|
||||||
// Apply scattering from the point and spot lights
|
// Apply scattering from the point and spot lights
|
||||||
lightScattering += LocalShadowedLightScattering[gridCoordinate].rgb;
|
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;
|
return toolPath;
|
||||||
}
|
}
|
||||||
@@ -82,17 +82,17 @@ namespace Flax.Deploy
|
|||||||
return toolPath;
|
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;
|
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;
|
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;
|
return toolPath;
|
||||||
}
|
}
|
||||||
@@ -121,7 +121,7 @@ namespace Flax.Deploy
|
|||||||
}
|
}
|
||||||
case TargetPlatform.Windows:
|
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;
|
return toolPath;
|
||||||
}
|
}
|
||||||
@@ -132,17 +132,17 @@ namespace Flax.Deploy
|
|||||||
return toolPath;
|
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;
|
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;
|
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;
|
return toolPath;
|
||||||
}
|
}
|
||||||
@@ -154,13 +154,9 @@ namespace Flax.Deploy
|
|||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private static bool CheckMsBuildPathFromRegistry(string keyRelativePath, string keyName, string msBuildRelativePath, out string outMsBuildPath)
|
||||||
/// 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)
|
|
||||||
{
|
{
|
||||||
string[] keyBasePaths =
|
string[] prefixes =
|
||||||
{
|
{
|
||||||
@"HKEY_CURRENT_USER\SOFTWARE\",
|
@"HKEY_CURRENT_USER\SOFTWARE\",
|
||||||
@"HKEY_LOCAL_MACHINE\SOFTWARE\",
|
@"HKEY_LOCAL_MACHINE\SOFTWARE\",
|
||||||
@@ -168,9 +164,9 @@ namespace Flax.Deploy
|
|||||||
@"HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\"
|
@"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);
|
string msBuildPath = Path.Combine(value, msBuildRelativePath);
|
||||||
if (File.Exists(msBuildPath))
|
if (File.Exists(msBuildPath))
|
||||||
|
|||||||
Reference in New Issue
Block a user