public ResourceDefinition(string name, int binding, TypeReference type, ShaderResourceKind kind) { Name = name; Binding = binding; ValueType = type; ResourceKind = kind; }
public override void VisitVariableDeclaration(VariableDeclarationSyntax node) { int resourceBinding = _lastResourceBinding++; if (node.Variables.Count != 1) { throw new ShaderGenerationException("Cannot declare multiple variables together."); } VariableDeclaratorSyntax vds = node.Variables[0]; string resourceName = vds.Identifier.Text; TypeInfo typeInfo = GetModel(node).GetTypeInfo(node.Type); string fullTypeName = GetModel(node).GetFullTypeName(node.Type); TypeReference tr = new TypeReference(fullTypeName); ShaderResourceKind kind = ClassifyResourceKind(fullTypeName); ResourceDefinition rd = new ResourceDefinition(resourceName, resourceBinding, tr, kind); if (kind == ShaderResourceKind.Uniform) { ValidateResourceType(typeInfo); } foreach (LanguageBackend b in _backends) { b.AddResource(_shaderSet.Name, rd); } }
private static ResourceKind GetResourceKind(ShaderResourceKind resourceKind) { switch (resourceKind) { case ShaderResourceKind.Uniform: return(ResourceKind.UniformBuffer); case ShaderResourceKind.Texture2D: case ShaderResourceKind.Texture2DArray: case ShaderResourceKind.TextureCube: case ShaderResourceKind.Texture2DMS: return(ResourceKind.TextureReadOnly); case ShaderResourceKind.Sampler: return(ResourceKind.Sampler); case ShaderResourceKind.StructuredBuffer: return(ResourceKind.StructuredBufferReadOnly); case ShaderResourceKind.RWStructuredBuffer: return(ResourceKind.StructuredBufferReadWrite); default: throw new ArgumentOutOfRangeException(); } }
public override void VisitVariableDeclaration(VariableDeclarationSyntax node) { if (node.Variables.Count != 1) { throw new ShaderGenerationException("Cannot declare multiple variables together."); } VariableDeclaratorSyntax vds = node.Variables[0]; string resourceName = vds.Identifier.Text; TypeInfo typeInfo = GetModel(node).GetTypeInfo(node.Type); string fullTypeName = GetModel(node).GetFullTypeName(node.Type); TypeReference valueType = new TypeReference(fullTypeName, typeInfo); ShaderResourceKind kind = ClassifyResourceKind(fullTypeName); if (kind == ShaderResourceKind.StructuredBuffer || kind == ShaderResourceKind.RWStructuredBuffer || kind == ShaderResourceKind.RWTexture2D) { valueType = ParseElementType(vds); } int set = 0; // Default value if not otherwise specified. if (GetResourceDecl(node, out AttributeSyntax resourceSetDecl)) { set = GetAttributeArgumentIntValue(resourceSetDecl, 0, GetModel(node)); } int resourceBinding = GetAndIncrementBinding(set); ResourceDefinition rd = new ResourceDefinition(resourceName, set, resourceBinding, valueType, kind); if (kind == ShaderResourceKind.Uniform) { ValidateResourceType(typeInfo); } foreach (LanguageBackend b in _backends) { b.AddResource(_shaderSet.Name, rd); } }
public override void VisitVariableDeclaration(VariableDeclarationSyntax node) { if (node.Variables.Count != 1) { throw new ShaderGenerationException("Cannot declare multiple variables together."); } VariableDeclaratorSyntax vds = node.Variables[0]; string resourceName = vds.Identifier.Text; TypeInfo typeInfo = GetModel(node).GetTypeInfo(node.Type); string fullTypeName = GetModel(node).GetFullTypeName(node.Type); TypeReference valueType = new TypeReference(fullTypeName, typeInfo.Type); ShaderResourceKind kind = ClassifyResourceKind(fullTypeName); var structure = _backends.Select(b => b.GetContext(_shaderSet.Name).Structures .FirstOrDefault(s => SymbolEqualityComparer.Default.Equals(s.Type, typeInfo.Type))) .FirstOrDefault(); if (structure != null && structure.Fields.Any(f => f.IsBuiltIn)) { kind = ShaderResourceKind.BuiltIn; } ShaderBuiltin builtin = default; if (kind == ShaderResourceKind.Uniform) { if (node.Parent is FieldDeclarationSyntax field) { if (field.Modifiers.Any(f => f.IsKind(SyntaxKind.PrivateKeyword))) { kind = ShaderResourceKind.Local; } else if (field.AttributeLists.Any(l => l.Attributes.Any(a => a.Name.ToString().Contains("Semantic")))) { kind = ShaderResourceKind.BuiltIn; SemanticType semanticType = GetSemanticType(vds); if (semanticType == SemanticType.None) { var geometrySemantic = GetGeometrySemantic(vds); if (geometrySemantic != GeometrySemantic.None) { builtin = new ShaderBuiltin(geometrySemantic); } } else { builtin = new ShaderBuiltin(semanticType); } } } else if (typeInfo.Type.GetAttributes().Any(a => a.AttributeClass.Name.Contains("Semantic"))) { kind = ShaderResourceKind.BuiltIn; } } if (kind == ShaderResourceKind.StructuredBuffer || kind == ShaderResourceKind.RWStructuredBuffer || kind == ShaderResourceKind.RWTexture2D || valueType.Name.Contains(nameof(UniformBuffer <int>))) { valueType = ParseElementType(vds); } if (node.Parent is FieldDeclarationSyntax) { var arraySize = node.Parent.DescendantNodes().OfType <AttributeSyntax>().FirstOrDefault( attrSyntax => attrSyntax.Name.ToString().EndsWith("ArraySize")); if (arraySize != null) { var fixedSize = (int)GetModel(node).GetConstantValue(arraySize.ArgumentList.Arguments.First().Expression).Value; valueType = new TypeReference(valueType.Name, valueType.TypeInfo, fixedSize); } var emitAttribute = node.Parent.DescendantNodes().OfType <AttributeSyntax>().FirstOrDefault( attrSyntax => attrSyntax.Name.ToString().EndsWith("EmitVertex")); if (emitAttribute != null) { kind = ShaderResourceKind.Emit; } } ResourceDefinition rd; if (kind == ShaderResourceKind.Local) { rd = new ResourceDefinition(resourceName, 0, 0, valueType, kind); } else { int set = 0; // Default value if not otherwise specified. if (GetResourceDecl(node, out AttributeSyntax resourceSetDecl)) { set = GetAttributeArgumentIntValue(resourceSetDecl, 0, GetModel(node)); } int resourceBinding = GetAndIncrementBinding(set); if (kind == ShaderResourceKind.Uniform) { ValidateUniformType(typeInfo); } rd = new ResourceDefinition(resourceName, set, resourceBinding, valueType, kind); } rd.Semantic = builtin.Semantic; foreach (LanguageBackend b in _backends) { b.AddResource(_shaderSet.Name, rd); } }
private static byte[] GetShaderBytecode(EngineDevice device, ResourceLink resourceLink, ShaderResourceKind resourceKind, string shaderModel) { switch (resourceKind) { case ShaderResourceKind.Bytecode: using (var inStream = resourceLink.OpenInputStream()) { return(inStream.ReadAllBytes()); } case ShaderResourceKind.HlsFile: using (ReusableStringBuilders.Current.UseStringBuilder(out var singleShaderSourceBuilder, 10024)) { SingleShaderFileBuilder.ReadShaderFileAndResolveIncludes( resourceLink, singleShaderSourceBuilder); // device.DebugEnabled ? D3DCompiler.ShaderFlags.Debug : D3DCompiler.ShaderFlags.None var shaderSource = singleShaderSourceBuilder.ToString(); var compileResult = Compiler.Compile( shaderSource, Array.Empty <D3D.ShaderMacro>(), null !, "main", resourceLink.ToString() ?? "", shaderModel, device.DebugEnabled ? ShaderFlags.Debug : ShaderFlags.None, out var compBlob, out var compErrorBlob); try { if (compileResult.Failure) { throw new SeeingSharpGraphicsException($"Unable to compile shader from {resourceLink}: {compileResult.Code} - {compileResult.ToString()}"); } return(compBlob.GetBytes()); } finally { SeeingSharpUtil.SafeDispose(ref compBlob); SeeingSharpUtil.SafeDispose(ref compErrorBlob); } } default: throw new SeeingSharpException($"Unhandled {nameof(ShaderResourceKind)}: {resourceKind}"); } }
/// <summary> /// Initializes a new instance of the <see cref="ShaderResource"/> class. /// </summary> /// <param name="shaderProfile">Shader profile used for compilation.</param> /// <param name="resourceLink">The source of the resource.</param> /// <param name="resourceKind">Kind of the shader resource.</param> protected ShaderResource(string shaderProfile, ResourceLink resourceLink, ShaderResourceKind resourceKind) { _resourceKind = resourceKind; _shaderProfile = shaderProfile; _resourceLink = resourceLink; }