[PATCH 6/6] wined3d: Do not apply fixed-funtion state in context_apply_blit_state().

Henri Verbeet hverbeet at codeweavers.com
Tue Mar 13 05:23:06 CDT 2018


From: Matteo Bruni <mbruni at codeweavers.com>

Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 dlls/wined3d/arb_program_shader.c |   2 +-
 dlls/wined3d/context.c            | 415 +++++++++++++++++---------------------
 dlls/wined3d/surface.c            |   6 +-
 dlls/wined3d/wined3d_private.h    |   6 +-
 4 files changed, 197 insertions(+), 232 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index acfd1d565cd..e9c9d7d1bfb 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -7840,7 +7840,7 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl
     else
         wined3d_texture_load(src_texture, context, FALSE);
 
-    context_apply_blit_state(context, device);
+    context_apply_ffp_blit_state(context, device);
 
     if (dst_location == WINED3D_LOCATION_DRAWABLE)
     {
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 3ba80683276..6530b6fc37e 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -2348,28 +2348,6 @@ const DWORD *context_get_tex_unit_mapping(const struct wined3d_context *context,
     return context->tex_unit_map;
 }
 
-/* Context activation is done by the caller. */
-static void set_blit_dimension(const struct wined3d_gl_info *gl_info, UINT width, UINT height)
-{
-    const GLdouble projection[] =
-    {
-        2.0 / width,          0.0,  0.0, 0.0,
-                0.0, 2.0 / height,  0.0, 0.0,
-                0.0,          0.0,  2.0, 0.0,
-               -1.0,         -1.0, -1.0, 1.0,
-    };
-
-    if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
-    {
-        gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
-        checkGLcall("glMatrixMode(GL_PROJECTION)");
-        gl_info->gl_ops.gl.p_glLoadMatrixd(projection);
-        checkGLcall("glLoadMatrixd");
-    }
-    gl_info->gl_ops.gl.p_glViewport(0, 0, width, height);
-    checkGLcall("glViewport");
-}
-
 static void context_get_rt_size(const struct wined3d_context *context, SIZE *size)
 {
     const struct wined3d_texture *rt = context->current_rt.texture;
@@ -2418,208 +2396,6 @@ 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
- *
- *****************************************************************************/
-/* Context activation is done by the caller. */
-static void SetupForBlit(const struct wined3d_device *device, struct wined3d_context *context)
-{
-    const struct wined3d_gl_info *gl_info = context->gl_info;
-    DWORD sampler;
-    SIZE rt_size;
-    int i;
-
-    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;
-
-    if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
-    {
-        /* 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
-         */
-        for (i = gl_info->limits.textures - 1; i > 0 ; --i)
-        {
-            sampler = context->rev_tex_unit_map[i];
-            context_active_texture(context, gl_info, i);
-
-            if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
-            {
-                gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
-                checkGLcall("glDisable GL_TEXTURE_CUBE_MAP_ARB");
-            }
-            gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
-            checkGLcall("glDisable GL_TEXTURE_3D");
-            if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
-            {
-                gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
-                checkGLcall("glDisable GL_TEXTURE_RECTANGLE_ARB");
-            }
-            gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
-            checkGLcall("glDisable GL_TEXTURE_2D");
-
-            gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-            checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);");
-
-            if (sampler != WINED3D_UNMAPPED_STAGE)
-            {
-                if (sampler < MAX_TEXTURES)
-                    context_invalidate_state(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP));
-                context_invalidate_state(context, STATE_SAMPLER(sampler));
-            }
-        }
-
-        context_active_texture(context, gl_info, 0);
-        if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
-        {
-            gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
-            checkGLcall("glDisable GL_TEXTURE_CUBE_MAP_ARB");
-        }
-        gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
-        checkGLcall("glDisable GL_TEXTURE_3D");
-        if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
-        {
-            gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
-            checkGLcall("glDisable GL_TEXTURE_RECTANGLE_ARB");
-        }
-        gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
-        checkGLcall("glDisable GL_TEXTURE_2D");
-
-        gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-
-        gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE);
-        checkGLcall("glMatrixMode(GL_TEXTURE)");
-        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 ...");
-        }
-
-        /* Setup transforms */
-        gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
-        checkGLcall("glMatrixMode(GL_MODELVIEW)");
-        gl_info->gl_ops.gl.p_glLoadIdentity();
-        checkGLcall("glLoadIdentity()");
-        context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
-
-        /* 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));
-        glDisableWINE(GL_FOG);
-        checkGLcall("glDisable GL_FOG");
-        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_FOGENABLE));
-    }
-
-    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 (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_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));
-    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);
-        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SPECULARENABLE));
-        checkGLcall("glDisable(GL_COLOR_SUM_EXT)");
-    }
-
-    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));
-
-    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));
-}
-
 static inline BOOL is_rt_mask_onscreen(DWORD rt_mask)
 {
     return rt_mask & (1u << 31);
@@ -2954,8 +2730,13 @@ 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;
     DWORD rt_mask, *cur_mask;
+    unsigned int sampler;
+    SIZE rt_size;
+
+    TRACE("Setting up context %p for blitting.\n", context);
 
     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
     {
@@ -2994,9 +2775,188 @@ void context_apply_blit_state(struct wined3d_context *context, const struct wine
     {
         context_check_fbo_status(context, GL_FRAMEBUFFER);
     }
-
-    SetupForBlit(device, context);
     context_invalidate_state(context, STATE_FRAMEBUFFER);
+
+    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)
+        {
+            gl_info->gl_ops.gl.p_glViewport(0, 0, 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 context_apply_blit_state()
+             * call. */
+        }
+        checkGLcall("blit state application");
+        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 (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));
+    }
+
+    if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
+    {
+        gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST);
+        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHATESTENABLE));
+    }
+    gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_TEST);
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ZENABLE));
+    gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE));
+    gl_info->gl_ops.gl.p_glDisable(GL_CULL_FACE);
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CULLMODE));
+    gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST);
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_STENCILENABLE));
+    gl_info->gl_ops.gl.p_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);
+        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE));
+    }
+    gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+    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));
+
+    /* 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);
+
+    device->shader_backend->shader_disable(device->shader_priv, context);
+
+    context->blit_w = rt_size.cx;
+    context->blit_h = rt_size.cy;
+
+    checkGLcall("blit state application");
+}
+
+static void context_apply_blit_projection(const struct wined3d_context *context, unsigned int w, unsigned int h)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    const GLdouble projection[] =
+    {
+        2.0 / w,     0.0,  0.0, 0.0,
+            0.0, 2.0 / h,  0.0, 0.0,
+            0.0,     0.0,  2.0, 0.0,
+           -1.0,    -1.0, -1.0, 1.0,
+    };
+
+    gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
+    gl_info->gl_ops.gl.p_glLoadMatrixd(projection);
+}
+
+/* Setup OpenGL states for fixed-function blitting. */
+/* Context activation is done by the caller. */
+void context_apply_ffp_blit_state(struct wined3d_context *context, const struct wined3d_device *device)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    unsigned int i, sampler;
+
+    if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
+        ERR("Applying fixed-function state without legacy context support.\n");
+
+    if (context->last_was_ffp_blit)
+    {
+        SIZE rt_size;
+
+        context_get_rt_size(context, &rt_size);
+        if (context->blit_w != rt_size.cx || context->blit_h != rt_size.cy)
+            context_apply_blit_projection(context, rt_size.cx, rt_size.cy);
+        context_apply_blit_state(context, device);
+
+        checkGLcall("ffp blit state application");
+        return;
+    }
+    context->last_was_ffp_blit = TRUE;
+
+    context_apply_blit_state(context, device);
+
+    /* Disable all textures. The caller can then bind a texture it wants to blit
+     * from. */
+    for (i = gl_info->limits.textures - 1; i > 0 ; --i)
+    {
+        context_active_texture(context, gl_info, i);
+
+        if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+            gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+        gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
+        if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+            gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
+        gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
+
+        gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+        sampler = context->rev_tex_unit_map[i];
+        if (sampler != WINED3D_UNMAPPED_STAGE)
+        {
+            if (sampler < MAX_TEXTURES)
+                context_invalidate_state(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP));
+            context_invalidate_state(context, STATE_SAMPLER(sampler));
+        }
+    }
+
+    context_active_texture(context, gl_info, 0);
+
+    if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
+        gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+    gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
+    if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
+        gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
+    gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
+
+    gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+    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);
+
+    gl_info->gl_ops.gl.p_glMatrixMode(GL_TEXTURE);
+    gl_info->gl_ops.gl.p_glLoadIdentity();
+
+    /* Setup transforms. */
+    gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
+    gl_info->gl_ops.gl.p_glLoadIdentity();
+    context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
+    context_apply_blit_projection(context, context->blit_w, context->blit_h);
+    context_invalidate_state(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
+
+    /* Other misc states. */
+    gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_LIGHTING));
+    glDisableWINE(GL_FOG);
+    context_invalidate_state(context, STATE_RENDER(WINED3D_RS_FOGENABLE));
+
+    if (gl_info->supported[EXT_SECONDARY_COLOR])
+    {
+        gl_info->gl_ops.gl.p_glDisable(GL_COLOR_SUM_EXT);
+        context_invalidate_state(context, STATE_RENDER(WINED3D_RS_SPECULARENABLE));
+    }
+    checkGLcall("ffp blit state application");
 }
 
 static BOOL have_framebuffer_attachment(unsigned int rt_count, struct wined3d_rendertarget_view * const *rts,
@@ -3117,6 +3077,7 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win
     }
 
     context->last_was_blit = FALSE;
+    context->last_was_ffp_blit = FALSE;
 
     /* Blending and clearing should be orthogonal, but tests on the nvidia
      * driver show that disabling blending when clearing improves the clearing
@@ -4037,6 +3998,7 @@ static BOOL context_apply_draw_state(struct wined3d_context *context,
 
     context->numDirtyEntries = 0; /* This makes the whole list clean */
     context->last_was_blit = FALSE;
+    context->last_was_ffp_blit = FALSE;
 
     return TRUE;
 }
@@ -4098,6 +4060,7 @@ static void context_apply_compute_state(struct wined3d_context *context,
     context_invalidate_state(context, STATE_FRAMEBUFFER);
 
     context->last_was_blit = FALSE;
+    context->last_was_ffp_blit = FALSE;
 }
 
 static BOOL use_transform_feedback(const struct wined3d_state *state)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 93a9f097a56..b0ccfb8122d 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -1653,7 +1653,7 @@ static void fb_copy_to_texture_hwstretch(struct wined3d_texture *dst_texture, un
     /* Activate the Proper context for reading from the source surface, set it up for blitting */
     context = context_acquire(device, src_texture, src_sub_resource_idx);
     gl_info = context->gl_info;
-    context_apply_blit_state(context, device);
+    context_apply_ffp_blit_state(context, device);
     wined3d_texture_load(dst_texture, context, FALSE);
 
     offscreen_buffer = context_get_offscreen_gl_buffer(context);
@@ -2764,8 +2764,7 @@ 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_ffp_blit_state(context, device);
 
     if (dst_location == WINED3D_LOCATION_DRAWABLE)
     {
@@ -2825,7 +2824,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 9dc193a6606..4f02ae465c1 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1911,7 +1911,9 @@ struct wined3d_context
     DWORD transform_feedback_paused : 1;
     DWORD shader_update_mask : 6; /* WINED3D_SHADER_TYPE_COUNT, 6 */
     DWORD clip_distance_mask : 8; /* MAX_CLIP_DISTANCES, 8 */
-    DWORD padding : 9;
+    DWORD last_was_ffp_blit : 1;
+    DWORD padding : 8;
+
     DWORD constant_update_mask;
     DWORD                   numbered_array_mask;
     GLenum                  tracking_parm;     /* Which source is tracking current colour         */
@@ -2138,6 +2140,8 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win
 void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target,
         struct wined3d_resource *rt, unsigned int rt_sub_resource_idx,
         struct wined3d_resource *ds, unsigned int ds_sub_resource_idx, DWORD location) DECLSPEC_HIDDEN;
+void context_apply_ffp_blit_state(struct wined3d_context *context,
+        const struct wined3d_device *device) DECLSPEC_HIDDEN;
 void context_active_texture(struct wined3d_context *context, const struct wined3d_gl_info *gl_info,
         unsigned int unit) DECLSPEC_HIDDEN;
 void context_bind_bo(struct wined3d_context *context, GLenum binding, GLuint name) DECLSPEC_HIDDEN;
-- 
2.11.0




More information about the wine-devel mailing list