Direct3d と dxgi を使用して VNC プログラムを作成していますが、ビデオ RAM とシステム RAM の間のリソース転送を最小限に抑えたいと考えています。しかし、次のコードの一部で混乱しています。メソッドAcquireNextFrameで取得したテクスチャの使用法はステージングではなく、CPU で読み取ることができないため、ステージング テクスチャにコピーする必要があります。しかし、CopyResourceがデフォルトの使用量リソースからステージング使用量リソースにコピーするときに何をするのだろうか? ステージング リソース用にビデオ RAM にメモリを割り当ててからその領域にコピーし、Mapを呼び出すとテクスチャがその領域からシステム RAM にコピーされますか、それともリソースをシステム RAM に直接コピーしますか?
DUPL_RETURN DUPLICATIONMANAGER::GetFrame(D3D11_MAPPED_SUBRESOURCE* rawBits, bool* Timeout) {
IDXGIResource* DesktopResource = nullptr;
DXGI_OUTDUPL_FRAME_INFO FrameInfo;
// Get new frame
HRESULT hr = m_DeskDupl->AcquireNextFrame(0, &FrameInfo, &DesktopResource);
if (hr == DXGI_ERROR_WAIT_TIMEOUT)
{
*Timeout = true;
return DUPL_RETURN_SUCCESS;
}
*Timeout = false;
if (FAILED(hr))
{
return ProcessFailure(m_Device, L"Failed to acquire next frame in DUPLICATIONMANAGER", L"Error", hr, FrameInfoExpectedErrors);
}
// If still holding old frame, destroy it
if (m_AcquiredDesktopImage)
{
m_AcquiredDesktopImage->Release();
m_AcquiredDesktopImage = nullptr;
}
// QI for IDXGIResource
hr = DesktopResource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void **>(&m_AcquiredDesktopImage));
DesktopResource->Release();
DesktopResource = nullptr;
if (FAILED(hr))
{
return ProcessFailure(nullptr, L"Failed to QI for ID3D11Texture2D from acquired IDXGIResource in DUPLICATIONMANAGER", L"Error", hr);
}
ID3D11Texture2D* StagingTex = nullptr;
D3D11_TEXTURE2D_DESC desc;
m_AcquiredDesktopImage->GetDesc(&desc);
desc.Usage = D3D11_USAGE_STAGING;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
desc.BindFlags = 0;
desc.MiscFlags = 0;
hr = m_Device->CreateTexture2D(&desc, nullptr, &StagingTex);
if (FAILED(hr)) {
return ProcessFailure(m_Device, L"Failed to create texture for extracting raw data", L"Error", hr, SystemTransitionsExpectedErrors);
}
m_DeviceContext->CopyResource(StagingTex, m_AcquiredDesktopImage);
UINT subresource = D3D11CalcSubresource(0, 0, 0);
**hr = m_DeviceContext->Map(StagingTex, subresource, D3D11_MAP_READ, 0, rawBits);**
if (FAILED(hr)) {
}
m_DeviceContext->Unmap(StagingTex, subresource);
StagingTex->Release();
return DUPL_RETURN_SUCCESS;
}