Page 1 of 3

Is there a faster way for DSA ? (Test EXE)

Posted: Fri Feb 10, 2006 10:26 am
by va!n
Some of you may know the DSA (direct screen acess) commands in PureBasic like DrawingBufferPitch()... For example a screen effect will be calculated and each pixel will be stored in a DIM... If all calculations are done, you have to write each pixel to the screenbuffer... Isnt there any way like following idea:

lBuffer = AllocateScreenBuffer(ScreenWidth, ScreenHeight)

This will allocate one complete memory block (ScreenWidth * ScreenHeigh * 32 bit for manipulations) instead using DIM fields... Then there could be a command like...

DrawScreenBuffer(lBuffer)

This command will paste all datas direct to the screen buffer... the user dont need again "for x = 0 to ScreenWidth" and "for y = 0 to ScreenHeight" methode...

I think this way could be a bit faster!? Anyway atm i am using DIM... is there any way how to speed it up (reading values from the dim?) maybe with a pointer? (or does it make no sence to improve speed?)

Using DSA on 640x480 screen may work ok on my system but if you try higher resolutions like 1024x768 for example the effects are very slow / not acceptable!

Is there any way to improve such stuff?? How does guys make this in there intros/demos? Thanks!

Posted: Fri Feb 10, 2006 12:40 pm
by Fred
You have probably another problem here, putting a pixel directly on the video card is the most efficient way to do it.

Posted: Fri Feb 10, 2006 1:42 pm
by va!n
i know that this should be the fastest way and i think even stuff with resolutions like 1024*768 for example should run smooth!?

However i found a small problem i cant understand... I changed for testing purposes the resolution down to 320*240 ! There is never any random stuff... every loop do the same thing...

But check out the FPS... i dont used any FPS limit commands... Normaly the effect runs here with around 60 PFS (in 320*240 only) ... But while running the effect, the FPS goes very often extremly down! (i mean < 50% as the normal FPS) !!

I added a small test routine, checking the FPS... if the actual FPS is under 50% of the old (normal FPS) one... it will draw a white box to the screen...

Just test and see how ofte you may see white box on screen... shouldnt the FPS everytime nearly the same... instead brake down 50% ???

www.secretly.de/test/Tunnel_FPS_Problem.exe


@all
If someone can confirm the problems with the FPS and seeing white boxes, please report... thanks

Posted: Fri Feb 10, 2006 1:56 pm
by aaron
I saw the same thing with the FPS and the white boxes, running on a ATI mobile chipset.

I noticed something with the white boxes: If I moved the mouse around over the window, the white boxes occur quite a bit. That made me think that the white boxes are an artifact from the OS updating the screen perhaps?

No idea why the FPS dropped to half speed for a few seconds though. I couldn't notice any difference with the animation itself though... it didn't seem that it was only running at 25 FPS.

Posted: Fri Feb 10, 2006 1:59 pm
by va!n
thanks for the first feedback...

i added the white boxes to see on screen if the FPS is down 50% ... i just randomized the position of the whote box to see when it happens...

[Edited]
A few seconds ago, i noticed following result... What means 1.#INF00 ??? here is the screenshot...

www.secretly.de/test/fx_problem.jpg

Posted: Fri Feb 10, 2006 2:15 pm
by IceSoft
I saw the white boxes on my Matrox Millenium G450 DVI too

Posted: Fri Feb 10, 2006 2:19 pm
by traumatic
How are you calculating the FPS?

All I can see is constant flickering, the update is way too fast.
You can't rate the actual frames per second like that.

Posted: Fri Feb 10, 2006 4:28 pm
by remi_meier
As I heard somewhere, it is much faster to write in the sequence of the
buffer without jumping a lot. For this, I think I used CopyMemory() and
it worked about 50% faster (if I remember it correctly). I don't know if
it is allowed but seemed to work fine and fast for me :lol: . So copy it back
all at once!

Posted: Fri Feb 10, 2006 4:30 pm
by va!n
traumatic wrote:How are you calculating the FPS?

All I can see is constant flickering, the update is way too fast.
You can't rate the actual frames per second like that.
Yes, you are right... the way i did the FPS still sucks... (esp using two times GetTickCount_() in one loop = bad! i needed it in a hurry and found it on the web! here is an example...

Code: Select all


texWidth     = 256
texHeight    = 256
screenWidth  = 640/2
screenHeight = 480/2

; -------- Open Screen --------

InitSprite() : InitKeyboard()

OpenWindow(0,0,0,screenWidth,screenHeight,#PB_Window_WindowCentered |#PB_Window_ScreenCentered ,"Realtime DirectX Effect")
OpenWindowedScreen(WindowID(0),0,0,screenWidth,screenHeight,0,0,0)

TimeDelay.l=100 
MasterTimer.l=GetTickCount_() 

Repeat
  ExamineKeyboard()
  ClearScreen(0)
        
  TimeDelay=GetTickCount_()-MasterTimer 
  MasterTimer=GetTickCount_() 
  FrameRate.f=1000/TimeDelay 
  
  OldFPS.f = NewFPS.f / 2    
  NewFPS.f = FrameRate.f

  SetWindowTitle(0,"ActualFPS: "+StrF(NewFPS)+"     PrevFPS: "+StrF(OldFPS*2))        
        
  StartDrawing(ScreenOutput())
    If  newFPS.f < oldFPS.f
      Box(Random(320-50),Random(240-50),50,50,$ffffff)
    EndIf
  StopDrawing()
 
  lEvent = WaitWindowEvent(2)
        
  FlipBuffers(1) ;: Delay(1)
   
Until KeyboardPushed(#PB_Key_Escape)

End
here is another methode to get the FPS... this looks a bit better...

Code: Select all


texWidth     = 256
texHeight    = 256
screenWidth  = 640/2
screenHeight = 480/2

; -------- Open Screen --------

InitSprite() : InitKeyboard()

OpenWindow(0,0,0,screenWidth,screenHeight,#PB_Window_WindowCentered |#PB_Window_ScreenCentered ,"Realtime DirectX Effect")
OpenWindowedScreen(WindowID(0),0,0,screenWidth,screenHeight,0,0,0)

 StartT=GetTickCount_()

Repeat
  ExamineKeyboard()
  ClearScreen(0)
        
  Fps+1
  If ElapsedMilliseconds()-StartT=>1000 : StartT=ElapsedMilliseconds() : CurrentFps=Fps : Fps=0 : EndIf
  
  StartDrawing(ScreenOutput()) 
    DrawingMode(1) : FrontColor(250)
    DrawText(20,20," FPS="+Str(CurrentFps)) 
  StopDrawing()
  
  lEvent = WaitWindowEvent(2)
   
  OldFPS.f = NewFPS.f / 2    
  NewFPS.f = CurrentFPS

  SetWindowTitle(0,"ActualFPS: "+StrF(NewFPS)+"     PrevFPS: "+StrF(OldFPS*2))        
        
  StartDrawing(ScreenOutput())
    If  newFPS.f < oldFPS.f
      Box(Random(320-50),Random(240-50),50,50,$ffffff)
    EndIf
  StopDrawing()     
        
  FlipBuffers(1) ;: Delay(1)
   
Until KeyboardPushed(#PB_Key_Escape)

End
However is it normal in the first example, that the FPS sometimes will be dropped half speed for a few seconds? I think this is the reason in my FX, that it does not run smooth!?

When trying to run the FX on my system in 1024*768 you can sadly forget it!

Posted: Fri Feb 10, 2006 4:35 pm
by va!n
remi_meier wrote:As I heard somewhere, it is much faster to write in the sequence of the
buffer without jumping a lot. For this, I think I used CopyMemory() and
it worked about 50% faster (if I remember it correctly). I don't know if
it is allowed but seemed to work fine and fast for me :lol: . So copy it back
all at once!
I thought too, that iw would be much faster to use a complete memory block and writing in a sequence to this and then copy this complete buffer to the gfxbuffer (as i tried to explain in my first post)...

@remi_meier:
Can we meet us in ICQ to talk about it? I will be back in about 30 minutes from now... Thanks in advance!

Maybe there is a way to use pointers to speed it more up and maybe to get it run smooth in 1024x768 mode as it doesnt did atm...

Posted: Fri Feb 10, 2006 5:14 pm
by Dummy
I kno maybe it's off topic but the really fastest method doing this is directly on the videocard...by pixelshaders ;)

I know it's a totally different system but it much faster ;)

Posted: Fri Feb 10, 2006 5:20 pm
by Thalius
Pixel Shaders are used to render on 3D Surfaces.. as i can gather va!n wants to access the screen directly ( for drawing commands ... tricks etc ) . I smell some good old Amiga-Demo code coming up ... :lol:

Thalius

Posted: Fri Feb 10, 2006 9:33 pm
by Jan Vooijs
Va!n,

Modifying your code:

Code: Select all

       
  StartDrawing(ScreenOutput())
    ; If  newFPS.f < oldFPS.f
      Box(Random(screenWidth-50),Random(screenHeight-50),50,50,$ffffff)
    ; EndIf
  StopDrawing()

It runs better and the white blocks are allways to be seen. Why the IF statement? It shows the white block ONLY if the previous fps is higher..

And an other thing, now the program runs "full screen" if you change the screenWidth and/or screenHeight...

An strange observation the SMALLER the screen size the MORE CPU cycles it uses?????

320x240 = 88%
1024x768 = 70%
1280x1024 = 55%

How is that!!!????

Posted: Sat Feb 11, 2006 3:31 pm
by Hatonastick
Scaling graphics down would be my guess, but Im usually wrong.

Posted: Sat Feb 11, 2006 3:44 pm
by djes
MrVain> Look at this ;) and thanx tonton : http://purebasic.hmt-forum.com/viewtopi ... ght=tonton