나는 종종 그래픽을 다룰 때 많은 조기 최적화를하는 경향이 있습니다. 항상 따라야 할 몇 가지 원칙이 있습니다.
- D3D 구성 요소의 수를 최소로 유지하십시오. (렌더링 상태, 버퍼, 쉐이더 등)
- 꼭 필요한 경우에만 구성 요소를 바인딩하십시오. (미제 한 등)
- 구성 요소를 가능한 많이 전문화하십시오. (필요한 BindFlags 등 만 설정하십시오.)
이로 인해 생성 된 구성 요소 및 현재 파이프 상태를 관리하기위한 매우 정교한 래퍼를 만들 수있었습니다. 이것은 귀중한 개발 시간을 많이 소비 할뿐만 아니라 복잡성을 더합니다.
그리고 최악의 경우 : 나는 그것이 문제의 가치가 있는지조차 모릅니다.
내 최적화 고려 사항 중 일부는 이미 낮은 수준에서 구현되었을 수 있으며 CPU에 시간을 낭비하면서 복제하고 있습니다. 성능에 미치는 영향은 무시할 수 있으므로 다른 고려 사항은 완전히 불필요 할 수 있습니다.
그래서 내 질문은 :
- 위의 지침 중 어느 것이 유효하며 어느 정도까지 따라야합니까?
- GPU는 상태 변경을 어떻게 처리합니까?
- 사용하지 않은 상태를 변경하면 어떻게됩니까? 활성화되어있는 동안에는 드로우 콜이 없습니다.
- 다양한 구성 요소를 바인딩 할 때 실제로 성능이 저하되는 것은 무엇입니까?
- 다른 성능 고려 사항은 무엇입니까?
실제 한계에 도달 할 때까지 성능에 신경 쓰지 말아야한다는 말만하지 마십시오. 그것은 실제적인 관점에서 분명히 사실이지만, 나는 주로 이론에 관심이 있습니다. 나는 어떻게 든 최적의 그래픽 프레임 워크 를 구축해야한다는 충동에 맞서 싸울 필요 가 있으며 평범한 "조기 최적화 강의"로는 그렇게 할 수 없다고 생각합니다.
구성 요소 관리
현재 SlimDX를 관리되는 래퍼로 사용하여 C #에서 DirectX 11 응용 프로그램을 작성하고 있습니다. 매우 낮은 수준의 래퍼이며 현재 추상화가 위에 있습니다.
Direct3D 추상화를 사용할 때 몇 가지 명백한 장점이 있습니다. 환경 설정, 셰이더 로딩, 상수 설정 및 메시 그리기는 훨씬 간단하고 훨씬 적은 코드를 사용 합니다 . 또한 대부분의 구성 요소의 생성 및 폐기를 관리하므로 모든 곳에서 자동으로 재사용 할 수 있으며 메모리 누수를 거의 완전히 피합니다.
- 일반적으로 모든 그래픽 구성 요소와 리소스를 어떻게 관리합니까?
- 아래 예제와 비슷한 방법으로 관리 래퍼를 추천 할 수 있습니까?
다음은 현재 구현 예입니다. 나는 인터페이스에 매우 만족합니다. 그것은 내 요구에 충분한 유연성을 가지고 있으며 사용하고 이해하는 것이 매우 간단합니다.
// Init D3D environment
var window = new RenderForm();
var d3d = new Direct3D(window, GraphicsSettings.Default);
var graphics = new GraphicsManager(d3d.Device);
// Load assets
var mesh = GeometryPackage.FromFile(d3d, "teapot.gp");
var texture = Texture.FromFile(d3d, "bricks.dds");
// Render states
graphics.SetViewports(new Viewport(0, 0, 800, 600);
graphics.SetRasterizer(wireFrame: false, culling: CullMode.Back);
graphics.SetDepthState(depthEnabled: true, depthWriteEnabled: true);
graphics.SetBlendState(BlendMethod.Transparency);
// Input layout
graphics.SetLayout("effect.fx", "VS", "vs_4_0",
new InputElement("POSITION", 0, Format.R32G32B32_Float, 0),
new InputElement("TEXCOORD", 0, Format.R32G32_Float, 0)
);
// Vertex shader
graphics.SetShader(Shader.Vertex, "effect.fx", "VS", "vs_4_0");
graphics.SetConstants(Shader.Vertex, 0, 4, stream => stream.Write(wvpMatrix));
// Pixel shader
graphics.SetShader(Shader.Pixel, "effect.fx", "PS", "ps_4_0");
graphics.SetTexture(Shader.Pixel, 0, texture);
graphics.SetSampler(Shader.Pixel, 0, Sampler.AnisotropicWrap);
graphics.SetConstants(Shader.Pixel, 0, 1, stream => stream.Write(new Color4(1, 0, 1, 0);
d3d.Run(() =>
{
// Draw and present
d3d.BackBuffer.Clear(new Color4(1, 0, 0.5f, 1));
graphics.SetOutput(d3d.BackBuffer);
graphics.Draw(mesh);
d3d.Present();
}