/// <summary> /// Creates a new instance of the <see cref="D2DInputDescriptionAttribute"/> type with the specified arguments. /// </summary> /// <param name="index">The index of the resource to declare the description for.</param> /// <param name="filter">The type of filter to apply to the input texture.</param> public D2DInputDescriptionAttribute(int index, D2D1Filter filter) { Index = index; Filter = filter; }
/// <summary> /// Extracts the input descriptions for the current shader. /// </summary> /// <param name="structDeclarationSymbol">The input <see cref="INamedTypeSymbol"/> instance to process.</param> /// <param name="inputDescriptions">The produced input descriptions for the shader.</param> /// <param name="diagnostics">The collection of produced <see cref="Diagnostic"/> instances.</param> public static void GetInfo( INamedTypeSymbol structDeclarationSymbol, out ImmutableArray <InputDescription> inputDescriptions, out ImmutableArray <Diagnostic> diagnostics) { int inputCount = 0; ImmutableArray <InputDescription> .Builder inputDescriptionsBuilder = ImmutableArray.CreateBuilder <InputDescription>(); ImmutableArray <Diagnostic> .Builder diagnosticsBuilder = ImmutableArray.CreateBuilder <Diagnostic>(); foreach (AttributeData attributeData in structDeclarationSymbol.GetAttributes()) { switch (attributeData.AttributeClass?.GetFullMetadataName()) { case "ComputeSharp.D2D1.D2DInputCountAttribute": inputCount = (int)attributeData.ConstructorArguments[0].Value !; break; case "ComputeSharp.D2D1.D2DInputDescriptionAttribute": if (attributeData.ConstructorArguments.Length == 2) { int index = (int)attributeData.ConstructorArguments[0].Value !; D2D1Filter filter = (D2D1Filter)attributeData.ConstructorArguments[1].Value !; _ = attributeData.TryGetNamedArgument("LevelOfDetailCount", out int levelOfDetailCount); inputDescriptionsBuilder.Add(new InputDescription((uint)index, filter, levelOfDetailCount)); } break; default: break; } } inputDescriptions = ImmutableArray <InputDescription> .Empty; // Validate the input count (ignore if invalid, this will be validated by the HLSL source generator) if (inputCount is not(>= 0 and <= 8)) { goto End; } // All simple indices must be in range if (inputDescriptionsBuilder.Any(description => description.Index >= inputCount)) { diagnosticsBuilder.Add(OutOfRangeInputDescriptionIndex, structDeclarationSymbol, structDeclarationSymbol); goto End; } HashSet <uint> inputDescriptionIndices = new(inputDescriptionsBuilder.Select(description => description.Index)); // All input description indices must be unique if (inputDescriptionIndices.Count != inputDescriptionsBuilder.Count) { diagnosticsBuilder.Add(RepeatedD2DInputDescriptionIndices, structDeclarationSymbol, structDeclarationSymbol); goto End; } inputDescriptions = inputDescriptionsBuilder.ToImmutable(); End: diagnostics = diagnosticsBuilder.ToImmutable(); }
/// <summary> /// Creates a new <see cref="D2D1InputDescription"/> instance with the specified parameters. /// </summary> /// <param name="index">The index of the resource the description belongs to.</param> /// <param name="filter">The type of filter to apply to the input texture.</param> /// <param name="levelOfDetailCount">The mip level to retrieve from the upstream transform, if specified.</param> internal D2D1InputDescription(int index, D2D1Filter filter, int levelOfDetailCount) { Index = index; Filter = filter; LevelOfDetailCount = levelOfDetailCount; }