Ejemplo n.º 1
0
 /// <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();
        }
Ejemplo n.º 3
0
 /// <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;
 }