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

Multiple buffering

Last post 08/06/2009 3:21 by trogo. 10 replies.
  • 14/08/2008 22:15

    Multiple buffering

    Hello.

    My app uses a thread to render and the main thread to update. After see some Gamefest presentations, I am trying to implement multiple buffering. The fact is that when creating the swap-chain with more that 1 buffer (I assume that if introducing 1 as the BufferCount, it is the front-buffer) the performance is quite improved.

    So, is that the way to implement multiple-buffering, DXGI just manages it?

  • 15/08/2008 5:30 In reply to

    Re: Multiple buffering

    There are multiple forms of multi-buffering. The multi-buffering the swap chain does has more to do with preventing rendering to a front buffer (which is typically slow and can produce tearing). Multi-buffering also is used to enable parallelism between multiple processing units. Traditionally, muti-buffering was used to ensure the GPU would be able to work on frame N, while the CPU worked on frame N+1. Now with multicore CPUs, the same technique is being discussed in light of enabling parallelism between CPU cores. DXGI manages the swap chain aspects, while the application must manage the parallelism aspects.
  • 19/08/2008 16:08 In reply to

    Re: Multiple buffering

    Ok, thank you.

     I am interested in enabling parallelism between some threads (the typical Update/Render paradigm). Could you tell me some advice about it?

    The fact is that I have researched 'bout this, but every page I found talks about double buffer in DirectX 9. You know, the application updates one frame, while the runtime manages the front buffer, not talking about managing multiple buffers.

  • 21/08/2008 23:40 In reply to

    Re: Multiple buffering

    I'm unsure what your 'typical' Update/Render paradigm entails, but the concept is rather simple. The Update thread usually hands off data to the Render thread. If you only have one piece of data, then the data is usually protected with synchronization (which would only let one thread manipulate it at a time); and the Update thread would not be able to concurrently generate the data while the Render thread worked on it. The general concept of multibuffering is to have two pieces of data and ping-pong between the two, such that Update can concurrently generate data, while Render works on the previous data. In the past, it has been intuitive to multi-buffer D3D resources, such as textures and queries. But, recently, it has become more popular for people to attempt to multi-buffer the graphics command stream, itself.
  • 23/10/2008 23:07 In reply to

    Re: Multiple buffering

    Brian Klamik:
    The general concept of multibuffering is to have two pieces of data and ping-pong between the two, such that Update can concurrently generate data, while Render works on the previous data.n

    This was what I refered to. any hint about how to achieve it?

  • 24/11/2008 2:19 In reply to

    Re: Multiple buffering

    Hi trogo

    I wanna implement double buffering..

    COuld u tell me hoe i can create a thread for rendering..

    thank you
  • 02/12/2008 0:58 In reply to

    Re: Multiple buffering

    duodevil:
    Hi trogo

    I wanna implement double buffering..

    COuld u tell me hoe i can create a thread for rendering..

    thank you

    Sure.

    I have post the code about how the thread is created in pastebin.com. The same about how the threaded function here.
  • 02/12/2008 1:52 In reply to

    Re: Multiple buffering

    It sounds like you need to double-buffer at the application layer, which has nothing to do with Direct3D.
    Your Update function will want to mutate the state of the game (a bunch of combinations of position/orientation/velocity/model/effect information in a scene graph, typically).
    Your Render function will want to present a scene based on that same scene graph information.
    To avoid a read/write hazard, you have to create a copy of your scene graph data, and hand off to the render thread, for each frame, while the Update function goes on mutating the scene graph in place. Alternatively, you can create two scene graphs, and copy from old to new each frame, but it boils down to the same thing.

    So, your update will look something like:

      update_loop() {
        if (!rendering_running) {
          copy_data_to_renderer(game_state);
          rendering_kickoff();
        }
        update_one_physics_step();
      }

      render_loop() {
        wait_for_kickoff();
        render_state(game_state_copy);
        rendering_running = false;
      }

      rendering_kickoff() {
        rendering_running = true;
        set_event(render_event);
      }

    Yes, you'll have to figure out what the proper primitive is for each part of those loops (rendering_running needs to be volatile, you'll need to handle termination requests, etc), but this sketch should show you how it can be made to work at the application level.

    Jon Watte, Direct3D MVP
    Tweets, occasionally
    kW X-port 3ds Max .X exporter
    kW Animation source code
  • 02/12/2008 22:40 In reply to

    Re: Multiple buffering

    OMG! Thank you a lot jwatte.

    Nowadays I am restructuring my codebase (switching it to OOP), so it will last some time until I implement this algorithm.
  • 17/03/2009 9:27 In reply to

    Re: Multiple buffering

    im trying to implement multithreading as well in my application and after reading this post i wonder if im doing it the right way.

    im not using multi buffers on the D3D part but working with some self made buffer thingy.

    currently im still testing whats the best way.

    First of all my render thread using a "renderQue",  wich is a list of commands to execute by the render thread.
    For example, when i call RenderManager::SetVertexBuffer() it will create a add a new command to the list, rather then directly execute the code.

    The command code is pretty simple using derived classes
    class IRenderCommand
    {
    public:
       virtual void ExecuteCommand();
    };

    sample of the SetIndexBuffer code
    class CmdSetIB : public IRenderCommand
    {
    public:
        void ExecuteCommand()
        {
            pD3DDevice->IASetIndexBuffer( pBuffer );
        }

    public:
        ID3D10Device    pDevice;
        ID3D10Buffer    pBuffer;
    };


    The render thread just loops trough the command list and execute each command.

    Currently the update/render thread running at the same speed.

    so the update thread does:
    - Wait for 'FrameTick' event
    - Update renderable object (fill the command que)
    - Fire 'BeginRender' event
    - Update non renderable objects
    - Wait for 'RenderComplete' event

    this make my update/render thread run at the same speed.
    So i fill my render command list, fire up the render thread (wich should be idle at this point) and process/empty the command list)

    Now i wonder, how much will buffering increase my game code?
    i could make something like this:
    - Wait for 'FrameTick' event
    - Update renderable objects (fill the command que)
    - Fire 'SwapRenderBuffer' event (this make the render thread to copy the command que)
    - Update non renderable object

    this would make the render thread keep looping without delays and keep processing the same command que till the 'SwatRenderBuffer' even is called to make copy of the new command list.


    so the first method i currently testing with is pretty simple, its just allow the update thread to do some stuff while im rendering instead of waiting for the render code to complete before continue. While the second method would probably have a higher render FPS as update FPS (is this a good thing or asking for problems?)

    Next to my update/render thread i also wanna add a paralel thread for the networking system and add some kind of thread pool with background workers for loading data on the background.


    so my main questions: Sync threads or use buffering and will render/update at different FPS improve performance or is that a bad idea?
  • 08/06/2009 3:21 In reply to

    Re: Multiple buffering

    Nightmare:
    so the update thread does:
    - Wait for 'FrameTick' event
    - Update renderable object (fill the command que)
    - Fire 'BeginRender' event
    - Update non renderable objects
    - Wait for 'RenderComplete' event

    So, with this algorithm, you are using just 1 buffer, isn't?

    Nightmare:
    Now i wonder, how much will buffering increase my game code?
    i could make something like this:
    - Wait for 'FrameTick' event
    - Update renderable objects (fill the command que)
    - Fire 'SwapRenderBuffer' event (this make the render thread to copy the command que)
    - Update non renderable object

    this would make the render thread keep looping without delays and keep processing the same command que till the 'SwatRenderBuffer' even is called to make copy of the new command list.

    And, with this one you would use 2 buffer at least.

    Nightmare:
    so the first method i currently testing with is pretty simple, its just allow the update thread to do some stuff while im rendering instead of waiting for the render code to complete before continue. While the second method would probably have a higher render FPS as update FPS (is this a good thing or asking for problems?)

    That's it. With multithreading you will be able to do other things while some other thread is rendering. Using 2 buffers is nosense to me if you are not using multithreading. So, as you are using multithreading, multi-buffering should work fine with you.

    Multibuffering allows you to make a scene more complex. While rendered-buffer is being drawing, updated-buffer should be updated. And, the scene could become as complex as more and more buffers are added to your engine. Recommended are 2 buffers for the update thread and one for the rendering thread. This way, your render thread can consume an already just processed buffer, while you are working with the other one. All of this while maintaining your fps or even improving it.

    Nightmare:
    Next to my update/render thread i also wanna add a paralel thread for the networking system and add some kind of thread pool with background workers for loading data on the background.

    Just test it. But take note that you should not create more hard-working threads than cores are on the system. So, if running a Athlon 64 X2 (for example), you should not create more than 2 threads. Side-note: I am using a Athlon 64 with just 1 core and my engine works fine. Obviously the game using it doesn't use very complex scenes.

    Nightmare:
    so my main questions: Sync threads or use buffering and will render/update at different FPS improve performance or is that a bad idea?

    Nope. Allways sync threads. Because if not done this way, you are going to loose control over your FPS rates. The main question here is: sync by using just 1 buffer (no sync needed at all) or sync by using multiple buffers? I tested both of them, and performance improved a lot by using multiple buffers.

    Finally, there are people knowing much more than I, so wait for a answer from them while testing your solution.
Page 1 of 1 (11 items) Previous Next