Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Direct3D9 Device Reset #1455

Closed
RobertBColton opened this issue Dec 13, 2018 · 2 comments
Closed

Direct3D9 Device Reset #1455

RobertBColton opened this issue Dec 13, 2018 · 2 comments
Labels
Confirmed The issue has been confirmed as existing by another user or contributor. Graphics Game visuals including render state, geometry pipeline, rasterization, and related assets. Reproducible Can be triggered determininistically by a discrete series of steps.

Comments

@RobertBColton
Copy link
Contributor

RobertBColton commented Dec 13, 2018

This is a known pain with Direct3D9. If the window is resized a device reset needs to be performed to resize the backbuffer. The device will not properly reset without freeing some resources and recreating them, such as surfaces. I patched surfaces in #756 to save and reload themselves during the reset, which I recall fixed only Project Mario. I've now run into new issues with the device reset in other games including Wild Racing and GMS 3D Cube Demo.

The first one is problematic to games that attempt to draw and then read a heightmap in the create event of the game like Wild Racing. Draw anything in the create event of the game, such as the following:

draw_point(0,0);
draw_batch_flush();

And you'll get the following error message:
Direct3D9 Device Reset Failure

The bug can be reproduced in other games as well, such as the GMS High Polygonal Model Count by simply enabling the MSAA which requires a device reset to change the backbuffer.

There appears to be basically two ways to solve this. We need to save/restore more D3D9 resources, either vertex buffers or vertex formats, I'm not sure. The alternative is we can switch to Direct3D9Ex which does not have these problems. The only down side is that Direct3D9Ex does not support Windows XP.

@RobertBColton RobertBColton added Graphics Game visuals including render state, geometry pipeline, rasterization, and related assets. Confirmed The issue has been confirmed as existing by another user or contributor. Reproducible Can be triggered determininistically by a discrete series of steps. labels Dec 13, 2018
@RobertBColton
Copy link
Contributor Author

RobertBColton commented Dec 14, 2018

Alright, I did some more research with Rusky. We have 3 different ways of solving this.

  1. We can leave our resources in the default pool and handle the device reset ourselves. We would just copy my hack for surfaces around to the other resources which need it. When we go to reset the device we just copy them to system memory, release them on the device, reset the device, then reupload them to the newly reset device. Rusky prefers this since keeping the resources in the default pool is still more consistent with newer D3D and other APIs but we may also need it anyway for other features (serializing the render state).
  2. We can drop XP support for Direct3D9 and switch to Direct3D9 Ex which is where Direct3D stops having this problem. I don't recommend this option yet for ENIGMA because we do have some Windows XP users and for some of them OpenGL is not a viable alternative graphics system because of their hardware/drivers.
  3. I can move all of the resources, except surfaces, to the managed memory pool (dynamic ones to the system memory pool) and not lose any performance. A disadvantage of this is that it will increase system RAM usage of the games, and I've already confirmed this in Task Manager where the 3D Cubes Demo goes from 40mb to 60mb.
  4. This was another idea brought up by Rusky that might be doable. If it's easy enough, I can switch to Direct3D9 Ex and then just use the managed memory pool when we're on Windows XP. This may be more or less trouble than it's worth depending on how much refactoring it'll actually take.

I discovered via apitrace that GMSv1.4 uses system memory pool and dynamic usage for dynamic vertex buffers (used in primitive drawing).
GMSv1.4 Dynamic Vertex Buffer Creation

I also discovered that GMSv1.4 uses the default pool with writeonly usage for static vertex buffers.
GMSv1.4 Static Vertex Buffer Creation

For GM8, I can't test anything because it used DrawPrimitiveUP for dynamic and static vertex data. Even though IDirect3DDevice8::CreateVertexBuffer did exist, Mark Overmars did not use it. I was able to discover that it creates textures in the managed memory pool.
GM8 Created Textures in Managed Pool

@RobertBColton
Copy link
Contributor Author

Closing as resolved by #1462.

@RobertBColton RobertBColton changed the title Direct3D9 Device Reset Bullshit Direct3D9 Device Reset Dec 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Confirmed The issue has been confirmed as existing by another user or contributor. Graphics Game visuals including render state, geometry pipeline, rasterization, and related assets. Reproducible Can be triggered determininistically by a discrete series of steps.
Projects
None yet
Development

No branches or pull requests

1 participant