메모리 세그먼트에 가상 주소 매핑
디스플레이 미니포트 드라이버는 정의하는 각 메모리 공간 또는 조리개 공간 세그먼트에 대해 CPU 가상 주소가 세그먼트에 대한 DXGK_SEGMENTDESCRIPTOR 구조의 Flags 멤버에서 CpuVisible 비트 필드 플래그를 설정하여 세그먼트에 있는 할당에 직접 매핑할 수 있는지 여부를 지정할 수 있습니다.
CPU 가상 주소를 세그먼트에 매핑하려면 세그먼트에 PCI 조리개를 통해 선형 액세스 권한이 있어야 합니다. 즉, 세그먼트 내의 모든 할당 오프셋은 PCI 조리개에서 오프셋과 동일해야 합니다. 따라서 비디오 메모리 관리자는 지정된 세그먼트 내의 할당 오프셋에 따라 모든 할당의 버스 상대 물리적 주소를 계산할 수 있습니다.
다음 다이어그램에서는 가상 주소가 선형 메모리 공간 세그먼트에 매핑되는 방법을 보여 줍니다.
다음 다이어그램에서는 가상 주소가 선형 조리개 공간 세그먼트의 기본 페이지에 매핑되는 방법을 보여 줍니다.
가상 주소를 세그먼트의 일부에 매핑하기 전에 비디오 메모리 관리자는 디스플레이 미니포트 드라이버의 DxgkDdiAcquireSwizzlingRange 함수를 호출하여 드라이버가 스위즐될 수 있는 할당 비트에 액세스하는 데 사용되는 조리개를 설정할 수 있도록 합니다. 드라이버는 오프셋을 할당에 액세스하는 PCI 조리개 또는 할당이 조리개에서 차지하는 공간 양으로 변경할 수 없습니다. 이러한 제약 조건(예: 하드웨어에서 스와이즐링되지 않은 조리개 부족)을 감안할 때 드라이버가 할당 CPU에 액세스할 수 없으면 비디오 메모리 관리자는 시스템 메모리에 대한 할당을 제거하고 애플리케이션이 해당 비트에 액세스할 수 있도록 합니다.
사용자 모드 표시 드라이버가 pfnLockCb 함수를 호출하여 메모리에 대한 직접 액세스를 요청할 때 이전에 만든 할당의 콘텐츠가 시스템 메모리에 있는 경우 비디오 메모리 관리자는 시스템 메모리 버퍼를 사용자 모드 디스플레이 드라이버에 반환하고 디스플레이 미니포트 드라이버는 할당에 액세스하는 데 관여하지 않습니다. 따라서 할당의 콘텐츠는 디스플레이 미니포트 드라이버에 의해 수정되지 않으며 스와이즈되지 않은 형식으로 유지됩니다. 즉, 비디오 메모리에서 CPU 액세스 가능 할당이 제거되면 디스플레이 미니포트 드라이버가 할당을 해제하여 결과 시스템 메모리 비트에 애플리케이션에서 직접 액세스할 수 있도록 해야 합니다.
현재 직접 애플리케이션 액세스를 위해 매핑된 할당과 연결된 GPU 리소스가 제거되면 할당 내용이 시스템 메모리로 전송되므로 애플리케이션이 동일한 가상 주소에서 다른 물리적 매체의 콘텐츠에 계속 액세스할 수 있습니다. 전송을 설정하기 위해 비디오 메모리 관리자는 디스플레이 미니포트 드라이버의 DxgkDdiBuildPagingBuffer 함수를 호출하여 페이징 버퍼를 만들고 GPU 스케줄러는 드라이버의 DxgkDdiSubmitCommand 함수를 호출하여 페이징 버퍼를 GPU 실행 단위로 큐에 대기합니다. 하드웨어별 전송 명령은 페이징 버퍼에 있습니다. 자세한 내용은 명령 버퍼 제출을 참조하세요. 비디오 메모리 관리자는 비디오의 시스템 메모리 전환이 애플리케이션에 표시되지 않도록 합니다. 그러나 드라이버는 PCI 조리개를 통한 할당의 바이트 순서가 할당이 제거될 때 할당의 바이트 순서와 정확히 일치하는지 확인해야 합니다.
조리개 공간 세그먼트의 경우 할당의 기본 비트가 이미 시스템 메모리에 있으므로 제거 프로세스 중에 데이터를 전송(해제)할 필요가 없습니다. 따라서 어퍼처 공간 세그먼트에 있는 CPU 액세스 가능 할당은 애플리케이션에서 직접 액세스하는 경우 스위즐할 수 없습니다.
응용 프로그램에서 CPU를 통해 표면에 직접 액세스할 수 있지만 조리개 공간 세그먼트에서 스위즐되는 경우 디스플레이 드라이버는 표면을 두 가지 할당으로 구현해야 합니다. 사용자 모드 표시 드라이버가 이러한 표면을 만들 때 pfnAllocateCb 함수를 호출할 수 있으며 D3DDDICB_ALLOCATE 구조의 NumAllocations 멤버를 2로 설정하고 D3DDDICB_ALLOCATEpAllocationInfo 배열에 있는 D3DDDI_ALLOCATIONINFO 구조의 pPrivateDriverData 멤버를 설정하여 할당에 대한 개인 데이터(예: 스위즐 및 비스위즈되지 않은 형식)를 가리킬 수 있습니다. GPU에서 사용할 할당에는 살짝 밀린 형식의 비트가 포함되며 애플리케이션에서 액세스할 할당에는 스와이즐되지 않은 형식의 비트가 포함됩니다. 비디오 메모리 관리자는 디스플레이 미니포트 드라이버의 DxgkDdiCreateAllocation 함수를 호출하여 할당을 만듭니다. 디스플레이 미니포트 드라이버는 사용자 모드 표시 드라이버에서 전달되는 개인 데이터(각 할당에 대한 DXGK_ALLOCATIONINFO 구조의 pPrivateDriverData 멤버)를 해석합니다. 비디오 메모리 관리자는 할당 형식을 인식하지 못합니다. 할당에 대해 특정 크기 및 맞춤의 메모리 블록을 할당합니다. 처리를 위해 표면을 잠그기 위해 사용자 모드 표시 드라이버의 Lock 함수를 호출하면 다음 작업이 발생합니다.
사용자 모드 표시 드라이버는 pfnRenderCb 함수를 호출하여 명령 버퍼의 unswizzle 작업을 Direct3D 런타임 및 디스플레이 미니포트 드라이버에 제출합니다.
사용자 모드 표시 드라이버는 pfnLockCb 함수를 호출하여 언스위즈되지 않은 할당을 잠급니다. 사용자 모드 표시 드라이버는 D3DDDICB_LOCK 구조체의 Flags 멤버에서 D3DDDILOCKCB_DONOTWAIT 플래그를 설정해서는 안 됩니다.
pfnLockCb 함수는 할당 간의 전송(언스위즐링)이 수행될 때까지 기다립니다.
pfnLockCb 함수는 디스플레이 미니포트 드라이버가 스와이징되지 않은 할당에 대한 가상 주소를 가져오고 가상 주소를 D3DDDICB_LOCKpData 멤버의 사용자 모드 표시 드라이버에 반환하도록 요청합니다.
사용자 모드 표시 드라이버는 D3DDDIARG_LOCK pSurfData 멤버의 애플리케이션에 대해 언스위즈되지 않은 할당의 가상 주소를 반환합니다.