Método ID3D11DeviceContext::UpdateSubresource (d3d11.h)
Consulte el ejemplo de holograma básico.
La CPU copia los datos de la memoria en un subrecurso creado en memoria no asignable.
Sintaxis
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*
Puntero al recurso de destino (consulte ID3D11Resource).
[in] DstSubresource
Tipo: UINT
Índice de base cero, que identifica el subrecurso de destino. Consulte D3D11CalcSubresource para obtener más detalles.
[in, optional] pDstBox
Tipo: const D3D11_BOX*
Puntero a un cuadro que define la parte del subrecurso de destino en el que se copiarán los datos del recurso. Las coordenadas están en bytes para los búferes y en elementos de textura para texturas. Si es NULL, los datos se escriben en el subrecurso de destino sin desplazamiento. Las dimensiones del origen deben ajustarse al destino (consulte D3D11_BOX).
Un cuadro vacío da como resultado una operación sin operación. Un cuadro está vacío si el valor superior es mayor o igual que el valor inferior, o el valor izquierdo es mayor o igual que el valor derecho, o el valor frontal es mayor o igual que el valor posterior. Cuando el cuadro está vacío, UpdateSubresource no realiza una operación de actualización.
[in] pSrcData
Tipo: const void*
Puntero a los datos de origen en la memoria.
[in] SrcRowPitch
Tipo: UINT
Tamaño de una fila de los datos de origen.
[in] SrcDepthPitch
Tipo: UINT
Tamaño de un segmento de profundidad de los datos de origen.
Valor devuelto
None
Observaciones
Para un búfer de constantes de sombreador; establezca pDstBox en NULL. No es posible usar este método para actualizar parcialmente un búfer de constantes de sombreador.
Un recurso no se puede usar como destino si:
- el recurso se crea con un uso inmutable o dinámico .
- el recurso se crea como un recurso de galería de símbolos de profundidad.
- el recurso se crea con la funcionalidad de muestreo múltiple (consulte DXGI_SAMPLE_DESC).
El rendimiento de UpdateSubresource depende de si hay o no contención para el recurso de destino. Por ejemplo, la contención de un recurso de búfer de vértices se produce cuando la aplicación ejecuta una llamada a Draw y, posteriormente, llama a UpdateSubresource en el mismo búfer de vértices antes de que la GPU ejecute realmente la llamada a Draw .
- Cuando haya contención para el recurso, UpdateSubresource realizará dos copias de los datos de origen. En primer lugar, la CPU copia los datos en un espacio de almacenamiento temporal accesible por el búfer de comandos. Esta copia se produce antes de que el método devuelva. A continuación, la GPU realiza una segunda copia para copiar los datos de origen en memoria no asignable. Esta segunda copia se produce de forma asincrónica porque se ejecuta mediante GPU cuando se vacía el búfer de comandos.
- Cuando no hay ninguna contención de recursos, el comportamiento de UpdateSubresource depende del cual sea más rápido (desde la perspectiva de la CPU): copiar los datos en el búfer de comandos y, a continuación, hacer que se ejecute una segunda copia cuando se vacía el búfer de comandos o que la CPU copie los datos en la ubicación final del recurso. Esto depende de la arquitectura del sistema subyacente.
Cada bloque de este objeto visual representa un elemento de datos y el tamaño de cada elemento depende del formato del recurso. Por ejemplo, si el formato del recurso es DXGI_FORMAT_R32G32B32A32_FLOAT, el tamaño de cada elemento sería de 128 bits o 16 bytes. Esta textura de volumen 3D tiene un ancho de dos, un alto de tres y una profundidad de cuatro.
Para calcular el tono de fila de origen y el tono de profundidad de origen de un recurso determinado, use las siguientes fórmulas:
- Tono de fila de origen = [tamaño de un elemento en bytes] * [número de elementos de una fila]
- Tono de profundidad de origen = [Tono de fila de origen] * [número de filas (alto)]
- Tono de fila de origen = 16 * 2 = 32
- Inclinación de profundidad de origen = 16 * 2 * 3 = 96
Por ejemplo, el siguiente fragmento de código muestra cómo especificar una región de destino en una textura 2D. Supongamos que la textura de destino es 512x512 y que la operación copiará los datos a los que apunta pData en [(120,100).". (200,220)] en la textura de destino. Suponga también que rowPitch se ha inicializado con el valor adecuado (como se explicó anteriormente). la parte delantera y posterior se establecen en 0 y 1 respectivamente, ya que, al tener delante igual a atrás, la caja está técnicamente vacía.
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 );
El caso 1D es similar. En el fragmento de código siguiente se muestra cómo especificar una región de destino en una textura 1D. Use las mismas suposiciones que anteriormente, salvo que la textura tiene una longitud de 512.
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 obtener información sobre varios tipos de recursos y cómo UpdateSubresource puede funcionar con cada tipo de recurso, consulta Introducción a un recurso en Direct3D 11.
Llamar a UpdateSubresource en un contexto diferido
Si la aplicación llama a UpdateSubresource en un contexto diferido con un cuadro de destino (al que apunta pDstBox ) que tiene un desplazamiento distinto de (0,0,0), y si el controlador no admite listas de comandos, UpdateSubresource aplica de forma inapropiada ese desplazamiento de cuadro de destino al parámetro pSrcData . Para evitar este comportamiento, use el código siguiente:
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 |
Encabezado | d3d11.h |
Library | D3D11.lib |