Example #1
0
    /// <summary>
    /// Creates an <see cref="ID2D1Bitmap"/> instance.
    /// </summary>
    /// <param name="d2D1DeviceContext">The input <see cref="ID2D1DeviceContext"/> instance to use to create the bitmap source.</param>
    /// <param name="width">The width of the bitmap to create.</param>
    /// <param name="height">The height of the bitmap to create.</param>
    /// <returns>A new <see cref="ID2D1Bitmap"/> instance.</returns>
    public static unsafe ComPtr <ID2D1Bitmap> CreateD2D1BitmapAndSetAsTarget(ID2D1DeviceContext *d2D1DeviceContext, uint width, uint height)
    {
        D2D_SIZE_U d2DSize;

        d2DSize.width  = width;
        d2DSize.height = height;

        D2D1_BITMAP_PROPERTIES1 d2DBitmapProperties1Target = default;

        d2DBitmapProperties1Target.pixelFormat.format    = DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM;
        d2DBitmapProperties1Target.pixelFormat.alphaMode = D2D1_ALPHA_MODE.D2D1_ALPHA_MODE_PREMULTIPLIED;
        d2DBitmapProperties1Target.bitmapOptions         =
            D2D1_BITMAP_OPTIONS.D2D1_BITMAP_OPTIONS_TARGET |
            D2D1_BITMAP_OPTIONS.D2D1_BITMAP_OPTIONS_CANNOT_DRAW;

        using ComPtr <ID2D1Bitmap> d2D1Bitmap1Target = default;

        // Create a target D2D1 bitmap
        d2D1DeviceContext->CreateBitmap(
            size: d2DSize,
            sourceData: null,
            pitch: 0,
            bitmapProperties: &d2DBitmapProperties1Target,
            bitmap: (ID2D1Bitmap1 **)d2D1Bitmap1Target.GetAddressOf()).Assert();

        d2D1DeviceContext->SetTarget((ID2D1Image *)d2D1Bitmap1Target.Get());

        return(d2D1Bitmap1Target.Move());
    }
Example #2
0
            public UsedAllocator Move()
            {
                var copy = this;

                copy.Allocator = Allocator.Move();
                return(copy);
            }
Example #3
0
        /// <inheritdoc/>
        public RentedCommandAllocator Move()
        {
            var copy = this;

            copy._value = _value.Move();
            return(copy);
        }
Example #4
0
        public AllocatorAndMarker Move()
        {
            var copy = this;

            copy.Allocator = Allocator.Move();
            return(copy);
        }
Example #5
0
    /// <summary>
    /// Compiles a new HLSL shader from the input source code.
    /// </summary>
    /// <param name="source">The HLSL source code to compile.</param>
    /// <param name="shaderProfile">The shader profile to use to compile the shader.</param>
    /// <param name="options">The options to use to compile the shader.</param>
    /// <returns>The bytecode for the compiled shader.</returns>
    public static ComPtr <ID3DBlob> Compile(ReadOnlySpan <char> source, D2D1ShaderProfile shaderProfile, D2D1CompileOptions options)
    {
        int maxLength = Encoding.ASCII.GetMaxByteCount(source.Length);

        byte[] buffer = ArrayPool <byte> .Shared.Rent(maxLength);

        int writtenBytes = Encoding.ASCII.GetBytes(source, buffer);

        try
        {
            // Compile the standalone D2D1 full shader
            using ComPtr <ID3DBlob> d3DBlobFullShader = CompileShader(
                      source: buffer.AsSpan(0, writtenBytes),
                      macro: ASCII.D2D_FULL_SHADER,
                      d2DEntry: ASCII.Execute,
                      entryPoint: ASCII.Execute,
                      target: ASCII.GetPixelShaderProfile(shaderProfile),
                      flags: (uint)(options& ~D2D1CompileOptions.EnableLinking));

            if ((options & D2D1CompileOptions.EnableLinking) == 0)
            {
                return(d3DBlobFullShader.Move());
            }

            // Compile the export function
            using ComPtr <ID3DBlob> d3DBlobFunction = CompileShader(
                      source: buffer.AsSpan(0, writtenBytes),
                      macro: ASCII.D2D_FUNCTION,
                      d2DEntry: ASCII.Execute,
                      entryPoint: default,
Example #6
0
        private GpuResource AllocateCommitted(GpuResourceDesc desc, D3D12_RESOURCE_ALLOCATION_INFO allocInfo)
        {
            using var device = _device.Copy();

            var heapProperties = GetHeapProperties(desc);

            var clearVal = desc.ClearValue.GetValueOrDefault();

            using ComPtr <ID3D12Resource> resource = default;

            Guard.ThrowIfFailed(device.Get()->CreateCommittedResource(
                                    &heapProperties,
                                    desc.HeapFlags,
                                    &desc.ResourceFormat.D3D12ResourceDesc,
                                    desc.InitialState,
                                    desc.ClearValue is null ? null : &clearVal,
                                    resource.Guid,
                                    ComPtr.GetVoidAddressOf(&resource)
                                    ));

            return(new GpuResource(
                       resource.Move(),
                       desc,
                       allocInfo.SizeInBytes,
                       0,
Example #7
0
        public GpuCommandSet Move()
        {
            var copy = this;

            copy.List      = List.Move();
            copy.Allocator = Allocator.Move();
            return(copy);
        }
Example #8
0
        internal GraphicsContext(ComPtr <ID3D12GraphicsCommandList> list, ComPtr <ID3D12CommandAllocator> allocator)
        {
            Debug.Assert(list.Exists);
            Debug.Assert(allocator.Exists);

            _list      = list.Move();
            _allocator = allocator.Move();
        }
Example #9
0
        // TODO root sig flags (when exposed)

        private RootSignature(
            ComPtr <ID3D12RootSignature> value,
            ReadOnlyMemory <RootParameter> parameters,
            ReadOnlyMemory <StaticSampler> staticSamplers
            )
        {
            _value         = value.Move();
            Parameters     = parameters;
            StaticSamplers = staticSamplers;
        }
Example #10
0
        public ComPtr <IDxcBlob> CompileShader(ReadOnlySpan <char> source)
        {
            using ComPtr <IDxcBlobEncoding> dxcBlobEncoding       = default;
            using ComPtr <IDxcOperationResult> dxcOperationResult = default;
            using ComPtr <IDxcBlob> dxcBlobBytecode = default;

            // Get the encoded blob from the source code
            fixed(char *p = source)
            {
                DxcLibrary.Get()->CreateBlobWithEncodingOnHeapCopy(
                    p,
                    (uint)source.Length * 2,
                    1200,
                    dxcBlobEncoding.GetAddressOf()).Assert();
            }

            // Try to compile the new compute shader
            fixed(char *shaderName = "")
            fixed(char *entryPoint       = nameof(IComputeShader.Execute))
            fixed(char *shaderProfile    = "cs_6_0")
            fixed(char *optimization     = "-O3")
            fixed(char *rowMajor         = "-Zpr")
            fixed(char *warningsAsErrors = "-Werror")
            {
                char **arguments = stackalloc char *[3] {
                    optimization, rowMajor, warningsAsErrors
                };

                DxcCompiler.Get()->Compile(
                    (IDxcBlob *)dxcBlobEncoding.Get(),
                    (ushort *)shaderName,
                    (ushort *)entryPoint,
                    (ushort *)shaderProfile,
                    (ushort **)arguments,
                    3,
                    null,
                    0,
                    DxcIncludeHandler.Get(),
                    dxcOperationResult.GetAddressOf()).Assert();
            }

            int status;

            dxcOperationResult.Get()->GetStatus(&status).Assert();

            // The compilation was successful, so we can extract the shader bytecode
            if (status == 0)
            {
                dxcOperationResult.Get()->GetResult(dxcBlobBytecode.GetAddressOf()).Assert();

                return(dxcBlobBytecode.Move());
            }

            return(ThrowHslsCompilationException(dxcOperationResult));
        }
Example #11
0
    /// <summary>
    /// Creates an <see cref="ID2D1DeviceContext"/> instance.
    /// </summary>
    /// <param name="d2D1Device">The input <see cref="ID2D1Device"/> instance to use to create the context.</param>
    /// <returns>A new <see cref="ID2D1DeviceContext"/> instance.</returns>
    public static unsafe ComPtr <ID2D1DeviceContext> CreateD2D1DeviceContext(ID2D1Device *d2D1Device)
    {
        using ComPtr <ID2D1DeviceContext> d2D1DeviceContext = default;

        // Create a D2D1 device context
        d2D1Device->CreateDeviceContext(
            options: D2D1_DEVICE_CONTEXT_OPTIONS.D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
            deviceContext: d2D1DeviceContext.GetAddressOf()).Assert();

        return(d2D1DeviceContext.Move());
    }
Example #12
0
        private const ulong HighestRequiredAlign = 1024 * 1024 * 4; // 4mb

        /// <summary>
        /// Creates a new allocator
        /// </summary>
        /// <param name="device">The <see cref="ID3D12Device"/> to allocate on</param>
        public GpuAllocator(ComPtr <ID3D12Device> device)
        {
            Debug.Assert(device.Exists);
            _device = device.Move();

            _heaps[GpuMemoryType.CpuReadOptimized]  = new();
            _heaps[GpuMemoryType.CpuWriteOptimized] = new();
            _heaps[GpuMemoryType.GpuOnly]           = new();

            CreateNewHeap(GpuMemoryType.CpuReadOptimized);
            CreateNewHeap(GpuMemoryType.CpuWriteOptimized);
            CreateNewHeap(GpuMemoryType.GpuOnly);
        }
Example #13
0
    /// <summary>
    /// Creates a new <see cref="WICHelper"/> instance.
    /// </summary>
    private WICHelper()
    {
        using ComPtr <IWICImagingFactory2> wicImagingFactory2 = default;

        Windows.CoCreateInstance(
            (Guid *)Unsafe.AsPointer(ref Unsafe.AsRef(in CLSID.CLSID_WICImagingFactory2)),
            null,
            (uint)CLSCTX.CLSCTX_INPROC_SERVER,
            Windows.__uuidof <IWICImagingFactory2>(),
            wicImagingFactory2.GetVoidAddressOf()).Assert();

        this.wicImagingFactory2 = wicImagingFactory2.Move();
    }
Example #14
0
    /// <summary>
    /// Creates an <see cref="ID2D1Bitmap"/> instance.
    /// </summary>
    /// <param name="d2D1DeviceContext">The input <see cref="ID2D1DeviceContext"/> instance to use to create the bitmap source.</param>
    /// <param name="wicBitmap">The input <see cref="IWICBitmap"/> to use to create the bitmap source.</param>
    /// <param name="d2D1Effect">The input <see cref="ID2D1Effect"/> to set the source for.</param>
    /// <returns>A new <see cref="ID2D1Bitmap"/> instance.</returns>
    public static unsafe ComPtr <ID2D1Bitmap> CreateD2D1BitmapAndSetAsSource(ID2D1DeviceContext *d2D1DeviceContext, IWICBitmap *wicBitmap, ID2D1Effect *d2D1Effect)
    {
        using ComPtr <ID2D1Bitmap> d2D1BitmapSource = default;

        // Create a source D2D1 bitmap from the WIC bitmap
        d2D1DeviceContext->CreateBitmapFromWicBitmap(
            wicBitmapSource: (IWICBitmapSource *)wicBitmap,
            bitmap: d2D1BitmapSource.GetAddressOf()).Assert();

        d2D1Effect->SetInput(0, (ID2D1Image *)d2D1BitmapSource.Get());

        return(d2D1BitmapSource.Move());
    }
        protected override ComPtr <ID3D12CommandAllocator> Create(ExecutionContext state)
        {
            using ComPtr <ID3D12CommandAllocator> allocator = default;
            Guard.ThrowIfFailed(_device.Get()->CreateCommandAllocator(
                                    (D3D12_COMMAND_LIST_TYPE)state,
                                    allocator.Guid,
                                    ComPtr.GetVoidAddressOf(&allocator)
                                    ));

            DirectXHelpers.SetObjectName(allocator.Get(), $"Pooled allocator #{_allocatorCount++}");

            return(allocator.Move());
        }
Example #16
0
        // this is a hack. TODO make it right
        internal static GpuResource FromRenderTarget(
            ComPtr <ID3D12Resource> resource
            )
        {
            var desc = resource.Get()->GetDesc();

            return(new GpuResource
            {
                _value = resource.Move(),
                Type = (GpuMemoryType)(-1) /* TODO wtf should we have here */,
                ResourceFormat = desc.Format,
                State = D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_COMMON
            });
        }
Example #17
0
    /// <summary>
    /// Creates an <see cref="ID2D1Factory2"/> instance.
    /// </summary>
    /// <returns>A new <see cref="ID2D1Factory2"/> instance.</returns>
    public static unsafe ComPtr <ID2D1Factory2> CreateD2D1Factory2()
    {
        using ComPtr <ID2D1Factory2> d2D1Factory2 = default;

        D2D1_FACTORY_OPTIONS d2D1FactoryOptions = default;

        // Create a Direct2D factory
        DirectX.D2D1CreateFactory(
            factoryType: D2D1_FACTORY_TYPE.D2D1_FACTORY_TYPE_SINGLE_THREADED,
            riid: Windows.__uuidof <ID2D1Factory2>(),
            pFactoryOptions: &d2D1FactoryOptions,
            ppIFactory: (void **)d2D1Factory2.GetAddressOf()).Assert();

        return(d2D1Factory2.Move());
    }
    /// <summary>
    /// Compiles a new HLSL shader from the input source code.
    /// </summary>
    /// <param name="source">The HLSL source code to compile.</param>
    /// <param name="shaderProfile">The shader profile to use to compile the shader.</param>
    /// <param name="enableLinkingSupport">Whether to enable linking support for the shader.</param>
    /// <returns>The bytecode for the compiled shader.</returns>
    public static ComPtr <ID3DBlob> Compile(ReadOnlySpan <char> source, D2D1ShaderProfile shaderProfile, bool enableLinkingSupport)
    {
        // Compile the standalone D2D1 full shader
        using ComPtr <ID3DBlob> d3DBlobFullShader = CompileD2DFullShader(source, shaderProfile);

        if (!enableLinkingSupport)
        {
            return(d3DBlobFullShader.Move());
        }

        // Compile the export function and embed it as private data if requested
        using ComPtr <ID3DBlob> d3DBlobFunction = CompileD2DFunction(source, shaderProfile);
        using ComPtr <ID3DBlob> d3DBlobLinked   = EmbedD2DFunctionPrivateData(d3DBlobFullShader.Get(), d3DBlobFunction.Get());

        return(d3DBlobLinked.Move());
    }
    /// <summary>
    /// Creates a <see cref="D3D12MA_Pool"/> instance suited to be used for cache coherent UMA devices.
    /// </summary>
    /// <param name="allocator">The <see cref="D3D12MA_Allocator"/> instance in use.</param>
    /// <returns>A <see cref="D3D12MA_Pool"/> instance suited to be used for cache coherent UMA devices.</returns>
    public static ComPtr <D3D12MA_Pool> CreatePoolForCacheCoherentUMA(this ref D3D12MA_Allocator allocator)
    {
        using ComPtr <D3D12MA_Pool> pool = default;

        D3D12MA_POOL_DESC poolDesc = default;

        poolDesc.HeapProperties.CreationNodeMask     = 1;
        poolDesc.HeapProperties.VisibleNodeMask      = 1;
        poolDesc.HeapProperties.Type                 = D3D12_HEAP_TYPE_CUSTOM;
        poolDesc.HeapProperties.CPUPageProperty      = D3D12_CPU_PAGE_PROPERTY_WRITE_BACK;
        poolDesc.HeapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_L0;

        allocator.CreatePool(&poolDesc, pool.GetAddressOf()).Assert();

        return(pool.Move());
    }
        /// <summary>
        /// Gets a new or reused <see cref="ID3D12CommandAllocator"/> item to use to issue GPU commands.
        /// </summary>
        /// <returns>The rented <see cref="ID3D12CommandAllocator"/> object to use.</returns>
        public ComPtr <ID3D12CommandAllocator> GetCommandAllocator(ID3D12Device *d3D12Device, ID3D12Fence *d3D12Fence)
        {
            using ComPtr <ID3D12CommandAllocator> d3D12CommandAllocator = default;

            lock (this.d3D12CommandAllocatorQueue)
            {
                if (this.d3D12CommandAllocatorQueue.TryDequeue(out * & d3D12CommandAllocator))
                {
                    d3D12CommandAllocator.Get()->Reset().Assert();

                    return(d3D12CommandAllocator.Move());
                }

                return(d3D12Device->CreateCommandAllocator(this.d3D12CommandListType));
            }
        }
Example #21
0
        private DescriptorHeap(ID3D12Device *device, D3D12_DESCRIPTOR_HEAP_DESC desc)
        {
            ComPtr <ID3D12DescriptorHeap> heap = default;

            Guard.ThrowIfFailed(device->CreateDescriptorHeap(&desc, heap.Guid, (void **)&heap));

            _heap = heap.Move();
            var cpu = _heap.Get()->GetCPUDescriptorHandleForHeapStart();
            var gpu = _heap.Get()->GetGPUDescriptorHandleForHeapStart();

            FirstDescriptor = new DescriptorHandle(cpu, gpu, desc.Type);

            Type           = desc.Type;
            NumDescriptors = desc.NumDescriptors;

            DirectXHelpers.SetObjectName(_heap.Get(), nameof(ID3D12DescriptorHeap));
        }
Example #22
0
        /// <summary>
        /// Creates a new <see cref="RootSignature"/>
        /// </summary>
        /// <param name="device">The <see cref="ID3D12Device"/> used to create the root signature</param>
        /// <param name="rootParameters">The <see cref="RootParameter"/>s in the signature</param>
        /// <param name="staticSamplers">The <see cref="StaticSampler"/>s in the signature</param>
        /// <returns>A new <see cref="RootSignature"/></returns>
        public static RootSignature Create(ID3D12Device *device, ReadOnlyMemory <RootParameter> rootParameters, ReadOnlyMemory <StaticSampler> staticSamplers)
        {
            using var rootParams = RentedArray <D3D12_ROOT_PARAMETER> .Create(rootParameters.Length);

            using var samplers = RentedArray <D3D12_STATIC_SAMPLER_DESC> .Create(staticSamplers.Length);

            TranslateStaticSamplers(staticSamplers, samplers.Value);

            fixed(D3D12_ROOT_PARAMETER *pRootParams = rootParams.Value)
            fixed(D3D12_STATIC_SAMPLER_DESC * pSamplerDesc = samplers.Value)
            {
                var desc = new D3D12_ROOT_SIGNATURE_DESC
                {
                    NumParameters     = (uint)rootParams.Value.Length,
                    pParameters       = pRootParams,
                    NumStaticSamplers = (uint)samplers.Value.Length,
                    pStaticSamplers   = pSamplerDesc,
                    Flags             = D3D12_ROOT_SIGNATURE_FLAGS.D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT // TODO provide finer grained control
                };

                ID3DBlob *pBlob  = default;
                ID3DBlob *pError = default;
                int       hr     = Windows.D3D12SerializeRootSignature(
                    &desc,
                    D3D_ROOT_SIGNATURE_VERSION.D3D_ROOT_SIGNATURE_VERSION_1,
                    &pBlob,
                    &pError
                    );

                if (Windows.FAILED(hr))
                {
                    ThrowHelper.ErrorWithBlob(hr, pError);
                }

                using ComPtr <ID3D12RootSignature> rootSig = default;
                Guard.ThrowIfFailed(device->CreateRootSignature(
                                        0 /* TODO: MULTI-GPU */,
                                        pBlob->GetBufferPointer(),
                                        pBlob->GetBufferSize(),
                                        rootSig.Guid,
                                        ComPtr.GetVoidAddressOf(&rootSig)
                                        ));

                return(new RootSignature(rootSig.Move(), rootParameters, staticSamplers));
            }
        }
Example #23
0
    /// <summary>
    /// Creates an <see cref="ID2D1Device"/> instance.
    /// </summary>
    /// <param name="d2D1Factory2">The input <see cref="ID2D1Factory2"/> instance to use to create the device.</param>
    /// <returns>A new <see cref="ID2D1Device"/> instance.</returns>
    public static unsafe ComPtr <ID2D1Device> CreateD2D1Device(ID2D1Factory2 *d2D1Factory2)
    {
        using ComPtr <ID3D11Device> d3D11Device = default;

        uint creationFlags = (uint)D3D11_CREATE_DEVICE_FLAG.D3D11_CREATE_DEVICE_BGRA_SUPPORT;
        D3D_FEATURE_LEVEL *featureLevels = stackalloc[]
        {
            D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_11_1,
            D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_11_0,
            D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_10_1,
            D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_10_0,
            D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_9_3,
            D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_9_2,
            D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_9_1
        };
        D3D_FEATURE_LEVEL d3DFeatureLevel;

        // Create the Direct3D 11 API device and context
        DirectX.D3D11CreateDevice(
            pAdapter: null,
            DriverType: D3D_DRIVER_TYPE.D3D_DRIVER_TYPE_HARDWARE,
            Software: HMODULE.NULL,
            Flags: creationFlags,
            pFeatureLevels: featureLevels,
            FeatureLevels: 7,
            SDKVersion: D3D11.D3D11_SDK_VERSION,
            ppDevice: d3D11Device.GetAddressOf(),
            pFeatureLevel: &d3DFeatureLevel,
            ppImmediateContext: null).Assert();

        using ComPtr <IDXGIDevice3> dxgiDevice3 = default;

        // Get a DXGI device from the D3D11 device
        d3D11Device.CopyTo(dxgiDevice3.GetAddressOf()).Assert();

        using ComPtr <ID2D1Device> d2D1Device = default;

        // Create a D2D1 device
        d2D1Factory2->CreateDevice(
            dxgiDevice: (IDXGIDevice *)dxgiDevice3.Get(),
            d2dDevice: d2D1Device.GetAddressOf());

        return(d2D1Device.Move());
    }
Example #24
0
        protected override ComPtr <ID3D12GraphicsCommandList> Create(ListCreationParams state)
        {
            using ComPtr <ID3D12GraphicsCommandList> list = default;
            Guard.ThrowIfFailed(_device.Get()->CreateCommandList(
                                    0, // TODO: MULTI-GPU
                                    state.Type,
                                    state.Allocator,
                                    state.Pso,
                                    list.Guid,
                                    ComPtr.GetVoidAddressOf(&list)
                                    ));

            DirectXHelpers.SetObjectName(list.Get(), $"Pooled list #{_listCount++}");

            // 'ManageRent' expects closed list
            Guard.ThrowIfFailed(list.Get()->Close());

            return(list.Move());
        }
Example #25
0
        internal GpuResource(
            ComPtr <ID3D12Resource> resource,
            GpuResourceDesc desc,
            ulong size,
            ulong offset,
            AllocatorHeap heap,
            GpuAllocator allocator
            )
        {
            _value         = resource.Move();
            State          = desc.InitialState;
            ResourceFormat = desc.Format;
            Type           = desc.GpuMemoryType;
            _size          = size;
            _offset        = offset;
            _heap          = heap;
            _allocator     = allocator;

            GpuAddress = UnderlyingResource->GetGPUVirtualAddress();
        }
Example #26
0
        private AllocatorHeap CreateNewHeap(GpuMemoryType type)
        {
            D3D12_HEAP_PROPERTIES props = new((D3D12_HEAP_TYPE)type);
            D3D12_HEAP_DESC       desc  = new(InitialHeapSize, props);

            ComPtr <ID3D12Heap> heap = default;

            _device.Get()->CreateHeap(&desc, heap.Guid, ComPtr.GetVoidAddressOf(&heap));

            var allocatorHeap = new AllocatorHeap {
                Heap = heap.Move(), FreeBlocks = new()
            };

            allocatorHeap.FreeBlocks.Add(new HeapBlock {
                Offset = 0, Size = desc.SizeInBytes
            });
            _heaps[type].Add(allocatorHeap);

            return(allocatorHeap);
        }
    /// <summary>
    /// Embeds the bytecode for an exported shader as private data into another shader bytecode.
    /// </summary>
    /// <param name="shaderBlob">The bytecode produced by <see cref="CompileD2DFullShader(ReadOnlySpan{char}, D2D1ShaderProfile)"/>.</param>
    /// <param name="exportBlob">The bytecode produced by <see cref="CompileD2DFunction(ReadOnlySpan{char}, D2D1ShaderProfile)"/>.</param>
    /// <returns>An <see cref="ID3DBlob"/> instance with the combined data of <paramref name="shaderBlob"/> and <paramref name="exportBlob"/>.</returns>
    private static ComPtr <ID3DBlob> EmbedD2DFunctionPrivateData(ID3DBlob *shaderBlob, ID3DBlob *exportBlob)
    {
        void *shaderPtr  = shaderBlob->GetBufferPointer();
        nuint shaderSize = shaderBlob->GetBufferSize();

        void *exportPtr  = exportBlob->GetBufferPointer();
        nuint exportSize = exportBlob->GetBufferSize();

        using ComPtr <ID3DBlob> resultBlob = default;

        DirectX.D3DSetBlobPart(
            pSrcData: shaderPtr,
            SrcDataSize: shaderSize,
            Part: D3D_BLOB_PART.D3D_BLOB_PRIVATE_DATA,
            Flags: 0,
            pPart: exportPtr,
            PartSize: exportSize,
            ppNewShader: resultBlob.GetAddressOf()).Assert();

        return(resultBlob.Move());
    }
    /// <summary>
    /// Creates a new <see cref="ShaderCompiler"/> instance.
    /// </summary>
    private ShaderCompiler()
    {
        using ComPtr <IDxcCompiler> dxcCompiler             = default;
        using ComPtr <IDxcLibrary> dxcLibrary               = default;
        using ComPtr <IDxcIncludeHandler> dxcIncludeHandler = default;

        DirectX.DxcCreateInstance(
            (Guid *)Unsafe.AsPointer(ref Unsafe.AsRef(in CLSID.CLSID_DxcCompiler)),
            Windows.__uuidof <IDxcCompiler>(),
            dxcCompiler.GetVoidAddressOf()).Assert();

        DirectX.DxcCreateInstance(
            (Guid *)Unsafe.AsPointer(ref Unsafe.AsRef(in CLSID.CLSID_DxcLibrary)),
            Windows.__uuidof <IDxcLibrary>(),
            dxcLibrary.GetVoidAddressOf()).Assert();

        dxcLibrary.Get()->CreateIncludeHandler(dxcIncludeHandler.GetAddressOf()).Assert();

        DxcCompiler       = dxcCompiler.Move();
        DxcLibrary        = dxcLibrary.Move();
        DxcIncludeHandler = dxcIncludeHandler.Move();
    }
Example #29
0
    /// <summary>
    /// Creates an <see cref="ID2D1Bitmap1"/> instance and copies data from a source bitmap.
    /// </summary>
    /// <param name="d2D1DeviceContext">The input <see cref="ID2D1DeviceContext"/> instance to use to create the bitmap.</param>
    /// <param name="d2D1Bitmap">The input <see cref="ID2D1Bitmap1"/> to read data from.</param>
    /// <param name="d2D1MappedRect">The resulting <see cref="D2D1_MAPPED_RECT"/> for the bitmap.</param>
    /// <returns>A new <see cref="ID2D1Bitmap1"/> instance.</returns>
    public static unsafe ComPtr <ID2D1Bitmap1> CreateD2D1Bitmap1Buffer(ID2D1DeviceContext *d2D1DeviceContext, ID2D1Bitmap *d2D1Bitmap, out D2D1_MAPPED_RECT d2D1MappedRect)
    {
        D2D_SIZE_U d2DSize = d2D1Bitmap->GetPixelSize();

        D2D1_BITMAP_PROPERTIES1 d2DBitmapProperties1Buffer = default;

        d2DBitmapProperties1Buffer.pixelFormat.format    = DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM;
        d2DBitmapProperties1Buffer.pixelFormat.alphaMode = D2D1_ALPHA_MODE.D2D1_ALPHA_MODE_PREMULTIPLIED;
        d2DBitmapProperties1Buffer.bitmapOptions         = D2D1_BITMAP_OPTIONS.D2D1_BITMAP_OPTIONS_CPU_READ | D2D1_BITMAP_OPTIONS.D2D1_BITMAP_OPTIONS_CANNOT_DRAW;

        using ComPtr <ID2D1Bitmap1> d2D1Bitmap1Buffer = default;

        // Create a buffer D2D1 bitmap
        d2D1DeviceContext->CreateBitmap(
            size: d2DSize,
            sourceData: null,
            pitch: 0,
            bitmapProperties: &d2DBitmapProperties1Buffer,
            bitmap: d2D1Bitmap1Buffer.GetAddressOf()).Assert();

        D2D_POINT_2U d2DPointDestination = default;
        D2D_RECT_U   d2DRectSource       = new(0, 0, d2DSize.width, d2DSize.height);

        // Copy the image from the target to the readback bitmap
        d2D1Bitmap1Buffer.Get()->CopyFromBitmap(
            destPoint: &d2DPointDestination,
            bitmap: d2D1Bitmap,
            srcRect: &d2DRectSource);

        fixed(D2D1_MAPPED_RECT *d2D1MappedRectPtr = &d2D1MappedRect)
        {
            // Map the buffer bitmap
            d2D1Bitmap1Buffer.Get()->Map(
                options: D2D1_MAP_OPTIONS.D2D1_MAP_OPTIONS_READ,
                mappedRect: d2D1MappedRectPtr).Assert();
        }

        return(d2D1Bitmap1Buffer.Move());
    }
        /// <summary>
        /// Creates a new <see cref="ID3D12InfoQueue"/> for a given device.
        /// </summary>
        /// <param name="d3D12Device">The target <see cref="ID3D12Device"/> to use to create the info queue.</param>
        /// <returns>A pointer to the newly created <see cref="ID3D12InfoQueue"/> instance.</returns>
        /// <exception cref="Exception">Thrown when the creation of the info queue fails.</exception>
        public static ComPtr <ID3D12InfoQueue> CreateInfoQueue(this ref ID3D12Device d3D12Device)
        {
            ComPtr <ID3D12InfoQueue> d3D12InfoQueue = default;

            d3D12Device.QueryInterface(FX.__uuidof <ID3D12InfoQueue>(), d3D12InfoQueue.GetVoidAddressOf()).Assert();

            D3D12_MESSAGE_ID *d3D12MessageIds = stackalloc D3D12_MESSAGE_ID[3]
            {
                D3D12_MESSAGE_ID_CREATEDEVICE_DEBUG_LAYER_STARTUP_OPTIONS,
                D3D12_MESSAGE_ID_MAP_INVALID_NULLRANGE,
                D3D12_MESSAGE_ID_UNMAP_INVALID_NULLRANGE
            };

            D3D12_INFO_QUEUE_FILTER d3D12InfoQueueFilter = default;

            d3D12InfoQueueFilter.DenyList.NumIDs  = 3;
            d3D12InfoQueueFilter.DenyList.pIDList = d3D12MessageIds;

            d3D12InfoQueue.Get()->PushRetrievalFilter(&d3D12InfoQueueFilter).Assert();

            return(d3D12InfoQueue.Move());
        }