다음을 통해 공유


DXGKDDI_RENDER 콜백 함수(d3dkmddi.h)

DxgkDdiRender 함수는 사용자 모드 표시 드라이버가 전달한 명령 버퍼에서 DMA(직접 메모리 액세스) 버퍼를 생성합니다.

구문

DXGKDDI_RENDER DxgkddiRender;

NTSTATUS DxgkddiRender(
  [in]     IN_CONST_HANDLE hContext,
  [in/out] INOUT_PDXGKARG_RENDER pRender
)
{...}

매개 변수

[in] hContext

DMA 및 명령 버퍼에 대한 디바이스 컨텍스트에 대한 핸들입니다. 디스플레이 미니포트 드라이버의 DxgkDdiCreateContext 함수는 이전에 DxgkDdiCreateContextpCreateContext 매개 변수가 가리키는 DXGKARG_CREATECONTEXT 구조체의 hContext 멤버에서 이 핸들을 반환했습니다.

드라이버가 컨텍스트 만들기를 지원하지 않는 경우 Microsoft DirectX 그래픽 커널 하위 시스템은 컨텍스트에 대한 핸들을 디바이스에 대한 핸들로 바꿉니다. 디스플레이 미니포트 드라이버의 DxgkDdiCreateDevice 함수는 이전에 dxgkDdiCreateDevicepCreateDevice 매개 변수가 가리키는 DXGKARG_CREATEDEVICE 구조체의 hDevice 멤버에서 디바이스 핸들을 반환했습니다.

[in/out] pRender

DMA 및 명령 버퍼에 대한 정보를 포함하는 DXGKARG_RENDER 구조체에 대한 포인터입니다.

반환 값

DxgkDdiRender 는 다음 값 중 하나를 반환합니다.

반환 코드 설명
STATUS_SUCCESS 전체 명령 버퍼가 변환되었습니다.
STATUS_NO_MEMORY DxgkDdiRender가 완료하는 데 필요한 메모리를 할당할 수 없습니다.
STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER 현재 DMA 버퍼가 고갈되었습니다.
STATUS_PRIVILEGED_INSTRUCTION DxgkDdiRender는 권한이 없는 명령(즉, 현재 중앙 처리 장치 [CPU] 프로세스의 권한을 초과하여 메모리에 액세스하는 명령)을 검색했습니다.
STATUS_ILLEGAL_INSTRUCTION DxgkDdiRender는 그래픽 하드웨어에서 지원할 수 없는 지침을 검색했습니다.
STATUS_INVALID_PARAMETER DxgkDdiRender는 그래픽 하드웨어에서 지원할 수 없는 명령 매개 변수를 검색했습니다. 그러나 그래픽 하드웨어는 명령 자체를 지원할 수 있습니다. 드라이버는 이 오류 코드를 반환할 필요가 없습니다. 대신 지원되지 않는 명령 매개 변수를 검색할 때 STATUS_ILLEGAL_INSTRUCTION 반환할 수 있습니다.
STATUS_INVALID_USER_BUFFER DxgkDdiRender가 데이터 또는 명령 언더런 또는 오버런을 검색했습니다. 즉, 드라이버가 예상보다 많거나 더 많은 명령이나 데이터를 수신했습니다. 드라이버는 이 오류 코드를 반환할 필요가 없습니다. 대신 데이터 또는 명령이 언더런 또는 오버런을 검색할 때 STATUS_ILLEGAL_INSTRUCTION 반환할 수 있습니다.
STATUS_INVALID_HANDLE DxgkDdiRender가 명령 버퍼에서 잘못된 핸들을 검색했습니다.
STATUS_GRAPHICS_DRIVER_MISMATCH 디스플레이 미니포트 드라이버는 DxgkDdiRender(즉, 명령 버퍼를 제출)에 대한 호출을 시작한 사용자 모드 디스플레이 드라이버와 호환되지 않습니다.
STATUS_GRAPHICS_GPU_EXCEPTION_ON_DEVICE 디스플레이 미니포트 드라이버가 DMA 스트림에서 오류를 감지했습니다. 드라이버가 이 오류 코드를 반환하면 그래픽 컨텍스트 디바이스가 손실된 상태로 배치됩니다.

설명

DirectX 그래픽 커널 하위 시스템은 디스플레이 미니포트 드라이버의 DxgkDdiRender 함수를 호출하여 사용자 모드 디스플레이 드라이버가 전달한 명령 버퍼에서 DMA 버퍼를 생성합니다. 디스플레이 미니포트 드라이버가 명령 버퍼에서 DMA 버퍼로 변환되는 경우 드라이버는 명령 버퍼의 유효성을 검사하여 명령 버퍼에 프로세스에 속하지 않는 메모리에 액세스하는 데 사용할 수 있는 권한 있는 명령이나 명령이 포함되지 않도록 해야 합니다. 출력 DMA 버퍼 외에도 디스플레이 미니포트 드라이버는 출력 패치 위치 목록을 생성해야 합니다. 비디오 메모리 관리자는 이 목록을 사용하여 DMA 버퍼를 적절하게 분할하고 패치합니다.

사용자 모드 디스플레이 드라이버가 생성하는 명령 버퍼 pCommand 및 입력 패치 위치 목록 pPatchLocationListIn 은 모두 사용자 모드 주소 공간에서 할당되고 그대로 디스플레이 미니포트 드라이버에 전달됩니다. 표시 미니포트 드라이버는 버퍼 및 목록에 대한 액세스에서 코드를 사용해야 __try/__except 하며, 해당 커널 버퍼에 콘텐츠를 복사하기 전에 버퍼 및 목록의 콘텐츠의 유효성을 검사해야 합니다(즉, pCommand 멤버의 콘텐츠를 pDmaBuffer 멤버에 복사하기 전에 pPatchLocationListIn 멤버의 콘텐츠를 pPatchLocationListOut 멤버에 복사하기 전에) pRender 매개 변수가 가리키는 DXGKARG_RENDER 구조체의 모든 멤버입니다.)

다음은 및 논리를 사용하여 __try__except 디스플레이 미니포트 드라이버가 이러한 버퍼에 액세스하는 방법의 예입니다. AllocationListIn은 사용자 모드 버퍼를 가리킵니다.

__try
  {
    for (Index = 0; Index < AllocationListInSize; AllocationTable++, 
           AllocationListIn++, AllocationListOut++, Index++) 
    {
      D3DKMT_HANDLE AllocationHandle = AllocationListIn->hAllocation;
      . . .
    }
  }
__except(EXCEPTION_EXECUTE_HANDLER)
  {
    Status = STATUS_INVALID_PARAMETER;
    SAMPLE_LOG_ERROR(
  "Exception occurred accessing user-mode allocation list. Returning Status=0x%I64x",
      Status);
    goto cleanup;
  }

참고

커널 버퍼에 액세스하려면 코드로부터 try/except 보호할 필요가 없습니다.

정보를 다시 만드는 것이 더 최적의 경우 디스플레이 미니포트 드라이버는 사용자 모드 디스플레이 드라이버가 제공하는 정보를 사용할 필요가 없습니다. 예를 들어 사용자 모드 표시 드라이버가 입력 패치 위치 목록을 제공하지 않아 pPatchLocationListIn 이 비어 있는 경우 디스플레이 미니포트 드라이버는 대신 명령 버퍼의 내용에 따라 pPatchLocationListOut 의 콘텐츠를 생성할 수 있습니다.

사용자 모드 표시 드라이버가 제공하는 할당 목록은 커널 전환 중에 유효성 검사, 복사 및 커널 모드 할당 목록으로 변환됩니다. DirectX 그래픽 커널 하위 시스템은 사용자 모드 디스플레이 드라이버가 제공하는 D3DKMT_HANDLE 형식의 핸들을 디바이스별 핸들로 변환하여 각 D3DDDI_ALLOCATIONLIST 요소를 DXGK_ALLOCATIONLIST 요소로 변환합니다. 이 핸들은 디스플레이 미니포트 드라이버의 DxgkDdiOpenAllocation 함수가 반환합니다. 각 할당의 인덱스와 할당의 쓰기 상태(즉, WriteOperation 비트 필드 플래그의 설정)는 변환 중에 일정하게 유지됩니다.

장치별 핸들 외에도 DirectX 그래픽 커널 하위 시스템은 각 할당에 대해 마지막으로 알려진 GPU 세그먼트 주소를 사용하여 디스플레이 미니포트 드라이버를 제공합니다. 할당 인덱스 N이 현재 페이징된 경우 DirectX 그래픽 커널 하위 시스템은 DXGKARG_RENDERpAllocationList 멤버의 N번째 요소에 대한 SegmentId 멤버를 0으로 설정합니다. 할당 목록의 N번째 요소에 대한 SegmentId 멤버가 0으로 설정되지 않은 경우 디스플레이 미니포트 드라이버는 제공된 세그먼트 주소 정보를 사용하여 생성된 DMA 버퍼를 미리 패치해야 합니다. DirectX 그래픽 커널 하위 시스템이 드라이버가 제대로 사전 패치해야 하는 DMA 버퍼의 DxgkDdiPatch 함수를 호출하지 않을 수 있으므로 요청 시 드라이버가 사전 패치해야 합니다.

참고

드라이버의 DxgkDdiRender 함수가 DMA 버퍼를 사전 패치하더라도 드라이버는 pPatchLocationListOut 멤버가 지정하는 출력 패치 위치 목록에 할당에 대한 모든 참조를 삽입해야 DXGKARG_RENDER . DMA 버퍼가 GPU에 제출되기 전에 할당 주소가 변경될 수 있으므로 이 목록에는 모든 참조가 포함되어야 합니다. 따라서 DirectX 그래픽 커널 하위 시스템은 DxgkDdiPatch 함수를 호출하여 DMA 버퍼를 다시 일치합니다.

할당을 바인딩 해제하기 위해 디스플레이 미니포트 드라이버는 할당 목록에서 NULL 핸들을 참조하는 요소를 지정한 다음 해당 NULL 할당을 참조하는 패치 위치 요소를 사용할 수 있습니다. 일반적으로 드라이버는 할당 목록의 첫 번째 요소(요소 0)를 NULL 요소로 사용해야 합니다.

디스플레이 미니포트 드라이버가 명령 버퍼를 DMA 버퍼로 변환하는 경우 디스플레이 미니포트 드라이버 및 사용자 모드 디스플레이 드라이버는 다음과 같은 상황에 대해 다음 작업을 수행해야 합니다.

  • 보장된 계약 DMA 모드(자세한 내용은 보장된 계약 DMA 버퍼 모델 사용 참조)에서 사용자 모드 표시 드라이버는 변환 명령에 충분한 리소스를 보장해야 합니다. 번역에 충분한 리소스가 없는 경우 디스플레이 미니포트 드라이버는 DMA 버퍼를 거부해야 합니다.

  • 디스플레이 미니포트 드라이버의 DxgkDdiRender 함수는 DMA 버퍼의 크기보다 크고 분할할 수 없는 단일 명령을 처리할 수 없으므로 사용자 모드 디스플레이 드라이버는 항상 단일 DMA 버퍼의 크기 이상으로 변환될 수 있는 명령을 분할해야 합니다.

DxgkDdiRender 를 페이징 가능으로 만들어야 합니다.

DxgkDdiRenderKm 함수에 대한 지원은 GDI 하드웨어 가속을 지원하는 디스플레이 어댑터용 Windows 7부터 추가되었습니다.

요구 사항

요구 사항
지원되는 최소 클라이언트 Windows Vista부터 사용 가능
대상 플랫폼 데스크톱
머리글 d3dkmddi.h
IRQL PASSIVE_LEVEL

추가 정보

D3DDDI_ALLOCATIONLIST

DXGKARG_CREATECONTEXT

DXGKARG_CREATEDEVICE

DXGKARG_RENDER

DXGK_ALLOCATIONLIST

DxgkDdiCreateContext

DxgkDdiCreateDevice

DxgkDdiOpenAllocation

DxgkDdiPatch

DxgkDdiRenderKm