From 6386c4c27e34bd907341b53942d1391b4b5fc874 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 24 Nov 2024 14:53:03 -0800 Subject: [PATCH] Update 'D2D.GetInput' to support all input types --- .../InvalidD2DInputArgumentAnalyzer.cs | 23 ++++++++++++------- .../HlslD2DIntrinsicInputTypeAttribute.cs | 4 ++++ src/ComputeSharp.D2D1/Intrinsics/D2D.cs | 2 -- ...ixelShaderDescriptorGenerator_Analyzers.cs | 2 +- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/ComputeSharp.D2D1.SourceGenerators/Diagnostics/Analyzers/InvalidD2DInputArgumentAnalyzer.cs b/src/ComputeSharp.D2D1.SourceGenerators/Diagnostics/Analyzers/InvalidD2DInputArgumentAnalyzer.cs index b970bb475..18359efb1 100644 --- a/src/ComputeSharp.D2D1.SourceGenerators/Diagnostics/Analyzers/InvalidD2DInputArgumentAnalyzer.cs +++ b/src/ComputeSharp.D2D1.SourceGenerators/Diagnostics/Analyzers/InvalidD2DInputArgumentAnalyzer.cs @@ -33,7 +33,7 @@ public override void Initialize(AnalysisContext context) context.RegisterCompilationStartAction(static context => { // If we can't get the D2D methods map, we have to stop right away - if (!TryBuildMethodSymbolMap(context.Compilation, out ImmutableDictionary? methodSymbols)) + if (!TryBuildMethodSymbolMap(context.Compilation, out ImmutableDictionary? methodSymbols)) { return; } @@ -65,7 +65,7 @@ public override void Initialize(AnalysisContext context) } // Validate that the target method is one of the ones we care about, and get the target input type - if (!methodSymbols.TryGetValue(targetMethodSymbol, out D2D1PixelShaderInputType targetInputType)) + if (!methodSymbols.TryGetValue(targetMethodSymbol, out D2D1PixelShaderInputType? targetInputType)) { return; } @@ -101,7 +101,7 @@ public override void Initialize(AnalysisContext context) typeSymbol, inputCount)); } - else if ((D2D1PixelShaderInputType)inputTypes[index] != targetInputType) + else if (targetInputType is not null && (D2D1PixelShaderInputType)inputTypes[index] != targetInputType) { // Second validation: the input type must match context.ReportDiagnostic(Diagnostic.Create( @@ -120,7 +120,7 @@ public override void Initialize(AnalysisContext context) /// The to consider for analysis. /// The resulting mapping of resolved instances. /// Whether all requested instances could be resolved. - private static bool TryBuildMethodSymbolMap(Compilation compilation, [NotNullWhen(true)] out ImmutableDictionary? methodSymbols) + private static bool TryBuildMethodSymbolMap(Compilation compilation, [NotNullWhen(true)] out ImmutableDictionary? methodSymbols) { // Get the 'D2D' symbol, to get methods from it if (compilation.GetTypeByMetadataName("ComputeSharp.D2D1.D2D") is not { } d2DSymbol) @@ -140,7 +140,7 @@ private static bool TryBuildMethodSymbolMap(Compilation compilation, [NotNullWhe d2DSymbol.GetMethod(nameof(D2D.SampleInputAtPosition)) ]; - ImmutableDictionary.Builder inputTypeMethodMap = ImmutableDictionary.CreateBuilder(SymbolEqualityComparer.Default); + ImmutableDictionary.Builder inputTypeMethodMap = ImmutableDictionary.CreateBuilder(SymbolEqualityComparer.Default); // Validate all methods and build the map foreach (IMethodSymbol? d2DMethodSymbol in d2DMethodSymbols) @@ -154,9 +154,16 @@ private static bool TryBuildMethodSymbolMap(Compilation compilation, [NotNullWhe } // Lookup the attribute to get the D2D input type (the attribute only exists on the 'D2D' type loaded in the analyzer) - D2D1PixelShaderInputType inputType = typeof(D2D).GetMethod(d2DMethodSymbol.Name).GetCustomAttribute()!.InputType; - - inputTypeMethodMap.Add(d2DMethodSymbol, (D2D1PixelShaderInputType)inputType); + if (typeof(D2D).GetMethod(d2DMethodSymbol.Name).GetCustomAttribute() is { } hlslD2DIntrinsicInputTypeAttribute) + { + inputTypeMethodMap.Add(d2DMethodSymbol, hlslD2DIntrinsicInputTypeAttribute.InputType); + } + else + { + // If the method is not annotated, we stil track it, but we will not indicate any exclusive input type. + // This means that the input index validation logic will still work, but we'll skip the input type checks. + inputTypeMethodMap.Add(d2DMethodSymbol, null); + } } methodSymbols = inputTypeMethodMap.ToImmutable(); diff --git a/src/ComputeSharp.D2D1/Intrinsics/Attributes/HlslD2DIntrinsicInputTypeAttribute.cs b/src/ComputeSharp.D2D1/Intrinsics/Attributes/HlslD2DIntrinsicInputTypeAttribute.cs index 57936251d..2e7b726b7 100644 --- a/src/ComputeSharp.D2D1/Intrinsics/Attributes/HlslD2DIntrinsicInputTypeAttribute.cs +++ b/src/ComputeSharp.D2D1/Intrinsics/Attributes/HlslD2DIntrinsicInputTypeAttribute.cs @@ -8,6 +8,10 @@ namespace ComputeSharp.D2D1.Intrinsics; /// An attribute indicating the input type associated with a given D2D HLSL intrinsic. /// /// The input type for the current instance. +/// +/// If this attribute is not present, methods will be considered as supporting all input types. +/// This matches the behavior for , when not present. +/// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] [Conditional("SOURCE_GENERATOR")] internal sealed class HlslD2DIntrinsicInputTypeAttribute(D2D1PixelShaderInputType inputType) : Attribute diff --git a/src/ComputeSharp.D2D1/Intrinsics/D2D.cs b/src/ComputeSharp.D2D1/Intrinsics/D2D.cs index 08e880158..5cb1aa310 100644 --- a/src/ComputeSharp.D2D1/Intrinsics/D2D.cs +++ b/src/ComputeSharp.D2D1/Intrinsics/D2D.cs @@ -17,9 +17,7 @@ public static class D2D /// /// The index of the input texture to get the input from. /// The color from the target input at the current coordinate, in INPUTN format. - /// This method is only available for simple inputs. [HlslIntrinsicName("D2DGetInput")] - [HlslD2DIntrinsicInputType(D2D1PixelShaderInputType.Simple)] public static Float4 GetInput(int index) => throw new InvalidExecutionContextException($"{typeof(D2D)}.{nameof(GetInput)}({typeof(int)})"); /// diff --git a/tests/ComputeSharp.D2D1.Tests.SourceGenerators/Test_D2DPixelShaderDescriptorGenerator_Analyzers.cs b/tests/ComputeSharp.D2D1.Tests.SourceGenerators/Test_D2DPixelShaderDescriptorGenerator_Analyzers.cs index 93fff339a..658f71f93 100644 --- a/tests/ComputeSharp.D2D1.Tests.SourceGenerators/Test_D2DPixelShaderDescriptorGenerator_Analyzers.cs +++ b/tests/ComputeSharp.D2D1.Tests.SourceGenerators/Test_D2DPixelShaderDescriptorGenerator_Analyzers.cs @@ -1354,6 +1354,7 @@ public async Task InvalidInputTypeForD2DIntrinsic_ValidArguments_DoesNotWarn() public float4 Execute() { D2D.GetInput(0); + D2D.GetInput(1); D2D.GetInputCoordinate(1); D2D.SampleInput(1, 0); D2D.SampleInputAtOffset(1, 0); @@ -1381,7 +1382,6 @@ public async Task InvalidInputTypeForD2DIntrinsic_InvalidArguments_Warns() { public float4 Execute() { - {|CMPSD2D0084:D2D.GetInput(1)|}; {|CMPSD2D0084:D2D.GetInputCoordinate(0)|}; {|CMPSD2D0084:D2D.SampleInput(0, 0)|}; {|CMPSD2D0084:D2D.SampleInputAtOffset(0, 0)|};