DXGKDDI_BUILDPAGINGBUFFER fungsi panggilan balik (d3dkmddi.h)

Fungsi DxgkDdiBuildPagingBuffer membangun buffer halaman untuk operasi memori.

Sintaks

DXGKDDI_BUILDPAGINGBUFFER DxgkddiBuildpagingbuffer;

NTSTATUS DxgkddiBuildpagingbuffer(
  [in]     IN_CONST_HANDLE hAdapter,
  [in/out] IN_PDXGKARG_BUILDPAGINGBUFFER pBuildPagingBuffer
)
{...}

Parameter

[in] hAdapter

Handel ke blok konteks yang terkait dengan adaptor tampilan. Driver miniport tampilan sebelumnya menyediakan handel ini ke subsistem kernel grafis Microsoft DirectX di parameter output MiniportDeviceContext dari fungsi DxgkDdiAddDevice .

[in/out] pBuildPagingBuffer

Penunjuk ke struktur DXGKARG_BUILDPAGINGBUFFER yang berisi informasi untuk membangun penyangga halaman.

Menampilkan nilai

DxgkDdiBuildPagingBuffer mengembalikan salah satu nilai berikut:

Menampilkan kode Deskripsi
STATUS_SUCCESS DxgkDdiBuildPagingBuffersuccessfully membangun buffer halaman.
STATUS_GRAPHICS_ALLOCATION_BUSY GPU saat ini menggunakan alokasi untuk buffer halaman.
STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER Lebih banyak ruang yang diperlukan dalam buffer halaman (yaitu, di anggota pDmaBuffer dari struktur DXGKARG_BUILDPAGINGBUFFER yang ditunjukkan parameter pBuildPagingBuffer).

Keterangan

Fungsi DxgkDdiBuildPagingBuffer dipanggil untuk membangun buffer akses memori langsung tujuan khusus (DMA) yang dikenal sebagai buffer halaman. Buffer halaman berisi operasi yang memindahkan konten bagian alokasi:

  • Dalam segmen alokasi.
  • Di antara segmen alokasi.
  • Dari segmen alokasi ke memori sistem.
  • Dari memori sistem hingga segmen alokasi.

Driver miniport tampilan harus menulis instruksi unit pemrosesan grafis (GPU) yang sesuai dalam buffer halaman yang disediakan (di anggota pDmaBufferDXGKARG_BUILDPAGINGBUFFER) sesuai dengan operasi penomor yang diminta; dan kemudian driver harus mengembalikan buffer halaman kembali ke manajer memori video (yang merupakan bagian dari Dxgkrnl.sys). Penjadwal GPU (yang juga merupakan bagian dari Dxgkrnl.sys) kemudian memanggil fungsi DxgkDdiSubmitCommand driver untuk meminta driver mengirimkan buffer paging sebagai buffer DMA biasa ke GPU.

Catatan Sebelum manajer memori video mengirimkan buffer halaman, ia memanggil fungsi DxgkDdiPatch driver untuk menetapkan (yaitu, patch) alamat fisik ke buffer halaman; namun, dalam panggilan ke DxgkDdiPatch, manajer memori video tidak menyediakan daftar lokasi patch. Fungsi DxgkDdiPatch driver dapat melakukan pembaruan menit terakhir pada buffer halaman; namun, fungsi DxgkDdiPatch driver tidak dapat mengubah ukuran buffer halaman.
 
Ketika driver berhasil membangun buffer halaman, DxgkDdiBuildPagingBuffer driver harus memperbarui pDmaBuffer untuk menunjuk melewati byte terakhir yang ditulis ke buffer halaman dan kemudian kembali STATUS_SUCCESS. Karena DxgkDdiBuildPagingBuffer dapat gagal hanya jika kehabisan ruang di penyangga halaman, driver harus selalu memverifikasi bahwa buffer halaman memiliki cukup ruang yang tersisa sebelum menulis ke buffer. Jika tidak cukup ruang yang tersisa di buffer halaman, driver harus kembali STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER. Manajer memori video kemudian akan memperoleh buffer halaman baru dan memanggil fungsi DxgkDdiBuildPagingBuffer driver lagi untuk mengisi buffer halaman baru sesuai dengan operasi paging yang diminta. Perhatikan bahwa untuk operasi paging yang diminta tertentu yang mengisi beberapa buffer halaman, penjadwal memanggil fungsi DxgkDdiSubmitCommand driver beberapa kali untuk setiap buffer halaman parsial untuk mengirimkan setiap buffer secara independen.

Jika DxgkDdiBuildPagingBuffer menentukan bahwa operasi paging memerlukan lebih dari satu buffer halaman, driver dapat menentukan informasi di anggota MultipassOffsetDXGKARG_BUILDPAGINGBUFFER dan dapat menggunakan informasi ini di beberapa perulangan operasi penomohan. Manajer memori video menginisialisasi informasi di MultipassOffset ke nol sebelum permintaan operasi paging pertama dan tidak memodifikasi informasi di MultipassOffset antar iterasi. Oleh karena itu, driver dapat menggunakan MultipassOffset untuk menyimpan kemajuan di antara iterasi. Misalnya, driver dapat menyimpan nomor halaman yang terakhir ditransfer untuk transfer berbasis halaman.

Buffer halaman saat ini dibangun untuk jenis operasi berikut:

  • Transfer

    Operasi transfer memindahkan konten alokasi dari satu lokasi ke lokasi lainnya. Operasi ini adalah jenis operasi memori yang paling umum.

    Alokasi selalu sepenuhnya ditransfer dari satu lokasi ke lokasi lain. Namun, karena kendala memori, transfer alokasi dapat dibagi menjadi beberapa sub-transfer (yaitu, sebagian alokasi dipindahkan dari lokasi A ke B, dan kemudian bagian berikut dipindahkan, dan sebagainya, sampai seluruh alokasi ditransfer). Sub-transfer pertama alokasi ditandai dengan bendera bit-field TransferStart di anggota Bendera anggota Transfer DXGKARG_BUILDPAGINGBUFFER; sub-transfer terakhir alokasi ditandai dengan bendera bidang bit TransferEnd . Driver dijamin akan menerima akhir transfer tertunda (yaitu, sub-transfer terakhir) sebelum driver menerima awal transfer baru.

    Setiap sub-transfer mungkin memerlukan beberapa panggilan ke DxgkDdiBuildPagingBuffer untuk diselesaikan (misalnya, driver mungkin kehabisan ruang buffer DMA). Oleh karena itu, driver mungkin menerima bendera TransferStart dalam beberapa panggilan ke DxgkDdiBuildPagingBuffer hingga driver menerima bendera TransferEnd dalam panggilan ke DxgkDdiBuildPagingBuffer. Menerima bendera TransferStart beberapa kali tidak menunjukkan dimulainya beberapa transfer baru; ini menunjukkan bahwa sub-transfer untuk alokasi memerlukan beberapa iterasi (misalnya, jika driver kehabisan ruang buffer DMA). Driver dapat menggunakan anggota MultipassOffsetdari DXGKARG_BUILDPAGINGBUFFER untuk melacak kemajuan untuk sub-transfer tertentu di beberapa iterasi DxgkDdiBuildPagingBuffer.

    Biasanya, transfer terjadi dalam satu operasi. Dalam situasi ini, bendera bit-field TransferStart dan TransferEnd diatur.

    Dalam beberapa skenario, driver mungkin diperlukan untuk menyiapkan sumber daya perangkat keras ketika alokasi tertentu dimasukkan ke dalam atau kehabisan memori. Secara default, GPU mungkin menggunakan alokasi yang dirujuk selama panggilan ke DxgkDdiBuildPagingBuffer. Dalam skenario ini, driver mungkin mengharuskan alokasi diam sebelum program driver sumber daya perangkat keras yang diperlukan (yaitu, pemrograman sumber daya perangkat keras tidak dapat diantrekan dalam buffer DMA yang disediakan). Untuk skenario tersebut, driver dapat gagal melakukan panggilan ke DxgkDdiBuildPagingBuffer dengan STATUS_GRAPHICS_ALLOCATION_BUSY.

    Jika driver kembali STATUS_GRAPHICS_ALLOCATION_BUSY, manajer memori video menunggu sampai GPU selesai dengan referensi apa pun ke alokasi saat ini dan kemudian memanggil fungsi DxgkDdiBuildPagingBuffer driver lagi. Dalam panggilan kedua ke DxgkDdiBuildPagingBuffer, manajer memori video mengatur bendera bit-field AllocationIsIdle di anggota Bendera anggota Transfer DXGKARG_BUILDPAGINGBUFFER untuk menunjukkan bahwa alokasi yang sedang dirujuk menganggur. Jika bendera diam tidak diatur, driver harus selalu menentukan bahwa alokasi saat ini sibuk atau mungkin segera sibuk. Jika bendera diam diatur, manajer memori video menjamin bahwa alokasi yang sedang dirujuk tetap menganggur selama panggilan ke DxgkDdiBuildPagingBuffer.

    Jika anggota hAllocation DXGKARG_BUILDPAGINGBUFFER NULL, driver harus menyalin data di sumber ke tujuan tanpa melakukan penyimpangan atau pemilahan.

  • Isian

    Operasi pengisian mengisi alokasi dengan pola tertentu. Operasi pengisian digunakan untuk menyiapkan konten awal alokasi. Ketika konten alokasi diisi, alokasi dijamin menganggur (yaitu, tidak digunakan oleh GPU). Operasi pengisian hanya dapat dilakukan pada segmen memori. Manajer memori video tidak pernah meminta agar driver miniport tampilan mengisi segmen aperture.

  • Buang isi

    Operasi buang-konten memberi tahu driver bahwa alokasi dibuang dari lokasi alokasi saat ini di segmen memori. Artinya, alokasi dikeluarkan dan tidak disalin kembali ke memori sistem.

    Dalam beberapa skenario, driver mungkin diperlukan untuk menyiapkan sumber daya perangkat keras ketika alokasi tertentu dimasukkan ke dalam atau kehabisan memori. Secara default, GPU mungkin menggunakan alokasi yang dirujuk selama panggilan ke DxgkDdiBuildPagingBuffer. Dalam skenario ini, driver mungkin mengharuskan alokasi diam sebelum program driver sumber daya perangkat keras yang diperlukan (yaitu, pemrograman sumber daya perangkat keras tidak dapat diantrekan dalam buffer DMA yang disediakan). Untuk skenario tersebut, driver dapat gagal melakukan panggilan ke DxgkDdiBuildPagingBuffer dengan STATUS_GRAPHICS_ALLOCATION_BUSY.

    Jika driver kembali STATUS_GRAPHICS_ALLOCATION_BUSY, manajer memori video menunggu sampai GPU selesai dengan referensi apa pun ke alokasi saat ini dan kemudian memanggil fungsi DxgkDdiBuildPagingBuffer driver lagi. Dalam panggilan kedua ke DxgkDdiBuildPagingBuffer, manajer memori video mengatur bendera bit-field AllocationIsIdle di anggota Bendera anggota DiscardContent dari struktur DXGKARG_BUILDPAGINGBUFFER untuk menunjukkan bahwa alokasi yang sedang dirujuk menganggur. Jika bendera diam tidak diatur, driver harus selalu menentukan bahwa alokasi saat ini sibuk atau mungkin segera sibuk. Jika bendera diam diatur, manajer memori video menjamin bahwa alokasi yang sedang dirujuk tetap menganggur selama panggilan ke DxgkDdiBuildPagingBuffer.

  • Membaca fisik

    Operasi baca-fisik membaca dari alamat memori fisik tertentu. Driver diminta untuk memprogram GPU untuk operasi. Ukuran memori fisik yang akan diakses untuk bacaan dapat dari 1 byte hingga 8 byte. Karena data yang dibaca tidak relevan, DxgkDdiBuildPagingBuffer tidak diperlukan untuk mengembalikan data. Namun, dalam skenario di mana CPU mencoba membaca dari memori AGP setelah GPU menulis ke memori AGP tersebut, operasi baca-fisik sangat penting untuk memastikan koherensi memori.

  • Menulis fisik

    Operasi tulis-fisik menulis ke alamat fisik tertentu. Driver diminta untuk memprogram GPU untuk operasi. Ukuran memori fisik yang akan diakses untuk operasi tulis dapat dari 1 byte hingga 8 byte. Karena data yang ditulis tidak relevan, DxgkDdiBuildPagingBuffer dapat menulis data apa pun ke memori. Namun, dalam skenario di mana CPU mencoba membaca dari memori AGP setelah GPU menulis ke memori AGP tersebut, operasi tulis-fisik sangat penting untuk memastikan koherensi memori.

  • Segmen bukaan peta

    Operasi map-aperture-segment memetakan daftar deskriptor memori (MDL) tertentu ke dalam segmen aperture tertentu pada offset segmen tertentu untuk sejumlah halaman tertentu. Jika bendera bit-field CacheCoherent diatur dalam anggota Bendera anggota MapApertureSegment dari struktur DXGKARG_BUILDPAGINGBUFFER , driver harus memastikan bahwa koherensi cache diberlakukan pada halaman yang dipetakan; jika tidak, koherensi cache tidak diperlukan untuk halaman yang dipetakan.

    Catatan Bendera bit-field CacheCoherent diatur hanya ketika memori yang dapat di-cache sedang dipetakan ke dalam segmen aperture koheren cache dan tidak pernah diatur pada segmen aperture non-cache-coherent atau pada alokasi gabungan tulis yang dipetakan ke dalam segmen cache-coherent.
     
    Driver dapat secara opsional menggunakan I/O yang dipetakan memori (MMIO) untuk mengonfigurasi segmen aperture. GPU tidak akan mengakses rentang aperture pada waktu konfigurasi. Namun, konfigurasi aperture ini tidak boleh mengganggu eksekusi GPU. GPU tidak akan menganggur ketika DxgkDdiBuildPagingBuffer dipanggil dengan set jenis operasi DXGK_OPERATION_MAP_APERTURE_SEGMENT, dan GPU mungkin sibuk mengakses bagian lain dari segmen aperture yang sedang dikonfigurasi ulang.
  • Membuka peta segmen bukaan

    Operasi unmap-aperture-segment membatalkan peta rentang segmen bukaan tertentu yang dipetakan sebelumnya. Driver harus memetakan rentang yang tidak dipetakan ke halaman dummy yang ditentukan anggota DummyPage dari anggota UnmapApertureSegment dari struktur DXGKARG_BUILDPAGINGBUFFER .

    Catatan Ketika driver membuka peta ke halaman dummy, driver harus mengaktifkan akses GPU melalui rentang bukaan yang ditentukan sehingga subsistem kernel grafis DirectX dapat mendeteksi masalah kerusakan. Tes kesuaian ada untuk memeriksa situasi ini.
     
    Manajer memori video menggunakan halaman dummy yang berada di bagian bukaan yang tidak dipetakan untuk menentukan kesulitan yang dimiliki manajer memori untuk mengakses segmen aperture.

    Driver dapat secara opsional menggunakan MMIO untuk mengonfigurasi segmen aperture. GPU tidak akan mengakses rentang bukaan pada waktu konfigurasi. Namun, konfigurasi aperture ini tidak boleh mengganggu eksekusi GPU. GPU tidak akan menganggur ketika DxgkDdiBuildPagingBuffer dipanggil dengan set jenis operasi DXGK_OPERATION_UNMAP_APERTURE_SEGMENT, dan GPU mungkin sibuk mengakses bagian lain dari segmen aperture yang sedang dikonfigurasi ulang.

  • Transfer kunci khusus

    Operasi transfer kunci khusus mirip dengan operasi transfer reguler. Namun, alih-alih mentransfer konten alokasi dari atau ke penyimpanan backing reguler alokasi, operasi transfer kunci khusus mentransfer konten alokasi dari atau ke alamat virtual alternatif yang disiapkan untuk alokasi ketika fungsi pfnLockCb dipanggil dengan set bendera bit-field UseAlternateVA .

    Operasi transfer kunci khusus hanya terjadi dalam salah satu skenario berikut:

    • Alokasi saat ini dapat diakses CPU dengan alamat virtual alternatif dan sedang dikeluarkan.
    • Alokasi yang sebelumnya dikeluarkan, seperti situasi yang dijelaskan dalam poin sebelumnya, sedang dimasukkan kembali ke halaman.
    Driver yang tidak mendukung penggunaan bendera bit-field UseAlternateVA tidak akan dipanggil untuk melakukan operasi transfer kunci khusus.

    Dalam beberapa skenario, driver mungkin diperlukan untuk mengatur sumber daya perangkat keras ketika alokasi tertentu dimasukkan ke dalam atau kehabisan memori. Secara default, GPU mungkin menggunakan alokasi yang dirujuk selama panggilan ke DxgkDdiBuildPagingBuffer. Dalam skenario ini, driver mungkin mengharuskan alokasi diam sebelum program driver sumber daya perangkat keras yang diperlukan (yaitu, pemrograman sumber daya perangkat keras tidak dapat diantrekan dalam buffer DMA yang disediakan). Untuk skenario seperti itu, driver dapat gagal memanggil DxgkDdiBuildPagingBuffer dengan STATUS_GRAPHICS_ALLOCATION_BUSY.

    Jika driver mengembalikan STATUS_GRAPHICS_ALLOCATION_BUSY, manajer memori video menunggu sampai GPU selesai dengan referensi apa pun ke alokasi saat ini dan kemudian memanggil fungsi DxgkDdiBuildPagingBuffer driver lagi. Dalam panggilan kedua ke DxgkDdiBuildPagingBuffer, manajer memori video mengatur bendera bit-field AllocationIsIdle di anggota Bendera anggota SpecialLockTransfer dari struktur DXGKARG_BUILDPAGINGBUFFER untuk menunjukkan bahwa alokasi yang sedang direferensikan menganggur. Jika bendera diam tidak diatur, driver harus selalu menentukan bahwa alokasi saat ini sibuk atau mungkin segera sibuk. Jika bendera diam diatur, manajer memori video menjamin bahwa alokasi yang sedang dirujuk tetap menganggur selama panggilan ke DxgkDdiBuildPagingBuffer.

Perhatikan bahwa jika driver harus menggunakan aperture perangkat keras untuk meliniarisasi alokasi berdenyut yang dapat diakses oleh aplikasi secara langsung, driver harus membatalkan alokasi tersebut saat driver mentransfer alokasi ke memori sistem untuk mempertahankan koherensi alamat virtual alokasi. Driver harus membatalkan alokasi karena pengeluaran mungkin terjadi saat aplikasi mengakses alokasi.

Manajer memori sistem memastikan bahwa transfer tidak terlihat oleh aplikasi. Namun, karena alokasi berada dalam memori sistem dan alamat virtual alokasi tidak dapat lagi melalui bukaan perangkat keras, driver harus memastikan byte yang dipesan ke dalam memori sistem cocok dengan apa yang terlihat melalui bukaan.

DxgkDdiBuildPagingBuffer harus dibuat dapat dipaginasi.

Contoh

Contoh kode berikut menunjukkan cara menggunakan DxgkDdiBuildPagingBuffer.

NTSTATUS ntStatus;
DXGKARG_BUILDPAGINGBUFFER param;

// The driver receives the following paging operation to build:
//
param.Flags = 0;
param.pDmaBuffer= CurrentPagingBuffer;
param.DmaSize = CurrentPagingBufferSizeLeft;
param.pDmaBufferPrivateData = CurrentPagingBufferPrivateData; 
param.DmaBufferPrivateDataSize = CurrentPagingBufferPrivateDataSizeLeft; 
param.Operation = DXGK_OPERATION_TRANSFER; 
param.Transfer.Flags = 0; 
param.Transfer.TransferOffset = CurrentOffsetInAllocationBeingTransfered; 
param.Transfer.hAllocation = DriverContextForAllocationBeingMoved; 
param.Transfer.Source.SegmentId = 0; // Source is an MDL. 
param.Transfer.Source.pMdl = MDLDescribingPagesForAllocationBeingMoved; 
param.Transfer.Destination.SegmentId = 1; // Source to segment #1. 
param.Transfer.Destination.SegmentAddress = 0; // Source to offset 0 of segment #1.

// The driver receives MultipassOffset when it is initialized to zero 
// and uses it for multiple iterations of the paging operation.
//
param.MultipassOffset = 0;

do {
    // Call the driver's BuildPagingBuffer function to build a paging buffer.
    //
    ntStatus = BuildPagingBuffer(hAdapter, &param);
    // BuildPagingBuffer updates the size that is left in the 
    //  paging buffer with the amount of bytes that were written.
    //
    if (NT_SUCCESS(ntStatus)) {
        //
        // If STATUS_SUCCESS, batch the paging buffer to the 
        // scheduler after multiple paging operations are batched.
    }
    else if (ntStatus == STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER) {

        //
        // If STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER, submit the current paging buffer to the scheduler to let 
        // the GPU start working on a partial transfer.
 
        VidSchSubmitPagingBuffer(CurrentPagingBuffer, CurrentPagingBufferSizeLeft);
 
        // Acquire a new paging buffer to complete the transfer.
        //
        VidMmAcquirePagingBuffer(&CurrentPagingBuffer, &CurrentPagingBufferSizeLeft);
    }
    else {
        //
        // A critical failure occurred, so bugcheck the system. 
        // This situation should never occur because the driver can 
        // fail the call only if it requires more DMA buffer space.
    }
} while(!NT_SUCCESS(ntStatus))

Persyaratan

Persyaratan Nilai
Klien minimum yang didukung Windows Vista
Target Platform Desktop
Header d3dkmddi.h
IRQL PASSIVE_LEVEL

Lihat juga

DXGKARG_BUILDPAGINGBUFFER

DxgkDdiAddDevice

DxgkDdiPatch

DxgkDdiSubmitCommand

pfnLockCb