[Interest] Qt/D3D integration through ANGLE PBuffer
Thomas Sevaldrud
thomas at silentwings.no
Fri Sep 25 09:56:05 CEST 2015
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/c7c90577/attachment.html>
More information about the Interest
mailing list