2011-01-31 4 views
41

텍스쳐, 버텍스 및 쉐이더 데이터가 이미 그래픽 카드에 있다고 가정하면 많은 양의 데이터를 카드에 보낼 필요가 없습니다. 데이터를 식별하기위한 몇 바이트, 아마도 4x4 매트릭스 및 기타 여러 매개 변수가 있습니다.그리기 호출에 비용이 많이 드는 이유는 무엇입니까?

어디에서 오는 오버 헤드가 있습니까? 작업을 GPU와 일종의 핸드 셰이크가 필요합니까?

왜 CPU에서 계산 된 작은 모델을 포함하는 단일 메쉬가 전송 되는가, 종종 정점 ID와 변환 행렬을 보내는 것보다 빠릅니까? (모델이 4x4 행렬보다 작은 경우가 아니면 두 번째 옵션이 전송 된 것처럼 보입니다.)

+2

오, 네,이 Q 주셔서 감사합니다. –

답변

47

우선 "그리기 호출"을 사용하면 특정 상태 (셰이더, 블렌드 상태 등)의 삼각형으로 특정 꼭지점 집합을 렌더링하도록 GPU에 지시하는 명령을 의미한다고 가정합니다.

그리기 호출은 반드시 비싸지는 않습니다. 이전 버전의 Direct3D에서는 컨텍스트 스위치가 많이 필요했지만 많은 비용이 듭니다. 그러나 최신 버전에서는 그렇지 않습니다.

그리기 호출을 적게하는 주된 이유는 그래픽 하드웨어가 전송할 수있는 것보다 훨씬 빨리 삼각형을 변환하고 렌더링 할 수 있기 때문입니다. 각 호출마다 삼각형을 거의 전송하지 않으면 CPU에 완전히 얽매여 있으며 GPU는 대부분 유휴 상태가됩니다. CPU는 GPU를 충분히 빠르게 공급할 수 없습니다.

두 개의 삼각형을 사용하여 한 번의 그리기 호출을 만드는 것은 저렴하지만 각 호출마다 데이터를 너무 적게 제출하면 GPU에 많은 지오메트리를 제출할 수있는 충분한 CPU 시간을 확보 할 수 없습니다.

그리기 호출을하는 데 약간의 비용이 들기 때문에 여러 가지 상태 (사용할 정점 집합, 사용할 셰이더 집합 등)를 설정해야하며 상태 변경은 하드웨어 측면 (다수의 레지스터 업데이트) 및 드라이버 측 (상태를 설정하는 호출 유효성 검사 및 변환).

각 호출이 너무 적은 데이터를 제출하는 경우에만 그리기 호출의 주 비용이 부과됩니다.이 경우 CPU 사용이 제한되어 하드웨어를 완전히 사용하지 못하게 될 수 있습니다.

그리기 호출을 사용하면 명령 버퍼가 플러시 될 수 있지만 내 경험에 따르면 일반적으로 기하학을 제출할 때가 아니라 SwapBuffers를 호출 할 때 발생합니다. 비디오 드라이버는 일반적으로 GPU에서 최대한 병렬 처리하기 위해 가능한 한 많이 버퍼링하려고합니다 (몇몇 프레임은 때로는!).

당신은 nVidia 프리젠 테이션 Batch Batch Batch!을 읽어야합니다. 상당히 오래된 것이지만이 주제를 정확하게 다루고 있습니다.

+1

이것은 거의 제가 찾고있는 것입니다. 감사! – notallama

+1

nVidia 데크 링크가 죽은 것처럼 보입니다. 이것을 시도하십시오 : http://tinyurl.com/acezt9b. –

10

Direct3D와 같은 그래픽 API는 API 수준의 호출을 장치 독립적 인 명령으로 변환하여 버퍼에 대기시킵니다. 실제 작업을 수행하기 위해 버퍼를 비우는 작업은 비용이 많이 든다. 실제 작업이 현재 수행 중이며, 사용자 모드에서 칩으로 커널 모드로 전환 될 수 있기 때문이다. 싼.

버퍼가 플러시 될 때까지 GPU는 CPU가 데이터를 다시 CPU에 매핑하는 것과 같이 차단 요청을하지 않는 한 CPU와 병렬로 사전 준비 작업을 수행 할 수 있습니다. 그러나 GPU는 실제로 그릴 때까지 모든 것을 준비하지도, 할 수도 없습니다. 일부 정점 또는 텍스처 데이터가 카드에 있기 때문에 적절히 정렬되어 있다는 것을 의미하지 않으며 정점 레이아웃이 설정되거나 셰이더가 바인딩 될 때까지 배열 할 수 없습니다. 실제 작업의 대부분은 명령 플러시 및 그리기 호출 중에 발생합니다.

DirectX SDK에는 section on accurately profiling D3D performance이 있습니다. 질문에 직접 관련이 없지만, 무엇이 비싸거나 (어떤 경우에는) 이유에 대한 힌트를 줄 수 있습니다.

관련성이 더 높은 것은 this blog post (및 후속 게시물 herehere)이며, GPU의 논리적, 저급 운영 프로세스에 대한 개요를 제공합니다. 기본적으로 (당신의 질문에 대한 답변을 직접 시도하기)

그러나, 통화가 비싼 이유는 ​​반드시 많은 양의 데이터를 전송할 수 있다는 것을,하지만 작업 의 큰 몸이 오히려이지 않는다을 지나면 명령 버퍼가 플러시 될 때까지 지연되는 버스를 통해 데이터가 전달됩니다.

2

간단한 대답 : 드라이버는 그리기를 호출 할 때까지 실제 작업의 일부 또는 전부를 버퍼링합니다. 이것은 변경된 상태의 정도에 따라 그리기 호출에 소요되는 시간을 비교적 예측 가능한 양으로 표시합니다.

는 몇 가지 이유에 대해 수행됩니다

  • 불필요한 일을 피하기 위해 : 당신이 (불필요) 비싼 작업이 될 때마다 일을 피할 수를 그리기 전에 같은 상태를 여러 번 설정합니다. 이것은 실제 생산 게임 엔진과 같이 커다란 코드베이스에서 상당히 흔하게 발생합니다.

    • 다음은 드라이버가 렌더링 명령을 저장하는 데 사용하는 버퍼 전체한다 :
    • 내부적으로 대신 불완전한 정보 즉시

    대체 대답 (들)을 처리하는 상호 의존적 인 상태가 무엇인지 화해 할 수 있도록 응용 프로그램은 GPU가 이전 작업 중 일부를 처리하기를 실제로 기다리고 있습니다. 이것은 일반적으로 프레임 내의 무작위 드로 콜에서 매우 큰 시간 블로킹으로 나타납니다.

  • 드라이버가 버퍼링 할 수있는 프레임 수에 도달했으며 앱이 그 중 하나를 처리하기 위해 GPU에서 대기 중입니다. 이것은 일반적으로 프레임 내의 첫 번째 그리기 호출에서 시간 차단의 큰 덩어리로 표시되거나 이전 프레임의 끝에서 현재에 표시됩니다.
관련 문제