It can be unnecessary at best and unsupported at worst (e.g. no ARB_texture_multisample).
-- v4: wined3d: Don't skip ARB fragment program selection when fog state is dirty. wined3d: Skip acquiring a context for an offscreen resource in texture2d_read_from_framebuffer(). wined3d: Don't force going through a texture when downloading from renderbuffers. wined3d: Handle depth textures in texture2d_read_from_framebuffer(). wined3d: Rename wined3d_context_gl_apply_fbo_state_blit() function. wined3d: Don't setup FBO and draw buffers in wined3d_context_gl_apply_blit_state(). wined3d: Don't call wined3d_texture_load() from wined3d_context_gl_apply_blit_state(). wined3d: Don't bind the FBO to GL_READ_FRAMEBUFFER in wined3d_context_gl_apply_blit_state(). wined3d: Prepare/load the destination resource location in arbfp_blitter_blit(). wined3d: Prepare/load the destination resource location in ffp_blitter_blit(). wined3d: Don't call wined3d_context_gl_apply_blit_state() from texture2d_read_from_framebuffer().
From: Matteo Bruni mbruni@codeweavers.com
None of the GL states set by wined3d_context_gl_apply_blit_state() should matter for glReadPixels(), aside from the FBO read binding. So just do that instead.
Some wined3d git archaeology suggests that the wined3d_context_gl_apply_blit_state() call was added right before Wine 1.2 to workaround various driver issues with glReadPixels() that in practice was erroneously affected by some GL states. If those kind of issues are still a thing, it might be necessary to reintroduce some limited state reset, possibly tied to a quirk. --- dlls/wined3d/surface.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 11b1da829d7..6850e984efb 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -372,16 +372,10 @@ void texture2d_read_from_framebuffer(struct wined3d_texture *texture, unsigned i context_gl = wined3d_context_gl(context); gl_info = context_gl->gl_info;
- if (src_location != resource->draw_binding) + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_READ_FRAMEBUFFER, resource, sub_resource_idx, NULL, 0, src_location); - wined3d_context_gl_check_fbo_status(context_gl, GL_READ_FRAMEBUFFER); - context_invalidate_state(context, STATE_FRAMEBUFFER); - } - else - { - wined3d_context_gl_apply_blit_state(context_gl, device); }
/* Select the correct read buffer, and give some debug output. @@ -405,6 +399,8 @@ void texture2d_read_from_framebuffer(struct wined3d_texture *texture, unsigned i src_is_upside_down = FALSE; } checkGLcall("glReadBuffer"); + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + wined3d_context_gl_check_fbo_status(context_gl, GL_READ_FRAMEBUFFER);
if (data.buffer_object) {
From: Matteo Bruni mbruni@codeweavers.com
Port of c0ab55700f681ace7ac13f9fdaa6075185fef35c to the FFP blitter. --- dlls/wined3d/texture.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 7ec5c4f4f3b..b96988f325e 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -6282,6 +6282,11 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit wined3d_texture_load(src_texture, context, FALSE); }
+ if (wined3d_texture_is_full_rect(dst_texture, dst_sub_resource_idx % dst_texture->level_count, dst_rect)) + wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, context, dst_location); + else + wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, dst_location); + wined3d_context_gl_apply_ffp_blit_state(context_gl, device);
if (dst_location == WINED3D_LOCATION_DRAWABLE)
From: Matteo Bruni mbruni@codeweavers.com
Port of c0ab55700f681ace7ac13f9fdaa6075185fef35c to the ARB FP blitter. --- dlls/wined3d/arb_program_shader.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index c535fe7d3ff..0a012d7b13a 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -7916,6 +7916,11 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl wined3d_texture_load(src_texture, context, FALSE); }
+ if (wined3d_texture_is_full_rect(dst_texture, dst_sub_resource_idx % dst_texture->level_count, dst_rect)) + wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, context, dst_location); + else + wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, dst_location); + wined3d_context_gl_apply_ffp_blit_state(context_gl, device);
if (dst_location == WINED3D_LOCATION_DRAWABLE)
From: Matteo Bruni mbruni@codeweavers.com
--- dlls/wined3d/context_gl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index 5a45ae7dc72..a32fc4ceb78 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -3254,7 +3254,7 @@ void wined3d_context_gl_apply_blit_state(struct wined3d_context_gl *context_gl, { wined3d_texture_load(rt, context, FALSE);
- wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_FRAMEBUFFER, &rt->resource, + wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_DRAW_FRAMEBUFFER, &rt->resource, context->current_rt.sub_resource_idx, NULL, 0, rt->resource.draw_binding); if (rt->resource.format->id != WINED3DFMT_NULL) rt_mask = 1; @@ -3264,7 +3264,7 @@ void wined3d_context_gl_apply_blit_state(struct wined3d_context_gl *context_gl, else { context_gl->current_fbo = NULL; - wined3d_context_gl_bind_fbo(context_gl, GL_FRAMEBUFFER, 0); + wined3d_context_gl_bind_fbo(context_gl, GL_DRAW_FRAMEBUFFER, 0); rt_mask = context_generate_rt_mask_from_resource(&rt->resource); } } @@ -3282,7 +3282,7 @@ void wined3d_context_gl_apply_blit_state(struct wined3d_context_gl *context_gl, }
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) - wined3d_context_gl_check_fbo_status(context_gl, GL_FRAMEBUFFER); + wined3d_context_gl_check_fbo_status(context_gl, GL_DRAW_FRAMEBUFFER); context_invalidate_state(context, STATE_FRAMEBUFFER);
wined3d_context_gl_get_rt_size(context_gl, &rt_size);
From: Matteo Bruni mbruni@codeweavers.com
It really isn't supposed to be its responsibility. All the callers of the function (which are blitters) take care of it already. --- dlls/wined3d/context_gl.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index a32fc4ceb78..cd03f945d38 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -3252,8 +3252,6 @@ void wined3d_context_gl_apply_blit_state(struct wined3d_context_gl *context_gl, { if (context->render_offscreen) { - wined3d_texture_load(rt, context, FALSE); - wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_DRAW_FRAMEBUFFER, &rt->resource, context->current_rt.sub_resource_idx, NULL, 0, rt->resource.draw_binding); if (rt->resource.format->id != WINED3DFMT_NULL)
From: Matteo Bruni mbruni@codeweavers.com
All the callers (i.e. the blitters) also call context_gl_apply_texture_draw_state() that does that part of the setup anyway. --- dlls/wined3d/arb_program_shader.c | 3 +- dlls/wined3d/context_gl.c | 92 ++++++++++++------------------- dlls/wined3d/glsl_shader.c | 3 +- dlls/wined3d/texture.c | 3 +- 4 files changed, 37 insertions(+), 64 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 0a012d7b13a..1008aefd76f 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -7921,6 +7921,7 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl else wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, dst_location);
+ context_gl_apply_texture_draw_state(context_gl, dst_texture, dst_sub_resource_idx, dst_location); wined3d_context_gl_apply_ffp_blit_state(context_gl, device);
if (dst_location == WINED3D_LOCATION_DRAWABLE) @@ -7930,8 +7931,6 @@ static DWORD arbfp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bl dst_rect = &d; }
- context_gl_apply_texture_draw_state(context_gl, dst_texture, dst_sub_resource_idx, dst_location); - if (op == WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST) { const struct wined3d_format *fmt = src_texture->resource.format; diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index cd03f945d38..ab86ea19a69 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -3238,50 +3238,12 @@ void wined3d_context_gl_apply_blit_state(struct wined3d_context_gl *context_gl, { struct wined3d_context *context = &context_gl->c; const struct wined3d_gl_info *gl_info; - uint32_t rt_mask, *cur_mask; - struct wined3d_texture *rt; unsigned int sampler; SIZE rt_size;
TRACE("Setting up context %p for blitting.\n", context);
gl_info = context_gl->gl_info; - rt = context->current_rt.texture; - - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) - { - if (context->render_offscreen) - { - wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_DRAW_FRAMEBUFFER, &rt->resource, - context->current_rt.sub_resource_idx, NULL, 0, rt->resource.draw_binding); - if (rt->resource.format->id != WINED3DFMT_NULL) - rt_mask = 1; - else - rt_mask = 0; - } - else - { - context_gl->current_fbo = NULL; - wined3d_context_gl_bind_fbo(context_gl, GL_DRAW_FRAMEBUFFER, 0); - rt_mask = context_generate_rt_mask_from_resource(&rt->resource); - } - } - else - { - rt_mask = wined3d_context_gl_generate_rt_mask_no_fbo(context_gl, &rt->resource); - } - - cur_mask = context_gl->current_fbo ? &context_gl->current_fbo->rt_mask : &context_gl->draw_buffers_mask; - - if (rt_mask != *cur_mask) - { - wined3d_context_gl_apply_draw_buffers(context_gl, rt_mask); - *cur_mask = rt_mask; - } - - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) - wined3d_context_gl_check_fbo_status(context_gl, GL_DRAW_FRAMEBUFFER); - context_invalidate_state(context, STATE_FRAMEBUFFER);
wined3d_context_gl_get_rt_size(context_gl, &rt_size);
@@ -3640,38 +3602,52 @@ void context_gl_apply_texture_draw_state(struct wined3d_context_gl *context_gl, struct wined3d_texture *texture, unsigned int sub_resource_idx, unsigned int location) { const struct wined3d_format *format = texture->resource.format; - GLenum buffer; + struct wined3d_context *context = &context_gl->c; + uint32_t rt_mask, *cur_mask;
- if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) - return; + TRACE("context_gl %p, texture %p, sub_resource_idx %u, location %s.\n", + context_gl, texture, sub_resource_idx, wined3d_debug_location(location));
- if (format->depth_size || format->stencil_size) + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_DRAW_FRAMEBUFFER, - NULL, 0, &texture->resource, sub_resource_idx, location); - - buffer = GL_NONE; + if (format->depth_size || format->stencil_size) + wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_DRAW_FRAMEBUFFER, NULL, + 0, &texture->resource, sub_resource_idx, location); + else + wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_DRAW_FRAMEBUFFER, &texture->resource, + sub_resource_idx, NULL, 0, location); } - else - { - wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_DRAW_FRAMEBUFFER, - &texture->resource, sub_resource_idx, NULL, 0, location);
- if (location == WINED3D_LOCATION_DRAWABLE) + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + { + if (location != WINED3D_LOCATION_DRAWABLE) { - TRACE("Texture %p is onscreen.\n", texture); - buffer = wined3d_texture_get_gl_buffer(texture); + if (texture->resource.format->id == WINED3DFMT_NULL || format->depth_size || format->stencil_size) + rt_mask = 0; + else + rt_mask = 1; } else { - TRACE("Texture %p is offscreen.\n", texture); - buffer = GL_COLOR_ATTACHMENT0; + rt_mask = context_generate_rt_mask_from_resource(&texture->resource); } } + else + { + rt_mask = wined3d_context_gl_generate_rt_mask_no_fbo(context_gl, &texture->resource); + }
- wined3d_context_gl_set_draw_buffer(context_gl, buffer); - wined3d_context_gl_check_fbo_status(context_gl, GL_DRAW_FRAMEBUFFER); - context_invalidate_state(&context_gl->c, STATE_FRAMEBUFFER); + cur_mask = context_gl->current_fbo ? &context_gl->current_fbo->rt_mask : &context_gl->draw_buffers_mask; + if (rt_mask != *cur_mask) + { + wined3d_context_gl_apply_draw_buffers(context_gl, rt_mask); + *cur_mask = rt_mask; + } + + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) + wined3d_context_gl_check_fbo_status(context_gl, GL_DRAW_FRAMEBUFFER); + + context_invalidate_state(context, STATE_FRAMEBUFFER); }
/* Context activation is done by the caller. */ diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 552d1bd75bd..964cf1308eb 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -13219,6 +13219,7 @@ static DWORD glsl_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bli else wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, dst_location);
+ context_gl_apply_texture_draw_state(context_gl, dst_texture, dst_sub_resource_idx, dst_location); wined3d_context_gl_apply_blit_state(context_gl, device);
if (dst_location == WINED3D_LOCATION_DRAWABLE) @@ -13228,8 +13229,6 @@ static DWORD glsl_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_bli dst_rect = &d; }
- context_gl_apply_texture_draw_state(context_gl, dst_texture, dst_sub_resource_idx, dst_location); - if (op == WINED3D_BLIT_OP_COLOR_BLIT_ALPHATEST) { const struct wined3d_format *f = src_texture->resource.format; diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index b96988f325e..5a3467085e2 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -6287,6 +6287,7 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit else wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, dst_location);
+ context_gl_apply_texture_draw_state(context_gl, dst_texture, dst_sub_resource_idx, dst_location); wined3d_context_gl_apply_ffp_blit_state(context_gl, device);
if (dst_location == WINED3D_LOCATION_DRAWABLE) @@ -6296,8 +6297,6 @@ static DWORD ffp_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit dst_rect = &r; }
- context_gl_apply_texture_draw_state(context_gl, dst_texture, dst_sub_resource_idx, dst_location); - gl_info->gl_ops.gl.p_glEnable(src_texture_gl->target); checkGLcall("glEnable(target)");
From: Matteo Bruni mbruni@codeweavers.com
To wined3d_context_gl_apply_fbo_state_explicit(). It's not really related to blitting in principle; what it does is attaching specific textures to the FBO instead of the d3d render targets, which was the "original" use of FBOs in wined3d.
BTW even that original use case (currently handled by context_state_fb()) is not using render_targets[] directly anymore and we end up kind of abusing the blit_targets[] arrays in struct wined3d_context_gl. Maybe we could rename that array as well. --- dlls/wined3d/context_gl.c | 6 +++--- dlls/wined3d/surface.c | 2 +- dlls/wined3d/texture.c | 4 ++-- dlls/wined3d/wined3d_gl.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index ab86ea19a69..eb3c8b2438e 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -850,7 +850,7 @@ static void wined3d_context_gl_apply_fbo_state(struct wined3d_context_gl *contex }
/* Context activation is done by the caller. */ -void wined3d_context_gl_apply_fbo_state_blit(struct wined3d_context_gl *context_gl, GLenum target, +void wined3d_context_gl_apply_fbo_state_explicit(struct wined3d_context_gl *context_gl, GLenum target, struct wined3d_resource *rt, unsigned int rt_sub_resource_idx, struct wined3d_resource *ds, unsigned int ds_sub_resource_idx, uint32_t location) { @@ -3611,10 +3611,10 @@ void context_gl_apply_texture_draw_state(struct wined3d_context_gl *context_gl, if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { if (format->depth_size || format->stencil_size) - wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_DRAW_FRAMEBUFFER, NULL, + wined3d_context_gl_apply_fbo_state_explicit(context_gl, GL_DRAW_FRAMEBUFFER, NULL, 0, &texture->resource, sub_resource_idx, location); else - wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_DRAW_FRAMEBUFFER, &texture->resource, + wined3d_context_gl_apply_fbo_state_explicit(context_gl, GL_DRAW_FRAMEBUFFER, &texture->resource, sub_resource_idx, NULL, 0, location); }
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 6850e984efb..b519e26ee2a 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -374,7 +374,7 @@ void texture2d_read_from_framebuffer(struct wined3d_texture *texture, unsigned i
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_READ_FRAMEBUFFER, + wined3d_context_gl_apply_fbo_state_explicit(context_gl, GL_READ_FRAMEBUFFER, resource, sub_resource_idx, NULL, 0, src_location); }
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 5a3467085e2..5edcaaa6064 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -531,7 +531,7 @@ static void texture2d_blt_fbo(struct wined3d_device *device, struct wined3d_cont buffer = GL_COLOR_ATTACHMENT0; }
- wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_READ_FRAMEBUFFER, + wined3d_context_gl_apply_fbo_state_explicit(context_gl, GL_READ_FRAMEBUFFER, &src_texture->resource, src_sub_resource_idx, NULL, 0, src_location); gl_info->gl_ops.gl.p_glReadBuffer(buffer); checkGLcall("glReadBuffer()"); @@ -632,7 +632,7 @@ static void texture2d_depth_blt_fbo(const struct wined3d_device *device, struct else wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, context, dst_location);
- wined3d_context_gl_apply_fbo_state_blit(context_gl, GL_READ_FRAMEBUFFER, NULL, 0, + wined3d_context_gl_apply_fbo_state_explicit(context_gl, GL_READ_FRAMEBUFFER, NULL, 0, &src_texture->resource, src_sub_resource_idx, src_location); wined3d_context_gl_check_fbo_status(context_gl, GL_READ_FRAMEBUFFER);
diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h index 98832d54ff5..ba150476e79 100644 --- a/dlls/wined3d/wined3d_gl.h +++ b/dlls/wined3d/wined3d_gl.h @@ -734,7 +734,7 @@ GLuint wined3d_context_gl_allocate_vram_chunk_buffer(struct wined3d_context_gl * void wined3d_context_gl_apply_blit_state(struct wined3d_context_gl *context_gl, const struct wined3d_device *device); BOOL wined3d_context_gl_apply_clear_state(struct wined3d_context_gl *context_gl, const struct wined3d_state *state, unsigned int rt_count, const struct wined3d_fb_state *fb); -void wined3d_context_gl_apply_fbo_state_blit(struct wined3d_context_gl *context_gl, GLenum target, +void wined3d_context_gl_apply_fbo_state_explicit(struct wined3d_context_gl *context_gl, GLenum target, struct wined3d_resource *rt, unsigned int rt_sub_resource_idx, struct wined3d_resource *ds, unsigned int ds_sub_resource_idx, uint32_t location); void wined3d_context_gl_apply_ffp_blit_state(struct wined3d_context_gl *context_gl,
From: Matteo Bruni mbruni@codeweavers.com
--- dlls/wined3d/surface.c | 8 ++++++-- dlls/wined3d/texture.c | 3 +-- 2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index b519e26ee2a..dce1de3ac18 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -374,8 +374,12 @@ void texture2d_read_from_framebuffer(struct wined3d_texture *texture, unsigned i
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - wined3d_context_gl_apply_fbo_state_explicit(context_gl, GL_READ_FRAMEBUFFER, - resource, sub_resource_idx, NULL, 0, src_location); + if (resource->format->depth_size || resource->format->stencil_size) + wined3d_context_gl_apply_fbo_state_explicit(context_gl, GL_READ_FRAMEBUFFER, + NULL, 0, resource, sub_resource_idx, src_location); + else + wined3d_context_gl_apply_fbo_state_explicit(context_gl, GL_READ_FRAMEBUFFER, + resource, sub_resource_idx, NULL, 0, src_location); }
/* Select the correct read buffer, and give some debug output. diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 5edcaaa6064..e093ed0b256 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -3006,8 +3006,7 @@ static BOOL wined3d_texture_gl_load_sysmem(struct wined3d_texture_gl *texture_gl return TRUE; }
- if (!(texture_gl->t.resource.bind_flags & WINED3D_BIND_DEPTH_STENCIL) - && (sub_resource->locations & WINED3D_LOCATION_DRAWABLE)) + if (sub_resource->locations & WINED3D_LOCATION_DRAWABLE) { texture2d_read_from_framebuffer(&texture_gl->t, sub_resource_idx, &context_gl->c, texture_gl->t.resource.draw_binding, dst_location);
From: Matteo Bruni mbruni@codeweavers.com
It can be unnecessary at best and unsupported at worst (e.g. no ARB_texture_multisample or MultisampleTextures setting disabled). --- dlls/wined3d/surface.c | 10 ++++++---- dlls/wined3d/texture.c | 11 +++++------ 2 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index dce1de3ac18..99338b91d5b 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -359,6 +359,9 @@ void texture2d_read_from_framebuffer(struct wined3d_texture *texture, unsigned i uint8_t *offset; unsigned int i;
+ TRACE("texture %p, sub_resource_idx %u, context %p, src_location %s, dst_location %s.\n", + texture, sub_resource_idx, context, wined3d_debug_location(src_location), wined3d_debug_location(dst_location)); + /* dst_location was already prepared by the caller. */ wined3d_texture_get_bo_address(texture, sub_resource_idx, &data, dst_location); offset = data.addr; @@ -382,10 +385,9 @@ void texture2d_read_from_framebuffer(struct wined3d_texture *texture, unsigned i resource, sub_resource_idx, NULL, 0, src_location); }
- /* Select the correct read buffer, and give some debug output. - * There is no need to keep track of the current read buffer or reset it, - * every part of the code that reads sets the read buffer as desired. - */ + /* Select the correct read buffer, and give some debug output. There is no + * need to keep track of the current read buffer or reset it, every part + * of the code that reads pixels sets the read buffer as desired. */ if (src_location != WINED3D_LOCATION_DRAWABLE || wined3d_resource_is_offscreen(resource)) { /* Mapping the primary render target which is not on a swapchain. diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index e093ed0b256..29bd1a432b9 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -2974,18 +2974,17 @@ static BOOL wined3d_texture_gl_load_sysmem(struct wined3d_texture_gl *texture_gl sub_resource = &texture_gl->t.sub_resources[sub_resource_idx];
/* We cannot download data from multisample textures directly. */ - if (wined3d_texture_gl_is_multisample_location(texture_gl, WINED3D_LOCATION_TEXTURE_RGB)) - { + if (wined3d_texture_gl_is_multisample_location(texture_gl, WINED3D_LOCATION_TEXTURE_RGB) + || sub_resource->locations & WINED3D_LOCATION_RB_MULTISAMPLE) wined3d_texture_load_location(&texture_gl->t, sub_resource_idx, &context_gl->c, WINED3D_LOCATION_RB_RESOLVED); + + if (sub_resource->locations & WINED3D_LOCATION_RB_RESOLVED) + { texture2d_read_from_framebuffer(&texture_gl->t, sub_resource_idx, &context_gl->c, WINED3D_LOCATION_RB_RESOLVED, dst_location); return TRUE; }
- if (sub_resource->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED)) - wined3d_texture_load_location(&texture_gl->t, sub_resource_idx, &context_gl->c, WINED3D_LOCATION_TEXTURE_RGB); - - /* Download the sub-resource to system memory. */ if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) { unsigned int row_pitch, slice_pitch, level;
From: Matteo Bruni mbruni@codeweavers.com
--- dlls/wined3d/surface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 99338b91d5b..87b3d3c38a4 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -368,7 +368,7 @@ void texture2d_read_from_framebuffer(struct wined3d_texture *texture, unsigned i
restore_texture = context->current_rt.texture; restore_idx = context->current_rt.sub_resource_idx; - if (restore_texture != texture || restore_idx != sub_resource_idx) + if (!wined3d_resource_is_offscreen(resource) && (restore_texture != texture || restore_idx != sub_resource_idx)) context = context_acquire(device, texture, sub_resource_idx); else restore_texture = NULL;
From: Matteo Bruni mbruni@codeweavers.com
This is in the same vein as e106bbdd39a5f27bce028ed992033eb0a5635f60 and further fallout from 2ddb6b66a7cda0bf6aaddc0c6899e35cc92ceee9. --- dlls/wined3d/arb_program_shader.c | 22 ---------------------- 1 file changed, 22 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 1008aefd76f..817b9ad9af0 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -6583,28 +6583,6 @@ static void fragment_prog_arbfp(struct wined3d_context *context, const struct wi
TRACE("context %p, state %p, state_id %#lx.\n", context, state, state_id);
- if (isStateDirty(context, STATE_RENDER(WINED3D_RS_FOGENABLE))) - { - if (!use_pshader && device->shader_backend == &arb_program_shader_backend && context->last_was_pshader) - { - /* Reload fixed function constants since they collide with the - * pixel shader constants. */ - for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) - { - set_bumpmat_arbfp(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_BUMPENV_MAT00)); - state_tss_constant_arbfp(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_CONSTANT)); - } - state_texfactor_arbfp(context, state, STATE_RENDER(WINED3D_RS_TEXTUREFACTOR)); - state_arb_specularenable(context, state, STATE_RENDER(WINED3D_RS_SPECULARENABLE)); - color_key_arbfp(context, state, STATE_COLOR_KEY); - } - else if (use_pshader) - { - context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL; - } - return; - } - if (!use_pshader) { /* Find or create a shader implementing the fixed function pipeline
Some wined3d git archaeology suggests that the wined3d_context_gl_apply_blit_state() call was added right before Wine 1.2 to workaround various driver issues with glReadPixels() that in practice was erroneously affected by some GL states. If those kind of issues are still a thing, it might be necessary to reintroduce some limited state reset, possibly tied to a quirk.
I'll try this on my r200 GPU together with the dx7 sdk samples. This was the driver for which I wrote a lot of those workarounds back then, although it certainly wasn't the only one. I'd hope Mesa's higher level abstraction layers nowadays fixed this even if r200 wasn't touched much in many years.
Afair glDrawPixels was the one where rendering was broken. glReadPixels was merely slow (like, 10 seconds for one frame) or caused an X server crash or kernel panic.
This merge request was approved by Zebediah Figura.
This merge request was approved by Jan Sikorski.