Diligent Core adalah API grafis tingkat rendah lintas platform modern yang menjadi fondasi Diligent Engine. Modul ini mengimplementasikan backend rendering Direct3D11, Direct3D12, OpenGL, OpenGLES, dan Vulkan (implementasi Metal tersedia untuk klien komersial), serta utilitas dasar khusus platform. Itu mandiri dan dapat dibangun sendiri. Silakan merujuk ke repositori utama untuk informasi tentang platform dan fitur yang didukung, instruksi pembuatan, dll.
Platform | Membangun Status |
---|---|
Menang32 | |
Jendela Universal | |
Linux | |
Android | |
macOS | |
iOS | |
TVOS | |
Ditulis |
Mengkloning Repositori
Dasar-dasar API
Tata Letak Sumber Daya Alur
Menang32
Platform Windows Universal
Linux
macOS
Android
iOS
Ditulis
Menghancurkan Mesin
Menginisialisasi Mesin
Menciptakan Sumber Daya
Membuat Shader
Menginisialisasi Status Pipa
Mengikat Sumber Daya Shader
Mengatur Status Pipeline dan Memanggil Perintah Draw
Interoperabilitas API tingkat rendah
Petunjuk pembuatan paket NuGet
Lisensi
Berkontribusi
Riwayat Rilis
Untuk mendapatkan repositori dan semua submodul, gunakan perintah berikut:
git clone --recursive https://github.com/DiligentGraphics/DiligentCore.git
Untuk membangun modul, lihat instruksi pembangunan di repositori master.
Sebelum Anda dapat menggunakan fungsionalitas apa pun yang disediakan oleh mesin, Anda perlu membuat perangkat render, konteks langsung, dan rantai pertukaran.
Pada platform Win32, Anda dapat membuat perangkat OpenGL, Direct3D11, Direct3D12 atau Vulkan seperti yang ditunjukkan di bawah ini:
batal InisialisasiDiligentEngine(HWND NativeWindowHandle) { SwapChainDesc SCDesc;// RefCntAutoPtr<IRenderDevice> m_pDevice;// RefCntAutoPtr<IDeviceContext> m_pImmediateContext;// RefCntAutoPtr<ISwapChain> m_pSwapChain;switch (m_DeviceType) {kasus RENDER_DEVICE_TYPE_D3D11: { MesinD3D11Buat Mesin InfoCI; # if ENGINE_DLL// Muat dll dan import GetEngineFactoryD3D11() functionauto* GetEngineFactoryD3D11 = LoadGraphicsEngineD3D11(); # endifauto* pFactoryD3D11 = GetEngineFactoryD3D11(); pFactoryD3D11->CreateDeviceAndContextsD3D11(EngineCI, &m_pDevice, &m_pImmediateContext); Jendela Win32NativeWindow{hWnd}; pFactoryD3D11->BuatSwapChainD3D11(m_pDevice, m_pImmediateContext, SCDesc, FullScreenModeDesc{}, Jendela, &m_pSwapChain); }pecah;kasus RENDER_DEVICE_TYPE_D3D12: { # if ENGINE_DLL// Muat dll dan import GetEngineFactoryD3D12() functionauto GetEngineFactoryD3D12 = LoadGraphicsEngineD3D12(); # endifEngineD3D12CreateInfo EngineCI;otomatis* pFactoryD3D12 = GetEngineFactoryD3D12(); pFactoryD3D12->CreateDeviceAndContextsD3D12(EngineCI, &m_pDevice, &m_pImmediateContext); Jendela Win32NativeWindow{hWnd}; pFactoryD3D12->BuatSwapChainD3D12(m_pDevice, m_pImmediateContext, SCDesc, FullScreenModeDesc{}, Jendela, &m_pSwapChain); }pecah;kasus RENDER_DEVICE_TYPE_GL: { # if EXPLICITLY_LOAD_ENGINE_GL_DLL// Muat dll dan import GetEngineFactoryOpenGL() functionauto GetEngineFactoryOpenGL = LoadGraphicsEngineOpenGL(); # endifauto* pFactoryOpenGL = GetEngineFactoryOpenGL(); MesinGLBuatInfo MesinCI; EngineCI.Window.hWnd = hWnd; pFactoryOpenGL->CreateDeviceAndSwapChainGL(EngineCI, &m_pDevice, &m_pImmediateContext, SCDesc, &m_pSwapChain); }pecah;kasus RENDER_DEVICE_TYPE_VULKAN: { # if EXPLICITLY_LOAD_ENGINE_VK_DLL// Muat dll dan import GetEngineFactoryVk() functionauto GetEngineFactoryVk = LoadGraphicsEngineVk(); # endifEngineVkCreateInfo EngineCI;otomatis* pFactoryVk = GetEngineFactoryVk(); pFactoryVk->CreateDeviceAndContextsVk(EngineCI, &m_pDevice, &m_pImmediateContext); Jendela Win32NativeWindow{hWnd}; pFactoryVk->CreateSwapChainVk(m_pDevice, m_pImmediateContext, SCDesc, Window, &m_pSwapChain); }rusak; bawaan: std::cerr << "Jenis perangkat tidak diketahui"; } }
Di Windows, mesin dapat ditautkan secara statis ke aplikasi atau dibuat sebagai DLL terpisah. Dalam kasus pertama, fungsi pabrik GetEngineFactoryOpenGL()
, GetEngineFactoryD3D11()
, GetEngineFactoryD3D12()
, dan GetEngineFactoryVk()
dapat dipanggil secara langsung. Dalam kasus kedua, Anda perlu memuat DLL ke dalam ruang alamat proses menggunakan fungsi LoadGraphicsEngineOpenGL()
, LoadGraphicsEngineD3D11()
, LoadGraphicsEngineD3D12()
, atau LoadGraphicsEngineVk()
. Setiap fungsi memuat perpustakaan dinamis yang sesuai dan mengimpor fungsi yang diperlukan untuk menginisialisasi mesin. Anda perlu menyertakan header berikut:
#include "EngineFactoryD3D11.h" #include "EngineFactoryD3D12.h" #include "EngineFactoryOpenGL.h" #include "EngineFactoryVk.h"
Anda juga perlu menambahkan direktori berikut ke jalur pencarian yang disertakan:
DiligentCore/Graphics/GraphicsEngineD3D11/interface
DiligentCore/Graphics/GraphicsEngineD3D12/interface
DiligentCore/Graphics/GraphicsEngineOpenGL/interface
DiligentCore/Graphics/GraphicsEngineVulkan/interface
Sebagai alternatif, Anda hanya dapat menambahkan jalur ke folder akar dan kemudian menggunakan jalur penyertaan yang terkait dengannya.
Aktifkan namespace Diligent
:
menggunakan namespace Rajin;
Fungsi IEngineFactoryD3D11::CreateDeviceAndContextsD3D11()
, IEngineFactoryD3D12::CreateDeviceAndContextsD3D12()
, dan IEngineFactoryVk::CreateDeviceAndContextsVk()
juga dapat membuat sejumlah konteks langsung dan tertunda tertentu, yang dapat digunakan untuk rendering asinkron dan perintah multi-utas rekaman. Konteks hanya dapat dibuat selama inisialisasi mesin. Fungsi ini mengisi array pointer ke konteks, dengan konteks langsung didahulukan, diikuti oleh semua konteks yang ditangguhkan.
Untuk lebih jelasnya, lihat file Tutorial00_HelloWin32.cpp.
Pada Platform Windows Universal, Anda dapat membuat perangkat Direct3D11 atau Direct3D12. Inisialisasi dilakukan dengan cara yang sama seperti pada Platform Win32. Perbedaannya adalah Anda terlebih dahulu membuat perangkat render dan konteks perangkat dengan memanggil IEngineFactoryD3D11::CreateDeviceAndContextsD3D11()
atau IEngineFactoryD3D12::CreateDeviceAndContextsD3D12()
. Rantai swap dibuat kemudian dengan panggilan ke IEngineFactoryD3D11::CreateSwapChainD3D11()
atau IEngineFactoryD3D12::CreateSwapChainD3D12()
. Silakan lihat file SampleAppUWP.cpp untuk lebih jelasnya.
Pada platform Linux, mesin mendukung backend OpenGL dan Vulkan. Inisialisasi konteks GL di Linux erat kaitannya dengan pembuatan jendela. Akibatnya, Diligent Engine tidak menginisialisasi konteksnya, namun melekat pada konteks yang diinisialisasi oleh aplikasi. Contoh inisialisasi mesin di Linux dapat dilihat di Tutorial00_HelloLinux.cpp.
Di MacOS, Diligent Engine mendukung backend OpenGL, Vulkan, dan Metal. Inisialisasi konteks GL di MacOS dilakukan oleh aplikasi, dan mesin melekat pada konteks yang dibuat oleh aplikasi; lihat GLView.mm untuk detailnya. Backend Vulkan diinisialisasi serupa dengan platform lain. Lihat MetalView.mm.
Di Android, Anda dapat membuat perangkat OpenGLES atau Vulkan. Cuplikan kode berikut menunjukkan contoh:
otomatis* pFactoryOpenGL = GetEngineFactoryOpenGL(); MesinGLBuatInfo MesinCI; EngineCI.Window.pAWindow = NativeWindowHandle; pFactoryOpenGL->BuatPerangkatDanSwapChainGL( EngineCI, &m_pDevice, &m_pContext, SCDesc, &m_pSwapChain);
Jika mesin dibuat sebagai perpustakaan dinamis, perpustakaan perlu dimuat oleh aktivitas asli. Kode berikut menunjukkan satu cara yang mungkin:
static{coba{System.loadLibrary("GraphicsEngineOpenGL"); } catch (UnsatisfiedLinkError e) {Log.e("aktivitas asli", "Gagal memuat perpustakaan GraphicsEngineOpenGL.n" + e); } }
Implementasi iOS mendukung backend OpenGLES, Vulkan dan Metal. Inisialisasi konteks GL di iOS dilakukan oleh aplikasi, dan mesin melekat pada konteks yang diinisialisasi oleh aplikasi; lihat EAGLView.mm untuk detailnya.
Di Emscripten, Anda dapat membuat perangkat OpenGLES. Cuplikan kode berikut menunjukkan contoh:
//Anda harus meneruskan id kanvas ke NativeWindowauto* pFactoryOpenGL = GetEngineFactoryOpenGL(); EngineGLCreateInfo EngineCI = {}; EngineCI.Window = NativeWindow{"#kanvas"}; pFactoryOpenGL->CreateDeviceAndSwapChainGL(EngineCI, &m_pDevice, &m_pContext, SCDesc, &m_pSwapChain);
Jika Anda menggunakan SDL atau GLFW dengan konteks yang ada, Anda dapat memberikan null sebagai pegangan jendela asli: EngineCI.Window = NativeWindow{nullptr}
Mesin melakukan penghitungan referensi otomatis dan mati ketika referensi terakhir ke objek mesin dilepaskan.
Sumber daya perangkat dibuat oleh perangkat render. Dua jenis sumber daya utama adalah buffer, yang mewakili memori linier, dan tekstur, yang menggunakan tata letak memori yang dioptimalkan untuk pemfilteran cepat. Untuk membuat buffer, Anda perlu mengisi struktur BufferDesc
dan memanggil IRenderDevice::CreateBuffer()
. Kode berikut membuat buffer seragam (konstan):
BufferDesc BuffDesc; BuffDesc.Name = "Buffer seragam"; BuffDesc.BindFlags = BIND_UNIFORM_BUFFER; BuffDesc.Usage = USAGE_DYNAMIC; BuffDesc.uiSizeInBytes = sizeof(ShaderConstants); BuffDesc.CPUAccessFlags = CPU_ACCESS_WRITE; m_pDevice->CreateBuffer(BuffDesc, nullptr, &m_pConstantBuffer);
Demikian pula, untuk membuat tekstur, isi struktur TextureDesc
dan panggil IRenderDevice::CreateTexture()
seperti pada contoh berikut:
TeksturDesc TexDesc; TexDesc.Name = "Tekstur saya 2D"; TexDesc.Type = TEXTURE_TYPE_2D; TexDesc.Lebar = 1024; TexDesc.Tinggi = 1024; TexDesc.Format = TEX_FORMAT_RGBA8_UNORM; TexDesc.Penggunaan = USAGE_DEFAULT; TexDesc.BindFlags = BIND_SHADER_RESOURCE | BIND_RENDER_TARGET | BIND_UNORDERED_ACCESS; TexDesc.Name = "Contoh Tekstur 2D"; m_pRenderDevice->CreateTexture(TexDesc, nullptr, &m_pTestTex);
Hanya ada satu fungsi CreateTexture()
yang mampu membuat semua jenis tekstur. Jenis, format, ukuran array, dan semua parameter lainnya ditentukan oleh anggota struktur TextureDesc
.
Untuk setiap flag pengikat yang ditentukan selama waktu pembuatan tekstur, objek tekstur akan membuat tampilan default. Tampilan sumber daya shader default menangani seluruh tekstur, tampilan target render default dan stensil kedalaman mereferensikan semua irisan array di tingkat mip paling detail, dan tampilan akses tidak berurutan mereferensikan seluruh tekstur. Untuk mendapatkan tampilan default dari tekstur, gunakan fungsi ITexture::GetDefaultView()
. Perhatikan bahwa fungsi ini tidak menambah penghitung referensi dari antarmuka yang dikembalikan. Anda dapat membuat tampilan tekstur tambahan menggunakan ITexture::CreateView()
. Gunakan IBuffer::CreateView()
untuk membuat tampilan buffer tambahan.
Untuk membuat shader, isi struktur ShaderCreateInfo
:
ShaderCreateInfo ShaderCI;
Ada tiga cara untuk membuat shader. Cara pertama adalah dengan memberikan pointer ke kode sumber shader melalui anggota ShaderCreateInfo::Source
. Cara kedua adalah dengan memberikan nama file. Cara ketiga adalah dengan memberikan pointer ke kode byte yang dikompilasi melalui anggota ShaderCreateInfo::ByteCode
. Graphics Engine sepenuhnya dipisahkan dari platform. Karena sistem file host bergantung pada platform, strukturnya memperlihatkan anggota ShaderCreateInfo::pShaderSourceStreamFactory
yang dimaksudkan untuk memberikan mesin akses ke sistem file. Jika Anda memberikan nama file sumber, Anda juga harus memberikan penunjuk non-null ke pabrik aliran sumber shader. Jika sumber shader berisi arahan #include
, pabrik aliran sumber juga akan digunakan untuk memuat file-file ini. Mesin ini menyediakan implementasi default untuk setiap platform yang didukung yang seharusnya cukup dalam banyak kasus. Namun Anda dapat menentukan penerapan Anda sendiri.
Anggota penting adalah ShaderCreateInfo::SourceLanguage
. Berikut ini adalah nilai yang valid untuk anggota ini:
SHADER_SOURCE_LANGUAGE_DEFAULT
- Format sumber shader cocok dengan API grafis yang mendasarinya: HLSL untuk mode D3D11 atau D3D12, dan GLSL untuk mode OpenGL, OpenGLES, dan Vulkan.
SHADER_SOURCE_LANGUAGE_HLSL
- Sumber shader ada di HLSL. Untuk mode OpenGL dan OpenGLES, kode sumber akan dikonversi ke GLSL. Di back-end Vulkan, kode akan dikompilasi ke SPIRV secara langsung.
SHADER_SOURCE_LANGUAGE_GLSL
- Sumber shader ada di GLSL.
SHADER_SOURCE_LANGUAGE_GLSL_VERBATIM
- Bahasa sumber shader adalah GLSL dan harus dikompilasi kata demi kata.
SHADER_SOURCE_LANGUAGE_MSL
- Bahasa sumbernya adalah Bahasa Bayangan Logam.
Anggota lain dari struktur ShaderCreateInfo
yang menentukan shader mencakup direktori pencarian, definisi makro shader, titik masuk shader, dan parameter lainnya.
Makro ShaderMacroHelper; Makro.AddShaderMacro("USE_SHADOWS", 1); Makro.AddShaderMacro("NUM_SHADOW_SAMPLES", 4); Makro.Finalize(); ShaderCI.Macros = Makro;
Ketika semuanya sudah siap, panggil IRenderDevice::CreateShader()
untuk membuat objek shader:
ShaderCreateInfo ShaderCI; ShaderCI.Desc.Name = "MyPixelShader"; ShaderCI.FilePath = "MyShaderFile.fx"; ShaderCI.EntryPoint = "PixelShader Saya"; ShaderCI.Desc.ShaderType = SHADER_TYPE_PIXEL; ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL;const auto* SearchDirectories = "shaders;shadersinc;"; RefCntAutoPtr<IShaderSourceInputStreamFactory> pShaderSourceFactory; m_pEngineFactory->CreateDefaultShaderSourceStreamFactory(SearchDirectories, &pShaderSourceFactory); ShaderCI.pShaderSourceStreamFactory = pShaderSourceFactory; RefCntAutoPtr<IShader> pShader; m_pDevice->BuatShader(ShaderCI, &pShader);
Diligent Engine mengikuti gaya Direct3D12/Vulkan untuk mengonfigurasi jalur grafis/komputasi. Satu Objek Status Saluran Pipa (PSO) monolitik mencakup semua status yang diperlukan (semua tahapan shader, deskripsi tata letak input, stensil kedalaman, rasterizer, dan deskripsi status campuran, dll.). Untuk membuat objek status pipeline grafis, tentukan instance struktur GraphicsPipelineStateCreateInfo
:
GrafisPipelineStateCreateInfo PSOCreateInfo; PipelineStateDesc& PSODesc = PSOCreateInfo.PSODesc; PSODesc.Name = "Status saluran pipa saya";
Jelaskan secara spesifik alur seperti jumlah dan format target render serta format stensil kedalaman:
// Ini adalah pipeline grafisPSODesc.PipelineType = PIPELINE_TYPE_GRAPHICS; PSOCreateInfo.GraphicsPipeline.NumRenderTargets = 1; PSOCreateInfo.GraphicsPipeline.RTVFormats[0] = TEX_FORMAT_RGBA8_UNORM_SRGB; PSOCreateInfo.GraphicsPipeline.DSVFormat = TEX_FORMAT_D32_FLOAT;
Inisialisasi deskripsi status stensil kedalaman DepthStencilStateDesc
. Perhatikan bahwa konstruktor menginisialisasi anggota dengan nilai default dan Anda hanya dapat menetapkan nilai yang berbeda dari nilai default.
// Init stensil kedalaman stateDepthStencilStateDesc& DepthStencilDesc = PSOCreateInfo.GraphicsPipeline.DepthStencilDesc; DepthStencilDesc.DepthEnable = benar; DepthStencilDesc.DepthWriteEnable = benar;
Inisialisasi deskripsi keadaan campuran BlendStateDesc
:
// Init campuran stateBlendStateDesc& BSDesc = PSOCreateInfo.GraphicsPipeline.BlendDesc; BSDesc.IndependentBlendEnable = False;auto &RT0 = BSDesc.RenderTargets[0]; RT0.BlendEnable = Benar; RT0.RenderTargetWriteMask = COLOR_MASK_ALL; RT0.SrcBlend = BLEND_FACTOR_SRC_ALPHA; RT0.DestBlend = BLEND_FACTOR_INV_SRC_ALPHA; RT0.BlendOp = BLEND_OPERATION_ADD; RT0.SrcBlendAlpha = BLEND_FACTOR_SRC_ALPHA; RT0.DestBlendAlpha = BLEND_FACTOR_INV_SRC_ALPHA; RT0.BlendOpAlpha = BLEND_OPERATION_ADD;
Inisialisasi deskripsi status rasterizer RasterizerStateDesc
:
// Init rasterizer stateRasterizerStateDesc& RasterizerDesc = PSOCreateInfo.GraphicsPipeline.RasterizerDesc; RasterizerDesc.FillMode = FILL_MODE_SOLID; RasterizerDesc.CullMode = CULL_MODE_NONE; RasterizerDesc.FrontCounterClockwise = Benar; RasterizerDesc.ScissorEnable = Benar; RasterizerDesc.AntialiasedLineEnable = Salah;
Inisialisasi deskripsi tata letak masukan InputLayoutDesc
:
// Tentukan input layoutInputLayoutDesc& Layout = PSOCreateInfo.GraphicsPipeline.InputLayout; LayoutElement LayoutElems[] = {LayoutElement( 0, 0, 3, VT_FLOAT32, False ),LayoutElement( 1, 0, 4, VT_UINT8, Benar ),LayoutElement( 2, 0, 2, VT_FLOAT32, False ), }; Layout.LayoutElements = LayoutElems; Tata Letak.NumElements = _countof(LayoutElems);
Tentukan topologi primitif dan atur pointer shader:
// Tentukan shader dan topologi primitifPSOCreateInfo.GraphicsPipeline.PrimitiveTopology = PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; PSOCreateInfo.pVS = m_pVS; PSOCreateInfo.pPS = m_pPS;
Tata letak sumber daya alur memberi tahu mesin bagaimana aplikasi akan menggunakan variabel sumber daya shader yang berbeda. Untuk memungkinkan pengelompokan sumber daya berdasarkan frekuensi perubahan pengikatan sumber daya yang diharapkan, Diligent Engine memperkenalkan klasifikasi variabel shader:
Variabel statis ( SHADER_RESOURCE_VARIABLE_TYPE_STATIC
) adalah variabel yang diharapkan disetel hanya satu kali. Mereka tidak dapat diubah setelah sumber daya terikat pada variabel. Variabel tersebut dimaksudkan untuk menyimpan konstanta global seperti atribut kamera atau buffer konstan atribut cahaya global. Perhatikan bahwa pengikatan sumber dayalah yang tidak boleh berubah, sedangkan konten sumber daya diperbolehkan berubah sesuai dengan penggunaannya.
Variabel yang dapat diubah ( SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE
) menentukan sumber daya yang diperkirakan akan berubah pada frekuensi per material. Contohnya mungkin termasuk tekstur yang menyebar, peta normal, dll. Sekali lagi pembaruan pada konten sumber daya bersifat ortogobal terhadap perubahan yang mengikat.
Variabel dinamis ( SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC
) diharapkan sering berubah dan acak.
Untuk menentukan tipe variabel, siapkan array struktur ShaderResourceVariableDesc
dan inisialisasi anggota PSODesc.ResourceLayout.Variables
dan PSODesc.ResourceLayout.NumVariables
. PSODesc.ResourceLayout.DefaultVariableType
juga dapat digunakan untuk mengatur tipe yang akan digunakan jika nama variabel tidak diberikan.
ShaderResourceVariableDesc ShaderVars[] = { {SHADER_TYPE_PIXEL, "g_StaticTexture", SHADER_RESOURCE_VARIABLE_TYPE_STATIC}, {SHADER_TYPE_PIXEL, "g_MutableTexture", SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE}, {SHADER_TYPE_PIXEL, "g_DynamicTexture", SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC} }; PSODesc.ResourceLayout.Variables = ShaderVars; PSODesc.ResourceLayout.NumVariables = _countof(ShaderVars); PSODesc.ResourceLayout.DefaultVariableType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC;
Saat membuat status pipeline, tekstur dapat ditetapkan secara permanen sebagai sampel yang tidak dapat diubah. Jika sampel yang tidak dapat diubah ditetapkan ke suatu tekstur, sampel tersebut akan selalu digunakan alih-alih sampel yang diinisialisasi dalam tampilan sumber daya shader tekstur. Untuk menentukan sampel yang tidak dapat diubah, siapkan array struktur ImmutableSamplerDesc
dan inisialisasi anggota PSODesc.ResourceLayout.ImmutableSamplers
dan PSODesc.ResourceLayout.NumImmutableSamplers
. Perhatikan bahwa sampler yang tidak dapat diubah dapat ditugaskan ke variabel tekstur jenis apa pun, tidak harus statis, sehingga pengikatan tekstur dapat diubah pada saat run-time, sementara sampler akan tetap tidak dapat diubah. Sangat disarankan untuk menggunakan sampler yang tidak dapat diubah bila memungkinkan.
ImmutableSamplerDesc ImtblSampler; ImtblSampler.ShaderStages = SHADER_TYPE_PIXEL; ImtblSampler.Desc.MinFilter = FILTER_TYPE_LINEAR; ImtblSampler.Desc.MagFilter = FILTER_TYPE_LINEAR; ImtblSampler.Desc.MipFilter = FILTER_TYPE_LINEAR; ImtblSampler.TextureName = "g_MutableTexture"; PSODesc.ResourceLayout.NumImmutableSamplers = 1; PSODesc.ResourceLayout.ImmutableSampler = &ImtblSampler;
Dokumen ini memberikan informasi rinci tentang bekerja dengan sampler tekstur.
Ketika semua bidang yang diperlukan pada struktur deskripsi PSO telah ditetapkan, panggil IRenderDevice::CreateGraphicsPipelineState()
untuk membuat objek PSO:
m_pDevice->CreateGraphicsPipelineState(PSOCreateInfo, &m_pPSO);
Seperti disebutkan di atas, pengikatan sumber daya shader di Diligent Engine didasarkan pada pengelompokan variabel dalam 3 kelompok berbeda (statis, bisa berubah, dan dinamis). Variabel statis adalah variabel yang diharapkan disetel hanya satu kali. Mereka tidak dapat diubah setelah sumber daya terikat pada variabel. Variabel tersebut dimaksudkan untuk menyimpan konstanta global seperti atribut kamera atau buffer konstan atribut cahaya global. Mereka terikat langsung ke Objek Status Pipa:
m_pPSO->GetStaticShaderVariable(SHADER_TYPE_PIXEL, "g_tex2DShadowMap")->Set(pShadowMapSRV);
Variabel yang dapat berubah dan dinamis terikat melalui objek baru yang disebut Shader Resource Binding (SRB), yang dibuat oleh status alur ( IPipelineState::CreateShaderResourceBinding()
), atau tanda tangan sumber daya alur dalam kasus penggunaan tingkat lanjut:
m_pPSO->BuatShaderResourceBinding(&m_pSRB, benar);
Parameter kedua memberitahu sistem untuk menginisialisasi struktur internal di objek SRB yang mereferensikan variabel statis di PSO.
Sumber daya yang dinamis dan dapat diubah kemudian diikat melalui objek SRB:
m_pSRB->GetVariable(SHADER_TYPE_PIXEL, "tex2DDiffuse")->Set(pDiffuseTexSRV); m_pSRB->GetVariable(SHADER_TYPE_VERTEX, "cbRandomAttribs")->Set(pRandomAttrsCB);
Perbedaan antara sumber daya yang bisa berubah dan dinamis adalah bahwa sumber daya yang bisa berubah hanya dapat disetel satu kali per contoh pengikatan sumber daya shader. Sumber daya dinamis dapat diatur beberapa kali. Penting untuk mengatur jenis variabel dengan benar karena hal ini mempengaruhi kinerja. Variabel statis dan bisa berubah lebih efisien. Variabel dinamis lebih mahal dan menimbulkan beberapa overhead run-time.
Cara alternatif untuk mengikat sumber daya shader adalah dengan membuat antarmuka IResourceMapping
yang memetakan nama literal sumber daya ke sumber daya sebenarnya:
Entri ResourceMappingEntry[] = { {"g_Texture", pTexture->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE)} }; ResourceMappingCreateInfo ResMappingCI; ResMappingCI.pEntries = Entri; ResMappingCI.NumEntries = _countof(Entri); RefCntAutoPtr<IResourceMapping> pResMapping; pRenderDevice->CreateResourceMapping(ResMappingCI, &pResMapping);
Pemetaan sumber daya kemudian dapat digunakan untuk mengikat semua sumber daya statis dalam keadaan pipa ( IPipelineState::BindStaticResources()
):
m_pPSO->BindStaticResources(SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, pResMapping, BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED);
atau semua sumber daya yang dapat diubah dan dinamis dalam pengikatan sumber daya shader ( IShaderResourceBinding::BindResources()
):
m_pSRB->BindResources(SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, pResMapping, BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED);
Parameter terakhir untuk semua fungsi BindResources()
menentukan cara penyelesaian sumber daya:
BIND_SHADER_RESOURCES_UPDATE_STATIC
- Menunjukkan bahwa pengikatan variabel statis harus diperbarui.
BIND_SHADER_RESOURCES_UPDATE_MUTABLE
- Menunjukkan bahwa pengikatan variabel yang dapat diubah harus diperbarui.
BIND_SHADER_RESOURCES_UPDATE_DYNAMIC
-Menunjukkan bahwa pengikatan variabel dinamis akan diperbarui.
BIND_SHADER_RESOURCES_UPDATE_ALL
- Menunjukkan bahwa semua tipe variabel (statis, bisa berubah, dan dinamis) harus diperbarui. Perhatikan bahwa jika tidak ada tanda BIND_SHADER_RESOURCES_UPDATE_STATIC
, BIND_SHADER_RESOURCES_UPDATE_MUTABLE
, dan BIND_SHADER_RESOURCES_UPDATE_DYNAMIC
yang disetel, semua tipe variabel akan diperbarui seolah-olah BIND_SHADER_RESOURCES_UPDATE_ALL
telah ditentukan.
BIND_SHADER_RESOURCES_KEEP_EXISTING
- Jika tanda ini ditentukan, hanya pengikatan yang belum terselesaikan yang akan diperbarui. Semua pengikatan yang ada akan mempertahankan nilai aslinya. Jika tanda ini tidak ditentukan, setiap variabel shader akan diperbarui jika pemetaan berisi sumber daya yang sesuai.
BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED
- Jika tanda ini ditentukan, semua pengikatan shader diharapkan dapat diselesaikan setelah panggilan. Jika hal ini tidak terjadi, kesalahan akan dilaporkan.
BindResources()
dapat dipanggil beberapa kali dengan pemetaan sumber daya berbeda untuk mengikat sumber daya. Namun, disarankan untuk menggunakan satu pemetaan sumber daya yang besar karena ukuran pemetaan tidak mempengaruhi waktu pencarian elemen.
Mesin melakukan pemeriksaan run-time untuk memverifikasi bahwa sumber daya yang benar telah diikat. Misalnya, jika Anda mencoba mengikat buffer konstan ke variabel tampilan sumber daya shader, kesalahan akan ditampilkan ke konsol debug.
Sebelum perintah draw apa pun dapat dipanggil, semua buffer simpul dan indeks yang diperlukan serta status pipeline harus terikat pada konteks perangkat:
// Tetapkan target render sebelum mengeluarkan perintah penarikan apa pun.auto* pRTV = m_pSwapChain->GetCurrentBackBufferRTV();auto* pDSV = m_pSwapChain->GetDepthBufferDSV(); m_pContext->SetRenderTargets(1, &pRTV, pDSV, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);// Hapus target render dan depth-stencilconst float zero[4] = {0, 0, 0, 0}; m_pContext->ClearRenderTarget(pRTV, ClearColor, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); m_pContext->ClearDepthStencil(pDSV, CLEAR_DEPTH_FLAG, 1.f, 0, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);// Mengatur buffer titik dan indeksIBuffer* buffer[] = {m_pVertexBuffer}; Uint32 offset[] = {0}; m_pContext->SetVertexBuffers(0, 1, buffer, offset, SET_VERTEX_BUFFERS_FLAG_RESET, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); m_pContext->SetIndexBuffer(m_pIndexBuffer, 0, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); m_pContext->SetPipelineState(m_pPSO);
Semua metode yang mungkin perlu melakukan transisi status sumber daya menggunakan RESOURCE_STATE_TRANSITION_MODE
enum sebagai parameter. Enum mendefinisikan mode berikut:
RESOURCE_STATE_TRANSITION_MODE_NONE
- Tidak melakukan transisi status sumber daya.
RESOURCE_STATE_TRANSITION_MODE_TRANSITION
- Transisi sumber daya ke status yang diperlukan oleh perintah.
RESOURCE_STATE_TRANSITION_MODE_VERIFY
- Jangan melakukan transisi, tetapi verifikasi bahwa statusnya benar.
Langkah terakhir adalah memasukkan sumber daya shader ke konteks perangkat. Hal ini dilakukan dengan metode IDeviceContext::CommitShaderResources()
:
m_pContext->CommitShaderResources(m_pSRB, COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES);
Jika metode ini tidak dipanggil, mesin akan mendeteksi bahwa sumber daya tidak dikomit dan mengeluarkan pesan debug. Perhatikan bahwa parameter terakhir memberitahu sistem untuk mentransisikan sumber daya ke status yang benar. Jika tanda ini tidak ditentukan, sumber daya harus secara eksplisit dialihkan ke status yang diperlukan melalui panggilan ke IDeviceContext::TransitionShaderResources()
:
m_pContext->TransitionShaderResources(m_pPSO, m_pSRB);
Perhatikan bahwa metode ini memerlukan penunjuk ke status alur yang membuat pengikatan sumber daya shader.
Ketika semua status dan sumber daya yang diperlukan terikat, IDeviceContext::DrawIndexed()
dapat digunakan untuk menjalankan perintah draw atau IDeviceContext::DispatchCompute()
dapat digunakan untuk menjalankan perintah komputasi. Perhatikan bahwa untuk perintah draw, alur grafis harus diikat, dan untuk perintah pengiriman, alur komputasi harus diikat. DrawIndexed()
menggunakan struktur DrawIndexedAttribs
sebagai argumen, misalnya:
DrawIndexedAttribs attr; attrs.IndexType = VT_UINT16; attrs.NumIndices = 36; attrs.Bendera = DRAW_FLAG_VERIFY_STATES; pContext->DrawIndexed(attrs);
Bendera DRAW_FLAG_VERIFY_STATES
menginstruksikan mesin untuk memverifikasi bahwa buffer simpul dan indeks yang digunakan oleh perintah draw dialihkan ke keadaan yang tepat.
DispatchCompute()
menggunakan struktur DispatchComputeAttribs
yang mendefinisikan dimensi grid komputasi:
m_pContext->SetPipelineState(m_pComputePSO); m_pContext->CommitShaderResources(m_pComputeSRB, COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES); DispatchComputeAttribs DispatchAttrs{64, 64, 8}; m_pContext->DispatchCompute(DispatchAttrs);
Anda dapat mempelajari lebih lanjut tentang API mesin dengan mempelajari contoh dan tutorial.
Diligent Engine secara ekstensif mendukung interoperabilitas dengan API tingkat rendah yang mendasarinya. Mesin dapat diinisialisasi dengan melampirkan ke perangkat D3D11/D3D12 yang ada atau konteks OpenGL/GLES dan menyediakan akses ke objek API asli yang mendasarinya. Lihat halaman berikut untuk informasi lebih lanjut:
Interoperabilitas Direct3D11
Interoperabilitas Direct3D12
Interoperabilitas OpenGL/GLES
Interoperabilitas Vulkan
Ikuti langkah-langkah berikut untuk membangun paket NuGet:
Instal paket Python yang diperlukan
python -m pip install -r ./BuildTools/.NET/requirements.txt
Jalankan skrip pembuatan paket NuGet, misalnya:
python ./BuildTools/.NET/dotnet-build-package.py -c Debug -d ./
Argumen | Keterangan | Diperlukan |
---|---|---|
-c ( configuration ) | Konfigurasi build perpustakaan dinamis asli (misalnya Debug, Rilis, dll.) | Ya |
-d ( root-dir ) | Jalur ke direktori root DiligentCore | Ya |
-s ( settings ) | Jalur ke file pengaturan | TIDAK |
dotnet-tests | Bendera yang menunjukkan apakah akan menjalankan pengujian .NET | TIDAK |
dotnet-publish | Bendera yang menunjukkan apakah akan menerbitkan paket ke Galeri NuGet | TIDAK |
free-memory | Gunakan argumen ini jika Anda mengalami kekurangan memori selama proses pembangunan | TIDAK |
Anda dapat mengganti pengaturan default menggunakan file pengaturan (periksa kamus default_settings
di dotnet-build-package.py
)
Lihat lisensi Apache 2.0.
Proyek ini memiliki beberapa ketergantungan pihak ketiga, yang masing-masing mungkin memiliki lisensi independen:
Vulkan-Headers: File Vulkan Header dan registri API (Lisensi Apache 2.0).
SPIRV-Cross: Alat penguraian dan kompilasi silang SPIRV (Lisensi Apache 2.0).
SPIRV-Headers: File header SPIRV (lisensi mirip Khronos MIT).
SPIRV-Tools: Alat optimasi dan validasi SPIRV (Lisensi Apache 2.0).
glslang: Kompiler referensi Khronos dan validator untuk GLSL, ESSL, dan HLSL (Lisensi 3-Klausul BSD, Lisensi 2-Klausul BSD, MIT, Lisensi Apache 2.0).
cahaya: Perpustakaan Wrangler Ekstensi OpenGL (perpustakaan grafis Mesa 3-D, lisensi mirip Khronos MIT).
volk: Meta loader untuk Vulkan API (lisensi mirip Arseny Kapoulkine MIT).
stb: perpustakaan domain publik file tunggal stb untuk C/C++ (Lisensi MIT atau domain publik).
googletest: Kerangka Pengujian dan Mocking Google (Lisensi "Baru" atau "Revisi" Klausul 3 BSD).
DirectXShaderCompiler: DirectX Shader Compiler berbasis LLVM/Clang (Lisensi Rilis LLVM).
DXBCChecksum: Algoritma komputasi DXBC Checksum oleh Tim Alat Pengembang AMD (MIT lincesne).
xxHash: Algoritme hash non-kriptografi yang sangat cepat (Lisensi 2-Klausul BSD).
Untuk menyumbangkan kode Anda, kirimkan Permintaan Tarik ke repositori ini. Diligent Engine didistribusikan di bawah lisensi Apache 2.0 yang menjamin bahwa konten dalam repositori DiligentCore bebas dari beban Kekayaan Intelektual. Dalam mengirimkan konten apa pun ke repositori ini, Anda melisensikan konten tersebut berdasarkan ketentuan yang sama, dan Anda setuju bahwa konten tersebut bebas dari klaim Kekayaan Intelektual apa pun dan Anda berhak melisensikannya berdasarkan ketentuan tersebut.
Diligent Engine menggunakan format dentang untuk memastikan gaya kode sumber yang konsisten di seluruh basis kode. Format ini divalidasi oleh CI untuk setiap permintaan penerapan dan penarikan, dan pembangunan akan gagal jika ditemukan masalah pemformatan kode. Silakan merujuk ke halaman ini untuk instruksi tentang cara mengatur format dentang dan pemformatan kode otomatis.
Lihat Riwayat Rilis
rajingrafis.com