[DX9,SlimDX,ATI] Incorrect saving surface to file

Started by
3 comments, last by user88 13 years, 2 months ago
Hi,

I use DirectX 9 and SlimDX for 3D visualization. There is a one problem for some ATI graphics adapters. When the scene is rendered to render target and i use Surface.ToFile() method it saves files with some incorrect content. Here is an example:
hskqcl.jpg

Note, not all ATI graphics adapters have such problems and none of nVidia devices have it. I have confirmed cases on HD 5660, 5650 and 4550.

For saving rendered scene to file i use simple X8R8G8B8 render target. But i noticed that there is[font="Arial"] IDirect3DDevice9::CreateOffscreenPlainSurface method.

What does that method produce and has this any relation [font="Arial"] problem?
Advertisement
I can't think of any way this would break like that on only a handful of cards, without it being a driver issue of some kind.

Have you tried using a few different driver versions on those problematic cards?
Thanks for answer Adam,

Yes, I made test with two different versions of drivers. First version was from CD which I got with the device. And second was latest drivers from the official web site (ver. 11.1).
Also the fact is that the previous version of our 3D engine works good on such graphics adapters. Unfortunately, there were lot of changes between these two version, and it is not so easy to detect what actually causes the problem..

So, any help will be appreciated!
Hello, i have solved this problem. I don't know why, but some ATI graphics adapters have problems with stretch rectangle when destination surface is the render target surface. All works good when destination surface is the surface of dynamic texture.

Here is the old code (in c#):

using (Surface src = Device.GetRenderTarget(renderTargetIndex))
{
SurfaceDescription srcDesc = src.Description;
format = srcDesc.Format;
Rectangle srcRect = new Rectangle(0, 0, width, height);
dst = Surface.CreateRenderTarget(Device, width, height, format, MultisampleType.None, 0, true);
Rectangle dstRect = new Rectangle(0, 0, width, height);
Device.StretchRectangle(src, srcRect, dst, dstRect, TextureFilter.None);
}

And new working code:

using (Surface src = Device.GetRenderTarget(0))
{
Surface nonMsaaSrc = src;
SurfaceDescription srcDesc = src.Description;

bool msaaOn = srcDesc.MultisampleType != MultisampleType.None;
if (msaaOn)
{
nonMsaaSrc = Surface.CreateRenderTarget(Device, srcDesc.Width, srcDesc.Height, srcDesc.Format, MultisampleType.None, 0, false);
Device.StretchRectangle(src, nonMsaaSrc, TextureFilter.None);
}

result = new Texture(Device, srcDesc.Width, srcDesc.Height, 1, Usage.Dynamic, srcDesc.Format, Pool.SystemMemory);
Surface dst = result.GetSurfaceLevel(0);
Device.GetRenderTargetData(nonMsaaSrc, dst);

if (msaaOn) nonMsaaSrc.Dispose();
}

This topic is closed to new replies.

Advertisement