Refactored Effects + start of EngineBuffers (I hate it)

This commit is contained in:
Simon Lübeß
2022-06-07 13:12:03 +02:00
parent a80018e80c
commit 866353a157
16 changed files with 282 additions and 217 deletions
+1 -1
View File
@@ -13,4 +13,4 @@ uint PS(float4 input : SV_Position) : SV_Target0
return ClearValue;
}
#effect[VS = VS, PS = PS]
#pragma Effect[VS = VS; PS = PS]
@@ -30,4 +30,4 @@ float4 PS(PS_IN input) : SV_TARGET
return float4(pow(color.rgb, 1.0f / 2.2f), color.a);
}
#effect[VS = VS, PS = PS]
#pragma Effect[VS = VS; PS = PS]
@@ -32,4 +32,4 @@ float4 PS(PS_IN input) : SV_TARGET
return float4(color, 1);
}
#effect[VS = VS, PS = PS]
#pragma Effect[VS = VS; PS = PS]
@@ -59,4 +59,4 @@ float4 PS(PS_Input input) : SV_Target0
return color;
}
#effect[VS=VS, PS=PS]
#pragma Effect[VS=VS; PS=PS]
@@ -28,4 +28,4 @@ float4 PS(PS_Input input) : SV_Target0
return Color;
}
#effect[VS=VS, PS=PS]
#pragma Effect[VS=VS; PS=PS]
@@ -90,4 +90,4 @@ float4 PS(PS_Input input) : SV_Target0
}
*/
#effect[VS=VS, PS=PS]
#pragma Effect[VS=VS; PS=PS]
+10 -8
View File
@@ -17,12 +17,14 @@ SamplerState RoughnessSampler : register(s3);
// Texture2D<float> AmbientTexture : register(t4);
// SamplerState AmbientSampler : register(s4);
cbuffer SceneConstants
#pragma EngineBuffer[ Name = "SceneConstants"; Binding = "Scene" ]
cbuffer SceneConstants : register(b0)
{
float4x4 ViewProjection;
}
cbuffer ObjectConstants
#pragma EngineBuffer[ Name = "ObjectConstants"; Binding = "Object" ]
cbuffer ObjectConstants : register(b1)
{
float4x4 Transform;
/**
@@ -35,15 +37,15 @@ cbuffer ObjectConstants
#endif
}
cbuffer Constants
cbuffer MaterialConstants : register(b2)
{
#EditorVariable{ Name = "AlbedoColor"; Preview = "Albedo Color"; Type="Color" }
#pragma EditorVariable[ Name = "AlbedoColor"; Preview = "Albedo Color"; Type="Color" ]
float4 AlbedoColor = float4(1.0, 1.0, 1.0, 1.0);
#EditorVariable{ Name = "NormalScaling"; Preview = "Normal Scaling" }
#pragma EditorVariable[ Name = "NormalScaling"; Preview = "Normal Scaling" ]
float2 NormalScaling = float2(1.0, 1.0);
#EditorVariable{ Name = "MetallicFactor"; Preview = "Metallic Factor"; Min = 0.0f; Max = 1.0f }
#pragma EditorVariable[ Name = "MetallicFactor"; Preview = "Metallic Factor"; Min = 0.0f; Max = 1.0f ]
float MetallicFactor = 1.0;
#EditorVariable{ Name = "RoughnessFactor"; Preview = "Rougness Factor"; Min = 0.0f; Max = 1.0f }
#pragma EditorVariable[ Name = "RoughnessFactor"; Preview = "Rougness Factor"; Min = 0.0f; Max = 1.0f ]
float RoughnessFactor = 1.0;
// float AmbientFactor = 1.0;
}
@@ -154,4 +156,4 @@ PS_OUT PS(PS_IN input)
return output;
}
#effect[VS=VS,PS=PS]
#pragma Effect[VS = VS; PS = PS]
@@ -123,4 +123,4 @@ float4 PS(PS_IN input) : SV_TARGET
return float4(final, 1);
}
#effect[VS=VS,PS=PS]
#pragma Effect[VS = VS; PS = PS]
@@ -71,4 +71,4 @@ PS_Output PS(PS_Input input)
return output;
}
#effect[VS=VS, PS=PS]
#pragma Effect[VS = VS; PS = PS]
@@ -49,4 +49,4 @@ float4 PS(PS_Input input) : SV_Target0
return final;
}
#effect[VS=VS, PS=PS]
#pragma Effect[VS=VS; PS=PS]
@@ -14,6 +14,9 @@ namespace GlitchyEngine.Renderer
{
Debug.Profiler.ProfileRendererFunction!();
// Clear
nativeBuffers = .();
for(let buffer in _buffers)
{
nativeBuffers[buffer.Index] = buffer.Buffer.nativeBuffer;
@@ -261,51 +261,53 @@ namespace GlitchyEngine.Renderer
_firstTexture = entry.Index;
}
if(_textureCount > 0)
{
shader.Buffers.PlatformFetchNativeBuffers();
//if (_textureCount > 0)
//{
switch (typeof(TShader))
{
// TODO: Add remaining shader stages
case typeof(PixelShader):
// TODO: bind uavs
if (_textureCount > 0)
{
NativeContext.PixelShader.SetShaderResources(_firstTexture, _textureCount, &_textures[_firstTexture]);
NativeContext.PixelShader.SetSamplers(_firstTexture, _textureCount, &_samplers[_firstTexture]);
}
_ps_FirstTexture = _firstTexture;
_ps_BoundTextures = _textureCount;
NativeContext.PixelShader.SetConstantBuffers(0, shader.Buffers.nativeBuffers.Count, &shader.Buffers.nativeBuffers);
NativeContext.PixelShader.SetShader((ID3D11PixelShader*)shader.nativeShader);
case typeof(VertexShader):
if (_textureCount > 0)
{
NativeContext.VertexShader.SetShaderResources(_firstTexture, _textureCount, &_textures[_firstTexture]);
NativeContext.VertexShader.SetSamplers(_firstTexture, _textureCount, &_samplers[_firstTexture]);
}
NativeContext.VertexShader.SetConstantBuffers(0, shader.Buffers.nativeBuffers.Count, &shader.Buffers.nativeBuffers);
NativeContext.VertexShader.SetShader((ID3D11VertexShader*)shader.nativeShader);
_vs_FirstTexture = _firstTexture;
_vs_BoundTextures = _textureCount;
default:
Runtime.FatalError(scope $"Shader stage \"{typeof(TShader)}\" not implemented.");
}
}
shader.Buffers.PlatformFetchNativeBuffers();
switch(typeof(TShader))
//if (VertexShader vs = shader as VertexShader)
[ConstSkip]
{
// TODO: Add remaining shader stages
case typeof(PixelShader):
NativeContext.PixelShader.SetConstantBuffers(0, shader.Buffers.nativeBuffers.Count, &shader.Buffers.nativeBuffers);
NativeContext.PixelShader.SetShader((ID3D11PixelShader*)shader.nativeShader);
case typeof(VertexShader):
NativeContext.VertexShader.SetConstantBuffers(0, shader.Buffers.nativeBuffers.Count, &shader.Buffers.nativeBuffers);
NativeContext.VertexShader.SetShader((ID3D11VertexShader*)shader.nativeShader);
if (VertexShader vs = shader as VertexShader)
{
SetReference!(_currentVertexShader, vs);
SetReference!(_currentVertexShader, shader);
_currentInputLayout?.Release();
_currentInputLayout = null;
}
default:
Runtime.FatalError(scope $"Shader stage \"{typeof(TShader)}\" not implemented.");
}
//}
}
public override void UnbindTextures()
@@ -1,9 +1,10 @@
using System;
using System.Collections;
using GlitchyEngine.Core;
namespace GlitchyEngine.Renderer
{
public class BufferCollection : IEnumerable<(String Name, int Index, Buffer Buffer)>
public class BufferCollection : RefCounter, IEnumerable<(String Name, int Index, Buffer Buffer)>
{
public typealias BufferEntry = (String Name, int Index, Buffer Buffer);
@@ -124,10 +125,7 @@ namespace GlitchyEngine.Renderer
{
Log.EngineLogger.AssertDebug(name == bufferEntry.Name);
bufferEntry.Buffer.ReleaseRef();
buffer.AddRef();
bufferEntry.Buffer = buffer;
SetReference!(bufferEntry.Buffer, buffer);
return true;
}
+168 -148
View File
@@ -120,7 +120,9 @@ namespace GlitchyEngine.Renderer
delete _;
};
BufferCollection _bufferCollection ~ delete _;
protected Dictionary<String, String> _engineBuffers ~ DeleteDictionaryAndKeysAndValues!(_);
BufferCollection _bufferCollection ~ _.ReleaseRef();
BufferVariableCollection _variables ~ delete _;
@@ -132,23 +134,13 @@ namespace GlitchyEngine.Renderer
public VertexShader VertexShader
{
get => _vs;
set
{
_vs?.ReleaseRef();
_vs = value;
_vs?.AddRef();
}
private set => SetReference!(_vs, value);
}
public PixelShader PixelShader
{
get => _ps;
set
{
_ps?.ReleaseRef();
_ps = value;
_ps?.AddRef();
}
private set => SetReference!(_ps, value);
}
public BufferCollection Buffers => _bufferCollection;
@@ -156,28 +148,6 @@ namespace GlitchyEngine.Renderer
public String Name => _name;
[Obsolete("Will be removed in the future", false)]
public this()
{
}
public this(String filename, String vsEntry, String psEntry, String shaderName = null)
{
Debug.Profiler.ProfileResourceFunction!();
CompileFromFile(filename, vsEntry, psEntry);
if(shaderName == null)
{
_name = new String(shaderName);
}
else
{
_name = new String();
Path.GetFileNameWithoutExtension(filename, _name);
}
}
public this(String filename, String shaderName = null)
{
Debug.Profiler.ProfileResourceFunction!();
@@ -187,8 +157,9 @@ namespace GlitchyEngine.Renderer
String psName = scope String();
_variableDescriptions = new VariableDesc();
_engineBuffers = new Dictionary<String, String>();
ProcessFile(filename, fileContent, vsName, psName, _variableDescriptions);
ProcessFile(filename, fileContent, vsName, psName, _variableDescriptions, _engineBuffers);
Compile(fileContent, filename, vsName, psName);
@@ -205,15 +176,6 @@ namespace GlitchyEngine.Renderer
}
}
public this(String shaderName, String vsPath, String vsEntry, String psPath, String psEntry)
{
Debug.Profiler.ProfileResourceFunction!();
Compile(vsPath, vsEntry, psPath, psEntry);
_name = new String(shaderName);
}
public ~this()
{
Debug.Profiler.ProfileResourceFunction!();
@@ -298,8 +260,6 @@ namespace GlitchyEngine.Renderer
context.SetPixelShader(_ps);
}
private void CompileFromFile(String filename, String vsEntry, String psEntry)
{
Debug.Profiler.ProfileResourceFunction!();
@@ -333,6 +293,81 @@ namespace GlitchyEngine.Renderer
code[commentPosition + 1] = '/';
}
private static Result<(int Start, int End)> GetNextPreprocessor(StringView code, int startindex, out StringView name, Dictionary<StringView, StringView> arguments)
{
name = .();
int startOfLine;
int endOfLine;
do
{
startOfLine = code.IndexOf("#pragma", startindex);
if (startOfLine == -1)
return .Err;
endOfLine = code.IndexOf('\n', startOfLine);
StringView line = (endOfLine != -1) ? code.Substring(startOfLine, endOfLine - startOfLine) : code.Substring(startOfLine);
// cut off the #pragma
line = line.Substring(7);
int lBracketIndex = line.IndexOf('[');
if (lBracketIndex == -1)
{
name = line..Trim();
break;
}
name = line.Substring(0, lBracketIndex);
name.Trim();
int rBracketIndex = line.IndexOf(']');
if (rBracketIndex == -1)
{
Log.EngineLogger.Error($"Pragma is missing closing Bracket (\"{line}\")");
rBracketIndex = line.Length;
}
StringView argumentText = line.Substring(lBracketIndex + 1, rBracketIndex - lBracketIndex - 1);
for (StringView argument in argumentText.Split(';'))
{
int equalsIndex = argument.IndexOf('=');
StringView argumentName = .();
StringView argumentValue = .();
if (equalsIndex == -1)
{
argumentName = argument;
argumentName.Trim();
}
else
{
argumentName = argument.Substring(0, equalsIndex);
argumentName.Trim();
argumentValue = argument.Substring(equalsIndex + 1);
argumentValue.Trim();
}
if (arguments.ContainsKey(argumentName))
{
Log.EngineLogger.Error($"Arguments \"{argumentName}\" already exists.");
continue;
}
arguments.Add(argumentName, argumentValue);
}
}
return .Ok((startOfLine, endOfLine));
}
/**
* Loads the effect file and extracts the names of the vertex- and pixel-shader.
* @param filename The path of the effect file.
@@ -341,7 +376,7 @@ namespace GlitchyEngine.Renderer
* @param outPsName The string that will receive the pixel shader entry point.
* @param outVarDescs The dictionary that will contain the Variable descriptions.
*/
private static void ProcessFile(String filename, String fileContent, String outVsName, String outPsName, VariableDesc outVarDescs)
private static void ProcessFile(String filename, String fileContent, String outVsName, String outPsName, VariableDesc outVarDescs, Dictionary<String, String> outEngineBuffers)
{
Debug.Profiler.ProfileResourceFunction!();
@@ -349,125 +384,101 @@ namespace GlitchyEngine.Renderer
// append line ending just in case the file doesn't end with one.
fileContent.Append('\n');
ProcessEditorVariables(filename, fileContent, outVarDescs);
int effectIndex = fileContent.IndexOf(effectKeyword, true);
Log.EngineLogger.Assert(effectIndex >= 0, "Could not find #effect preprocessor directive.");
int lineEndIndex = fileContent.IndexOf('\n', effectIndex + effectKeyword.Length);
// String containing the #effect directive
StringView effectDirective = fileContent.Substring(effectIndex, lineEndIndex - effectIndex);
int paramStartIndex = effectDirective.IndexOf('[');
Log.EngineLogger.Assert(paramStartIndex >= 0, "Expected '[' after \"#effect\"");
StringView effectToBracket = effectDirective.Substring(effectKeyword.Length, paramStartIndex - effectKeyword.Length);
// Make sure there is only whitespace between "#effect" and "["
Log.EngineLogger.Assert(effectToBracket.IsWhiteSpace, "Expected '[' after \"#effect\"");
int paramEndIndex = effectDirective.IndexOf(']');
Log.EngineLogger.Assert(paramEndIndex >= 0, "Expected ']'");
StringView parameters = effectDirective.Substring(paramStartIndex + 1, paramEndIndex - paramStartIndex - 1);
for(StringView parameter in parameters.Split(','))
{
int indexOfEquals = parameter.IndexOf("=");
Dictionary<StringView, StringView> arguments = scope .();
Log.EngineLogger.Assert(indexOfEquals >= 0, "Expected '='");
StringView paramName = parameter.Substring(0, indexOfEquals);
paramName.Trim();
StringView paramValue = parameter.Substring(indexOfEquals + 1);
paramValue.Trim();
switch(paramName)
{
case "VS", "VertexShader":
outVsName.Append(paramValue);
case "PS", "PixelShader":
outPsName.Append(paramValue);
default:
Log.EngineLogger.Assert(false, scope $"Unknown parameter name \"{paramName}\".");
}
}
// remove preprocessor directive from string so that the compiler wont try process it
CommentLine(fileContent, effectIndex);
}
private static void ProcessEditorVariables(StringView fileName, StringView code, VariableDesc outVarDescs)
{
int index = 0;
while (true)
{
index = code.IndexOf("#EditorVariable", index);
Result<(int Start, int End)> result = GetNextPreprocessor(fileContent, index, let name, arguments..Clear());
if (index == -1)
if (result case .Err)
break;
CommentLine(code, index);
index = code.IndexOf('{', index);
Log.EngineLogger.AssertDebug(index != -1, "Missing '{'.");
index++;
int endIndex = code.IndexOf('}', index);
Log.EngineLogger.AssertDebug(endIndex != -1, "Missing '}'.");
StringView variableInfo = StringView(code, index, endIndex - index);
Log.ClientLogger.Info($"Found variable: \"{variableInfo}\"");
Dictionary<String, Variant> parameters = new .();
String variableName = null;
for (StringView argument in variableInfo.Split(';', .RemoveEmptyEntries))
else if (result case .Ok(let value))
{
int equalsIndex = argument.IndexOf('=');
index = value.End;
if (equalsIndex == -1)
switch(name)
{
Log.EngineLogger.Error($"Missing value for Argument \"{argument..Trim()}\".");
case "Effect":
for (let (argName, argValue) in arguments)
{
switch(argName)
{
case "VS", "VertexShader":
outVsName.Append(argValue);
case "PS", "PixelShader":
outPsName.Append(argValue);
default:
Log.EngineLogger.Assert(false, scope $"Unknown parameter name \"{name}\".");
}
}
case "EditorVariable":
ProcessEditorVariables(arguments, outVarDescs);
case "EngineBuffer":
ProcessEngineBuffer(arguments, outEngineBuffers);
default:
continue;
}
else
{
StringView argName = argument.Substring(0, equalsIndex)..Trim();
StringView argValue = argument.Substring(equalsIndex + 1)..Trim();
CommentLine(fileContent, value.Start);
}
}
}
}
private static void ProcessEngineBuffer(Dictionary<StringView, StringView> arguments, Dictionary<String, String> outEngineBuffers)
{
String nameInEngine = null;
String nameInShader = null;
for (var (argName, argValue) in arguments)
{
if (argValue.StartsWith('"') && argValue.EndsWith('"'))
{
argValue = argValue[1...^2];
}
if (argName == "Name")
variableName = new String(argValue);
else
switch (argName)
{
Variant value;
if (argName == "Min" || argName == "Max")
{
value = ParseVariableValue(argValue);
case "Name":
nameInShader = new String(argValue);
case "Binding":
nameInEngine = new String(argValue);
default:
Log.EngineLogger.Assert(false, scope $"Unknown parameter for EngineBuffer: \"{argName}\".");
}
else
{
value = Variant.Create(new String(argValue), true);
}
parameters.Add(new String(argName), value);
Log.EngineLogger.AssertDebug(nameInEngine != null);
Log.EngineLogger.AssertDebug(nameInShader != null);
outEngineBuffers.Add(nameInEngine, nameInShader);
}
private static void ProcessEditorVariables(Dictionary<StringView, StringView> arguments, VariableDesc outVarDescs)
{
String variableName = null;
Dictionary<String, Variant> parameters = new .();
for (var (name, value) in arguments)
{
if (value.StartsWith('"') && value.EndsWith('"'))
{
value = value[1...^2];
}
switch(name)
{
case "Name":
variableName = new String(value);
case "Min", "Max":
Variant paramValue = ParseVariableValue(value);
parameters.Add(new String(name), paramValue);
default:
Variant paramValue = Variant.Create(new String(value), true);
parameters.Add(new String(name), paramValue);
}
}
@@ -475,8 +486,6 @@ namespace GlitchyEngine.Renderer
outVarDescs.Add(variableName, parameters);
index = endIndex;
}
}
private static Variant ParseVariableValue(StringView valueString)
@@ -613,6 +622,9 @@ namespace GlitchyEngine.Renderer
internalIndex++;
}
SetReference!(_vs.[Friend]_buffers, _bufferCollection);
SetReference!(_ps.[Friend]_buffers, _bufferCollection);
}
private void MergeBufferVariables()
@@ -621,8 +633,16 @@ namespace GlitchyEngine.Renderer
_variables = new BufferVariableCollection(false);
for(let buffer in _bufferCollection)
outer: for(let buffer in _bufferCollection)
{
for (let eb in _engineBuffers)
{
if (eb.value == buffer.Name)
{
continue outer;
}
}
if(let cbuffer = buffer.Buffer as ConstantBuffer)
{
for(let variable in cbuffer.Variables)
+42 -2
View File
@@ -93,6 +93,19 @@ namespace GlitchyEngine.Renderer
static BlendState _lightBlend;
static DepthStencilState _fullscreenDepthState;
static Buffer _sceneBuffer;
static Buffer _objectBuffer;
[Ordered]
struct ObjectConstantsBuffer
{
public Matrix Transform;
public Matrix4x3 Transform_InvT;
public uint32 EntityId;
private Vector3 _padding;
}
public static void Init(GraphicsContext context, EffectLibrary effectLibrary)
{
Debug.Profiler.ProfileFunction!();
@@ -179,10 +192,19 @@ namespace GlitchyEngine.Renderer
DepthStencilStateDescription dsDesc = .Default;
dsDesc.DepthEnabled = false;
_fullscreenDepthState = new DepthStencilState(dsDesc);
BufferDescription sceneBufferDesc = .(sizeof(Matrix), .Constant, .Dynamic, .Write);
_sceneBuffer = new Buffer(sceneBufferDesc);
BufferDescription objectBufferDesc = .(sizeof(ObjectConstantsBuffer), .Constant, .Dynamic, .Write);
_objectBuffer = new Buffer(objectBufferDesc);
}
static void DeinitDeferredRenderer()
{
_objectBuffer.ReleaseRef();
_sceneBuffer.ReleaseRef();
_fullscreenDepthState.ReleaseRef();
_lightBlend.ReleaseRef();
_gBufferBlend.ReleaseRef();
@@ -192,6 +214,7 @@ namespace GlitchyEngine.Renderer
TestFullscreenEffect.ReleaseRef();
}
// [Obsolete("", false)]
public static void BeginScene(OldCamera camera)
{
Debug.Profiler.ProfileRendererFunction!();
@@ -208,6 +231,8 @@ namespace GlitchyEngine.Renderer
_sceneConstants.CameraPosition = transform.Translation;
_sceneConstants.CameraTarget = renderTarget;
_sceneConstants.CompositionTarget = finalTarget;
_sceneBuffer.SetData<Matrix>(viewProjection);
}
public static void BeginScene(EditorCamera camera, RenderTargetGroup finalTarget)
@@ -219,6 +244,8 @@ namespace GlitchyEngine.Renderer
_sceneConstants.CameraPosition = camera.Position;
_sceneConstants.CameraTarget = camera.RenderTarget;
_sceneConstants.CompositionTarget = finalTarget;
_sceneBuffer.SetData<Matrix>(viewProjection, 0, .WriteDiscard);
}
public static int SortMeshes(SubmittedMesh left, SubmittedMesh right)
@@ -282,14 +309,27 @@ namespace GlitchyEngine.Renderer
{
Debug.Profiler.ProfileRendererScope!("SetVariables");
entry.Material.SetVariable("ViewProjection", _sceneConstants.ViewProjection);
ObjectConstantsBuffer objectData;
objectData.Transform = entry.Transform;
Matrix4x3 mat = Matrix4x3((Matrix3x3)(entry.Transform).Invert().Transpose());
objectData.Transform_InvT = mat;
objectData.EntityId = entry.EntityId;
_objectBuffer.SetData(objectData, 0, .WriteDiscard);
entry.Material.Effect.Buffers.TryReplaceBuffer("SceneConstants", _sceneBuffer);
entry.Material.Effect.Buffers.TryReplaceBuffer("ObjectConstants", _objectBuffer);
/*entry.Material.SetVariable("ViewProjection", _sceneConstants.ViewProjection);
entry.Material.SetVariable("Transform", entry.Transform);
entry.Material.SetVariable("EntityId", entry.EntityId);
Matrix3x3 mat = (Matrix3x3)(entry.Transform).Invert().Transpose();
entry.Material.SetVariable("Transform_InvT", mat);
entry.Material.SetVariable("Transform_InvT", mat);*/
}
entry.Material.Bind(_context);
+1 -1
View File
@@ -21,7 +21,7 @@ namespace GlitchyEngine.Renderer
public abstract class Shader : RefCounter
{
protected BufferCollection _buffers ~ delete _;//:append _;
protected internal BufferCollection _buffers ~ _.ReleaseRef();//:append _;
protected ShaderTextureCollection _textures ~ delete _;