This is the documentation for Enlighten.

7.1.1.1.1. ワーキング メモリの割り当て


概要

この例では、入力ライティングと出力イラディアンスを解く方法を示します。フレームごとの更新ループには以下の 4 つの一時メモリ バッファが追加で必要です。

  • 入力ライティング用に 1 つ
  • イラディアンス用に 1 つ
  • 最終出力の受け取り用に 1 つ (一時的な解決を使用している場合は永続)
  • 中間バウンス出力の受け取り用に 1 つ (一時的な解決を使用している場合は永続)

中間バウンス出力は、イラディアンス ソルバーの 2 次出力として生成され、EndInputLighting パスへの入力として使用されます。

一時的な解決を使用する場合、バウンス出力もライティングの差分値を集計します。従って、各システムで一意の永続バッファを使用する必要があります。ライティングの変化によっては、一時的なソルバーが一部しか更新しない (またはまったくしない) 場合があるため、最終出力テクスチャでも同様です。

メモリ アロケーターの設定

IPrecompute オブジェクトを含め、Enlighten オブジェクトの作成または使用の前に、メモリ アロケーターを設定する必要があります。 これは、過去の Enlighten リリースの動作からの変更点です。

ファイル GeoBase/GeoMemory.h は、仮想クラス MemoryAllocator と関連する関数 SetMemoryAllocator() を含みます。

Enlighten には、デフォルト メモリ アロケーター GeoMemoryDefault が付属しており、標準 C ライブラリのメモリ関数を使用して実装されています。このアロケーターを使用するか、メモリ管理に紐付け、またはメモリ使用率を追跡するためにカスタム アロケーターを実装することができます。

Enlighten のデフォルト メモリ アロケーターの使用例

メモリ アロケーターがプログラム全体で存在するように、このコードをメイン関数で使用します。

Geo::GeoMemoryDefault alloc;
Geo::SetMemoryAllocator(&alloc);
別のメモリ アロケーターの使用

別のアロケーターを使用するには、MemoryAllocator クラスから派生させ、上記のように SetMemoryAllocator() クラスを呼び出します。

Enlighten ランタイムは realloc 関数を使用しないため、ランタイムを使用するためのダミー実装を提供できます。ただし、低レベル プリコンピュート API を使用している場合は、 realloc の適切な実装が必要です。

実際の割り当て/解放を変更した場合は、適切なアライメントを確保してください。そうしないとエラーが発生する可能性があります。

入力ライティングのワーキング バッファ

入力ライティング タスクでは、ワーキング メモリのスクラッチ領域の一部が使用されます。これは、必要なバッファのサイズを解決するタスクに渡されるライトのリストによって決まります。

// ワークスペース メモリの確保
Geo::u32 workspaceSizeRequired = Enlighten::CalcRequiredScratchSpaceMemory(lights, numLights);
void *   scratchMemory         = GEO_ALIGNED_MALLOC(workspaceSizeRequired, 16);

多数のシステムの入力ライティングを解決する際、単純に最大のタスクを処理するのに十分なサイズのバッファを 1 つ割り当て、それを再利用します。

ソルバーのワーキング バッファ

解決関数も、ワーキング メモリのスクラッチ領域を必要とします。そのサイズは既定のシステムの割り当て量と依存関係の数によって決まります。RadSystemCore 構造体を使用して、Enlighten に対してクエリを実行し、正確なサイズのワーキング バッファを取得します。

// ワークスペース メモリの確保
Geo::u32 irradianceMemoryRequired = Enlighten::CalcRequiredIrradianceTaskWorkspaceMemory(&myRadSystemCore);
void*    irradianceWorkspace      = GEO_ALIGNED_MALLOC(irradianceMemoryRequired, 128);

出力テクスチャ バッファ

ラジオシティ出力を取得するバッファを割り当てます。

// ラジオシティ出力テクスチャを作成します。
Geo::s32 outputTextureSize       = radCore->m_MetaData.m_OutputWidth * radCore->m_MetaData.m_OutputHeight;
Geo::s32 outputTextureMemorySize = outputTextureSize * 8; // fp16 output = 8 bytes per pixel
 
void*    irradianceOutput        = GEO_ALIGNED_MALLOC(outputTextureMemorySize, 16);

ディレクショナル イラディアンス出力用のバッファを割り当てることもできます。

// ディレクショナル出力テクスチャを作成します。
Geo::s32 outputTextureSize       = radCore->m_MetaData.m_OutputWidth * radCore->m_MetaData.m_OutputHeight;
Geo::s32 outputTextureMemorySize = outputTextureSize * 4; // 8 bit per channel output = 4 bytes per pixel
 
// 輝度ベースのディレクショナル イラディアンス用の単一の出力テクスチャ
void*    directionalOutput       = GEO_ALIGNED_MALLOC(outputTextureMemorySize, 16);
 
// または、代わりに色分けされたディレクショナル イラディアン用の 3 つの出力テクスチャ
void*    directionalOutputR      = GEO_ALIGNED_MALLOC(outputTextureMemorySize, 16);
void*    directionalOutputG      = GEO_ALIGNED_MALLOC(outputTextureMemorySize, 16);
void*    directionalOutputB      = GEO_ALIGNED_MALLOC(outputTextureMemorySize, 16);

上記のコード例は単純化されており、行あたりの追加パディングがない線形バッファを前提としています (ストライドが幅に設定されています)。実際は、出力テクスチャには 4 の倍数の幅がありますが、データのストライドはグラフィックス ドライバーによっては実際の幅と異なる場合があります。この場合、出力バッファがテクスチャと同じサイズになるよう割り当て、適切なストライドを Enlighten ソルバーに渡す方が便利です。

永続データ バッファ

RadSystemCore を使用して永続データ要件を確認します。

Geo::s32 bounceOutputSize = Enlighten::CalcRequiredPersistentDataSize(&myRadSystemCore);
void*    bounceOutput     = GEO_ALIGNED_MALLOC(bounceOutputSize, 16);