Zincirleri Değiştir

Swap chain’ler, arka tampon rotasyonunu denetler ve grafik animasyonunun temelini oluşturur.

Genel bakış

Direct3D 12'deki değiştirme zincirleri için programlama modeli, D3D'nin önceki sürümlerindekiyle aynı değildir. Örneğin, D3D10 ve D3D11'de mevcut olan otomatik kaynak döndürmeyi desteklemeye yönelik programlama kolaylığı artık desteklenmedi. Otomatik kaynak döndürme özelliği etkinleştirilmiş uygulamalar aynı API nesnesini işlerken, işlenen gerçek yüzey her çerçeveyi değiştirir. Direct3D 12'nin diğer özelliklerinin düşük CPU ek yüküne sahip olmasını sağlamak için değiştirme zincirlerinin davranışı Direct3D 12 ile değiştirilir. Otomatik renk tuşu ve çoklu örnekleme desteklenmez, ancak özellikle esnetme ve döndürme hala desteklenmektedir.

Arabellek ömrü

Uygulamalara back buffer'lara başvuran önceden oluşturulmuş tanımlayıcıları depolama izni verilir. Bu, bir değiştirme zincirine ait arabellek kümesinin, değiştirme zinciri süresince hiç değişmemesini sağlayarak etkinleştirilir. IDXGISwapChain::GetBuffer tarafından döndürülen arabellek kümesi, belirli API'ler çağrılana kadar değişmez:

GetBuffer tarafından döndürülen arabelleklerin sırası hiçbir zaman değişmez.

IDXGISwapChain3::GetCurrentBackBufferIndex geçerli geri arabelleğinin dizinini uygulamaya döndürür.

Değişim efektleri

Desteklenen tek değiştirme efektleri, arabellek sayısının birden fazla olmasını gerektiren DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL ve DXGI_SWAP_EFFECT_FLIP_DISCARD'dır.

Tip

Minimum girdi gecikmesini hedefleyen oyunlar için takas zincirini DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING ile oluşturun, ardından Present(0, DXGI_PRESENT_ALLOW_TEARING) çağrısını yapın. Bu, birleştiricinin vsync'ini baypas eder ve sunumdan ekranda gösterime kadar olan gecikmeyi en aza indirir. Çalışma zamanında, bu yolu kullanmadan önce IDXGIFactory5::CheckFeatureSupportkomutunu DXGI_FEATURE_PRESENT_ALLOW_TEARING çağırarak yırtılma desteğini doğrulayın.

Warning

Yaygın bir kare zamanlaması hatası, CPU işini GPU fence’i ile düzgün şekilde senkronize etmeden Present(1, 0) (vsync-on) çağrılmasıdır. Bu, CPU'nın önceden çalışmasına ve giriş gecikme süresini artıran bir çerçeve kuyruğu oluşturmasına neden olur. Uçuştaki CPU çerçevelerini sınırlamak için her zaman bir çerçeve sayısı çiti kullanın (genellikle arabellek sayısı eksi bir ile).

Pencereli ve tam ekran modları arasında geçiş yapma

Direct3D 12, tam ekran özel kullanım modunu (FSE) desteklemez. Bunun yerine, ekranda görünen tek uygulama bir oyun olduğunda işletim sistemi, performans dezavantajları olmadan FSE'ye benzer bir etki elde etmek için tam ekran optimizasyonu (FSO) adlı bir strateji kullanır. FSO hakkında daha fazla bilgi için bkz. Tam Ekran İyileştirmelerini Açıklama.

Direct3D 12, uygulamaların pencereli ve tam ekran modları arasında geçiş yaptıktan sonra ResizeBuffers çağırması gereken kısıtlamayı korur (D3D11 flip-model takas zincirleri aynı kısıtlamalara sahiptir).

IDXGISwapChain::SetFullscreenState geçişleri, değiştirme zincirindeki uygulama tarafından görünen arabellek kümesini değiştirmez. Yalnızca ResizeBuffers ve ResizeTarget çağrıları uygulama tarafından görünen arabellekleri oluşturur veya yok eder. Ancak, Direct3D 12 IDXGISwapChain::SetFullscreenState tam ekran özel moda girmez ve tam ekran iyileştirmelerine izin vermek için çözünürlükleri ve yenileme hızlarını değiştirir. Bu değişiklikler, bu yöntem kullanılmadan bir uygulama tarafından yapılabilir

IDXGISwapChain::Present veya IDXGISwapChain1::Present çağrıldığında, sunulacak arka arabellek D3D12_RESOURCE_STATE_PRESENT durumunda olmalıdır. Böyle bir durum söz konusu değilse, Present DXGI_ERROR_INVALID_CALL ile başarısız olur.

Tam ekran swap zincirleri, swap zinciri son kez serbest bırakılmadan önce SetFullscreenState(FALSE, NULL) çağrılmasının gerekmesi kısıtlamasına tabi olmaya devam eder. SetFullscreenState(FALSE), Direct3D 12 cihazlarında çalışan takas zincirlerinde başarılı olur.

Mevcut işlemler, takas zinciri oluşturma sırasında sağlanan 3B kuyrukta gerçekleşir ve uygulamalar birden çok takas zincirini eşzamanlı olarak sunabilir ve komut listelerini kaydedip yürütebilir.

Grafik işlemlerinin son kısmı bir hesaplama kuyruğunda gerçekleştirildiğinde (örneğin, kare son işleme) veya cihazın grafik kuyruğunu içermediğinde, üzerinde sunum yapılacak ikinci bir 3B kuyruğu oluşturmak faydalı olabilir ve sunum gecikmesinin bir sonraki karenin başlangıcını geciktirmesini önleyebilir.

Örnek

Aşağıdaki örnek kod, ana işleme döngüsünde mevcut olacaktır:

Warning

Aşağıdaki örnek netlik için basitleştirilmiştir. Prodüksiyon düzeyindeki bir oyun döngüsü, simülasyon güncellemelerini render alma sıklığından ayırmalıdır; örneğin, simülasyon için sabit bir zaman adımı kullanıp görüntüyü mümkün olduğunca hızlı oluşturmalı ve işlem hattındaki kare sayısını sınırlamak için bir fence kullanmalıdır. Uçuşta olan kare sayısı sınırlandırılmadığında, Present flip-model swap chain’lerde hemen başarılı olabilir; bu da CPU’nun kareleri sınırsız biçimde sıraya koymasına ve giriş gecikmesini artırmasına yol açar.

void Present()
{
    m_swapChain->Present(0, m_presentFlags);
    m_backBufferIndex = (m_backBufferIndex + 1) % m_backBufferCount;
}

Takas zincirleri oluşturma

CreateSwapChainForHwnd, CreateSwapChainForCoreWindow veya CreateSwapChainForComposition çağrılarını kullanırken, pDevice parametresinin aslında bir aygıtı değil, Direct3D 12'de doğrudan komut kuyruğuna işaret eden bir işaretçi gerektirdiğini unutmayın.

Windows 7'de sunum yapma

Windows 7’de Direct3D 12 hedeflenirken, Direct3D 12 için gerekli DXGI türleri bulunmadığından, sunum yapmak için D3D12On7 tarafından sağlanan ID3D12CommandQueueDownLevel arabirimini (doğrudan komut kuyruğundan sorgulanan) kullanmanız gerekir.

Windows 7 present yöntemine açık bir komut listesi sağlarsınız; bu liste daha sonra kullanılır, kapatılır ve sizin için cihaza otomatik olarak gönderilir. Uygulama tarafından oluşturulmuş, bağlı bir kaynak olan, tek örnekli ve aşağıdaki biçimlerden biri olan bir arka arabellek sağlamanız gerekir.

  • DXGI_FORMAT_R16G16B16A16_FLOAT
  • DXGI_FORMAT_R10G10B10A2_UNORM
  • DXGI_FORMAT_R8G8B8A8_UNORM
  • DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
  • DXGI_FORMAT_B8G8R8X8_UNORM
  • DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM
  • DXGI_FORMAT_B8G8R8A8_UNORM
  • DXGI_FORMAT_B8G8R8A8_UNORM_SRGB