Ejemplo n.º 1
0
        void EnsureResources(SharpDX.Direct3D11.Device device, Texture2DDescription description, Rectangle captureRegion, ScreenshotRequest request)
        {
            if (_device != null && request.Resize != null && (_resizedRT == null || (_resizedRT.Device.NativePointer != _device.NativePointer || _resizedRT.Description.Width != request.Resize.Value.Width || _resizedRT.Description.Height != request.Resize.Value.Height)))
            {
                // Create/Recreate resources for resizing
                RemoveAndDispose(ref _resizedRT);
                RemoveAndDispose(ref _resizedRTV);
                RemoveAndDispose(ref _saQuad);

                _resizedRT = ToDispose(new Texture2D(_device, new Texture2DDescription()
                {
                    Format            = SharpDX.DXGI.Format.R8G8B8A8_UNorm, // Supports BMP/PNG/etc
                    Height            = request.Resize.Value.Height,
                    Width             = request.Resize.Value.Width,
                    ArraySize         = 1,
                    SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
                    BindFlags         = BindFlags.RenderTarget,
                    MipLevels         = 1,
                    Usage             = ResourceUsage.Default,
                    OptionFlags       = ResourceOptionFlags.None
                }));

                _resizedRTV = ToDispose(new RenderTargetView(_device, _resizedRT));

                _saQuad = ToDispose(new DX11.ScreenAlignedQuadRenderer());
                _saQuad.Initialize(new DX11.DeviceManager(_device));
            }

            // Check if _resolvedRT or _finalRT require creation
            if (_finalRT != null && _finalRT.Device.NativePointer == _device.NativePointer &&
                _finalRT.Description.Height == captureRegion.Height && _finalRT.Description.Width == captureRegion.Width &&
                _resolvedRT != null && _resolvedRT.Description.Height == description.Height && _resolvedRT.Description.Width == description.Width &&
                _resolvedRT.Device.NativePointer == device.NativePointer && _resolvedRT.Description.Format == description.Format
                )
            {
                return;
            }

            RemoveAndDispose(ref _query);
            RemoveAndDispose(ref _resolvedRT);
            RemoveAndDispose(ref _resolvedSharedSRV);
            RemoveAndDispose(ref _finalRT);
            RemoveAndDispose(ref _resolvedRTShared);

            _query = new Query(_device, new QueryDescription()
            {
                Flags = QueryFlags.None,
                Type  = QueryType.Event
            });
            _queryIssued = false;

            _resolvedRT = ToDispose(new Texture2D(device, new Texture2DDescription()
            {
                CpuAccessFlags    = CpuAccessFlags.None,
                Format            = description.Format, // for multisampled backbuffer, this must be same format
                Height            = description.Height,
                Usage             = ResourceUsage.Default,
                Width             = description.Width,
                ArraySize         = 1,
                SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), // Ensure single sample
                BindFlags         = BindFlags.ShaderResource,
                MipLevels         = 1,
                OptionFlags       = ResourceOptionFlags.SharedKeyedmutex
            }));

            // Retrieve reference to the keyed mutex
            _resolvedRTKeyedMutex = ToDispose(_resolvedRT.QueryInterfaceOrNull <SharpDX.DXGI.KeyedMutex>());

            using (var resource = _resolvedRT.QueryInterface <SharpDX.DXGI.Resource>())
            {
                _resolvedRTShared          = ToDispose(_device.OpenSharedResource <Texture2D>(resource.SharedHandle));
                _resolvedRTKeyedMutex_Dev2 = ToDispose(_resolvedRTShared.QueryInterfaceOrNull <SharpDX.DXGI.KeyedMutex>());
            }

            // SRV for use if resizing
            _resolvedSharedSRV = ToDispose(new ShaderResourceView(_device, _resolvedRTShared));

            _finalRT = ToDispose(new Texture2D(_device, new Texture2DDescription()
            {
                CpuAccessFlags    = CpuAccessFlags.Read,
                Format            = description.Format,
                Height            = captureRegion.Height,
                Usage             = ResourceUsage.Staging,
                Width             = captureRegion.Width,
                ArraySize         = 1,
                SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
                BindFlags         = BindFlags.None,
                MipLevels         = 1,
                OptionFlags       = ResourceOptionFlags.None
            }));
            _finalRTMapped = false;
        }
Ejemplo n.º 2
0
        void EnsureResources(global::SharpDX.Direct3D11.Device device, Texture2DDescription description, Rectangle captureRegion, ScreenshotRequest request, bool useSameDeviceForResize = false)
        {
            var resizeDevice = useSameDeviceForResize ? device : _device;

            // Check if _resolvedRT or _finalRT require creation
            if (_finalRT != null && (_finalRT.Device.NativePointer == device.NativePointer || _finalRT.Device.NativePointer == _device.NativePointer) &&
                _finalRT.Description.Height == captureRegion.Height && _finalRT.Description.Width == captureRegion.Width &&
                _resolvedRT != null && _resolvedRT.Description.Height == description.Height && _resolvedRT.Description.Width == description.Width &&
                (_resolvedRT.Device.NativePointer == device.NativePointer || _resolvedRT.Device.NativePointer == _device.NativePointer) && _resolvedRT.Description.Format == description.Format
                )
            {
            }
            else
            {
                RemoveAndDispose(ref _query);
                RemoveAndDispose(ref _resolvedRT);
                RemoveAndDispose(ref _resolvedSRV);
                RemoveAndDispose(ref _finalRT);
                RemoveAndDispose(ref _resolvedRTShared);
                RemoveAndDispose(ref _resolvedRTKeyedMutex);
                RemoveAndDispose(ref _resolvedRTKeyedMutex_Dev2);

                _query = new Query(resizeDevice, new QueryDescription()
                {
                    Flags = QueryFlags.None,
                    Type  = QueryType.Event
                });
                _queryIssued = false;

                try
                {
                    ResourceOptionFlags resolvedRTOptionFlags = ResourceOptionFlags.None;

                    if (device != resizeDevice)
                    {
                        resolvedRTOptionFlags |= ResourceOptionFlags.SharedKeyedmutex;
                    }

                    _resolvedRT = ToDispose(new Texture2D(device, new Texture2DDescription()
                    {
                        CpuAccessFlags    = CpuAccessFlags.None,
                        Format            = description.Format, // for multisampled backbuffer, this must be same format
                        Height            = description.Height,
                        Usage             = ResourceUsage.Default,
                        Width             = description.Width,
                        ArraySize         = 1,
                        SampleDescription = new global::SharpDX.DXGI.SampleDescription(1, 0), // Ensure single sample
                        BindFlags         = BindFlags.ShaderResource,
                        MipLevels         = 1,
                        OptionFlags       = resolvedRTOptionFlags
                    }));
                }
                catch
                {
                    // Failed to create the shared resource, try again using the same device as game for resize
                    EnsureResources(device, description, captureRegion, request, true);
                    return;
                }

                // Retrieve reference to the keyed mutex
                _resolvedRTKeyedMutex = ToDispose(_resolvedRT.QueryInterfaceOrNull <global::SharpDX.DXGI.KeyedMutex>());

                // If the resolvedRT is a shared resource _resolvedRTKeyedMutex will not be null
                if (_resolvedRTKeyedMutex != null)
                {
                    using (var resource = _resolvedRT.QueryInterface <global::SharpDX.DXGI.Resource>())
                    {
                        _resolvedRTShared          = ToDispose(resizeDevice.OpenSharedResource <Texture2D>(resource.SharedHandle));
                        _resolvedRTKeyedMutex_Dev2 = ToDispose(_resolvedRTShared.QueryInterfaceOrNull <global::SharpDX.DXGI.KeyedMutex>());
                    }
                    // SRV for use if resizing
                    _resolvedSRV = ToDispose(new ShaderResourceView(resizeDevice, _resolvedRTShared));
                }
                else
                {
                    _resolvedSRV = ToDispose(new ShaderResourceView(resizeDevice, _resolvedRT));
                }

                _finalRT = ToDispose(new Texture2D(resizeDevice, new Texture2DDescription()
                {
                    CpuAccessFlags    = CpuAccessFlags.Read,
                    Format            = description.Format,
                    Height            = captureRegion.Height,
                    Usage             = ResourceUsage.Staging,
                    Width             = captureRegion.Width,
                    ArraySize         = 1,
                    SampleDescription = new global::SharpDX.DXGI.SampleDescription(1, 0),
                    BindFlags         = BindFlags.None,
                    MipLevels         = 1,
                    OptionFlags       = ResourceOptionFlags.None
                }));
                _finalRTMapped = false;
            }

            if (_resolvedRT != null && _resolvedRTKeyedMutex_Dev2 == null && resizeDevice == _device)
            {
                resizeDevice = device;
            }

            if (resizeDevice != null && request.Resize != null && (_resizedRT == null || (_resizedRT.Device.NativePointer != resizeDevice.NativePointer || _resizedRT.Description.Width != request.Resize.Value.Width || _resizedRT.Description.Height != request.Resize.Value.Height)))
            {
                // Create/Recreate resources for resizing
                RemoveAndDispose(ref _resizedRT);
                RemoveAndDispose(ref _resizedRTV);
                RemoveAndDispose(ref _saQuad);

                _resizedRT = ToDispose(new Texture2D(resizeDevice, new Texture2DDescription()
                {
                    Format            = global::SharpDX.DXGI.Format.R8G8B8A8_UNorm, // Supports BMP/PNG/etc
                    Height            = request.Resize.Value.Height,
                    Width             = request.Resize.Value.Width,
                    ArraySize         = 1,
                    SampleDescription = new global::SharpDX.DXGI.SampleDescription(1, 0),
                    BindFlags         = BindFlags.RenderTarget,
                    MipLevels         = 1,
                    Usage             = ResourceUsage.Default,
                    OptionFlags       = ResourceOptionFlags.None
                }));

                _resizedRTV = ToDispose(new RenderTargetView(resizeDevice, _resizedRT));

                _saQuad = ToDispose(new ScreenAlignedQuadRenderer());
                _saQuad.Initialize(new DeviceManager(resizeDevice));
            }
        }