microsoft / angle

ANGLE: OpenGL ES to DirectX translation
Other
615 stars 166 forks source link

DirectX interop - eglCreatePbufferFromClientBuffer not working #124

Closed claudiuslollarius closed 6 years ago

claudiuslollarius commented 7 years ago

Mainly to work around the issues with Swapchainpanel resizing, I am trying to use Angle to render to an off screen buffer and draw that as a Bitmaplmage using Win2D, which has been working well for me so far.

I am trying to follow the instructions outlined here, so:

Up to this point, everything seems to work: I get a non null handle. However calls to eglCreatePbufferFromClientBuffer always return EGL_NO_SURFACE, and glGetError() returns 0.

What am I doing wrong?

I am quoting the relevant code below. You can also check the full source here. (look in the LibretroRT.FrontendComponents.Renderer project)

void RenderTargetManager::CreateRenderTargets(CanvasAnimatedControl^ canvas, unsigned int width, unsigned int height)
{
    DestroyRenderTargets();

    ComPtr<ID3D11Device> d3dDevice;
    __abi_ThrowIfFailed(GetDXGIInterface(canvas->Device, d3dDevice.GetAddressOf()));

    D3D11_TEXTURE2D_DESC texDesc = { 0 };
    texDesc.Width = width;
    texDesc.Height = height;
    texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    texDesc.MipLevels = 1;
    texDesc.ArraySize = 1;
    texDesc.SampleDesc.Count = 1;
    texDesc.SampleDesc.Quality = 0;
    texDesc.Usage = D3D11_USAGE_DEFAULT;
    texDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
    texDesc.CPUAccessFlags = 0;
    texDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;

    ComPtr<ID3D11Texture2D> d3dTexture;
    __abi_ThrowIfFailed(d3dDevice->CreateTexture2D(&texDesc, nullptr, d3dTexture.GetAddressOf()));
    D3DTexture = d3dTexture;

    ComPtr<IDXGISurface> dxgiResource;
    __abi_ThrowIfFailed(d3dTexture.As(&dxgiResource));

    auto d3dsurface = CreateDirect3DSurface(dxgiResource.Get());
    Win2DTexture = CanvasBitmap::CreateFromDirect3D11Surface(canvas->Device, d3dsurface);

    OpenGLESSurface = OpenGLESManager->CreateSurface(D3DTexture);
    OpenGLESTexture = OpenGLESManager->CreateTextureFromSurface(OpenGLESSurface);
}
EGLSurface OpenGLES::CreateSurface(ComPtr<ID3D11Texture2D> d3dTexture)
{
    D3D11_TEXTURE2D_DESC textureDescription;
    d3dTexture->GetDesc(&textureDescription);

    ComPtr<IDXGIResource> dxgiResource;
    __abi_ThrowIfFailed(d3dTexture.As(&dxgiResource));
    HANDLE sharedHandle;
    __abi_ThrowIfFailed(dxgiResource->GetSharedHandle(&sharedHandle));

    EGLSurface output = EGL_NO_SURFACE;
    EGLint pBufferAttributes[] = { EGL_WIDTH, textureDescription.Width, EGL_HEIGHT, textureDescription.Height, EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, EGL_NONE };
    output = eglCreatePbufferFromClientBuffer(mEglDisplay, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, sharedHandle, mEglConfig, pBufferAttributes);
    if (output == EGL_NO_SURFACE)
    {
        throw Exception::CreateException(E_FAIL, L"Failed to create EGL surface");
    }

    return output;
}
austinkinross commented 7 years ago

Hi there, apologies for the delayed reply. Have you tried calling eglGetError rather than glGetError?

I recommend trying to use DXGI_FORMAT_B8G8R8A8_UNORM instead of R8G8B8A8. You should still use EGL_TEXTURE_RGBA in your pBufferAttributes though.

I also recommend comparing your code to the sample code available here:

Hope this helps!

austinkinross commented 6 years ago

I'm closing this old issue since I believe your question has been answered. Please feel free to reopen this issue if you have further questions on this topic. Thanks!

alexmercerind commented 1 year ago

Hi! Does this interop work on Windows 7 too?

I created a Direct3D 9 device & texture, took shared HANDLE from it & can confirm that it's working on Windows 10 & 11. But, it is showing a blank screen on Windows 7.

One more thing I'd like to mention is that I needed glFlush on Windows 11. Is there something I'm missing?

austinkinross commented 1 year ago

I recommend asking over on the main ANGLE repo, either their Google Group or their Slack channel. More info: https://chromium.googlesource.com/angle/angle/+/main/README.md