Archived

This topic is now archived and is closed to further replies.

djsomers

use filp() without Lock()ing the surface ?

Recommended Posts

Can I Flip the primary surface without Locking it first, and also can I blit to secondary (offscreen) buffers and in vram buffers without locking their suraface first. I am advised that my locking - unlocking is very slow. djsomers

Share this post


Link to post
Share on other sites
you should only flip the back buffer to the primary if its not locked,

as for bliting you should lock the target, i dont remember but i dont think you need to lock the src, but you mite, read the SDK to find out


-VBLimits
Sorry about the Spelling..


Edited by - VBLimits on November 16, 2001 4:55:24 AM

Share this post


Link to post
Share on other sites
Seems like u want to Flip/Blt surfaces without locking/unlock them everytime, right ?
Well... i got this little soluction for you... and yea it works !

If u r in Windowed Mode...things r pretty simple. Right after creating the back buffer, Lock it once
and store the surface pointer ( which may look something like g_pDDBackBufferPointer ) as a
global variable. Nows itz just a matter of using this global variable wherever u want to; you dont
have to lock surfaces for every frame now.

If u r in FullScreen mode... dont worry , all u have to do is write few more lines of codes. In fullscreen
mode, Surfaces are flipped rather than Blitting. While ur BackBuffer is Flipped with the FrontBuffer, the
surfaces pointers get swapped internally. So the solution is; when u Create ur BackBuffer and FrontBuffer lock
both of them once, get the pointer to global variables ( for example g_pDDBackBufferPointer and g_pDDFrontBufferPointer ). Now Swap these two pointer everytime u Flip !!. This is how u can skip the
whole process of Locking/Unlocking. And tell u what... it works !!!

Example:

HRESULT Present()
{

HRESULT hr = g_pDDFrontBuffer->(g_pDDBackBuffer,DDFLIP_WAIT);
if(FAILED(hr)) return hr;

// swap the global variables
VOID *pTemp;
pTemp = g_pDDFrontBufferPointer;
g_pDDFrontBufferPointer = g_pDDBackBufferPointer;
g_pDDBackBufferPointer = pTemp;

}

Now u can use the pointer g_pDDBackBufferPointer to write anything on the backbuffer cuz it
will always be pointing to the CURRENT backbuffer. Problem solved !! I hope this should improve
the speed of you program quite substantially.

Share this post


Link to post
Share on other sites
Something''s not right here. A couple of points...

1)Neither the primary nor back buffer should be locked when you flip. If either is, flip will fail.

2) If you are doing a hardware blit (IDirectDrawSurface*->blit()), then the surface should not be locked, otherwise the blit will fail (so, no, VBlimits, you should *NOT* lock the target for blitting). You only need to lock the surface if you are going to access surface memory yourself, for your own custom blit routines, line drawing routines, and what have you.

3) This one is directed to browny - there is absolutely no guarantee that saving a pointer to a locked surface will always point to that surface. A number of things could happen to cause that saved pointer to suddenly be pointing at garbage. You should *NEVER* rely on a surface pointer. Doing so is just asking for trouble - maybe not now, but probably later. That would be a hell of a debugging nightmare. Just because it works for you now doesn''t mean it will always work on every machine. There was considerable debate about this a while back and the common consensus was, don''t do it.

So, in answer to the original questions, yes and yes. If you are using the DDraw blit routines you can (and have to) blit without locking the surfaces.

Share this post


Link to post
Share on other sites
I don't know where you guys get your information from, I ran some test on lock & unlock, its really not that slow, on my system it takes about the same amount of time as counting from 0 to 800 in a for loop. That's it, just counting, nothing else.

Sure if you were locking 1000 vertex buffers each frame or something, but who would do that anyway.

Have a look at my post.

http://www.gamedev.net/community/forums/topic.asp?topic_id=65990


Edited by - burp on November 16, 2001 3:29:03 PM

Share this post


Link to post
Share on other sites
quote:
Original post by burp
I don''t know where you guys get your information from, I ran some test on lock & unlock, its really not that slow, on my system it takes about the same amount of time as counting from 0 to 800 in a for loop. That''s it, just counting, nothing else.

Sure if you were locking 1000 vertex buffers each frame or something, but who would do that anyway.

Have a look at my post.

http://www.gamedev.net/community/forums/topic.asp?topic_id=65990


Edited by - burp on November 16, 2001 3:29:03 PM


It also depends on heavily loaded the memory on the card is, if it is PCI, AGP, AGPx2 and even how you have created the buffer (for vertex and indece buffers).

You need to run your tests on more than just one platform to get a more accurate picture.



D.V.

Carpe Diem

Share this post


Link to post
Share on other sites
quote:
DeltaVee, It also depends on heavily loaded the memory on the card is, if it is PCI, AGP, AGPx2 and even how you have created the buffer (for vertex and
indece buffers).


That''s true... Or is it? Does anyone know what a lock really is and how it works. I have some idea, but I''m looking for a technical explanation.

I have AGPx4, what do you have and how long does your lock unlock take?

Maybe we should create a program that would test locking and unlocking under different circumstances and have other members of GameDev run it, the results could then be tabulated and added to a GameDev tutorial or something.

Then we really would know for sure.

Share this post


Link to post
Share on other sites
Surface locking is the same as locking a standard heap block, only DDraw has to get all the info on the surface as well (for the DDSURFACEDESC struct).

When a standard memory block is locked, a flag on it just has to be set so that nothing tries to move it (i.e. that the pointer you get stays constant).

Superpig
- saving pigs from untimely fates
- sleeps in a ham-mock at www.thebinaryrefinery.cjb.net

Share this post


Link to post
Share on other sites
quote:

Post by superpig

Surface locking is the same as locking a standard heap block, only DDraw has to get all the info on the surface as well (for the DDSURFACEDESC struct).

When a standard memory block is locked, a flag on it just has to be set so that nothing tries to move it (i.e. that the pointer you get stays constant).



That's what I was thinking too, its basically just the same thing as a IDirectDrawSurface7:ageLock, which it needed on some (all?) hardware to do DMA transfers.

So lock really has nothing to do with the graphics card per say, it has to do with Windows memory management.



Edited by - burp on November 16, 2001 10:52:58 PM

Share this post


Link to post
Share on other sites
quote:

Post by burp
Sure if you were locking 1000 vertex buffers each frame or something, but who would do that anyway.


I once had a program that locked the vertex buffer around 480000 times a frame! However I reworked the engine so that it stores vertex information in arrays, and then those arrays are read and shoved into a vertex buffer once right before the engine renders... stupid voxel engines,
Cheers,
-Jesse

Share this post


Link to post
Share on other sites
I think there is only one absolutely safe way to use a surface without locking it first.

IDirectDrawSurface7::SetSurfaceDesc

quote:

MS SDK

Currently, this method can be used only to set the surface data and pixel format used by an explicit system-memory surface. This is useful because it allows a surface to use data from a previously allocated buffer without copying. The new surface memory is allocated by the client application, and therefore the client application must also deallocate it. For more information, see Updating Surface Characteristics.

Using this method incorrectly causes unpredictable behavior. The DirectDrawSurface object does not deallocate surface memory that it did not allocate. Therefore, when the surface memory is no longer needed, it is your responsibility to deallocate it. However, when this method is called, DirectDraw frees the original surface memory that it implicitly allocated when creating the surface.





Edited by - burp on November 17, 2001 6:52:36 PM

Share this post


Link to post
Share on other sites
And one time at band camp...

quote:

webmunkey

I once had a program that locked the vertex buffer around 480000 times a frame!




So, did those 480000 locks slow your engine down or what?

Edited by - burp on November 17, 2001 1:20:27 PM

Share this post


Link to post
Share on other sites
quote:
Original post by burp
So lock really has nothing to do with the graphics card per say, it has to do with Windows memory management.


Well, kinda. Any decent graphics card now provides video memory - that is, surface memory can be in the video card itself. However, because not all the cards do this, Windows has to be able to fill in the gap. So the card does it if it can, and otherwise it''s left to the memory manager...

Superpig
- saving pigs from untimely fates
- sleeps in a ham-mock at www.thebinaryrefinery.cjb.net

Share this post


Link to post
Share on other sites