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개 크기입니다.

반환 값

없음

설명

셰이더 상수 버퍼의 경우 pDstBoxNULL로 설정합니다. 이 메서드를 사용하여 셰이더 상수 버퍼를 부분적으로 업데이트할 수 없습니다.

다음과 같은 경우 리소스를 대상으로 사용할 수 없습니다.

  • 리소스는 변경할 수 없거나동적 으로 사용됩니다.
  • 리소스는 깊이 스텐실 리소스로 만들어집니다.
  • 리소스는 다중 샘플링 기능을 사용하여 만들어집니다( DXGI_SAMPLE_DESC 참조).
UpdateSubresource가 반환되면 메서드가 원래 콘텐츠를 이미 복사/스냅했기 때문에 애플리케이션은 pSrcData가 가리키는 데이터를 자유롭게 변경하거나 해제할 수 있습니다.

UpdateSubresource의 성능은 대상 리소스에 대한 경합이 있는지 여부에 따라 달라집니다. 예를 들어 꼭짓점 버퍼 리소스에 대한 경합은 애플리케이션이 그리기 호출을 실행하고 나중에 그리기 호출이 GPU에 의해 실제로 실행되기 전에 동일한 꼭짓점 버퍼에서 UpdateSubresource를 호출할 때 발생합니다.

  • 리소스에 대한 경합이 있는 경우 UpdateSubresource 는 원본 데이터의 복사본을 2개 수행합니다. 먼저 CPU에서 명령 버퍼에서 액세스할 수 있는 임시 스토리지 공간으로 데이터를 복사합니다. 이 복사는 메서드가 반환되기 전에 발생합니다. 그런 다음 GPU에서 두 번째 복사를 수행하여 원본 데이터를 mappable이 아닌 메모리에 복사합니다. 이 두 번째 복사는 명령 버퍼가 플러시될 때 GPU에서 실행되기 때문에 비동기적으로 발생합니다.
  • 리소스 경합이 없는 경우 UpdateSubresource 의 동작은 CPU의 관점에서 데이터를 명령 버퍼에 복사한 다음 명령 버퍼가 플러시될 때 두 번째 복사를 실행하거나 CPU가 데이터를 최종 리소스 위치에 복사하도록 하는 등 더 빠른 동작에 따라 달라집니다. 이는 기본 시스템의 아키텍처에 따라 달라집니다.
참고기능 수준 9_x 하드웨어에만 적용UpdateSubresource 또는 ID3D11DeviceContext::CopySubresourceRegion 을 사용하여 준비 리소스에서 기본 리소스로 복사하는 경우 대상 콘텐츠를 손상시킬 수 있습니다. NULL 원본 상자를 전달하고 원본 리소스의 차원이 대상 리소스와 다른 경우 또는 대상 오프셋(x, y 및 z)을 사용하는 경우에 발생합니다. 이 경우 항상 원본 리소스의 전체 크기인 원본 상자를 전달합니다.
 
원본 행 피치 및 원본 깊이 피치 매개 변수를 더 잘 이해하기 위해 다음 그림에서는 3D 볼륨 텍스처를 보여 줍니다. 3D 볼륨 텍스처 그림

이 시각적 개체의 각 블록은 데이터의 요소를 나타내며 각 요소의 크기는 리소스의 형식에 따라 달라집니다. 예를 들어 리소스 형식이 DXGI_FORMAT_R32G32B32A32_FLOAT 경우 각 요소의 크기는 128비트 또는 16바이트입니다. 이 3D 볼륨 텍스처의 너비는 2, 높이는 3, 깊이는 4입니다.

지정된 리소스에 대한 원본 행 피치 및 원본 깊이 피치를 계산하려면 다음 수식을 사용합니다.

  • 원본 행 피치 = [한 요소의 크기(바이트)] * [한 행의 요소 수]
  • 원본 깊이 피치 = [원본 행 피치] * [행 수(높이)]
각 요소의 크기가 16바이트인 이 예제 3D 볼륨 텍스처의 경우 수식은 다음과 같습니다.
  • 원본 행 피치 = 16 * 2 = 32
  • 원본 깊이 피치 = 16 * 2 * 3 = 96
다음 그림에서는 리소스가 메모리에 배치되는 것을 보여 줍니다. 메모리에 배치된 3D 볼륨 텍스처 그림

예를 들어 다음 코드 조각은 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

추가 정보

ID3D11DeviceContext

ID3D11Resource

기본 홀로그램 샘플