Lessons Learned from Multithreading

My posts haven't been very frequent lately due to being extremely busy working on a book project. There are two other authors working with me, and I think the project is really starting to shape up. Even with all of the writing, I have still been working on Hieroglyph 3 here and there when I get a chance.

With the addition of text rendering (as described last time) into the engine, it produced somewhat of a collision with my new multithreaded rendering features. The multithreading system more or less takes a render view and processes it on one of deferred contexts, each of which is running on its own thread. Currently I hard code the number of threads, but eventually I will just detect how many cores are available in the host system and automatically adjust. Once all of the deferred contexts have produced command lists, they are all executed in the proper order on the immediate context.

The problem with requiring all render work to exist within render views is that you can't just hack things in to get it displaying. The actual root of the problem is that the immediate context doesn't retain its pipeline state after processing a bunch of command lists... so trying to put text up when there is no render target, blend state, depthstencil state, etc... doesn't work so good.

So to put some text up onto the screen for debugging messages or whatever, I actually need to put all of the state setting and drawing calls into a render view and draw them via the deferred contexts. This is actually the correct thing to do since it fits into the MT design system. However, I want to make it as easy as possible for applications to use text rendering, so I will be making a Text Render View that will be available as part of the application class to add messages to and render. It should work out, I just need to find the time to put it all together and test it out...

The moral of this little surprise is this: when you design a system to make a particular requirement for your applications to follow, don't be surprised when you actually need to follow your requirements to make something work!

By the way, if anyone has had a chance to look at the Hieroglyph 3 engine, I would love to hear any feedback that you might have or suggestions for improvement. The documentation is still on hold due to the book project, but it should start to slowly emerge as time opens up...

One of the things I did was setup my system so that I could by-pass the deferred context rendering if needs be; the structure processed by the rendering thread could hold either a command list or a functor so I could pass a function call to it and have it executed there and then on the immedate context.

Mostly this was for debugging my inital setup, but I could imagine it would be useful for say debug text rendering.

That is more or less like having one of my render view objects for rendering the text The problem stemmed from the fact that I normally would rely on basic states being set already in the immediate context before I had MT setup. With deferred rendering, anything done on the immediate context needs to be setup, so I might as well use the render view system which already does this type of setup for me.

I can switch to ST/MT mode easily, but I was hoping that I could make it so that the application is unaware of what the renderer is doing - to the app it should look the same. And it will continue to be this way - I was just complaining that I need to create a new type of view for things that I didn't need to before