Método ID3D11DeviceContext::UpdateSubresource (d3d11.h)
Consulte o exemplo de holograma básico.
A CPU copia dados da memória para um sub-recurso criado na memória não aplicaível.
Sintaxe
void UpdateSubresource(
[in] ID3D11Resource *pDstResource,
[in] UINT DstSubresource,
[in, optional] const D3D11_BOX *pDstBox,
[in] const void *pSrcData,
[in] UINT SrcRowPitch,
[in] UINT SrcDepthPitch
);
Parâmetros
[in] pDstResource
Tipo: ID3D11Resource*
Um ponteiro para o recurso de destino (consulte ID3D11Resource).
[in] DstSubresource
Tipo: UINT
Um índice baseado em zero, que identifica o sub-recurso de destino. Consulte D3D11CalcSubresource para obter mais detalhes.
[in, optional] pDstBox
Tipo: const D3D11_BOX*
Um ponteiro para uma caixa que define a parte do sub-recurso de destino para a qual copiar os dados do recurso. As coordenadas estão em bytes para buffers e em texels para texturas. Se NULL, os dados serão gravados na sub-fonte de destino sem deslocamento. As dimensões da origem devem se ajustar ao destino (consulte D3D11_BOX).
Uma caixa vazia resulta em uma no-op. Uma caixa estará vazia se o valor superior for maior ou igual ao valor inferior ou o valor esquerdo for maior ou igual ao valor à direita ou o valor frontal for maior ou igual ao valor de fundo. Quando a caixa está vazia, UpdateSubresource não executa uma operação de atualização.
[in] pSrcData
Tipo: const void*
Um ponteiro para os dados de origem na memória.
[in] SrcRowPitch
Tipo: UINT
O tamanho de uma linha dos dados de origem.
[in] SrcDepthPitch
Tipo: UINT
O tamanho de uma fatia de profundidade dos dados de origem.
Valor retornado
Nenhum
Comentários
Para um buffer de constante de sombreador; defina pDstBox como NULL. Não é possível usar esse método para atualizar parcialmente um buffer de constante de sombreador.
Um recurso não poderá ser usado como destino se:
- o recurso é criado com uso imutável ou dinâmico .
- o recurso é criado como um recurso de estêncil de profundidade.
- o recurso é criado com funcionalidade multisampling (consulte DXGI_SAMPLE_DESC).
O desempenho do UpdateSubresource depende se há ou não contenção para o recurso de destino. Por exemplo, a contenção de um recurso de buffer de vértice ocorre quando o aplicativo executa uma chamada de Desenho e, posteriormente, chama UpdateSubresource no mesmo buffer de vértice antes que a chamada de Desenho seja realmente executada pela GPU.
- Quando houver contenção para o recurso, UpdateSubresource executará duas cópias dos dados de origem. Primeiro, os dados são copiados pela CPU para um espaço de armazenamento temporário acessível pelo buffer de comando. Essa cópia ocorre antes que o método retorne. Em seguida, uma segunda cópia é executada pela GPU para copiar os dados de origem em memória não aplicaível. Essa segunda cópia ocorre de forma assíncrona porque é executada pela GPU quando o buffer de comando é liberado.
- Quando não há contenção de recursos, o comportamento de UpdateSubresource depende do que é mais rápido (da perspectiva da CPU): copiar os dados para o buffer de comando e, em seguida, ter uma segunda cópia executada quando o buffer de comando é liberado ou fazer com que a CPU copie os dados para o local final do recurso. Isso depende da arquitetura do sistema subjacente.
Cada bloco nesse visual representa um elemento de dados e o tamanho de cada elemento depende do formato do recurso. Por exemplo, se o formato de recurso for DXGI_FORMAT_R32G32B32A32_FLOAT, o tamanho de cada elemento será de 128 bits ou 16 bytes. Essa textura de volume 3D tem uma largura de dois, uma altura de três e uma profundidade de quatro.
Para calcular o tom de linha de origem e o tom de profundidade de origem para um determinado recurso, use as seguintes fórmulas:
- Pitch de Linha de Origem = [tamanho de um elemento em bytes] * [número de elementos em uma linha]
- Arremesso de Profundidade de Origem = [Campo de Linha de Origem] * [número de linhas (altura)]
- Campo de linha de origem = 16 * 2 = 32
- Arremesso de Profundidade de Origem = 16 * 2 * 3 = 96
Por exemplo, o snippet de código a seguir mostra como especificar uma região de destino em uma textura 2D. Suponha que a textura de destino seja 512x512 e a operação copiará os dados apontados por pData para [(120,100).. (200.220)] na textura de destino. Suponha também que rowPitch tenha sido inicializado com o valor adequado (conforme explicado acima). front e back são definidos como 0 e 1, respectivamente, porque por ter frente igual a back, a caixa está tecnicamente vazia.
D3D11_BOX destRegion;
destRegion.left = 120;
destRegion.right = 200;
destRegion.top = 100;
destRegion.bottom = 220;
destRegion.front = 0;
destRegion.back = 1;
pd3dDeviceContext->UpdateSubresource( pDestTexture, 0, &destRegion, pData, rowPitch, 0 );
O caso 1D é semelhante. O snippet a seguir mostra como especificar uma região de destino em uma textura 1D. Use as mesmas suposições que acima, exceto que a textura tem 512 de comprimento.
D3D11_BOX destRegion;
destRegion.left = 120;
destRegion.right = 200;
destRegion.top = 0;
destRegion.bottom = 1;
destRegion.front = 0;
destRegion.back = 1;
pd3dDeviceContext->UpdateSubresource( pDestTexture, 0, &destRegion, pData, rowPitch, 0 );
Para obter informações sobre vários tipos de recursos e como UpdateSubresource pode funcionar com cada tipo de recurso, consulte Introdução a um recurso no Direct3D 11.
Chamando UpdateSubresource em um contexto adiado
Se o aplicativo chamar UpdateSubresource em um contexto adiado com uma caixa de destino, para a qual pDstBox aponta, que tem um deslocamento não (0,0,0) e, se o driver não der suporte a listas de comandos, UpdateSubresource aplicará inadequadamente esse deslocamento de caixa de destino ao parâmetro pSrcData . Para contornar esse comportamento, use o seguinte código:
HRESULT UpdateSubresource_Workaround(
ID3D11Device *pDevice,
ID3D11DeviceContext *pDeviceContext,
ID3D11Resource *pDstResource,
UINT dstSubresource,
const D3D11_BOX *pDstBox,
const void *pSrcData,
UINT srcBytesPerElement,
UINT srcRowPitch,
UINT srcDepthPitch,
bool* pDidWorkAround )
{
HRESULT hr = S_OK;
bool needWorkaround = false;
D3D11_DEVICE_CONTEXT_TYPE contextType = pDeviceContext->GetType();
if( pDstBox && (D3D11_DEVICE_CONTEXT_DEFERRED == contextType) )
{
D3D11_FEATURE_DATA_THREADING threadingCaps = { FALSE, FALSE };
hr = pDevice->CheckFeatureSupport( D3D11_FEATURE_THREADING, &threadingCaps, sizeof(threadingCaps) );
if( SUCCEEDED(hr) )
{
if( !threadingCaps.DriverCommandLists )
{
needWorkaround = true;
}
}
}
const void* pAdjustedSrcData = pSrcData;
if( needWorkaround )
{
D3D11_BOX alignedBox = *pDstBox;
// convert from pixels to blocks
if( m_bBC )
{
alignedBox.left /= 4;
alignedBox.right /= 4;
alignedBox.top /= 4;
alignedBox.bottom /= 4;
}
pAdjustedSrcData = ((const BYTE*)pSrcData) - (alignedBox.front * srcDepthPitch) - (alignedBox.top * srcRowPitch) - (alignedBox.left * srcBytesPerElement);
}
pDeviceContext->UpdateSubresource( pDstResource, dstSubresource, pDstBox, pAdjustedSrcData, srcRowPitch, srcDepthPitch );
if( pDidWorkAround )
{
*pDidWorkAround = needWorkaround;
}
return hr;
}
Requisitos
Plataforma de Destino | Windows |
Cabeçalho | d3d11.h |
Biblioteca | D3D11.lib |