Sign in to follow this  

Device Reset - ObjectDisposedException "DynamicIndexBuffer" - but I dont use Dynamic Buffers ...

This topic is 1971 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,

I'm trying to squash a few problems in my Device reset code neccessary after the user resizes my game window. I've got Device_Reset handling code on all my created textures and IB/VBs (I'm not using the default content loader, which I believe handles all this anyway) but keep getting the error in the title, on the Device.Reset(parameters) call I make to resize the backbuffer, after the viewport size changes.

Normally I'd just hunt it down, but I dont use any Dyanamic buffers (either index or vertex) so I'm initially stumped. However I do sometimes use SpriteBatch like this
[source lang="csharp"]using (SpriteBatch sprite = new SpriteBatch(device))
{
sprite.Begin(SpriteSortMode.Immediate, BlendState.Opaque, samplerState, DepthStencilState.None, RasterizerState.CullNone, effect: null);
sprite.Draw(this.rawTexture, new Vector2(0, 0), Color.White);
sprite.End();
}
[/source]
and I'm wondering if the DeviceReset call is being executed during the execution of the Using block, and whether SprintBatch is internally creating Dynamic buffers ? Can anyone tell me whether SpriteBatch does create dynamics or not, and what the correct pattern is that I should follow during a SpriteBatch operation to handle device reset events ? I may be completely wrong in my identification of SpriteBatch being the problem, so if no-one else has ever had a problem with it, I must be way off...

Thanks,
Phillip

Share this post


Link to post
Share on other sites
Sprites create dynamic buffers, yes. In fact, Sprites are just a wrapper around standard buffers and draw calls, so what applies to standard stuff also applies here.

Not sure about slim/sharp DX, or XNA, but there should be something like OnLostDevice and OnResetDevice methods available which should be called in the appropriate places, which will handle any default pool resources created by the sprite (including dynamic buffers), as well as any AddRef calls they may make on other resources. Edited by mhagain

Share this post


Link to post
Share on other sites
mhagin,

Thanks for your response. That clears up my confusion
[quote name='mhagain' timestamp='1342906899' post='4961773']
Sprites create dynamic buffers, yes. In fact, Sprites are just a wrapper around standard buffers and draw calls, so what applies to standard stuff also applies here.

Not sure about slim/sharp DX, or XNA, but there should be something like OnLostDevice and OnResetDevice methods available which should be called in the appropriate places, which will handle any default pool resources created by the sprite (including dynamic buffers), as well as any AddRef calls they may make on other resources.
[/quote]

Unfortunately SpriteBatch does not have any event handlers around DeviceLost or DeviceReset - so I guess I just recreate the SpriteBatch if the device raises one of these events; this means I cannot effectively use the common "using" block to ensure Disposal, since the SpriteBatch object I start with might not be the one I end with. I guess the correct pattern here is to wrap SpriteBatch into another class with a getter such as;

public SpriteBatch CurrentSpriteBatch
{
get
{
return internalSpriteBatch;
}
}

where I set the internalSpriteBatch object internally, and monitor the DeviceReset, and recreate it as neccessary with the same parameters. I presume I'd also have to re-run any code I'd targetted at the SpriteBatch as well, such as any draw calls, since resetting the SpriteBatch in response to a DeviceLost will reset it to the initial turquoise default state.

In fact, now you've told me that the SpriteBatch does use internal disposable graphics assets, then any code structured in my original post will always be incorrect. The probable correct code would look something like this;

using (SpriteBatchWrapper spw = new SpriteBatchWrapper( ... params ...)
{
spw.DoWork( () =>
... some lambda func or delegate
);
}

The SpriteBatchWrapper class task would be to create an internal SpriteBatch, (and recreate it if the device is lost in the meantime), and excute the work delegate/func, and if the device is lost during that delegate execution, to re-execute the delegate.

Its interesting that all the examples of SpriteBatch seem to make no consideration of the device being lost during the using{} block - is this because the device is almoist never reset in most game architectures, becuase they are typically full screen or fixed window ...

Phillip

Share this post


Link to post
Share on other sites
You should not be creating a SpriteBatch and then disposing of it to draw a single sprite, that's no different than creating the underlying gpu resources (vertexbuffer/indexbuffer) and tossing them away after first use. The purpose of spritebatch is to stay around and act as a rotating buffer to draw hundreds or even thousands of sprites. Treat it like the rest of the content you load up initially.

Creating resources with or without the content manager shouldn't have an affect as the tracking that XNA does under the hood to ensure resources are recreated happen automatically wen that resource is constructed.

As for the exception, that may need further investigation - since XNA 2.0 device resources should always remain valid, even when the device is lost (refer to this [url="http://blogs.msdn.com/b/shawnhar/archive/2007/12/12/virtualizing-the-graphicsdevice-in-xna-game-studio-2-0.aspx"]Shawn Hargreaves post[/url]). Since it looks like you're not using the standard XNA Game class, as you're explicitly resetting the device (probably to resize the window you're rendering to?), I would take a look at the [url="http://create.msdn.com/en-US/education/catalog/sample/winforms_series_1"]XNA WinForms sample[/url]. Perhaps you're resetting, and then still trying to draw right after?

Share this post


Link to post
Share on other sites
[quote name='Starnick' timestamp='1342969430' post='4961935']
As for the exception, that may need further investigation
[/quote]

Thanks for the guidance on SpriteBatch. In fact I'm only using it to create a Texture from a PNG with mipmapping and it only occurs one-time when a landscape tile is loaded, so I genuinely dont have any further use for it.

The exception occurs when I call Device.Reset() method, when I'm resizing windows aggressively (i.e. moving to Full Screen and Window mode doesn't seem to cause the error). I based my code on the XNA WinForms sample, so I think the basic handling is sound enough (but clearly, stil flawed somewhere). I'll look into it further and see if I can track the Dispose Event on the assets I'm handling and see if I can spot which specific one is incorrectly handled - although its definitely of Type Dynamic .... Buffer which I dont manually create, so it must, to my mind, by the implicit resources in the SpriteBatch. Some more delving is required. Thanks for your reply.

Share this post


Link to post
Share on other sites

This topic is 1971 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this