For DX11, i don't think so. But DX12/Vulkan are radically diferent and you better think of new methods for the video driver. Calls like "setRendertarget", "set/getTransform" or even "setMaterial" rely on a model that is no longer valid under those API. I mean, it is still perfectly feasible to create DX12/VK drivers for Irrlicht as it is right now, and might provide better performance than the current APIs on some scenarios, but with the current set up you're very likely losing their greatest potential. The problem with DX12/VK is that they don't rely on global states in the video driver anymore, but on pipelines.
Think of a pipeline as a snapshot of the current driver state, including shaders, blending states, texture sampling states and so on. and that anything that uses a pipeline will get rendered using that style. It is like a material, but with extended capabilities, that you can't change during the rendering, save, obviously, the used texture maps, and that can be reutilized once and again without change. So, basicly, you use each pipeline for each type of render you want, this is a bit less flexible than a dynamic state model, but the gain is important, compared, there is no need for state caches anymore, because the state changes are not possible during the render and you still can define and use an array of pipelines. Actually, even if many renderstate changes may happen during the running of a program, these use to be on very few options, so the potential combinatory explosion that using an array of pipelines may cause is greatly reduced because of this and thus, makes sense to use them. And anyway, in Vulkan, at least, it is possible to define derivative pipelines, so you might have a master pipeline and derive others from it. I still have to check how goes that, but on the paper, it is possible.
As the pipelines are static objects, they can be referenced on multiple threads, and there is no need to worry about modifying them accidentally, or perhaps, you can, but you have to understand that changing a pipeline will change any rendering that takes place using it. The multiple threads are meant to build the draw calls and record them, and the actual rendering is deferred until the moment all the draw calls have been recorded, and takes place after, and only after, you tell the API to start. You can establish rendering dependences, at least on Vulkan, to make sure some renders take place before others, and that's it. Anything that sets a global parameter (a model/view/projection transform, a rendering material on the driver or a rendertarget...) that can't be shared among all the API calls you send is a rendering dependance that may prevent other tasks to run in parallel. So any new structure for those new APIs, should keep in mind the problem of the parallelism to make sure you use them the most efficiently way possible.
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt