Poznámka
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Nahrávání 2D nebo 3D texturových dat se podobá nahrání 1D dat s tím rozdílem, že aplikace musí věnovat větší pozornost zarovnání dat související s výškou řádků. Vyrovnávací paměti lze použít nezávisle a souběžně z několika částí grafického potrubí a jsou velmi flexibilní.
- nahrání dat textury pomocí bufferů
- kopírování
- mapování a zrušení mapování
- zarovnání vyrovnávací paměti
- související témata
Nahrání dat textury prostřednictvím vyrovnávacích pamětí
Aplikace musí nahrávat data prostřednictvím ID3D12GraphicsCommandList::CopyTextureRegion nebo ID3D12GraphicsCommandList::CopyBufferRegion. Pravděpodobnost, že data textur budou větší, budou k nim opakovaně přistupovat a využijí lepší koherentnost cache díky nelineárním rozložením paměti, je vyšší než u jiných dat prostředků. Při použití vyrovnávacích pamětí v D3D12 mají aplikace úplnou kontrolu nad umístěním dat a uspořádáním souvisejícím s kopírováním dat o prostředcích, pokud jsou splněny požadavky na zarovnání paměti.
Ukázka zvýrazní, kde aplikace jednoduše zplošťuje 2D data na 1D před jejich umístěním do vyrovnávací paměti. V případě 2D scénáře mipmap může aplikace buď jednotlivé dílčí prostředky efektivně zploštit a rychle použít 1D algoritmus pro poddělení, nebo využít složitější techniku 2D poddělení ke snížení využití grafické paměti. Očekává se, že první technika se bude používat častěji, protože je jednodušší. Druhá technika může být užitečná při balení dat na disk nebo přes síť. V obou případech musí aplikace stále volat API pro kopírování pro každý dílčí prostředek.
// 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 );
Všimněte si použití pomocných struktur CD3DX12_HEAP_PROPERTIES a CD3DX12_TEXTURE_COPY_LOCATIONa metod CreateCommittedResource a CopyTextureRegion.
Kopírování
Metody D3D12 umožňují aplikacím nahradit v D3D11 metody UpdateSubresource , CopySubresourceRegion , a počáteční data zdrojů. Jeden 3D subresource může obsahovat data textur uspořádaných po řádcích umístěná v prostředcích vyrovnávací paměti. CopyTextureRegion může kopírovat data textury z vyrovnávací paměti do texturového prostředku s neznámým rozložením textury, a naopak. Aplikace by měly preferovat tento typ techniky pro naplnění často přístupných prostředků GPU vytvořením velkých vyrovnávacích pamětí v haldě UPLOAD a vytvořením často přístupných prostředků GPU v haldě DEFAULT, která nemá přístup k procesoru. Taková technika efektivně podporuje diskrétní GPU a jejich velké objemy paměti nepřístupné procesoru, aniž by to často ovlivňovalo architektury UMA.
Všimněte si následujících dvou konstant:
const UINT D3D12_TEXTURE_DATA_PITCH_ALIGNMENT = 256;
const UINT D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT = 512;
- D3D12_SUBRESOURCE_FOOTPRINT
- D3D12_PLACED_SUBRESOURCE_FOOTPRINT
- D3D12_TEXTURE_COPY_LOCATION
- D3D12_TEXTURE_COPY_TYPE
- ID3D12Device::GetCopyableFootprints
- ID3D12GraphicsCommandList::CopyResource
- ID3D12GraphicsCommandList::CopyTextureRegion
- ID3D12GraphicsCommandList::CopyBufferRegion
- ID3D12GraphicsCommandList::CopyTiles
- ID3D12CommandQueue::UpdateTileMappings
Mapování a odmapování
mapy a unmap lze volat více vlákny bezpečně. První volání Map přidělí pro prostředek virtuální adresní prostor CPU. Poslední volání Unmap dealokuje rozsah virtuálních adres CPU. Virtuální adresa procesoru se obvykle vrací do aplikace.
Kdykoli se data předávají mezi CPU a GPU prostřednictvím prostředků v haldách zpětného čtení, musí být použity Map a Unmap, aby byly podporovány všechny systémy, na nichž je D3D12 podporováno. Udržování co nejtěsnějších rozsahů maximalizuje efektivitu na systémech, které vyžadují rozsahy (viz D3D12_RANGE).
Výkon nástrojů pro ladění těží nejen z přesného použití rozsahů při všech Map / Unmap voláních, ale také z toho, že aplikace uvolní prostředky, když už nebudou prováděny žádné úpravy procesoru.
Metoda D3D11 použití Map (se sadou parametrů DISCARD) k přejmenování prostředků není v D3D12 podporována. Aplikace musí implementovat přejmenování prostředků. Všechna volání mapy přes jsou implicitně nastavena jako NO_OVERWRITE a jsou vícevláknová. Je zodpovědností aplikace zajistit, aby se před přístupem k datům pomocí procesoru dokončila veškerá relevantní práce GPU obsažená v seznamech příkazů. Volání D3D12 map neprázdní žádné vyrovnávací paměti příkazů ani neblokují čekání na dokončení práce GPU. V důsledku toho mohou být Map a Unmap v některých scénářích dokonce optimalizovány.
Zarovnání vyrovnávací paměti
Omezení zarovnání vyrovnávací paměti:
- Kopírování lineární podsložky musí být zarovnané k 512 bajtům (se šířkou řádku zarovnanou k D3D12_TEXTURE_DATA_PITCH_ALIGNMENT bajtům).
- Čtení konstantních dat musí být násobkem 256 bajtů od začátku haldy (tj. pouze z adres, které jsou zarovnané na 256 bajtů).
- Čtení indexových dat musí být násobkem velikosti datového typu indexu (tj. pouze z adres, které jsou přirozeně zarovnané s ohledem na data).
- ID3D12GraphicsCommandList::ExecuteIndirect data musí být z posunů, které jsou násobky 4 (tj. pouze z adres, které jsou zarovnané pomocí DWORD).