0

我正在使用 direct3d 和 dxgi 编写 VNC 程序,并且我想尽量减少视频 RAM 和系统 RAM 之间的资源传输。但是我对以下代码的某些部分感到困惑。由于AcquireNextFrame方法获取的纹理的使用不是 staging 并且不能被 CPU 读取,所以我必须将其复制到一个 staging 纹理。但我想知道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;

}

4

0 回答 0