다음을 통해 공유


ID3D12Resource::Map 메서드(d3d12.h)

리소스에서 지정된 하위 리소스에 대한 CPU 포인터를 가져오지만 애플리케이션에 포인터 값을 공개하지 않을 수 있습니다. 또한 맵 은 필요한 경우 CPU 캐시를 무효화하여 CPU가 이 주소로 읽어들일 때 GPU에서 수정한 내용을 반영합니다.

구문

HRESULT Map(
                  UINT              Subresource,
  [in, optional]  const D3D12_RANGE *pReadRange,
  [out, optional] void              **ppData
);

매개 변수

Subresource

형식: UINT

하위 리소스의 인덱스 번호를 지정합니다.

[in, optional] pReadRange

형식: const D3D12_RANGE*

액세스할 메모리 범위를 설명하는 D3D12_RANGE 구조체에 대한 포인터입니다.

이는 CPU가 읽을 수 있는 지역과 좌표가 하위 리소스 상대 지역임을 나타냅니다. null 포인터는 CPU에서 전체 하위 리소스를 읽을 수 있음을 나타냅니다. End가 Begin보다 작거나 같은 범위를 전달하여 CPU가 데이터를 읽지 않도록 지정하는 것이 유효합니다.

[out, optional] ppData

형식: void**

리소스 데이터에 대한 포인터를 수신하는 메모리 블록에 대한 포인터입니다.

null 포인터는 유효하며 WriteToSubresource와 같은 메서드에 대한 CPU 가상 주소 범위를 캐시하는 데 유용합니다. ppData가 NULL이 아닌 경우 반환된 포인터는 pReadRange의 값에 의해 오프셋되지 않습니다.

반환 값

형식: HRESULT

이 메서드는 Direct3D 12 반환 코드 중 하나를 반환합니다.

설명

MapUnmap은 여러 스레드에서 안전하게 호출할 수 있습니다. 중첩된 호출은 지원되며 다시 계산됩니다. 첫 번째 Map 호출은 리소스에 대해 CPU 가상 주소 범위를 할당합니다. 마지막 Unmap 호출은 CPU 가상 주소 범위 할당을 취소합니다. CPU 가상 주소는 일반적으로 애플리케이션에 반환됩니다. 그러나 알 수 없는 레이아웃으로 텍스처의 내용을 조작하면 CPU 가상 주소가 공개되지 않습니다. 자세한 내용은 WriteToSubresource 를 참조하세요. 이 영구적으로 중첩되지 않는 한 애플리케이션은 일관성 있는 주소를 사용할 수 없습니다.

Map에서 반환된 포인터는 일반 포인터의 모든 기능을 보장하지는 않지만 대부분의 애플리케이션은 일반적인 사용량의 차이를 알 수 없습니다. 예를 들어 WRITE_COMBINE 동작이 있는 포인터는 WRITE_BACK 동작보다 CPU 메모리 순서가 약합니다. CPU와 GPU 모두에서 액세스할 수 있는 메모리는 PCIe 제한으로 인해 CPU에 있는 동일한 원자성 메모리 보장을 공유하도록 보장되지 않습니다. 동기화에 펜스를 사용합니다.

에는 단순 및 고급의 두 가지 사용 모델 범주가 있습니다. 간단한 사용 모델은 도구 성능을 최대화하므로 애플리케이션은 고급 모델이 앱에 필요한 것으로 입증될 때까지 간단한 모델을 고수하는 것이 좋습니다.

단순 사용 모델

애플리케이션은 모든 어댑터 아키텍처를 합리적으로 지원하기 위해 UPLOAD, DEFAULT 및 READBACK의 힙 형식 추상화에 충실해야 합니다.

애플리케이션은 실수로도 업로드 힙의 리소스에 대한 포인터에서 CPU 읽기를 피해야 합니다. CPU 읽기는 작동하지만 많은 일반적인 GPU 아키텍처에서 엄청나게 느리므로 다음을 고려하세요.

  • D3D12_HEAP_TYPE_UPLOAD 있거나 D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE 있는 힙과 연결된 리소스에서 CPU를 읽지 마세요.
  • pData 지점이 PAGE_WRITECOMBINE 할당될 수 있는 메모리 영역이며 앱은 이러한 메모리와 연결된 모든 제한을 준수해야 합니다.
  • 다음 C++ 코드도 메모리에서 읽고 다음 x86 어셈블리 코드로 확장할 수 있으므로 성능 저하를 트리거할 수 있습니다.

    C++ 코드:

    *((int*)MappedResource.pData) = 0;
    

    x86 어셈블리 코드:

    AND DWORD PTR [EAX],0
    
  • 적절한 최적화 설정 및 언어 구문을 사용하여 이 성능 저하를 방지합니다. 예를 들어 휘발성 포인터를 사용하거나 코드 크기 대신 코드 속도를 최적화하여 xor 최적화를 방지할 수 있습니다.
애플리케이션은 CPU가 리소스를 수정하지 않는 동안 리소스를 매핑되지 않은 상태로 두고 항상 단단하고 정확한 범위를 사용하는 것이 좋습니다. 이렇게 하면 그래픽 디버깅 및 디버그 계층과 같은 도구에 가장 빠른 모드를 사용할 수 있습니다. 이러한 도구는 GPU에서 읽을 수 있는 메모리에 대한 모든 CPU 수정 사항을 추적해야 합니다.

고급 사용 모델

CPU 액세스 가능한 힙의 리소스를 영구적으로 매핑할 수 있습니다. 즉, 리소스를 만든 직후에 을 한 번 호출할 수 있습니다. 매핑 해제 는 호출할 필요가 없지만 리소스에 대한 마지막 참조가 해제된 후에는 Map 에서 반환된 주소를 더 이상 사용하지 않아야 합니다. 영구 맵을 사용하는 경우 애플리케이션은 GPU가 메모리를 읽거나 쓰는 명령 목록을 실행하기 전에 CPU가 메모리에 데이터 쓰기를 완료하는지 확인해야 합니다. 일반적인 시나리오에서 애플리케이션은 ExecuteCommandLists를 호출하기 전에 메모리에 씁니다. 그러나 펜스를 사용하여 명령 목록 실행을 지연하는 것도 작동합니다.

리소스가 삭제된 후 애플리케이션이 포인터에 액세스하지 않는 경우 모든 CPU 액세스 가능 메모리 유형은 리소스가 매핑되지만 매핑되지 않은 영구 매핑 사용을 지원합니다.

예제

D3D12Bundles 샘플은 다음과 같이 ID3D12Resource::Map을 사용합니다.

삼각형 데이터를 꼭짓점 버퍼에 복사합니다.

// Copy the triangle data to the vertex buffer.
UINT8* pVertexDataBegin;
CD3DX12_RANGE readRange(0, 0);        // We do not intend to read from this resource on the CPU.
ThrowIfFailed(m_vertexBuffer->Map(0, &readRange, reinterpret_cast<void**>(&pVertexDataBegin)));
memcpy(pVertexDataBegin, triangleVertices, sizeof(triangleVertices));
m_vertexBuffer->Unmap(0, nullptr);

상수 버퍼에 대한 업로드 힙을 만듭니다.

// Create an upload heap for the constant buffers.
ThrowIfFailed(pDevice->CreateCommittedResource(
    &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
    D3D12_HEAP_FLAG_NONE,
    &CD3DX12_RESOURCE_DESC::Buffer(sizeof(ConstantBuffer) * m_cityRowCount * m_cityColumnCount),
    D3D12_RESOURCE_STATE_GENERIC_READ,
    nullptr,
    IID_PPV_ARGS(&m_cbvUploadHeap)));

// Map the constant buffers. Note that unlike D3D11, the resource 
// does not need to be unmapped for use by the GPU. In this sample, 
// the resource stays 'permanently' mapped to avoid overhead with 
// mapping/unmapping each frame.
CD3DX12_RANGE readRange(0, 0);        // We do not intend to read from this resource on the CPU.
ThrowIfFailed(m_cbvUploadHeap->Map(0, &readRange, reinterpret_cast<void**>(&m_pConstantBuffers)));

D3D12 참조의 예제 코드를 참조하세요.

요구 사항

요구 사항
대상 플랫폼 Windows
헤더 d3d12.h
라이브러리 D3D12.lib
DLL D3D12.dll

추가 정보

ID3D12Resource

하위 리소스

Unmap