🔒 Locked
Problem changing texture data
Advertisement
Original Post
On XP, and an ATI Radeon Mobility 300, the following code flips a texture vertically after being loaded...I've recently upgraded to Vista and an NVidia Geforce 8800, and now the same code does nothing at all!! I've tried the same executable on XP, and it works perfectly, but on Vista, all are the textures are upside-down because they are not being flipping by the following function. I'm using the Apr 2006 DX SDK. Any idea what's going on? The flipping when commented out, or uncommented out in Vista has no effect. HRESULT hr = D3DXCreateTextureFromFileEx( g_pd3dDevice, imagePaths[x], D3DX_DEFAULT, D3DX_DEFAULT, D3DX_FROM_FILE, D3DUSAGE_DYNAMIC, D3DFMT_FROM_FILE, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0xFF000000, 0, 0, &g_pTextureAll[x] ); D3DSURFACE_DESC desc; g_pTextureAll[x]->GetLevelDesc(0,&desc); desc.Type = desc.Type; // goes to surface, both vista, xp desc.Format = desc.Format; //desc.Format = D3DFMT_A1R5G5B5, both vista, xp D3DLOCKED_RECT data; g_pTextureAll[x]->LockRect( 0, &data, NULL, D3DLOCK_READONLY ); BYTE* bits = (BYTE *)data.pBits; Flip_Bitmap((BYTE*)data.pBits, desc.Width*2, desc.Height); g_pTextureAll[x]->UnlockRect( 0 ); int CLevelDisplay::Flip_Bitmap(BYTE *image, int bytes_per_line, int height) { // this function is used to flip bottom-up .BMP images BYTE *buffer; // used to perform the image processing int index; // looping index // allocate the temporary buffer if (!(buffer = (BYTE *)malloc(bytes_per_line*height))) return(0); // copy image to work area memcpy(buffer,image,bytes_per_line*height); // flip vertically for (index=0; index < height; index++) memcpy(ℑ[((height-1) - index)*bytes_per_line], &buffer[index*bytes_per_line], bytes_per_line); // release the memory free(buffer); // return success return(1); }
What HRESULT's are you getting for ALL calls, not just the creation of the texture? If nothing is happening then it's almost certain that one of the locking functions (e.g. LockRect()) is failing.
Also, what sort of step-through debugging have you done? Static code analysis only goes so far, and as you pointed out the code CAN work in some configurations. You need to do runtime analysis of what the code is REALLY doing and not what you THINK its doing.
Running against the reference rasterizer and D3D debug runtimes will also yield some very useful information.
Get back to us with the answers to those two questions and we can hopefully help you fix this [smile]
Jack
Also, what sort of step-through debugging have you done? Static code analysis only goes so far, and as you pointed out the code CAN work in some configurations. You need to do runtime analysis of what the code is REALLY doing and not what you THINK its doing.
Running against the reference rasterizer and D3D debug runtimes will also yield some very useful information.
Get back to us with the answers to those two questions and we can hopefully help you fix this [smile]
Jack
hmm, I didn't spot that flag on the first look... but why did you ever specify read only when you're modifying the texture?!?! By definition that shouldn't work [smile]
Jack
Jack
Quote:
Original post by AberAber
Figured it out. Apparently graphics card treats differently or Vista???
g_pTextureAll[x]->LockRect( 0, &data, NULL, D3DLOCK_READONLY );
to
g_pTextureAll[x]->LockRect( 0, &data, NULL, NULL);
1. When you pass D3DLOCK_READONLY you make a promise to D3D (and the device driver) that you will only ever read from the locked texture. You then break that promise by expecting to be able to write to the texture using the pointer you got back.
The fact that this works on any machine is just good luck. When you pass D3DLOCK_READONLY, it is acceptable behaviour for the device driver to give you a pointer to a cached copy of the texture (remember the promise).
In fact for swizzled formats and textures in the managed pool I'd almost always expect the driver to return a system memory copy rather than the real memory being used by the GPU (device drivers do things like swizzling and unswizzling inside Lock()/Unlock()).
2.
Quote:
Flip_Bitmap((BYTE*)data.pBits, desc.Width*2, desc.Height);
D3DLOCKED_RECT.Pitch is there for a reason. There are plenty of situations and hardware configurations where it won't be the same as the width of the texture in bytes. In theory it can be a negative number too. A memcpy() to "copy image to work area" won't cut it.
3.
Quote:
D3DUSAGE_DYNAMIC
Do you need to Lock() the texture regularly? If you don't then you don't need a dynamic texture. You can still Lock() a texture that wasn't created with the D3DUSAGE_DYNAMIC flag, it's just [potentially] a bit slower to lock (but faster to render with).
4. How is the bitmap being used? If it's being used as a texture on sprites or 3D geometry then why not just flip the texture coordinates and let the GPU do the flip (it'll be *much* faster, free in fact, and doesn't need to do things like allocate temporary memory).
In addition to Simon's stuff, the Debug Runtimes would probably highlight this bug. You should ALWAYS be using the debug runtimes when developing, there's no excuse not to.
The reason (I assume) it works on your ATI card is that it has shared graphics memory, so the driver can just return a pointer to system memory anyway.
The reason (I assume) it works on your ATI card is that it has shared graphics memory, so the driver can just return a pointer to system memory anyway.
The textures are only loaded once, so I just flipped the bytes instead of having to worry about texture coordinates or anything like that. What happened is I was using bitmaps, so I had to flip them vertically, otherwise they're upside-down in-game.
What should I replace D3DUSAGE_DYNAMIC with? I am loading the texture, then changing the bytes, then it's not modified any longer. I thought I had changed it to something else, but it wouldn't let me change any bytes from the texture.
I got no errors, it's just as readonly the textures were not flipped till I took off the readonly flag, which seemed to work on almost all graphics cards until this end.
What is data pitch giving to me? How would I change my function call?
What should I replace D3DUSAGE_DYNAMIC with? I am loading the texture, then changing the bytes, then it's not modified any longer. I thought I had changed it to something else, but it wouldn't let me change any bytes from the texture.
I got no errors, it's just as readonly the textures were not flipped till I took off the readonly flag, which seemed to work on almost all graphics cards until this end.
What is data pitch giving to me? How would I change my function call?
Quote:
What should I replace D3DUSAGE_DYNAMIC with? I am loading the texture, then changing the bytes, then it's not modified any longer. I thought I had changed it to something else, but it wouldn't let me change any bytes from the texture.
Replace the usage with 0 and also replace the pool with D3DPOOL_MANAGED because textures in the default pool aren't directly lockable (dynamic textures are a special case, but they aren't well suited for use as general purpose textures).
Quote:
I got no errors, it's just as readonly the textures were not flipped till I took off the readonly flag, which seemed to work on almost all graphics cards until this end.
There is a truly staggering number of combinations of graphics chips, device driver versions, Windows versions, DirectX versions, motherboards, operating systems, BIOS configurations, etc. Many behave the same, some don't.
Writing to memory that a driver only expects reads from can actually be a difficult situation to properly catch and report in an error.
The advice about using the debug runtime is still good though. I've lost count of the number of times it's helped me locate bugs over the years...
Quote:
What is data pitch giving to me? How would I change my function call?
http://msdn2.microsoft.com/en-us/library/bb206357(VS.85).aspx
It's another one of those things that varies from driver to driver, OS to OS. I've seen at least one driver that lays surfaces out side-by-side in memory instead of one-after-the-other. MIP-map chains can sometimes have strange pitches too.
To deal with pitch, copy the texture line by line. Copy 'width' pixels, and add 'pitch' bytes to the start address off the line to get to the next line.
Does using Managed instead of the Default pool mean there's extra memory being used because a system and video memory copy of the texture is held?
Quote:
Original post by sirlemonhead
Does using Managed instead of the Default pool mean there's extra memory being used because a system and video memory copy of the texture is held?
Yes.
But:
1) system memory is virtual memory so gets paged out to disk if necessary when not in use. In normal use there shouldn't be any significant increase in physical system memory use.
2) if your application overcommits video memory you'll need a pool of system memory textures and your own system->default memory management scheme anyway. A custom texture manager is easy to write, but one that's efficient in all situations (virtual texturing on 3DLabs cards anyone?) and aware of all hardware configurations (UMA/shared memory systems anyone?) isn't so easy. The D3D and driver resource managers take all the edge cases into account.
3) default pool resources have to be torn down and re-constructed in lost device situations, that re-creation becomes a pain and a poor user experience if you have to load things in from disk again (obvious optimisation: a system memory copy...). That work is done for you with managed resources.
The only real downside to using managed resources is the pages in your address space that are occupied by the [paged out] system memory copies that aren't doing anything most of the time. That said, unless you're overcommitting massively or doing silly things, 2GB is still a lot of address space to be hitting a limit due to textures for an app (I've known a few situations where the limit has been a problem but it's always been down to a poor/silly decision elsewhere).
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement