Example #1
0
        public static IReadOnlyList <DXGI_MODE_DESC> GetDisplayModeList(this IDXGIOutput output, DXGI_FORMAT format, DXGI_ENUM_MODES modes)
        {
            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            // DXGI_FORMAT_R16G16B16A16_FLOAT
            // DXGI_FORMAT_R10G10B10A2_UNORM
            // DXGI_FORMAT_R8G8B8A8_UNORM
            // DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
            // DXGI_FORMAT_B8G8R8A8_UNORM
            // DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM
            // DXGI_FORMAT_B8G8R8A8_UNORM_SRGB

            var  list = new List <DXGI_MODE_DESC>();
            uint num  = 0;

            output.GetDisplayModeList(format, (uint)modes, ref num, null);
            if (num > 0)
            {
                var array = new DXGI_MODE_DESC[num];
                output.GetDisplayModeList(format, (uint)modes, ref num, array);
                list.AddRange(array);
            }
            return(list);
        }
Example #2
0
        /// <summary>
        ///     Enumerate adapter (video card) outputs.
        /// </summary>
        /// <param name="outputIndex">The index of the output.</param>
        /// <param name="output">The object to an output (see <seealso cref="IDXGIOutput" />).</param>
        /// <returns></returns>
        public int EnumOutputs(uint outputIndex, out IDXGIOutput output)
        {
            int result = GetMethodDelegate <EnumOutputsDelegate>().Invoke(this, outputIndex, out IntPtr outputPtr);

            output = result == 0 ? new DXGIOutput(outputPtr) : null;
            return(result);
        }
Example #3
0
        public static DXGI_OUTPUT_DESC GetDesc(this IDXGIOutput output)
        {
            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            output.GetDesc(out var desc).ThrowOnError();
            return(desc);
        }
    public IDXGIDecodeSwapChain CreateDecodeSwapChainForCompositionSurfaceHandle(
        IUnknown device,
        IntPtr surface,
        IDXGIResource yuvDecodeBuffers,
        IDXGIOutput restrictToOutput)
    {
        // Reserved for future use (https://docs.microsoft.com/it-it/windows/desktop/api/dxgi1_3/ns-dxgi1_3-dxgi_decode_swap_chain_desc)
        var description = new DecodeSwapChainDescription
        {
            Flags = 0
        };

        return(CreateDecodeSwapChainForCompositionSurfaceHandle(device, surface, description, yuvDecodeBuffers, restrictToOutput));
    }
Example #5
0
        public static DXGI_FRAME_STATISTICS?GetFrameStatistics(this IDXGIOutput output)
        {
            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            if (output.GetFrameStatistics(out var stats).IsError)
            {
                return(null);
            }

            return(stats);
        }
Example #6
0
        public static DXGI_GAMMA_CONTROL?GetGammaControl(this IDXGIOutput output)
        {
            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            if (output.GetGammaControl(out var control).IsError)
            {
                return(null);
            }

            return(control);
        }
Example #7
0
        public static DXGI_GAMMA_CONTROL_CAPABILITIES?GetGammaControlCapabilities(this IDXGIOutput output)
        {
            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            if (output.GetGammaControlCapabilities(out var desc).IsError)
            {
                return(null);
            }

            return(desc);
        }
Example #8
0
        public static DXGI_MODE_DESC?FindClosestMatchingMode(this IDXGIOutput output, DXGI_MODE_DESC modeToMatch, object concernedDevice)
        {
            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            if (output.FindClosestMatchingMode(ref modeToMatch, out var closest, ComObject.Unwrap(concernedDevice)).IsError)
            {
                return(null);
            }

            return(closest);
        }
Example #9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EngineOutputInfo" /> class.
        /// </summary>
        internal EngineOutputInfo(int adapterIndex, int outputIndex, IDXGIOutput output)
        {
            this.AdapterIndex  = adapterIndex;
            this.OutputIndex   = outputIndex;
            _outputDescription = output.Description;

            // Get all supported modes
            var modes = output.GetDisplayModeList(
                GraphicsHelper.Internals.DEFAULT_TEXTURE_FORMAT,
                DisplayModeEnumerationFlags.Interlaced);

            // Convert and sort them
            var engineModes = new EngineOutputModeInfo[modes.Length];

            for (var loop = 0; loop < engineModes.Length; loop++)
            {
                engineModes[loop] = new EngineOutputModeInfo(this, modes[loop]);
            }
            Array.Sort(engineModes, (left, right) =>
            {
                var result = left.PixelCount.CompareTo(right.PixelCount);
                if (result == 0)
                {
                    result = left.RefreshRateNumerator.CompareTo(right.RefreshRateNumerator);
                }
                return(result);
            });

            // Strip them (we want to have each relevant mode once)
            var strippedModeList = new List <EngineOutputModeInfo>(engineModes.Length);
            var lastOutputMode   = new EngineOutputModeInfo();

            for (var loop = engineModes.Length - 1; loop > -1; loop--)
            {
                if (!engineModes[loop].Equals(lastOutputMode))
                {
                    lastOutputMode = engineModes[loop];
                    strippedModeList.Add(lastOutputMode);
                }
            }

            // Store mode list
            this.SupportedModes = strippedModeList.ToArray();
        }
 public IDXGISwapChain1 CreateSwapChainForCompositionSurfaceHandle(IUnknown device, IntPtr surface, SwapChainDescription1 description, IDXGIOutput restrictToOutput)
 {
     return(CreateSwapChainForCompositionSurfaceHandle(device, surface, ref description, restrictToOutput));
 }
            public static DesktopDuplicatorInternal CreateDesktopDuplicator(ILogger logger, int adapterIndex, int outputDeviceIndex)
            {
                var dd = new DesktopDuplicatorInternal
                {
                    _outputDeviceIndex = outputDeviceIndex
                };

                var createFactoryResult = DXGI.CreateDXGIFactory1(out IDXGIFactory1 factory);

                if (!createFactoryResult.Success)
                {
                    throw new DesktopDuplicationException("Couldn't create a DXGI Factory.");
                }

                IDXGIAdapter1 adapter = null;
                IDXGIOutput   output  = null;

                try
                {
                    var result = factory.EnumAdapters1(adapterIndex, out adapter);
                    if (result.Failure)
                    {
                        throw new DesktopDuplicationException($"An error occurred attempting to retrieve the adapter at the specified index ({adapterIndex}): {result}");
                    }

                    if (adapter == null)
                    {
                        throw new DesktopDuplicationException($"An adapter was not found at the specified index ({adapterIndex}).");
                    }

                    logger.LogInformation($"Using adapter at index {adapterIndex} - {adapter.Description.Description}");

                    var createD3dDeviceResult = D3D11.D3D11CreateDevice(adapter, DriverType.Unknown, DeviceCreationFlags.None, null, out dd._d3dDevice, out dd._immediateContext);
                    if (!createD3dDeviceResult.Success)
                    {
                        throw new DesktopDuplicationException("Couldn't create a D3D device from the specified adapter.");
                    }

                    using var device = dd._d3dDevice.QueryInterface <IDXGIDevice>();
                    var outputResult = adapter.EnumOutputs(outputDeviceIndex, out output);
                    if (outputResult.Failure)
                    {
                        throw new DesktopDuplicationException($"An error occurred attempting to retrieve the output device at the specified index ({outputDeviceIndex}): {outputResult}");
                    }

                    if (output == null)
                    {
                        throw new DesktopDuplicationException($"An output was not found at the specified index ({outputDeviceIndex}).");
                    }

                    logger.LogInformation($"Using output device on adapter {adapterIndex} at index {outputDeviceIndex}.");

                    var output6 = output.QueryInterface <IDXGIOutput6>();
                    try
                    {
                        // Copy the values to a new rect.
                        var rectTemp = output6.Description.DesktopCoordinates;
                        dd._desktopRect = new RawRect(rectTemp.Left, rectTemp.Top, rectTemp.Right, rectTemp.Bottom);

                        dd._outputDuplication = output6.DuplicateOutput(device);

                        var stagingTexture = new Texture2DDescription()
                        {
                            CpuAccessFlags    = CpuAccessFlags.Read,
                            BindFlags         = BindFlags.None,
                            Format            = dd._outputDuplication.Description.ModeDescription.Format,
                            Width             = Math.Abs(dd._desktopRect.Right - dd._desktopRect.Left),
                            Height            = Math.Abs(dd._desktopRect.Bottom - dd._desktopRect.Top),
                            OptionFlags       = ResourceOptionFlags.None,
                            MipLevels         = 1,
                            ArraySize         = 1,
                            SampleDescription = { Count = 1, Quality = 0 },
                            Usage             = Usage.Staging // << can be read by CPU
                        };

                        // Initialize the Output Duplication -- If this isn't done occassionally an 'Unsupported' result will occur with DuplicationOutput1
                        dd._desktopImageTexture = dd._d3dDevice.CreateTexture2D(stagingTexture);
                    }
                    catch (SharpGenException ex)
                    {
                        if (ex.Descriptor.NativeApiCode == "DXGI_ERROR_UNSUPPORTED")
                        {
                            throw new DesktopDuplicationException("Unsupported desktop mode or scenario.");
                        }
                        else if (ex.Descriptor.NativeApiCode == "DXGI_ERROR_NOT_CURRENTLY_AVAILABLE")
                        {
                            throw new DesktopDuplicationException("There is already the maximum number of applications using the Desktop Duplication API running, please close one of the applications and try again.");
                        }
                        else
                        {
                            throw;
                        }
                    }
                }
                finally
                {
                    if (output != null)
                    {
                        output.Dispose();
                    }

                    if (adapter != null)
                    {
                        adapter.Dispose();
                    }

                    if (factory != null)
                    {
                        factory.Dispose();
                    }
                }

                return(dd);
            }