D3D12_PIPELINE_STATE_STREAM_DESC
構造体サイズ=各フィールドのバイト数(x64/x86 で異なる場合は x64/x86 と併記)。x64/x86 列=フィールドのバイトオフセット(HSPで dupptr / lpoke / wpoke 等に使用)。
フィールド
| フィールド | 型 | サイズ | x64 | x86 | 説明 |
|---|---|---|---|---|---|
| SizeInBytes | UINT_PTR | 8/4 | +0 | +0 | SAL: pPipelineStateSubobjectStream メンバーが指す不透明なデータ構造のサイズを、バイト単位で指定します。 |
| pPipelineStateSubobjectStream | void* | 8/4 | +8 | +4 | SAL: 任意のパイプライン ステート サブオブジェクトをバイト ストリームとして記述するデータ構造のアドレスを指定します。 |
公式ドキュメント
パイプライン ステート ストリームを記述します。
解説(Remarks)
パイプライン ステート オブジェクトを作成するには、この構造体を ID3D12Device2::CreatePipelineState メソッドと共に使用します。
指定するストリームの形式は、D3D12_PIPELINE_STATE_SUBOBJECT_TYPE と、それに対応するサブオブジェクト型とが交互に並ぶ構成である必要があります (たとえば、D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER は D3D12_RASTERIZER_DESC と対になります)。アラインメントに関して、D3D12 ランタイムは、サブオブジェクトが連続したフィールドの集まりではなく、列挙型と構造体からなる個々の組であることを前提としています。また、システムの自然なワード アラインメントに合わせられていることも前提としています。これは alignas(void*) を使用するか、列挙型 + サブオブジェクトと void* の union を作成することで実現できます。
D3D12_PIPELINE_STATE_SUBOBJECT_TYPE を単に void* と union にするだけでは不十分です。一部のサブオブジェクトのアラインメントがずれてしまうためです。
たとえば、D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PRIMITIVE_TOPOLOGY の後ろには D3D12_PRIMITIVE_TOPOLOGY_TYPE 列挙型が続きます。サブオブジェクト型を void* と union にすると、これら 2 つのメンバーの間に余分なパディングが入り、ストリームが壊れてしまいます。
このため、alignas を利用できない場合は、サブオブジェクトの構造体全体を void* と union にしてください
D3D12_RASTERIZER_DESC で使用するのに適したサブオブジェクトの例を次に示します。
struct alignas(void*) StreamingRasterizerDesc
{
private:
D3D12_PIPELINE_STATE_SUBOBJECT_TYPE Type = D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER;
public:
D3D12_RASTERIZER_DESC Desc;
}
ランタイムは、VS (頂点シェーダー)、CS (コンピュート シェーダー)、MS (メッシュ シェーダー) のうちどのサブオブジェクト型が見つかるかによって、パイプライン ストリームの種類 (有効な種類は COMPUTE、GRAPHICS、MESH) を判断します。これらのシェーダーがいずれも見つからない場合、ランタイムはパイプラインの作成に失敗します。また、これらのシェーダーのうち NULL でないものが複数見つかった場合も失敗します。つまり、ID3D12Device2::CreatePipelineState の各呼び出しにおいて、シェーダー バイトコードへのポインターが NULL でないものが 1 つだけであれば、たとえばストリーム オブジェクトに CS と VS の両方を含めても問題ありません。 そのパイプラインに関係のないサブオブジェクト型 (グラフィックス ストリーム内のコンピュート シェーダー サブオブジェクトなど) は無視されます。 サブオブジェクトが指定されていない場合 (上記の必須サブオブジェクトを除く)、ランタイムが既定値を提供します。
C++ 用の d3dx12.h 拡張の使用を検討してください。これはすべてのパイプライン サブオブジェクトに対する一連のヘルパー構造体を提供します (たとえば、上記の構造体は CD3DX12_PIPELINE_STATE_STREAM_RASTERIZER によく似ています)。このヘッダーは github の DirectX-Headers リポジトリにあります。
-runtime-validation
ランタイムは、PSO の記述がコンピュート、メッシュ、グラフィックスのいずれかのパイプラインであること、すべてのサブオブジェクトが認識可能な型であること、そしてサブオブジェクトが重複していないことを検証します。
サブオブジェクトの重複を検出する目的において、一部のサブオブジェクトは他のサブオブジェクトの「派生」バージョンと見なされます。たとえば、ランタイムが D3D12_DEPTH_STENCIL_DESC サブオブジェクトを検出し、その後に D3D12_DEPTH_STENCIL_DESC1 を検出した場合、これらは重複したサブオブジェクトと見なされ、失敗します。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での定義
#include <windows.h>
// D3D12_PIPELINE_STATE_STREAM_DESC (x64 16 / x86 8 バイト)
typedef struct D3D12_PIPELINE_STATE_STREAM_DESC {
UINT_PTR SizeInBytes;
void* pPipelineStateSubobjectStream;
} D3D12_PIPELINE_STATE_STREAM_DESC;using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct D3D12_PIPELINE_STATE_STREAM_DESC
{
public UIntPtr SizeInBytes;
public IntPtr pPipelineStateSubobjectStream;
}Imports System.Runtime.InteropServices
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure D3D12_PIPELINE_STATE_STREAM_DESC
Public SizeInBytes As UIntPtr
Public pPipelineStateSubobjectStream As IntPtr
End Structureimport ctypes
from ctypes import wintypes
class D3D12_PIPELINE_STATE_STREAM_DESC(ctypes.Structure):
_fields_ = [
("SizeInBytes", ctypes.c_size_t),
("pPipelineStateSubobjectStream", ctypes.c_void_p),
]#[repr(C)]
pub struct D3D12_PIPELINE_STATE_STREAM_DESC {
pub SizeInBytes: usize,
pub pPipelineStateSubobjectStream: *mut core::ffi::c_void,
}import "golang.org/x/sys/windows"
type D3D12_PIPELINE_STATE_STREAM_DESC struct {
SizeInBytes uintptr
pPipelineStateSubobjectStream uintptr
}type
D3D12_PIPELINE_STATE_STREAM_DESC = record
SizeInBytes: NativeUInt;
pPipelineStateSubobjectStream: Pointer;
end;const D3D12_PIPELINE_STATE_STREAM_DESC = extern struct {
SizeInBytes: usize,
pPipelineStateSubobjectStream: ?*anyopaque,
};type
D3D12_PIPELINE_STATE_STREAM_DESC {.bycopy.} = object
SizeInBytes: uint
pPipelineStateSubobjectStream: pointerstruct D3D12_PIPELINE_STATE_STREAM_DESC
{
size_t SizeInBytes;
void* pPipelineStateSubobjectStream;
}HSP用 定義
HSP3.7/3.8 は構造体機能が無いため4byte整数配列(dim)+peek/poke で操作(32/64bitでサイズ・位置が異なる場合はタブで分割)。IronHSP は NSTRUCT(#defstruct/stdim/->)で32/64bit共通。
; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x86 レイアウト)
; D3D12_PIPELINE_STATE_STREAM_DESC サイズ: 8 バイト(x86)
dim st, 2 ; 4byte整数×2(構造体サイズ 8 / 4 切り上げ)
; SizeInBytes : UINT_PTR (+0, 4byte) st.0 = 値 / 値 = st.0 (lpoke/lpeek も可)
; pPipelineStateSubobjectStream : void* (+4, 4byte) st.1 = 値 / 値 = st.1 (lpoke/lpeek も可)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x64 レイアウト)
; D3D12_PIPELINE_STATE_STREAM_DESC サイズ: 16 バイト(x64)
dim st, 4 ; 4byte整数×4(構造体サイズ 16 / 4 切り上げ)
; SizeInBytes : UINT_PTR (+0, 8byte) qpoke st,0,値 / qpeek(st,0) ※IronHSPのみ。3.7/3.8は lpoke st,0,下位 : lpoke st,4,上位
; pPipelineStateSubobjectStream : void* (+8, 8byte) qpoke st,8,値 / qpeek(st,8) ※IronHSPのみ。3.7/3.8は lpoke st,8,下位 : lpoke st,12,上位
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。; IronHSP は NSTRUCT(構造体)をサポート。32bit/64bit どちらでも同じコードで動作します。
#defstruct global D3D12_PIPELINE_STATE_STREAM_DESC
#field intptr SizeInBytes
#field intptr pPipelineStateSubobjectStream
#endstruct
stdim st, D3D12_PIPELINE_STATE_STREAM_DESC ; NSTRUCT 変数を確保
st->SizeInBytes = 100
mes "SizeInBytes=" + st->SizeInBytes