Welcome, Guest. Please login or register.

Author Topic: Warp3d synchro/double-triply bufferging  (Read 18680 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
    • Show only replies by Piru
    • http://www.iki.fi/sintonen/
Re: Warp3d synchro/double-triply bufferging
« Reply #14 on: February 14, 2005, 04:39:00 PM »
@RWO
Quote
Karlos do you know how to do window double buffering?

There is no window buffering.
 

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
    • Show only replies by Piru
    • http://www.iki.fi/sintonen/
Re: Warp3d synchro/double-triply bufferging
« Reply #15 on: February 14, 2005, 04:44:27 PM »
@Karlos
Quote
One of the things is knowing exactly where to put the WaitBOVP() call - it can make all the difference.

You should not put it anywhere, ever. WaitBOVP() busyloops (or at least it busyloops with certain system configurations). It's a very bad idea to use this call.

You should use the syncronization service provided by ScreenBuffers (or rather graphics.library/DBufInfo that is used by intuition ScreenBuffers). See graphics.doc/DBufInfo for example of syncronized doublebuffering.
 

Offline kas1eTopic starter

Re: Warp3d synchro/double-triply bufferging
« Reply #16 on: February 14, 2005, 10:58:24 PM »
@Piru

but what about MiniGL sources ? i founding these strings in mglDisplaySwitch:

Code: [Select]


context->BufNr++;
if (context->BufNr == context->NumBuffers)context->BufNr = 0;

context->Buffers[nowbuf]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort=NULL;
while(!ChangeScreenBuffer(context->w3dScreen,context->Buffers[nowbuf]));

W3D_SetDrawRegion(context->w3dContext,context->Buffers[context->BufNr]->sb_BitMap,0,&(context->scissor));

if (context->DoSync) // if Sync in GL = TRUE, do SYNC.
{
struct ViewPort *vp = &(context->w3dScreen->ViewPort);
WaitBOVP(vp);
};



it's too bad ?
 

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
    • Show only replies by Piru
    • http://www.iki.fi/sintonen/
Re: Warp3d synchro/double-triply bufferging
« Reply #17 on: February 14, 2005, 11:14:00 PM »
Quote
it's too bad ?

Yes it is. It should use the buffering provided by the ScreenBuffers. With ScreenBuffer it would be perfectly synched to the display beam, and it would never busyloop.

Also, the code does some nasty manual busylooping if the ScreenBuffer cannot be swapped instead of just refusing the swap (ok, there might be some implementation specific reasons why it MUST always succeed to swap). Such while loops can create nasty lockup. If construct like this MUST be used, the code should sleep a bit after each failure.

Also, such WaitBOVP syncing breaks triplebuffering (triplebuffering will appear identical to doublebuffering then).
 

Offline kas1eTopic starter

Re: Warp3d synchro/double-triply bufferging
« Reply #18 on: February 14, 2005, 11:52:25 PM »
But in this examples ScreenBuffers combinate with WaitBOVP, but it is a ScreenBuffers anyway. Do you mean just using WaitBlit(), instead WaitBOVP(), maybe ?
 
 

Offline EntilZha

  • Full Member
  • ***
  • Join Date: Feb 2002
  • Posts: 131
    • Show only replies by EntilZha
    • http://www.hyperion-entertainment.com
Re: Warp3d synchro/double-triply bufferging
« Reply #19 on: February 15, 2005, 01:25:06 AM »
Quote
Yes it is. It should use the buffering provided by the ScreenBuffers. With ScreenBuffer it would be perfectly synched to the display beam, and it would never busyloop.


It does use ScreenBuffers.

Quote
Also, the code does some nasty manual busylooping if the ScreenBuffer cannot be swapped instead of just refusing the swap (ok, there might be some implementation specific reasons why it MUST always succeed to swap). Such while loops can create nasty lockup. If construct like this MUST be used, the code should sleep a bit after each failure.


It hardly ever fails to swap the screen buffer, anyway.

Quote
Also, such WaitBOVP syncing breaks triplebuffering (triplebuffering will appear identical to doublebuffering then)


That's what it's inside an IF statement... you can actually turn it off... so what's the point ?
- Thomas
Avatar by Karlos
 

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
    • Show only replies by Piru
    • http://www.iki.fi/sintonen/
Re: Warp3d synchro/double-triply bufferging
« Reply #20 on: February 15, 2005, 01:53:16 AM »
@EntilZha
Quote
It does use ScreenBuffers.

Indeed, ScreenBuffers themselves do sync to VBL by default. However, this is not enough to get "nice" syncronisation, as the WaitBOVP sync code points out.

ScreenBuffers (or graphics DBuf actually) have the ability to do the "nice" syncronisation (making sure the frame has been seen at least once), by using dbi_DispMessage. There is no need to use WaitBOVP.

Quote
That's what it's inside an IF statement... you can actually turn it off... so what's the point ?

DoSync is enabled by default, thus if triplebuffering is enabled (mglChooseNumberOfBuffers), one has to manually disable sync (MGLEnableSync) or you actually get doublebuffering with more memory usage. But I suppose that's obvious to everyone.

PS. It could be that graphics.library original ChangeVPBitMap does indeed busywait aswell, but this shouldn't be used as an excuse to force the same on systems where ScreenBuffers does multitasking friendly syncing, while WaitBOVP doesn't.

I'm sure you knew all this already.
 

Offline kas1eTopic starter

Re: Warp3d synchro/double-triply bufferging
« Reply #21 on: February 15, 2005, 03:51:36 AM »
mess :)

2piru: can you write func base on dbi_DispMessage, witchout
WaitTOF/WaitBOVP under Warp3D ?:)

2entzilla: why do not create 'W3D_Sync' for upcoming warp3d (if it will be) releases ?
 
 

Offline kas1eTopic starter

Re: Warp3d synchro/double-triply bufferging
« Reply #22 on: February 16, 2005, 01:51:26 AM »
@piru

Well, i try to use your case here:

Code: [Select]


    DBIport[0] = CreateMsgPort();
    DBIport[1] = CreateMsgPort();

    myScreenbuffer1 = AllocScreenBuffer(screen,NULL, SB_SCREEN_BITMAP);
    myScreenbuffer2 = AllocScreenBuffer(screen,NULL, 0);

    myScreenbuffer1->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort = DBIport[0];
    myScreenbuffer1->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort = DBIport[1];
    myScreenbuffer2->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort = DBIport[0];
    myScreenbuffer2->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort = DBIport[1];  


 ..create context/open screen...


while(1)
{
   // ...do some matrix/etc stuff
 
  while(!ChangeScreenBuffer(screen, myScreenbuffer2));
 
  if (! SafeToWrite)
      while(! GetMsg(DBIport[0])) Wait(1l<<(DBIport[0]->mp_SigBit));
      SafeToWrite=TRUE;

  W3D_LockHardware(context);
  W3D_ClearDrawRegion(context,0x00000000);  // fill screen with black color
  W3D_DrawTriStrip(context,&tris);
  W3D_UnLockHardware(context);


  if (! SafeToChange)
      while(! GetMsg(DBIport[1])) Wait(1l<<(DBIport[1]->mp_SigBit));
      SafeToChange=TRUE;
  while(!ChangeScreenBuffer(screen, myScreenbuffer1));
  SafeToChange=FALSE;
  SafeToWrite=FALSE;
}


     
In this case, after running, system halt, and only reboot can help me. If i adding WaitBOVP() in loop, it working, but problem anyway here - blinking of my object.

I just try this:

Code: [Select]


ChangeScreenBuffer(screen, myScreenbuffer2);
myScreenbuffer2->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort=0;

  W3D_LockHardware(context);
  W3D_ClearDrawRegion(context,0x00000000);  // fill screen with black color
  W3D_DrawTriStrip(context,&tris);
  W3D_UnLockHardware(context);


 myScreenbuffer2->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort=0;
ChangeScreenBuffer(screen, myScreenbuffer1);              



or just:

Code: [Select]


 ChangeScreenBuffer(screen, myScreenbuffer2);
 DBIport[0]=0;

  W3D_LockHardware(context);
  W3D_ClearDrawRegion(context,0x00000000);  // fill screen with black color
  W3D_DrawTriStrip(context,&tris);
  W3D_UnLockHardware(context);


 DBIport[1]=0;
 ChangeScreenBuffer(screen, myScreenbuffer1);      



Result the same. Just halt. If adding WaitBOVP(&(screen)->ViewPort); it works, but the same problem - blinking.
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show only replies by Karlos
Re: Warp3d synchro/double-triply bufferging
« Reply #23 on: February 16, 2005, 10:29:07 PM »
Quote

RWO wrote:
Karlos do you know how to do window double buffering?

-RWO


Piru is right in that there is no such thing. However, if you AllocBitmap() a BitMap using the display's BitMap as a friend, you will create an offscreen buffer you can render to.

You then use a call such as ClipBlit() to blit the offscreen buffer to the window. It isn't as fast as fullscreen (the blit actually does take some measurable time on older cards), but you achieve desired effect.
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show only replies by Karlos
Re: Warp3d synchro/double-triply bufferging
« Reply #24 on: February 16, 2005, 10:32:07 PM »
Quote

EntilZha wrote:
Quote
Yes it is. It should use the buffering provided by the ScreenBuffers. With ScreenBuffer it would be perfectly synched to the display beam, and it would never busyloop.


It does use ScreenBuffers.

Quote
Also, the code does some nasty manual busylooping if the ScreenBuffer cannot be swapped instead of just refusing the swap (ok, there might be some implementation specific reasons why it MUST always succeed to swap). Such while loops can create nasty lockup. If construct like this MUST be used, the code should sleep a bit after each failure.


It hardly ever fails to swap the screen buffer, anyway.



I ran a piece of code for two hours solid when testing something. In that time, the ChangeScreenBuffer() never failed once. I was curious to see if the while(!ChangeScreenBuffer(...)); call busy looped so had it increment a counter. It was still zero after the strain test finished.

I'd say Thomas remark here was understated even.
int p; // A
 

Offline Piru

  • \' union select name,pwd--
  • Hero Member
  • *****
  • Join Date: Aug 2002
  • Posts: 6946
    • Show only replies by Piru
    • http://www.iki.fi/sintonen/
Re: Warp3d synchro/double-triply bufferging
« Reply #25 on: February 17, 2005, 12:56:40 AM »
@kas1e

Of course it flickers, as you don't tell W3D where to render to. Now it only renders to the first buffer, and you toggle between the rendered frame and empty frame.

Like Karlos already pointed out you need to tell W3D where to render by using W3D_SetDrawRegion().

About the code in general: You've misunderstood something there. You must not call ChangeScreenBuffer for both ScreenBuffers in the loop, but instead you must have single call to ChangeScreenBuffer, and toggle between myScreenbuffer1 and myScreenbuffer2. When looking at the graphics/ChangeVPBitMap example, replace the ChangeVPBitMap call with ChangeScreenBuffer call.

Further checking to do:
1) Did you set both SafeToChange and SafeToWrite to TRUE initially?
2) Did you implement cleaning up the possibly pending messages after the loop?
 

Offline AmiGR

  • Hero Member
  • *****
  • Join Date: Mar 2002
  • Posts: 698
    • Show only replies by AmiGR
Re: Warp3d synchro/double-triply bufferging
« Reply #26 on: February 17, 2005, 06:30:08 AM »
BTW, the tall screen method/scrolling for double buffering will not work if there's any screen promotion utility that does screen centering active. The user ends up looking at the middle of the drawing area seeing a frame of the bottom part of the screen on top and vice versa... It took me *ages* to figure out what the hell caused that problem! :-)
- AMiGR

Evil, biased mod from hell.
 

Offline Mr_Capehill

  • Full Member
  • ***
  • Join Date: May 2002
  • Posts: 189
    • Show only replies by Mr_Capehill
Re: Warp3d synchro/double-triply bufferging
« Reply #27 on: February 17, 2005, 08:45:29 AM »
Karlos, does it make a big difference speed wisely to have a friend bitmap? I usually just allocate a bitmap with certain colour format properties and use BlitBitMapRastPort(), letting the OS handle all kind of conversion and saving me the trouble to support various possible colour formats.
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show only replies by Karlos
Re: Warp3d synchro/double-triply bufferging
« Reply #28 on: February 17, 2005, 03:59:52 PM »
Quote

Mr_Capehill wrote:
Karlos, does it make a big difference speed wisely to have a friend bitmap? I usually just allocate a bitmap with certain colour format properties and use BlitBitMapRastPort(), letting the OS handle all kind of conversion and saving me the trouble to support various possible colour formats.


It does indeed make a difference. Depending on your RTG card/driver, you might find that your graphics are converted by software.

I benchmarked the OS conversion and discovered that all cross-format blits on my CGX/Permedia2 were done in software by the driver software and not particularly quickly either. As a consequence I wrote my own routines and a 2D function LUT to do the job. These were hand optimised asm that did each possible conversion (there are less than 14x14 - most conversions are symmetrical) as fast as possible, taking advantage of 32-bit accesses, rotate instructions etc not available at the C level. They outperformed the OS blit routines by up to 3x on my system depending on the source/destination formats.

Anybody who ever ran my pixeltest tool has inadvertendly seen these routines, pixeltest was actually written purely to benchmark them (unbeknown to the users at large, you can specify the source data format on the command line).

Bottom line is:

Allocate your offscreen BitMap as a friend of the display. This ensures

a) that the BitMap is in Video memory

b) that the BitMap in the same format as the display, meaning that any Blit will be done in HW.

For Warp3D's hardware acceleration to work, (a) is absolutely essential anyway.

The downside is that you will have to care about the supported formats yourself. However, you would be very unlucky to encounter anything other than the following hardware formats

8-bit CLUT
15-bit RGB big endian (A1:R5:G5:B5)
15-bit RGB little endian
16-bit RGB big endian (A0:R5:G6:B5)
16-bit RGB little endian
32-bit ARGB
32-bit BGRA (just 'little endian' ARGB32 ;-) )

which is a lot less than the total possible number of formats supported.

Even 24-bit packed pixel modes are rare on any half modern graphics card.

Only rely on the OS to do the conversion if speed is not essential to your application. Or at least allow the user to choose (I envisage newer drivers that properly do colourspace conversion in hardware will appear)
int p; // A
 

Offline Mr_Capehill

  • Full Member
  • ***
  • Join Date: May 2002
  • Posts: 189
    • Show only replies by Mr_Capehill
Re: Warp3d synchro/double-triply bufferging
« Reply #29 from previous page: February 17, 2005, 08:09:47 PM »
@Karlos: thanks for interesting answer. Could I get your pixeltool utility? I want to try it :)