Clonando um efeito
Clonar um efeito cria uma segunda cópia quase idêntica do efeito. Consulte o qualificador único a seguir para obter uma explicação de por que ele não é exato. Uma segunda cópia de um efeito é útil quando se deseja usar a estrutura de efeitos em vários threads, pois o runtime de efeito não é thread-safe para manter o alto desempenho.
Como os contextos do dispositivo também são não thread-safe, threads diferentes devem passar contextos de dispositivo diferentes para o método ID3DX11EffectPass::Apply.
Um efeito pode ser clonado com a seguinte sintaxe:
ID3DX11Effect* pClonedEffect = NULL;
UINT Flags = D3DX11_EFFECT_CLONE_FORCE_NONSINGLE;
HRESULT hr = pEffect->CloneEffect( Flags, &pClonedEffect );
No exemplo acima, a cópia clonada encapsulará o mesmo estado que o efeito original, independentemente do estado em que o efeito original está. Especialmente:
- Se pEffect for otimizado, o efeito pCloned será otimizado
- Se pEffect tiver algumas variáveis gerenciadas pelo usuário, o Efeito pCloned terá as mesmas variáveis gerenciadas pelo usuário (consulte a única descrição abaixo)
- Todas as atualizações de variáveis pendentes (até que uma chamada Apply atualize o estado do dispositivo) no pEffect estarão pendentes em pClonedEffect
Os seguintes objetos de dispositivo Direct3D 11 são imutáveis ou nunca atualizados pela estrutura de efeitos, portanto, o efeito clonado apontará para os mesmos objetos que o efeito original:
- Objetos de bloco de estado (ID3D11BlendState, ID3D11RasterizerState, ID3D11DepthStencilState, ID3D11SamplerState)
- Sombreadores
- Instâncias de classe
- Texturas (sem incluir buffers de textura)
- Exibições de acesso não ordenadas
Os seguintes objetos de dispositivo Direct3D 11 são imutáveis e modificados pelo runtime de efeito (a menos que gerenciado pelo usuário ou único em um efeito clonado); novas cópias desses objetos são criadas quando não são simples:
- Buffers constantes
- Buffers de textura
Buffers constantes únicos e buffers de textura
Observe que essa discussão se aplica a buffers constantes e texturas, mas buffers constantes são considerados para facilitar a leitura.
Pode haver casos em que um buffer constante é atualizado apenas por um thread, mas o estado do dispositivo definido por efeitos clonados usará esses dados. Por exemplo, o efeito main pode atualizar o mundo e exibir matrizes que são referenciadas de sombreadores em efeitos clonados que não alteram o mundo e exibem matrizes. Nesses casos, os efeitos clonados precisam referenciar o buffer constante atual em vez de recriar um.
Há duas maneiras de alcançar esse resultado desejado:
- Usar ID3DX11EffectConstantBuffer::SetConstantBuffer no efeito clonado para torná-lo gerenciado pelo usuário
- Marque o buffer constante como "único" no código HLSL, forçando o runtime de efeito a tratar como gerenciado pelo usuário após a clonagem
Há duas diferenças entre os dois métodos acima. Primeiro, no método 1, um novo ID3D11Buffer será criado e o usuário antes de SetConstantBuffer ser chamado. Além disso, depois de chamar UndoSetConstantBuffer no efeito clonado, a variável no método 1 apontará para o buffer recém-criado (quais efeitos serão atualizados em Apply), enquanto a variável no método 2 continuará apontando para o buffer original (não atualizando-o em Apply).
Consulte o seguinte exemplo em HLSL:
cbuffer ObjectData
{
float4 Position;
};
single cbuffer ViewData
{
float4x4 ViewMatrix;
};
Durante a clonagem, o efeito clonado criará um novo ID3D11Buffer para ObjectData e preencherá seu conteúdo em Aplicar, mas fará referência ao ID3D11Buffer original para ViewData. O qualificador único pode ser ignorado no processo de clonagem definindo o sinalizador D3DX11_EFFECT_CLONE_FORCE_NONSINGLE.
Tópicos relacionados