[PATCH] wined3d: Avoid calling removed/deprecated GL functions in SetupForBlit().

Matteo Bruni matteo.mystral at gmail.com
Fri Dec 8 09:01:37 CST 2017


2017-12-08 10:41 GMT+01:00 Józef Kucia <jkucia at codeweavers.com>:
> Eliminates possible GL errors when core contexts are used.
>
> Signed-off-by: Józef Kucia <jkucia at codeweavers.com>

I'd rather go in a slightly different direction for this i.e. see the
attached patch.

I'm not rejecting your patch though.
-------------- next part --------------
commit 0deb0ba0475d1a9fd9032640dc14175939763eb0
Author: Matteo Bruni <mbruni at codeweavers.com>
Date:   Fri Oct 23 23:12:55 2015 +0200

    wined3d: Put FFP blit setup in a separate function.
    
    To be able to avoid setting up states that aren't relevant for some
    blitters.
    FIXME: context_apply_blit_ffp_state() should probably manage its own
    context flag (last_was_ffp_blit?) to avoid redundant work and avoid
    potential performance regressions.

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 6941a2bb3c..894c715427 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -7833,6 +7833,7 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl
         wined3d_texture_load(src_texture, context, FALSE);
 
     context_apply_blit_state(context, device);
+    context_apply_blit_ffp_state(context, device);
 
     if (dst_location == WINED3D_LOCATION_DRAWABLE)
     {
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 23f63aacda..fe9a011825 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -2379,55 +2379,17 @@ void context_enable_clip_distances(struct wined3d_context *context, unsigned int
     checkGLcall("toggle clip distances");
 }
 
-/*****************************************************************************
- * SetupForBlit
- *
- * Sets up a context for DirectDraw blitting.
- * All texture units are disabled, texture unit 0 is set as current unit
- * fog, lighting, blending, alpha test, z test, scissor test, culling disabled
- * color writing enabled for all channels
- * register combiners disabled, shaders disabled
- * world matrix is set to identity, texture matrix 0 too
- * projection matrix is setup for drawing screen coordinates
- *
- * Params:
- *  This: Device to activate the context for
- *  context: Context to setup
- *
- *****************************************************************************/
+/* Setup OpenGL states for fixed-function blitting. */
 /* Context activation is done by the caller. */
-static void SetupForBlit(const struct wined3d_device *device, struct wined3d_context *context)
+void context_apply_blit_ffp_state(struct wined3d_context *context, const struct wined3d_device *device)
 {
     int i;
     const struct wined3d_gl_info *gl_info = context->gl_info;
     DWORD sampler;
     SIZE rt_size;
 
-    TRACE("Setting up context %p for blitting\n", context);
-
-    context_get_rt_size(context, &rt_size);
-
-    if (context->last_was_blit)
-    {
-        if (context->blit_w != rt_size.cx || context->blit_h != rt_size.cy)
-        {
-            set_blit_dimension(gl_info, rt_size.cx, rt_size.cy);
-            context->blit_w = rt_size.cx;
-            context->blit_h = rt_size.cy;
-            /* No need to dirtify here, the states are still dirtified because
-             * they weren't applied since the last SetupForBlit() call. */
-        }
-        TRACE("Context is already set up for blitting, nothing to do\n");
-        return;
-    }
-    context->last_was_blit = TRUE;
-
     /* Disable all textures. The caller can then bind a texture it wants to blit
-     * from
-     *
-     * The blitting code uses (for now) the fixed function pipeline, so make sure to reset all fixed
-     * function texture unit. No need to care for higher samplers
-     */
+     * from. */
     for (i = gl_info->limits.textures - 1; i > 0 ; --i)
     {
         sampler = context->rev_tex_unit_map[i];
@@ -2458,11 +2420,8 @@ static void SetupForBlit(const struct wined3d_device *device, struct wined3d_con
             context_invalidate_state(context, STATE_SAMPLER(sampler));
         }
     }
-    if (gl_info->supported[ARB_SAMPLER_OBJECTS])
-        GL_EXTCALL(glBindSampler(0, 0));
-    context_active_texture(context, gl_info, 0);
 
-    sampler = context->rev_tex_unit_map[0];
+    context_active_texture(context, gl_info, 0);
 
     if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
     {
@@ -2486,60 +2445,12 @@ static void SetupForBlit(const struct wined3d_device *device, struct wined3d_con
     gl_info->gl_ops.gl.p_glLoadIdentity();
     checkGLcall("glLoadIdentity()");
 
-    if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
-    {
-        gl_info->gl_ops.gl.p_glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
-                GL_TEXTURE_LOD_BIAS_EXT, 0.0f);
-        checkGLcall("glTexEnvf GL_TEXTURE_LOD_BIAS_EXT ...");
-    }
-
-    if (sampler != WINED3D_UNMAPPED_STAGE)
-    {
-        if (sampler < MAX_TEXTURES)
-        {
-            context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + sampler));
-            context_invalidate_state(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP));
-        }
-        context_invalidate_state(context, STATE_SAMPLER(sampler));
-    }
-
-    /* Other misc states */
-    gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST);
-    checkGLcall("glDisable(GL_ALPHA_TEST)");
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHATESTENABLE));
     gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
     checkGLcall("glDisable GL_LIGHTING");
     context_invalidate_state(context, STATE_RENDER(WINED3D_RS_LIGHTING));
-    gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_TEST);
-    checkGLcall("glDisable GL_DEPTH_TEST");
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZENABLE));
     glDisableWINE(GL_FOG);
     checkGLcall("glDisable GL_FOG");
     context_invalidate_state(context, STATE_RENDER(WINED3D_RS_FOGENABLE));
-    gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
-    checkGLcall("glDisable GL_BLEND");
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE));
-    gl_info->gl_ops.gl.p_glDisable(GL_CULL_FACE);
-    checkGLcall("glDisable GL_CULL_FACE");
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CULLMODE));
-    gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST);
-    checkGLcall("glDisable GL_STENCIL_TEST");
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_STENCILENABLE));
-    gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST);
-    checkGLcall("glDisable GL_SCISSOR_TEST");
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE));
-    if (gl_info->supported[ARB_POINT_SPRITE])
-    {
-        gl_info->gl_ops.gl.p_glDisable(GL_POINT_SPRITE_ARB);
-        checkGLcall("glDisable GL_POINT_SPRITE_ARB");
-        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE));
-    }
-    gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE,GL_TRUE,GL_TRUE);
-    checkGLcall("glColorMask");
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE));
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1));
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2));
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3));
     if (gl_info->supported[EXT_SECONDARY_COLOR])
     {
         gl_info->gl_ops.gl.p_glDisable(GL_COLOR_SUM_EXT);
@@ -2553,24 +2464,8 @@ static void SetupForBlit(const struct wined3d_device *device, struct wined3d_con
     gl_info->gl_ops.gl.p_glLoadIdentity();
     checkGLcall("glLoadIdentity()");
     context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
-
-    context->last_was_rhw = TRUE;
-    context_invalidate_state(context, STATE_VDECL); /* because of last_was_rhw = TRUE */
-
-    context_enable_clip_distances(context, 0);
-    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CLIPPING));
-
-    /* FIXME: Make draw_textured_quad() able to work with a upper left origin. */
-    if (gl_info->supported[ARB_CLIP_CONTROL])
-        GL_EXTCALL(glClipControl(GL_LOWER_LEFT, GL_NEGATIVE_ONE_TO_ONE));
-
+    context_get_rt_size(context, &rt_size);
     set_blit_dimension(gl_info, rt_size.cx, rt_size.cy);
-
-    /* Disable shaders */
-    device->shader_backend->shader_disable(device->shader_priv, context);
-
-    context->blit_w = rt_size.cx;
-    context->blit_h = rt_size.cy;
     context_invalidate_state(context, STATE_VIEWPORT);
     context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
 }
@@ -2911,10 +2806,14 @@ static DWORD context_generate_rt_mask_no_fbo(const struct wined3d_context *conte
 /* Context activation is done by the caller. */
 void context_apply_blit_state(struct wined3d_context *context, const struct wined3d_device *device)
 {
+    const struct wined3d_gl_info *gl_info = context->gl_info;
     struct wined3d_texture *rt = context->current_rt.texture;
     struct wined3d_surface *surface;
     DWORD rt_mask, *cur_mask;
+    DWORD sampler;
+    SIZE rt_size;
 
+    TRACE("Setting up context %p for blitting.\n", context);
     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
     {
         context_validate_onscreen_formats(context, NULL);
@@ -2955,8 +2854,98 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine
         context_check_fbo_status(context, GL_FRAMEBUFFER);
     }
 
-    SetupForBlit(device, context);
+    context_get_rt_size(context, &rt_size);
+
+    if (context->last_was_blit)
+    {
+        if (context->blit_w != rt_size.cx || context->blit_h != rt_size.cy)
+        {
+            context->blit_w = rt_size.cx;
+            context->blit_h = rt_size.cy;
+            /* No need to dirtify here, the states are still dirtified because
+             * they weren't applied since the last context_apply_blit_state()
+             * call. */
+        }
+        TRACE("Context is already set up for blitting, nothing to do\n");
+        return;
+    }
+    context->last_was_blit = TRUE;
+
+    if (gl_info->supported[ARB_SAMPLER_OBJECTS])
+        GL_EXTCALL(glBindSampler(0, 0));
+    context_active_texture(context, gl_info, 0);
+    sampler = context->rev_tex_unit_map[0];
+
+    if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
+    {
+        gl_info->gl_ops.gl.p_glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
+                GL_TEXTURE_LOD_BIAS_EXT, 0.0f);
+        checkGLcall("glTexEnvf(GL_TEXTURE_LOD_BIAS_EXT)");
+    }
+
+    if (sampler != WINED3D_UNMAPPED_STAGE)
+    {
+        if (sampler < MAX_TEXTURES)
+        {
+            context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + sampler));
+            context_invalidate_state(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP));
+        }
+        context_invalidate_state(context, STATE_SAMPLER(sampler));
+    }
+
+    gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST);
+    checkGLcall("glDisable(GL_ALPHA_TEST)");
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHATESTENABLE));
+    gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_TEST);
+    checkGLcall("glDisable(GL_DEPTH_TEST)");
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZENABLE));
+    gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
+    checkGLcall("glDisable(GL_BLEND)");
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE));
+    gl_info->gl_ops.gl.p_glDisable(GL_CULL_FACE);
+    checkGLcall("glDisable(GL_CULL_FACE)");
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CULLMODE));
+    gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST);
+    checkGLcall("glDisable(GL_STENCIL_TEST)");
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_STENCILENABLE));
+    gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST);
+    checkGLcall("glDisable(GL_SCISSOR_TEST)");
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE));
+    /* Commenting out this (and the FBO blits) breaks test_pointsize() in
+     * d3d9:visual on r600g (legacy profile only, core doesn't have the toggle
+     * and that works fine).
+     * This seems to be a driver bug, Nvidia works fine. */
+    if (gl_info->supported[ARB_POINT_SPRITE])
+    {
+        gl_info->gl_ops.gl.p_glDisable(GL_POINT_SPRITE_ARB);
+        checkGLcall("glDisable GL_POINT_SPRITE_ARB");
+        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE));
+    }
+    gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+    checkGLcall("glColorMask");
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE));
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1));
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2));
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3));
+
+    context->last_was_rhw = TRUE;
+    context_invalidate_state(context, STATE_VDECL); /* because of last_was_rhw = TRUE */
+
+    context_enable_clip_distances(context, 0);
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CLIPPING));
+
+    device->shader_backend->shader_disable(device->shader_priv, context);
+
+    context->blit_w = rt_size.cx;
+    context->blit_h = rt_size.cy;
+
     context_invalidate_state(context, STATE_FRAMEBUFFER);
+
+    /* FIXME: Make draw_textured_quad() able to work with a upper left origin. */
+    if (gl_info->supported[ARB_CLIP_CONTROL])
+        GL_EXTCALL(glClipControl(GL_LOWER_LEFT, GL_NEGATIVE_ONE_TO_ONE));
+    gl_info->gl_ops.gl.p_glViewport(0, 0, rt_size.cx, rt_size.cy);
+    context_invalidate_state(context, STATE_VIEWPORT);
 }
 
 static BOOL context_validate_rt_config(UINT rt_count, struct wined3d_rendertarget_view * const *rts,
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 02e0c70382..71e414c0e7 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -1649,6 +1649,7 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_surface *dst_surface, st
     context = context_acquire(device, src_texture, src_sub_resource_idx);
     gl_info = context->gl_info;
     context_apply_blit_state(context, device);
+    context_apply_blit_ffp_state(context, device);
     wined3d_texture_load(dst_texture, context, FALSE);
 
     offscreen_buffer = context_get_offscreen_gl_buffer(context);
@@ -2798,8 +2799,8 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit
      * unless we're overwriting it completely. */
     wined3d_texture_load(src_texture, context, FALSE);
 
-    /* Activate the destination context, set it up for blitting. */
     context_apply_blit_state(context, device);
+    context_apply_blit_ffp_state(context, device);
 
     if (dst_location == WINED3D_LOCATION_DRAWABLE)
     {
@@ -2858,7 +2859,6 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit
         checkGLcall("glDisable(GL_ALPHA_TEST)");
     }
 
-    /* Leave the OpenGL state valid for blitting. */
     gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
     checkGLcall("glDisable(GL_TEXTURE_2D)");
     if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 1d0b39df03..e33a2139e4 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2127,6 +2127,7 @@ void context_alloc_fence(struct wined3d_context *context, struct wined3d_fence *
 void context_alloc_occlusion_query(struct wined3d_context *context,
         struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN;
 void context_apply_blit_state(struct wined3d_context *context, const struct wined3d_device *device) DECLSPEC_HIDDEN;
+void context_apply_blit_ffp_state(struct wined3d_context *context, const struct wined3d_device *device) DECLSPEC_HIDDEN;
 BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_state *state,
         UINT rt_count, const struct wined3d_fb_state *fb) DECLSPEC_HIDDEN;
 void context_apply_compute_state(struct wined3d_context *context,


More information about the wine-devel mailing list