EntBlog
Code, 3D, Games, Linux and much more...
Beware of what you get when locking DirectX Resources Buffers
January 30, 2006 @ 17:09 | In Programming | |
I’m writing this because is a topic that is hard to find in the net. This is my contribution to the google database.
Due to a Windows Kernel bug, sometimes the pointers returned by the Lock functions of DirectX (Index Buffers, Vertex Buffers, etc) are invalid. Citing the DirectX 9.0 SDK:
A limitation of the Windows2000 Kernel can result in some resources being freed while the resource is locked and being accessed by the application
This results in the app writing to freed memory, causing an exception
The problem only occurs with D3DPOOL_DEFAULT resources that the display driver chooses to place in system memory. When the device is put into a lost state (due to a mode change or ALT+TAB), all D3DPOOL_DEFAULT resources are freed. Direct3D has code to alias video memory resource pointers and redirect them to a dummy page, but D3DPOOL_DEFAULT system memory resources are not protected. The most common D3DPOOL_DEFAULT resources that get placed in system memory are Index Buffers, but some drivers may choose to place other resources in system memory as well. Apps can protect themselves by wrapping all resource accesses inside try…catch blocks
I’ve seen this problem in Vertex and Index buffers (always in the default pool) not only when doing ALT + TAB. And remember that WindowsXP is a Windows2000 kernel too.
You have four options to take (from worst to better) in this scenario:
- Do nothing. Your application will crash sometimes. You will say to your client that it is a Microsoft bug but the client won’t trust you.
- Use the IsBadWritePtr function against the pointers returned by the DirectX API. This won’t save you the scenario in which the pointer is invalidated after testing with IsBadWritePtr (for example, when you are writing to the buffer)
- Wrap with a try…catch block the code between Lock and Unlock. Your code have to be prepared to be exception safe. And if your code is not prepared, you are in trouble. At least you will get a lot of memory leaks. In some architectures this can be a serious problem. You should fix a lot of code and be prepared to fix future code. Even more, try…catch(…) blocks are evil. You shouldn’t be using them. You may be hiding exceptions not related with the Lock/Unlock problem. I will write about this in the future.
- Use the IsBadWritePtr function against the pointers returned by the DirectX API and if you get a bad pointer return a pointer to a dummy memory block internally allocated by you. To me, this is the cleanest and safest option. You should return a memory block long enough to hold the size requested by the Lock.
One last thing, IsBadWritePtr is not implemented doing some magic kernel operations. It checks the memory trying to write to it and catching the exceptions if it fails.
We will have to wait for Windows Vista to forget this horror.
Wed, 20 Aug 2008 20:08:09 +0200 / 25 queries. 1.454 seconds / 4 Users Online
|
|
|
|
|
Theme modified from Pool theme. Valid XHTML and CSS
About
Categories
>> Use the IsBadWritePtr function against the pointers returned by the DirectX API and if you get a bad pointer return a pointer to a dummy memory block internally allocated by you. To me, this is the cleanest and safest option. You should return a memory block long enough to hold the size requested by the Lock.
What if the pointer is invalid after the call to IsBadWritePtr?
Comment by chanka
January 31, 2006 @ 10:16 #
IsBadWritePtr() won’t return you a pointer. It returns a bool indicating if the memory pointer is writable or not.
BOOL IsBadWritePtr(LPVOID lp, UINT_PTR ucb);
Comment by ent
January 31, 2006 @ 10:55 #
I mean, if the IsBadWritePtr() return true, and after the call the memory is invalidated.
Comment by chanka
January 31, 2006 @ 15:13 #
Hmmm, yes. You are right, both fourth and second solution have the same problem. try…catch seems to be the only real solution to this problem. :-\
Comment by ent
February 1, 2006 @ 2:18 #
Yes ninja
Comment by chanka
February 1, 2006 @ 7:19 #