Ejemplo n.º 1
0
    internal GraphicsRenderTarget(GraphicsSwapchain swapchain, int index) : base(swapchain)
    {
        _index = index;

        _d3d12RtvDescriptorHandle = GetD3D12RtvDescriptorHandle();

        var d3d12RtvResource = CreateD3D12RtvResource(out _d3d12RtvResourceVersion);

        _d3d12RtvResource.Attach(d3d12RtvResource);

        ID3D12Resource *CreateD3D12RtvResource(out uint d3d12RtvResourceVersion)
        {
            var d3d12RenderTargetViewDesc = new D3D12_RENDER_TARGET_VIEW_DESC {
                Format        = swapchain.RenderTargetFormat.AsDxgiFormat(),
                ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D,
                Texture2D     = new D3D12_TEX2D_RTV()
            };

            ID3D12Resource *d3d12RtvResource;

            ThrowExternalExceptionIfFailed(swapchain.DxgiSwapchain->GetBuffer((uint)_index, __uuidof <ID3D12Resource>(), (void **)&d3d12RtvResource));

            swapchain.Device.D3D12Device->CreateRenderTargetView(d3d12RtvResource, &d3d12RenderTargetViewDesc, _d3d12RtvDescriptorHandle);
            return(GetLatestD3D12Resource(d3d12RtvResource, out d3d12RtvResourceVersion));
        }

        D3D12_CPU_DESCRIPTOR_HANDLE GetD3D12RtvDescriptorHandle()
        {
            var d3d12RtvDescriptorHandleIncrementSize = Device.D3D12RtvDescriptorSize;
            var d3d12RtvDescriptorHandleForHeapStart  = Swapchain.D3D12RtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart();

            D3D12_CPU_DESCRIPTOR_HANDLE.InitOffsetted(out var d3d12RtvDescriptorHandle, d3d12RtvDescriptorHandleForHeapStart, _index, d3d12RtvDescriptorHandleIncrementSize);
            return(d3d12RtvDescriptorHandle);
        }
    }
Ejemplo n.º 2
0
    private protected GraphicsCommandQueue(GraphicsDevice device, GraphicsContextKind kind) : base(device)
    {
        var d3d12CommandListType = kind.AsD3D12CommandListType();

        var d3d12CommandQueue = CreateD3D12CommandQueue(d3d12CommandListType, out _d3d12CommandQueueVersion);

        _d3d12CommandQueue.Attach(d3d12CommandQueue);

        _kind = kind;

        _waitForIdleFence = device.CreateFence(isSignalled: false);

        SetNameUnsafe(Name);

        ID3D12CommandQueue *CreateD3D12CommandQueue(D3D12_COMMAND_LIST_TYPE d3d12CommandListType, out uint d3d12CommandQueueVersion)
        {
            ID3D12CommandQueue *d3d12CommandQueue;

            var d3d12CommandQueueDesc = new D3D12_COMMAND_QUEUE_DESC {
                Type     = d3d12CommandListType,
                Priority = 0,
                Flags    = D3D12_COMMAND_QUEUE_FLAG_NONE,
                NodeMask = 0,
            };

            ThrowExternalExceptionIfFailed(Device.D3D12Device->CreateCommandQueue(&d3d12CommandQueueDesc, __uuidof <ID3D12CommandQueue>(), (void **)&d3d12CommandQueue));

            return(GetLatestD3D12CommandQueue(d3d12CommandQueue, out d3d12CommandQueueVersion));
        }
    }
Ejemplo n.º 3
0
    /// <summary>Initializes a new instance of the <see cref="GraphicsService" /> class.</summary>
    public GraphicsService() : base(name: null)
    {
        var dxgiFactory = CreateDxgiFactory(out _dxgiFactoryVersion);

        _dxgiFactory.Attach(dxgiFactory);

        _adapters = GetAdapters(dxgiFactory);
Ejemplo n.º 4
0
    /// <summary>Converts the current object reference to a type indicated by the given IID and assigns that to a target <see cref="ComPtr{T}"/> value.</summary>
    /// <param name="riid">The IID indicating the interface type to convert the COM object reference to.</param>
    /// <param name="other">A reference to the target <see cref="ComPtr{T}"/> value to write to.</param>
    /// <returns>The result of <see cref="IUnknown.QueryInterface"/> for the target IID.</returns>
    /// <remarks>This method will automatically release the target COM object pointed to by <paramref name="other"/>, if any.</remarks>
    public readonly HRESULT AsIID(Guid *riid, ref ComPtr <IUnknown> other)
    {
        IUnknown *ptr;
        HRESULT   result = ptr_->QueryInterface(riid, (void **)&ptr);

        other.Attach(ptr);
        return(result);
    }
Ejemplo n.º 5
0
    /// <summary>Converts the current object reference to type <typeparamref name="U"/> and assigns that to a target <see cref="ComPtr{T}"/> value.</summary>
    /// <typeparam name="U">The interface type to use to try casting the current COM object.</typeparam>
    /// <param name="other">A reference to the target <see cref="ComPtr{T}"/> value to write to.</param>
    /// <returns>The result of <see cref="IUnknown.QueryInterface"/> for the target type <typeparamref name="U"/>.</returns>
    /// <remarks>This method will automatically release the target COM object pointed to by <paramref name="other"/>, if any.</remarks>
    public readonly HRESULT As <U>(ref ComPtr <U> other)
        where U : unmanaged, IUnknown.Interface
    {
        U *     ptr;
        HRESULT result = ptr_->QueryInterface(__uuidof <U>(), (void **)&ptr);

        other.Attach(ptr);
        return(result);
    }
Ejemplo n.º 6
0
    private protected GraphicsContext(GraphicsCommandQueue commandQueue, GraphicsContextKind kind) : base(commandQueue)
    {
        // No need for a CommandQueue.AddContext(this) as it will be done by the underlying pool

        var d3d12CommandListType = kind.AsD3D12CommandListType();

        var d3d12CommandAllocator = CreateD3D12CommandAllocator(d3d12CommandListType, out _d3d12CommandAllocatorVersion);

        _d3d12CommandAllocator.Attach(d3d12CommandAllocator);

        var d3d12GraphicsCommandList = CreateD3D12GraphicsCommandList(d3d12CommandListType, out _d3d12GraphicsCommandListVersion);

        _d3d12GraphicsCommandList.Attach(d3d12GraphicsCommandList);

        _kind  = kind;
        _fence = Device.CreateFence(isSignalled: true);

        SetNameUnsafe(Name);

        ID3D12CommandAllocator *CreateD3D12CommandAllocator(D3D12_COMMAND_LIST_TYPE d3d12CommandListType, out uint d3d12CommandAllocatorVersion)
        {
            ID3D12CommandAllocator *d3d12CommandAllocator;

            ThrowExternalExceptionIfFailed(Device.D3D12Device->CreateCommandAllocator(d3d12CommandListType, __uuidof <ID3D12CommandAllocator>(), (void **)&d3d12CommandAllocator));
            return(GetLatestD3D12CommandAllocator(d3d12CommandAllocator, out d3d12CommandAllocatorVersion));
        }

        ID3D12GraphicsCommandList *CreateD3D12GraphicsCommandList(D3D12_COMMAND_LIST_TYPE d3d12CommandListType, out uint d3d12GraphicsCommandListVersion)
        {
            ID3D12GraphicsCommandList *d3d12GraphicsCommandList;

            if (Device.D3D12DeviceVersion >= 4)
            {
                var d3d12Device4 = (ID3D12Device4 *)Device.D3D12Device;
                ThrowExternalExceptionIfFailed(d3d12Device4->CreateCommandList1(nodeMask: 0, d3d12CommandListType, D3D12_COMMAND_LIST_FLAG_NONE, __uuidof <ID3D12GraphicsCommandList>(), (void **)&d3d12GraphicsCommandList));
            }
            else
            {
                var d3d12Device = Device.D3D12Device;
                ThrowExternalExceptionIfFailed(d3d12Device->CreateCommandList(nodeMask: 0, d3d12CommandListType, _d3d12CommandAllocator, pInitialState: null, __uuidof <ID3D12GraphicsCommandList>(), (void **)&d3d12GraphicsCommandList));

                // Command lists are created in the recording state, but there is nothing
                // to record yet. The main loop expects it to be closed, so close it now.
                ThrowExternalExceptionIfFailed(d3d12GraphicsCommandList->Close());
            }

            return(GetLatestD3D12GraphicsCommandList(d3d12GraphicsCommandList, out d3d12GraphicsCommandListVersion));
        }
    }
Ejemplo n.º 7
0
    internal GraphicsAdapter(GraphicsService service, IDXGIAdapter1 *dxgiAdapter) : base(service)
    {
        dxgiAdapter = GetLatestDxgiAdapter(dxgiAdapter, out _dxgiAdapterVersion);
        _dxgiAdapter.Attach(dxgiAdapter);

        DXGI_ADAPTER_DESC1 dxgiAdapterDesc;

        ThrowExternalExceptionIfFailed(dxgiAdapter->GetDesc1(&dxgiAdapterDesc));

        _description = GetUtf16Span(dxgiAdapterDesc.Description, 128).GetString() ?? string.Empty;
        _pciDeviceId = dxgiAdapterDesc.DeviceId;
        _pciVendorId = dxgiAdapterDesc.VendorId;

        SetName(_description);

        _devices      = new ValueList <GraphicsDevice>();
        _devicesMutex = new ValueMutex();
    }
Ejemplo n.º 8
0
        public WicImageFrame(WicImageContainer decoder, uint index)
        {
            Container = decoder;

            using var frame = default(ComPtr <IWICBitmapFrameDecode>);
            HRESULT.Check(decoder.WicDecoder->GetFrame(index, frame.GetAddressOf()));

            using var source = new ComPtr <IWICBitmapSource>((IWICBitmapSource *)frame.Get());

            double dpix, dpiy;

            HRESULT.Check(frame.Get()->GetResolution(&dpix, &dpiy));
            (DpiX, DpiY) = (dpix, dpiy);

            uint frameWidth, frameHeight;

            HRESULT.Check(frame.Get()->GetSize(&frameWidth, &frameHeight));

            using var metareader = default(ComPtr <IWICMetadataQueryReader>);
            if (SUCCEEDED(frame.Get()->GetMetadataQueryReader(metareader.GetAddressOf())))
            {
                string orientationPath =
                    MagicImageProcessor.EnableXmpOrientation ? Wic.Metadata.OrientationWindowsPolicy :
                    Container.ContainerFormat == FileFormat.Jpeg ? Wic.Metadata.OrientationJpeg :
                    Wic.Metadata.OrientationExif;

                ExifOrientation   = ((Orientation)metareader.GetValueOrDefault <ushort>(orientationPath)).Clamp();
                WicMetadataReader = metareader.Detach();
            }

            using var preview = default(ComPtr <IWICBitmapSource>);
            if (decoder.IsRawContainer && index == 0 && SUCCEEDED(decoder.WicDecoder->GetPreview(preview.GetAddressOf())))
            {
                uint pw, ph;
                HRESULT.Check(preview.Get()->GetSize(&pw, &ph));

                if (pw == frameWidth && ph == frameHeight)
                {
                    source.Attach(preview.Detach());
                }
            }

            using var transform = default(ComPtr <IWICBitmapSourceTransform>);
            if (SUCCEEDED(source.Get()->QueryInterface(__uuidof <IWICBitmapSourceTransform>(), (void **)transform.GetAddressOf())))
            {
                uint tw = 1, th = 1;
                HRESULT.Check(transform.Get()->GetClosestSize(&tw, &th));

                SupportsNativeScale = tw < frameWidth || th < frameHeight;
            }

            using var ptransform = default(ComPtr <IWICPlanarBitmapSourceTransform>);
            if (SUCCEEDED(source.Get()->QueryInterface(__uuidof <IWICPlanarBitmapSourceTransform>(), (void **)ptransform.GetAddressOf())))
            {
                var fmts = WicTransforms.PlanarPixelFormats;
                var desc = stackalloc WICBitmapPlaneDescription[fmts.Length];
                fixed(Guid *pfmt = fmts)
                {
                    uint tw = frameWidth, th = frameHeight, st = 0;

                    HRESULT.Check(ptransform.Get()->DoesSupportTransform(
                                      &tw, &th,
                                      WICBitmapTransformOptions.WICBitmapTransformRotate0, WICPlanarOptions.WICPlanarOptionsDefault,
                                      pfmt, desc, (uint)fmts.Length, (int *)&st
                                      ));

                    SupportsPlanarProcessing = st != 0;
                }

                ChromaSubsampling =
                    desc[1].Width < desc[0].Width && desc[1].Height < desc[0].Height ? WICJpegYCrCbSubsamplingOption.WICJpegYCrCbSubsampling420 :
                    desc[1].Width < desc[0].Width ? WICJpegYCrCbSubsamplingOption.WICJpegYCrCbSubsampling422 :
                    desc[1].Height < desc[0].Height ? WICJpegYCrCbSubsamplingOption.WICJpegYCrCbSubsampling440 :
                    WICJpegYCrCbSubsamplingOption.WICJpegYCrCbSubsampling444;
            }

            var guid = default(Guid);

            HRESULT.Check(source.Get()->GetPixelFormat(&guid));
            if (PixelFormat.FromGuid(guid).NumericRepresentation == PixelNumericRepresentation.Indexed)
            {
                var newFormat = PixelFormat.Bgr24Bpp;
                if (Container.ContainerFormat == FileFormat.Gif && Container.FrameCount > 1)
                {
                    newFormat = PixelFormat.Bgra32Bpp;
                }
                else
                {
                    using var pal = default(ComPtr <IWICPalette>);
                    HRESULT.Check(Wic.Factory->CreatePalette(pal.GetAddressOf()));
                    HRESULT.Check(source.Get()->CopyPalette(pal));

                    int bval;
                    if (SUCCEEDED(pal.Get()->HasAlpha(&bval)) && bval != 0)
                    {
                        newFormat = PixelFormat.Bgra32Bpp;
                    }
                    else if ((SUCCEEDED(pal.Get()->IsGrayscale(&bval)) && bval != 0) || (SUCCEEDED(pal.Get()->IsBlackWhite(&bval)) && bval != 0))
                    {
                        newFormat = PixelFormat.Grey8Bpp;
                    }
                }

                var nfmt = newFormat.FormatGuid;
                using var conv = default(ComPtr <IWICFormatConverter>);
                HRESULT.Check(Wic.Factory->CreateFormatConverter(conv.GetAddressOf()));
                HRESULT.Check(conv.Get()->Initialize(source, &nfmt, WICBitmapDitherType.WICBitmapDitherTypeNone, null, 0.0, WICBitmapPaletteType.WICBitmapPaletteTypeCustom));

                source.Attach((IWICBitmapSource *)conv.Detach());
            }

            WicFrame  = frame.Detach();
            WicSource = source.Detach();
        }
Ejemplo n.º 9
0
 /// <summary>Increments the reference count for the current COM object, if any, and copies its address to a target <see cref="ComPtr{T}"/>.</summary>
 /// <param name="other">The target reference to copy the address of the current COM object to.</param>
 /// <returns>This method always returns <see cref="S_OK"/>.</returns>
 public readonly HRESULT CopyTo(ref ComPtr <T> other)
 {
     InternalAddRef();
     other.Attach(ptr_);
     return(S_OK);
 }