Rendering Resource Commands
On this page
Since version 1.33 of Prysm, Renoir uses “Resource commands” for the creation and destruction of GPU resources. These commands must be handled by the rendering backend which now has a new entry point API through which the resource commands are executed. This page describes the expected flow that every rendering backend of Renoir should support.
Resource Commands
The concept of rendering commands is not new in Renoir. The RendererBackend::ExecuteRendering
is implemented for every rendering backend and it is meant to execute the rendering commands that Renoir has generated. The new backend API is the RendererBackend::ExecuteResourceCommands
. The method is meant to execute commands which create or destroy some GPU resources – texture, depth-stencil textures, pipeline state, samplers, constant buffer, index/vertex buffer
Up until 1.33, all GPU resources have been created/destroyed through the other virtual methods of the backends:
RendererBackend::CreatePipelineState
RendererBackend::CreateVertexBuffer
RendererBackend::DestroyVertexBuffer
RendererBackend::CreateIndexBuffer
RendererBackend::DestrozIndexBuffer
RendererBackend::CreateConstantBuffer
RendererBackend::DestroyConstantBuffer
RendererBackend::CreateTexture
RendererBackend::DestroyTexture
RendererBackend::CreateDepthStencilTexture
RendererBackend::DestroyDepthStencilTexture
RendererBackend::CreateSampler2D
RendererBackend::DestroySampler2D
RendererBackend::WrapUserTexture
RendererBackend::WrapUserRenderTarget
The idea of the new API is to replace all of the calls to these methods with a single call to RendererBackend::ExecuteResourceCommands
. The new method accepts an array of structures very similar to RendererBackend::BackendCommandsBuffer
(the input data to RendererBackend::ExecuteRendering
). The input buffers for RendererBackend::ExecuteResourceCommands
are RendererBackend::BackendResourceCommandsBuffer
. These contain commands which describe the creation/destruction of some resources and are essentially a serialized form of the calls to the old backend methods for creating/destroying a resource. The definition of the commands and their types can be seen in the new RenoirBacknerd/BackendResourceCommands.h
header.
The execution of the resource commands is straight forward and every one of the provided default backends implements the method in the same way. Those implementations can be used as a reference when implementing a custom backend for Renoir. The general form is:
void Backend::ExecuteResourceCommands(const BackendResourceCommandsBuffer* buffers, unsigned buffersCount, ResourcesCommandsStage executionStage)
{
for (auto i = 0u; i < buffersCount; ++i)
{
auto buffer = buffers[i];
for (auto cmd = 0u; cmd < buffer.Count; ++cmd)
{
const auto offset = buffer.Offsets[cmd];
switch (offset.Command)
{
case BRC_WrapUserRT: ...;
case BRC_CreateTexture: ...;
...
}
}
}
}
where each switch case is a call to the existing method for the corresponding command. The command execution manner is identical to the one in RendererBackend::ExecuteRendering
.
The benefit of this execution is that there is now a single entry point in the backend code which will create/destroy some GPU resources.
Resource commands stage
The RendererBackend::ExecuteResourceCommands
method also gets an argument of type ResourcesCommandsStage
. This is used only for debugging purposes and it signifies the stage for which the resource commands are executed. Generally, during rendering, we’ll have two calls to RendererBackend::ExecuteResourceCommands
- Once before
RendererBackend::ExecuteRendering
to create some resources - Once after
RendererBackend::ExecuteRendering
to destroy some resources
The ResourcesCommandsStage
can be used to differentiate between these stages. It also shows if the backend is executing some resource commands for creating resources for glyphs rendering (RCS_CreateGlyphResources
) or if it is destroying resources during deinitialization (RCS_DestoryAllRenderingResources
).