how to make sure StretchRect is done?

Started by
6 comments, last by Evil Steve 13 years, 4 months ago
// pD3D9Surface was got from 3rd party library
IDirect3DDevice9* pD3D9device =NULL;
pD3D9Surface->GetDevice(&pD3D9device);
HANDLE hSharedHandle =NULL;
LPDIRECT3DTEXTURE9 pD3DTmpTexture = NULL;
hr = pD3D9device->CreateTexture(nImageWidth, nImageHeight, 1,
D3DUSAGE_DYNAMIC,
D3D9Format,
D3DPOOL_DEFAULT,
&pD3DTmpTexture,
&hSharedHandle);
hr =pD3D9device->StretchRect(pD3D9Surface, NULL, pD3D9TmpSurface, NULL, D3DTEXF_NONE);
// here how could I know copy is done?
Currently, I use "pD3D9TmpSurface->LockRect(&loc, NULL, D3DLOCK_READONLY)"
to make sure the copy is done. But this is very bad for performance. so how could I do to make sure copy is done?
thank you for your answers.
Advertisement
Why does it matter? The driver is free to do it whenever it likes, so long as it doesn't affect the outcome.
thank you. but I want to use copied surface to do something else. before it completes copy action the copied surface has nothing. currently I use lockrect to make sure copy is done. but lockrect costs too much time. so is there any way to know the copy is done?
Quote:Original post by mliu
thank you. but I want to use copied surface to do something else. before it completes copy action the copied surface has nothing. currently I use lockrect to make sure copy is done. but lockrect costs too much time. so is there any way to know the copy is done?


I'm pretty sure the driver will take care of that for you and block if you make a read request before the stretch is finished. Have you actually had it read before the stretch finished, or are you trying to anticipate potential problems?
Quote:Original post by kuroioranda
Quote:Original post by mliu
thank you. but I want to use copied surface to do something else. before it completes copy action the copied surface has nothing. currently I use lockrect to make sure copy is done. but lockrect costs too much time. so is there any way to know the copy is done?


I'm pretty sure the driver will take care of that for you and block if you make a read request before the stretch is finished. Have you actually had it read before the stretch finished, or are you trying to anticipate potential problems?


thank you! but I think I can not actually understand what you said.The question I encountered is that I got a surface from a library which does not belong to us.
This surface can not be shared, so I created a surface which can be shared, then copy the origin surface to the surface I created, at last I created a device and a surface using the shared handle. the problem is that I do not know when stretchrect is done. so even I got the shared handle and create surface use this shared handle. but probably the surface created use shared handle has no data, because stretchrect is not completed. To me the solution is that after I called stretchrect, I called lockrect, but as you know lockrect cost too much time, so how could I do to make sure stretchrect is done? or any solution to solve the problem I came up with? Thank you very much!
Quote:Original post by mliu
Quote:Original post by kuroioranda
Quote:Original post by mliu
thank you. but I want to use copied surface to do something else. before it completes copy action the copied surface has nothing. currently I use lockrect to make sure copy is done. but lockrect costs too much time. so is there any way to know the copy is done?


I'm pretty sure the driver will take care of that for you and block if you make a read request before the stretch is finished. Have you actually had it read before the stretch finished, or are you trying to anticipate potential problems?


thank you! but I think I can not actually understand what you said.The question I encountered is that I got a surface from a library which does not belong to us.
This surface can not be shared, so I created a surface which can be shared, then copy the origin surface to the surface I created, at last I created a device and a surface using the shared handle. the problem is that I do not know when stretchrect is done. so even I got the shared handle and create surface use this shared handle. but probably the surface created use shared handle has no data, because stretchrect is not completed. To me the solution is that after I called stretchrect, I called lockrect, but as you know lockrect cost too much time, so how could I do to make sure stretchrect is done? or any solution to solve the problem I came up with? Thank you very much!


What I meant was, are you sure you need to check if the copy is done? The driver is almost definitely doing that for you automatically. If you try to use the surface before the stretch is done, the driver will check that and say "wait, this other operation isn't done" and then it will stall until the stretch is complete. All of this will be invisible to your program. You should be able to just pretend that the stretch completes immediately.
There is no "good" performance in this case. You're queuing a command into the command buffer (StretchRect) and then immediately forcing it to flush (LockRect). The overhead of LockRect is negligible compared to waiting for the GPU to finish everything in the command buffer.

Not sure what you're doing, but if you can afford to be a frame old than use two surfaces and ping-pong them. If not, is there any other work you can do on the CPU side before issuing calling LockRect?
-- gekko
Quote:Original post by mliu
I want to use copied surface to do something else.
As kuroioranda said, the driver will make sure that the StretchRect is done when you try to access the surface for anything else. There's no special code needed, the driver does it automatically.

Unless of course you're trying to access the surface from another thread, and the device isn't created as D3DCREATE_MULTITHREADED, because then all bets are off.

This topic is closed to new replies.

Advertisement