Accessing BackBuffer() = slow(?!)

Blitz3D Forums/Blitz3D Programming/Accessing BackBuffer() = slow(?!)

Kryzon(Posted 2008) [#1]
Hey there, I was testing some writing to the memory of the BackBuffer() through a DLL and - wow! it just gave me a FPS of 0.7 frames per second... Well, i'm not really sure, but that doens't seem to be suitable for real-time purposes :D
The C++ code I'm using is correct, has been revised several times and is as optimized as you'd get. The problem lies in Blitz3D's handling of buffer memory and the accessing of it.

I am using the LockBuffer/UnlockBuffer on the BackBuffer() just before I call in the userlib function to read from it (passing the memory pointer of the BB() to the DLL). Problem is, it IS actually doing it's job, processing the pixels the way I wanted the DLL to do - but it's just excessively slow.
What is the fastest (consequently, the most adequate) method to utilize to actually acheive Real-Time capabilities of Buffer Processing through an external DLL? it's just this last thing I need to do to make my special-effect work.

Thank you for your time,
Rafael.


markcw(Posted 2008) [#2]
I don't know, are you treating the buffer as a DX7 surface in your DLL?
Ask MixhailV, he wrote FastImage: http://fastlibs.com/libraries.php


Kryzon(Posted 2008) [#3]
No, I'm manually writing down the pixel values to the memory buffer. But it seems it is excessively slow to access the buffer memory.

I'll ask MixailV what he knows, thanks for the info :)


Ross C(Posted 2008) [#4]
Best to copy the backbuffer to a texture, then edit the texture. It's alot quicker :o)


Kryzon(Posted 2008) [#5]
Problem is I don't want to have to show a texture in a plane in front of the camera - I was like, hoping to do this the "right" way, manipulating the backbuffer then writing the results back to it again, then FLIPping it so the user could see the results of whatever effect I might want.


markcw(Posted 2008) [#6]
Well my understanding of it is: to manipulate surfaces fast you treat it like a DX7 surface so that the video card does the work (hardware accelerated).

Have you got the dx7sdk? It's very useful but hard to find today. I suppose I could email it to you if you don't have it (it's about 100MB).

Another guy who could help is Tom Speed, you can get his email here.


Charrua(Posted 2008) [#7]
Hi Rafael

If I don't missunderstood, you want to take a "image" of the backbuffer before flip, to do some bit processing and then, flip.

I'been working with two cameras, that render the same and think, why to render 2, that duplicates the trisrendered, If I use only one camera, render one, then, before flip, copy the half backbuffer of the camera just rendered (by renderworld).

I started with grabimage, copypixel, copypixelfast, and all the associated lock/unlockbuffer. None work's for me.

The only way I found to copy the backbuffer was using copyrect
it's fast, you have not to lock/unlock nothing, you have not to make a buffer active as for copypixel etc.
CopyRect 0,0,512,768,512,0,BackBuffer(),BackBuffer()
that line copy the rendered viewport of one camera (viewport:0,0,512,768) to the other half of the screen.

I supose you could use copyrect to copy the area of the backbuffer to an image in memory (created with createimage, with the same size) and then pass to the dll a pointer to that image. Then, copyrect again from the image (your dll has handled) to the backbuffer.

hope that help

Juan


Kryzon(Posted 2008) [#8]
I see now, Markcw! Searched in the MSDN and found the DirectDraw documentation, lot's of interesting stuff there! I mean, the Flip command must be something like the IDirectDrawSurface5::Flip, that's so interesting!
And the most lovely thing is that it's all hardware accelerated (I believe that's why MixailV was getting so much speed from his FastImage library).

Well, if DirectX 9 has DDraw implementation (I hear it was taken from v8), there'll be no need for the SDK. Except the documentation - if there's a way for you to send it to me, I'd be most thankful!

Thanks for the posts here.


Kryzon(Posted 2008) [#9]
Hmm, I understand, Odriozola. I guess it's not necessary to create another image, because the backbuffer is just another DDraw Surface. What I did notice is that now I can access it's surface by adding +12 to the buffer handle - and pass that to the DLL that'll do whatever I want. Thanks for the CopyRect information, I'll look into it.


Warner(Posted 2008) [#10]
I think the problem with reading/writing to buffers is that they are stored in the videocard memory. I also think that uploading data to the videocard is faster than reading data from it. This however, might depend on the type of videocard.


DareDevil(Posted 2008) [#11]
is possible execute copyrect x,y,x1,y1,BackBuffer(), BANKbuffer()?


MikhailV(Posted 2008) [#12]
Any manual manipulations with pixels are slow...
About copyrect x,y,x1,y1,BackBuffer(), BANKbuffer() - Bank has no buffer. It is possible to copy video-data in bank, but blitz-language very slow. I shall repeat, even in C ++ operations with pixels will be slow. Use only GPU-accelerated methods from DirectX7!


Charrua(Posted 2008) [#13]
I only use copyrect from BackBuffer to BackBuffer and from BackBuffer to ImageBuffer

Juan


Kryzon(Posted 2008) [#14]
Use only GPU-accelerated methods from DirectX7!

And by that you mean DirectX 7's DirectDraw? I just hope DirectX 9 SDK will do the trick with DirectDraw.
Just gotta find the surface structure commands for peeking, poking, etc.


SLotman(Posted 2008) [#15]
DirectDraw was dropped on DX8. There´s no DirectDraw on DX8/DX9/DX10.

Also, editing the backbuffer will always be slow. I once did a routine to process the screen in C++/OpenGL and it was so slow it couldnt be used inside the game I was making.


markcw(Posted 2008) [#16]
Here's a quote from Tom Speed if it's any help. Did you get the dx7doc.zip I emailed you?
// This should work fine for textures, cubemaps & images.

....

IDirectDrawSurface7 *tex=NULL;

// bbHandle is a Blitz3D handle, i.e, handle = loadtexture("blah.jpg")
tex = DDS_FromBBTextureHandle(bbHandle, frame == 0); 

// you can now do whatever work you want to the DDS handle 'tex'


IDirectDrawSurface7* DDS_FromBBCubemapHandle(unsigned int handle,int face)

{

 if(handle==0) return 0;

 handle = (unsigned int) *((int*)(handle));

 handle = (unsigned int) *((int*)(handle+12));

 handle = (unsigned int) *((int*)(handle));

 if(handle==0) return 0;

 

 return (IDirectDrawSurface7*) *((int*)(handle+24+(face*4)));

}

 

IDirectDrawSurface7* DDS_FromBBTextureHandle(unsigned int handle,int frame)

{

 if(handle==0) return 0;

 handle = (unsigned int) *((int*)(handle));

 handle = (unsigned int) *((int*)(handle+12));

 handle = (unsigned int) *((int*)(handle+(4 * frame)));

 if(handle==0) return 0;

 

 return (IDirectDrawSurface7*) *((int*)(handle+12));

}

 

IDirectDrawSurface7* DDS_FromBBImageHandle(unsigned int handle,int frame)

{

 if(handle==0) return 0;

 handle = (unsigned int) *((int*)(handle+4));

 handle = (unsigned int) *((int*)(handle+(4 * frame)));

 if(handle==0) return 0;

 

 return (IDirectDrawSurface7*) *((int*)(handle+12));

}



markcw(Posted 2008) [#17]
Rafael, sorry I can't reply by email but outgoing is not working today.

Anyway, try these files:
http://www.blitzmax.com/logs/userlog.php?user=8652&log=1737


Kryzon(Posted 2008) [#18]
Hey Mark, just got your email showing your upload account. Downloaded both Docs (from 6.1 and 7) and that .DOC looks promising! lot's of info there about DDraw!

So, I let here a big Thank You to you :D

Bye and cya later,
Rafael.