Skip to content

DescriptorPile

Chuck Walbourn edited this page Jan 27, 2022 · 17 revisions
DirectXTK DescriptorHeap

The DescriptorHeap manages heaps of metadata descriptors, but is generally used with static indices (typically in the form of an enumeration). This is useful for many scenarios, but is difficult to use when descriptors usage is data-driven (such as when loading models). To help with this, the DescriptorPile class extends the basic DescriptorHeap with dynamic index allocation.

Header

#include "DescriptorHeap.h"

Initialization

Creation of a descriptor pile is identical to DescriptorHeap, but typically with a large maximum capability. For example, this is a pile that can have up to 128 descriptors.

srvPile = std::make_unique<DescriptorPile>(device,
    D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
    D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE,
    128);

Since this is the most common usage case (CBV/SRV/UAV heap with shader visibility), there's a simplified constructor version:

srvPile = std::make_unique<DescriptorPile>(device, 128);

It's often useful to mix static descriptor indices with dynamically allocated descriptors, so you can provide an optional parameter to reserve part of the range for use with static descriptors:

enum StaticDescriptors
{
    Font,
    CtrlFont,
    SceneTex,
    RadianceTex,
    IrradianceTex,
    // Add other static descriptors here
    Reserve,
    Count = 128
};

srvPile = std::make_unique<DescriptorPile>(device,
    StaticDescriptors::Count,
    StaticDescriptors::Reserve);

If more descriptors are reserved or allocated than the capacity, then an exception is thrown.

Usage

In addition to the methods and properties on a DescriptorHeap, a descriptor pile supports the following methods:

  • Allocate: Allocates a single descriptor from the pile.

  • AllocateRange: Allocates 1 or more descriptors from the pile.

Example

Here is an example of using the descriptor pile with model loading:

// Load models.
car = Model::CreateFrom*(device, ...);
ship = Model::CreateFrom*(device, ...);

// Create sampler heap.
states = std::make_unique<CommonStates>(device);

// Create factories (referencing our descriptor pile).
modelResources = std::make_unique<EffectTextureFactory>(device,
    resourceUpload, srvPile->Heap());

fxFactory = std::make_unique<EffectFactory>(srvPile->Heap(), states->Heap());

// Load materials for first model.
int txtOffset = 0;
{
    size_t start, end;
    resourceDescriptors->AllocateRange(car->textureNames.size(), start, end);
    txtOffset = static_cast<int>(start);
}
car->LoadTextures(*modelResources, txtOffset);

// Create effects instances for first model (use the same offset as above).
carFX = car->CreateEffects(*fxFactory, pdOpaque, pdAlpha, txtOffset);

// Load materials for second model.
{
    size_t start, end;
    m_resourceDescriptors->AllocateRange(ship->textureNames.size(), start, end);
    txtOffset = static_cast<int>(start);
}
ship->LoadTextures(*modelResources, txtOffset);

// Create effects instances for second model (use the same offset as above).
shipFX = car->CreateEffects(*fxFactory, pdOpaque, pdAlpha, txtOffset);

For Use

  • Universal Windows Platform apps
  • Windows desktop apps
  • Windows 11
  • Windows 10
  • Xbox One
  • Xbox Series X|S

Architecture

  • x86
  • x64
  • ARM64

For Development

  • Visual Studio 2022
  • Visual Studio 2019 (16.11)
  • clang/LLVM v12 - v18
  • MinGW 12.2, 13.2
  • CMake 3.20

Related Projects

DirectX Tool Kit for DirectX 11

DirectXMesh

DirectXTex

DirectXMath

Tools

Test Suite

Model Viewer

Content Exporter

DxCapsViewer

See also

DirectX Landing Page

Clone this wiki locally