ID3D11DeviceContext::UpdateSubresource 메서드(d3d11.h)
기본 홀로그램 샘플을 참조하세요.
CPU는 메모리의 데이터를 매핑할 수 없는 메모리에서 만든 하위 리소스로 복사합니다.
구문
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
대상 하위 리소스를 식별하는 인덱스(0부터 시작)입니다. 자세한 내용은 D3D11CalcSubresource 를 참조하세요.
[in, optional] pDstBox
형식: const D3D11_BOX*
리소스 데이터를 복사할 대상 하위 리소스의 부분을 정의하는 상자에 대한 포인터입니다. 좌표는 버퍼의 경우 바이트 단위이고 텍스처의 경우 텍셀 단위입니다. NULL인 경우 데이터는 오프셋 없이 대상 하위 리소스에 기록됩니다. 원본의 차원이 대상에 맞아야 합니다( D3D11_BOX 참조).
빈 상자는 no-op을 생성합니다. 위쪽 값이 아래쪽 값보다 크거나 같거나 왼쪽 값이 오른쪽 값보다 크거나 같거나 앞 값이 뒤 값보다 크거나 같으면 상자가 비어 있습니다. 상자가 비어 있으면 UpdateSubresource 는 업데이트 작업을 수행하지 않습니다.
[in] pSrcData
형식: const void*
메모리의 원본 데이터에 대한 포인터입니다.
[in] SrcRowPitch
형식: UINT
원본 데이터의 한 행 크기입니다.
[in] SrcDepthPitch
형식: UINT
원본 데이터의 깊이 조각 1개 크기입니다.
반환 값
없음
설명
셰이더 상수 버퍼의 경우 pDstBox 를 NULL로 설정합니다. 이 메서드를 사용하여 셰이더 상수 버퍼를 부분적으로 업데이트할 수 없습니다.
다음과 같은 경우 리소스를 대상으로 사용할 수 없습니다.
- 리소스는 변경할 수 없거나동적 으로 사용됩니다.
- 리소스는 깊이 스텐실 리소스로 만들어집니다.
- 리소스는 다중 샘플링 기능을 사용하여 만들어집니다( DXGI_SAMPLE_DESC 참조).
UpdateSubresource의 성능은 대상 리소스에 대한 경합이 있는지 여부에 따라 달라집니다. 예를 들어 꼭짓점 버퍼 리소스에 대한 경합은 애플리케이션이 그리기 호출을 실행하고 나중에 그리기 호출이 GPU에 의해 실제로 실행되기 전에 동일한 꼭짓점 버퍼에서 UpdateSubresource를 호출할 때 발생합니다.
- 리소스에 대한 경합이 있는 경우 UpdateSubresource 는 원본 데이터의 복사본을 2개 수행합니다. 먼저 CPU에서 명령 버퍼에서 액세스할 수 있는 임시 스토리지 공간으로 데이터를 복사합니다. 이 복사는 메서드가 반환되기 전에 발생합니다. 그런 다음 GPU에서 두 번째 복사를 수행하여 원본 데이터를 mappable이 아닌 메모리에 복사합니다. 이 두 번째 복사는 명령 버퍼가 플러시될 때 GPU에서 실행되기 때문에 비동기적으로 발생합니다.
- 리소스 경합이 없는 경우 UpdateSubresource 의 동작은 CPU의 관점에서 데이터를 명령 버퍼에 복사한 다음 명령 버퍼가 플러시될 때 두 번째 복사를 실행하거나 CPU가 데이터를 최종 리소스 위치에 복사하도록 하는 등 더 빠른 동작에 따라 달라집니다. 이는 기본 시스템의 아키텍처에 따라 달라집니다.
이 시각적 개체의 각 블록은 데이터의 요소를 나타내며 각 요소의 크기는 리소스의 형식에 따라 달라집니다. 예를 들어 리소스 형식이 DXGI_FORMAT_R32G32B32A32_FLOAT 경우 각 요소의 크기는 128비트 또는 16바이트입니다. 이 3D 볼륨 텍스처의 너비는 2, 높이는 3, 깊이는 4입니다.
지정된 리소스에 대한 원본 행 피치 및 원본 깊이 피치를 계산하려면 다음 수식을 사용합니다.
- 원본 행 피치 = [한 요소의 크기(바이트)] * [한 행의 요소 수]
- 원본 깊이 피치 = [원본 행 피치] * [행 수(높이)]
- 원본 행 피치 = 16 * 2 = 32
- 원본 깊이 피치 = 16 * 2 * 3 = 96
예를 들어 다음 코드 조각은 2D 텍스처에서 대상 영역을 지정하는 방법을 보여줍니다. 대상 텍스처가 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 호출
애플리케이션이 pDstBox가 가리키는 대상 상자가 있는 지연된 컨텍스트에서 UpdateSubresource를 호출하는 경우(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 |
헤더 | d3d11.h |
라이브러리 | D3D11.lib |