Метод ID3D11DeviceContext::UpdateSubresource (d3d11.h)
См. пример базовой голограммы.
ЦП копирует данные из памяти в подресурс, созданный в памяти без сопоставления.
Синтаксис
void UpdateSubresource(
[in] ID3D11Resource *pDstResource,
[in] UINT DstSubresource,
[in, optional] const D3D11_BOX *pDstBox,
[in] const void *pSrcData,
[in] UINT SrcRowPitch,
[in] UINT SrcDepthPitch
);
Параметры
[in] pDstResource
Тип: ID3D11Resource*
Указатель на целевой ресурс (см. ID3D11Resource).
[in] DstSubresource
Тип: UINT
Отсчитываемый от нуля индекс, определяющий целевой подресурс. Дополнительные сведения см. в разделе D3D11CalcSubresource .
[in, optional] pDstBox
Тип: const D3D11_BOX*
Указатель на поле, определяющее часть целевого подресурса для копирования данных ресурса. Координаты в байтах для буферов и в текселях для текстур. При значении NULL данные записываются в целевой подресурс без смещения. Размеры источника должны соответствовать назначению (см . D3D11_BOX).
Пустое поле приводит к тому, что операция будет недоступна. Поле пусто, если верхнее значение больше или равно нижнему значению, левое значение больше или равно значению справа либо переднее значение больше или равно обратному значению. Если поле пусто, UpdateSubresource не выполняет операцию обновления.
[in] pSrcData
Тип: const void*
Указатель на исходные данные в памяти.
[in] SrcRowPitch
Тип: UINT
Размер одной строки исходных данных.
[in] SrcDepthPitch
Тип: UINT
Размер одного среза глубины исходных данных.
Возвращаемое значение
None
Remarks
Для буфера констант шейдера; Присвойте pDstBox значение NULL. Этот метод нельзя использовать для частичного обновления буфера констант шейдера.
Ресурс нельзя использовать в качестве назначения, если:
- ресурс создается с неизменяемым или динамическим использованием.
- ресурс создается как ресурс трафарета глубины.
- ресурс создается с возможностью множественной выборки (см . DXGI_SAMPLE_DESC).
Производительность UpdateSubresource зависит от того, существует ли состязание за целевой ресурс. Например, состязание за ресурс буфера вершин происходит, когда приложение выполняет вызов Draw , а затем вызывает UpdateSubresource в том же буфере вершин до фактического выполнения вызова Draw GPU.
- При возникновении состязания за ресурс UpdateSubresource выполнит 2 копии исходных данных. Во-первых, данные копируются ЦП во временное дисковое пространство, доступное с помощью буфера команд. Это копирование происходит перед возвратом метода . Затем gpu выполняет вторую копию для копирования исходных данных в память без сопоставления. Вторая копия выполняется асинхронно, так как она выполняется GPU при очистке буфера команд.
- Если нет состязания за ресурсы, поведение UpdateSubresource зависит от того, что быстрее (с точки зрения ЦП): копирование данных в буфер команд и последующее выполнение второй копии при очистке буфера команд или копирование ЦП в конечное расположение ресурса. Это зависит от архитектуры базовой системы.
Каждый блок в этом визуальном элементе представляет элемент данных, а размер каждого элемента зависит от формата ресурса. Например, если формат ресурса DXGI_FORMAT_R32G32B32A32_FLOAT, размер каждого элемента будет составлять 128 бит или 16 байт. Эта текстура объемного объема имеет ширину 2, высоту 3 и глубину 4.
Чтобы вычислить шаг исходной строки и глубину исходной строки для заданного ресурса, используйте следующие формулы:
- Исходный шаг строки = [размер одного элемента в байтах] * [количество элементов в одной строке]
- Исходный шаг глубины = [Шаг исходной строки] * [количество строк (высота)]
- Шаг исходной строки = 16 * 2 = 32
- Исходный шаг глубины = 16 * 2 * 3 = 96
Например, в следующем фрагменте кода показано, как указать конечную область в двухd-текстуре. Предположим, что текстура назначения — 512x512, и операция скопирует данные, на которые указывает pData , в [(120,100).. (200 220)] в конечной текстуре. Также предположим, что rowPitch инициализирован с правильным значением (как описано выше). для переднего и заднего полей заданы значения 0 и 1 соответственно, так как, если передняя часть равна задней, поле технически пусто.
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 );
1D-случай аналогичен. В следующем фрагменте кода показано, как указать конечную область в 1D-текстуре. Используйте те же предположения, что и выше, за исключением того, что текстура имеет длину 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 );
Сведения о различных типах ресурсов и о том, как UpdateSubresource может работать с каждым типом ресурсов, см. в статье Общие сведения о ресурсе в Direct3D 11.
Вызов UpdateSubresource в отложенном контексте
Если приложение вызывает UpdateSubresource в отложенном контексте с полем назначения, на которое указывает pDstBox , которое имеет смещение, отличное от (0,0,0), и если драйвер не поддерживает списки команд, UpdateSubresource неправильно применяет это смещение целевого поля к параметру pSrcData . Чтобы обойти это поведение, используйте следующий код:
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;
}
Требования
Целевая платформа | Windows |
Header | d3d11.h |
Библиотека | D3D11.lib |