PFND3DDDI_LOCKCB fungsi panggilan balik (d3dumddi.h)

Fungsi pfnLockCb mengunci alokasi dan mendapatkan penunjuk ke alokasi dari driver miniport tampilan atau manajer memori video.

Sintaks

PFND3DDDI_LOCKCB Pfnd3dddiLockcb;

HRESULT Pfnd3dddiLockcb(
  HANDLE hDevice,
  D3DDDICB_LOCK *unnamedParam2
)
{...}

Parameter

hDevice

Handel ke perangkat tampilan (konteks grafis).

unnamedParam2

pData [masuk, keluar]

Penunjuk ke struktur D3DDDICB_LOCK yang menjelaskan alokasi untuk dikunci.

Mengembalikan nilai

pfnLockCb mengembalikan salah satu nilai berikut:

Menampilkan kode Deskripsi
S_OK Alokasi berhasil dikunci.
D3DERR_NOTAVAILABLE Bukaan tidak tersedia.
D3DERR_WASSTILLDRAWING Alokasi masih digunakan untuk penyajian.
D3DDDIERR_CANTEVICTPINNEDALLOCATION Alokasi tidak dapat dikunci karena tidak tersedianya aperture yang mendesis dan ketidakmampuan untuk mengeluarkan alokasi karena disematkan.
E_OUTOFMEMORY pfnLockCb tidak dapat diselesaikan karena memori yang tidak mencukup (situasi ini terjadi ketika sistem berada dalam situasi memori yang sangat rendah dan tidak ada cukup ruang untuk mengalokasikan array halaman).
E_INVALIDARG Parameter divalidasi dan ditentukan salah.
D3DDDIERR_DEVICEREMOVED pfnLockCb tidak dapat menyebabkan manajer memori video dan driver miniport tampilan melakukan tindakan yang sesuai karena terjadi penghentian Plug and Play (PnP) atau peristiwa Deteksi dan Pemulihan Batas Waktu (TDR). Fungsi driver tampilan mode pengguna yang disebut pfnLockCb (biasanya, fungsi Lock atau ResourceMap ) harus mengembalikan kode kesalahan ini kembali ke runtime Direct3D.
Direct3D Versi 9 Catatan: Untuk informasi selengkapnya tentang mengembalikan kode kesalahan, lihat Mengembalikan Kode Kesalahan yang Diterima dari Fungsi Runtime.
Direct3D Versi 10 dan 11 Catatan: Jika fungsi driver tidak mengembalikan nilai (yaitu, memiliki VOID untuk jenis parameter pengembalian), fungsi driver memanggil fungsi pfnSetErrorCb untuk mengirim kode kesalahan kembali ke runtime. Untuk informasi selengkapnya tentang menangani kode kesalahan, lihat Menangani Kesalahan.

Fungsi ini mungkin juga mengembalikan nilai HRESULT lainnya.

Keterangan

Driver tampilan mode pengguna dapat memanggil fungsi pfnLockCb runtime Microsoft Direct3D untuk mengunci alokasi dan mendapatkan pointer ke alokasi dari driver miniport tampilan atau manajer memori video. Driver tampilan mode pengguna biasanya memanggil pfnLockCb sebagai respons terhadap panggilan ke fungsi Lock atau ResourceMap (atau variasi ResourceMap lainnya seperti DynamicIABufferMapDiscard) untuk mengunci sumber daya atau permukaan dalam sumber daya. Sebelum kembali dari panggilan Kunci atau ResourceMap , driver tampilan mode pengguna harus terlebih dahulu memetakan sumber daya atau permukaan ke alokasi yang sesuai lalu memanggil pfnLockCb untuk mengunci alokasi. Alokasi harus dikunci sebelum dapat dibaca dari atau ditulis ke karena mengunci:

  • Menjamin bahwa rentang alamat virtual untuk alokasi tetap tidak berubah, valid, dapat dibaca, dan dapat ditulis selama durasi kunci. Manajer memori video memberikan jaminan ini.
  • Menyediakan cara untuk menyinkronkan operasi baca dan tulis alokasi dengan akses perangkat keras grafis dari alokasi. Manajer memori video dan driver miniport tampilan melakukan sinkronisasi.
Catatan Direct3D Versi 9:

Driver tampilan mode pengguna biasanya memanggil fungsi pfnLockCb dan pfnUnlockCb yang sesuai dengan setiap panggilan ke fungsi Kunci dan Buka Kuncinya , masing-masing, kecuali ketika driver menangani sumber daya di mana bendera bit-field Dinamis diatur dalam anggota Bendera dari struktur D3DDDIARG_CREATERESOURCE ketika sumber daya dibuat. Runtime sering meminta agar driver mengunci jenis sumber daya ini, sering kali dengan bendera bit-field NoOverwrite diatur dalam anggota Bendera dari struktur D3DDDIARG_LOCK . Karena data dalam sumber daya tersebut tidak boleh dimodifikasi (seperti yang ditunjukkan oleh NoOverwrite), memanggil pfnLockCb untuk setiap permintaan kunci menghabiskan waktu pemrosesan yang berlebihan. Untuk mencegah panggilan pfnLockCb untuk setiap permintaan kunci, driver dapat menyimpan penunjuk memori virtual yang dikembalikannya di anggota pSurfData D3DDDIARG_LOCK ketika fungsi Kunci dipanggil dengan set bendera bit-field NoOverwrite . Namun, driver dapat terus memanggil pfnLockCb setiap kali fungsi Kunci dipanggil dengan set bendera Buang bit-field atau tidak ada bendera yang ditetapkan.

Direct3D Versi 10 dan 11 Catatan:

Driver tampilan mode pengguna biasanya memanggil fungsi pfnLockCb dan pfnUnlockCb yang sesuai dengan setiap panggilan ke fungsi ResourceMap dan ResourceUnmap -nya (atau variasi lain dari fungsi-fungsi ini). Ini tidak terjadi ketika driver menangani sumber daya di mana nilai D3D10_DDI_USAGE_DYNAMIC diatur dalam anggota Penggunaan struktur D3D10DDIARG_CREATERESOURCE atau D3D11DDIARG_CREATERESOURCE saat sumber daya dibuat. Runtime sering meminta agar driver mengunci jenis sumber daya ini, sering kali dengan meneruskan nilai D3D10_DDI_MAP_WRITE_NOOVERWRITE ke parameter DDIMap dalam panggilan ke ResourceMap. Karena data dalam sumber daya tersebut tidak boleh dimodifikasi (seperti yang ditunjukkan oleh D3D10_DDI_MAP_WRITE_NOOVERWRITE), memanggil pfnLockCb untuk setiap permintaan kunci menggunakan waktu pemrosesan yang berlebihan. Untuk mencegah panggilan pfnLockCb untuk setiap permintaan kunci, driver dapat menyimpan penunjuk memori virtual yang dikembalikannya dalam parameter pMappedSubResource ketika fungsi ResourceMap-nya dipanggil dengan D3D10_DDI_MAP_WRITE_NOOVERWRITE. Namun, driver dapat terus memanggil pfnLockCb setiap kali fungsi ResourceMap-nya dipanggil dengan nilai D3D10_DDI_MAP_WRITE_DISCARD atau 0 diteruskan ke parameter DDIMap .

Meskipun aplikasi tidak memegang kunci yang luar biasa ke sumber daya yang terkait dengan penunjuk memori virtual, driver biasanya menghapus cache penunjuk memori virtual dengan memanggil fungsi pfnUnlockCb sebelum driver memanggil fungsi pfnRenderCb . Jika kunci tidak di-cache atau jika kunci tidak dapat di-uncach karena aplikasi masih mengunci sumber daya, perangkat keras mungkin dirender dari alokasi terkunci. Manajer memori video tidak dapat mendukung mode operasi ini jika alokasi berada dalam memori video lokal; oleh karena itu, manajer memori mengeluarkan alokasi ke sistem atau memori AGP ketika manajer memori mendeteksi situasi ini. Jika alokasi tidak didukung di segmen memori sistem atau AGP, manajer memori gagal melakukan panggilan ke pfnRenderCb dengan D3DDDIERR_CANTRENDERLOCKEDALLOCATION. Oleh karena itu, puncak dan alokasi buffer indeks yang dialokasikan sebagai respons terhadap pembuatan sumber daya di mana bendera bidang bit Dinamis diatur dalam anggota Bendera D3DDDIARG_CREATERESOURCE (atau nilai D3D10_DDI_USAGE_DYNAMIC diatur dalam anggota Penggunaan D3D10DDIARG_CREATERESOURCE atau D3D11DDIARG_CREATERESOURCE) harus didukung dalam segmen sistem atau AGP.

Mengatur bendera Buang bit-field di anggota BenderaD3DDDICB_LOCK dalam panggilan ke pfnLockCb menyebabkan manajer memori video membuat instans baru alokasi yang sedang dikunci. Manajer memori video mewakili instans baru dengan mengembalikan handel baru ke driver tampilan mode pengguna di anggota hAllocation D3DDDICB_LOCK.

Catatan Fungsi DxgkDdiCreateAllocation driver miniport tampilan tidak dipanggil ketika instans baru alokasi dibuat. Instans muncul ke driver miniport tampilan sebagai alokasi yang secara bersamaan dipaginasi ke beberapa lokasi yang berbeda.
 
Manajer memori video mungkin gagal kunci di mana bendera Buang bit-field diatur karena manajer memori video tidak dapat membuat instans baru atau menggunakan kembali instans alokasi yang ada. Ketika kegagalan ini terjadi, driver tampilan mode pengguna harus memanggil fungsi pfnRenderCb untuk membersihkan buffer perintah saat ini ke kernel. Flush buffer perintah ini mungkin menghentikan beberapa instans alokasi yang tidak dapat dikunci dengan menggunakan bendera Buang bit-field.

Setelah membersihkan buffer perintahnya, driver tampilan mode pengguna harus mencoba mengunci permukaan lagi dengan menggunakan bendera bit-field Buang dan NoExistingReference . Bendera bit-field NoExistingReference menunjukkan kepada manajer memori video bahwa driver saat ini tidak memiliki referensi ke instans alokasi apa pun yang sedang dikunci dalam buffer perintahnya. Manajer memori video kemudian dapat menggunakan kembali instans alokasi apa pun untuk menangani kunci, termasuk instans saat ini.

Setelah panggilan ke pfnLockCb tempat bendera Buang bit-field diatur, driver tampilan mode pengguna harus selalu memeriksa nilai handel yang diperbarui di anggota hAllocationD3DDDICB_LOCK. Jika handel alokasi baru disediakan, driver tampilan mode pengguna harus memperbarui struktur data internalnya untuk mereferensikan handel alokasi baru. Driver tampilan mode pengguna juga harus menambahkan versi yang diprogram ulang dari alamat dasar alokasi terkunci ke buffer perintah saat ini (karena instans alokasi berisi alamat dasar yang berbeda). Manajer memori video memvalidasi penggunaan instans alokasi yang digunakan oleh driver dan menolak buffer DMA yang salah menggunakan instans alokasi (yaitu, panggilan ke pfnPresentCb dan pfnRenderCb gagal jika mereka salah menggunakan instans alokasi). Setelah driver mereferensikan instans alokasi tertentu, driver tidak dapat lagi mereferensikan instans sebelumnya dari alokasi yang sama. Misalnya, jika buffer perintah menggunakan alokasi A dan saat ini menggunakan instans A0 dan A1, maka segera setelah A1 digunakan (yaitu, muncul dalam daftar lokasi patch) A0 menjadi tidak valid. Driver miniport tampilan dapat menghasilkan daftar lokasi patch yang mereferensikan A0 dan A1. Namun, referensi harus diurutkan (yaitu, A0 dapat digunakan terlebih dahulu; A0 menjadi tidak valid setelah A2 digunakan; A1 menjadi tidak valid ketika A2 digunakan, dan sebagainya).

Driver tampilan mode pengguna mungkin memanggil pfnLockCb untuk alokasi memori sistem, bahkan jika memori belum dialokasikan sebelumnya, karena driver miniport tampilan mungkin benar-benar dalam proses pengiriman, melalui DMA, atau secara asinkron mentransfer alokasi tersebut ke perangkat keras grafis. Oleh karena itu, sebelum aplikasi diizinkan untuk menulis ke permukaan, driver miniport tampilan dan manajer memori video harus diberi tahu sehingga mereka dapat memblokir kunci jika perlu.

Driver tampilan mode pengguna juga dapat mengunci subregion alokasi. Jenis kunci ini biasanya tidak diperlukan ketika bukaan perangkat keras yang tidak berdenyut atau linier tersedia karena, dalam situasi ini, driver tampilan mode pengguna dapat menerjemahkan kunci pada seluruh alokasi ke subregion dengan mengimbangi pointer. Namun, ketika pfnLockCb gagal dengan menggunakan D3DERR_NOTAVAILABLE untuk menunjukkan bahwa bukaan tidak tersedia, manajer memori meminta driver tampilan mode pengguna untuk menyalin konten memori video. Driver tampilan mode pengguna tidak berdenyut atau membuat linearisasi konten memori video saat menyalinnya ke area memori lain. Dalam situasi ini, driver tampilan mode pengguna dapat menyediakan daftar halaman untuk disalin untuk menghemat penyalinan dalam jumlah besar saat mengunci subregion kecil dalam alokasi besar. Perhatikan bahwa manajer memori gagal melakukan panggilan ke pfnLockCb dengan D3DERR_NOTAVAILABLE jika driver tampilan mode pengguna tidak mengatur bendera bidang bit LockEntire di anggota Bendera struktur D3DDDICB_LOCK dan tidak menentukan daftar halaman di anggota halaman D3DDDICB_LOCK. Jika driver tampilan mode pengguna mengatur bendera bit-field LockEntire , driver tersebut juga harus mengatur anggota NumPages dan pPages masing-masing D3DDDICB_LOCK ke 0 dan NULL. Driver tampilan mode pengguna harus selalu menyediakan daftar halaman di halaman saat mengunci alokasi yang dibuat dengan penyimpanan dukungan permanen. Dalam situasi ini, manajer memori menggunakan daftar halaman untuk menandai sebagai halaman tertentu yang kotor saja dan tidak diperlukan untuk menyalin seluruh alokasi dari penyimpanan cadangan ketika digunakan untuk penyajian.

Driver tampilan mode pengguna dapat memanggil pfnLockCb untuk memperoleh beberapa rentang berdenyut untuk satu alokasi (misalnya, satu rentang berdenyut untuk setiap tingkat MIP). Jika driver tidak dapat memperoleh salah satu rentang, runtime Direct3D mengeluarkan seluruh alokasi untuk menangani kunci (semua tingkat MIP) dan merebut kembali semua rentang yang menggeser.

Ketika driver tampilan mode pengguna meminta agar rentang menggeser ditetapkan ke alokasi, driver secara efektif meminta akses ke bit alokasi yang tidak berdenyut. Untuk permintaan tersebut, manajer memori video baik halaman dalam alokasi ke segmen memori dan menyiapkan rentang yang menggelegar untuk mengakses alokasi atau halaman dalam alokasi ke segmen memori dan kemudian mengeluarkan alokasi ke memori sistem sambil meminta agar driver membatalkan alokasi dalam perjalanan ke memori sistem. Alokasi yang tidak didengar ke memori sistem disusun ulang (dengan dipaginasi ke dalam memori video) sebelum GPU menggunakan alokasi lagi. Akibatnya, driver tidak dapat meminta kunci tanpa jenis penimpaan (dengan mengatur bendera bit-field DonotWait ) saat memperoleh rentang yang menggeser. Demikian pula, driver tidak dapat mereferensikan kunci alokasi sedemikian rupa dalam buffer DMA yang dikirimkan ke GPU (karena buffer DMA akan ditolak).

Driver tampilan mode pengguna mungkin mengunci alokasi bergelob tanpa memperoleh rentang berdenyut jika driver harus mengakses bit alokasi dalam format berdenyut. Dalam situasi ini, manajer memori video menyediakan driver dengan penunjuk ke bit alokasi yang bergelora. Namun, driver tidak dapat meminta penunjuk ke bit alokasi yang bergelombang sementara permintaan untuk bit yang tidak berdenyut luar biasa, dan sebaliknya (artinya, kunci saat ini tertunda pada alokasi dengan rentang berdenyut diperoleh).

Driver tampilan mode pengguna harus meneruskan bendera Buang bit-field di anggota Bendera D3DDDICB_LOCK dalam panggilan pfnLockCb dalam situasi berikut:

  • Ketika runtime Direct3D melewati bendera Buang bit-field di anggota Bendera struktur D3DDDIARG_LOCK dalam panggilan ke fungsi Kunci driver tampilan mode pengguna
  • Ketika runtime meneruskan nilai D3D10_DDI_MAP_WRITE_DISCARD ke parameter DDIMap dalam panggilan ke fungsi ResourceMap driver
Mengatur bendera Buang bit-field menyebabkan manajer memori menentukan apakah harus mengganti nama alokasi atau harus menyebabkan utas aplikasi terhenti hingga alokasi diam. Untuk informasi selengkapnya tentang mengganti nama alokasi, lihat Meminta untuk Mengganti Nama Alokasi. Driver dapat menggunakan dukungan penggantian nama sendiri atau dukungan penggantian nama manajer memori. Untuk menggunakan dukungan penggantian nama sendiri, driver mengatur bendera bit-field DonotWait , sebagai respons terhadap panggilan Kunci dengan bendera Buang bit-field yang ditetapkan, atau sebagai respons terhadap panggilan ResourceMap dengan kumpulan nilai D3D10_DDI_MAP_WRITE_DISCARD. Mengatur bendera bit-field DonotWait menyebabkan manajer memori gagal melakukan panggilan ke pfnLockCb dengan D3DERR_WASSTILLDRAWING jika perangkat keras grafis masih menggunakan alokasi. Kegagalan seperti itu menunjukkan kepada driver tampilan mode pengguna untuk mengganti nama atau beberapa buffer alokasi.
Catatan Bendera bit-field DonotWait tidak berpengaruh pada manajer memori jika bendera Buang bit-field juga diatur.
 
Driver tampilan mode pengguna harus mengatur bendera bit-field IgnoreSync di anggota Bendera D3DDDICB_LOCK ketika tidak memerlukan manajer memori untuk memeriksa apakah perangkat keras grafis menggunakan alokasi. Pengandar tampilan mode pengguna kemudian harus menyinkronkan akses ke alokasi dengan benar. Jika bendera bit-field DonotWait tidak ditentukan dengan bendera bit-field IgnoreSync , manajer memori mengabaikan bendera ignoreSync bit-field.
Catatan Bendera bit-field IgnoreSync tidak berpengaruh pada manajer memori jika bendera Buang bit-field juga diatur.
 
Contoh

Contoh kode berikut menunjukkan bagaimana bendera Buang bit-field digunakan dalam panggilan ke pfnLockCb.

HRESULT hr;
D3DDDICB_LOCK LockData;
LockData.hAllocation = AllocationToLock;
LockData.Flags.Discard = TRUE;
hr = pfnLockCb(&LockData)
if (FAILED(hr)) {
    FlushAccumulatedCommandBufferToKernel();
    LockData.Flags.Discard = TRUE;
    LockData.Flags.NoExistingReference = TRUE;
    hr = pfnLockCb(&LockData);
    if (FAILED(hr)) {
        // Fails the lock to the application
    }
}
UpdateAllocationHandleInUMDDataStructure(LockData.hAllocation);
ProgramSurfaceBaseAddressInCurrentCommandBuffer(LockData.hAllocation);

Persyaratan

Persyaratan Nilai
Klien minimum yang didukung Tersedia di Windows Vista dan versi yang lebih baru dari sistem operasi Windows.
Target Platform Desktop
Header d3dumddi.h (termasuk D3dumddi.h)

Lihat juga

D3D10DDIARG_CREATERESOURCE

D3D11DDIARG_CREATERESOURCE

D3DDDIARG_LOCK

D3DDDICB_LOCK

D3DDDI_DEVICECALLBACKS

Lock

ResourceMap

ResourceUnmap