Skip to content

Commit 1333299

Browse files
Implement constant buffers for HDRP global variables. (#52)
* Fixed execution error without raytracing * Prepare Prepass refacto * Another round of preparation * Renamed XRPassScope to XRSinglePassScope * RenderAfterPostProcess is now static * Add AfterPostProcess to RenderGraph (WIP) * AfterPostProcess implementation * Fixed wrong RTHandle allocation * Fixed light layers texture binding during deferred lighting pass * Implemented Post Process Final Pass with RenderGraph * Post merge fixes * Fixed some issues with missing buffers in SSS and deferred lighting compute shaders. * Fixed alpha in post processes * Removed RenderGraphResource and RenderGraphMutableResource in favor of more explicit RendererListHandle and TextureHandle * Fixed decal normal patch pass * Fixed stencil resolve render pass * Fixed RenderDBuffer render pass function capturing variables. * Fixed wrong variable capture and restored ClearLightList to the render graph implementation of BuildGPULightList * Various fixes of things that diverged compared to regular path. * Unified renderer list and texture invalid handle error. * Revert wrong change * Added constant buffer hlsl generation * Changed UnityGlobal constant buffers to ShaderVariablesGlobals and generate it from C# * post merge fix * Removed useless comment. * Missing doc * Started moving cmd.SetGlobalXXX to update the global CB (WIP) * Implemented Volumetrics global CB and various fixes. * Implemented shadow global CB update. * Finished up Global Constant Buffer setup * Fix null ref * Fixed global constant buffer alignment issues. * Fixed shadows and SSS * Small ConstantBuffer API refacto * Small fix * Volumetric Constant Buffer implementation + Fix * Fix ambient occlusion * Removed redundant SetGlobalXXX * Light list build global CB implementation * Fixed path tracing frame index constant * Fixed ao constant w/ raytracing * Better path tracing fix. * Refactored CB API to comply with Render Graph specificities * Update test screenshot * Fixed constant buffer generation to use macros. * Fixed color/depth pyramid debug * Cleanup * Small fix * Post merge fix * Added global constant buffer hlsl generation. * Post merge fix * Post merge fix * Post merge fix 2 * Double inclusion fix. * Fixed CB visibility * Indentation fix * Removed temporary comments. * Moved some constants around. * Post merge fix + Port ProbeVolume global variables to constant buffers. * Fixed deallocation of constant buffers * Properly release Volumetric constant buffers. * Another update to CB API * Updated documentation.
1 parent 2ccd42a commit 1333299

File tree

86 files changed

+1446
-1751
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+1446
-1751
lines changed

TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/8x_ShaderGraph/8105_BlendStates/HairGraph/HairGraphBackThenFrontRendering.shadergraph

Lines changed: 13 additions & 10 deletions
Large diffs are not rendered by default.
Lines changed: 2 additions & 2 deletions
Loading

com.unity.render-pipelines.core/Editor/ShaderGenerator/ShaderTypeGeneration.cs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,15 @@ public string EmitTypeDecl()
407407

408408
shaderText += "// Generated from " + type.FullName + "\n";
409409
shaderText += "// PackingRules = " + attr.packingRules.ToString() + "\n";
410-
if (!attr.omitStructDeclaration)
410+
411+
if (attr.generateCBuffer)
412+
{
413+
if (attr.constantRegister != -1)
414+
shaderText += "GLOBAL_CBUFFER_START(" + type.Name + ", b" + attr.constantRegister + ")\n";
415+
else
416+
shaderText += "CBUFFER_START(" + type.Name + ")\n";
417+
}
418+
else if (!attr.omitStructDeclaration)
411419
{
412420
shaderText += "struct " + type.Name + "\n";
413421
shaderText += "{\n";
@@ -418,7 +426,11 @@ public string EmitTypeDecl()
418426
shaderText += " " + shaderFieldInfo.ToString() + "\n";
419427
}
420428

421-
if (!attr.omitStructDeclaration)
429+
if (attr.generateCBuffer)
430+
{
431+
shaderText += "CBUFFER_END\n";
432+
}
433+
else if (!attr.omitStructDeclaration)
422434
{
423435
shaderText += "};\n";
424436
}
@@ -764,6 +776,10 @@ private string EmitPackedGetters()
764776
{
765777
funcSignature = "float4 " + funcSignature;
766778
}
779+
else if (packedInfo.fieldType == typeof(Vector2Int))
780+
{
781+
funcSignature = "int2 " + funcSignature;
782+
}
767783
funcBody += "return (" + sourceName + "." + packedInfo.fieldName + ");";
768784
break;
769785
default:
@@ -850,6 +866,10 @@ private string EmitPackedSetters()
850866
{
851867
funcSignature += "float4 " + newParamName + ", inout " + type.Name + " " + sourceName + ")";
852868
}
869+
else if (packedInfo.fieldType == typeof(Vector2Int))
870+
{
871+
funcSignature += "int2 " + newParamName + ", inout " + type.Name + " " + sourceName + ")";
872+
}
853873
funcBody += sourceName + "." + packedInfo.fieldName + " = " + newParamName + ";";
854874
break;
855875
default:
@@ -939,6 +959,10 @@ private string EmitPackedInit()
939959
{
940960
funcSignature += "float4 " + newParamName + ", inout " + type.Name + " " + sourceName + ")";
941961
}
962+
else if (packedInfo.fieldType == typeof(Vector2Int))
963+
{
964+
funcSignature += "int2 " + newParamName + ", inout " + type.Name + " " + sourceName + ")";
965+
}
942966
funcBody += sourceName + "." + packedInfo.fieldName + " = " + newParamName + ";";
943967
break;
944968
default:
@@ -1015,6 +1039,16 @@ public bool Generate()
10151039
var arrayInfos = (field.GetCustomAttributes(typeof(HLSLArray), false) as HLSLArray[]);
10161040
if (arrayInfos.Length != 0)
10171041
{
1042+
// For constant buffers, every element of the array needs to be aligned to a Vector4
1043+
if (attr.generateCBuffer &&
1044+
arrayInfos[0].elementType != typeof(Vector4) &&
1045+
arrayInfos[0].elementType != typeof(ShaderGenUInt4) &&
1046+
arrayInfos[0].elementType != typeof(Matrix4x4))
1047+
{
1048+
Error("Invalid HLSLArray target: '" + field.FieldType + "'" + ", only Vector4, Matrix4x4 and ShaderGenUInt4 are supported for arrays in constant buffers.");
1049+
return false;
1050+
}
1051+
10181052
arraySize = arrayInfos[0].arraySize;
10191053
fieldType = arrayInfos[0].elementType;
10201054
}
@@ -1171,6 +1205,10 @@ public bool Generate()
11711205
EmitPrimitiveType(floatPrecision, 3, arraySize, field.Name, "", m_ShaderFields);
11721206
else if (fieldType == typeof(Vector4))
11731207
EmitPrimitiveType(floatPrecision, 4, arraySize, field.Name, "", m_ShaderFields);
1208+
else if (fieldType == typeof(Vector2Int))
1209+
EmitPrimitiveType(PrimitiveType.Int, 2, arraySize, field.Name, "", m_ShaderFields);
1210+
else if (fieldType == typeof(ShaderGenUInt4))
1211+
EmitPrimitiveType(PrimitiveType.UInt, 4, arraySize, field.Name, "", m_ShaderFields);
11741212
else if (fieldType == typeof(Matrix4x4))
11751213
EmitMatrixType(floatPrecision, 4, 4, arraySize, field.Name, "", m_ShaderFields);
11761214
else if (!ExtractComplex(field, m_ShaderFields))
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
using System.Collections.Generic;
2+
using Unity.Collections.LowLevel.Unsafe;
3+
4+
namespace UnityEngine.Rendering
5+
{
6+
/// <summary>
7+
/// Constant Buffer management class.
8+
/// </summary>
9+
public class ConstantBuffer
10+
{
11+
static List<ConstantBufferBase> m_RegisteredConstantBuffers = new List<ConstantBufferBase>();
12+
13+
/// <summary>
14+
/// Update the GPU data of the constant buffer and bind it globally.
15+
/// </summary>
16+
/// <typeparam name="CBType">The type of structure representing the constant buffer data.</typeparam>
17+
/// <param name="cmd">Command Buffer used to execute the graphic commands.</param>
18+
/// <param name="data">Input data of the constant buffer.</param>
19+
/// <param name="shaderId">Shader porperty id to bind the constant buffer to.</param>
20+
public static void PushGlobal<CBType>(CommandBuffer cmd, in CBType data, int shaderId) where CBType : struct
21+
{
22+
var cb = TypedConstantBuffer<CBType>.instance;
23+
24+
cb.UpdateData(cmd, data);
25+
cb.SetGlobal(cmd, shaderId);
26+
}
27+
28+
/// <summary>
29+
/// Update the GPU data of the constant buffer and bind it to a compute shader.
30+
/// </summary>
31+
/// <typeparam name="CBType">The type of structure representing the constant buffer data.</typeparam>
32+
/// <param name="cmd">Command Buffer used to execute the graphic commands.</param>
33+
/// <param name="data">Input data of the constant buffer.</param>
34+
/// <param name="cs">Compute shader to which the constant buffer should be bound.</param>
35+
/// <param name="shaderId">Shader porperty id to bind the constant buffer to.</param>
36+
public static void Push<CBType>(CommandBuffer cmd, in CBType data, ComputeShader cs, int shaderId) where CBType : struct
37+
{
38+
var cb = TypedConstantBuffer<CBType>.instance;
39+
40+
cb.UpdateData(cmd, data);
41+
cb.Set(cmd, cs, shaderId);
42+
}
43+
44+
/// <summary>
45+
/// Update the GPU data of the constant buffer and bind it to a material.
46+
/// </summary>
47+
/// <typeparam name="CBType">The type of structure representing the constant buffer data.</typeparam>
48+
/// <param name="cmd">Command Buffer used to execute the graphic commands.</param>
49+
/// <param name="data">Input data of the constant buffer.</param>
50+
/// <param name="mat">Material to which the constant buffer should be bound.</param>
51+
/// <param name="shaderId">Shader porperty id to bind the constant buffer to.</param>
52+
public static void Push<CBType>(CommandBuffer cmd, in CBType data, Material mat, int shaderId) where CBType : struct
53+
{
54+
var cb = TypedConstantBuffer<CBType>.instance;
55+
56+
cb.UpdateData(cmd, data);
57+
cb.Set(mat, shaderId);
58+
}
59+
60+
/// <summary>
61+
/// Update the GPU data of the constant buffer.
62+
/// </summary>
63+
/// <typeparam name="CBType">The type of structure representing the constant buffer data.</typeparam>
64+
/// <param name="cmd">Command Buffer used to execute the graphic commands.</param>
65+
/// <param name="data">Input data of the constant buffer.</param>
66+
public static void UpdateData<CBType>(CommandBuffer cmd, in CBType data) where CBType : struct
67+
{
68+
var cb = TypedConstantBuffer<CBType>.instance;
69+
70+
cb.UpdateData(cmd, data);
71+
}
72+
73+
/// <summary>
74+
/// Bind the constant buffer globally.
75+
/// </summary>
76+
/// <typeparam name="CBType">The type of structure representing the constant buffer data.</typeparam>
77+
/// <param name="cmd">Command Buffer used to execute the graphic commands.</param>
78+
/// <param name="shaderId">Shader porperty id to bind the constant buffer to.</param>
79+
public static void SetGlobal<CBType>(CommandBuffer cmd, int shaderId) where CBType : struct
80+
{
81+
var cb = TypedConstantBuffer<CBType>.instance;
82+
83+
cb.SetGlobal(cmd, shaderId);
84+
}
85+
86+
/// <summary>
87+
/// Bind the constant buffer to a compute shader.
88+
/// </summary>
89+
/// <typeparam name="CBType">The type of structure representing the constant buffer data.</typeparam>
90+
/// <param name="cmd">Command Buffer used to execute the graphic commands.</param>
91+
/// <param name="cs">Compute shader to which the constant buffer should be bound.</param>
92+
/// <param name="shaderId">Shader porperty id to bind the constant buffer to.</param>
93+
public static void Set<CBType>(CommandBuffer cmd, ComputeShader cs, int shaderId) where CBType : struct
94+
{
95+
var cb = TypedConstantBuffer<CBType>.instance;
96+
97+
cb.Set(cmd, cs, shaderId);
98+
}
99+
100+
/// <summary>
101+
/// Bind the constant buffer to a material.
102+
/// </summary>
103+
/// <typeparam name="CBType">The type of structure representing the constant buffer data.</typeparam>
104+
/// <param name="mat">Material to which the constant buffer should be bound.</param>
105+
/// <param name="shaderId">Shader porperty id to bind the constant buffer to.</param>
106+
public static void Set<CBType>(Material mat, int shaderId) where CBType : struct
107+
{
108+
var cb = TypedConstantBuffer<CBType>.instance;
109+
110+
cb.Set(mat, shaderId);
111+
}
112+
113+
/// <summary>
114+
/// Release all currently allocated constant buffers.
115+
/// This needs to be called before shutting down the application.
116+
/// </summary>
117+
public static void ReleaseAll()
118+
{
119+
foreach (var cb in m_RegisteredConstantBuffers)
120+
cb.Release();
121+
122+
m_RegisteredConstantBuffers.Clear();
123+
}
124+
125+
internal abstract class ConstantBufferBase
126+
{
127+
public abstract void Release();
128+
}
129+
130+
internal static void Register(ConstantBufferBase cb)
131+
{
132+
m_RegisteredConstantBuffers.Add(cb);
133+
}
134+
135+
class TypedConstantBuffer<CBType> : ConstantBufferBase where CBType : struct
136+
{
137+
CBType[] m_Data = new CBType[1]; // Array is required by the ComputeBuffer SetData API
138+
static TypedConstantBuffer<CBType> s_Instance = null;
139+
internal static TypedConstantBuffer<CBType> instance
140+
{
141+
get
142+
{
143+
if (s_Instance == null)
144+
s_Instance = new TypedConstantBuffer<CBType>();
145+
return s_Instance;
146+
}
147+
set
148+
{
149+
s_Instance = value;
150+
}
151+
}
152+
ComputeBuffer m_GPUConstantBuffer = null;
153+
154+
TypedConstantBuffer()
155+
{
156+
m_GPUConstantBuffer = new ComputeBuffer(1, UnsafeUtility.SizeOf<CBType>(), ComputeBufferType.Constant);
157+
ConstantBuffer.Register(this);
158+
}
159+
160+
public void UpdateData(CommandBuffer cmd, in CBType data)
161+
{
162+
m_Data[0] = data;
163+
cmd.SetComputeBufferData(m_GPUConstantBuffer, m_Data);
164+
}
165+
166+
public void SetGlobal(CommandBuffer cmd, int shaderId)
167+
{
168+
cmd.SetGlobalConstantBuffer(m_GPUConstantBuffer, shaderId, 0, m_GPUConstantBuffer.stride);
169+
}
170+
171+
public void Set(CommandBuffer cmd, ComputeShader cs, int shaderId)
172+
{
173+
cmd.SetComputeConstantBufferParam(cs, shaderId, m_GPUConstantBuffer, 0, m_GPUConstantBuffer.stride);
174+
}
175+
176+
public void Set(Material mat, int shaderId)
177+
{
178+
// This isn't done via command buffer because as long as the buffer itself is not destroyed,
179+
// the binding stays valid. Only the commit of data needs to go through the command buffer.
180+
// We do it here anyway for now to simplify user API.
181+
mat.SetConstantBuffer(shaderId, m_GPUConstantBuffer, 0, m_GPUConstantBuffer.stride);
182+
}
183+
184+
public override void Release()
185+
{
186+
CoreUtils.SafeRelease(m_GPUConstantBuffer);
187+
s_Instance = null;
188+
}
189+
}
190+
}
191+
}
Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

com.unity.render-pipelines.core/Runtime/ShaderGenerator/ShaderGeneratorAttributes.cs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ public class GenerateHLSL : System.Attribute
9494
/// Generate structure declaration or not.
9595
/// </summary>
9696
public bool omitStructDeclaration;
97+
/// <summary>
98+
/// Generate constant buffer declaration or not.
99+
/// </summary>
100+
public bool generateCBuffer;
101+
/// <summary>
102+
/// If specified, when generating a constant buffer, use this explicit register.
103+
/// </summary>
104+
public int constantRegister;
97105

98106
/// <summary>
99107
/// GenerateHLSL attribute constructor.
@@ -105,7 +113,10 @@ public class GenerateHLSL : System.Attribute
105113
/// <param name="paramDefinesStart">Start value of debug defines.</param>
106114
/// <param name="omitStructDeclaration">Omit structure declaration.</param>
107115
/// <param name="containsPackedFields">Contains packed fields.</param>
108-
public GenerateHLSL(PackingRules rules = PackingRules.Exact, bool needAccessors = true, bool needSetters = false, bool needParamDebug = false, int paramDefinesStart = 1, bool omitStructDeclaration = false, bool containsPackedFields = false)
116+
/// <param name="generateCBuffer">Generate a constant buffer.</param>
117+
/// <param name="constantRegister">When generating a constant buffer, specify the optional constant register.</param>
118+
public GenerateHLSL(PackingRules rules = PackingRules.Exact, bool needAccessors = true, bool needSetters = false, bool needParamDebug = false, int paramDefinesStart = 1,
119+
bool omitStructDeclaration = false, bool containsPackedFields = false, bool generateCBuffer = false, int constantRegister = -1)
109120
{
110121
packingRules = rules;
111122
this.needAccessors = needAccessors;
@@ -114,6 +125,8 @@ public GenerateHLSL(PackingRules rules = PackingRules.Exact, bool needAccessors
114125
this.paramDefinesStart = paramDefinesStart;
115126
this.omitStructDeclaration = omitStructDeclaration;
116127
this.containsPackedFields = containsPackedFields;
128+
this.generateCBuffer = generateCBuffer;
129+
this.constantRegister = constantRegister;
117130
}
118131
}
119132

@@ -183,7 +196,7 @@ public class HLSLArray : System.Attribute
183196
/// <summary>
184197
/// Size of the array.
185198
/// </summary>
186-
public int arraySize;
199+
public int arraySize;
187200
/// <summary>
188201
/// Type of the array elements.
189202
/// </summary>
@@ -282,5 +295,11 @@ public PackingAttribute(string displayName = "", FieldPacking packingScheme = Fi
282295
}
283296
}
284297

298+
/// <summary>
299+
/// This type needs to be used when generating unsigned integer arrays for constant buffers.
300+
/// </summary>
301+
public struct ShaderGenUInt4
302+
{
285303

304+
}
286305
}

com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/AxfSurfaceInputsUIBlock.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,6 @@ void DrawAxfSurfaceOptionsGUI()
426426
BRDFVariants |= ((uint)wardVariant) << 2;
427427
BRDFVariants |= ((uint)blinnVariant) << 4;
428428

429-
// cmd.SetGlobalFloat( HDShaderIDs._TexturingModeFlags, *(float*) &texturingModeFlags );
430429
m_SVBRDF_BRDFType.floatValue = (float)BRDFType;
431430
m_SVBRDF_BRDFVariants.floatValue = (float)BRDFVariants;
432431

@@ -488,8 +487,6 @@ void DrawAxfSurfaceOptionsGUI()
488487
clearcoatRefraction = EditorGUILayout.Toggle("Enable Refraction", clearcoatRefraction);
489488
}
490489

491-
// cmd.SetGlobalFloat( HDShaderIDs._TexturingModeFlags, *(float*) &texturingModeFlags );
492-
493490
--EditorGUI.indentLevel;
494491
break;
495492
}

0 commit comments

Comments
 (0)