You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
Vulkan/DXC does not support initialization of static const variable having complex type. This change lines change the initialization to some simple define instead. #rb none #ROBOMERGE-SOURCE: CL 16574414 #ROBOMERGE-BOT: (v828-16531559) [CL 16574416 by charles derousiers in ue5-main branch]
495 lines
15 KiB
Plaintext
495 lines
15 KiB
Plaintext
/*=============================================================================
|
|
ShaderPrintCommon.ush:
|
|
Include this to be able to call ShaderPrint() from arbitrary shaders
|
|
=============================================================================*/
|
|
|
|
#pragma once
|
|
|
|
// Include the MiniFont symbol definitions
|
|
#include "MiniFontCommon.ush"
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Uniforms and structures
|
|
|
|
// Needs to match C++ code in ShaderPrintUniform.cpp
|
|
struct FShaderPrintItem
|
|
{
|
|
float2 ScreenPos; // Position in normalized coordinates
|
|
int Value; // Cast to value or symbol
|
|
int Type; // SHADER_PRINT_TYPE_* defines how to read Value
|
|
float3 Color; // Color
|
|
};
|
|
|
|
struct FPackedShaderPrintItem
|
|
{
|
|
float2 ScreenPos; // Position in normalized coordinates
|
|
int Value; // Cast to value or symbol
|
|
uint TypeAndColor;//
|
|
};
|
|
|
|
RWStructuredBuffer<FPackedShaderPrintItem> RWValuesBuffer;
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Input types
|
|
|
|
// Content of FShaderPrintItem.Type defines what to cast FShaderPrintItem.Value as
|
|
#define SHADER_PRINT_TYPE_SYMBOL 0
|
|
#define SHADER_PRINT_TYPE_FLOAT 1
|
|
#define SHADER_PRINT_TYPE_INT 2
|
|
#define SHADER_PRINT_TYPE_UINT 3
|
|
#define SHADER_PRINT_TYPE_HEX 4
|
|
|
|
#define SHADER_PRINT_COUNT_OFFSET 0
|
|
#define SHADER_PRINT_VALUE_OFFSET 1
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Font Color
|
|
|
|
struct FFontColor
|
|
{
|
|
float3 Color;
|
|
};
|
|
|
|
FFontColor InitFontColor(float InX, float InY, float InZ) { FFontColor Out; Out.Color = float3(InX, InY, InZ); return Out; }
|
|
FFontColor InitFontColor(float3 In) { FFontColor Out; Out.Color = In; return Out; }
|
|
FFontColor GetDefaultFontColor() { FFontColor Out; Out.Color = float3(1,1,1); return Out; }
|
|
|
|
// Certain shader compiler does not support static initialization with complex type.
|
|
// In the meantime, using define to provide default color initialization
|
|
#if 1
|
|
#define FontWhite InitFontColor(1, 1, 1)
|
|
#define FontBlack InitFontColor(0, 0, 0)
|
|
#define FontRed InitFontColor(1, 0, 0)
|
|
#define FontGreen InitFontColor(0, 1, 0)
|
|
#define FontBlue InitFontColor(0, 0, 1)
|
|
#define FontYellow InitFontColor(1, 1, 0)
|
|
#define FontCyan InitFontColor(0, 1, 1)
|
|
#define FontMagenta InitFontColor(1, 0, 1)
|
|
#define FontOrange InitFontColor(243.f / 255.f, 156.f / 255.f, 18.f / 255.f)
|
|
#define FontPurple InitFontColor(169.f / 255.f, 7.f / 255.f, 228.f / 255.f)
|
|
#define FontTurquoise InitFontColor(26.f / 255.f, 188.f / 255.f, 156.f / 255.f)
|
|
#define FontSilver InitFontColor(189.f / 255.f, 195.f / 255.f, 199.f / 255.f)
|
|
#define FontEmerald InitFontColor(46.f / 255.f, 204.f / 255.f, 113.f / 255.f)
|
|
#else
|
|
static const FFontColor FontWhite = InitFontColor(1, 1, 1);
|
|
static const FFontColor FontBlack = InitFontColor(0, 0, 0);
|
|
static const FFontColor FontRed = InitFontColor(1, 0, 0);
|
|
static const FFontColor FontGreen = InitFontColor(0, 1, 0);
|
|
static const FFontColor FontBlue = InitFontColor(0, 0, 1);
|
|
static const FFontColor FontYellow = InitFontColor(1, 1, 0);
|
|
static const FFontColor FontCyan = InitFontColor(0, 1, 1);
|
|
static const FFontColor FontMagenta = InitFontColor(1, 0, 1);
|
|
static const FFontColor FontOrange = InitFontColor(243.f / 255.f, 156.f / 255.f, 18.f / 255.f);
|
|
static const FFontColor FontPurple = InitFontColor(169.f /255.f, 7.f / 255.f, 228.f / 255.f);
|
|
static const FFontColor FontTurquoise = InitFontColor( 26.f / 255.f, 188.f / 255.f, 156.f / 255.f);
|
|
static const FFontColor FontSilver = InitFontColor(189.f / 255.f, 195.f / 255.f, 199.f / 255.f);
|
|
static const FFontColor FontEmerald = InitFontColor( 46.f / 255.f, 204.f / 255.f, 113.f / 255.f);
|
|
#endif
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Util pack/unpac functions
|
|
|
|
FPackedShaderPrintItem PackShaderPrintItem(FShaderPrintItem In)
|
|
{
|
|
const uint3 Color8bits = saturate(In.Color) * 0xFF;
|
|
|
|
FPackedShaderPrintItem Out;
|
|
Out.ScreenPos = In.ScreenPos;
|
|
Out.Value = In.Value;
|
|
Out.TypeAndColor = Color8bits.z<<24 | Color8bits.y<<16 | Color8bits.x<<8 | (In.Type & 0xFF);
|
|
return Out;
|
|
}
|
|
|
|
FShaderPrintItem UnpackShaderPrintItem(FPackedShaderPrintItem In)
|
|
{
|
|
FShaderPrintItem Out;
|
|
Out.ScreenPos = In.ScreenPos;
|
|
Out.Value = In.Value;
|
|
Out.Type = (In.TypeAndColor) & 0xFF;
|
|
Out.Color.x = float((In.TypeAndColor >> 8) & 0xFF) / 255.f;
|
|
Out.Color.y = float((In.TypeAndColor >> 16) & 0xFF) / 255.f;
|
|
Out.Color.z = float((In.TypeAndColor >> 24) & 0xFF) / 255.f;
|
|
return Out;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Global variables
|
|
|
|
#include "/Engine/Generated/UniformBuffers/ShaderPrintUniform.ush"
|
|
//float4 FontSize; // .xy character size, .zw character spacing (in normalized coordinates)
|
|
//int MaxValueCount; // maximum number of values that we can print in one frame
|
|
//int MaxSymbolCount; // maximum number of symbols (after conversion from characters) that we can print in one frame
|
|
|
|
static const float2 ShaderPrintCursorStart = float2(0.05f, 0.05f);
|
|
static const float ShaderPrintTabCount = 12.f;
|
|
|
|
// 'Global' values for tracking printing state (per thread)
|
|
static float2 ShaderPrintCursorPos = ShaderPrintCursorStart;
|
|
static bool ShaderPrintFilterEnable = true;
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Internal helpers
|
|
|
|
void ShaderPrint_Internal(in FShaderPrintItem Item)
|
|
{
|
|
// If MaxValueCount is 0 then we don't reset the buffer counter so early out here
|
|
if (ShaderPrintUniform.MaxValueCount == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Buffer counter is stored in first element .Value
|
|
int IndexToStore = 0;
|
|
InterlockedAdd(RWValuesBuffer[SHADER_PRINT_COUNT_OFFSET].Value, 1, IndexToStore);
|
|
|
|
// Prevent writing off the buffer
|
|
// Note that counter still increases so need clamp when reading it in later passes
|
|
if (IndexToStore >= ShaderPrintUniform.MaxValueCount)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Because counter is in first element, read/writes need to be offset by 1
|
|
RWValuesBuffer[IndexToStore + SHADER_PRINT_VALUE_OFFSET] = PackShaderPrintItem(Item);
|
|
}
|
|
|
|
void ShaderPrint_Internal(in float2 ScreenPos, in int Value, in FFontColor FontColor, in int Type)
|
|
{
|
|
FShaderPrintItem Item;
|
|
Item.ScreenPos = ScreenPos;
|
|
Item.Value = Value;
|
|
Item.Type = Type;
|
|
Item.Color = FontColor.Color;
|
|
ShaderPrint_Internal(Item);
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Symbol printing
|
|
|
|
float2 ShaderPrintSymbol(in float2 ScreenPos, in int Symbol, in FFontColor Color)
|
|
{
|
|
if (ShaderPrintFilterEnable)
|
|
{
|
|
ShaderPrint_Internal(ScreenPos, Symbol, Color, SHADER_PRINT_TYPE_SYMBOL);
|
|
ScreenPos.x += ShaderPrintUniform.FontSize.z;
|
|
}
|
|
return ScreenPos;
|
|
}
|
|
|
|
float2 ShaderPrintSymbol(in float2 ScreenPos, in int Symbol)
|
|
{
|
|
return ShaderPrintSymbol(ScreenPos, Symbol, GetDefaultFontColor());
|
|
}
|
|
|
|
void ShaderPrintSymbol(in int symbol, in FFontColor Color)
|
|
{
|
|
ShaderPrintCursorPos = ShaderPrintSymbol(ShaderPrintCursorPos, symbol, Color);
|
|
}
|
|
|
|
void ShaderPrintSymbol(in int symbol)
|
|
{
|
|
ShaderPrintCursorPos = ShaderPrintSymbol(ShaderPrintCursorPos, symbol, GetDefaultFontColor());
|
|
}
|
|
|
|
// Function for reading global TEXT string.
|
|
// The data and function are generated by the shader compiler.
|
|
//float2 ShaderPrintText(float2 Pos, uint InTextEntry, float3 InColor);
|
|
GENERATED_SHADER_PRINT
|
|
|
|
float2 ShaderPrintHelloWorld(in float2 ScreenPos)
|
|
{
|
|
if (ShaderPrintFilterEnable)
|
|
{
|
|
ScreenPos = ShaderPrintSymbol(ScreenPos, _H_);
|
|
ScreenPos = ShaderPrintSymbol(ScreenPos, _E_);
|
|
ScreenPos = ShaderPrintSymbol(ScreenPos, _L_);
|
|
ScreenPos = ShaderPrintSymbol(ScreenPos, _L_);
|
|
ScreenPos = ShaderPrintSymbol(ScreenPos, _O_);
|
|
ScreenPos = ShaderPrintSymbol(ScreenPos, _SPC_);
|
|
ScreenPos = ShaderPrintSymbol(ScreenPos, _W_);
|
|
ScreenPos = ShaderPrintSymbol(ScreenPos, _O_);
|
|
ScreenPos = ShaderPrintSymbol(ScreenPos, _R_);
|
|
ScreenPos = ShaderPrintSymbol(ScreenPos, _L_);
|
|
ScreenPos = ShaderPrintSymbol(ScreenPos, _D_);
|
|
ScreenPos = ShaderPrintSymbol(ScreenPos, _SPC_);
|
|
}
|
|
return ScreenPos;
|
|
}
|
|
|
|
void ShaderPrintHelloWorld()
|
|
{
|
|
ShaderPrintCursorPos = ShaderPrintHelloWorld(ShaderPrintCursorPos);
|
|
}
|
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Value printing (common value printing)
|
|
|
|
// float
|
|
float2 ShaderPrintValue(in float2 ScreenPos, in float Value, in FFontColor Color)
|
|
{
|
|
ShaderPrint_Internal(ScreenPos, asint(Value), Color, SHADER_PRINT_TYPE_FLOAT);
|
|
ScreenPos.x += ShaderPrintUniform.FontSize.z * ShaderPrintTabCount;
|
|
return ScreenPos;
|
|
}
|
|
|
|
// int
|
|
float2 ShaderPrintValue(in float2 ScreenPos, in int Value, in FFontColor Color)
|
|
{
|
|
ShaderPrint_Internal(ScreenPos, Value, Color, SHADER_PRINT_TYPE_INT);
|
|
ScreenPos.x += ShaderPrintUniform.FontSize.z * ShaderPrintTabCount;
|
|
return ScreenPos;
|
|
}
|
|
|
|
// uint
|
|
float2 ShaderPrintValue(in float2 ScreenPos, in uint Value, in FFontColor Color)
|
|
{
|
|
ShaderPrint_Internal(ScreenPos, asint(Value), Color, SHADER_PRINT_TYPE_UINT);
|
|
ScreenPos.x += ShaderPrintUniform.FontSize.z * ShaderPrintTabCount;
|
|
return ScreenPos;
|
|
}
|
|
|
|
// bool
|
|
float2 ShaderPrintValue(in float2 ScreenPos, in bool Value, in FFontColor Color)
|
|
{
|
|
ShaderPrint_Internal(ScreenPos, asint(Value ? 1u : 0u), Color, SHADER_PRINT_TYPE_UINT);
|
|
ScreenPos.x += ShaderPrintUniform.FontSize.z * ShaderPrintTabCount;
|
|
return ScreenPos;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Scalar type printing
|
|
|
|
#define SHADER_PRINT_OVERLOAD_1(InNumComponent, InType) \
|
|
float2 ShaderPrint(in float2 ScreenPos, in InType Value, in FFontColor Color) \
|
|
{ \
|
|
if (ShaderPrintFilterEnable) \
|
|
{ \
|
|
ScreenPos = ShaderPrintValue(ScreenPos, Value, Color); \
|
|
} \
|
|
return ScreenPos; \
|
|
} \
|
|
float2 ShaderPrint(in float2 ScreenPos, in InType Value) \
|
|
{ \
|
|
if (ShaderPrintFilterEnable) \
|
|
{ \
|
|
ScreenPos = ShaderPrint(ScreenPos, Value, GetDefaultFontColor()); \
|
|
} \
|
|
return ScreenPos; \
|
|
} \
|
|
void ShaderPrint(in InType Value, in FFontColor Color) \
|
|
{ \
|
|
if (ShaderPrintFilterEnable) \
|
|
{ \
|
|
ShaderPrintCursorPos = ShaderPrint(ShaderPrintCursorPos, Value, Color); \
|
|
} \
|
|
} \
|
|
void ShaderPrint(in InType Value) \
|
|
{ \
|
|
if (ShaderPrintFilterEnable) \
|
|
{ \
|
|
ShaderPrintCursorPos = ShaderPrint(ShaderPrintCursorPos, Value, GetDefaultFontColor()); \
|
|
} \
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Vector type printing
|
|
|
|
#define SHADER_PRINT_OVERLOAD_N(InNumComponent, InType) \
|
|
float2 ShaderPrint(in float2 ScreenPos, in InType Value, in FFontColor Color) \
|
|
{ \
|
|
if (ShaderPrintFilterEnable) \
|
|
{ \
|
|
UNROLL \
|
|
for (uint CompIt = 0; CompIt < InNumComponent; ++CompIt) \
|
|
{ \
|
|
ScreenPos = ShaderPrintValue(ScreenPos, Value[CompIt], Color); \
|
|
} \
|
|
} \
|
|
return ScreenPos; \
|
|
} \
|
|
float2 ShaderPrint(in float2 ScreenPos, in InType Value) \
|
|
{ \
|
|
if (ShaderPrintFilterEnable) \
|
|
{ \
|
|
UNROLL \
|
|
for (uint CompIt=0;CompIt<InNumComponent;++CompIt) \
|
|
{ \
|
|
ScreenPos = ShaderPrint(ScreenPos, Value[CompIt], GetDefaultFontColor()); \
|
|
} \
|
|
} \
|
|
return ScreenPos; \
|
|
} \
|
|
void ShaderPrint(in InType Value, in FFontColor Color) \
|
|
{ \
|
|
if (ShaderPrintFilterEnable) \
|
|
{ \
|
|
UNROLL \
|
|
for (uint CompIt=0;CompIt<InNumComponent;++CompIt) \
|
|
{ \
|
|
ShaderPrintCursorPos = ShaderPrint(ShaderPrintCursorPos, Value[CompIt], Color); \
|
|
} \
|
|
} \
|
|
} \
|
|
void ShaderPrint(in InType Value) \
|
|
{ \
|
|
if (ShaderPrintFilterEnable) \
|
|
{ \
|
|
UNROLL \
|
|
for (uint CompIt=0;CompIt<InNumComponent;++CompIt) \
|
|
{ \
|
|
ShaderPrintCursorPos = ShaderPrint(ShaderPrintCursorPos, Value[CompIt], GetDefaultFontColor()); \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
SHADER_PRINT_OVERLOAD_1(1, float)
|
|
SHADER_PRINT_OVERLOAD_N(2, float2)
|
|
SHADER_PRINT_OVERLOAD_N(3, float3)
|
|
SHADER_PRINT_OVERLOAD_N(4, float4)
|
|
|
|
SHADER_PRINT_OVERLOAD_1(1, uint)
|
|
SHADER_PRINT_OVERLOAD_N(2, uint2)
|
|
SHADER_PRINT_OVERLOAD_N(3, uint3)
|
|
SHADER_PRINT_OVERLOAD_N(4, uint4)
|
|
|
|
SHADER_PRINT_OVERLOAD_1(1, int)
|
|
SHADER_PRINT_OVERLOAD_N(2, int2)
|
|
SHADER_PRINT_OVERLOAD_N(3, int3)
|
|
SHADER_PRINT_OVERLOAD_N(4, int4)
|
|
|
|
SHADER_PRINT_OVERLOAD_1(1, bool)
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Matrix type printing
|
|
|
|
#define SHADER_PRINT_OVERLOAD_NN(InNumComponentX, InNumComponentY, InType) \
|
|
float2 ShaderPrint(in float2 ScreenPos, in InType Value, in FFontColor Color) \
|
|
{ \
|
|
if (ShaderPrintFilterEnable) \
|
|
{ \
|
|
UNROLL \
|
|
for (uint CompY=0;CompY<InNumComponentY;++CompY) \
|
|
{ \
|
|
ScreenPos = ShaderPrint(ScreenPos, Value[CompY], Color); \
|
|
ScreenPos += float2(0.f, ShaderPrintUniform.FontSize.w); \
|
|
} \
|
|
} \
|
|
return ScreenPos; \
|
|
} \
|
|
float2 ShaderPrint(in float2 ScreenPos, in InType Value) \
|
|
{ \
|
|
if (ShaderPrintFilterEnable) \
|
|
{ \
|
|
UNROLL \
|
|
for (uint CompY = 0; CompY < InNumComponentY; ++CompY) \
|
|
{ \
|
|
ScreenPos = ShaderPrint(ScreenPos, Value[CompY], GetDefaultFontColor()); \
|
|
ScreenPos += float2(0.f, ShaderPrintUniform.FontSize.w); \
|
|
} \
|
|
} \
|
|
return ScreenPos; \
|
|
} \
|
|
void ShaderPrint(in InType Value, in FFontColor Color) \
|
|
{ \
|
|
if (ShaderPrintFilterEnable) \
|
|
{ \
|
|
UNROLL \
|
|
for (uint CompY = 0; CompY < InNumComponentY; ++CompY) \
|
|
{ \
|
|
ShaderPrintCursorPos = ShaderPrint(ShaderPrintCursorPos, Value[CompY], Color); \
|
|
ShaderPrintCursorPos += float2(0.f, ShaderPrintUniform.FontSize.w); \
|
|
} \
|
|
} \
|
|
} \
|
|
void ShaderPrint(in InType Value) \
|
|
{ \
|
|
if (ShaderPrintFilterEnable) \
|
|
{ \
|
|
UNROLL \
|
|
for (uint CompY = 0; CompY < InNumComponentY; ++CompY) \
|
|
{ \
|
|
ShaderPrintCursorPos = ShaderPrint(ShaderPrintCursorPos, Value[CompY], GetDefaultFontColor()); \
|
|
ShaderPrintCursorPos += float2(0.f, ShaderPrintUniform.FontSize.w); \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
SHADER_PRINT_OVERLOAD_NN(3, 3, float3x3)
|
|
SHADER_PRINT_OVERLOAD_NN(4, 3, float4x3)
|
|
SHADER_PRINT_OVERLOAD_NN(4, 4, float4x4)
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Formating helpers
|
|
|
|
float2 ShaderPrintSpace(in float2 ScreenPos, in float Count = 1)
|
|
{
|
|
if (ShaderPrintFilterEnable)
|
|
{
|
|
ScreenPos.x += ShaderPrintUniform.FontSize.z * Count;
|
|
}
|
|
return ScreenPos;
|
|
|
|
}
|
|
|
|
void ShaderPrintSpace(in float Count = 1)
|
|
{
|
|
ShaderPrintCursorPos = ShaderPrintSpace(ShaderPrintCursorPos, Count);
|
|
}
|
|
|
|
float2 ShaderPrintNewline(in float2 ScreenPos)
|
|
{
|
|
if (ShaderPrintFilterEnable)
|
|
{
|
|
ScreenPos.x = ShaderPrintCursorStart.x;
|
|
ScreenPos.y += ShaderPrintUniform.FontSize.w;
|
|
}
|
|
return ScreenPos;
|
|
}
|
|
|
|
void ShaderPrintNewline()
|
|
{
|
|
ShaderPrintCursorPos = ShaderPrintNewline(ShaderPrintCursorPos);
|
|
}
|
|
|
|
float2 ShaderPrintGetCursorPos()
|
|
{
|
|
return ShaderPrintCursorPos;
|
|
}
|
|
|
|
float2 ShaderPrintSetCursorPos(in float2 ScreenPos)
|
|
{
|
|
float2 PrevScreenPos = ShaderPrintCursorPos;
|
|
ShaderPrintCursorPos = ScreenPos;
|
|
return PrevScreenPos;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Filter helpers
|
|
// Use these to restrict ShaderPrint to a subset of active threads
|
|
// The filter functions can be called once at the start of the shader to filter all later printing
|
|
//
|
|
// Example use cases would be:
|
|
//
|
|
// ShaderPrintFilter(all(SvPosition.xy == float2(100, 100)));
|
|
// to debug a single pixel
|
|
//
|
|
// ShaderPrintFilter(all(DispatchThreadId == uint3(0, 0, 0)));
|
|
// to debug a single compute shader thread
|
|
//
|
|
// ShaderPrintFilterOneThread()
|
|
// to debug a single random active thread
|
|
// Note that ShaderPrintFilterOneThread() only works for one shader invocation in a view since it relies on a global memory location
|
|
|
|
void ShaderPrintFilter(bool bFilter)
|
|
{
|
|
ShaderPrintFilterEnable = bFilter;
|
|
}
|
|
|
|
void ShaderPrintFilterOneThread()
|
|
{
|
|
// Atomic flag is stored in first element .Type Value
|
|
uint PrevValue;
|
|
InterlockedCompareExchange(RWValuesBuffer[SHADER_PRINT_COUNT_OFFSET].TypeAndColor, 0, 1, PrevValue);
|
|
ShaderPrintFilter(PrevValue == 0);
|
|
} |