Advertisement

Benefits of multithreaded renderer

Started by February 25, 2020 02:15 AM
39 comments, last by NikiTo 4 years, 6 months ago

@ccherng
That's correct: if you want to change shaders, then you need to issue multiple draw calls. In D3D12/Vulkan this would essentially boil down to setting a new PSO, and then following it up with another draw. You're mentioned buffering up an “array” of draw calls and shader settings: that's exactly what a command buffer is! You generate it, and then you pass it off to the GPU in a single call. Sure you have to call APIs to fill up that buffer, but these are user-mode calls we're talking about (there's no kernel-mode transitions necessary for modern graphics APIs).

@mjp I think he asked about the need of 8K drawing calls for 8K zombies.

For example, having to render 1000 asteroids. The vertices could be pushed in a single array and all of the asteroids can be rendered with a single draw call(if not rendering them with different settings depending of the distance from the camera. But even this way, not much levels/draw calls are needed). This is what i think he asked about - why not put all the data inside arrays and issue a single drawing call. No need to issue 1000 drawing calls, one drawing call for every one of the 1000 asteroids.

I don't have enough experience, so i can not come up with some example of having to issue thousands of drawing calls. The most complicated example i can think of is a 3D chatroom.

Advertisement

I experimented with multi-threaded renders on my 2d game engine with great success but the implementation was different when not used as a single thread.

  1. Single thread — layers are rendered on to the back buffer surface in sequential order and then back buffer is presented to the window.

With multi-threading however, I encountered an interesting issue, because all the layers are being rendered in parallel, you cannot possibly write to the back buffer with all layers at the same time or you'll end up with some garbled up junk of a mess.

So I had to render each layer on a different surface and then once the threads finish their processing I combine all the layers together on the back buffer and then present it to the window.

The performance increase is significant.

@rafaelsantana It is a normal issue with any parallelism - you can not concurrently write to the final destination. You need to reorder things. this is inherent for any parallelism, not only MT. MT is not to blame.

And it is hard to tell how much of this “significant increase in performance” is due to MT or the fact that you rendered things separately, which by default could give you an important speedup.

NikiTo said:

@rafaelsantana It is a normal issue with any parallelism - you can not concurrently write to the final destination. You need to reorder things. this is inherent for any parallelism, not only MT. MT is not to blame.

And it is hard to tell how much of this “significant increase in performance” is due to MT or the fact that you rendered things separately, which by default could give you an important speedup.

5 layers … let's see..

In single thread render 1, 2, 3, 4, 5, then present …

In MT Render 1,2,3,4,5 in parallel and then combine … interestingly enough, you still have to combine 5 layers in ST so it often the operation ends up being redundant. I did notice a performance increase in very saturated scenes … since I am working with raw GDI I did not think it was worth the effort to fully implement it YET.

I found an old video of when I tested it and uploaded for this post, I got good results but not enough to warrant fully implement it, maybe some other time.

@rafaelsantana Why do you need multiple layers/multithreading for the scene in the video?

Advertisement

NikiTo said:

@rafaelsantana Why do you need multiple layers/multithreading for the scene in the video?

It was a test.

@rafaelsantana Ok.

This is what i fail to see - a practical example where MT is needed, other than extremely optimized AAA games and tests.

(For your scene, i would render it all at once with a single shader and a single drawing call. With a quad per square and a z-buffer. It would read the VRAM much less and will be much faster than MT.)

NikiTo said:

@rafaelsantana Ok.

This is what i fail to see - a practical example where MT is needed, other than extremely optimized AAA games and tests.

(For your scene, i would render it all at once with a single shader and a single drawing call. With a quad per square and a z-buffer. It would read the VRAM much less and will be much faster than MT.)

Reason why I ditched the idea of MT; the implementation was very involved and I had factor in more variables. I went for simplicity which, looked more elegant and less confusing IMO.

Also when I speak of layers, I'm referring to the individual tile maps that I used for the drawing. they are drawn all at once to the buffer and then presented to the window one after the other of course, background is drawn, the use another tile map to render some more stuff, the cool thing about tile maps is that you can use a special formula to find the location at which you need to begin Blitting as opposed to cycling through an array of thousands of sprites to see if they were in the viewport or not … also this is the Windows GDI if I ever decide to take this project and port it over to DirectX using the technique you mentioned is a great idea.

@rafaelsantana What you do, already looks very nice.
Don't overdo it without a solid reason. This way you will finish your projects sooner.

It should feel great to finish a project… i haven't finished a project since many many years.

This topic is closed to new replies.

Advertisement