XNA Creators Club Online
Page 1 of 1 (8 items)
Sort Posts: Previous Next

Relation between IDirect3dDevice9->Present() & Backbuffers

Last post 08-27-2008 4:01 AM by legalize. 7 replies.
  • 08-20-2008 11:49 AM

    Relation between IDirect3dDevice9->Present() & Backbuffers

    Lets say I have a IDirect3dDevice9 configured with D3DSWAPEFFECT_DISCARD and three backbuffers.

    I then create a vector "Backbuffers" with surfacepointers to this backbuffers:

    for (i = 0; i < 3 ; i++ ) { this->DirectX_Device->GetBackBuffer( 0, i, D3DBACKBUFFER_TYPE_MONO, &this->Backbuffers[i] ); }

     

    I set the first backbuffer in this vector to be rendered first.

    this->DirectX_Device->SetRenderTarget( 0, this->Backbuffers[0] );

     

     Now, lets consider a typical display-loop:

     first I write the first picture in the backbuffer to display next:

     this->DirectX_Device->UpdateSurface( this->Offscreensurface, NULL, this->Backbuffers[0], &this->Displayposition );

    and present it by IDirect3dDevice9->Present()


       

    To which slot x in this->Backbuffers[x] do I have to write the second, third and fourth prepared picture?

     What goes on here, exactly which pointer get exchanged by direct3d?

     

     

     Regards

     R4DIUM

     

      

     

     

     

     

     

     

     

     



       


  • 08-20-2008 11:07 PM In reply to

    Re: Relation between IDirect3dDevice9->Present() & Backbuffers

    Normally you would just let D3D take care of the switching of the backbuffers the present call does this for you, and changes the back buffer to the next buffer in the swap chain.

    If I am getting it right what you want to do is implement your own swap chain? To do this you need a circular array, this can be a list what ever the container behind it doesn't really change the way it works. What you do is the following, when you want to assign a number to the index of the buffer you do a modulo operation with the amount of your back buffers. In this way your actual index wont ever go over the array size and you are reusing the buffers that has been used for the n-1 image to draw the new image in.

    If you want to render to a texture just use a texture and grab it's surface and set that as the render target, there is a lot of information to be found online about this, or just use the D3DX function for it.

    Now what I want to know is why are you reimplementing something D3D already does for you, if you need another swap chain then the default one because you need to grab the back buffer create an additional one. Once this one is created you have to tell the D3D device to use this chain instead of the original one. I had to do this because I had to write some text to the back buffer with GDI+ overlaid over the image already there, for the job at the time I wasn't allowed to use the D3DX library to avoid confusion as to why I had to do it that why.


  • 08-21-2008 1:55 PM In reply to

    Re: Relation between IDirect3dDevice9->Present() & Backbuffers

    No, that wasn't exactly my question....

    Let me put it another way:

    Lets say I have a vector of size 3 holding the three backsurfaces gathered with GetBackbuffer()

    vector:

    BSurface0 BSurface1 BSurface2

    To what backbufferslot do I transfer the next picture of a videostream with UpdateSurface() in dependency of the already presented pictures e.g.:

    presented pictures = 0, transfered pictures = 0

    then I would transfer in the first backbuffer BSurface0, cause that one get's displayed by the next present() operation.

     

    let's say that I show my prepared picture in BSurface0 by present()

    To which backbufferslot  do I have to write the second picture of the videostream?

    Surprisingly it is still BSurface0 and not BSurface1

     

    Let's say that I have a prepared picture in BSurface0 (get's displayed next) and did not present it

    Then I write the next videstream picture to BSurface1.

     

    So actually the formula to write the next picture is not

    VectorSlot = Number_of_Presented_Picture % Number_of_Backbuffers

    but

    VectorSlot = Number_of_Transfered_Pictures - Number_of_Presented_Picture

     So I always begin to fill up the BSurfaces in the vector  from left to right!

     

    Several questions arize here:

    1.) How does DirectX manage that the BSurfacesX in my vector refer to different backbuffers in dependency of the present operations internally ?

    E.g. if I always transfer one frame and immediately present it three times.

    BSurface0 refers to Bckbuffer0 Backbuffer1 and Backbuffer2 one after another.

     2.) I don't want the each BSurfaceX in the vector refer to different backbuffers over the time , I am more interested

    in a function like VectorSlot = Number_of_Presented_Picture % Number_of_Backbuffers.

    How can I do this?

     

    Regards

    R4DIUM

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     


  • 08-21-2008 11:14 PM In reply to

    Re: Relation between IDirect3dDevice9->Present() & Backbuffers

    If you take a look at Chapter 4. 2D Applications from my book "The Direct3D Graphics Pipeline", I have a table showing what happens to the back buffers during presentation; it is on pg. 123 of the book, pg. 13 within the PDF.  Does that help?
  • 08-22-2008 8:32 PM In reply to

    Re: Relation between IDirect3dDevice9->Present() & Backbuffers

    No unfortunately that doesn't help me.

    Your code example at the end of the chapter only uses one backbuffer, if I am right.

     

    You describe the D3DSWAPEFFECT_DISCARD correctly as subsequently displaying the fixed backbuffers A B C.

    But the surprise for me is, that if you get a handle to them with GetBackBuffer() and store the returned surface pointers in a

    vector, e.g. the first surface entry in that vector which originally pointed/refered to backbuffer A changes while applying the present() operation and

    also points/refers to the other backbuffers B and C over time.

    My question is how this is handled internally(does DX exchange the pointers of the surfaces which point to the backbuffers?),

    and if there is a way to  make each surfaces entry stored in the vector only refer to only one backbuffer over the time and make them so to speak "fixed"

    as in your example.

     

    regards

     

    R4dium


     


  • 08-23-2008 5:58 PM In reply to

    Re: Relation between IDirect3dDevice9->Present() & Backbuffers

    How Direct3D manipulates the surface pointers internally is an implementation detail that isn't specified.  The most reliable way to deal with this is to call GetBackBuffer when you need a back buffer pointer and not cache these.  Calling GetBackBuffer is not a costly operation, so there isn't really any need to cache these interface pointers.
  • 08-23-2008 10:05 PM In reply to

    Re: Relation between IDirect3dDevice9->Present() & Backbuffers

    Agreed, but would be interesting to know that implementation detail.

     

    Suppose you want to program a multi-threaded application where one thread always

    presents() the next backbuffer and other N threads fill the remaining N backbuffers simultaneously.

    It is quite problematic to implement this, when the fetched pointers change their target/backbuffers all the time, even when

    using GetBackBuffer().

    Actually we don't need to use GetBackBuffer because the returned surface suffers from the same drawback as the vector surfaces.

    Is there really no way to let the pointers always refer to the same surface indepentently of their position in the swapchain?

     

    Regards

    R4dium


  • 08-27-2008 4:01 AM In reply to

    Re: Relation between IDirect3dDevice9->Present() & Backbuffers

    R4DIUM:
    Suppose you want to program a multi-threaded application where one thread alwayspresents() the next backbuffer and other N threads fill the remaining N backbuffers simultaneously.

    In Direct3D9 (or 10) you'll have to do all the rendering from the same thread anyway, so its not realistic to do this.

    Is there really no way to let the pointers always refer to the same surface indepentently of their position in the swapchain?

    Why do you think you need this?  All the games that have been written for Direct3D so far haven't needed this... that ought to be a hint that maybe you should approach things differently.

Page 1 of 1 (8 items) Previous Next
var gDomain='m.webtrends.com'; var gDcsId='dcschd84w10000w4lw9hcqmsz_8n3x'; var gTrackEvents=1; var gFpc='WT_FPC'; /*<\/scr"+"ipt>");} /*]]>*/
DCSIMG