I'm currently writing a rendering library for my own use using Direct3D 11. It's not intended as a rendering engine in itself, just something to help me rapidly produce demos and projects. Essentially it's composed of a scene graph (implemented as a simple node hierarchy and octree), a rendering interface to perform state sorting and such as well as issue actual device calls, and some code for easily setting up and using other little bits (textures, shaders, tools, etc).
Ideally I'd like this library to be 'thread-agnostic', so a host application could make use of it on it's own render thread, or even across seveal with D3D 11's device contexts. With this in mind, the obvious sounding solution for making draw calls would be to submit some sort of render operation message to the render interface so it can dump it in a queue for sorting and processing later.
A message is going to carry all of the state data required for a draw to happen. This means it'll need to point to constant buffers, various states (including rasterizer, depth/stencil, blend, etc), shaders, buffers, and more. My main concern here is how big these messages are going to end up despite the members being pointers, especially in a large scene. The vertex buffers are causing issues here too, with a message having to have an array of buffer pointers to support multiple streams, though this could probably be solved using some sort of binding object which groups a set of them together and just point to that instead.
The only alternative I've thought of so far is simply storing a list of key-value pairs, with a key for sorting, and a value which is a pointer to an object which implements a RenderOp interface. This interface would have a series of virtual state getter methods (e.g. getIndexBuffer), and probably some sort of type id which indicated the nature of the states it would need to dodge calls when a method would always return null. This has the added benefit of also saving a little memory. This seems a more friendly solution, but i'm unsure how much impact the virtual calls would have.
Has anyone had to deal with something similar to this, or got any suggestions on how to go about it?