Hi,
Here is a first shot at implementing depth/stencil buffer locking in wined3d.
Currently depth/stencil buffer locations are onscreen and offscreen, with transitions between the two states done in load_ds_location. I added another location, sysmem, and implemented transitions from offscreen to sysmem and from sysmem to offscreen. If buffer is onscreen, it will be moved offscreen first, then to sysmem.
Some issues with this implementation:
1) make dsurface.ok in ddraw/tests crashes in context_acquire (wined3d/context.c:2456) called from surface_load_location (wined3d/surface.c:6323), I'm guessing in because there is no swapchain. How can I prevent this crash and still get a context? Loading from offscreen to sysmem shouldn't require a swapchain.
2) When running my test app [1] I also get this error:
err:d3d_surface:surface_load_ds_location >>>>>>>>>>>>>>>>> GL_INVALID_VALUE (0x501) from glTexSubImage2D @ ../../../../wine/dlls/wined3d/surface.c / 5877
3) There are other issues with my test app (looks like it's related to textures), so can't be sure if locking works correctly. There is an improvement over the unpatched version, but can't be sure until the other issue is resolved. Game uses pre-rendered backgrounds and probably loads the Z-buffer by locking the surface, so it can render 3D characters correctly over the pre-rendered backgrounds.
It happens in the "if (surface->flags & SFLAG_DS_SYSMEM)" branch of the surface_load_ds_location function. Uploading happens on each frame, this error only happens for the first upload.
I'm quite new to wined3d code so I might have missed some obvious things. Any comments and suggestions are welcome.
Thanks.
Octavian
[1] The demo of The Longest Journey, available for download here (to reproduce, click on the Begin Journey, press ESC to skip intro movies; notice how rendered characters look): http://games.softpedia.com/get/Games-Demo/The-Longest-Journey-161-Demo.shtml
On 2 November 2011 11:59, Octavian Voicu octavian.voicu@gmail.com wrote:
- make dsurface.ok in ddraw/tests crashes in context_acquire
(wined3d/context.c:2456) called from surface_load_location (wined3d/surface.c:6323), I'm guessing in because there is no swapchain. How can I prevent this crash and still get a context? Loading from offscreen to sysmem shouldn't require a swapchain.
In practice it does. The reason is that to get a GL context you need a window, or at least a Drawable, and currently in wined3d that means you need a swapchain. There are a couple of things that need to be fixed there. One is that wined3d should really be able to do rendering without a swapchain for d3d10/11, the other is that ddraw should create its swapchain much earlier, likely on SetCooperativeLevel(). I'm not sure all that matter a whole lot here though, the more interesting question is probably how you managed to get the surface to be in the offscreen location without a swapchain.
The sysmem <-> texture transfer code looks at first sight like it should be using surface_upload_data() / surface_download_data(). Another issue is that SFLAG_DS_ONSCREEN and SFLAG_DS_OFFSCREEN should actually go away and be replaced with SFLAG_INDRAWABLE / SFLAG_INTEXTURE. These are separate flags for historical reasons, but it should be possible to merge them back now.
On Wed, Nov 2, 2011 at 3:41 PM, Henri Verbeet hverbeet@gmail.com wrote:
I'm not sure all that matter a whole lot here though, the more interesting question is probably how you managed to get the surface to be in the offscreen location without a swapchain.
According to git blame, Stefan managed to do that :)
Crash happens in test_ddsd() in ddraw/tests/dsurface.c:4330, after unlocking a newly created z-buffer. The surface is in video memory when created, even if it contains junk, right?
It is strange though that there is no swapchain at that point, it is created early on in the test.
Octavian
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Am 03.11.2011 um 11:35 schrieb Octavian Voicu:
Crash happens in test_ddsd() in ddraw/tests/dsurface.c:4330, after unlocking a newly created z-buffer. The surface is in video memory when created, even if it contains junk, right?
Surfaces are created with SFLAG_INSYSMEM(see dlls wined3d/surface.c, surface_private_setup), but due to the SFLAG_DS_ONSCREEN and SFLAG_DS_OFFSCREEN flags as well as your newly created SFLAG_DS_SYSMEM this doesn't apply for depth stencils. This problem should go away once depth stencils use the normal location flags.