Introduzione alla fase input-assembler

Per inizializzare la fase di input-assembler (IA) sono necessari alcuni passaggi. Ad esempio, è necessario creare risorse del buffer con i dati dei vertici necessari per la pipeline, indicare alla fase IA dove si trovano i buffer e il tipo di dati che contengono e specificare il tipo di primitive da assemblare dai dati.

I passaggi di base relativi alla configurazione della fase IA, illustrata nella tabella seguente, sono trattati in questo argomento.

Procedi Descrizione
Creare buffer di input Creare e inizializzare buffer di input con i dati dei vertici di input.
Creare l'oggetto Input-Layout Definire il modo in cui i dati del buffer dei vertici verranno trasmessi nella fase IA usando un oggetto layout di input.
Associare oggetti alla fase input-assembler Associare gli oggetti creati (buffer di input e l'oggetto input-layout) alla fase IA.
Specificare il tipo primitivo Identificare il modo in cui i vertici verranno assemblati in primitive.
Call Draw Methods Inviare i dati associati alla fase IA tramite la pipeline.

 

Dopo aver compreso questi passaggi, passare a Uso dei valori generati dal sistema.

Creare buffer di input

Esistono due tipi di buffer di input: vertex buffer e buffer di indice. I vertex buffer forniscono i dati dei vertici alla fase IA. I buffer di indice sono facoltativi; forniscono indici ai vertici dal vertex buffer. È possibile creare uno o più vertex buffer e, facoltativamente, un buffer di indice.

Dopo aver creato le risorse del buffer, è necessario creare un oggetto layout di input per descrivere il layout dei dati nella fase IA e quindi è necessario associare le risorse del buffer alla fase IA. La creazione e l'associazione di buffer non è necessaria se gli shader non usano buffer. Per un esempio di un semplice vertex shader e pixel shader che disegna un singolo triangolo, vedere Uso della fase input-assembler senza buffer.

Per informazioni sulla creazione di un vertex buffer, vedere Procedura: Creare un vertex buffer. Per informazioni sulla creazione di un buffer di indice, vedere Procedura: Creare un buffer di indice.

Creare l'oggetto Input-Layout

L'oggetto input-layout incapsula lo stato di input della fase IA. Include una descrizione dei dati di input associati alla fase IA. I dati vengono trasmessi nella fase IA dalla memoria, da uno o più vertex buffer. La descrizione identifica i dati di input associati da uno o più vertex buffer e consente al runtime di controllare i tipi di dati di input rispetto ai tipi di parametro di input dello shader. Questo controllo dei tipi non solo verifica che i tipi siano compatibili, ma anche che ognuno degli elementi richiesti dallo shader sia disponibile nelle risorse del buffer.

Un oggetto layout di input viene creato da una matrice di descrizioni degli elementi di input e un puntatore allo shader compilato (vedere ID3D11Device::CreateInputLayout). La matrice contiene uno o più elementi di input; ogni elemento di input descrive un singolo elemento vertex-data da un singolo buffer di vertici. L'intero set di descrizioni degli elementi di input descrive tutti gli elementi dei dati dei vertici di tutti i vertex buffer che verranno associati alla fase IA.

La descrizione del layout seguente descrive un singolo buffer dei vertici che contiene tre elementi di dati dei vertici:

D3D11_INPUT_ELEMENT_DESC layout[] =
{
    { L"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, 
          D3D11_INPUT_PER_VERTEX_DATA, 0 },
    { L"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, 
          D3D11_INPUT_PER_VERTEX_DATA, 0 },
    { L"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 20, 
          D3D11_INPUT_PER_VERTEX_DATA, 0 },
};

Una descrizione dell'elemento di input descrive ogni elemento contenuto da un singolo vertice in un buffer dei vertici, tra cui dimensioni, tipo, posizione e scopo. Ogni riga identifica il tipo di dati usando la semantica, l'indice semantico e il formato dei dati. Una semantica è una stringa di testo che identifica come verranno usati i dati. In questo esempio, la prima riga identifica i dati di posizione a 3 componenti (ad esempio xyz), la seconda riga identifica i dati di trama a 2 componenti (ad esempio UV) e la terza riga identifica i dati normali.

In questo esempio di descrizione di un elemento di input, l'indice semantico (che è il secondo parametro) è impostato su zero per tutte e tre le righe. L'indice semantico consente di distinguere tra due righe che usano la stessa semantica. Poiché in questo esempio non sono presenti semantiche simili, l'indice semantico può essere impostato sul valore predefinito, zero.

Il terzo parametro è il formato. Il formato (vedere DXGI_FORMAT) specifica il numero di componenti per elemento e il tipo di dati, che definisce le dimensioni dei dati per ogni elemento. Il formato può essere tipizzato completamente al momento della creazione della risorsa oppure è possibile creare una risorsa usando un DXGI_FORMAT, che identifica il numero di componenti in un elemento, ma lascia il tipo di dati non definito.

Slot di input

I dati vengono inseriti nella fase IA tramite input denominati slot di input, come illustrato nella figura seguente. La fase IA ha n slot di input, progettati per supportare fino a n vertex buffer che forniscono dati di input. Ogni vertex buffer deve essere assegnato a uno slot diverso; queste informazioni vengono archiviate nella dichiarazione di input-layout quando viene creato l'oggetto input-layout. È anche possibile specificare un offset dall'inizio di ogni buffer al primo elemento del buffer da leggere.

illustration of the input slots for the ia stage

I due parametri successivi sono lo slot di input e l'offset di input. Quando si usano più buffer, è possibile associarli a uno o più slot di input. L'offset di input è il numero di byte tra l'inizio del buffer e l'inizio dei dati.

Riutilizzo di oggetti layout di input

Ogni oggetto layout di input viene creato in base a una firma dello shader; Ciò consente all'API di convalidare gli elementi input-layout-object rispetto alla firma di input dello shader per assicurarsi che esista una corrispondenza esatta di tipi e semantiche. È possibile creare un singolo oggetto layout di input per molti shader, purché tutte le firme di input dello shader corrispondano esattamente.

Associare oggetti alla fase input-assembler

Dopo aver creato le risorse del buffer dei vertici e un oggetto layout di input, è possibile associarle alla fase IA chiamando ID3D11DeviceContext::IASetVertexBuffers e ID3D11DeviceContext::IASetInputLayout. L'esempio seguente mostra l'associazione di un singolo buffer dei vertici e un oggetto layout di input alla fase IA:

UINT stride = sizeof( SimpleVertex );
UINT offset = 0;
g_pd3dDevice->IASetVertexBuffers( 
    0,                // the first input slot for binding
    1,                // the number of buffers in the array
    &g_pVertexBuffer, // the array of vertex buffers
    &stride,          // array of stride values, one for each buffer
    &offset );        // array of offset values, one for each buffer

// Set the input layout
g_pd3dDevice->IASetInputLayout( g_pVertexLayout );

L'associazione dell'oggetto layout di input richiede solo un puntatore all'oggetto .

Nell'esempio precedente viene associato un singolo buffer dei vertici; Tuttavia, più vertex buffer possono essere associati da una singola chiamata a ID3D11DeviceContext::IASetVertexBuffers e il codice seguente mostra una chiamata di questo tipo per associare tre buffer di vertici:

UINT strides[3];
strides[0] = sizeof(SimpleVertex1);
strides[1] = sizeof(SimpleVertex2);
strides[2] = sizeof(SimpleVertex3);
UINT offsets[3] = { 0, 0, 0 };
g_pd3dDevice->IASetVertexBuffers( 
    0,                 //first input slot for binding
    3,                 //number of buffers in the array
    &g_pVertexBuffers, //array of three vertex buffers
    &strides,          //array of stride values, one for each buffer
    &offsets );        //array of offset values, one for each buffer

Un buffer di indice è associato alla fase IA chiamando ID3D11DeviceContext::IASetIndexBuffer.

Specificare il tipo primitivo

Dopo aver associato i buffer di input, la fase IA deve essere in grado di assemblare i vertici in primitive. Questa operazione viene eseguita specificando il tipo primitivo chiamando ID3D11DeviceContext::IASetPrimitiveTopology. Il codice seguente chiama questa funzione per definire i dati come elenco di triangoli senza adiacenza:

g_pd3dDevice->IASetPrimitiveTopology( D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

Il resto dei tipi primitivi è elencato in D3D_PRIMITIVE_TOPOLOGY.

Call Draw Methods

Dopo che le risorse di input sono state associate alla pipeline, un'applicazione chiama un metodo di disegno per eseguire il rendering delle primitive. Esistono diversi metodi di disegno, illustrati nella tabella seguente; alcuni usano buffer di indice, alcuni usano i dati dell'istanza e alcuni riutilizzano i dati dalla fase di streaming-output come input alla fase dell'assembler di input.

Metodi draw Descrizione
ID3D11DeviceContext::D raw Disegnare primitive non indicizzate e non a istanza.
ID3D11DeviceContext::D rawInstanced Disegnare primitive non indicizzate e con istanza.
ID3D11DeviceContext::D rawIndexed Disegnare primitive indicizzate e non a istanza.
ID3D11DeviceContext::D rawIndexedInstanced Disegnare primitive indicizzate e con istanze.
ID3D11DeviceContext::D rawAuto Disegnare primitive non indicizzate e non a istanza dai dati di input provenienti dalla fase di streaming-output.

 

Ogni metodo di disegno esegue il rendering di un singolo tipo di topologia. Durante il rendering, le primitive incomplete (quelle senza vertici sufficienti, senza indici, primitive parziali e così via) vengono eliminate automaticamente.

Fase input-assembler