[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