/// <summary>
        /// Function to retrieve the outputs attached to a video adapter.
        /// </summary>
        /// <param name="device">The Direct 3D device used to filter display modes.</param>
        /// <param name="adapter">The adapter to retrieve the outputs from.</param>
        /// <param name="outputCount">The number of outputs for the device.</param>
        /// <param name="log">The logging interface used to capture debug messages.</param>
        /// <returns>A list if video output info values.</returns>
        private static Dictionary <string, VideoOutputInfo> GetOutputs(D3D11.Device5 device, Adapter4 adapter, int outputCount, IGorgonLog log)
        {
            var result = new Dictionary <string, VideoOutputInfo>(StringComparer.OrdinalIgnoreCase);

            // Devices created under RDP/TS do not support output selection.
            if (SystemInformation.TerminalServerSession)
            {
                log.Print("Devices under terminal services and software devices devices do not use outputs, no outputs enumerated.", LoggingLevel.Intermediate);
                return(result);
            }

            for (int i = 0; i < outputCount; ++i)
            {
                using (Output output = adapter.GetOutput(i))
                    using (Output6 output6 = output.QueryInterface <Output6>())
                    {
                        var outputInfo = new VideoOutputInfo(i, output6, GetVideoModes(device, output6));

                        if (outputInfo.VideoModes.Count == 0)
                        {
                            log.Print($"Output '{output.Description.DeviceName}' on adapter '{adapter.Description1.Description}' has no full screen video modes.",
                                      LoggingLevel.Intermediate);
                        }

                        result.Add(output.Description.DeviceName, outputInfo);
                    }
            }

            return(result);
        }
Example #2
0
        /// <inheritdoc />
        /// <summary>
        ///   Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources
        /// </summary>
        public void Dispose()
        {
            // release resources
            Alive = false;

            Duplication.Dispose();
            Duplication = null;

            Output.Dispose();
            Output = null;

            Output1?.Dispose();
            Output1 = null;

            Output6?.Dispose();
            Output6 = null;

            DxgiDevice.Dispose();
            DxgiDevice = null;

            Device.Dispose();
            Device = null;

            Texture.Dispose();
            Texture = null;

            Adapter1.Dispose();
            Adapter1 = null;
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="VideoOutputInfo" /> class.
 /// </summary>
 /// <param name="index">The index of the output.</param>
 /// <param name="output">The output used to provide information.</param>
 /// <param name="modes">The list of full screen display modes supported by this output on the video adapter.</param>
 public VideoOutputInfo(int index, Output6 output, IEnumerable <ModeDescription1> modes)
 {
     Index      = index;
     _desc      = output.Description;
     Name       = _desc.DeviceName.Replace("\0", string.Empty);
     Rotation   = (RotationMode)_desc.Rotation;
     VideoModes = modes.Select(item => new GorgonVideoMode(item)).ToArray();
 }
Example #4
0
 /// <inheritdoc />
 /// <summary>
 ///   Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources
 /// </summary>
 public void Dispose()
 {
     // release resources
     Duplication.Dispose();
     Output.Dispose();
     Output1?.Dispose();
     Output6?.Dispose();
     Context.Dispose();
     DxgiDevice.Dispose();
     Device.Dispose();
     Texture.Dispose();
     Adapter1.Dispose();
 }
Example #5
0
        public DxCapture(int width, int height, int adapter, int monitor, FileLogger logger)
        {
            try
            {
                _logger = logger;
                _width  = width;
                _height = height;

                _factory = new Factory1();
                _adapter = _factory.GetAdapter1(adapter);
                _device  = new SharpDX.Direct3D11.Device(_adapter);

                _output           = _adapter.GetOutput(monitor);
                _output6          = _output.QueryInterface <Output6>();
                _duplicatedOutput = _output6.DuplicateOutput1(_device, 0, 1, new Format[] { Format.B8G8R8A8_UNorm });

                var textureDesc = new Texture2DDescription
                {
                    CpuAccessFlags    = CpuAccessFlags.Read,
                    BindFlags         = BindFlags.None,
                    Format            = Format.B8G8R8A8_UNorm,
                    Width             = _width,
                    Height            = _height,
                    OptionFlags       = ResourceOptionFlags.None,
                    MipLevels         = 1,
                    ArraySize         = 1,
                    SampleDescription = { Count = 1, Quality = 0 },
                    Usage             = ResourceUsage.Staging
                };
                _screenTexture = new Texture2D(_device, textureDesc);
            }
            catch (Exception ex)
            {
                Task.Run(() => _logger?.WriteLog(ex.ToString()));
                throw;
            }
        }
Example #6
0
        /// <summary>
        ///   Struct constructor
        /// </summary>
        /// <param name="adapter1">DXGI adapter device instance</param>
        /// <param name="output">DXGI output associated with this source</param>
        /// <param name="region">Region of the DXGI output device</param>
        internal DxgiCaptureSource(Adapter1 adapter1, Output output, Rectangle region)
        {
            Device   = null;
            Adapter1 = adapter1;
            Output   = output;
            Output1  = null;
            Output6  = null;
            Region   = region;

            if (region != output.Description.DesktopBounds)
            {
                Subregion = new ResourceRegion(region.Left - output.Description.DesktopBounds.Left,
                                               region.Top - output.Description.DesktopBounds.Top,
                                               0,
                                               region.Width + region.Left,
                                               region.Height + region.Top,
                                               1);
            }
            else
            {
                Subregion = null;
            }

            try {
                // create device
                Device = new Device(adapter1, DeviceCreationFlags.None, FeatureLevel.Level_11_0)
                {
#if DEBUG
                    DebugName = output.Description.DeviceName + " // " + adapter1.Description.Description
#endif
                };

                DxgiDevice = Device.QueryInterface <SharpDX.DXGI.Device>();

                // create texture
                Texture = new Texture2D(Device, new Texture2DDescription {
                    CpuAccessFlags    = CpuAccessFlags.Read,
                    BindFlags         = BindFlags.None,
                    Format            = Format.B8G8R8A8_UNorm,
                    Width             = region.Width,
                    Height            = region.Height,
                    OptionFlags       = ResourceOptionFlags.None,
                    MipLevels         = 1,
                    ArraySize         = 1,
                    SampleDescription = { Count = 1, Quality = 0 },
                    Usage             = ResourceUsage.Staging
                });

                // duplicate desktop
                try {
                    Format[] formats = { Format.B8G8R8A8_UNorm };
                    Output6     = output.QueryInterface <Output6>();
                    Duplication = Output6.DuplicateOutput1(Device, 0, formats.Length, formats);
                } catch (Exception exception)
                    when(exception is NotSupportedException ||
                         exception.HResult == ResultCode.Unsupported.Result ||
                         exception.HResult == Result.NoInterface.Result)
                    {
                        Output1     = output.QueryInterface <Output1>();
                        Duplication = Output1.DuplicateOutput(Device);
                    }
            } catch (Exception exception)
                when(exception is NotSupportedException ||
                     exception is NotImplementedException ||
                     exception.HResult == ResultCode.Unsupported.Result ||
                     exception.HResult == Result.NotImplemented.Result ||
                     exception.HResult == Result.NoInterface.Result)
                {
                    throw new NotSupportedException("Platform not supported", exception);
                }

            Alive = true;
        }
Example #7
0
        /// <summary>
        ///     Initializes the <see cref="GraphicsDevice" />.
        /// </summary>
        /// <param name="parameters"> [in,out] Options for controlling the operation. </param>
        public void Initialize(ref GameGraphicsParameters parameters)
        {
            if (IsInitialized)
            {
                return;
            }

            _vSync = parameters.UseVSync ? 1 : 0;

            using (Factory4 factory4 = new Factory4())
            {
                _dxgiFactory = factory4.QueryInterface <Factory5>();
            }

            ModeDescription modeDescription =
                new ModeDescription(
                    parameters.Width,
                    parameters.Height,
                    parameters.Rational,
                    parameters.Format);

            if (parameters.AdapterLuid != -1 && parameters.OutputIndex != -1)
            {
                using (Adapter adapter = _dxgiFactory.GetAdapterByLuid(parameters.AdapterLuid))
                    using (Output output = adapter.GetOutput(parameters.OutputIndex))
                    {
                        _adapter4 = adapter.QueryInterface <Adapter4>();
                        _output6  = output.QueryInterface <Output6>();
                        _output6.GetClosestMatchingMode(
                            null,
                            modeDescription,
                            out modeDescription);
                    }
            }
            else
            {
                IEnumerable <Adapter> adapters =
                    _dxgiFactory.Adapters1
                    .Where(
                        a => (a.Description1.Flags & AdapterFlags.Software) !=
                        AdapterFlags.Software && a.GetOutputCount() > 0)
                    .Select(
                        a => (adapter: a,
                              featureLevel: SharpDX.Direct3D11.Device.GetSupportedFeatureLevel(a)))
                    .GroupBy(t => t.featureLevel)
                    .OrderByDescending(t => t.Key)
                    .First()
                    .Select(k => k.adapter);

                _adapter4 = null;
                foreach (Adapter adapter in adapters)
                {
                    using (adapter)
                    {
                        for (int o = 0; o < adapter.GetOutputCount(); o++)
                        {
                            using (Output output = adapter.GetOutput(o))
                            {
                                output.GetClosestMatchingMode(
                                    null,
                                    modeDescription,
                                    out ModeDescription desc);
                                if (_adapter4 == null ||
                                    desc.RefreshRate.Numerator / desc.RefreshRate.Denominator >
                                    modeDescription.RefreshRate.Numerator / modeDescription.RefreshRate.Denominator)
                                {
                                    modeDescription = desc;
                                    Interlocked.Exchange(ref _output6, output.QueryInterface <Output6>())?.Dispose();
                                    Interlocked.Exchange(ref _adapter4, adapter.QueryInterface <Adapter4>())?.Dispose();
                                }
                            }
                        }
                    }
                }
            }

            // ReSharper disable once VariableHidesOuterVariable
            Device CreateDevice(in GameGraphicsParameters parameters)
            {
                if (_adapter4 != null)
                {
                    Console.WriteLine("------- GRAPHIC CARD INFORMATION -------");
                    Console.WriteLine($"Luid:\t\t\t{_adapter4.Description2.Luid}");
                    Console.WriteLine(
                        $"Description:\t\t{_adapter4.Description2.Description.TrimEnd('\t', ' ', '\r', '\n', (char)0)}");
                    Console.WriteLine($"DeviceId:\t\t{_adapter4.Description2.DeviceId}");
                    Console.WriteLine($"VendorId:\t\t{_adapter4.Description2.VendorId}");
                    Console.WriteLine($"Revision:\t\t{_adapter4.Description2.Revision}");
                    Console.WriteLine($"SubsystemId:\t\t{_adapter4.Description2.SubsystemId}");
#if x64
                    Console.WriteLine();
                    Console.WriteLine($"SystemMemory:\t\t{_adapter4.Description2.DedicatedSystemMemory}");
                    Console.WriteLine($"VideoMemory:\t\t{_adapter4.Description2.DedicatedVideoMemory}");
                    Console.WriteLine($"SharedSystemMemory:\t{_adapter4.Description2.SharedSystemMemory}");
#endif
                    Console.WriteLine();
                    Console.WriteLine($"Format:\t\t\t{modeDescription.Format}");
                    Console.WriteLine($"Width x Height:\t\t{modeDescription.Width} x {modeDescription.Height}");
                    Console.WriteLine(
                        $"RefreshRate:\t\t{modeDescription.RefreshRate} ({modeDescription.RefreshRate.Numerator / modeDescription.RefreshRate.Denominator}HZ)");
                    Console.WriteLine($"Scaling:\t\t{modeDescription.Scaling}");
                    Console.WriteLine($"ScanlineOrdering:\t{modeDescription.ScanlineOrdering}");
                    Console.WriteLine();
                    Console.WriteLine($"DeviceName:\t\t{_output6.Description.DeviceName}");
                    Console.WriteLine(
                        $"DesktopBounds:\t\t{_output6.Description.DesktopBounds.Left};{_output6.Description.DesktopBounds.Top};{_output6.Description.DesktopBounds.Right};{_output6.Description.DesktopBounds.Bottom}");
                    Console.WriteLine($"MonitorHandle:\t\t{_output6.Description.MonitorHandle}");
                    Console.WriteLine($"IsAttachedToDesktop:\t{_output6.Description.IsAttachedToDesktop}");
                    Console.WriteLine($"Rotation:\t\t{_output6.Description.Rotation}");
                    Console.WriteLine("----------------------------------------\n");

                    return(new Device(_adapter4, parameters.DeviceCreationFlags, s_featureLevels));
                }
                return(new Device(parameters.DriverType, parameters.DeviceCreationFlags, s_featureLevels));
            }

            using (Device defaultDevice = CreateDevice(in parameters))
            {
                _d3DDevice5 = defaultDevice.QueryInterface <Device5>();
            }

            _d3DDeviceContext = _d3DDevice5.ImmediateContext3.QueryInterface <DeviceContext4>();
            _dxgiDevice4      = _d3DDevice5.QueryInterface <Device4>();

            SampleDescription sampleDescription = new SampleDescription(1, 0);
            if (parameters.EnableMultiSampling && parameters.MultiSampleCount != MultiSampleCount.None)
            {
                sampleDescription.Count   = (int)parameters.MultiSampleCount;
                sampleDescription.Quality =
                    Math.Max(
                        _d3DDevice5.CheckMultisampleQualityLevels(
                            modeDescription.Format,
                            sampleDescription.Count) - 1,
                        0);
            }

            SwapChainDescription swapChainDescription = new SwapChainDescription
            {
                BufferCount       = parameters.BufferCount,
                ModeDescription   = modeDescription,
                IsWindowed        = true,
                OutputHandle      = parameters.Handle,
                SampleDescription = sampleDescription,
                SwapEffect        = parameters.SwapEffect,
                Usage             = parameters.Usage,
                Flags             = parameters.SwapChainFlags
            };

            using (SwapChain swapChain = new SwapChain(_dxgiFactory, _d3DDevice5, swapChainDescription))
            {
                _swapChain4 = swapChain.QueryInterface <SwapChain4>();
            }

            _dxgiFactory.MakeWindowAssociation(parameters.Handle, parameters.WindowAssociationFlags);

            _swapChain4.ResizeTarget(ref modeDescription);

            SetFullscreenState(parameters.DisplayType == DisplayType.Fullscreen);

            _resizeParameters = new ResizeParameters
            {
                BufferCount    = parameters.BufferCount,
                Width          = parameters.Width,
                Height         = parameters.Height,
                SwapChainFlags = parameters.SwapChainFlags
            };

            Resize(_resizeParameters);

            _blendStates        = new BlendStates(this);
            _depthStencilStates = new DepthStencilStates(this);
            _rasterizerStates   = new RasterizerStates(this);
            _samplerStates      = new SamplerStates(this);
            _textures           = new Textures(this);

            IsInitialized = true;
        }