> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Map

> 리소스에서 지정된 하위 리소스에 대한 CPU 포인터를 가져옵니다. 단, 포인터 값을 응용 프로그램에 공개하지 않을 수 있습니다. Map은 또한 CPU 캐시를 무효화합니다.

리소스에서 지정된 하위 리소스에 대한 CPU 포인터를 가져옵니다. 단, 포인터 값을 응용 프로그램에 공개하지 않을 수 있습니다. **Map**은 필요할 때 CPU 캐시도 무효화하므로, 이 주소에 대한 CPU 읽기가 GPU에 의한 모든 수정 사항을 반영합니다.

## 구문

```cpp theme={null}
HRESULT Map(
    UINT Subresource,
    const D3D12_RANGE  pReadRange,
    void  ppData
)
```

### 매개 변수

*Subresource*<br />형식: UINT

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

*pReadRange \[in, optional]*<br />형식: const D3D12\_RANGE \*

액세스할 메모리의 범위를 설명하는 [D3D12\_RANGE](/reference/graphics/d3d12/structs/d3d12_range_public) 구조체에 대한 포인터입니다.

이는 CPU가 읽을 수 있는 영역을 나타내며, 좌표는 하위 리소스에 상대적입니다. 널 포인터는 하위 리소스 전체를 CPU가 읽을 수 있음을 나타냅니다. **End**가 **Begin**보다 작거나 같은 범위를 전달하여 CPU가 데이터를 읽지 않는다고 지정하는 것은 유효합니다.

*ppData \[out, optional]*<br />형식: void \*\*

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

널 포인터도 유효하며, [WriteToSubresource](/reference/graphics/d3d12/interfaces/id3d12resource/methods/id3d12resource_writetosubresource_public)와 같은 메서드에서 CPU 가상 주소 범위를 캐시하는 데 유용합니다. <i>ppData</i>가 NULL이 아니면 반환되는 포인터는 <i>pReadRange</i>의 값에 의해 오프셋되지 않습니다.

### 반환 값

형식: HRESULT

이 메서드는 [Direct3D 12 반환 코드](https://learn.microsoft.com/en-us/windows/desktop/direct3d12/d3d12-graphics-reference-returnvalues) 중 하나를 반환합니다.

## 설명

**Map**과 [Unmap](/reference/graphics/d3d12/interfaces/id3d12resource/methods/id3d12resource_unmap_public)은 여러 스레드에서 안전하게 호출할 수 있습니다. 중첩된 **Map** 호출이 지원되며 참조 카운트됩니다. **Map**의 첫 번째 호출은 리소스에 대한 CPU 가상 주소 범위를 할당합니다. **Unmap**의 마지막 호출은 CPU 가상 주소 범위를 할당 해제합니다. CPU 가상 주소는 일반적으로 응용 프로그램에 반환되지만, 알 수 없는 레이아웃을 가진 텍스처의 콘텐츠를 조작하는 경우 CPU 가상 주소 공개가 금지됩니다. 자세한 내용은 [WriteToSubresource](/reference/graphics/d3d12/interfaces/id3d12resource/methods/id3d12resource_writetosubresource_public)를 참조하세요. **Map**이 지속적으로 중첩되지 않는 한, 응용 프로그램은 주소가 일관되게 유지된다고 가정할 수 없습니다.

**Map**이 반환하는 포인터에는 일반 포인터의 모든 기능이 보장되지는 않지만, 대부분의 응용 프로그램은 일반적인 사용에서 차이를 느끼지 못할 것입니다. 예를 들어, WRITE\_COMBINE 동작이 있는 포인터는 WRITE\_BACK 동작보다 CPU 메모리 순서 보장이 약합니다. CPU와 GPU가 모두 액세스할 수 있는 메모리는 PCIe 제한으로 인해 CPU가 갖는 것과 동일한 원자적 메모리 보장을 공유한다고 보장되지 않습니다. 동기화에는 펜스를 사용하세요.

**Map**에는 두 가지 사용 모델 범주가 있습니다. 간단한 모델과 고급 모델입니다. 간단한 사용 모델은 도구 성능을 최대화하므로, 응용 프로그램은 고급 모델이 필요하다고 입증되기 전까지는 간단한 모델을 고수하는 것이 좋습니다.

<h3><a id="Simple_Usage_Models" /><a id="simple_usage_models" /><a id="SIMPLE_USAGE_MODELS" />간단한 사용 모델</h3> 모든 어댑터 아키텍처를 합리적으로 잘 지원하기 위해, 응용 프로그램은 UPLOAD, DEFAULT, READBACK의 힙 유형 추상화를 고수해야 합니다.

응용 프로그램은 UPLOAD 힙의 리소스 포인터에서 CPU가 읽는 것을 피해야 합니다. 실수로라도 마찬가지입니다. CPU 읽기는 작동하지만 많은 일반적인 GPU 아키텍처에서 매우 느리므로, 다음을 고려하세요:

<ul>
  <li>
    D3D12\_HEAP\_TYPE\_UPLOAD이거나 D3D12\_CPU\_PAGE\_PROPERTY\_WRITE\_COMBINE인 힙과 연결된 리소스에서 CPU가 읽지 않도록 하세요.
  </li>

  <li>
    **pData**가 가리키는 메모리 영역은 [PAGE\_WRITECOMBINE](https://learn.microsoft.com/en-us/windows/desktop/Memory/memory-protection-constants)으로 할당될 수 있으며, 앱은 해당 메모리와 관련된 모든 제한을 준수해야 합니다.
  </li>

  <li>
    다음과 같은 C++ 코드조차도 메모리에서 읽고 성능 저하를 유발할 수 있습니다. 왜냐하면 이 코드가 다음 x86 어셈블리 코드로 확장될 수 있기 때문입니다.

    C++ 코드:

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

    x86 어셈블리 코드:

    ```
    AND DWORD PTR [EAX],0
    ```
  </li>

  <li>
    이러한 성능 저하를 방지하려면 적절한 최적화 설정과 언어 구문을 사용하세요. 예를 들어, **volatile** 포인터를 사용하거나 코드 크기 대신 코드 속도에 대해 최적화함으로써 xor 최적화를 피할 수 있습니다.
  </li>
</ul>

CPU가 리소스를 수정하지 않을 때는 리소스를 매핑되지 않은 상태로 두고, 항상 좁고 정확한 범위를 사용하는 것이 권장됩니다. 이는 [그래픽 디버깅](https://learn.microsoft.com/en-us/visualstudio/debugger/visual-studio-graphics-diagnostics) 및 디버그 계층과 같은 도구에 대해 가장 빠른 모드를 활성화합니다. 이러한 도구는 GPU가 읽을 수 있는 메모리에 대한 모든 CPU 수정 사항을 추적해야 합니다.

<h3><a id="Advanced_Usage_Models" /><a id="advanced_usage_models" /><a id="ADVANCED_USAGE_MODELS" />고급 사용 모델</h3> CPU 액세스 가능 힙의 리소스는 지속적으로 매핑될 수 있습니다. 즉, 리소스 생성 직후 **Map**을 한 번만 호출할 수 있습니다. [Unmap](/reference/graphics/d3d12/interfaces/id3d12resource/methods/id3d12resource_unmap_public)은 호출할 필요가 없지만, 리소스의 마지막 참조가 해제된 후에는 **Map**에서 반환된 주소를 더 이상 사용해서는 안 됩니다. 지속적인 매핑을 사용할 때, 응용 프로그램은 GPU가 메모리를 읽거나 쓰는 명령 목록을 실행하기 전에 CPU가 데이터를 메모리에 쓰는 것을 완료했는지 확인해야 합니다. 일반적인 시나리오에서 응용 프로그램은 [ExecuteCommandLists](/reference/graphics/d3d12_x/interfaces/id3d12commandqueue/methods/id3d12commandqueue_executecommandlists)를 호출하기 전에 메모리에 쓰기만 하면 됩니다. 하지만 명령 목록 실행을 지연시키기 위해 펜스를 사용하는 것도 가능합니다.

CPU 액세스 가능한 모든 메모리 유형은 지속적인 매핑 사용을 지원합니다. 여기서 리소스는 매핑된 후 매핑 해제되지 않으며, 응용 프로그램이 리소스가 폐기된 후 포인터에 액세스하지 않는 경우에만 가능합니다.

#### 예제

[D3D12Bundles](https://learn.microsoft.com/en-us/windows/desktop/direct3d12/working-samples) 샘플은 다음과 같이 **ID3D12Resource::Map**을 사용합니다:

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

```cpp theme={null}
// 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);
```

상수 버퍼용 업로드 힙을 만듭니다.

```cpp theme={null}
// 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 참조의 예제 코드](https://learn.microsoft.com/en-us/windows/desktop/direct3d12/notes-on-example-code)를 참조하세요.

<div class="code" />

## 요구 사항

**헤더:** d3d12\_xs.h 또는 d3d12\_x.h<br />**라이브러리:** d3d12\_xs.lib 또는 d3d12\_x.lib<br />**지원 플랫폼**: XBOX Series 콘솔 및 XBOX One 제품군

## 함께 보기

[ID3D12Resource](/reference/graphics/d3d12_xs/interfaces/ID3D12Resource/id3d12resource_xs)

[하위 리소스](https://learn.microsoft.com/en-us/windows/desktop/direct3d12/subresources)

[Unmap](/reference/graphics/d3d12/interfaces/id3d12resource/methods/id3d12resource_unmap_public)


## Related topics

- [XMemMapPhysicalPages](/ko/reference/system/xmem/functions/xmemmapphysicalpages.md)
- [ApuMapApuAddress](/ko/reference/audio/apu/functions/apumapapuaddress.md)
- [ApuMapVirtualAddress](/ko/reference/audio/apu/functions/apumapvirtualaddress.md)
- [XMemMapPhysicalPagesScatter](/ko/reference/system/xmem/functions/xmemmapphysicalpagesscatter.md)
- [CopyTileMappings](/ko/reference/graphics/d3d12/interfaces/id3d12commandqueue/methods/id3d12commandqueue_copytilemappings_public.md)
