[Interest] Qt/D3D integration through ANGLE PBuffer

Thomas Sevaldrud thomas at silentwings.no
Fri Sep 25 00:03:52 CEST 2015


Ok, I've experimented a bit here now, but I am struggling to get a valid
PBuffer (eglCreatePBufferSurface returns 0).

I have tried creating a new QOpenGLContext and pull the eglDisplay and
eglConfig from that through the nativeResourceForContext.

If I have only the Context without any surface to begin with, I get
EGL_NOT_INITIALIZED.

If I add an QOffscreenSurface and make the context current on this, I get
EGL_BAD_CONFIG.

This is the relevant code, any idea what I'm doing wrong here?

    QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);


    QSurfaceFormat format;

    format.setRenderableType(QSurfaceFormat::OpenGLES);


    m_glContext = new QOpenGLContext;

    m_glContext->setFormat(format);


    m_glContext->create();


    QOffscreenSurface* surf = new QOffscreenSurface();

    surf->setFormat(format);

    surf->create();


    m_glContext->makeCurrent(surf);


    QPlatformNativeInterface *nativeInterface =
QGuiApplication::platformNativeInterface();

    EGLDisplay* m_eglDisplay =
static_cast<EGLDisplay*>(nativeInterface->nativeResourceForContext("eglDisplay",
m_glContext));

    EGLConfig* m_eglConfig =
static_cast<EGLConfig*>(nativeInterface->nativeResourceForContext("eglConfig",
m_glContext));


    EGLint attribs[] = {

        EGL_WIDTH, 1024,

        EGL_HEIGHT, 1024,

        EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,

        EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,

        EGL_NONE

    };


    EGLSurface pbuffer = eglCreatePbufferSurface(m_eglDisplay,
m_eglConfig, attribs);

    int err = eglGetError(); // Returns EGL_BAD_CONFIG



On Thu, Sep 24, 2015 at 7:05 PM, Agocs Laszlo <laszlo.agocs at theqtcompany.com
> wrote:

> Right. You can either use eglChooseConfig or pull it with
> nativeResourceForContext from the context you will use for the Qt Quick
> rendering.  The latter is probably the way to go since you also need the
> display, and eglGetCurrentDisplay() is not helpful at that stage due to the
> lack of a current context.
>
>
>
> Laszlo
>
>
>
>
>
> *From:* Thomas Sevaldrud [mailto:thomas at silentwings.no]
> *Sent:* 24. september 2015 17:11
> *To:* Agocs Laszlo <laszlo.agocs at theqtcompany.com>
> *Cc:* Andrew Knight <andrew.knight at intopalo.com>; Interest at qt-project.org
>
> *Subject:* Re: [Interest] Qt/D3D integration through ANGLE PBuffer
>
>
>
> Ok, but I see that they use the existing context to get the eglDisplay and
> eglConfig parameters that are needed for the createPBufferSurface call:
>
>
>
>     QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
>
>     m_eglDisplay = static_cast<EGLDisplay*>(
>
>                 nativeInterface->nativeResourceForContext("eglDisplay", currentContext));
>
>     m_eglConfig = static_cast<EGLConfig*>(
>
>                 nativeInterface->nativeResourceForContext("eglConfig", currentContext));
>
>
>
> I suppose I can use eglGetDisplay and eglChooseConfig to get these, but
> how do I create a QOpenGLContext that matches the eglConfig? I need this
> for the QQuickRenderControl.
>
>
>
> - Thomas
>
>
>
> On Thu, Sep 24, 2015 at 5:02 PM, Agocs Laszlo <
> laszlo.agocs at theqtcompany.com> wrote:
>
> That’s most likely used only for the texture handle that gets generated in
> that function. Neither that nor the EGL_TEXTURE_* parameters are relevant
> in your case.
>
>
>
> Cheers,
>
> Laszlo
>
>
>
> *From:* interest-bounces+laszlo.agocs=theqtcompany.com at qt-project.org
> [mailto:interest-bounces+laszlo.agocs=theqtcompany.com at qt-project.org] *On
> Behalf Of *Thomas Sevaldrud
> *Sent:* 24. september 2015 16:46
> *To:* Andrew Knight <andrew.knight at intopalo.com>
> *Cc:* Interest at qt-project.org
> *Subject:* Re: [Interest] Qt/D3D integration through ANGLE PBuffer
>
>
>
> Ah, excellent, so I just set up a QQuickWindow with the RenderControl as
> parent, right?
>
>
> Just one more question:
>
>
>
> In the QtMultimedia D3D9 example they set up a QOpenGLContext with an
> invisble QWindow as current context before creating the EGL Pbuffer. I
> suppose this is in order to get the correct EGL Config and surface
> parameters? I suppose I could just as well use a QOffscreenSurface as the
> hidden QWindow? Is this the best way to do it? It just seems a little
> backwards to create an offscreen surface first in order to create the
> offscreen surface I actually want... Or maybe I'm not thinking straight
> here :-)
>
>
>
> - Thomas
>
>
>
>
>
> On Thu, Sep 24, 2015 at 4:30 PM, Andrew Knight <andrew.knight at intopalo.com>
> wrote:
>
> Hi,
>
> On 09/24/2015 05:15 PM, Thomas Sevaldrud wrote:
>
> This is great, thanks for very useful info!
>
> I'm not sure I understood Andew's part about rendering the Quick Scene
> graph, or I may have been a bit unclear when describing the problem.
> Basically I want to render a Qt Quick scene graph and some custom OpenGL
> graphics into a Direct3D control (D3DImage in WPF). What Andew suggests
> would be the other way around I think? I.e use a D3D texture in the scene
> graph? Or did I misunderstand?
>
>
> Yes, that's what I was referring to. Sorry for the misunderstanding.
>
> As Laszlo suggests I'll try using QQuickRenderControl to render my scene
> into the PBuffer/D3D texture, but I must admit I am a bit confused as to
> how this works too. For instance I'm not sure I understand how to set up
> the QML Engine so that it is associated with the QQuickRenderControl. In
> the QuickRenderControl example from Qt 5.5 it appears that they set up the
> QML Engine in a QQuickWindow with an FBO as render target. In my case I
> need the EGL PBuffer as render target. How would I go about doing that?
>
>
> You don't need the QOpenGLFramebufferObject in this case. As Laszlo said,
> simply bind the pbuffer and it will become the current render target. The
> scene graph will render to the pbuffer and you can use that in your D3D
> scene as a normal texture.
>
> - Thomas
>
>
>
>
>
>
>
> On Thu, Sep 24, 2015 at 2:48 PM, Andrew Knight <andrew.knight at intopalo.com
> <mailto:andrew.knight at intopalo.com>> wrote:
>
>     Hi Thomas,
>
>     On 09/24/2015 03:11 PM, Thomas Sevaldrud wrote:
>
>         Hi,
>
>         I have earlier made an implementation of Qt/D3D integration by
>         hacking into the ANGLE D3D SwapChain and extracting the
>         D3DSurface directly there.
>
>         However, this is a bit flakey, and I have had to change this
>         code several times when new versions of Qt and ANGLE are released.
>
>         So, now I want to do this the supported way through the
>         EGL_ANGLE_surface_d3d_texture_2d_share_handle extension. If I
>         understand this correctly I can set up a PBuffer-based render
>         target which I can query for a D3D texture sharing handle
>         using the eglQuerySurfacePointerANGLE extension.
>
>
>     Yes, this is possible.
>
>         Now, before I start coding, I wonder if anyone has an example
>         of using this extension for rendering to a D3D Texture?
>         Someone mentioned on the list earlier that there should be an
>         example of this in QtMultimedia, but I haven't been able to
>         find it.
>
>
>     The two places this extension is used are at:
>     (D3D11)
>
> http://code.qt.io/cgit/qt/qtmultimedia.git/tree/src/plugins/winrt/qwinrtabstractvideorenderercontrol.cpp#n372
>
>     This one creates a shared texture using D3D and shares it with
>     ANGLE. This texture is updated when a video player or camera
>     queues a frame. It is bound to the pipeline with a QOpenGLTexture
>     object and eglBindTexImage().
>
>     (D3D9)
>
> http://code.qt.io/cgit/qt/qtmultimedia.git/tree/src/plugins/wmf/evrd3dpresentengine.cpp#n451
>
>     This one first creates a pbuffer using EGL, gets the shared
>     texture handle from it, and then opens up the texture in D3D.
>
>     Both cases are therefore covered, as well as both major D3D versions.
>
>         Also, for the PBuffer implementation, should I create a
>         PBuffer directly through EGL, or can I use QOffsceenSurface?
>         If I understand correctly, QOffscreenSurface will be
>         implemented with a PBuffer on Windows?
>         To complicate matters even more I want to include a Quick
>         scene graph in this as well, but I suppose I can use the new
>         QQuickRenderControl class for this when I have the PBuffer
>         render target sorted out?
>
>
>     I would just render to your D3D texture (by creating it via one of
>     the ways described above) and use it in the scene graph by binding
>     its content to the currently bound QOpenGLTexture object with
>     eglBindTexImage(). You can create a QSGTexture from a
>     QOpenGLTexture by passing the texture id to
>     QSGEngine::createTextureFromId().
>
>         Best regards,
>         Thomas
>
>
>         _______________________________________________
>         Interest mailing list
>
>         Interest at qt-project.org <mailto:Interest at qt-project.org>
>         http://lists.qt-project.org/mailman/listinfo/interest
>
>
>
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20150925/6e4bcede/attachment.html>


More information about the Interest mailing list