편집

다음을 통해 공유


Direct3D 10 질문과 대답

이 문서에는 Direct3D 9(D3D9)에서 Direct3D 10(D3D10)으로 기존 애플리케이션을 포팅하는 개발자의 관점에서 Direct3D 10을 둘러싼 몇 가지 질문과 대답이 포함되어 있습니다.

상수 버퍼

상수 버퍼를 업데이트하는 가장 좋은 방법은 무엇인가요?

UpdateSubresource 및 무시를 사용하여 맵은 거의 동일한 속도여야 합니다. 최소 메모리 양을 복사하는 메모리에 따라 둘 중에서 선택합니다. 데이터가 하나의 연속 블록에 이미 메모리에 저장된 경우 UpdateSubresource를 사용합니다. 다른 위치에서 데이터를 누적해야 하는 경우 삭제와 함께 맵을 사용합니다.

상수 버퍼를 구성하는 최악의 방법은 무엇인가요?

최악의 성능은 특정 셰이더에 대한 모든 상수를 하나의 상수 버퍼에 배치하여 실현됩니다. 이는 종종 D3D9에서 D3D10으로 이식하는 가장 쉬운 방법이지만 성능을 저해할 수 있습니다. 예를 들어 다음과 같은 상수 버퍼를 사용하는 시나리오를 고려해 보세요.

cbuffer VSGlobalsCB
{
    matrix  ViewProj;
    matrix  Bones[100];
    matrix  World;
    float   SpecPower;
    float4  BDRFCoefficients;
    float   AppTime;
    uint2   RenderTargetSize;
};

버퍼는 6560바이트입니다. 렌더링할 개체가 1000개이고, 그 중 100개는 스킨 메시이고, 그 중 900개는 정적 메시인 애플리케이션이 있다고 가정합니다. 또한 이 애플리케이션이 하나의 광원으로 섀도 매핑을 사용하고 있다고 가정합니다. 즉, 조명에서 렌더링된 깊이 맵과 정방향 렌더링 패스에 대해 하나씩 두 개의 패스가 있습니다. 이로 인해 2000개 그리기 호출이 발생합니다. 각 그리기 호출이 상수 버퍼의 모든 부분을 업데이트할 필요는 없지만 전체 상수 버퍼는 여전히 업데이트되어 카드 전송됩니다. 이로 인해 프레임마다 13MB의 데이터가 업데이트됩니다(2000 그리기 호출 6560KB).

상수 버퍼를 구성하는 가장 좋은 방법은 무엇인가요?

가장 좋은 방법은 업데이트 빈도에 따라 상수 버퍼를 구성하는 것입니다. 비슷한 주파수에서 업데이트되는 상수는 동일한 버퍼에 있어야 합니다. 예를 들어 "상수 버퍼를 구성하는 최악의 방법은 무엇인가요?"에 제시된 시나리오를 고려해 보십시오. 하지만 상수 레이아웃이 더 좋습니다.

cbuffer VSGlobalPerFrameCB
  { 
    float   AppTime; 
  };
cbuffer VSPerSkinnedCB
  { 
    matrix  Bones[100]; 
  };
cbuffer VSPerStaticCB
  {
    matrix  World;
  };
cbuffer VSPerPassCB
  {
    matrix  ViewProj;
    uint2   RenderTargetSize;
  };
cbuffer VSPerMaterialCB
  {
    float   SpecPower;
    float4  BDRFCoefficients;
  };    

상수 버퍼는 업데이트 빈도에 따라 분할되지만 이는 솔루션의 절반에 불과합니다. 애플리케이션은 분할을 최대한 활용하기 위해 상수 버퍼를 올바르게 업데이트해야 합니다. 900개의 정적 메시, 100개의 스킨 메시, 1개의 라이트 패스, 1개의 전진 패스 등 위와 동일한 장면을 가정합니다. 또한 개체당 일부 상수 버퍼가 저장된다고 가정합니다. 즉, 각 개체는 스킨 또는 정적 여부에 따라 VSPerSkinnedCB 또는 VSPerStaticCB를 포함합니다. 파이프라인을 통해 전송되는 행렬의 양을 두 배로 늘리지 않도록 하기 위해 이 작업을 수행합니다.

프레임을 세 단계로 분할합니다. 첫 번째 단계는 프레임의 시작이며 렌더링이 없고 일정한 업데이트만 포함합니다.

시작 프레임

  • 애플리케이션 시간에 대한 VSGlobalPerFrameCB 업데이트(4바이트)
  • 스키닝된 100개 개체에 대한 VSPerSkinnedCB 100개 업데이트(640000바이트)
  • 900개 정적 개체에 대한 VSPerStaticCB 업데이트(57600바이트)

다음은 섀도 맵 패스입니다. 실제로 업데이트되는 유일한 상수 버퍼는 VSPerPassCB입니다. 다른 모든 상수 버퍼는 시작 프레임 패스 중에 업데이트되었습니다. 이러한 상수 버퍼를 바인딩해야 하지만 버퍼가 이미 업데이트되었으므로 비디오 카드 전달되는 정보의 양은 최소화됩니다.

섀도 패스

  • VSPerPassCB 업데이트(72바이트)
  • 피부가 있는 메시 100개 그리기(100개의 바인드, 업데이트 없음)
  • 900개의 정적 메시 그리기(100개의 바인딩, 업데이트 없음)

마찬가지로, 앞으로 렌더링 패스는 메시당 저장되지 않았기 때문에 재질별 데이터만 업데이트하면 됩니다. 장면에 500개 재질이 사용 중이라고 가정하는 경우:

전달 패스

  • VSPerPassCB 업데이트(72바이트)
  • 업데이트 500 VSPerMaterialCB(10000바이트)

이로 인해 총 707KB에 불과합니다. 이는 매우 모순된 시나리오이지만 업데이트 빈도에 따라 상수를 정렬하여 일정한 업데이트 오버헤드를 줄일 수 있는 정도를 보여 줍니다.

메시, 재질 등에 대한 개별 상수 버퍼를 저장할 공간이 충분하지 않으면 어떻게 해야 하나요?

항상 상수 버퍼의 계층화된 시스템을 사용할 수 있습니다. 필요한 최대 상수 버퍼 크기까지 가변 크기 상수 버퍼(16바이트, 32바이트, 64바이트 등)를 만듭니다. 상수 버퍼를 셰이더에 바인딩할 때 셰이더에 필요한 데이터를 저장할 수 있는 가장 작은 상수 버퍼를 선택합니다. 이 방법은 약간 덜 효율적이지만 좋은 중간 단계입니다.

서로 다른 셰이더 간에 상수 버퍼를 공유하고 있습니다. 한 셰이더는 모든 상수를 사용할 수 있지만 다른 셰이더는 일부 상수를 사용할 수 있습니다. 이를 업데이트하는 가장 좋은 방법은 무엇인가요?

한 가지 방법은 상수 버퍼를 더욱 분할하는 것입니다. 그러나 너무 많은 상수 버퍼가 바인딩되는 지점이 있습니다. 이 경우 여러 셰이더에서 사용하지 않을 가능성이 있는 상수를 상수 버퍼의 끝으로 이동합니다. 셰이더에서 변수 데이터를 가져오는 경우 D3D10_SHADER_VARIABLE_DESC D3D10_SVF_USED 플래그를 사용하여 변수가 사용되는지 확인합니다. 사용되지 않는 변수를 상수 버퍼의 끝에 배치하면 이러한 변수를 사용하지 않는 셰이더에 더 작은 버퍼를 바인딩하여 업데이트 비용을 절약할 수 있습니다.

패스/드로우당 한 번이 아닌 프레임당 한 번만 캐릭터의 뼈를 업로드하는 경우 프레임 속도를 얼마나 개선할 수 있나요?

중복 데이터의 양에 따라 프레임 속도를 8%에서 50% 사이로 개선할 수 있습니다. 최악의 경우 성능이 저하되지 않습니다.

한 번에 바인딩해야 하는 상수 버퍼는 몇 개입니까?

모든 데이터를 셰이더에 가져오는 데 걸리는 최소 상수 버퍼 수를 바인딩합니다. 현실적인 시나리오에서 5개는 사용할 권장되는 상수 버퍼 수입니다. 셰이더 간에 상수 버퍼를 공유(VS 및 PS에 동일한 CB 바인딩)도 성능을 향상시킬 수 있습니다.

상수 버퍼를 사용하지 않고 바인딩하는 데 비용이 있나요?

예, 실제로 버퍼를 사용하지 않을 경우 VSSetConsantBuffer 또는 PSSetConstantBuffer를 호출하지 마세요. 이 추가 API 오버헤드는 여러 그리기 호출 과정에서 더해질 수 있습니다.

시스템 상태

D3D10에서 상태를 관리하는 가장 좋은 방법은 무엇인가요?

가장 좋은 해결 방법은 모든 상태를 미리 알고 상태 개체를 미리 만드는 것입니다. 즉, 렌더링 시 상태 바인딩만 수행해야 합니다. D3D10은 중복 항목도 필터링합니다.

게임이 동적으로 로드되었거나 사용자가 생성한 콘텐츠가 있습니다. 모든 상태 개체를 앞에 로드할 수 없습니다.   어떻게 해야 합니까?

여기에는 두 가지 솔루션이 있습니다. 첫 번째는 즉시 상태 개체를 만들고 D3D10에서 중복 항목을 필터링할 수 있도록 하는 것입니다. 그러나 프레임당 상태 개체가 많이 변경되는 시나리오에는 권장되지 않습니다. 더 나은 해결 방법은 상태 개체를 직접 해시하고 요구 사항에 맞는 개체가 해시 테이블에 없는 경우에만 상태 개체를 만드는 것입니다. 사용자 지정 해시 테이블을 사용하는 이유는 애플리케이션이 해당 애플리케이션과 관련된 사용 시나리오에 따라 빠른 해시를 선택할 수 있다는 것입니다. 예를 들어 애플리케이션이 BlendState의 rendertargetwritemask만 변경하고 다른 모든 값을 동일하게 유지하는 경우 애플리케이션은 전체 구조 대신 rendertargetwritemask에서 해시를 생성할 수 있습니다.

AlphaTest 상태가 사라졌습니다. 해당 리포지토리는 어디로 갔을까요?

이제 AlphaTest는 셰이더의 성능이어야 합니다. FixedFuncEMU 샘플을 참조하세요.

사용자 클립 평면이 어떻게 되었나요?

사용자 클립 평면이 셰이더로 이동되었습니다. 이를 처리하는 방법에는 두 가지가 있습니다. 첫 번째는 꼭짓점 셰이더 또는 기하 도형 셰이더에서 SV_ClipDistance 출력하는 것입니다. 다른 옵션은 꼭짓점 셰이더 또는 기하 도형 셰이더에서 전달된 일부 값을 기반으로 픽셀 셰이더에서 무시를 사용하는 것입니다. 둘 다 실험하여 특정 시나리오에 더 빠른 것을 확인합니다. SV_ClipDistance 사용하면 하드웨어에서 기하 도형 바운드 그리기 호출이 느리게 실행될 수 있는 기하 도형 기반 클리핑 루틴을 사용할 수 있습니다. 마찬가지로 무시를 사용하면 작업이 픽셀 셰이더로 이동되어 픽셀 바인딩된 그리기 호출이 느리게 실행될 수 있습니다.

지우기는 내 래스터라이저 상태의 가위 사각형 설정과 같은 상태 설정을 준수하지 않습니다.

지우기를 파이프라인 상태에서 분리했습니다. D3D9 스타일 동작을 가져오기 위해 전체 화면 쿼드를 그려 지우기를 에뮬레이트합니다.

렌더링 오류를 시도하고 진단하도록 상태를 다시 기본값으로 설정합니다. 이제 화면에 개체를 그리는 것을 알지만 화면이 검은색으로 표시됩니다.

상태를 다시 기본값(NULL)으로 설정할 때 OMSetBlendState 호출의 SampleMask가 0이 아닌지 확인합니다. SampleMask가 0으로 설정된 경우 모든 샘플은 논리적으로 AND가 0으로 설정됩니다. 이 시나리오에서는 샘플이 혼합 테스트를 통과하지 않습니다.

D3DSAMP\SRGBTEXTURE 상태는 어디로 이동했나요?

SRGB가 샘플러 상태의 일부로 제거되었으며 이제 텍스처 형식에 연결됩니다. SRGB 텍스처를 바인딩하면 Direct3D 9에서 D3DSAMP_SRGBTEXTURE 지정한 경우 동일한 샘플링이 발생합니다.

형식

D3D10 형식에 해당하는 D3D9 형식은 무엇입니까?

A8R8G8B8 텍스처 형식은 어떻게 되었나요?

D3D10에서는 더 이상 사용되지 않습니다. 텍스처를 R8G8B8A8 다시 공급하거나 로드할 때 살짝 밀거나 셰이더에서 스위즐할 수 있습니다.

팔레트화된 텍스처를 사용할 어떻게 할까요? 있나요?

색상표를 텍스처 또는 상수 버퍼에 놓고 파이프라인에 바인딩합니다. 픽셀 셰이더에서 palettized 텍스처의 인덱스로 간접 조회를 수행합니다.

이러한 새로운 SRGB 형식은 무엇인가요?

SRGB는 샘플러 상태의 일부로 제거되었으며 이제 텍스처 형식에 연결됩니다. SRGB 텍스처를 바인딩하면 Direct3D 9에서 D3DSAMP_SRGBTEXTURE 지정한 경우 동일한 샘플링이 발생합니다.

삼각형 팬은 어디로 갔습니까?

삼각형 팬은 D3D10에서 더 이상 사용되지 않습니다. 삼각형 팬은 콘텐츠 파이프라인 또는 로드 중에서 변환해야 합니다.

셰이더 연결

내 Direct3D 9 셰이더는 셰이더 모델 4.0으로 잘 컴파일되지만 파이프라인에 바인딩하면 디버그 런타임을 사용하여 디버그 출력에 링크 오류가 표시됩니다.

셰이더 연결은 D3D10에서 훨씬 더 엄격합니다. 이후 단계의 요소는 이전 단계의 출력 순서대로 읽어야 합니다. 예를 들어:

꼭짓점 셰이더 출력:

    float4 Pos  : SV_POSITION;
    float3 Norm : NORMAL;
    float2 Tex  : TEXCOORD0;

픽셀 셰이더는 다음을 읽습니다.

        float3 Norm : NORMAL;
        float2 Tex  : TEXCOORD0;

픽셀 셰이더에서는 위치가 필요하지 않지만 위치가 꼭짓점 셰이더에서 출력되지만 픽셀 셰이더에서 읽지 않기 때문에 연결 오류가 발생합니다. 더 올바른 버전은 다음과 같습니다.

꼭짓점 셰이더 출력:

        float3 Norm : NORMAL;
        float2 Tex  : TEXCOORD0;
        float4 Pos  : SV_POSITION;

픽셀 셰이더는 다음을 읽습니다.

        float3 Norm : NORMAL;
        float2 Tex  : TEXCOORD0;

이 경우 꼭짓점 셰이더가 동일한 정보를 출력하지만 이제 픽셀 셰이더가 순서 출력으로 항목을 읽습니다. 픽셀 셰이더가 Tex 이후에 아무 것도 읽지 않으므로 VS가 PS가 읽는 것보다 더 많은 정보를 출력하는 것을 걱정할 필요가 없습니다.

입력 레이아웃을 만들려면 셰이더 서명이 필요하지만 셰이더를 만들기 전에 메시를 로드하고 레이아웃을 만듭니다. 어떻게 해야 합니까?

한 가지 해결 방법은 메시를 로드하기 전에 순서를 전환하고 셰이더를 로드하는 것입니다. 그러나, 이것은 훨씬 쉽게 말한 보다. 애플리케이션에서 필요할 때 항상 요청 시 입력 레이아웃을 만들 수 있습니다. 셰이더 서명의 버전을 유지해야 합니다. 셰이더 및 버퍼 레이아웃을 기반으로 해시를 만들고 일치하는 해시가 아직 없는 경우에만 입력 레이아웃을 만들어야 합니다.

그리기 호출

D3D10이 60Hz에 도달하는 그리기 호출에 대한 제한은 무엇인가요? 30Hz?

Direct3D 9는 그리기 호출당 CPU 비용으로 인해 그리기 호출 수에 제한이 있었습니다. Direct3D 10에서는 각 그리기 호출 비용이 절감되었습니다. 그러나 그리기 호출과 프레임 속도 사이에는 더 이상 명확한 상관 관계가 없습니다. 그리기 호출에는 종종 많은 지원 호출(상수 버퍼 업데이트, 텍스처 바인딩, 상태 설정 등)이 필요하기 때문에 API의 프레임 속도 영향은 단순히 호출 횟수를 그리는 것이 아니라 전체 API 사용에 더 많이 종속됩니다.

리소스

어떤 작업에 어떤 리소스 사용 유형을 사용해야 하나요?

다음 치트 시트를 사용합니다.

  • CPU는 프레임당 리소스를 두 번 이상 업데이트합니다. D3D10_USAGE_DYNAMIC
  • CPU는 프레임당 한 번 미만의 리소스를 업데이트합니다. D3D10_USAGE_DEFAULT
  • CPU는 리소스를 업데이트하지 않습니다. D3D10_USAGE_IMMUTABLE
  • CPU는 리소스를 읽어야 합니다D3D10_USAGE_STAGING

상수 버퍼는 항상 자주 업데이트되기 때문에 "치트시트"를 준수하지 않습니다. 상수 버퍼에 사용할 리소스 유형은 상수 버퍼 섹션을 참조하세요 .

DrawPrimitiveUP 및 DrawIndexedPrimitiveUP은 어떻게 되었나요?

D3D10에서 사라졌습니다. 동적 기하 도형의 경우 큰 D3D10_USAGE_DYNAMIC 버퍼를 사용합니다. 프레임의 시작 부분에서 D3D10_MAP_WRITE_DISCARD 매핑합니다. 이후의 각 그리기 호출에 대해 이전에 그린 꼭짓점의 위치를 지나 쓰기 포인터를 이동하고 버퍼를 D3D10_MAP_WRITE_NO_OVERWRITE 매핑합니다. 프레임이 끝나기 전에 버퍼의 끝에 가까워지면 쓰기 포인터를 시작 부분에 래핑하고 D3D10_MAP_WRITE_DISCARD 매핑합니다.

16비트 인덱스와 32비트 인덱스를 동일한 동적 기하 도형 버퍼에 쓸 수 있나요?

예, 가능하지만 특정 하드웨어에서 성능 저하가 발생할 수 있습니다. 동적 16비트 인덱스 데이터와 32비트 인덱스 데이터에 대한 별도의 버퍼를 만드는 것이 더 안전합니다.

GPU에서 CPU로 데이터를 다시 읽을 어떻게 할까요? 있나요?

스테이징 리소스를 사용해야 합니다. CopyResource를 사용하여 GPU 리소스에서 준비 리소스로 데이터를 복사합니다. 준비 리소스를 매핑하여 데이터를 읽습니다.

내 애플리케이션은 StretchRect 기능에 종속되었습니다.

기본적으로 기본 Direct3D 기능의 래퍼이므로 API에서 제거되었습니다. StretchRect 기능 중 일부는 D3DX10LoadTextureFromTexture로 이동되었습니다. 형식 변환 및 텍스처 복사의 경우 D3DX10LoadTextureFromTexture에서 작업을 수행할 수 있습니다. 그러나 한 크기에서 다른 크기로 변환하는 등의 작업에는 애플리케이션의 텍스처로 렌더링 작업이 필요할 수 있습니다.

리소스에 대한 맵 호출에는 오프셋 또는 크기가 없습니다. Direct3D 9의 잠금 호출에 있습니다. 변경된 이유는 무엇인가요?

Direct3D 9의 Lock 호출에 대한 오프셋 및 크기는 기본적으로 API가 복잡했으며 드라이버에서 무시되는 경우가 많습니다. 맵 호출에서 반환된 포인터에서 애플리케이션에서 오프셋을 대신 계산해야 합니다.

텍스처로서의 깊이

더 빠른 것은 무엇인가요? 깊이를 텍스처로 사용하거나 알파에 깊이를 쓰고 읽으시나요?

이는 애플리케이션 및 하드웨어에 따라 다릅니다. 가장 많은 대역폭을 저장하는 중 하나를 사용합니다. 이미 여러 렌더링 대상을 사용하고 있고 추가 채널이 있는 경우 셰이더에서 깊이를 쓰는 것이 더 나은 솔루션일 수 있습니다. 또한 알파 또는 다른 렌더링 대상에 깊이를 쓰면 깊이 버퍼에 액세스해야 하는 계산 속도를 높일 수 있는 선형 깊이 값을 작성할 수 있습니다.

깊이 쓰기를 사용하지 않도록 설정하는 한 텍스처를 입력으로 바인딩하고 깊이 스텐실 텍스처로 바인딩할 수 있나요?

D3D10에는 없습니다.

MSAA

MSAA 깊이 스텐실 텍스처를 resolve 수 있나요?

D3D10에는 없습니다. 그러나 MSAA 텍스처에서 개별 샘플을 샘플링할 수 있습니다. 자세한 내용은 HLSL 섹션을 참조하세요.

MSAA를 사용하도록 설정하는 즉시 애플리케이션이 충돌하는 이유는 무엇인가요?

드라이버에서 실제로 열거한 MSAA 샘플 수 및 품질 번호를 사용하도록 설정하고 있는지 확인합니다.

크래시

내 애플리케이션이 D3D10 또는 드라이버에서 충돌하고 이유를 모르겠어요.

첫 번째 단계는 D3D10CreateDevice에 전달된 디버그 런타임(D3D10_CREATE_DEVICE_DEBUG 플래그)을 사용하도록 설정하는 것입니다. 이렇게 하면 가장 일반적인 오류가 디버그 출력으로 노출됩니다.

애플리케이션을 사용하려고 하면 PIX가 충돌합니다.

첫 번째 단계는 D3D10CreateDevice에 전달된 디버그 런타임(D3D10_CREATE_DEVICE_DEBUG 플래그)을 사용하도록 설정하는 것입니다. 디버그 출력이 클린 않으면 PIX가 충돌할 확률이 훨씬 높습니다.

게임이 D3D10 아래의 32비트 Vista에서 가상 주소 공간이 부족합니다. D3D9에는 문제가 없습니다.

D3D10 및 가상 주소 공간에 몇 가지 문제가 있었습니다. 이는 KB940105 수정되었습니다. 문제가 해결되지 않으면 D3D9에서 만든 것보다 D3D10에서 매핑(잠김)될 수 있는 리소스를 더 이상 만들지 않는지 확인합니다. 또한 앞으로 더 널리 퍼질 것이기 때문에 64비트로 포팅하는 것에 대해서도 생각해 보십시오.

조건자 렌더링

조건자 렌더링을 사용했습니다(폐색 쿼리 결과 기반). 내 앱이 여전히 동일한 속도인 이유는 무엇인가요?

먼저 건너뛰려는 렌더링이 실제로 애플리케이션 병목 상태인지 확인합니다. 병목 상태가 아닌 경우 렌더링을 건너뛰면 프레임 속도에 도움이 되지 않습니다.

둘째, 쿼리 문제와 조건자하려는 렌더링 사이에 충분한 시간이 경과했는지 확인합니다. 렌더링 호출이 GPU에 도달할 때까지 쿼리가 완료되지 않은 경우 렌더링이 어쨌든 발생합니다.

셋째, 조건자는 특정 호출만 건너뜁니다. 건너뛴 호출은 그리기, 지우기, 복사, 업데이트, ResolveSubresource 및 GenerateMips입니다. 상태 설정, IA 설정, 맵 및 만들기 호출은 조건자를 준수하지 않습니다. 조건자로 사용할 그리기 호출 주위에 많은 상태 설정 호출이 있는 경우 이러한 상태는 여전히 설정됩니다.

기하 도형 셰이더

기하 도형 셰이더를 사용하여 내 테셀레이트해야 하나요(여기에 아무것도 삽입)?

아니요. 기하 도형 셰이더는 테셀레이션에 사용하면 안 됩니다.

기하 도형 셰이더를 사용하여 기하 도형을 만들 수 있나요?

예, 매우 제한된 시나리오에서. 현재 D3D10(2008) 부품의 기하 도형 셰이더는 많은 확장을 처리할 수 없습니다. 이는 나중에 변경될 수 있습니다. 비디오 카드 공급업체는 기존 지점 스프라이트 하드웨어로 인해 1~4개의 확장을 위한 특별한 경로를 가질 수 있습니다. 다른 확장은 매우 제한적이어야 합니다. ParticlesGS 및 PipesGS 샘플은 제한된 확장만 수행하여 높은 프레임 속도를 달성합니다. 프레임당 몇 점만 확장됩니다.

기하 도형 셰이더를 어떻게 사용해야 하나요?

실루엣 감지, 바리센트릭 좌표 등과 같은 전체 기본 형식에 대한 작업이 필요한 모든 항목입니다. 또한 기본 형식을 보낼 렌더링 대상 배열의 조각을 선택하는 데 사용합니다.

기하 도형 셰이더에서 가변 기하 도형의 양을 출력할 수 있나요?

예, 하지만 이로 인해 성능 문제가 발생할 수 있습니다. 한 호출에 대해 1포인트, 다른 호출에 대해 4포인트를 출력하는 예제를 사용합니다. 확장 지침 내에서 맞추는 동안 기하 도형 셰이더 스레드가 직렬로 실행될 수 있습니다.

D3D10은 메시에 인접한 인덱스를 생성하는 방법을 어떻게 알 수 있나요? 또는 기하 도형 셰이더에 인접 정보가 필요함을 지정할 때 D3D10이 올바르게 렌더링되지 않는 이유는 무엇인가요?

인접 정보는 D3D10이 아니라 애플리케이션에 의해 생성됩니다. 인접 인덱스는 애플리케이션에서 생성되며 기본형당 6개의 인덱스를 포함해야 합니다. 6개 중 홀수 인덱스는 인접한 에지 꼭짓점입니다. ID3DX10Mesh::GenerateAdjacencyAndPointsReps를 사용하여 이 데이터를 생성할 수 있습니다.

HLSL

정수 및 비트 명령이 느리나요?

그들은 될 수 있습니다. 다양한 D3D10 카드는 사용 가능한 ALU 단위의 하위 집합에서만 정수 작업을 실행할 수 있습니다. 이는 하드웨어에 크게 의존합니다. 특정 하드웨어에서 정수 작업을 처리하는 방법에 대한 권장 사항은 개별 하드웨어 공급업체를 참조하세요. 또한 형식 간의 캐스트에 주의해야 합니다.

VPOS는 어떻게 되었나요?

픽셀 셰이더에 대한 입력을 SV_POSITION 선언하면 VPOS로 선언하는 것과 동일한 동작이 발생합니다.

MSAA 텍스처를 샘플링할 어떻게 할까요? 있나요?

셰이더에서 텍스처를 Texture2DMS로 선언합니다. 그런 다음 Texture2DMS 개체의 Sample 메서드를 사용하여 개별 샘플을 가져올 수 있습니다.

상수 버퍼의 셰이더 변수가 실제로 사용되는지 알 어떻게 할까요? 있나요?

해당 변수에 대해 반영된 D3D10_SHADER_VARIABLE_DESC 구조체를 확인합니다. uFlags에는 D3D10_SVF_USED 플래그가 설정되어 있어야 합니다.

상수 버퍼의 셰이더 변수가 실제로 FX10을 사용하는지 알 어떻게 할까요? 있나요?

현재 FX10을 사용할 수 없습니다.

FX10에서 만드는 상수 버퍼를 제어할 수 없습니다. 어떻게 만들고 업데이트합니까?

모든 FX10 관리 상수 버퍼는 D3D10_USAGE_DEFAULT 리소스로 만들어지고 UpdateSubresource를 사용하여 업데이트됩니다. FX10은 모든 상수 데이터의 백업 저장소를 유지하므로 UpdateSubresource는 이러한 데이터를 업데이트하는 가장 좋은 방법입니다.

셰이더를 사용하여 고정 함수 파이프라인을 에뮬레이트할 어떻게 할까요? 있나요?

FixedFuncEMU 샘플을 참조하세요.

컴파일러 힌트인 새 \[unroll\], \[loop\], \[branch\]등을 사용해야 하나요?

일반적으로 그렇지 않습니다. 컴파일러는 종종 두 가지 방법을 모두 시도하고 가장 빠른 방법을 선택합니다. 예를 들어 루프 내부의 텍스처 페치에서 그라데이션에 액세스해야 하는 경우 [unroll]을 사용해야 하는 경우도 있습니다.

부분 정밀도는 D3D10에서 차이를 만들나요? D3D9 HLSL에서는 부분 전체 자릿수를 지정할 수 있지만 D3D10 HLSL에서는 지정할 수 없습니다.

모든 D3D10 작업은 32비트 부동 소수점 정밀도에서 실행되도록 지정됩니다. 따라서 부분 정밀도는 D3D10에서 차이를 만들어서는 안 됩니다.

D3D9에서는 깊이 버퍼를 텍스처로 바인딩하고 일반 tex2d hlsl 지침을 사용하여 HW PCF 섀도 필터링을 수행할 수 있습니다. D3D10에서 이 작업을 어떻게 할까요??

비교 샘플러 상태를 사용하고 SampleCmp 지침을 사용해야 합니다.

이 레지스터 키워드(keyword) D3D10에서 어떻게 작동하나요?

이제 D3D10의 레지스터 키워드(keyword) 특정 리소스가 바인딩된 슬롯에 적용됩니다. 이 경우 리소스는 버퍼(상수 또는 기타), 텍스처 또는 샘플러일 수 있습니다.

  • 상수 버퍼의 경우 register(bN) 구문을 사용합니다. 여기서 N은 입력 슬롯(0-15)입니다.
  • 텍스처의 경우 register(tN) 구문을 사용합니다. 여기서 N은 입력 슬롯(0-127)입니다.
  • 샘플러의 경우 register(sN) 구문을 사용합니다. 여기서 N은 입력 슬롯(0-127)입니다.

레지스터를 사용하여 전체 버퍼를 바인딩할 위치를 지정하는 경우 상수 버퍼 내에 변수를 배치할 어떻게 할까요? 있나요?

packoffset 키워드(keyword) 사용합니다. packoffset에 대한 인수는 c[0-4095]의 형식입니다. [x,y,z,w]. 예를 들어:

        cbuffer cbLotsOfEmptySpace
        {
        float   IWaste2Floats   : packoffset(c0.z);
        float4  IWasteMore  : packoffset(c13);
        };

이 상수 버퍼에서 IWaste2Floats는 상수 버퍼의 세 번째 부동 소수점(12바이트)에 배치됩니다. IWasteMore는 상수 버퍼의 13번째 float4 또는 52번째 float에 배치됩니다.