为什么 ID3D11DeviceContext::map() 函数不起作用并返回 E_INVALIDAGR(一个或多个参数无效)
当我想使用 DXGI Duplication API 截图时,deviceContext->map()
总是失败。它返回E_INVALIDAGR(一个或多个参数无效)。不过,我认为没有任何论据是无效的。我不知道如何解决这个问题。这是我的代码。 (所有初始化均成功,包括device
、deviceContext
、dxgiOutputDuplication
)。
/*
this function take a screenshot and save the bmp image of the screenshot to the data pointer.
@param BYTE* data: (out) The pointer to a BYTE array where the bmp image will be saved to.
@return ULARGE_INTEGER: the size of bmp image.
*/
ULARGE_INTEGER GetFrame(BYTE* data) {
IDXGIResource* desktopResource = nullptr;
DXGI_OUTDUPL_FRAME_INFO FrameInfo{};
ID3D11Texture2D* acquiredDesktopImage = nullptr;
//Get new frame
HRESULT hr = 0;
do {
hr = dxgiOutputDuplication->AcquireNextFrame(1000, &FrameInfo, &desktopResource);
} while (hr != S_OK);
hr = desktopResource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&acquiredDesktopImage));
if (hr != S_OK) {
printf("failed to query interface\n");
}
D3D11_MAPPED_SUBRESOURCE* resource = new D3D11_MAPPED_SUBRESOURCE();
ID3D11Texture2D* copiedImage = nullptr;
D3D11_TEXTURE2D_DESC desc{};
acquiredDesktopImage->GetDesc(&desc);
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
hr = device->CreateTexture2D(&desc, NULL, &copiedImage);
if (hr != S_OK) {
printf("failed to create texture\n");
}
deviceContext->CopyResource(copiedImage, acquiredDesktopImage);
hr = deviceContext->Map(copiedImage, 0, D3D11_MAP_READ, NULL, resource);
// always failed in the upper line.
if (hr != S_OK) {
printf("failed to map\n");
}
ULARGE_INTEGER length = encodeData(dxgiOutDuplDesc.ModeDesc.Width, dxgiOutDuplDesc.ModeDesc.Height, resource->RowPitch, resource->pData, data);
// This function is to encode the data from rgb matrix to bmp format.
// Here is the description of this function.
/*
encode RGB matrix to bmp format and save it into data
@param int width: (in) matrix width
@param int height: (in) matrix height
@param UINT stride: (in) the size of a line of matrix
@param void* pixels: (in) data source pointer
@param BYTE* data: (out) data result pointer
@return ULARGE_INTEGER: data result length
*/
desktopResource->Release();
acquiredDesktopImage->Release();
delete resource;
return length;
}
这是初始化函数。
BOOL initDevice() {
IDXGIDevice* dxgiDevice = nullptr;
IDXGIAdapter* dxgiAdapter = nullptr;
IDXGIOutput* dxgiOutput = nullptr;
IDXGIOutput1* dxgiOutput1 = nullptr;
D3D_FEATURE_LEVEL feature_levels[] = {
D3D_FEATURE_LEVEL_11_0
};
CHECK_RESULT(D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_DEBUG, feature_levels, ARRAYSIZE(feature_levels), D3D11_SDK_VERSION, &device, NULL, &deviceContext));
printf("successful init create d3d11 device\n");
// Get DXGI device
CHECK_RESULT(device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice)));
// Get DXGI adapter
CHECK_RESULT(dxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&dxgiAdapter)));
// Get output
CHECK_RESULT(dxgiAdapter->EnumOutputs(0, &dxgiOutput));
CHECK_RESULT(dxgiOutput->GetDesc(&dxgiOutputDesc));
// QI for Output 1
CHECK_RESULT(dxgiOutput->QueryInterface(__uuidof(dxgiOutput1), reinterpret_cast<void**>(&dxgiOutput1)));
// Create desktop duplication
CHECK_RESULT(dxgiOutput1->DuplicateOutput(device, &dxgiOutputDuplication));
dxgiOutputDuplication->GetDesc(&dxgiOutDuplDesc);
dxgiDevice->Release();
dxgiDevice = nullptr;
dxgiAdapter->Release();
dxgiAdapter = nullptr;
dxgiOutput->Release();
dxgiOutput = nullptr;
dxgiOutput1->Release();
dxgiOutput1 = nullptr;
return true;
}
这是我使用的宏。
#define CHECK_RESULT(func) if ((func) != S_OK) return false
我尝试更改desc(D3D11_TEXTURE2D_DESC)
的几乎所有参数,但都无法成功。另外,我搜索过这个问题,他们文章上的代码和我的一样,所以我对发生的事情感到非常困惑。有人能帮我吗?我将非常感谢你的帮助。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的“copiedImage”纹理对于映射无效:
应该类似于:
看看这个 ScreenGrab 代码。
您也没有释放您的
copiedImage
纹理。您应该考虑使用 COM 智能指针,例如 Microsoft::WRL::ComPtr避免资源泄漏。Your 'copiedImage' texture is not valid for mapping:
should be something like:
Take a look at this ScreenGrab code on GitHub.
You also didn't release your
copiedImage
texture. You should consider using a COM smart-pointer like Microsoft::WRL::ComPtr to avoid resource leaks.