Example #1
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="device">Device</param>
        /// <param name="breakOnWarning">Generate an error on warning</param>
        public SharpDebugger(SharpDevice device, bool breakOnWarning)
        {
            _device = device;
            //init the debug device
            Debug = new DeviceDebug(device.Device);
            //init the queue interface
            Queue = Debug.QueryInterface<InfoQueue>();

            if (breakOnWarning)
                Queue.SetBreakOnSeverity(MessageSeverity.Warning, true);
        }
        private static MyRenderDeviceSettings CreateDeviceInternal(IntPtr windowHandle, MyRenderDeviceSettings? settingsToTry)
        {
            if (Device != null)
            { 
                Device.Dispose();
                Device = null;
            }

            if (settingsToTry != null)
            {
                Log.WriteLine("CreateDevice - original settings");
                var originalSettings = settingsToTry.Value;
                LogSettings(ref originalSettings);
            }

            FeatureLevel[] featureLevels = { FeatureLevel.Level_11_0 };
            DeviceCreationFlags flags = DeviceCreationFlags.None;
      
    #if DEBUG_DEVICE && DEBUG
            flags |= DeviceCreationFlags.Debug;
    #endif

            WinApi.DEVMODE mode = new WinApi.DEVMODE();
            WinApi.EnumDisplaySettings(null, WinApi.ENUM_REGISTRY_SETTINGS, ref mode);

            var settings = settingsToTry ?? new MyRenderDeviceSettings()
            {
                AdapterOrdinal = -1,
                BackBufferHeight = mode.dmPelsHeight,
                BackBufferWidth = mode.dmPelsWidth,
                WindowMode = MyWindowModeEnum.Fullscreen,
                RefreshRate = 60000,
                VSync = false,
            };
            settings.AdapterOrdinal = ValidateAdapterIndex(settings.AdapterOrdinal);

            if (settings.AdapterOrdinal == -1)
            {
                throw new MyRenderException("No supported device detected!", MyRenderExceptionEnum.GpuNotSupported);
            }

            m_settings = settings;

            Log.WriteLine("CreateDevice settings");
            LogSettings(ref m_settings);

            // If this line crashes cmd this: Dism /online /add-capability /capabilityname:Tools.Graphics.DirectX~~~~0.0.1.0
            var adapters = GetAdaptersList();
            if (m_settings.AdapterOrdinal >= adapters.Length)
                throw new MyRenderException("No supported device detected!", MyRenderExceptionEnum.GpuNotSupported);
            var adapterId = adapters[m_settings.AdapterOrdinal].AdapterDeviceId;
            if (adapterId >= GetFactory().Adapters.Length)
                throw new MyRenderException("Invalid adapter id binding!", MyRenderExceptionEnum.GpuNotSupported);
            var adapter = GetFactory().Adapters[adapterId];
            Device = new Device(adapter, flags, FeatureLevel.Level_11_0);

            // HACK: This is required for Steam overlay to work. Apparently they hook only CreateDevice methods with DriverType argument.
            try
            {
                using (new Device(DriverType.Hardware, flags, FeatureLevel.Level_11_0)){}
            }
            catch { }

            if (flags.HasFlag(DeviceCreationFlags.Debug))
            {
                if (DebugDevice != null)
                {
                    DebugDevice.Dispose();
                    DebugDevice = null;
                }

                DebugDevice = new DeviceDebug(Device);
                DebugInfoQueue = DebugDevice.QueryInterface<InfoQueue>();

                new System.Threading.Thread(ProcessDebugOutput).Start();
            }

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

            DeviceContext = Device.ImmediateContext;

            m_windowHandle = windowHandle;

            m_resolution = new Vector2I(m_settings.BackBufferWidth, m_settings.BackBufferHeight);

            if (!m_initialized)
            {
                InitSubsystems();
                m_initialized = true;
            }

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

            if (m_swapchain == null)
            {
                SharpDX.DXGI.Device d = Device.QueryInterface<SharpDX.DXGI.Device>();
                Adapter a = d.GetParent<Adapter>();
                var factory = a.GetParent<Factory>();

                var scDesc = new SwapChainDescription();
                scDesc.BufferCount = MyRender11Constants.BUFFER_COUNT;
                scDesc.Flags = SwapChainFlags.AllowModeSwitch;
                scDesc.IsWindowed = true;
                scDesc.ModeDescription.Format = MyRender11Constants.DX11_BACKBUFFER_FORMAT;
                scDesc.ModeDescription.Height = m_settings.BackBufferHeight;
                scDesc.ModeDescription.Width = m_settings.BackBufferWidth;
                scDesc.ModeDescription.RefreshRate.Numerator = m_settings.RefreshRate;
                scDesc.ModeDescription.RefreshRate.Denominator = 1000;
                scDesc.ModeDescription.Scaling = DisplayModeScaling.Unspecified;
                scDesc.ModeDescription.ScanlineOrdering = DisplayModeScanlineOrder.Progressive;
                scDesc.SampleDescription.Count = 1;
                scDesc.SampleDescription.Quality = 0;
                scDesc.OutputHandle = m_windowHandle;
                scDesc.Usage = Usage.RenderTargetOutput;
                scDesc.SwapEffect = SwapEffect.Discard;

                m_swapchain = new SwapChain(factory, Device, scDesc);

                m_swapchain.GetParent<Factory>().MakeWindowAssociation(m_windowHandle, WindowAssociationFlags.IgnoreAll);
            }

            // we start with window always (DXGI recommended)
            m_settings.WindowMode = MyWindowModeEnum.Window;
            ApplySettings(settings);

            return m_settings;
        }
        internal static MyRenderDeviceSettings CreateDevice(IntPtr windowHandle, MyRenderDeviceSettings? settingsToTry)
        {
            if (Device != null)
            { 
                Device.Dispose();
                Device = null;
            }

            FeatureLevel[] featureLevels = { FeatureLevel.Level_11_0 };
            DeviceCreationFlags flags = DeviceCreationFlags.None;
      
    #if DEBUG_DEVICE    
            flags |= DeviceCreationFlags.Debug;
    #endif

            WinApi.DEVMODE mode = new WinApi.DEVMODE();
            WinApi.EnumDisplaySettings(null, WinApi.ENUM_REGISTRY_SETTINGS, ref mode);

            var adapters = GetAdaptersList();

            int adapterIndex = settingsToTry.HasValue ? settingsToTry.Value.AdapterOrdinal : - 1;

            bool adapterIndexNotValid = 
                adapterIndex == -1
                || adapters.Length <= settingsToTry.Value.AdapterOrdinal
                || !adapters[settingsToTry.Value.AdapterOrdinal].IsSupported;
            if(adapterIndexNotValid)
            {
                var maxVram = 0ul;

                for(int i=0; i<adapters.Length; i++)
                {
                    if(adapters[i].IsSupported)
                    {
                        maxVram = (ulong) Math.Max(maxVram, adapters[i].VRAM);
                    }
                }

                // taking supporting adapter with most VRAM
                for (int i = 0; i < adapters.Length; i++)
                {
                    if(adapters[i].IsSupported && adapters[i].VRAM == maxVram)
                    {
                        adapterIndex = i;
                        break;
                    }
                }
            }

            if(adapterIndex == -1)
            {
                throw new MyRenderException("No supporting device detected!", MyRenderExceptionEnum.GpuNotSupported);
            }

            var settings = settingsToTry ?? new MyRenderDeviceSettings()
            {
                AdapterOrdinal = adapterIndex,
                BackBufferHeight = mode.dmPelsHeight,
                BackBufferWidth = mode.dmPelsWidth,
                WindowMode = MyWindowModeEnum.Fullscreen,
                VSync = false,
            };
            m_settings = settings;

            Device = new Device(GetFactory().Adapters[adapters[m_settings.AdapterOrdinal].AdapterDeviceId], flags, FeatureLevel.Level_11_0);

            // HACK: This is required for Steam overlay to work. Apparently they hook only CreateDevice methods with DriverType argument.
            try
            {
                using (new Device(DriverType.Hardware, flags, FeatureLevel.Level_11_0)){}
            }
            catch { }

            if (flags.HasFlag(DeviceCreationFlags.Debug))
            {
                if (DebugDevice != null)
                {
                    DebugDevice.Dispose();
                    DebugDevice = null;
                }

                DebugDevice = new DeviceDebug(Device);
                DebugInfoQueue = DebugDevice.QueryInterface<InfoQueue>();

                new System.Threading.Thread(ProcessDebugOutput).Start();
            }

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

            ImmediateContext = Device.ImmediateContext;

            m_windowHandle = windowHandle;

            m_resolution = new Vector2I(m_settings.BackBufferWidth, m_settings.BackBufferHeight);

            if (!m_initialized)
            {
                InitSubsystems();
                m_initialized = true;
            }
            

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

            if (m_swapchain == null)
            {
                SharpDX.DXGI.Device d = Device.QueryInterface<SharpDX.DXGI.Device>();
                Adapter a = d.GetParent<Adapter>();
                var factory = a.GetParent<Factory>();

                var scDesc = new SwapChainDescription();
                scDesc.BufferCount = MyRender11Constants.BUFFER_COUNT;
                scDesc.Flags = SwapChainFlags.AllowModeSwitch;
                scDesc.IsWindowed = true;
                scDesc.ModeDescription.Format = MyRender11Constants.BACKBUFFER_FORMAT;
                scDesc.ModeDescription.Height = m_settings.BackBufferHeight;
                scDesc.ModeDescription.Width = m_settings.BackBufferWidth;
                scDesc.ModeDescription.RefreshRate.Numerator = m_settings.RefreshRate;
                scDesc.ModeDescription.RefreshRate.Denominator = 1000;
                scDesc.ModeDescription.Scaling = DisplayModeScaling.Unspecified;
                scDesc.ModeDescription.ScanlineOrdering = DisplayModeScanlineOrder.Progressive;
                scDesc.SampleDescription.Count = 1;
                scDesc.SampleDescription.Quality = 0;
                scDesc.OutputHandle = m_windowHandle;
                scDesc.Usage = Usage.RenderTargetOutput;
                scDesc.SwapEffect = SwapEffect.Discard;

                m_swapchain = new SwapChain(factory, Device, scDesc);

                m_swapchain.GetParent<Factory>().MakeWindowAssociation(m_windowHandle, WindowAssociationFlags.IgnoreAll);
            }

            // we start with window always (DXGI recommended)
            m_settings.WindowMode = MyWindowModeEnum.Window;
            ApplySettings(settings);

            return m_settings;
        }