Вопрос об использовании расширения "WGL_NV_DX_interop2" для копирования текстуры из DX в GL - PullRequest
0 голосов
/ 07 июля 2019

моя программа использует API дублирования рабочего стола Windows для захвата экрана, захваченное изображение хранится в текстуре D3D11, поэтому я использую расширение "WGL_NV_DX_interop2", чтобы скопировать текстуру D3D в текстуру OpenGL, поскольку задача захвата экрана и рендеринг OpenGLзадача выполняется в другом потоке, я создаю текстуру D3D с именем tex_exchange и регистрирую ее как gl texture obj, задача захвата экрана копирует результат рендеринга в tex_exchange, а задача OpenGL копирует содержимое tex_exchange в текстуру gl;но я обнаружил, что когда задача OpenGL выполняет копирование текстуры, снимок экрана сообщит об ошибке, ошибка отчета API D3D - это ID3D11Device :: CreateShaderResourceView (), а код ошибки - 0x887A0005, похоже, у моего кода для копирования текстуры есть какая-то проблема, поэтому яопубликовать некоторый код моей программы, чтобы надеяться, что некоторые помогут;

// the function to create intermedia texture "tex_exchange"
D3D11_TEXTURE2D_DESC desc;
RtlZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
desc.Width = desktopDup->m_dupDesc.ModeDesc.Width;
desc.Height = desktopDup->m_dupDesc.ModeDesc.Height;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = 0;
desc.CPUAccessFlags = 0;
desc.MiscFlags = i0;
HRESULT hr = desktopDup->m_device->CreateTexture2D(&desc, NULL, ppTex);
if (FAILED(hr))
{
    gLogger->WriteLog(LogLevel::error, "%s() fail for CreateTexture2D() fail, hr=%08X", __FUNCTION__, hr);
    assert(S_OK == hr);
    return false;
}


// the function to register tex_exchange in OpenGL
gl_DXDev = wglDXOpenDeviceNV(desktopDup->m_device.p);
if (!gl_DXDev)
{
    gLogger->WriteLog(LogLevel::error, "%s() fail for glDXDev is null, glError=%u", __FUNCTION__,glGetError());
    assert(gl_DXDev);
    return E_FAIL;
}

glGenTextures(1, &gl_tex_id);
if (gl_tex_id == 0)
{
    gLogger->WriteLog(LogLevel::error, "%s() gen gl texture fail, glError=%u", __FUNCTION__, glGetError());
    assert(gl_tex_id);
    return E_FAIL;
}
glBindTexture(GL_TEXTURE_2D, gl_tex_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBindTexture(GL_TEXTURE_2D, 0);

gl_tex_obj = wglDXRegisterObjectNV(gl_DXDev, d3dtex_exchange.p, gl_tex_id, GL_TEXTURE_2D, WGL_ACCESS_READ_ONLY_NV);
if (!gl_tex_obj)
{
    gLogger->WriteLog(LogLevel::error, "%s() reg gl texture fail,errCode=%u", __FUNCTION__, GetLastError());
    assert(gl_tex_obj);
    return E_FAIL;
}

// the function to copy D3D Desktop Duplication rendering result to tex_exchange
desktopDup->m_context->CopyResource(d3dtex_exchange, desktopSurf);

// the function to copy tex_exchange to OpenGL
if (!wglDXLockObjectsNV(gl_DXDev, 1, &gl_tex_obj))  // when the function is called, DX task will report a error
{
    gLogger->WriteLog(LogLevel::error, "%s() wglDXLockObjectsNV() fail,errCode=%u", __FUNCTION__, GetLastError());
    assert(FALSE);
    return;
}

if (!wglDXUnlockObjectsNV(gl_DXDev, 1, &gl_tex_obj))
{
    gLogger->WriteLog(LogLevel::error, "%s() wglDXUnlockObjectsNV() fail,errCode=%u", __FUNCTION__, GetLastError());
    assert(FALSE);
    return;
}
...