Fixes a regression from commit 74b9ef2c1d7bc37c79b02b7c541d4b440de0b43d.
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/wined3d/state.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index d860d13bdb0..6df5a6d0190 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -1584,17 +1584,17 @@ static void state_colorwrite0(struct wined3d_context *context, const struct wine
static void state_colorwrite1(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - set_color_mask(wined3d_context_gl(context)->gl_info, 1, state->render_states[WINED3D_RS_COLORWRITEENABLE]); + set_color_mask(wined3d_context_gl(context)->gl_info, 1, state->render_states[WINED3D_RS_COLORWRITEENABLE1]); }
static void state_colorwrite2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - set_color_mask(wined3d_context_gl(context)->gl_info, 2, state->render_states[WINED3D_RS_COLORWRITEENABLE]); + set_color_mask(wined3d_context_gl(context)->gl_info, 2, state->render_states[WINED3D_RS_COLORWRITEENABLE2]); }
static void state_colorwrite3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - set_color_mask(wined3d_context_gl(context)->gl_info, 3, state->render_states[WINED3D_RS_COLORWRITEENABLE]); + set_color_mask(wined3d_context_gl(context)->gl_info, 3, state->render_states[WINED3D_RS_COLORWRITEENABLE3]); }
static void state_localviewer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/wined3d/adapter_gl.c | 2 +- dlls/wined3d/arb_program_shader.c | 1 - dlls/wined3d/glsl_shader.c | 22 ++++++++++------------ dlls/wined3d/shader.c | 2 +- dlls/wined3d/utils.c | 6 +++--- dlls/wined3d/wined3d_private.h | 4 ++-- 6 files changed, 17 insertions(+), 20 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c index 0b7fcf47297..8684a4e07cf 100644 --- a/dlls/wined3d/adapter_gl.c +++ b/dlls/wined3d/adapter_gl.c @@ -3770,7 +3770,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, d3d_info->limits.vs_uniform_count = shader_caps.vs_uniform_count; d3d_info->limits.ps_uniform_count = shader_caps.ps_uniform_count; d3d_info->limits.varying_count = shader_caps.varying_count; - d3d_info->limits.max_compat_varying_count = shader_caps.max_compat_varying_count; + d3d_info->full_ffp_varyings = !!(shader_caps.wined3d_caps & WINED3D_SHADER_CAP_FULL_FFP_VARYINGS); d3d_info->shader_double_precision = !!(shader_caps.wined3d_caps & WINED3D_SHADER_CAP_DOUBLE_PRECISION); d3d_info->shader_output_interpolation = !!(shader_caps.wined3d_caps & WINED3D_SHADER_CAP_OUTPUT_INTERPOLATION);
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index b81898b78e7..9502430ef5a 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -4958,7 +4958,6 @@ static void shader_arb_get_caps(const struct wined3d_adapter *adapter, struct sh }
caps->varying_count = 0; - caps->max_compat_varying_count = 0; caps->wined3d_caps = WINED3D_SHADER_CAP_SRGB_WRITE; if (use_nv_clip(gl_info)) caps->wined3d_caps |= WINED3D_SHADER_CAP_VS_CLIPPING; diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index e5f51925cdc..0f1a319872f 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -420,13 +420,12 @@ static void shader_glsl_add_version_declaration(struct wined3d_string_buffer *bu shader_addline(buffer, "#version %u\n", shader_glsl_get_version(gl_info)); }
-unsigned int shader_glsl_max_compat_varyings(const struct wined3d_gl_info *gl_info) +unsigned int shader_glsl_full_ffp_varyings(const struct wined3d_gl_info *gl_info) { /* On core profile we have to also count diffuse and specular colours and * the fog coordinate. */ - if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]) - return WINED3D_MAX_TEXTURES * 4; - return (WINED3D_MAX_TEXTURES + 2) * 4 + 1; + return gl_info->limits.glsl_varyings >= (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] + ? WINED3D_MAX_TEXTURES * 4 : (WINED3D_MAX_TEXTURES + 2) * 4 + 1); }
static void shader_glsl_append_imm_vec(struct wined3d_string_buffer *buffer, @@ -7155,8 +7154,7 @@ static GLuint shader_glsl_generate_vs3_rasterizer_input_setup(struct shader_glsl
if (texcoords_written_mask[i] != WINED3DSP_WRITEMASK_ALL) { - if (gl_info->limits.glsl_varyings < shader_glsl_max_compat_varyings(gl_info) - && !texcoords_written_mask[i]) + if (!shader_glsl_full_ffp_varyings(gl_info) && !texcoords_written_mask[i]) continue;
shader_glsl_write_mask_to_str(~texcoords_written_mask[i] & WINED3DSP_WRITEMASK_ALL, reg_mask); @@ -9066,7 +9064,7 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr if (settings->texcoords & (1u << i)) shader_addline(buffer, "ffp_varying_texcoord[%u] = ffp_texture_matrix[%u] * ffp_attrib_texcoord%u;\n", i, i, i); - else if (gl_info->limits.glsl_varyings >= shader_glsl_max_compat_varyings(gl_info)) + else if (shader_glsl_full_ffp_varyings(gl_info)) shader_addline(buffer, "ffp_varying_texcoord[%u] = vec4(0.0);\n", i); else output_legacy_texcoord = FALSE; @@ -11104,7 +11102,6 @@ static void shader_glsl_get_caps(const struct wined3d_adapter *adapter, struct s caps->vs_uniform_count = min(WINED3D_MAX_VS_CONSTS_F, gl_info->limits.glsl_vs_float_constants); caps->ps_uniform_count = min(WINED3D_MAX_PS_CONSTS_F, gl_info->limits.glsl_ps_float_constants); caps->varying_count = gl_info->limits.glsl_varyings; - caps->max_compat_varying_count = shader_glsl_max_compat_varyings(gl_info);
/* FIXME: The following line is card dependent. -8.0 to 8.0 is the * Direct3D minimum requirement. @@ -11130,6 +11127,8 @@ static void shader_glsl_get_caps(const struct wined3d_adapter *adapter, struct s | WINED3D_SHADER_CAP_SRGB_WRITE; if (needs_interpolation_qualifiers_for_shader_outputs(gl_info)) caps->wined3d_caps |= WINED3D_SHADER_CAP_OUTPUT_INTERPOLATION; + if (shader_glsl_full_ffp_varyings(gl_info)) + caps->wined3d_caps |= WINED3D_SHADER_CAP_FULL_FFP_VARYINGS; }
static BOOL shader_glsl_color_fixup_supported(struct color_fixup_desc fixup) @@ -11555,8 +11554,7 @@ static void glsl_vertex_pipe_vdecl(struct wined3d_context *context, * Likewise, we have to invalidate the shader when using per-vertex * colours and diffuse/specular attribute presence changes, or when * normal presence changes. */ - if (gl_info->limits.glsl_varyings < shader_glsl_max_compat_varyings(gl_info) - || (state->render_states[WINED3D_RS_COLORVERTEX] + if (!shader_glsl_full_ffp_varyings(gl_info) || (state->render_states[WINED3D_RS_COLORVERTEX] && (diffuse != context->last_was_diffuse || specular != context->last_was_specular)) || normal != context->last_was_normal) context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX; @@ -12071,7 +12069,7 @@ static void glsl_fragment_pipe_vdecl(struct wined3d_context *context, const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info;
/* Because of settings->texcoords_initialized and args->texcoords_initialized. */ - if (gl_info->limits.glsl_varyings < shader_glsl_max_compat_varyings(gl_info)) + if (!shader_glsl_full_ffp_varyings(gl_info)) context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL;
if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_FOGENABLE))) @@ -12084,7 +12082,7 @@ static void glsl_fragment_pipe_vs(struct wined3d_context *context, const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info;
/* Because of settings->texcoords_initialized and args->texcoords_initialized. */ - if (gl_info->limits.glsl_varyings < shader_glsl_max_compat_varyings(gl_info)) + if (!shader_glsl_full_ffp_varyings(gl_info)) context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL; }
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 87089950235..4961dca1ce0 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -4114,7 +4114,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 } }
- if (d3d_info->limits.varying_count < d3d_info->limits.max_compat_varying_count) + if (!d3d_info->full_ffp_varyings) { const struct wined3d_shader *vs = state->shader[WINED3D_SHADER_TYPE_VERTEX];
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index b9cad2a56b4..cf7c177f76e 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -6188,7 +6188,7 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d * Reading uninitialized varyings on core profile contexts results in an * error while with builtin varyings on legacy contexts you get undefined * behavior. */ - if (d3d_info->limits.varying_count && d3d_info->limits.varying_count < d3d_info->limits.max_compat_varying_count) + if (d3d_info->limits.varying_count && !d3d_info->full_ffp_varyings) { settings->texcoords_initialized = 0; for (i = 0; i < WINED3D_MAX_TEXTURES; ++i) @@ -6395,7 +6395,7 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, settings->texcoords |= 1u << i; settings->texgen[i] = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX]; } - if (d3d_info->limits.varying_count >= d3d_info->limits.max_compat_varying_count) + if (d3d_info->full_ffp_varyings) settings->texcoords = (1u << WINED3D_MAX_TEXTURES) - 1;
if (d3d_info->emulated_flatshading) @@ -6444,7 +6444,7 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, settings->texcoords |= 1u << i; settings->texgen[i] = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX]; } - if (d3d_info->limits.varying_count >= d3d_info->limits.max_compat_varying_count) + if (d3d_info->full_ffp_varyings) settings->texcoords = (1u << WINED3D_MAX_TEXTURES) - 1;
for (i = 0; i < WINED3D_MAX_ACTIVE_LIGHTS; ++i) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 80ed41bb845..229974d0c83 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -176,7 +176,6 @@ struct wined3d_d3d_limits
unsigned int max_rt_count; unsigned int max_clip_distances; - unsigned int max_compat_varying_count; unsigned int texture_size; float pointsize_max; }; @@ -218,6 +217,7 @@ struct wined3d_d3d_info uint32_t srgb_read_control : 1; uint32_t srgb_write_control : 1; uint32_t clip_control : 1; + uint32_t full_ffp_varyings : 1; enum wined3d_feature_level feature_level;
DWORD multisample_draw_location; @@ -1309,6 +1309,7 @@ typedef void (*SHADER_HANDLER)(const struct wined3d_shader_instruction *); #define WINED3D_SHADER_CAP_SRGB_WRITE 0x00000002u #define WINED3D_SHADER_CAP_DOUBLE_PRECISION 0x00000004u #define WINED3D_SHADER_CAP_OUTPUT_INTERPOLATION 0x00000008u +#define WINED3D_SHADER_CAP_FULL_FFP_VARYINGS 0x00000010u
struct shader_caps { @@ -1323,7 +1324,6 @@ struct shader_caps unsigned int ps_uniform_count; float ps_1x_max_value; unsigned int varying_count; - unsigned int max_compat_varying_count;
DWORD wined3d_caps; };
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/d3d9/tests/d3d9ex.c | 6 +++--- dlls/d3d9/tests/device.c | 6 +++--- include/d3d9caps.h | 3 --- 3 files changed, 6 insertions(+), 9 deletions(-)
diff --git a/dlls/d3d9/tests/d3d9ex.c b/dlls/d3d9/tests/d3d9ex.c index 354a51d85a1..2792b09631c 100644 --- a/dlls/d3d9/tests/d3d9ex.c +++ b/dlls/d3d9/tests/d3d9ex.c @@ -4025,9 +4025,9 @@ static void test_device_caps(void) | D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING | D3DPMISCCAPS_FOGVERTEXCLAMPED | D3DPMISCCAPS_POSTBLENDSRGBCONVERT)), "PrimitiveMiscCaps field has unexpected flags %#x.\n", caps.PrimitiveMiscCaps); - ok(!(caps.RasterCaps & ~(D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_PAT | D3DPRASTERCAPS_ZTEST - | D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_ANTIALIASEDGES - | D3DPRASTERCAPS_MIPMAPLODBIAS | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZBUFFERLESSHSR + ok(!(caps.RasterCaps & ~(D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_ZTEST + | D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_FOGTABLE + | D3DPRASTERCAPS_MIPMAPLODBIAS | D3DPRASTERCAPS_ZBUFFERLESSHSR | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_ANISOTROPY | D3DPRASTERCAPS_WBUFFER | D3DPRASTERCAPS_WFOG | D3DPRASTERCAPS_ZFOG | D3DPRASTERCAPS_COLORPERSPECTIVE | D3DPRASTERCAPS_SCISSORTEST | D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index f05aded3815..06607481b89 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -12644,9 +12644,9 @@ static void test_device_caps(void) | D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING | D3DPMISCCAPS_FOGVERTEXCLAMPED | D3DPMISCCAPS_POSTBLENDSRGBCONVERT)), "PrimitiveMiscCaps field has unexpected flags %#x.\n", caps.PrimitiveMiscCaps); - ok(!(caps.RasterCaps & ~(D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_PAT | D3DPRASTERCAPS_ZTEST - | D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_ANTIALIASEDGES - | D3DPRASTERCAPS_MIPMAPLODBIAS | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZBUFFERLESSHSR + ok(!(caps.RasterCaps & ~(D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_ZTEST + | D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_FOGTABLE + | D3DPRASTERCAPS_MIPMAPLODBIAS | D3DPRASTERCAPS_ZBUFFERLESSHSR | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_ANISOTROPY | D3DPRASTERCAPS_WBUFFER | D3DPRASTERCAPS_WFOG | D3DPRASTERCAPS_ZFOG | D3DPRASTERCAPS_COLORPERSPECTIVE | D3DPRASTERCAPS_SCISSORTEST | D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS diff --git a/include/d3d9caps.h b/include/d3d9caps.h index 58fd3d91d01..feee0d4ce55 100644 --- a/include/d3d9caps.h +++ b/include/d3d9caps.h @@ -125,13 +125,10 @@ #endif
#define D3DPRASTERCAPS_DITHER __MSABI_LONG(0x00000001) -#define D3DPRASTERCAPS_PAT __MSABI_LONG(0x00000008) #define D3DPRASTERCAPS_ZTEST __MSABI_LONG(0x00000010) #define D3DPRASTERCAPS_FOGVERTEX __MSABI_LONG(0x00000080) #define D3DPRASTERCAPS_FOGTABLE __MSABI_LONG(0x00000100) -#define D3DPRASTERCAPS_ANTIALIASEDGES __MSABI_LONG(0x00001000) #define D3DPRASTERCAPS_MIPMAPLODBIAS __MSABI_LONG(0x00002000) -#define D3DPRASTERCAPS_ZBIAS __MSABI_LONG(0x00004000) #define D3DPRASTERCAPS_ZBUFFERLESSHSR __MSABI_LONG(0x00008000) #define D3DPRASTERCAPS_FOGRANGE __MSABI_LONG(0x00010000) #define D3DPRASTERCAPS_ANISOTROPY __MSABI_LONG(0x00020000)
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=55447
Your paranoid android.
=== debian10 (32 bit report) ===
d3d9: d3d9ex: Timeout device: Timeout
=== debian10 (build log) ===
Task: WineTest did not produce the win32_fr_FR report
=== debian10 (32 bit WoW report) ===
d3d9: d3d9ex: Timeout device: Timeout
=== debian10 (build log) ===
Task: WineTest did not produce the wow64 report
On Wed, 14 Aug 2019 at 00:33, Matteo Bruni mbruni@codeweavers.com wrote:
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
dlls/d3d9/tests/d3d9ex.c | 6 +++--- dlls/d3d9/tests/device.c | 6 +++--- include/d3d9caps.h | 3 --- 3 files changed, 6 insertions(+), 9 deletions(-)
These fail here on Windows:
device.c:12647: Test failed: RasterCaps field has unexpected flags 0xf736191. d3d9ex.c:4028: Test failed: RasterCaps field has unexpected flags 0xf736191.
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- wined3d_texture_blt_special() doesn't actually support any blit flag (even worse, it entirely ignores most of them).
dlls/wined3d/surface.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 99ee1a4addf..23dc2290480 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -2939,14 +2939,14 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_
if (!device->d3d_initialized) { - WARN("D3D not initialized, using fallback.\n"); + WARN("D3D not initialized, using CPU blit fallback.\n"); goto cpu; }
if (flags & ~simple_blit) { - WARN_(d3d_perf)("Using fallback for complex blit (%#x).\n", flags); - goto fallback; + WARN_(d3d_perf)("Using CPU fallback for complex blit (%#x).\n", flags); + goto cpu; }
src_swapchain = src_texture->swapchain; @@ -2960,7 +2960,9 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_ if (src_swapchain && dst_swapchain && src_swapchain != dst_swapchain) { FIXME("Using fallback for cross-swapchain blit.\n"); - goto fallback; + if (SUCCEEDED(wined3d_texture_blt_special(dst_texture, dst_sub_resource_idx, &dst_rect, + src_texture, src_sub_resource_idx, &src_rect, flags, fx, filter))) + return WINED3D_OK; }
scale = src_box->right - src_box->left != dst_box->right - dst_box->left @@ -3121,12 +3123,6 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_
return WINED3D_OK;
-fallback: - /* Special cases for render targets. */ - if (SUCCEEDED(wined3d_texture_blt_special(dst_texture, dst_sub_resource_idx, &dst_rect, - src_texture, src_sub_resource_idx, &src_rect, flags, fx, filter))) - return WINED3D_OK; - cpu: return surface_cpu_blt(dst_texture, dst_sub_resource_idx, dst_box, src_texture, src_sub_resource_idx, src_box, flags, fx, filter);
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
It turns out it was actually dead code. The last remaining caller was the cross-swapchain blit case but surface_blt_special() actually rejected those (or any swapchain to swapchain blit).
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- Right now a drawable -> texture CPU blit starts with calling surface_load_sysmem() on the drawable, which is a bit ugly since probably we don't ever want to download the drawable - it's a GPU-only access texture. A staging texture might be a solution.
dlls/wined3d/surface.c | 554 +---------------------------------------- 1 file changed, 4 insertions(+), 550 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 23dc2290480..de77df2ca07 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -876,547 +876,6 @@ void texture2d_load_fb_texture(struct wined3d_texture_gl *texture_gl, context_restore(context, restore_texture, restore_idx); }
-/* Does a direct frame buffer -> texture copy. Stretching is done with single - * pixel copy calls. */ -static void fb_copy_to_texture_direct(struct wined3d_texture_gl *dst_texture, unsigned int dst_sub_resource_idx, - const RECT *dst_rect_in, struct wined3d_texture_gl *src_texture, unsigned int src_sub_resource_idx, - const RECT *src_rect, enum wined3d_texture_filter_type filter) -{ - struct wined3d_device *device = dst_texture->t.resource.device; - unsigned int src_height, src_level, dst_level; - const struct wined3d_gl_info *gl_info; - struct wined3d_context_gl *context_gl; - float xrel, yrel; - struct wined3d_context *context; - BOOL upsidedown = FALSE; - RECT dst_rect = *dst_rect_in; - GLenum dst_target; - - /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag - * glCopyTexSubImage is a bit picky about the parameters we pass to it - */ - if(dst_rect.top > dst_rect.bottom) { - UINT tmp = dst_rect.bottom; - dst_rect.bottom = dst_rect.top; - dst_rect.top = tmp; - upsidedown = TRUE; - } - - context = context_acquire(device, &src_texture->t, src_sub_resource_idx); - context_gl = wined3d_context_gl(context); - gl_info = context_gl->gl_info; - wined3d_context_gl_apply_blit_state(context_gl, device); - wined3d_texture_load(&dst_texture->t, context, FALSE); - - /* Bind the target texture */ - wined3d_context_gl_bind_texture(context_gl, dst_texture->target, dst_texture->texture_rgb.name); - if (wined3d_resource_is_offscreen(&src_texture->t.resource)) - { - TRACE("Reading from an offscreen target\n"); - upsidedown = !upsidedown; - gl_info->gl_ops.gl.p_glReadBuffer(wined3d_context_gl_get_offscreen_gl_buffer(context_gl)); - } - else - { - gl_info->gl_ops.gl.p_glReadBuffer(wined3d_texture_get_gl_buffer(&src_texture->t)); - } - checkGLcall("glReadBuffer"); - - xrel = (float) (src_rect->right - src_rect->left) / (float) (dst_rect.right - dst_rect.left); - yrel = (float) (src_rect->bottom - src_rect->top) / (float) (dst_rect.bottom - dst_rect.top); - - if ((xrel - 1.0f < -eps) || (xrel - 1.0f > eps)) - { - FIXME_(d3d_perf)("Doing a pixel by pixel copy from the framebuffer to a texture.\n"); - - if (filter != WINED3D_TEXF_NONE && filter != WINED3D_TEXF_POINT) - ERR("Texture filtering not supported in direct blit.\n"); - } - else if ((filter != WINED3D_TEXF_NONE && filter != WINED3D_TEXF_POINT) - && ((yrel - 1.0f < -eps) || (yrel - 1.0f > eps))) - { - ERR("Texture filtering not supported in direct blit\n"); - } - - src_level = src_sub_resource_idx % src_texture->t.level_count; - dst_level = dst_sub_resource_idx % dst_texture->t.level_count; - - src_height = wined3d_texture_get_level_height(&src_texture->t, src_level); - dst_target = wined3d_texture_gl_get_sub_resource_target(dst_texture, dst_sub_resource_idx); - if (upsidedown - && !((xrel - 1.0f < -eps) || (xrel - 1.0f > eps)) - && !((yrel - 1.0f < -eps) || (yrel - 1.0f > eps))) - { - /* Upside down copy without stretching is nice, one glCopyTexSubImage call will do. */ - gl_info->gl_ops.gl.p_glCopyTexSubImage2D(dst_target, dst_level, - dst_rect.left /*xoffset */, dst_rect.top /* y offset */, - src_rect->left, src_height - src_rect->bottom, - dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top); - } - else - { - LONG row; - UINT yoffset = src_height - src_rect->top + dst_rect.top - 1; - /* I have to process this row by row to swap the image, - * otherwise it would be upside down, so stretching in y direction - * doesn't cost extra time - * - * However, stretching in x direction can be avoided if not necessary - */ - for(row = dst_rect.top; row < dst_rect.bottom; row++) { - if ((xrel - 1.0f < -eps) || (xrel - 1.0f > eps)) - { - /* Well, that stuff works, but it's very slow. - * find a better way instead - */ - LONG col; - - for (col = dst_rect.left; col < dst_rect.right; ++col) - { - gl_info->gl_ops.gl.p_glCopyTexSubImage2D(dst_target, dst_level, - dst_rect.left + col /* x offset */, row /* y offset */, - src_rect->left + col * xrel, yoffset - (int) (row * yrel), 1, 1); - } - } - else - { - gl_info->gl_ops.gl.p_glCopyTexSubImage2D(dst_target, dst_level, - dst_rect.left /* x offset */, row /* y offset */, - src_rect->left, yoffset - (int) (row * yrel), dst_rect.right - dst_rect.left, 1); - } - } - } - checkGLcall("glCopyTexSubImage2D"); - - context_release(context); - - /* The texture is now most up to date - If the surface is a render target - * and has a drawable, this path is never entered. */ - wined3d_texture_validate_location(&dst_texture->t, dst_sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_texture_invalidate_location(&dst_texture->t, dst_sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB); -} - -/* Uses the hardware to stretch and flip the image */ -static void fb_copy_to_texture_hwstretch(struct wined3d_texture_gl *dst_texture, unsigned int dst_sub_resource_idx, - const RECT *dst_rect_in, struct wined3d_texture_gl *src_texture, unsigned int src_sub_resource_idx, - const RECT *src_rect, enum wined3d_texture_filter_type filter) -{ - unsigned int src_width, src_height, src_pow2_width, src_pow2_height, src_level; - struct wined3d_device *device = dst_texture->t.resource.device; - GLenum src_target, dst_target, texture_target; - GLuint src, backup = 0; - float left, right, top, bottom; /* Texture coordinates */ - const struct wined3d_gl_info *gl_info; - struct wined3d_context_gl *context_gl; - struct wined3d_context *context; - GLenum drawBuffer = GL_BACK; - GLenum offscreen_buffer; - BOOL noBackBufferBackup; - BOOL src_offscreen; - BOOL upsidedown = FALSE; - RECT dst_rect = *dst_rect_in; - - TRACE("Using hwstretch blit\n"); - - src_target = wined3d_texture_gl_get_sub_resource_target(src_texture, src_sub_resource_idx); - dst_target = wined3d_texture_gl_get_sub_resource_target(dst_texture, dst_sub_resource_idx); - - /* Activate the Proper context for reading from the source surface, set it up for blitting */ - context = context_acquire(device, &src_texture->t, src_sub_resource_idx); - context_gl = wined3d_context_gl(context); - gl_info = context_gl->gl_info; - wined3d_context_gl_apply_ffp_blit_state(context_gl, device); - wined3d_texture_load(&dst_texture->t, context, FALSE); - - offscreen_buffer = wined3d_context_gl_get_offscreen_gl_buffer(context_gl); - src_level = src_sub_resource_idx % src_texture->t.level_count; - src_width = wined3d_texture_get_level_width(&src_texture->t, src_level); - src_height = wined3d_texture_get_level_height(&src_texture->t, src_level); - src_pow2_width = wined3d_texture_get_level_pow2_width(&src_texture->t, src_level); - src_pow2_height = wined3d_texture_get_level_pow2_height(&src_texture->t, src_level); - - src_offscreen = wined3d_resource_is_offscreen(&src_texture->t.resource); - noBackBufferBackup = src_offscreen && wined3d_settings.offscreen_rendering_mode == ORM_FBO; - if (!noBackBufferBackup && !src_texture->texture_rgb.name) - { - /* Get it a description */ - wined3d_texture_load(&src_texture->t, context, FALSE); - } - - /* Try to use an aux buffer for drawing the rectangle. This way it doesn't need restoring. - * This way we don't have to wait for the 2nd readback to finish to leave this function. - */ - if (context_gl->aux_buffers >= 2) - { - /* Got more than one aux buffer? Use the 2nd aux buffer */ - drawBuffer = GL_AUX1; - } - else if ((!src_offscreen || offscreen_buffer == GL_BACK) && context_gl->aux_buffers >= 1) - { - /* Only one aux buffer, but it isn't used (Onscreen rendering, or non-aux orm)? Use it! */ - drawBuffer = GL_AUX0; - } - - if (noBackBufferBackup) - { - gl_info->gl_ops.gl.p_glGenTextures(1, &backup); - checkGLcall("glGenTextures"); - wined3d_context_gl_bind_texture(context_gl, GL_TEXTURE_2D, backup); - texture_target = GL_TEXTURE_2D; - } - else - { - /* Backup the back buffer and copy the source buffer into a texture to draw an upside down stretched quad. If - * we are reading from the back buffer, the backup can be used as source texture - */ - texture_target = src_target; - wined3d_context_gl_bind_texture(context_gl, texture_target, src_texture->texture_rgb.name); - gl_info->gl_ops.gl.p_glEnable(texture_target); - checkGLcall("glEnable(texture_target)"); - - /* For now invalidate the texture copy of the back buffer. Drawable and sysmem copy are untouched */ - src_texture->t.sub_resources[src_sub_resource_idx].locations &= ~WINED3D_LOCATION_TEXTURE_RGB; - } - - /* Make sure that the top pixel is always above the bottom pixel, and keep a separate upside down flag - * glCopyTexSubImage is a bit picky about the parameters we pass to it - */ - if(dst_rect.top > dst_rect.bottom) { - UINT tmp = dst_rect.bottom; - dst_rect.bottom = dst_rect.top; - dst_rect.top = tmp; - upsidedown = TRUE; - } - - if (src_offscreen) - { - TRACE("Reading from an offscreen target\n"); - upsidedown = !upsidedown; - gl_info->gl_ops.gl.p_glReadBuffer(offscreen_buffer); - } - else - { - gl_info->gl_ops.gl.p_glReadBuffer(wined3d_texture_get_gl_buffer(&src_texture->t)); - } - - /* TODO: Only back up the part that will be overwritten */ - gl_info->gl_ops.gl.p_glCopyTexSubImage2D(texture_target, 0, 0, 0, 0, 0, src_width, src_height); - - checkGLcall("glCopyTexSubImage2D"); - - /* No issue with overriding these - the sampler is dirty due to blit usage */ - gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, wined3d_gl_mag_filter(filter)); - checkGLcall("glTexParameteri"); - gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, - wined3d_gl_min_mip_filter(filter, WINED3D_TEXF_NONE)); - checkGLcall("glTexParameteri"); - - if (!src_texture->t.swapchain || &src_texture->t == src_texture->t.swapchain->back_buffers[0]) - { - src = backup ? backup : src_texture->texture_rgb.name; - } - else - { - gl_info->gl_ops.gl.p_glReadBuffer(GL_FRONT); - checkGLcall("glReadBuffer(GL_FRONT)"); - - gl_info->gl_ops.gl.p_glGenTextures(1, &src); - checkGLcall("glGenTextures(1, &src)"); - wined3d_context_gl_bind_texture(context_gl, GL_TEXTURE_2D, src); - - /* TODO: Only copy the part that will be read. Use src_rect->left, - * src_rect->bottom as origin, but with the width watch out for power - * of 2 sizes. */ - gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, src_pow2_width, - src_pow2_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - checkGLcall("glTexImage2D"); - gl_info->gl_ops.gl.p_glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, src_width, src_height); - - gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - checkGLcall("glTexParameteri"); - gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - checkGLcall("glTexParameteri"); - - gl_info->gl_ops.gl.p_glReadBuffer(GL_BACK); - checkGLcall("glReadBuffer(GL_BACK)"); - - if (texture_target != GL_TEXTURE_2D) - { - gl_info->gl_ops.gl.p_glDisable(texture_target); - gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D); - texture_target = GL_TEXTURE_2D; - } - } - checkGLcall("glEnd and previous"); - - left = src_rect->left; - right = src_rect->right; - - if (!upsidedown) - { - top = src_height - src_rect->top; - bottom = src_height - src_rect->bottom; - } - else - { - top = src_height - src_rect->bottom; - bottom = src_height - src_rect->top; - } - - if (src_texture->t.flags & WINED3D_TEXTURE_NORMALIZED_COORDS) - { - left /= src_pow2_width; - right /= src_pow2_width; - top /= src_pow2_height; - bottom /= src_pow2_height; - } - - /* draw the source texture stretched and upside down. The correct surface is bound already */ - gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - gl_info->gl_ops.gl.p_glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - wined3d_context_gl_set_draw_buffer(context_gl, drawBuffer); - gl_info->gl_ops.gl.p_glReadBuffer(drawBuffer); - - gl_info->gl_ops.gl.p_glBegin(GL_QUADS); - /* bottom left */ - gl_info->gl_ops.gl.p_glTexCoord2f(left, bottom); - gl_info->gl_ops.gl.p_glVertex2i(0, 0); - - /* top left */ - gl_info->gl_ops.gl.p_glTexCoord2f(left, top); - gl_info->gl_ops.gl.p_glVertex2i(0, dst_rect.bottom - dst_rect.top); - - /* top right */ - gl_info->gl_ops.gl.p_glTexCoord2f(right, top); - gl_info->gl_ops.gl.p_glVertex2i(dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top); - - /* bottom right */ - gl_info->gl_ops.gl.p_glTexCoord2f(right, bottom); - gl_info->gl_ops.gl.p_glVertex2i(dst_rect.right - dst_rect.left, 0); - gl_info->gl_ops.gl.p_glEnd(); - checkGLcall("glEnd and previous"); - - if (texture_target != dst_target) - { - gl_info->gl_ops.gl.p_glDisable(texture_target); - gl_info->gl_ops.gl.p_glEnable(dst_target); - texture_target = dst_target; - } - - /* Now read the stretched and upside down image into the destination texture */ - wined3d_context_gl_bind_texture(context_gl, texture_target, dst_texture->texture_rgb.name); - gl_info->gl_ops.gl.p_glCopyTexSubImage2D(texture_target, - 0, - dst_rect.left, dst_rect.top, /* xoffset, yoffset */ - 0, 0, /* We blitted the image to the origin */ - dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top); - checkGLcall("glCopyTexSubImage2D"); - - if (drawBuffer == GL_BACK) - { - /* Write the back buffer backup back. */ - if (backup) - { - if (texture_target != GL_TEXTURE_2D) - { - gl_info->gl_ops.gl.p_glDisable(texture_target); - gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_2D); - texture_target = GL_TEXTURE_2D; - } - wined3d_context_gl_bind_texture(context_gl, GL_TEXTURE_2D, backup); - } - else - { - if (texture_target != src_target) - { - gl_info->gl_ops.gl.p_glDisable(texture_target); - gl_info->gl_ops.gl.p_glEnable(src_target); - texture_target = src_target; - } - wined3d_context_gl_bind_texture(context_gl, src_target, src_texture->texture_rgb.name); - } - - gl_info->gl_ops.gl.p_glBegin(GL_QUADS); - /* top left */ - gl_info->gl_ops.gl.p_glTexCoord2f(0.0f, 0.0f); - gl_info->gl_ops.gl.p_glVertex2i(0, src_height); - - /* bottom left */ - gl_info->gl_ops.gl.p_glTexCoord2f(0.0f, (float)src_height / (float)src_pow2_height); - gl_info->gl_ops.gl.p_glVertex2i(0, 0); - - /* bottom right */ - gl_info->gl_ops.gl.p_glTexCoord2f((float)src_width / (float)src_pow2_width, - (float)src_height / (float)src_pow2_height); - gl_info->gl_ops.gl.p_glVertex2i(src_width, 0); - - /* top right */ - gl_info->gl_ops.gl.p_glTexCoord2f((float)src_width / (float)src_pow2_width, 0.0f); - gl_info->gl_ops.gl.p_glVertex2i(src_width, src_height); - gl_info->gl_ops.gl.p_glEnd(); - } - gl_info->gl_ops.gl.p_glDisable(texture_target); - checkGLcall("glDisable(texture_target)"); - - /* Cleanup */ - if (src != src_texture->texture_rgb.name && src != backup) - { - gl_info->gl_ops.gl.p_glDeleteTextures(1, &src); - checkGLcall("glDeleteTextures(1, &src)"); - } - if (backup) - { - gl_info->gl_ops.gl.p_glDeleteTextures(1, &backup); - checkGLcall("glDeleteTextures(1, &backup)"); - } - - context_release(context); - - /* The texture is now most up to date - If the surface is a render target - * and has a drawable, this path is never entered. */ - wined3d_texture_validate_location(&dst_texture->t, dst_sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB); - wined3d_texture_invalidate_location(&dst_texture->t, dst_sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB); -} - -static HRESULT wined3d_texture_blt_special(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, - const RECT *dst_rect, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, - const RECT *src_rect, DWORD flags, const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) -{ - struct wined3d_swapchain *src_swapchain, *dst_swapchain; - const struct wined3d_rendertarget_view *rtv; - - TRACE("dst_texture %p, dst_sub_resource_idx %u, dst_rect %s, src_texture %p, " - "src_sub_resource_idx %u, src_rect %s, flags %#x, fx %p, filter %s.\n", - dst_texture, dst_sub_resource_idx, wine_dbgstr_rect(dst_rect), src_texture, src_sub_resource_idx, - wine_dbgstr_rect(src_rect), flags, fx, debug_d3dtexturefiltertype(filter)); - - if (dst_texture->resource.type != WINED3D_RTYPE_TEXTURE_2D) - { - FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(dst_texture->resource.type)); - return WINED3DERR_INVALIDCALL; - } - - /* Get the swapchain. One of the surfaces has to be a primary surface. */ - if (!(dst_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU)) - { - WARN("Destination resource is not GPU accessible, rejecting GL blit.\n"); - return WINED3DERR_INVALIDCALL; - } - - if (!(src_texture->resource.access & WINED3D_RESOURCE_ACCESS_GPU)) - { - WARN("Source resource is not GPU accessible, rejecting GL blit.\n"); - return WINED3DERR_INVALIDCALL; - } - - src_swapchain = src_texture->swapchain; - dst_swapchain = dst_texture->swapchain; - - /* Early sort out of cases where no render target is used */ - if (!(rtv = dst_texture->resource.device->fb.render_targets[0]) || (!src_swapchain && !dst_swapchain - && (&src_texture->resource != rtv->resource || src_sub_resource_idx != rtv->sub_resource_idx) - && (&dst_texture->resource != rtv->resource || dst_sub_resource_idx != rtv->sub_resource_idx))) - { - TRACE("No surface is render target, not using hardware blit.\n"); - return WINED3DERR_INVALIDCALL; - } - - /* No destination color keying supported */ - if (flags & (WINED3D_BLT_DST_CKEY | WINED3D_BLT_DST_CKEY_OVERRIDE)) - { - /* Can we support that with glBlendFunc if blitting to the frame buffer? */ - TRACE("Destination color key not supported in accelerated Blit, falling back to software\n"); - return WINED3DERR_INVALIDCALL; - } - - if (dst_swapchain && dst_swapchain == src_swapchain) - { - FIXME("Implement hardware blit between two surfaces on the same swapchain\n"); - return WINED3DERR_INVALIDCALL; - } - - if (dst_swapchain && src_swapchain) - { - FIXME("Implement hardware blit between two different swapchains\n"); - return WINED3DERR_INVALIDCALL; - } - - if (dst_swapchain) - { - /* Handled with regular texture -> swapchain blit */ - if (&src_texture->resource == rtv->resource && src_sub_resource_idx == rtv->sub_resource_idx) - TRACE("Blit from active render target to a swapchain\n"); - } - else if (src_swapchain && &dst_texture->resource == rtv->resource - && dst_sub_resource_idx == rtv->sub_resource_idx) - { - FIXME("Implement blit from a swapchain to the active render target\n"); - return WINED3DERR_INVALIDCALL; - } - - if (!dst_swapchain && (src_swapchain || (&src_texture->resource == rtv->resource - && src_sub_resource_idx == rtv->sub_resource_idx))) - { - unsigned int src_level, src_width, src_height; - /* Blit from render target to texture */ - BOOL stretchx; - - /* P8 read back is not implemented */ - if (src_texture->resource.format->id == WINED3DFMT_P8_UINT - || dst_texture->resource.format->id == WINED3DFMT_P8_UINT) - { - TRACE("P8 read back not supported by frame buffer to texture blit\n"); - return WINED3DERR_INVALIDCALL; - } - - if (flags & (WINED3D_BLT_SRC_CKEY | WINED3D_BLT_SRC_CKEY_OVERRIDE)) - { - TRACE("Color keying not supported by frame buffer to texture blit\n"); - return WINED3DERR_INVALIDCALL; - /* Destination color key is checked above */ - } - - if (dst_rect->right - dst_rect->left != src_rect->right - src_rect->left) - stretchx = TRUE; - else - stretchx = FALSE; - - /* Blt is a pretty powerful call, while glCopyTexSubImage2D is not. glCopyTexSubImage cannot - * flip the image nor scale it. - * - * -> If the app asks for an unscaled, upside down copy, just perform one glCopyTexSubImage2D call - * -> If the app wants an image width an unscaled width, copy it line per line - * -> If the app wants an image that is scaled on the x axis, and the destination rectangle is smaller - * than the frame buffer, draw an upside down scaled image onto the fb, read it back and restore the - * back buffer. This is slower than reading line per line, thus not used for flipping - * -> If the app wants a scaled image with a dest rect that is bigger than the fb, it has to be copied - * pixel by pixel. */ - src_level = src_sub_resource_idx % src_texture->level_count; - src_width = wined3d_texture_get_level_width(src_texture, src_level); - src_height = wined3d_texture_get_level_height(src_texture, src_level); - if (!stretchx || dst_rect->right - dst_rect->left > src_width - || dst_rect->bottom - dst_rect->top > src_height) - { - TRACE("No stretching in x direction, using direct framebuffer -> texture copy.\n"); - fb_copy_to_texture_direct(wined3d_texture_gl(dst_texture), dst_sub_resource_idx, dst_rect, - wined3d_texture_gl(src_texture), src_sub_resource_idx, src_rect, filter); - } - else - { - TRACE("Using hardware stretching to flip / stretch the texture.\n"); - fb_copy_to_texture_hwstretch(wined3d_texture_gl(dst_texture), dst_sub_resource_idx, dst_rect, - wined3d_texture_gl(src_texture), src_sub_resource_idx, src_rect, filter); - } - - return WINED3D_OK; - } - - /* Default: Fall back to the generic blt. Not an error, a TRACE is enough */ - TRACE("Didn't find any usable render target setup for hw blit, falling back to software\n"); - return WINED3DERR_INVALIDCALL; -} - /* Context activation is done by the caller. */ static void fbo_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_context *context) { @@ -2952,17 +2411,12 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_ src_swapchain = src_texture->swapchain; dst_swapchain = dst_texture->swapchain;
- /* This isn't strictly needed. FBO blits for example could deal with - * cross-swapchain blits by first downloading the source to a texture - * before switching to the destination context. We just have this here to - * not have to deal with the issue, since cross-swapchain blits should be - * rare. */ + /* TODO: We could support cross-swapchain blits by first downloading the + * source to a texture. */ if (src_swapchain && dst_swapchain && src_swapchain != dst_swapchain) { - FIXME("Using fallback for cross-swapchain blit.\n"); - if (SUCCEEDED(wined3d_texture_blt_special(dst_texture, dst_sub_resource_idx, &dst_rect, - src_texture, src_sub_resource_idx, &src_rect, flags, fx, filter))) - return WINED3D_OK; + FIXME("Cross-swapchain blit not supported.\n"); + return WINED3DERR_INVALIDCALL; }
scale = src_box->right - src_box->left != dst_box->right - dst_box->left
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/wined3d/surface.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index de77df2ca07..7009df23de7 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -2411,10 +2411,12 @@ HRESULT texture2d_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_ src_swapchain = src_texture->swapchain; dst_swapchain = dst_texture->swapchain;
- /* TODO: We could support cross-swapchain blits by first downloading the - * source to a texture. */ - if (src_swapchain && dst_swapchain && src_swapchain != dst_swapchain) + if (src_swapchain && dst_swapchain && src_swapchain != dst_swapchain + && (wined3d_settings.offscreen_rendering_mode != ORM_FBO + || src_texture == src_swapchain->front_buffer)) { + /* TODO: We could support cross-swapchain blits by first downloading + * the source to a texture. */ FIXME("Cross-swapchain blit not supported.\n"); return WINED3DERR_INVALIDCALL; }
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com