DirectX 9 - Troubles with VOLUME texture rendering

Started by
10 comments, last by Nesta 14 years, 1 month ago
Hello everyone. I have problems rendering VOLUME texture using DirectX 9. Below is the description: 1. As an input data I have the collection of frames which are used for building of volume texture. 2. If there are too many frames or if they are to wide or high I simply delete some of them from collection and also decrease their size (let's call this operation "scaling"). To identify if there are to many frames or not I retrieve the size of available video memory and also properties of the graphic card (MaxTextureWidth and MaxTextureHeight fields from D3DCAPS9 are used for this purpose). 3. Than I create volume texture which is based on "scaled" data. I pass corresponding "scaled" width, height and depth. And now where the problems arises. IDirect3DDevice9::CreateVolumeTexture() returns S_OK but blank white screen is displayed while rendering. Event if I fill the texture with invalid data at least the background must be black but it's also white. I performed some experiments and discovered that if I increase "scaling" coefficient (i.e. remove more frames from source collection and perform higher scaling for each of them) everything works fine, the texture is rendered like expected. I have some question regarding to this issue: a) Why CreateVolumeTexture() returns S_OK even in case when it's not able to successfully create texture? b) Are there any other ways to check if texture has been successfully created? Maybe IDirect3DDevice or IDirect3DVolumeTexture have appropriate methods for this? c) Another detail. Everything works fine on my machine with normal "scaling" coefficient and with increased one. But on machine of my colleague the problem arises when normal "scaling" coefficient is used. When I remove more frames from source collection everything works fine even on his computer. d) And the most interesting. Couple months ago his machine was able to render the same texture normally with normal "scaling" coefficient. We have automatic Windows update enabled (we use Windows XP Professional). Is there a possibility that the latest updates somehow corrupted behavior of DirectX 9? Any ideas? Please ask me for details if I haven't clarified something. Thanks.
Advertisement
Could be a driver bug. Have your friend try other driver versions.
I also thought about driver bug but 2 months ago everything worked fine and the system was not reinstalled and drivers were not updated either. An only updates both of us had are only related to automated Windows updates.
Quote:Original post by Nesta
I also thought about driver bug but 2 months ago everything worked fine and the system was not reinstalled and drivers were not updated either. An only updates both of us had are only related to automated Windows updates.
Are you sure there wasn't a driver update as part of windows update? Do the Debug Runtimes say anything? Do you get the same behaviour with the reference rasterizer?
Thanks for informing me about Debug Runtime. I didn't know about this tool before. I will try it right now and say what happens.
Debug Runtime really helped me. I was not able to fix that particular bug but it helped me to fix couple others. Really useful tool. Thanks I will continue investigating this bug and see if Debug Runtime can help me in it.
I used Debug Runtime and discovered than during the call of code:
m_pId3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, trianglesCount);

I see following lines in Debug Output:
Direct3D9: (ERROR) :All POOL_MANAGED resources in this device freed. No further video memory available.
Direct3D9: (ERROR) :The resource manager failed to promote or update a dirty texture. The texture will be disabled.

The same lines also appear when I call
m_pId3dDevice->ValidateDevice(&outValue)

The most interesting thing is that ValidateDevice() call returns S_OK, outValue is always '1'.

Does anybody know why in this case neither DrawPrimitive() nor ValidateDevice() function return any kind of D3D_ERROR? These functions always return success.

Thanks
Quote:Original post by Nesta
I see following lines in Debug Output:
Direct3D9: (ERROR) :All POOL_MANAGED resources in this device freed. No further video memory available.
Direct3D9: (ERROR) :The resource manager failed to promote or update a dirty texture. The texture will be disabled.
That error means: "I needed to create a resource in video memory for rendering, but there wasn't enough video memory. I purged all other D3DPOOL_MANAGED resources from video memory, but there still wasn't enough left over."

I would assume this happens because the frontbuffer, z-buffer, and other default pool resources are in video memory, and/or the GetAvailableTextureMem() function doesn't return video memory directly, meaning you've created a resource that's too large to fit in VRAM at the moment, but is probably big enough to fit in VRAM if there was nothing else there.

As for ways to detect this - good question. I've asked about this on the Microsoft DirectX newsgroups, lets see if Microsoft have any suggestions...
Thanks for your help. I really appreciate it.
It really seems logical that rendering fails because I try to use more memory than my graphic card can offer because when I apply "scaling" to the source volume everything works fine. If you can get more information about detecting of allocating to much space, please share it in this topic.

I have another question regarding to this situation. As I mentioned in previous posts, DirectX writes the corresponding message to Debug Output when I call m_pId3dDevice->DrawPrimitive(). While the result of this function execution is S_OK. So my code "thinks" everything works fine while it's not so. Is there any way I can retrieve this information from DirectX to be able at least to rebuild my volume in such case? I tried m_pId3dDevice->ValidateDevice() but it also returns S_OK.

Thanks everyone for help.
Well, I haven't had any updates on the DirectX newsgroups so I looked into this a bit further.

DrawPrimitive doesn't return an error because the bit of code that uploads the resources to video memory is a void function. I can only assume it's an internal function that's never supposed to fail. The function goes through all bound textures and if they're in the managed pool, it tries to create a copy of the resource in the default pool. If that fails, then it just tells the driver that no texture is bound in that stage (Hence "The texture will be disabled").

ValidateDevice doesn't report an error because it only reports errors from the driver, and it's the D3D layer that tries and fails to create the default pool texture - the driver just sees that there's no texture bound in that stage and carries on to check other things.

Unfortunately, the only other function I can see that creates the default pool copy is IDirect3DResource9::PreLoad - which is also a void function, so there's no way to tell if it fails from there.

The only suggestion I have is creating the volume texture in the default pool yourself, thus bypassing the resource manager completely. That looks like the only way to get this working - CreateVolumeTexture will fail if the texture can't be created in the default pool.

This topic is closed to new replies.

Advertisement