Wine for NET Core WPF Apps

Christopher Cifra christopher.cifra at ni.com
Thu Aug 15 19:12:07 CDT 2019


That makes sense and matches what I am seeing.  The swapchain does have the correct window set on it by way of wined3d_swapchain_set_window.  But in wined3d_context_gl_acquire we get into the rendering offscreen case:

    if (current_context && current_context->current_rt.texture == texture)
    {
        ...
    }
    else if (texture && !wined3d_resource_is_offscreen(&texture->resource))
    {
        ...
    }
    else
    {
        TRACE("Rendering offscreen.\n");

        /* Stay with the current context if possible. Otherwise use the
         * context for the primary swapchain. */
        if (current_context && current_context->device == device)
            context = current_context;
        else if (!(context = swapchain_get_context(device->swapchains[0])))
            return NULL;
    }

Which then uses device->swapchains[0] to get the context.  device->swapchains[0] is not the correct swapchain and it does not have the same window.
Then wined3d_context_gl_activate is called with a context for the wrong window.

My first hack fix was to change what device->swapchains[0] was pointing to and that worked just fine.  It does not seem like that is a good idea though.
Passing in the swapchain allows the rendering offscreen case to use the specified swapchain instead of the first swapchain of the device.

I also tried always getting the swapchain from the texture but that caused other issues that I don't fully understand yet.

I can create a patch with my change if you think it may be easier for you to recommend a better alternative.  Here is a portion of the trace log of when things go wrong:
0034:trace:d3d:wined3d_device_end_scene device 0x1a4a3200.
0034:trace:d3d:wined3d_swapchain_present swapchain 0x1a3c5290, src_rect (864,562)-(996,623), dst_rect (864,562)-(996,623), dst_window_override 0x20056, swap_interval 0, flags 0.
0036:warn:d3d:wined3d_context_gl_bind_shader_resources No resource view bound at index 0, 0.
0034:trace:d3d:wined3d_device_begin_scene device 0x1a4a3200.
0036:trace:d3d:wined3d_context_gl_check_fbo_status FBO complete.
0034:trace:d3d:wined3d_query_create device 0x1a4a3200, type 0x8, parent 0x1a633f90, parent_ops 0x7f4518c8a750, query 0x1a633fa0.
0034:trace:d3d:wined3d_event_query_create device 0x1a4a3200, type 0x8, parent 0x1a633f90, parent_ops 0x7f4518c8a750, query 0x1a633fa0.
0034:trace:d3d:wined3d_event_query_create Created query 0x1a632360.
0034:trace:d3d:wined3d_query_get_data_size query 0x1a632360.
0034:trace:d3d:wined3d_query_issue query 0x1a632360, flags 0x1.
0034:trace:d3d:wined3d_device_end_scene device 0x1a4a3200.

0034:trace:d3d:wined3d_swapchain_present swapchain 0x1a639fb0, src_rect (0,0)-(1190,637), dst_rect (0,0)-(1190,637), dst_window_override 0x1005e, swap_interval 0, flags 0.
^ here we are presenting the swap chain that should render into the second window

0036:trace:d3d:wined3d_context_gl_release Releasing context 0x1a419180, level 1.
0036:trace:d3d:wined3d_cs_run WINED3D_CS_OP_DRAW executed.
0036:trace:d3d:wined3d_cs_run Executing WINED3D_CS_OP_PRESENT.
0036:trace:d3d:wined3d_context_gl_acquire device 0x1a4a3200, texture 0x1a56b530, sub_resource_idx 0.
0036:trace:d3d:wined3d_context_gl_acquire Rendering offscreen.
0036:trace:d3d:wined3d_context_gl_enter Entering context 0x1a419180, level 1.

0036:trace:d3d:swapchain_gl_present Presenting DC 0x27003f.
^ This is the same DC as when we render into the first window

0036:trace:d3d:wined3d_texture_load_location texture 0x1a56b530, sub_resource_idx 0, context 0x1a419180, location WINED3D_LOCATION_TEXTURE_RGB.
0036:trace:d3d:wined3d_texture_load_location Current resource location WINED3D_LOCATION_TEXTURE_RGB.
0036:trace:d3d:wined3d_texture_load_location Location WINED3D_LOCATION_TEXTURE_RGB is already up to date.
0036:trace:d3d:swapchain_blit swapchain 0x1a3c5290, context 0x1a419180, src_rect (864,562)-(996,623), dst_rect (864,562)-(996,623).

dst_window_override 0x1005e is the second window.
When we present with that override we will enter the Renering offscreen case and use device->swapchaings[0].  You can then see that we are presenting to DC 0x27003f which is the same one as when we present to the first window.

Thanks for all of your help!
  --Chris



-----Original Message-----
From: Henri Verbeet <hverbeet at gmail.com> 
Sent: Thursday, August 15, 2019 5:16 AM
To: Christopher Cifra <christopher.cifra at ni.com>
Cc: wine-devel at winehq.org
Subject: [EXTERNAL] Re: Wine for NET Core WPF Apps

On Thu, 15 Aug 2019 at 06:25, Christopher Cifra <christopher.cifra at ni.com> wrote:
> I figured out the issues with multiple windows and WPF.  WPF passes in an override window to SwapChain Present when it wants to draw into a specific window.  In Wine when swapchain_gl_present calls context_acquire the context returned is for the wrong window because it does not look at the override window of the swap chain. I can fix the issue but it requires modifying context_acquire to take the swap chain as a parameter.  In the failure case there is no texture passed to context_acquire because the swap chain does not have a back buffer so I do not have a way to get the correct swap chain.  Because there is no texture wined3d_context_gl_acquire uses the first swap chain of the device which is not the correct swap chain and has a different window.
>

That doesn't sound quite right. The override window is handled by the
wined3d_swapchain_set_window() call in wined3d_cs_exec_present(), and then applied to the context by the wined3d_context_gl_update_window()
call in wined3d_context_gl_activate().

The context_acquire() call in swapchain_gl_present() passes in the frontbuffer, but if the swapchain didn't have any backbuffers you wouldn't get there in the first place; wined3d_swapchain_present() would return an error.

Henri


More information about the wine-devel mailing list