Bagikan melalui


Mengunggah data tekstur melalui buffer

Mengunggah data tekstur 2D atau 3D mirip dengan mengunggah data 1D, kecuali bahwa aplikasi perlu memperhatikan lebih dekat ke penyelarasan data yang terkait dengan pitch baris. Buffer dapat digunakan secara ortogonal dan bersamaan dari beberapa bagian alur grafis, dan sangat fleksibel.

Unggah Data Tekstur melalui Buffer

Aplikasi harus mengunggah data melalui ID3D12GraphicsCommandList::CopyTextureRegion atau ID3D12GraphicsCommandList::CopyBufferRegion. Data tekstur jauh lebih mungkin lebih besar, diakses berulang kali, dan mendapat manfaat dari koherensi cache yang ditingkatkan dari tata letak memori non-linier daripada data sumber daya lainnya. Ketika buffer digunakan dalam D3D12, aplikasi memiliki kontrol penuh pada penempatan data dan pengaturan yang terkait dengan penyalinan data sumber daya di sekitar, selama persyaratan penyelarasan memori terpenuhi.

Sampel menyoroti di mana aplikasi hanya meratakan data 2D ke dalam 1D sebelum menempatkannya di buffer. Untuk skenario mipmap 2D, aplikasi dapat meratakan setiap sub-sumber daya secara diskrit dan cepat menggunakan algoritma sub-alokasi 1D, atau, menggunakan teknik sub-alokasi 2D yang lebih rumit untuk meminimalkan pemanfaatan memori video. Teknik pertama diharapkan untuk digunakan lebih sering karena lebih sederhana. Teknik kedua mungkin berguna saat mengemas data ke disk atau di seluruh jaringan. Dalam kedua kasus, aplikasi masih harus memanggil API salin untuk setiap sub-sumber daya.

// Prepare a pBitmap in memory, with bitmapWidth, bitmapHeight, and pixel format of DXGI_FORMAT_B8G8R8A8_UNORM. 
//
// Sub-allocate from the buffer for texture data.
//

D3D12_SUBRESOURCE_FOOTPRINT pitchedDesc = { 0 };
pitchedDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
pitchedDesc.Width = bitmapWidth;
pitchedDesc.Height = bitmapHeight;
pitchedDesc.Depth = 1;
pitchedDesc.RowPitch = Align(bitmapWidth * sizeof(DWORD), D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);

//
// Note that the helper function UpdateSubresource in D3DX12.h, and ID3D12Device::GetCopyableFootprints 
// can help applications fill out D3D12_SUBRESOURCE_FOOTPRINT and D3D12_PLACED_SUBRESOURCE_FOOTPRINT structures.
//
// Refer to the D3D12 Code example for the previous section "Uploading Different Types of Resources"
// for the code for SuballocateFromBuffer.
//

SuballocateFromBuffer(
    pitchedDesc.Height * pitchedDesc.RowPitch,
    D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT
    );

D3D12_PLACED_SUBRESOURCE_FOOTPRINT placedTexture2D = { 0 };
placedTexture2D.Offset = m_pDataCur – m_pDataBegin;
placedTexture2D.Footprint = pitchedDesc;

//
// Copy texture data from DWORD* pBitmap->pixels to the buffer
//

for (UINT y = 0; y < bitmapHeight; y++)
{
  UINT8 *pScan = m_pDataBegin + placedTexture2D.Offset + y * pitchedDesc.RowPitch;
  memcpy( pScan, &(pBitmap->pixels[y * bitmapWidth]), sizeof(DWORD) * bitmapWidth );
}

//
// Create default texture2D resource.
//

D3D12_RESOURCE_DESC  textureDesc { ... };

CComPtr<ID3D12Resource> texture2D;
d3dDevice->CreateCommittedResource( 
        &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), 
        D3D12_HEAP_FLAG_NONE, &textureDesc, 
        D3D12_RESOURCE_STATE_COPY_DEST, 
        nullptr, 
        IID_PPV_ARGS(&texture2D) );

//
// Copy heap data to texture2D.
//

commandList->CopyTextureRegion( 
        &CD3DX12_TEXTURE_COPY_LOCATION( texture2D, 0 ), 
        0, 0, 0, 
        &CD3DX12_TEXTURE_COPY_LOCATION( m_spUploadHeap, placedTexture2D ), 
        nullptr );

Perhatikan penggunaan struktur pembantu CD3DX12_HEAP_PROPERTIES dan CD3DX12_TEXTURE_COPY_LOCATION, dan metode CreateCommittedResource dan CopyTextureRegion.

Menyalin

Metode D3D12 memungkinkan aplikasi untuk menggantikan D3D11 UpdateSubresource, CopySubresourceRegion, dan data awal sumber daya. Satu sub sumber daya 3D data tekstur utama baris mungkin terletak di sumber daya buffer. CopyTextureRegion dapat menyalin data tekstur tersebut dari buffer ke sumber daya tekstur dengan tata letak tekstur yang tidak diketahui, dan sebaliknya. Aplikasi harus lebih memilih jenis teknik ini untuk mengisi sumber daya GPU yang sering diakses, dengan membuat buffer besar dalam tumpuk UPLOAD sambil membuat sumber daya GPU yang sering diakses dalam timbunan DEFAULT yang tidak memiliki akses CPU. Teknik seperti itu secara efisien mendukung GPU diskrit dan memori CPU yang tidak dapat diakses dalam jumlah besar, tanpa biasanya menghambat arsitektur UMA.

Perhatikan dua konstanta berikut:

const UINT D3D12_TEXTURE_DATA_PITCH_ALIGNMENT = 256;
const UINT D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT = 512;

Pemetaan dan pembukaan

Peta dan Batalkan Pemetaan dapat dipanggil oleh beberapa utas dengan aman. Panggilan pertama ke Peta mengalokasikan rentang alamat virtual CPU untuk sumber daya. Panggilan terakhir ke Batalkan pemindahan rentang alamat virtual CPU. Alamat virtual CPU umumnya dikembalikan ke aplikasi.

Setiap kali data diteruskan antara CPU dan GPU melalui sumber daya dalam tumpukan readback, Peta dan Unmap harus digunakan untuk mendukung semua sistem D3D12 didukung. Menjaga rentang seketat mungkin memaksimalkan efisiensi pada sistem yang memerlukan rentang (lihat D3D12_RANGE).

Performa alat penelusuran kesalahan tidak hanya mendapat manfaat dari penggunaan rentang yang akurat pada semua panggilan Petakan / Pemetaan, tetapi juga dari aplikasi yang tidak memetakan sumber daya ketika modifikasi CPU tidak akan lagi dilakukan.

Metode D3D11 menggunakan Peta (dengan set parameter BUANG) untuk mengganti nama sumber daya tidak didukung di D3D12. Aplikasi harus menerapkan penggantian nama sumber daya sendiri. Semua panggilan Peta secara implisit NO_OVERWRITE dan multi-utas. Adalah tanggung jawab aplikasi untuk memastikan bahwa setiap pekerjaan GPU yang relevan yang terkandung dalam daftar perintah selesai sebelum mengakses data dengan CPU. Panggilan D3D12 ke Peta tidak secara implisit membersihkan buffer perintah apa pun, juga tidak memblokir menunggu GPU selesai bekerja. Akibatnya, Petakan dan Batalkan Peta bahkan dapat dioptimalkan dalam beberapa skenario.

Perataan buffer

Pembatasan perataan buffer:

  • Penyalinan subresource linear harus diratakan ke 512 byte (dengan pitch baris diratakan ke D3D12_TEXTURE_DATA_PITCH_ALIGNMENT byte).
  • Pembacaan data konstan harus kelipatan 256 byte dari awal tumpukan (yaitu hanya dari alamat yang selaras dengan 256 byte).
  • Pembacaan data indeks harus berupa kelipatan ukuran jenis data indeks (yaitu hanya dari alamat yang secara alami diselaraskan untuk data).
  • DATA ID3D12GraphicsCommandList::ExecuteIndirect harus dari offset yang merupakan kelipatan 4 (yaitu hanya dari alamat yang diselaraskan DWORD).