/// <summary> /// Loads or compiles the bytecode from an input D2D1 pixel shader. /// </summary> /// <typeparam name="T">The type of D2D1 pixel shader to load the bytecode for.</typeparam> /// <param name="shaderProfile">The shader profile to use to get the shader bytecode.</param> /// <returns>A <see cref="ReadOnlyMemory{T}"/> instance with the resulting shader bytecode.</returns> /// <exception cref="InvalidOperationException">Thrown if the input shader has not been precompiled.</exception> private static ReadOnlyMemory <byte> LoadOrCompilePixelShaderBytecode <T>(D2D1ShaderProfile?shaderProfile) where T : unmanaged, ID2D1PixelShader { D2D1ShaderBytecodeLoader bytecodeLoader = default; Unsafe.SkipInit(out T shader); shader.LoadBytecode(ref bytecodeLoader, shaderProfile); using ComPtr <ID3DBlob> dynamicBytecode = bytecodeLoader.GetResultingShaderBytecode(out ReadOnlySpan <byte> precompiledBytecode); // If a precompiled shader is available, return it if (!precompiledBytecode.IsEmpty) { return(new PinnedBufferMemoryManager(precompiledBytecode).Memory); } // Otherwise, return the dynamic shader instead byte *bytecodePtr = (byte *)dynamicBytecode.Get()->GetBufferPointer(); int bytecodeSize = (int)dynamicBytecode.Get()->GetBufferSize(); return(new ReadOnlySpan <byte>(bytecodePtr, bytecodeSize).ToArray()); }
/// <summary> /// Gets the shader info associated with a given D2D1 shader. /// </summary> /// <typeparam name="T">The type of D2D1 shader to retrieve info for.</typeparam> /// <returns>The resulting <see cref="D2D1ShaderInfo"/> instance.</returns> public static unsafe D2D1ShaderInfo GetShaderInfo <T>() where T : struct, ID2D1PixelShader { Unsafe.SkipInit(out T shader); shader.BuildHlslSource(out string hlslSource); D2D1ShaderBytecodeLoader bytecodeLoader = default; shader.LoadBytecode(ref bytecodeLoader, D2D1ShaderProfile.PixelShader50); using ComPtr <ID3DBlob> dynamicBytecode = bytecodeLoader.GetResultingShaderBytecode(out ReadOnlySpan <byte> precompiledBytecode); byte *bytecodePtr; int bytecodeSize; if (!precompiledBytecode.IsEmpty) { bytecodePtr = (byte *)Unsafe.AsPointer(ref MemoryMarshal.GetReference(precompiledBytecode)); bytecodeSize = precompiledBytecode.Length; } else { bytecodePtr = (byte *)dynamicBytecode.Get()->GetBufferPointer(); bytecodeSize = (int)dynamicBytecode.Get()->GetBufferSize(); } using ComPtr <ID3D11ShaderReflection> d3D11ShaderReflection = default; DirectX.D3DReflect( pSrcData: bytecodePtr, SrcDataSize: (nuint)bytecodeSize, pInterface: Windows.__uuidof <ID3D11ShaderReflection>(), ppReflector: d3D11ShaderReflection.GetVoidAddressOf()).Assert(); D3D11_SHADER_DESC d3D11ShaderDescription; d3D11ShaderReflection.Get()->GetDesc(&d3D11ShaderDescription).Assert(); return(new( CompilerVersion : new string(d3D11ShaderDescription.Creator), HlslSource : hlslSource, ConstantBufferCount : d3D11ShaderDescription.ConstantBuffers, BoundResourceCount : d3D11ShaderDescription.BoundResources, InstructionCount : d3D11ShaderDescription.InstructionCount, TemporaryRegisterCount : d3D11ShaderDescription.TempRegisterCount, TemporaryArrayCount : d3D11ShaderDescription.TempArrayCount, ConstantDefineCount : d3D11ShaderDescription.DefCount, DeclarationCount : d3D11ShaderDescription.DclCount, TextureNormalInstructions : d3D11ShaderDescription.TextureNormalInstructions, TextureLoadInstructionCount : d3D11ShaderDescription.TextureLoadInstructions, TextureStoreInstructionCount : d3D11ShaderDescription.cTextureStoreInstructions, FloatInstructionCount : d3D11ShaderDescription.FloatInstructionCount, IntInstructionCount : d3D11ShaderDescription.IntInstructionCount, UIntInstructionCount : d3D11ShaderDescription.UintInstructionCount, StaticFlowControlInstructionCount : d3D11ShaderDescription.StaticFlowControlCount, DynamicFlowControlInstructionCount : d3D11ShaderDescription.DynamicFlowControlCount, EmitInstructionCount : d3D11ShaderDescription.EmitInstructionCount, BarrierInstructionCount : d3D11ShaderDescription.cBarrierInstructions, InterlockedInstructionCount : d3D11ShaderDescription.cInterlockedInstructions, BitwiseInstructionCount : d3D11ShaderReflection.Get()->GetBitwiseInstructionCount(), MovcInstructionCount : d3D11ShaderReflection.Get()->GetMovcInstructionCount(), MovInstructionCount : d3D11ShaderReflection.Get()->GetMovInstructionCount(), InterfaceSlotCount : d3D11ShaderReflection.Get()->GetNumInterfaceSlots(), RequiresDoublePrecisionSupport : (d3D11ShaderReflection.Get()->GetRequiresFlags() & (D3D.D3D_SHADER_REQUIRES_DOUBLES | D3D.D3D_SHADER_REQUIRES_11_1_DOUBLE_EXTENSIONS)) != 0)); }