[Interest] Qt/D3D integration through ANGLE PBuffer

Thomas Sevaldrud thomas at silentwings.no
Fri Sep 25 10:47:17 CEST 2015


That didn't help, unfortunately. I tried moving the setAttribute to no
effect.

If I try dereferencing the eglDisplay and eglConfig values like this:

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

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

    EGLSurface pbuffer = eglCreatePbufferSurface(*eglDisplay,
*eglConfig, attribs);


It simply crashes on the eglCreatePBufferSurface call. It appears that the
nativeResourceForContext call actually returns by value instead of by
address. For example, I usually get 0x3 for the eglConfig. Dereferencing
this as a pointer is probably not going well :-)


It appears that I can just as well do this:


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

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

    EGLSurface pbuffer = eglCreatePbufferSurface(eglDisplay,
eglConfig, attribs);


It still doesn't work though...


- Thomas


On Fri, Sep 25, 2015 at 10:16 AM, Agocs Laszlo <
laszlo.agocs at theqtcompany.com> wrote:

>
>  QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
>
>
> This should be set before constructing the QGuiApplication.
>
>     EGLSurface pbuffer = eglCreatePbufferSurface(m_eglDisplay, m_eglConfig, attribs);
>
> This should be eglCreatePbufferSurface(*m_eglDisplay, *m_eglConfig, attribs).
>
> Note that you may be running into the problem of the implementation offering different configs for different purpose and rejecting the non-matching ones.
> But try fixing the pbuffer creation first and see if that helps.
>
> BR,
> Laszlo
>
>
>
> ------------------------------
> *From:* Thomas Sevaldrud <thomas at silentwings.no>
> *Sent:* Friday, September 25, 2015 9:56 AM
> *To:* Agocs Laszlo
> *Cc:* Andrew Knight; Interest at qt-project.org
>
> *Subject:* Re: [Interest] Qt/D3D integration through ANGLE PBuffer
>
> Now I've tried a lot of other things, but I'm still not there...
>
> I've tried using eglChooseConfig on the eglDisplay I got from the
> QPlatformNativeInterface (with different variations of the attribList below)
>
>     const EGLint attribList[] =
>
>     {
>
>         EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
>
>         EGL_RED_SIZE, 8,
>
>         EGL_GREEN_SIZE, 8,
>
>         EGL_BLUE_SIZE, 8,
>
>         EGL_ALPHA_SIZE, 8,
>
>         EGL_DEPTH_SIZE, 16,
>
>         EGL_STENCIL_SIZE, 8,
>
>         EGL_NONE
>
>     };
>
>
>     EGLint iConfigs;
>
>     EGLConfig eglConfig;
>
>
>     eglChooseConfig(eglDisplay, attribList,
>
>                      &eglConfig, 1, &iConfigs);
>
>
> This returns no usable configs (iConfigs == 0).
>
> I've also tried going all EGL:
>
>     EGLDisplay eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
>     eglInitialize(eglDisplay, NULL, NULL);
>
>
> And used eglChooseConfig like above. This time I got the PBuffer and share
> handle, so this looks most promising. Now I could use an eglContext and
> QOpenGLContext->setNativeHandle() to get a context for use with Quick.
> However, when I try to create an eglContext I get EGL_BAD_CONFIG again...
>
>     EGLContext eglContext = eglCreateContext(eglDisplay, eglConfig, NULL,
> NULL);
>
>
> There must be something fundamental here that I have gotten wrong with
> regards to context and surface...
>
> - Thomas
>
>
>
>
> On Fri, Sep 25, 2015 at 12:03 AM, Thomas Sevaldrud <thomas at silentwings.no>
> wrote:
>
>> 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/f7964359/attachment.html>


More information about the Interest mailing list