d3d:d3d12:texture
目次
Texture の転送
転送手順の概要
Buffer, Texture の転送もアプリケーション側で管理する必要があります。
GPU 側の VRAM を直接 Map することはできません。 一旦 Map 可能な Buffer (D3D12_HEAP_TYPE_UPLOAD) に書き込み、GPU の Copy 命令で転送を行います。
- Texture 用の Resource 作成 (D3D12_HEAP_TYPE_DEFAULT, D3D12_RESOURCE_STATE_COPY_DEST)
- 転送用 Buffer の Resource を作成 (D3D12_HEAP_TYPE_UPLOAD, D3D12_RESOURCE_STATE_GENERIC_READ)
- レイアウト取得 ( GetCopyableFootprints() )
- レイアウトに従い、転送するピクセルデータを Buffer に書き込む
- 転送用 CommandList を作成
- CommandList に CopyTextureRegion() 等の転送コマンドを格納
- 転送に使う CommandList/Queue が描画用と共用なら ResourceBarrier が必要。D3D12_RESOURCE_STATE_COPY_DEST → D3D12_RESOURCE_STATE_GENERIC_READ
- 転送用の CommandQueue で CommandList を実行
- CommandQueue に転送完了 Fence (Sginal) を挿入
- Fence で転送完了を確認。完了後は Upload 用の Buffer と CommandList を Release できる。
例
Texture 用 Resource 作成。
ID3D12Resource* iTexture= nullptr; D3D12_RESOURCE_DESC desc; memset( &desc, 0, sizeof(desc) ); desc.Dimension= D3D12_RESOURCE_DIMENSION_TEXTURE2D; desc.Width= 512; desc.Height= 512; desc.DepthOrArraySize= 1; desc.MipLevels= 1; desc.Format= DXGI_FORMAT_R8G8B8A8_UNORM; desc.SampleDesc.Count= 1; D3D12_HEAP_PROPERTIES heap; memset( &heap, 0, sizeof(heap) ); heap.Type= D3D12_HEAP_TYPE_DEFAULT; iD3DDevice->CreateCommitedResource( &heap, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&iTexture) );
Footprint 取得。
D3D12_PLACED_SUBRESOURCE_FOOTPRINT footprint; UINT64 total_bytes= 0; iD3DDevice->GetCopyableFootprints( &desc, 0, 1, 0, &footprint, nullptr, nullptr, &total_bytes );
Upload 用 Buffer 作成
D3D12_RESOURCE_DESC desc; memset( &desc, 0, sizeof(desc) ); desc.Dimension= D3D12_RESOURCE_DIMENSION_BUFFER; desc.Width= total_bytes; desc.Height= 1; desc.DepthOrArraySize= 1; desc.MipLevels= 1; desc.SamleDesc.Count= 1; desc.Layout= D3D12_TEXTURE_LAYOUT_ROW_MAJOR; D3D12_HEAP_PROPERTIES heap; memset( &heap, 0, sizeof(heap) ); heap.Type= D3D12_HEAP_TYPE_UPLOAD; ID3D12Resource* iUploadBuffer= nullptr; iD3DDevice->CreateCommittedResource( &heap, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&iUploadBuffer) );
Upload Buffer への書き込み。
void* ptr= nullptr; iUploadBuffer->Map( 0, nullptr, &ptr ); memcpy( reinterpret_cast<unsigned char*>(ptr) + footprint.Offset, pixel_data, pixel_data_size );
Copy コマンド作成
D3D12_TEXTURE_COPY_LOCATION dest; memset( &dest, 0, sizeof(dest) ); dest.pResource= iTexture; dest.Type= D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; dest.SubresourceIndex= 0; D3D12_TEXTURE_COPY_LOCATION src; memset( &src, 0, sizeof(src) ); src.pResource= iUploadBuffer; src.Type= D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; src.PlacedFootprint= footprint; ID3D12GraphicsCommandList* iCommandList= GetCurrentCommandList(); iCommandList->CopyTextureRegion( &dest, 0, 0, 0, &src, nullptr );
ResourceBarrier 挿入
D3D12_RESOURCE_BARRIER barrier; memset( &barrier, 0, sizeof(barrier) ); barrier.Type= D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; barrier.Transition.pResource= iTexture; barrier.Transition.Subresource= D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; barrier.Transition.StateBefore= D3D12_RESOURCE_STATE_COPY_DEST; barrier.Transition.StateAfter= D3D12_RESOURCE_STATE_GENERIC_READ; iCommandList->ResourceBarrier( 1, &barrier );
Command 実行
iCommandList->Close(); ID3D12CommandList* list[]= { iCommandList }; iCommandQueue->ExecuteCommandLists( 1, list ); FenceCount++; iCommandQueue->Signal( iUploadFence, FenceCount );
ResourceView の作成
D3D12_SHADER_RESOURCE_VIEW_DESC desc; memset( &desc, 0, sizeof(desc) ); desc.Format= DXGI_FORMAT_R8G8B8A8_UNORM; desc.ViewDimension= D3D12_SRV_DIMENSION_TEXTURE2D; desc.Shader4ComponentMapping= D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; desc.Texture2D.MipLevels= 1; D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle= iDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); iD3DDevice->CreateShaderResourceView( iTexture, &desc, cpu_handle );
d3d/d3d12/texture.txt · 最終更新: 2015/09/20 20:45 by oga