Refactor D3D12 Resource Management
Refactored and renamed components related to D3D12 graphics programming, replacing "descriptor" with "viewGroup" to improve resource grouping and management. Updated `D3D12CommandBuffer`, `D3D12DescriptorAllocator`, and `D3D12PipelineLibrary` to reflect these changes. Simplified material and shader creation in `D3D12ResourceAllocator`. Enhanced `D3D12ResourceDatabase` with resource naming for debugging and improved management. Refactored `Shader` and `ShaderPass` to use modern C# features and `IResourceReleasable` interface. Introduced `D3D12Utility` for centralized utility methods. Updated `Material` class for efficient buffer creation. Renamed `ShaderCompiler` to `SDLCompiler` with improved error handling. Updated `MeshRenderPass` to use new shader compilation process. Various improvements in error handling, code readability, and utility methods.
This commit is contained in:
@@ -27,7 +27,7 @@ internal class DefinesBlock : IBlockParser<List<Token>, List<string>>
|
||||
return defines;
|
||||
}
|
||||
|
||||
public static List<string>? SemanticAnalysis(List<Token>? syntax, List<ShaderError> errors)
|
||||
public static List<string>? SemanticAnalysis(List<Token>? syntax, List<SDLError> errors)
|
||||
{
|
||||
if (syntax == null)
|
||||
{
|
||||
|
||||
@@ -4,5 +4,5 @@ internal interface IBlockParser<T, U>
|
||||
{
|
||||
public static abstract bool ShouldEnter(Token token);
|
||||
public static abstract T? Parse(TokenStreamSlice ts);
|
||||
public static abstract U? SemanticAnalysis(T? syntax, List<ShaderError> errors);
|
||||
public static abstract U? SemanticAnalysis(T? syntax, List<SDLError> errors);
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ internal class IncludesBlock : IBlockParser<List<Token>, List<string>>
|
||||
return includes;
|
||||
}
|
||||
|
||||
public static List<string>? SemanticAnalysis(List<Token>? syntax, List<ShaderError> errors)
|
||||
public static List<string>? SemanticAnalysis(List<Token>? syntax, List<SDLError> errors)
|
||||
{
|
||||
if (syntax == null || syntax.Count == 0)
|
||||
{
|
||||
@@ -44,7 +44,7 @@ internal class IncludesBlock : IBlockParser<List<Token>, List<string>>
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = $"Included file '{path}' not found.",
|
||||
line = includeToken.line,
|
||||
|
||||
@@ -30,7 +30,7 @@ internal class KeywordsBlock : IBlockParser<List<FunctionCallDeclaration>, List<
|
||||
return keywords;
|
||||
}
|
||||
|
||||
public static List<KeywordsGroup>? SemanticAnalysis(List<FunctionCallDeclaration>? syntax, List<ShaderError> errors)
|
||||
public static List<KeywordsGroup>? SemanticAnalysis(List<FunctionCallDeclaration>? syntax, List<SDLError> errors)
|
||||
{
|
||||
if (syntax == null)
|
||||
{
|
||||
@@ -42,7 +42,7 @@ internal class KeywordsBlock : IBlockParser<List<FunctionCallDeclaration>, List<
|
||||
{
|
||||
if (keyword.arguments == null || keyword.arguments.Count == 0)
|
||||
{
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = $"Function '{keyword.name.lexeme}' must have at least one argument.",
|
||||
line = keyword.name.line,
|
||||
@@ -61,7 +61,7 @@ internal class KeywordsBlock : IBlockParser<List<FunctionCallDeclaration>, List<
|
||||
group.type = KeywordType.Static;
|
||||
break;
|
||||
default:
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = $"Unknown function name '{keyword.name.lexeme}'.",
|
||||
line = keyword.name.line,
|
||||
|
||||
@@ -61,7 +61,7 @@ internal class PassBlock : IBlockParser<PassSyntax, PassSemantic>
|
||||
return pass;
|
||||
}
|
||||
|
||||
public static PassSemantic? SemanticAnalysis(PassSyntax? syntax, List<ShaderError> errors)
|
||||
public static PassSemantic? SemanticAnalysis(PassSyntax? syntax, List<SDLError> errors)
|
||||
{
|
||||
if (syntax == null)
|
||||
{
|
||||
@@ -81,7 +81,7 @@ internal class PassBlock : IBlockParser<PassSyntax, PassSemantic>
|
||||
if (semantic.localProperties != null
|
||||
&& semantic.localProperties.Any(p => p.scope == PropertyScope.Global))
|
||||
{
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = "Global properties cannot be declared inside a pass. Move them to the shader properties block.",
|
||||
line = syntax.name.line,
|
||||
@@ -108,7 +108,7 @@ internal class PassBlock : IBlockParser<PassSyntax, PassSemantic>
|
||||
break;
|
||||
|
||||
default:
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = $"Unknown function '{func.name.lexeme}' in pass {syntax.name.lexeme}.",
|
||||
line = func.name.line,
|
||||
@@ -123,7 +123,7 @@ internal class PassBlock : IBlockParser<PassSyntax, PassSemantic>
|
||||
{
|
||||
// TODO: Inheritance from base pass.
|
||||
// TODO: Add mesh shader support.
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = $"Pass {syntax.name.lexeme} must contain a mesh shader (ms) and a pixel shader (ps) declaration.",
|
||||
line = syntax.name.line,
|
||||
@@ -134,11 +134,11 @@ internal class PassBlock : IBlockParser<PassSyntax, PassSemantic>
|
||||
return semantic;
|
||||
}
|
||||
|
||||
private static void AnalysisShaderEntry(List<ShaderError> errors, FunctionCallDeclaration func, ref ShaderEntryPoint shaderEntryPoint)
|
||||
private static void AnalysisShaderEntry(List<SDLError> errors, FunctionCallDeclaration func, ref ShaderEntryPoint shaderEntryPoint)
|
||||
{
|
||||
if (func.arguments?.Count != 2)
|
||||
{
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = "Shader declaration requires exactly two arguments: (shaderPath, entryPoint).",
|
||||
line = func.name.line,
|
||||
|
||||
@@ -38,7 +38,7 @@ internal class PipelineBlock : IBlockParser<PipelineSyntax, PipelineSemantic>
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
public static PipelineSemantic? SemanticAnalysis(PipelineSyntax? syntax, List<ShaderError> errors)
|
||||
public static PipelineSemantic? SemanticAnalysis(PipelineSyntax? syntax, List<SDLError> errors)
|
||||
{
|
||||
if (syntax == null)
|
||||
{
|
||||
@@ -80,7 +80,7 @@ internal class PipelineBlock : IBlockParser<PipelineSyntax, PipelineSemantic>
|
||||
semantic.zTest = ZTestOptions.Always;
|
||||
break;
|
||||
default:
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = $"Invalid ZTest option: {valueDecl.value.lexeme}",
|
||||
line = valueDecl.value.line,
|
||||
@@ -100,7 +100,7 @@ internal class PipelineBlock : IBlockParser<PipelineSyntax, PipelineSemantic>
|
||||
semantic.zWrite = ZWriteOptions.Off;
|
||||
break;
|
||||
default:
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = $"Invalid ZWrite option: {valueDecl.value.lexeme}",
|
||||
line = valueDecl.value.line,
|
||||
@@ -123,7 +123,7 @@ internal class PipelineBlock : IBlockParser<PipelineSyntax, PipelineSemantic>
|
||||
semantic.cull = CullOptions.Back;
|
||||
break;
|
||||
default:
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = $"Invalid Cull option: {valueDecl.value.lexeme}",
|
||||
line = valueDecl.value.line,
|
||||
@@ -152,7 +152,7 @@ internal class PipelineBlock : IBlockParser<PipelineSyntax, PipelineSemantic>
|
||||
semantic.blend = BlendOptions.PremultipliedAlpha;
|
||||
break;
|
||||
default:
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = $"Invalid Blend option: {valueDecl.value.lexeme}",
|
||||
line = valueDecl.value.line,
|
||||
@@ -169,7 +169,7 @@ internal class PipelineBlock : IBlockParser<PipelineSyntax, PipelineSemantic>
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = $"Invalid Color Mask value: {valueDecl.value.lexeme}",
|
||||
line = valueDecl.value.line,
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Ghost.Shader.Compiler.Parser;
|
||||
|
||||
internal class PropertiesBlock : IBlockParser<PropertiesSyntax, List<PropertySemantic>>
|
||||
{
|
||||
private delegate object? PropertyValueBuilder(List<Token> tokens, List<ShaderError> errors);
|
||||
private delegate object? PropertyValueBuilder(List<Token> tokens, List<SDLError> errors);
|
||||
|
||||
private sealed record PropTypeInfo(int ArgCount, TokenType ArgTokenType, PropertyValueBuilder? Builder);
|
||||
|
||||
@@ -78,11 +78,11 @@ internal class PropertiesBlock : IBlockParser<PropertiesSyntax, List<PropertySem
|
||||
[ShaderPropertyType.TextureCube] = new(1, TokenType.Identifier, (syntax, errors) => ParseTextureDefault(syntax[0], errors)),
|
||||
};
|
||||
|
||||
private static float ParseFloatValue(Token token, List<ShaderError> errors)
|
||||
private static float ParseFloatValue(Token token, List<SDLError> errors)
|
||||
{
|
||||
if (!float.TryParse(token.lexeme, CultureInfo.InvariantCulture, out var result))
|
||||
{
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = $"Failed to parse float value '{token.lexeme}'.",
|
||||
line = token.line,
|
||||
@@ -93,11 +93,11 @@ internal class PropertiesBlock : IBlockParser<PropertiesSyntax, List<PropertySem
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int ParseIntValue(Token token, List<ShaderError> errors)
|
||||
private static int ParseIntValue(Token token, List<SDLError> errors)
|
||||
{
|
||||
if (!int.TryParse(token.lexeme, CultureInfo.InvariantCulture, out var result))
|
||||
{
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = $"Failed to parse int value '{token.lexeme}'.",
|
||||
line = token.line,
|
||||
@@ -108,11 +108,11 @@ internal class PropertiesBlock : IBlockParser<PropertiesSyntax, List<PropertySem
|
||||
return result;
|
||||
}
|
||||
|
||||
private static uint ParseUIntValue(Token token, List<ShaderError> errors)
|
||||
private static uint ParseUIntValue(Token token, List<SDLError> errors)
|
||||
{
|
||||
if (!uint.TryParse(token.lexeme, CultureInfo.InvariantCulture, out var result))
|
||||
{
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = $"Failed to parse uint value '{token.lexeme}'.",
|
||||
line = token.line,
|
||||
@@ -123,11 +123,11 @@ internal class PropertiesBlock : IBlockParser<PropertiesSyntax, List<PropertySem
|
||||
return result;
|
||||
}
|
||||
|
||||
private static bool ParseBoolValue(Token token, List<ShaderError> errors)
|
||||
private static bool ParseBoolValue(Token token, List<SDLError> errors)
|
||||
{
|
||||
if (!bool.TryParse(token.lexeme, out var result))
|
||||
{
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = $"Failed to parse bool value '{token.lexeme}'.",
|
||||
line = token.line,
|
||||
@@ -138,11 +138,11 @@ internal class PropertiesBlock : IBlockParser<PropertiesSyntax, List<PropertySem
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string ParseTextureDefault(Token token, List<ShaderError> errors)
|
||||
private static string ParseTextureDefault(Token token, List<SDLError> errors)
|
||||
{
|
||||
if (!TokenLexicon.IsTextureDefaultValue(token.lexeme))
|
||||
{
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = $"Texture default value '{token.lexeme}' is not valid.",
|
||||
line = token.line,
|
||||
@@ -242,7 +242,7 @@ internal class PropertiesBlock : IBlockParser<PropertiesSyntax, List<PropertySem
|
||||
return syntax;
|
||||
}
|
||||
|
||||
public static List<PropertySemantic>? SemanticAnalysis(PropertiesSyntax? syntax, List<ShaderError> errors)
|
||||
public static List<PropertySemantic>? SemanticAnalysis(PropertiesSyntax? syntax, List<SDLError> errors)
|
||||
{
|
||||
if (syntax == null)
|
||||
{
|
||||
@@ -295,11 +295,11 @@ internal class PropertiesBlock : IBlockParser<PropertiesSyntax, List<PropertySem
|
||||
return models;
|
||||
}
|
||||
|
||||
private static bool ValidatePropertyType(List<ShaderError> errors, PropertyDeclaration property, PropertySemantic model)
|
||||
private static bool ValidatePropertyType(List<SDLError> errors, PropertyDeclaration property, PropertySemantic model)
|
||||
{
|
||||
if (!TokenLexicon.IsType(property.type.lexeme))
|
||||
{
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = $"Shader property type '{property.type.lexeme}' is not a valid type.",
|
||||
line = property.type.line,
|
||||
@@ -313,11 +313,11 @@ internal class PropertiesBlock : IBlockParser<PropertiesSyntax, List<PropertySem
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool ValidatePropertyName(List<ShaderError> errors, HashSet<string> usedPropertyNames, PropertyDeclaration property, PropertySemantic model)
|
||||
private static bool ValidatePropertyName(List<SDLError> errors, HashSet<string> usedPropertyNames, PropertyDeclaration property, PropertySemantic model)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(property.name.lexeme))
|
||||
{
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = "Shader property has an empty name.",
|
||||
line = property.name.line,
|
||||
@@ -328,7 +328,7 @@ internal class PropertiesBlock : IBlockParser<PropertiesSyntax, List<PropertySem
|
||||
}
|
||||
else if (usedPropertyNames.Contains(property.name.lexeme))
|
||||
{
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = $"Shader property name '{property.name.lexeme}' is duplicated.",
|
||||
line = property.name.line,
|
||||
@@ -342,12 +342,12 @@ internal class PropertiesBlock : IBlockParser<PropertiesSyntax, List<PropertySem
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool ValidatePropertyConstructor(List<ShaderError> errors, PropertyDeclaration property, PropertySemantic model)
|
||||
private static bool ValidatePropertyConstructor(List<SDLError> errors, PropertyDeclaration property, PropertySemantic model)
|
||||
{
|
||||
var constructor = property.propertyConstructor;
|
||||
if (!constructor.HasValue)
|
||||
{
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = "Shader property constructor is null.",
|
||||
line = property.name.line,
|
||||
@@ -360,7 +360,7 @@ internal class PropertiesBlock : IBlockParser<PropertiesSyntax, List<PropertySem
|
||||
var constructorValue = constructor.Value;
|
||||
if (string.IsNullOrWhiteSpace(constructorValue.name.lexeme))
|
||||
{
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = "Shader property constructor has an empty name.",
|
||||
line = constructorValue.name.line,
|
||||
@@ -372,7 +372,7 @@ internal class PropertiesBlock : IBlockParser<PropertiesSyntax, List<PropertySem
|
||||
|
||||
if (constructorValue.name.lexeme != property.type.lexeme)
|
||||
{
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = $"Shader property constructor name '{constructorValue.name.lexeme}' does not match property type '{property.type.lexeme}'.",
|
||||
line = constructorValue.name.line,
|
||||
@@ -384,7 +384,7 @@ internal class PropertiesBlock : IBlockParser<PropertiesSyntax, List<PropertySem
|
||||
|
||||
if (!s_propTypeInfo.TryGetValue(model.type, out var info))
|
||||
{
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = $"No constructor metadata registered for property type '{model.type}'.",
|
||||
line = constructorValue.name.line,
|
||||
@@ -397,7 +397,7 @@ internal class PropertiesBlock : IBlockParser<PropertiesSyntax, List<PropertySem
|
||||
// Count check
|
||||
if (constructorValue.arguments == null)
|
||||
{
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = "Shader property constructor arguments are null.",
|
||||
line = constructorValue.name.line,
|
||||
@@ -409,7 +409,7 @@ internal class PropertiesBlock : IBlockParser<PropertiesSyntax, List<PropertySem
|
||||
|
||||
if (constructorValue.arguments.Count != info.ArgCount)
|
||||
{
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = $"Shader property constructor for type '{property.type.lexeme}' expects {info.ArgCount} argument(s), but got {constructorValue.arguments.Count}.",
|
||||
line = constructorValue.name.line,
|
||||
@@ -426,7 +426,7 @@ internal class PropertiesBlock : IBlockParser<PropertiesSyntax, List<PropertySem
|
||||
var arg = constructorValue.arguments[i];
|
||||
if (!arg.Match(info.ArgTokenType))
|
||||
{
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = $"Shader property constructor argument {i} expects token kind '{info.ArgTokenType}', but got '{arg.type}'.",
|
||||
line = arg.line,
|
||||
@@ -451,7 +451,7 @@ internal class PropertiesBlock : IBlockParser<PropertiesSyntax, List<PropertySem
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = $"Failed to construct default value for property '{property.name.lexeme}': {ex.Message}",
|
||||
line = constructorValue.name.line,
|
||||
|
||||
@@ -49,7 +49,7 @@ internal class ShaderBlock : IBlockParser<ShaderSyntax, ShaderSemantics>
|
||||
return shader;
|
||||
}
|
||||
|
||||
public static ShaderSemantics? SemanticAnalysis(ShaderSyntax? syntax, List<ShaderError> errors)
|
||||
public static ShaderSemantics? SemanticAnalysis(ShaderSyntax? syntax, List<SDLError> errors)
|
||||
{
|
||||
if (syntax == null)
|
||||
{
|
||||
@@ -85,7 +85,7 @@ internal class ShaderBlock : IBlockParser<ShaderSyntax, ShaderSemantics>
|
||||
case TokenLexicon.KnownFunctions.FALLBACK:
|
||||
if (func.arguments == null || func.arguments.Count != 1)
|
||||
{
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = "Fallback declaration requires exactly one arguments: (fallback shader name).",
|
||||
line = func.name.line,
|
||||
@@ -98,7 +98,7 @@ internal class ShaderBlock : IBlockParser<ShaderSyntax, ShaderSemantics>
|
||||
shaderModel.fallback = func.arguments[0].lexeme;
|
||||
break;
|
||||
default:
|
||||
errors.Add(new ShaderError
|
||||
errors.Add(new SDLError
|
||||
{
|
||||
message = $"Unknown function '{func.name.lexeme}' in shader.",
|
||||
line = func.name.line,
|
||||
|
||||
Reference in New Issue
Block a user