[Interest] Qt/D3D integration through ANGLE PBuffer
Thomas Sevaldrud
thomas at silentwings.no
Fri Sep 25 11:11:19 CEST 2015
Finally success!
As always it was a simple and stupid mistake.... It appears that I have
linked with the release version of libEGL in the debug version of my test
program. Linking with the debug version solved it. Now I get a pbuffer and
share handle using the QOpenGLContext. Mixing debug and release libs always
bites me on the Windows platform :-(
Now I just need to get the QSG running :-)
Thanks for all help this far!
- Thomas
On Fri, Sep 25, 2015 at 10:47 AM, Thomas Sevaldrud <thomas at silentwings.no>
wrote:
> 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/6c654092/attachment.html>
More information about the Interest
mailing list