다음을 통해 공유


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

리소스에서 지정된 하위 리소스에 대한 CPU 포인터를 가져오지만 애플리케이션에 포인터 값을 공개하지 않을 수 있습니다. 또한 Map 은 필요한 경우 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 반환 코드 중 하나를 반환합니다.

비고

매핑 해제 는 여러 스레드에서 안전하게 호출할 수 있습니다. 중첩된 호출이 지원되며 다시 계산됩니다. 대한 첫 번째 호출은 리소스에 대한 CPU 가상 주소 범위를 할당합니다. 매핑 해제 마지막 호출은 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 액세스 가능 힙의 리소스를 영구적으로 매핑할 수 있습니다. 즉, 리소스를 만든 직후에 을 한 번 호출할 수 있습니다. 매핑 해제 는 호출할 필요가 없지만 에서 반환된 주소는 리소스에 대한 마지막 참조가 해제된 후에 더 이상 사용되지 않아야 합니다. 영구 맵을 사용할 때 애플리케이션은 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 참조의 예제 코드를 참조하세요.

요구 사항

요구 사항 가치
대상 플랫폼 윈도우즈
Header d3d12.h
Library D3D12.lib
DLL D3D12.dll

참고하십시오

ID3D12Resource

하위 리소스

매핑 해제