Penautan Shader Efek

Direct2D menggunakan pengoptimalan yang disebut penautan shader efek yang menggabungkan beberapa efek grafik penyajian lolos ke dalam satu pass.

Gambaran Umum Penautan Shader Efek

Efek pengoptimalan penautan shader dibangun di atas penautan shader HLSL, fitur Direct3D 11.2 yang memungkinkan shader piksel dan verteks dihasilkan pada runtime dengan menautkan fungsi shader yang telah dikompilasi sebelumnya. Gambar berikut mengilustrasikan konsep penautan shader efek dalam grafik efek. Gambar pertama menunjukkan grafik efek Direct2D yang khas dengan empat transformasi penyajian. Tanpa penautan shader, setiap transformasi mengonsumsi kode penyajian dan membutuhkan permukaan perantara; secara total, grafik ini membutuhkan 4 pass dan 3 perantara.

mengubah grafik tanpa penautan shader: 4 pass dan 3 perantara.

Gambar kedua menunjukkan grafik efek yang sama di mana setiap transformasi penyajian telah diganti dengan versi fungsi yang dapat ditautkan. Direct2D dapat menautkan seluruh grafik dan menjalankannya dalam satu pass tanpa memerlukan perantara apa pun. Hal ini dapat memberikan penurunan waktu eksekusi GPU yang signifikan dan pengurangan konsumsi memori GPU puncak.

mengubah grafik dengan penautan shader: 1 pass, 0 perantara.

 

Penautan shader efek beroperasi pada transformasi individu dalam efek; ini berarti bahwa bahkan grafik dengan efek tunggal dapat memperoleh manfaat dari penautan shader jika efek tersebut memiliki beberapa transformasi yang valid.

Menggunakan Penautan Efek Shader

Jika Anda membangun aplikasi Direct2D yang menggunakan efek, Anda tidak perlu melakukan apa pun untuk memanfaatkan penautan shader efek. Direct2D secara otomatis menganalisis grafik efek untuk menentukan cara paling optimal untuk menautkan setiap transformasi.

Penulis efek bertanggung jawab untuk menerapkan efeknya dengan cara yang mendukung penautan shader efek; untuk informasi selengkapnya, lihat bagian Penulisan efek kustom yang kompatibel dengan penautan shader di bawah ini. Semua efek bawaan mendukung penautan shader.

Direct2D hanya akan menautkan transformasi penyajian yang berdekatan dalam situasi yang bermanfaat. Ini memperhitungkan beberapa faktor saat menentukan apakah akan menautkan dua transformasi. Misalnya, penautan shader tidak dilakukan jika salah satu transformasi menggunakan vertex atau shader komputasi, karena hanya shader piksel yang dapat ditautkan. Selain itu, jika efek tidak ditulis agar kompatibel dengan penautan shader, maka transformasi di sekitarnya tidak akan ditautkan dengannya.

Dalam kasus bahwa bahaya penautan seperti itu ada, Direct2D tidak akan menghubungkan transformasi apa pun yang berdekatan dengan bahaya, tetapi masih akan mencoba untuk menautkan sisa grafik.

mengubah grafik dengan bahaya penautan: 2 lolos, 1 menengah.

Menulis efek kustom yang kompatibel dengan penautan shader

Jika Anda menulis efek Direct2D kustom Anda sendiri, Anda perlu memastikan bahwa transformasinya mendukung penautan shader efek. Ini membutuhkan beberapa perubahan kecil dari bagaimana efek kustom sebelumnya diterapkan. Jika transformasi dalam efek kustom Anda tidak mendukung penautan shader, Maka Direct2D tidak akan menautkannya dengan transformasi apa pun yang berdekatan dengannya dalam grafik efek.

Sebagai penulis efek kustom, Anda harus mengetahui beberapa konsep dan persyaratan utama:

  • Tidak ada perubahan pada implementasi antarmuka efek

    Anda tidak perlu mengubah kode apa pun yang mengimplementasikan berbagai antarmuka efek seperti ID2D1DrawTransform.

  • Menyediakan shader versi fungsi penuh dan ekspor

    Anda harus menyediakan versi fungsi ekspor dari shader efek Anda yang dapat ditautkan oleh Direct2D. Selain itu, Anda juga harus terus menyediakan shader asli dan penuh; ini karena Direct2D memilih pada runtime versi shader yang tepat tergantung pada apakah penautan shader akan diterapkan ke tautan tertentu dalam grafik.

    Jika transformasi hanya menyediakan blob shader piksel penuh (melalui ID2D1EffectContext::LoadPixelShader), itu tidak akan ditautkan ke transformasi yang berdekatan.

  • Fungsi pembantu

    Direct2D menyediakan fungsi pembantu dan makro HLSL yang akan secara otomatis menghasilkan versi fungsi penuh dan ekspor shader. Pembantu ini dapat ditemukan di d2d1effecthelpers.hlsli. Selain itu, pengkompilasi HLSL (FXC) memungkinkan Anda memasukkan shader fungsi ekspor ke bidang privat di shader penuh. Dengan cara ini, Anda hanya perlu menulis shader sekali dan meneruskan kedua versi ke Direct2D secara bersamaan. Baik d2d1effecthelpers.hlsli dan pengkompilasi FXC disertakan sebagai bagian dari Windows SDK.

    Fungsi pembantu:

    Anda juga dapat menulis dua versi setiap shader secara manual dan mengkompilasinya dua kali, selama spesifikasi yang dijelaskan di bawah ini dalam Spesifikasi fungsi Ekspor terpenuhi.

  • Hanya shader piksel

    Direct2D tidak mendukung penautan shader komputasi atau vertex. Namun, jika efek Anda menggunakan vertex dan shader piksel, output shader piksel masih dapat ditautkan.

  • Pengambilan sampel sederhana versus kompleks

    Penautan fungsi shader berfungsi dengan menyambungkan output dari satu shader piksel yang diteruskan ke input pass shader piksel berikutnya. Ini hanya dimungkinkan ketika shader piksel yang mengonsumsi hanya memerlukan satu nilai input untuk melakukan komputasinya; nilai ini biasanya berasal dari pengambilan sampel tekstur input pada koordinat tekstur yang dipancarkan oleh shader vertex. Shader piksel seperti itu dikatakan melakukan pengambilan sampel sederhana.

    konversi skala abu-abu adalah contoh pengambilan sampel sederhana. nilai piksel output tertentu hanya bergantung pada nilai piksel input yang sesuai.

    Beberapa shader piksel, seperti kabur Gaussian, menghitung outputnya dari beberapa sampel input, bukan hanya satu sampel. Shader piksel seperti itu dikatakan melakukan pengambilan sampel yang kompleks.

    kabur gaussian adalah contoh pengambilan sampel yang kompleks. nilai piksel output tengah bergantung pada beberapa piksel input.

    Hanya fungsi shader dengan input sederhana yang dapat memiliki input yang disediakan oleh fungsi shader lain. Fungsi shader dengan input kompleks harus disediakan dengan tekstur input untuk sampel. Ini berarti bahwa Direct2D tidak akan menautkan shader dengan input kompleks ke pendahulunya.

    Saat menggunakan pembantu Direct2D HLSL, Anda harus menunjukkan di HLSL apakah shader menggunakan input yang kompleks atau sederhana.

Contoh shader efek yang kompatibel dengan penautan

Menggunakan pembantu D2D, cuplikan kode berikut mewakili shader efek yang kompatibel dengan penautan sederhana:

#define D2D_INPUT_COUNT 1
#define D2D_INPUT0_SIMPLE
#include “d2d1effecthelpers.hlsli”

D2D_PS_ENTRY(LinkingCompatiblePixelShader)
{
    float4 input = D2DGetInput(0);
    input.rgb *= input.a;
    return input;
}          

Dalam contoh singkat ini, perhatikan bahwa tidak ada parameter fungsi yang dideklarasikan, bahwa jumlah input dan jenis setiap input dideklarasikan sebelum fungsi entri, input diambil dengan memanggil D2DGetInput, dan arahan praproscesor tersebut harus ditentukan sebelum file pembantu disertakan.

Shader yang kompatibel dengan penautan harus menyediakan shader piksel sekali pakai biasa dan fungsi shader ekspor. Makro D2D_PS_ENTRY memungkinkan masing-masing dibuat dari kode yang sama, ketika digunakan bersama dengan skrip kompilasi shader.

Saat mengkompilasi shader penuh, makro diperluas ke dalam kode berikut, yang memiliki tanda tangan input yang kompatibel dengan Efek D2D.

Texture2D<float4> InputTexture0;
SamplerState InputSampler0;

float4 LinkingCompatiblePixelShader(
    float4 pos   : SV_POSITION,
    float4 posScene : SCENE_POSITION,
    float4 uv0  : TEXCOORD0
    ) : SV_Target
    {
        float4 input = InputTexture0.Sample(InputSampler0, uv0.xy);
        input.rgb *= input.a;
        return input;
    }    

Saat mengkompilasi versi fungsi ekspor dari kode yang sama, kode berikut dihasilkan:

// Shader function version
export float4 LinkingCompatiblePixelShader_Function(
    float4 input0 : INPUT0)
    {
        input.rgb *= input.a;
        return input;
    }      

Perhatikan bahwa input tekstur, biasanya diambil dengan mengambil sampel Texture2D, telah diganti dengan input fungsi (input0).

Untuk melihat deskripsi lengkap langkah demi langkah tentang apa yang perlu Anda lakukan untuk menulis efek yang kompatibel dengan penautan, lihat tutorial Efek kustom dan sampel efek gambar kustom Direct2D.

Mengkompilasi penautan kompatibel-shader

Agar dapat ditautkan, blob shader piksel yang diteruskan ke D2D harus berisi versi fungsi penuh dan ekspor shader. Ini dicapai dengan menyematkan fungsi ekspor yang dikompilasi ke area D3D_BLOB_PRIVATE_DATA.

Ketika shader ditulis dengan fungsi pembantu D2D, target kompilasi D2D harus ditentukan pada waktu kompilasi. Jenis target kompilasi D2D_FULL_SHADER dan D2D_FUNCTION.

Mengkompilasi shader efek yang kompatibel dengan penautan adalah proses dua langkah:

Catatan

Saat mengkompilasi efek menggunakan Visual Studio, Anda harus membuat file batch yang menjalankan perintah FXC dan menjalankan file batch ini sebagai langkah build kustom yang berjalan sebelum langkah kompilasi.

 

Langkah 1: Mengkompilasi fungsi ekspor

fxc /T <shadermodel> <MyShaderFile>.hlsl /D D2D_FUNCTION /D D2D_ENTRY=<entry> /Fl <MyShaderFile>.fxlib           

Untuk mengkompilasi versi fungsi ekspor shader, Anda harus meneruskan bendera berikut ke FXC.

Bendera Deskripsi
/T <ShaderModel> Atur <ShaderModel> ke profil shader piksel yang sesuai seperti yang didefinisikan dalam Sintaks FXC. Ini harus menjadi salah satu profil yang tercantum di bawah "Penautan shader HLSL".
<MyShaderFile.hlsl> Atur <MyShaderFile> ke nama file HLSL.
/D D2D_FUNCTION Definisi ini menginstruksikan FXC untuk mengkompilasi versi fungsi ekspor shader.
/D D2D_ENTRY=<entry> Atur <entri> ke nama titik entri HLSL yang Anda tentukan di dalam makro D2D_PS_ENTRY .
/Fl <MyShaderFile.fxlib> Atur <MyShaderfile> ke tempat Anda ingin menyimpan versi fungsi ekspor shader. Perhatikan bahwa ekstensi .fxlib hanya untuk kemudahan identifikasi.

Langkah 2: Kompilasi shader penuh dan sematkan fungsi ekspor

fxc /T ps_<shadermodel> <MyShaderFile>.hlsl /D D2D_FULL_SHADER /D D2D_ENTRY=<entry> /E <entry> /setprivate <MyShaderFile>.fxlib /Fo <MyShader>.cso /Fh <MyShader>.h           

Untuk mengkompilasi versi lengkap shader Anda dengan versi ekspor yang disematkan, Anda harus meneruskan bendera berikut ke FXC.

Bendera Deskripsi
/T <ShaderModel> Atur <ShaderModel> ke profil shader piksel yang sesuai seperti yang didefinisikan dalam Sintaks FXC. Ini harus menjadi profil shader piksel yang sesuai dengan profil penautan yang ditentukan di Langkah 1.
<MyShaderFile.hlsl> Atur <MyShaderFile> ke nama file HLSL.
/D D2D_FULL_SHADER Definisi ini menginstruksikan FXC untuk mengkompilasi versi lengkap shader.
/D D2D_ENTRY=<entry> Atur <entri> ke nama titik entri HLSL yang Anda tentukan di dalam makro D2D_PS_ENTRY().
Entri /E <> Atur <entri> ke nama titik entri HLSL yang Anda tentukan di dalam makro D2D_PS_ENTRY().
/setprivate <MyShaderFile.fxlib> Argumen ini menginstruksikan FXC untuk menyematkan shader fungsi ekspor yang dihasilkan pada langkah 1 ke area D3D_BLOB_PRIVATE_DATA.
/Fo <MyShader.cso> Atur <MyShader> ke tempat Anda ingin menyimpan shader gabungan final.
/Fh <MyShader.h> Atur <MyShader> ke tempat Anda ingin menyimpan header gabungan akhir.

Mengekspor spesifikasi fungsi

Dimungkinkan - meskipun tidak disarankan - untuk menulis shader efek yang kompatibel tanpa menggunakan pembantu yang disediakan D2D. Perawatan harus dilakukan untuk memastikan bahwa shader penuh dan tanda tangan input fungsi ekspor sesuai dengan spesifikasi D2D.

Spesifikasi untuk shader penuh sama dengan versi Windows sebelumnya. Secara singkat, parameter input shader piksel harus SV_POSITION, SCENE_POSITION, dan satu INPUT TEXCOORD per efek.

Untuk fungsi ekspor, fungsi harus mengembalikan float4 dan inputnya harus merupakan salah satu jenis berikut:

  • Input sederhana

    float4 d2d_inputN : INPUTN         
    

    Untuk input sederhana, D2D akan menyisipkan fungsi Sampel antara tekstur input dan fungsi shader, atau input akan disediakan oleh output dari fungsi shader lain.

  • Input kompleks

    float4 d2d_uvN  : TEXCOORDN                
    

    Untuk input kompleks, D2D hanya akan meneruskan koordinat tekstur seperti yang dijelaskan dalam dokumentasi Windows 8.

  • Lokasi keluaran

    float4 d2d_posScene : SCENE_POSITION                
    

    Hanya satu input SCENE_POSITION yang dapat didefinisikan. Parameter ini hanya boleh disertakan jika perlu, karena hanya satu fungsi per shader tertaut yang dapat menggunakan parameter ini.

Semantik harus didefinisikan seperti di atas, karena D2D akan memeriksa semantik untuk memutuskan cara menautkan fungsi bersama-sama. Jika ada input fungsi yang tidak cocok dengan salah satu jenis di atas, fungsi akan ditolak untuk penautan shader.

Pembantu HLSL

Antarmuka ID3D11Linker

Antarmuka ID3D11FunctionLinkingGraph