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@gmail.com Sent: Thursday, August 15, 2019 5:16 AM To: Christopher Cifra christopher.cifra@ni.com Cc: wine-devel@winehq.org Subject: [EXTERNAL] Re: Wine for NET Core WPF Apps
On Thu, 15 Aug 2019 at 06:25, Christopher Cifra christopher.cifra@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