quote:Original post by Mithrandir here are the situations where im sure DX can change the lpitch without telling you: Lost surfaces (if the user multi-tasks). and Texture management. other than that, im pretty sure that DX doesnt mess with the lpitch of surfaces at all.
Thanks. There are actually two places one could consider assuming: - Assuming lPitch is width * bpp so one can right optimized ASM routines. This may be okay in sysram, but maybe not. If lPitch is off during surface creation, the program would abort. If the program never aborts during testing, it''s probably fine. - Assuming lPitch remains the same from when you create the surface (which you are addressing). I''m not utilizing texture-management, but lost surfaces could be an issue. However, I''m not sure if it is possible to lose surfaces in sysram? You lose surfaces in video ram due to changing modes... but would you also lose surfaces in sysram if the system is doing a lot of swapping, etc.?
Probably if you''re managing it yourself, it''d be ok, but if it were a D3D or driver managed texture, it may change if the texture manager moves it from sysmem to vidmem and back.
I''d play it safe and never assume. The code is trivial.
You''re supposed to get the lPitch every time you lock a surface, and not assume. There is really no optimization in assuming the lPitch hasn''t changed anyway. (one variable assignment per frame (?), whoopy!)
There could be optimization in knowing lPitch the whole time, which is what this post was originally about. However, I doubt if that optimization is all that significant these days (using shifts vs. a mul). In writing a custom Blt routine, one would have to calculate y * lPitch + x only once. For each line, add (lPitch - width-of-sprite) to the offset...
I think the solution is creating Client Memory Surfaces. This way, you can define your own surface format, assuming the pitch to be equal to the width.
"Excerpt from DX7 SDK HELP" Client memory surfaces are simply DirectDrawSurface objects that use system memory that your application has previously allocated to hold image data. Creating such a surface isn''t common, but it isn''t difficult to do and it can be useful for applications that need to use DirectDraw surface features on existing memory buffers.
[C++] When creating surfaces, DirectDraw needs information about the dimensions of the surface (measured in pixels) and the surface pitch (measured in bytes), as well as the surface''s pixel format. However, unlike creating other types of surfaces, this information for client memory surfaces doesn''t tell DirectDraw how you want the surface to be created, it tells DirectDraw how you''ve already created it. You set these characteristics, plus the memory address of the buffer you''ve allocated, in the DDSURFACEDESC2 structure you pass to the IDirectDraw7::CreateSurface method.
A client memory surfaces works just like a normal system-memory surface, with the exception that DirectDraw does not attempt to free the surface memory when it''s no longer needed; freeing client allocated memory is the application''s responsibility.
The following example shows how you might allocate memory and create a DirectDrawSurface object for a 64×64 pixel 24-bit RGB surface:
// For this example, g_lpDD is a valid IDirectDraw7 interface pointer.
#define WIDTH 64 // in pixels #define HEIGHT 64 #define DEPTH 3 // in bytes (3bytes == 24 bits)
// Allocate memory for a 64 by 64, 24-bit per pixel buffer. // REMEMBER: The application is responsible for freeing this // buffer when it is no longer needed. if (lpSurface = malloc((size_t)WIDTH*HEIGHT*DEPTH)) ZeroMemory(lpSurface, (DWORD)WIDTH*HEIGHT*DEPTH); else return DDERR_OUTOFMEMORY;