diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index 2456e162cd1..5433738c579 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -1023,6 +1023,8 @@ static HRESULT WINAPI IDirect3DDevice9Impl_StretchRect(IDirect3DDevice9Ex *iface wined3d_mutex_lock(); hr = wined3d_surface_blt(dst->wined3d_surface, pDestRect, src->wined3d_surface, pSourceRect, 0, NULL, Filter); + if (hr == WINEDDERR_INVALIDRECT) + hr = D3DERR_INVALIDCALL; wined3d_mutex_unlock(); return hr; diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index 499ea5f77ed..523bbc1ef49 100644 --- a/dlls/d3d9/tests/visual.c +++ b/dlls/d3d9/tests/visual.c @@ -2589,11 +2589,11 @@ static void stretchrect_test(IDirect3DDevice9 *device) /* Flipping in y-direction through src_rect, no scaling (not allowed) */ hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_offscreen_dest64, &dst_rect64, 0); - todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); + ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); /* Flipping in y-direction through dst_rect, no scaling (not allowed) */ hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_offscreen_dest64, &dst_rect64_flipy, 0); - todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); + ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); } /* offscreenplain ==> rendertarget texture, same size */ @@ -2618,11 +2618,11 @@ static void stretchrect_test(IDirect3DDevice9 *device) /* Flipping in y-direction through src_rect, no scaling (not allowed) */ hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0); - todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); + ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); /* Flipping in y-direction through dst_rect, no scaling (not allowed) */ hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0); - todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); + ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); } /* offscreenplain ==> rendertarget surface, same size */ @@ -2641,11 +2641,11 @@ static void stretchrect_test(IDirect3DDevice9 *device) /* Flipping in y-direction through src_rect, no scaling (not allowed) */ hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0); - todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); + ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); /* Flipping in y-direction through dst_rect, no scaling (not allowed) */ hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0); - todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); + ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); } /* offscreenplain ==> texture, same size (should fail) */ @@ -2735,11 +2735,11 @@ static void stretchrect_test(IDirect3DDevice9 *device) /* Flipping in y-direction through src_rect, no scaling (not allowed) */ hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0); - todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); + ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); /* Flipping in y-direction through dst_rect, no scaling (not allowed) */ hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0); - todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); + ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); } /* texture ==> rendertarget surface, same size */ @@ -2758,11 +2758,11 @@ static void stretchrect_test(IDirect3DDevice9 *device) /* Flipping in y-direction through src_rect, no scaling (not allowed) */ hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0); - todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); + ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); /* Flipping in y-direction through dst_rect, no scaling (not allowed) */ hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0); - todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); + ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); } /* texture ==> texture, same size (should fail) */ @@ -2857,11 +2857,11 @@ static void stretchrect_test(IDirect3DDevice9 *device) /* Flipping in y-direction through src_rect, no scaling (not allowed) */ hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0); - todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); + ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); /* Flipping in y-direction through dst_rect, no scaling (not allowed) */ hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0); - todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); + ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); } /* rendertarget texture ==> rendertarget surface, same size */ @@ -2880,11 +2880,11 @@ static void stretchrect_test(IDirect3DDevice9 *device) /* Flipping in y-direction through src_rect, no scaling (not allowed) */ hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64, 0); - todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); + ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); /* Flipping in y-direction through dst_rect, no scaling (not allowed) */ hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0); - todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); + ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); } /* rendertarget texture ==> texture, same size (should fail) */ @@ -2975,11 +2975,11 @@ static void stretchrect_test(IDirect3DDevice9 *device) /* Flipping in y-direction through src_rect, no scaling (not allowed) */ hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_tex_rt_dest64, &dst_rect64, 0); - todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); + ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); /* Flipping in y-direction through dst_rect, no scaling (not allowed) */ hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_tex_rt_dest64, &dst_rect64_flipy, 0); - todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); + ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); } /* rendertarget surface ==> rendertarget surface, same size */ @@ -2998,11 +2998,11 @@ static void stretchrect_test(IDirect3DDevice9 *device) /* Flipping in y-direction through src_rect, no scaling (not allowed) */ hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy, surf_rt_dest64, &dst_rect64_flipy, 0); - todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); + ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); /* Flipping in y-direction through dst_rect, no scaling (not allowed) */ hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64, surf_rt_dest64, &dst_rect64_flipy, 0); - todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); + ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); } /* rendertarget surface ==> texture, same size (should fail) */ @@ -3071,11 +3071,11 @@ static void stretchrect_test(IDirect3DDevice9 *device) /* Flipping in y-direction through src_rect, no scaling (not allowed) */ hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy, surf_tex_rt_dest640_480, &dst_rect, 0); - todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); + ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); /* Flipping in y-direction through dst_rect, no scaling (not allowed) */ hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect, surf_tex_rt_dest640_480, &dst_rect_flipy, 0); - todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); + ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect failed with %08x\n", hr); } /* TODO: Test format conversions */ diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index ed95d2d0f23..676536e4b4f 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -1308,10 +1308,37 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC } surface_get_rect(dst_surface, dst_rect_in, &dst_rect); + + /* The destination rect can be out of bounds on the condition + * that a clipper is set for the surface. */ + if (!dst_surface->clipper && (dst_rect.left >= dst_rect.right || dst_rect.top >= dst_rect.bottom + || dst_rect.left > dst_surface->resource.width || dst_rect.left < 0 + || dst_rect.top > dst_surface->resource.height || dst_rect.top < 0 + || dst_rect.right > dst_surface->resource.width || dst_rect.right < 0 + || dst_rect.bottom > dst_surface->resource.height || dst_rect.bottom < 0)) + { + WARN("Application gave us bad destination rectangle for blit without a clipper set.\n"); + return WINEDDERR_INVALIDRECT; + } + if (src_surface) + { surface_get_rect(src_surface, src_rect_in, &src_rect); + + if (src_rect.left >= src_rect.right || src_rect.top >= src_rect.bottom + || src_rect.left > src_surface->resource.width || src_rect.left < 0 + || src_rect.top > src_surface->resource.height || src_rect.top < 0 + || src_rect.right > src_surface->resource.width || src_rect.right < 0 + || src_rect.bottom > src_surface->resource.height || src_rect.bottom < 0) + { + WARN("Application gave us bad source rectangle for Blt.\n"); + return WINEDDERR_INVALIDRECT; + } + } else + { memset(&src_rect, 0, sizeof(src_rect)); + } if (!device->d3d_initialized) { @@ -6459,51 +6486,8 @@ static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT * dst_surface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx, debug_d3dtexturefiltertype(filter)); - /* First check for the validity of source / destination rectangles. - * This was verified using a test application and by MSDN. */ - if (src_surface) - { - if (src_rect->right < src_rect->left || src_rect->bottom < src_rect->top - || src_rect->left > src_surface->resource.width || src_rect->left < 0 - || src_rect->top > src_surface->resource.height || src_rect->top < 0 - || src_rect->right > src_surface->resource.width || src_rect->right < 0 - || src_rect->bottom > src_surface->resource.height || src_rect->bottom < 0) - { - WARN("Application gave us bad source rectangle for Blt.\n"); - return WINEDDERR_INVALIDRECT; - } - - if (!src_rect->right || !src_rect->bottom - || src_rect->left == (int)src_surface->resource.width - || src_rect->top == (int)src_surface->resource.height) - { - TRACE("Nothing to be done.\n"); - return WINED3D_OK; - } - } - xsrc = *src_rect; - /* The destination rect can be out of bounds on the condition that a - * clipper is set for the surface. */ - if (!dst_surface->clipper && (dst_rect->right < dst_rect->left || dst_rect->bottom < dst_rect->top - || dst_rect->left > dst_surface->resource.width || dst_rect->left < 0 - || dst_rect->top > dst_surface->resource.height || dst_rect->top < 0 - || dst_rect->right > dst_surface->resource.width || dst_rect->right < 0 - || dst_rect->bottom > dst_surface->resource.height || dst_rect->bottom < 0)) - { - WARN("Application gave us bad destination rectangle for Blt without a clipper set.\n"); - return WINEDDERR_INVALIDRECT; - } - - if (dst_rect->right <= 0 || dst_rect->bottom <= 0 - || dst_rect->left >= (int)dst_surface->resource.width - || dst_rect->top >= (int)dst_surface->resource.height) - { - TRACE("Nothing to be done.\n"); - return WINED3D_OK; - } - if (!src_surface) { RECT full_rect;