From: Paul Gofman gofmanp@gmail.com
Signed-off-by: Paul Gofman gofmanp@gmail.com Signed-off-by: Henri Verbeet hverbeet@codeweavers.com --- This supersedes patch 173737.
dlls/wined3d/context.c | 232 +++++++++++++++++++++++++++---------------------- 1 file changed, 128 insertions(+), 104 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index f4c0d46f8e6..5b8402bfe4f 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -1935,93 +1935,22 @@ HRESULT wined3d_context_no3d_init(struct wined3d_context *context_no3d, struct w return WINED3D_OK; }
-HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wined3d_swapchain_gl *swapchain_gl) +static BOOL wined3d_context_gl_create_wgl_ctx(struct wined3d_context_gl *context_gl, + struct wined3d_swapchain_gl *swapchain_gl) { - const struct wined3d_format *color_format, *ds_format; + const struct wined3d_format *colour_format, *ds_format; struct wined3d_context *context = &context_gl->c; - const struct wined3d_d3d_info *d3d_info; const struct wined3d_gl_info *gl_info; struct wined3d_resource *target; + struct wined3d_adapter *adapter; unsigned int target_bind_flags; struct wined3d_device *device; HGLRC ctx, share_ctx; unsigned int i;
- TRACE("context_gl %p, swapchain %p.\n", context_gl, swapchain_gl); - - wined3d_context_init(&context_gl->c, &swapchain_gl->s); - device = context->device; - gl_info = &device->adapter->gl_info; - context_gl->gl_info = gl_info; - d3d_info = context->d3d_info; - - context_gl->tid = GetCurrentThreadId(); - context_gl->window = context->swapchain->win_handle; - if (context_gl->window == GetDesktopWindow()) - { - TRACE("Swapchain is created on the desktop window, trying backup device context.\n"); - context_gl->dc = NULL; - } - else if (!(context_gl->dc = GetDCEx(context_gl->window, 0, DCX_USESTYLE | DCX_CACHE))) - WARN("Failed to retrieve device context, trying swapchain backup.\n"); - - if (!context_gl->dc) - { - if (!(context_gl->dc = wined3d_swapchain_gl_get_backup_dc(swapchain_gl))) - { - ERR("Failed to retrieve a device context.\n"); - return E_FAIL; - } - context_gl->dc_is_private = TRUE; - } - - list_init(&context_gl->fbo_list); - list_init(&context_gl->fbo_destroy_list); - - list_init(&context_gl->occlusion_queries); - list_init(&context_gl->fences); - list_init(&context_gl->timestamp_queries); - list_init(&context_gl->so_statistics_queries); - list_init(&context_gl->pipeline_statistics_queries); - - for (i = 0; i < ARRAY_SIZE(context_gl->tex_unit_map); ++i) - context_gl->tex_unit_map[i] = WINED3D_UNMAPPED_STAGE; - for (i = 0; i < ARRAY_SIZE(context_gl->rev_tex_unit_map); ++i) - context_gl->rev_tex_unit_map[i] = WINED3D_UNMAPPED_STAGE; - if (gl_info->limits.graphics_samplers >= WINED3D_MAX_COMBINED_SAMPLERS) - { - /* Initialize the texture unit mapping to a 1:1 mapping. */ - unsigned int base, count; - - wined3d_gl_limits_get_texture_unit_range(&gl_info->limits, WINED3D_SHADER_TYPE_PIXEL, &base, &count); - if (base + WINED3D_MAX_FRAGMENT_SAMPLERS > ARRAY_SIZE(context_gl->rev_tex_unit_map)) - { - ERR("Unexpected texture unit base index %u.\n", base); - goto fail; - } - for (i = 0; i < min(count, WINED3D_MAX_FRAGMENT_SAMPLERS); ++i) - { - context_gl->tex_unit_map[i] = base + i; - context_gl->rev_tex_unit_map[base + i] = i; - } - - wined3d_gl_limits_get_texture_unit_range(&gl_info->limits, WINED3D_SHADER_TYPE_VERTEX, &base, &count); - if (base + WINED3D_MAX_VERTEX_SAMPLERS > ARRAY_SIZE(context_gl->rev_tex_unit_map)) - { - ERR("Unexpected texture unit base index %u.\n", base); - goto fail; - } - for (i = 0; i < min(count, WINED3D_MAX_VERTEX_SAMPLERS); ++i) - { - context_gl->tex_unit_map[WINED3D_MAX_FRAGMENT_SAMPLERS + i] = base + i; - context_gl->rev_tex_unit_map[base + i] = WINED3D_MAX_FRAGMENT_SAMPLERS + i; - } - } - - if (!(context_gl->texture_type = heap_calloc(gl_info->limits.combined_samplers, - sizeof(*context_gl->texture_type)))) - goto fail; + adapter = device->adapter; + gl_info = &adapter->gl_info;
target = &context->current_rt.texture->resource; target_bind_flags = target->bind_flags; @@ -2037,14 +1966,14 @@ HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wi WINED3DFMT_S1_UINT_D15_UNORM, };
- color_format = target->format; + colour_format = target->format;
/* In case of ORM_BACKBUFFER, make sure to request an alpha component for * X4R4G4B4/X8R8G8B8 as we might need it for the backbuffer. */ - if (color_format->id == WINED3DFMT_B4G4R4X4_UNORM) - color_format = wined3d_get_format(device->adapter, WINED3DFMT_B4G4R4A4_UNORM, target_bind_flags); - else if (color_format->id == WINED3DFMT_B8G8R8X8_UNORM) - color_format = wined3d_get_format(device->adapter, WINED3DFMT_B8G8R8A8_UNORM, target_bind_flags); + if (colour_format->id == WINED3DFMT_B4G4R4X4_UNORM) + colour_format = wined3d_get_format(adapter, WINED3DFMT_B4G4R4A4_UNORM, target_bind_flags); + else if (colour_format->id == WINED3DFMT_B8G8R8X8_UNORM) + colour_format = wined3d_get_format(adapter, WINED3DFMT_B8G8R8A8_UNORM, target_bind_flags);
/* DirectDraw supports 8bit paletted render targets and these are used by * old games like StarCraft and C&C. Most modern hardware doesn't support @@ -2052,17 +1981,17 @@ HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wi * conversion (ab)uses the alpha component for storing the palette index. * For this reason we require a format with 8bit alpha, so request * A8R8G8B8. */ - if (color_format->id == WINED3DFMT_P8_UINT) - color_format = wined3d_get_format(device->adapter, WINED3DFMT_B8G8R8A8_UNORM, target_bind_flags); + if (colour_format->id == WINED3DFMT_P8_UINT) + colour_format = wined3d_get_format(adapter, WINED3DFMT_B8G8R8A8_UNORM, target_bind_flags);
/* Try to find a pixel format which matches our requirements. */ if (!swapchain_gl->s.ds_format) { for (i = 0; i < ARRAY_SIZE(ds_formats); ++i) { - ds_format = wined3d_get_format(device->adapter, ds_formats[i], WINED3D_BIND_DEPTH_STENCIL); + ds_format = wined3d_get_format(adapter, ds_formats[i], WINED3D_BIND_DEPTH_STENCIL); if ((context_gl->pixel_format = context_choose_pixel_format(device, - context_gl->dc, color_format, ds_format, TRUE))) + context_gl->dc, colour_format, ds_format, TRUE))) { swapchain_gl->s.ds_format = ds_format; break; @@ -2075,7 +2004,7 @@ HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wi else { context_gl->pixel_format = context_choose_pixel_format(device, - context_gl->dc, color_format, swapchain_gl->s.ds_format, TRUE); + context_gl->dc, colour_format, swapchain_gl->s.ds_format, TRUE); } } else @@ -2085,17 +2014,20 @@ HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wi * don't need depth or stencil buffers, and can mostly ignore the render * target format. This wouldn't necessarily be quite correct for 10bpc * display modes, but we don't currently support those. - * Using the same format regardless of the color/depth/stencil targets + * Using the same format regardless of the colour/depth/stencil targets * makes it much less likely that different wined3d instances will set * conflicting pixel formats. */ - color_format = wined3d_get_format(device->adapter, WINED3DFMT_B8G8R8A8_UNORM, target_bind_flags); - ds_format = wined3d_get_format(device->adapter, WINED3DFMT_UNKNOWN, WINED3D_BIND_DEPTH_STENCIL); + colour_format = wined3d_get_format(adapter, WINED3DFMT_B8G8R8A8_UNORM, target_bind_flags); + ds_format = wined3d_get_format(adapter, WINED3DFMT_UNKNOWN, WINED3D_BIND_DEPTH_STENCIL); context_gl->pixel_format = context_choose_pixel_format(device, - context_gl->dc, color_format, ds_format, FALSE); + context_gl->dc, colour_format, ds_format, FALSE); }
if (!context_gl->pixel_format) - goto fail; + { + ERR("Failed to choose pixel format.\n"); + return FALSE; + }
wined3d_context_gl_enter(context_gl);
@@ -2103,7 +2035,7 @@ HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wi { ERR("Failed to set pixel format %d on device context %p.\n", context_gl->pixel_format, context_gl->dc); context_release(context); - goto fail; + return FALSE; }
share_ctx = device->context_count ? wined3d_context_gl(device->contexts[0])->gl_ctx : NULL; @@ -2111,8 +2043,9 @@ HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wi { if (!(ctx = context_create_wgl_attribs(gl_info, context_gl->dc, share_ctx))) { + ERR("Failed to create a WGL context.\n"); context_release(context); - goto fail; + return FALSE; } } else @@ -2121,7 +2054,7 @@ HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wi { ERR("Failed to create a WGL context.\n"); context_release(context); - goto fail; + return FALSE; }
if (share_ctx && !wglShareLists(share_ctx, ctx)) @@ -2130,25 +2063,116 @@ HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wi context_release(context); if (!wglDeleteContext(ctx)) ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx, GetLastError()); - goto fail; + return FALSE; } }
- context->render_offscreen = wined3d_resource_is_offscreen(target); - context_gl->draw_buffers_mask = context_generate_rt_mask(GL_BACK); - context_gl->valid = 1; - - context_gl->gl_ctx = ctx; context_gl->dc_has_format = TRUE; context_gl->needs_set = 1; + context_gl->valid = 1; + context_gl->gl_ctx = ctx; + + return TRUE; +} + +HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wined3d_swapchain_gl *swapchain_gl) +{ + struct wined3d_context *context = &context_gl->c; + const struct wined3d_d3d_info *d3d_info; + const struct wined3d_gl_info *gl_info; + struct wined3d_device *device; + unsigned int i; + + TRACE("context_gl %p, swapchain %p.\n", context_gl, swapchain_gl); + + wined3d_context_init(&context_gl->c, &swapchain_gl->s); + + device = context->device; + gl_info = &device->adapter->gl_info; + context_gl->gl_info = gl_info; + d3d_info = context->d3d_info; + + context_gl->tid = GetCurrentThreadId(); + context_gl->window = context->swapchain->win_handle; + if (context_gl->window == GetDesktopWindow()) + { + TRACE("Swapchain is created on the desktop window, trying backup device context.\n"); + context_gl->dc = NULL; + } + else if (!(context_gl->dc = GetDCEx(context_gl->window, 0, DCX_USESTYLE | DCX_CACHE))) + WARN("Failed to retrieve device context, trying swapchain backup.\n"); + + if (!context_gl->dc) + { + if (!(context_gl->dc = wined3d_swapchain_gl_get_backup_dc(swapchain_gl))) + { + ERR("Failed to retrieve a device context.\n"); + return E_FAIL; + } + context_gl->dc_is_private = TRUE; + } + + list_init(&context_gl->fbo_list); + list_init(&context_gl->fbo_destroy_list); + + list_init(&context_gl->occlusion_queries); + list_init(&context_gl->fences); + list_init(&context_gl->timestamp_queries); + list_init(&context_gl->so_statistics_queries); + list_init(&context_gl->pipeline_statistics_queries); + + for (i = 0; i < ARRAY_SIZE(context_gl->tex_unit_map); ++i) + context_gl->tex_unit_map[i] = WINED3D_UNMAPPED_STAGE; + for (i = 0; i < ARRAY_SIZE(context_gl->rev_tex_unit_map); ++i) + context_gl->rev_tex_unit_map[i] = WINED3D_UNMAPPED_STAGE; + if (gl_info->limits.graphics_samplers >= WINED3D_MAX_COMBINED_SAMPLERS) + { + /* Initialize the texture unit mapping to a 1:1 mapping. */ + unsigned int base, count; + + wined3d_gl_limits_get_texture_unit_range(&gl_info->limits, WINED3D_SHADER_TYPE_PIXEL, &base, &count); + if (base + WINED3D_MAX_FRAGMENT_SAMPLERS > ARRAY_SIZE(context_gl->rev_tex_unit_map)) + { + ERR("Unexpected texture unit base index %u.\n", base); + goto fail; + } + for (i = 0; i < min(count, WINED3D_MAX_FRAGMENT_SAMPLERS); ++i) + { + context_gl->tex_unit_map[i] = base + i; + context_gl->rev_tex_unit_map[base + i] = i; + } + + wined3d_gl_limits_get_texture_unit_range(&gl_info->limits, WINED3D_SHADER_TYPE_VERTEX, &base, &count); + if (base + WINED3D_MAX_VERTEX_SAMPLERS > ARRAY_SIZE(context_gl->rev_tex_unit_map)) + { + ERR("Unexpected texture unit base index %u.\n", base); + goto fail; + } + for (i = 0; i < min(count, WINED3D_MAX_VERTEX_SAMPLERS); ++i) + { + context_gl->tex_unit_map[WINED3D_MAX_FRAGMENT_SAMPLERS + i] = base + i; + context_gl->rev_tex_unit_map[base + i] = WINED3D_MAX_FRAGMENT_SAMPLERS + i; + } + } + + if (!(context_gl->texture_type = heap_calloc(gl_info->limits.combined_samplers, + sizeof(*context_gl->texture_type)))) + goto fail; + + if (!wined3d_context_gl_create_wgl_ctx(context_gl, swapchain_gl)) + goto fail; + + /* Set up the context defaults. */ + + context->render_offscreen = wined3d_resource_is_offscreen(&context->current_rt.texture->resource); + context_gl->draw_buffers_mask = context_generate_rt_mask(GL_BACK);
- /* Set up the context defaults */ if (!wined3d_context_gl_set_current(context_gl)) { ERR("Cannot activate context to set up defaults.\n"); context_release(context); - if (!wglDeleteContext(ctx)) - ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx, GetLastError()); + if (!wglDeleteContext(context_gl->gl_ctx)) + ERR("wglDeleteContext(%p) failed, last error %#x.\n", context_gl->gl_ctx, GetLastError()); goto fail; }