Rendering Resource Commands

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).