SharpDXException DeviceRemoved when using GetData()

I post here because maybe someone can point me in the right direction.
I honestly don’t have a clue what’s going on.

Yesterday I talked to a customer:
This always happens when calling getData() on a texture2D.
The problem is that we have 600+ Installations out there and all of them are working.
Except this one…

The customers rig:

  • Win 7
  • NVIDIA GT 640 with 2G RAM

Currently used MG version: 3.6.0.1598

Things I found out:

  • Can happen when an illegal command is sent to the card
  • GetDeviceRemoveReason is DXGI_ERROR_DEVICE_REMOVED (hmmm)
  • If I remove a getData() method it happens with the next one
  • The customer re-installed his card-driver
  • The customer installed an older version of the card-driver
    no change…

Steps I will take the next days:

  • Trying to deliver a debug build
  • Update to newest MG develop build

One other thing strikes me as somewhat odd… The stacktrace further down shows like two traces… like it happened twice… both ‘threads’ originating from the programs main method… I have inserted comments to the stacktrace to emphasize what I mean:

Log:

SharpDX.SharpDXException: HRESULT: [0x887A0005], Module: [SharpDX.DXGI], ApiCode: [DXGI_ERROR_DEVICE_REMOVED/DeviceRemoved], Message: Unknown
   bei SharpDX.Result.CheckError()
   bei SharpDX.Direct3D11.DeviceContext.MapSubresource(Resource resourceRef, Int32 subresource, MapMode mapType, MapFlags mapFlags)
   bei SharpDX.Direct3D11.DeviceContext.MapSubresource(Texture2D resource, Int32 mipSlice, Int32 arraySlice, MapMode mode, MapFlags flags, DataStream& stream)
   bei SharpDX.Direct3D11.DeviceContext.MapSubresource(Resource resource, Int32 subresource, MapMode mode, MapFlags flags, DataStream& stream)
   bei Microsoft.Xna.Framework.Graphics.Texture2D.PlatformGetData[T](Int32 level, Int32 arraySlice, Rectangle rect, T[] data, Int32 startIndex, Int32 elementCount)
   bei Microsoft.Xna.Framework.Graphics.Texture2D.GetData[T](T[] data)
   bei Utilities.Utils.DrawFilledRectangle(GraphicsDevice graphicsDevice, Texture2D sourceTexture, Rectangle rectangle, Color color)
   bei Panels.ButtonPanel.Initialize()
   bei ScreenManagerLibrary.GameScreenBase.Initialize()
   bei ScreenManagerLibrary.ScreenManager.AddScreen(GameScreenBase screen)
   bei ScreenManagerLibrary.Screens.LoadingScreen.Update(GameTime gt, Boolean otherFocused, Boolean coveredByOtherScreen)
   bei ScreenManagerLibrary.ScreenManager.DoUpdates(GameTime gameTime, Boolean isDoScreenUpdateAndHandleInputs)
   bei ScreenManagerLibrary.ScreenManager.Update(GameTime gameTime)
   bei Microsoft.Xna.Framework.Game.<.cctor>b__19(IUpdateable updateable, GameTime gameTime)
   bei Microsoft.Xna.Framework.Game.SortingFilteringCollection`1.ForEachFilteredItem[TUserData](Action`2 action, TUserData userData)
   bei ThrobaxTD.TowerDefenseGame.Update(GameTime gameTime)
   bei Microsoft.Xna.Framework.Game.DoUpdate(GameTime gameTime)
   bei Microsoft.Xna.Framework.Game.Tick()
   bei MonoGame.Framework.WinFormsGameWindow.RunLoop()
   bei MonoGame.Framework.WinFormsGamePlatform.RunLoop()
   bei Microsoft.Xna.Framework.Game.Run(GameRunBehavior runBehavior)
   bei ThrobaxTD.Program.Main(String[] args)
// Seems to start over from here (re-starts with Main)
// Its the exact same stacktrace up to the exception itself...
   bei SharpDX.Result.CheckError()
   bei SharpDX.Direct3D11.DeviceContext.MapSubresource(Resource resourceRef, Int32 subresource, MapMode mapType, MapFlags mapFlags)
   bei SharpDX.Direct3D11.DeviceContext.MapSubresource(Texture2D resource, Int32 mipSlice, Int32 arraySlice, MapMode mode, MapFlags flags, DataStream& stream)
   bei SharpDX.Direct3D11.DeviceContext.MapSubresource(Resource resource, Int32 subresource, MapMode mode, MapFlags flags, DataStream& stream)
   bei Microsoft.Xna.Framework.Graphics.Texture2D.PlatformGetData[T](Int32 level, Int32 arraySlice, Rectangle rect, T[] data, Int32 startIndex, Int32 elementCount)
   bei Microsoft.Xna.Framework.Graphics.Texture2D.GetData[T](T[] data)
   bei Utilities.Utils.DrawFilledRectangle(GraphicsDevice graphicsDevice, Texture2D sourceTexture, Rectangle rectangle, Color color)
   bei Panels.ButtonPanel.Initialize()
   bei ScreenManagerLibrary.GameScreenBase.Initialize()
   bei ScreenManagerLibrary.ScreenManager.AddScreen(GameScreenBase screen)
   bei ScreenManagerLibrary.Screens.LoadingScreen.Update(GameTime gt, Boolean otherFocused, Boolean coveredByOtherScreen)
   bei ScreenManagerLibrary.ScreenManager.DoUpdates(GameTime gameTime, Boolean isDoScreenUpdateAndHandleInputs)
   bei ScreenManagerLibrary.ScreenManager.Update(GameTime gameTime)
   bei Microsoft.Xna.Framework.Game.<.cctor>b__19(IUpdateable updateable, GameTime gameTime)
   bei Microsoft.Xna.Framework.Game.SortingFilteringCollection`1.ForEachFilteredItem[TUserData](Action`2 action, TUserData userData)
   bei ThrobaxTD.TowerDefenseGame.Update(GameTime gameTime)
   bei Microsoft.Xna.Framework.Game.DoUpdate(GameTime gameTime)
   bei Microsoft.Xna.Framework.Game.Tick()
   bei MonoGame.Framework.WinFormsGameWindow.RunLoop()
   bei MonoGame.Framework.WinFormsGamePlatform.RunLoop()
   bei Microsoft.Xna.Framework.Game.Run(GameRunBehavior runBehavior)
   bei ThrobaxTD.Program.Main(String[] args)

Not sure what could cause this error, but if DrawFilledRectangle does what it says it does, you don’t need to use GetData for it. There are more efficient ways to do it that might also bypass this issue.

Hi Jjagg. Was hoping you’d read this :slight_smile:
Yeah. I know. Didn’t want a code-review… You don’t want it either… Imagine what else you would find… :smile:

The truth is… I used it for quite some (setup-related) stuff back then… could rewrite some of it… but not all of it like building collision-textures aso… so getting completely rid of it is no option at this moment.
Even if I did that, I’m not sure if the rig of this customer would throw the next inexplicable error at me somewhere else…

I debugged the SharpDX code and it happens after the mapsubresource at the error-check. But no clue as to why…

Is GetData() depricated now or what?

I read pretty much everything :stuck_out_tongue:

Maybe this could be done at build time using a pipeline extension, if you’re willing to put in the effort to overhaul your system.

Sorry, I can’t help with this problem. Seems like a very specific issue. GetData is definitely not deprecated.

1 Like

Well thanks. That’s some information at least.
I’ll post the results in the next few days.

I updated to the newest MG develop build yesterday.
Still to hear from the customer.
But I’m not very optimistic that it helped to be honest.
After googling a lot my guess would be some driver/operating system issue but it’s odd that it doesn’t manifest in other games + he re-installed the drivers… odd.

Have another one with:
SharpDXEception at
SwapChain.ResizeBuffers()…

SharpDX.SharpDXException: HRESULT: [0x887A0001], Module: [SharpDX.DXGI], ApiCode: [DXGI_ERROR_INVALID_CALL/InvalidCall], Message: The application made a call that is invalid. Either the parameters of the call or the state of some object was incorrect.
Enable the D3D debug layer in order to see details via debug messages.

   at SharpDX.Result.CheckError()
   at SharpDX.DXGI.SwapChain.ResizeBuffers(Int32 bufferCount, Int32 width, Int32 height, Format newFormat, SwapChainFlags swapChainFlags)
   at Microsoft.Xna.Framework.Graphics.GraphicsDevice.CreateSizeDependentResources()
   at Microsoft.Xna.Framework.Graphics.GraphicsDevice.Reset()
   at Microsoft.Xna.Framework.Graphics.GraphicsDevice.Reset(PresentationParameters presentationParameters)
   at Microsoft.Xna.Framework.GraphicsDeviceManager.ApplyChanges()
   at Utilities.Utils.InitGraphicsMode(Game game, GraphicsDeviceManager graphicsDeviceManager, Int32 width, Int32 height, Boolean isFullScreen, Single targetElapsedIntervalInMillis, Boolean isSynchronizeWithVerticalRetrace, Boolean isFixedTimeStep, Boolean isPreferMultiSampling, SurfaceFormat preferredBackBufferFormat, DepthFormat preferredDepthFormat, Nullable`1 zero)
   at ThrobaxTD.Screens.OptionsGraphicsMenuScreen.OnSaveAndBackMenuEntrySelected(Object sender, PlayerIndexEventArgs e)

MG build develop 3.7.0.1549 (latest) on windows build on windows machine (OS: Windows 10 GPU: 750 TI).

Happens immediately after my init-code calls Apply();

The resolution I set here is advertised by his graphics card and needless to say that I cannot reproduce the bug on my rig.

Here is my code:

/// <summary>
        ///     Attempt to set the display mode to the desired resolution.  Iterates
        ///     through the display capabilities of the default graphics adapter to
        ///     determine if the graphics adapter supports the requested resolution.
        ///     If so, the resolution is set and the function returns
        ///     <see langword="true" />.  If not, no change is made and the function
        ///     returns <see langword="false" />.
        /// </summary>
        /// <param name="game">The game.</param>
        /// <param name="graphicsDeviceManager">The graphics.</param>
        /// <param name="width">Desired screen width.</param>
        /// <param name="height">Desired screen height.</param>
        /// <param name="isFullScreen">
        ///     True if you wish to go to Full Screen,
        ///     <see langword="false" /> for Windowed Mode.
        /// </param>
        /// <param name="targetElapsedIntervalInMillis">The target elapsed interval in milliseconds.</param>
        /// <param name="isSynchronizeWithVerticalRetrace">
        ///     if set to <c>true</c> [is synchronize with vertical retrace].
        /// </param>
        /// <param name="isFixedTimeStep">
        ///     if set to <c>true</c> [is fixed time step].
        /// </param>
        /// <param name="isPreferMultiSampling">
        ///     if set to <c>true</c> [is prefer multi sampling].
        /// </param>
        /// <param name="preferredBackBufferFormat">The preferred back buffer format.</param>
        /// <param name="preferredDepthFormat">The preferred depth format.</param>
        /// <param name="zero">
        ///     The left upper corner of the bound-rectangle. If null, we will take the left-upper corner of the
        ///     screen the window is currently on.
        /// </param>
        /// <returns></returns>
        public static Rectangle? InitGraphicsMode(Game game, GraphicsDeviceManager graphicsDeviceManager, int width,
            int height,
            bool isFullScreen, float targetElapsedIntervalInMillis = 1000f / 60f,
            bool isSynchronizeWithVerticalRetrace = true, bool isFixedTimeStep = false,
            bool isPreferMultiSampling = true,
            SurfaceFormat preferredBackBufferFormat = SurfaceFormat.Color,
            DepthFormat preferredDepthFormat = DepthFormat.None, Point? zero = null)
        {
			try
			{
				// Form.ActiveForm really gets the form of the currently active window. We want the game's window.
				var f = (Form) Control.FromHandle(game.Window.Handle);
				if (f == null)
					return null;

				// Quality switches.
				graphicsDeviceManager.PreferredBackBufferFormat = preferredBackBufferFormat;
				graphicsDeviceManager.PreferredDepthStencilFormat = preferredDepthFormat;
				// This tells MonoGame to not switch the mode of the graphics-card directly, but to scale the window.
				graphicsDeviceManager.HardwareModeSwitch = false;
				// This tells MonoGame to fetch pre DX9c devices as well.
				graphicsDeviceManager.GraphicsProfile = GraphicsProfile.Reach;
				// Enables anti-aliasing.
				graphicsDeviceManager.PreferMultiSampling = isPreferMultiSampling;
				// Set to true to set the draw-restriction to the refresh-rate of the monitor.
				graphicsDeviceManager.SynchronizeWithVerticalRetrace = isSynchronizeWithVerticalRetrace;
				// If set to false, you are unbinding update and draw thus allowing them to be called separately.
				game.IsFixedTimeStep = isFixedTimeStep;
				// Determines how often update will be called (works only if IsFixedTimeStep is true.
				// 60 times per second is the default value.
				game.TargetElapsedTime = TimeSpan.FromMilliseconds(targetElapsedIntervalInMillis);

				Screen screen;
				if (zero.HasValue && isFullScreen)
				{
					screen = Screen.FromPoint(new System.Drawing.Point(zero.Value.X, zero.Value.Y));
				}
				else
				{
					screen = Screen.FromControl(f);
					zero = new Point(screen.Bounds.X, screen.Bounds.Y);
				}

				var x = screen.Bounds.Width;
				var y = screen.Bounds.Height;

				width = Math.Min(width, x);
				height = Math.Min(height, y);

				if (!isFullScreen)
				{
					x = width + 16;
					y = height + 38;
					zero = zero + new Point((screen.Bounds.Width - width) / 2, (screen.Bounds.Height - height) / 2);
				}

				game.Window.IsBorderless = isFullScreen;

#if LINUX
			Debug.DLog("getting form...");
			Form form = Control.FromHandle(game.Window.Handle).FindForm();
			if (form != null)
			{
				Debug.DLog("setting location...");
				form.Location = new System.Drawing.Point(x, y);
			}
			else
			{
				Debug.DLog("form was null.");
			}
#else
				game.Window.Position = zero.Value;
#endif

				graphicsDeviceManager.PreferredBackBufferWidth = width;
				graphicsDeviceManager.PreferredBackBufferHeight = height;
				graphicsDeviceManager.IsFullScreen = isFullScreen;
				graphicsDeviceManager.ApplyChanges();

				f.SetDesktopBounds(zero.Value.X, zero.Value.Y, x, y);
				return new Rectangle(zero.Value.X, zero.Value.Y, width, height);
			}
			catch (Exception)
			{
				return null;
			}
		}

Anyone?
Any ideas?
Anyone had some of those lately?
Still hope this is all my fault and somebody points me in the right direction and tells me how stupid I am :slight_smile: