3302{
3303 unsigned int bpp, src_height, src_width, dst_height, dst_width, row_byte_count;
3308 unsigned int src_fmt_flags, dst_fmt_flags;
3311 unsigned int x, sx, xinc,
y, sy, yinc;
3312 unsigned int texture_level;
3314 BOOL same_sub_resource;
3319
3320 TRACE(
"dst_texture %p, dst_sub_resource_idx %u, dst_box %s, src_texture %p, "
3321 "src_sub_resource_idx %u, src_box %s, flags %#x, fx %p, filter %s.\n",
3322 dst_texture, dst_sub_resource_idx,
debug_box(dst_box), src_texture,
3324
3325 if (
device->d3d_initialized)
3327
3328 if (src_texture == dst_texture && src_sub_resource_idx == dst_sub_resource_idx)
3329 {
3330 same_sub_resource =
TRUE;
3331
3332 map_binding = dst_texture->
resource.map_binding;
3333 texture_level = dst_sub_resource_idx % dst_texture->
level_count;
3342
3343 src_map = dst_map;
3344 src_format = dst_texture->
resource.format;
3346 dst_fmt_flags = dst_texture->
resource.format_flags;
3347 src_fmt_flags = dst_fmt_flags;
3348 }
3349 else
3350 {
3351 same_sub_resource =
FALSE;
3353 dst_fmt_flags = dst_texture->
resource.format_flags;
3355 {
3357 {
3363 }
3364 src_texture = converted_texture;
3365 src_sub_resource_idx = 0;
3366 }
3367 src_format = src_texture->
resource.format;
3368 src_fmt_flags = src_texture->
resource.format_flags;
3369
3370 map_binding = src_texture->
resource.map_binding;
3371 texture_level = src_sub_resource_idx % src_texture->
level_count;
3378
3379 map_binding = dst_texture->
resource.map_binding;
3380 texture_level = dst_sub_resource_idx % dst_texture->
level_count;
3388 }
3389 flags &= ~WINED3D_BLT_RAW;
3390
3392 src_height = src_box->
bottom - src_box->
top;
3393 src_width = src_box->
right - src_box->
left;
3394 dst_height = dst_box->
bottom - dst_box->
top;
3395 dst_width = dst_box->
right - dst_box->
left;
3396 row_byte_count = dst_width *
bpp;
3397
3398 sbase = (
BYTE *)src_map.data
3401 dbuf = (
BYTE *)dst_map.data
3402 + ((dst_box->
top /
dst_format->block_height) * dst_map.row_pitch)
3404
3406 {
3408
3409 if (same_sub_resource)
3410 {
3411 FIXME(
"Only plain blits supported on compressed surfaces.\n");
3413 goto release;
3414 }
3415
3416 if (src_height != dst_height || src_width != dst_width)
3417 {
3418 WARN(
"Stretching not supported on compressed surfaces.\n");
3420 goto release;
3421 }
3422
3424 src_map.row_pitch, dst_map.row_pitch, dst_width, dst_height,
3426 goto release;
3427 }
3428
3430 && (src_width != dst_width || src_height != dst_height))
3431 {
3432
3433 static int once;
3435 }
3436
3437 xinc = (src_width << 16) / dst_width;
3438 yinc = (src_height << 16) / dst_height;
3439
3441 {
3442
3443 if (dst_width == src_width)
3444 {
3445 if (dst_height == src_height)
3446 {
3447
3448
3449 sbuf = sbase;
3450
3451
3452 if (!same_sub_resource || dst_box->
top < src_box->
top
3454 {
3455
3456 for (
y = 0;
y < dst_height; ++
y)
3457 {
3458 memcpy(dbuf, sbuf, row_byte_count);
3459 sbuf += src_map.row_pitch;
3460 dbuf += dst_map.row_pitch;
3461 }
3462 }
3463 else if (dst_box->
top > src_box->
top)
3464 {
3465
3466 sbuf += src_map.row_pitch * dst_height;
3467 dbuf += dst_map.row_pitch * dst_height;
3468 for (
y = 0;
y < dst_height; ++
y)
3469 {
3470 sbuf -= src_map.row_pitch;
3471 dbuf -= dst_map.row_pitch;
3472 memcpy(dbuf, sbuf, row_byte_count);
3473 }
3474 }
3475 else
3476 {
3477
3478 for (
y = 0;
y < dst_height; ++
y)
3479 {
3480 memmove(dbuf, sbuf, row_byte_count);
3481 sbuf += src_map.row_pitch;
3482 dbuf += dst_map.row_pitch;
3483 }
3484 }
3485 }
3486 else
3487 {
3488
3489 for (
y = sy = 0;
y < dst_height; ++
y, sy += yinc)
3490 {
3491 sbuf = sbase + (sy >> 16) * src_map.row_pitch;
3492 memcpy(dbuf, sbuf, row_byte_count);
3493 dbuf += dst_map.row_pitch;
3494 }
3495 }
3496 }
3497 else
3498 {
3499
3500 unsigned int last_sy = ~0
u;
3501 for (
y = sy = 0;
y < dst_height; ++
y, sy += yinc)
3502 {
3503 sbuf = sbase + (sy >> 16) * src_map.row_pitch;
3504
3505 if ((sy >> 16) == (last_sy >> 16))
3506 {
3507
3508
3509 memcpy(dbuf, dbuf - dst_map.row_pitch, row_byte_count);
3510 }
3511 else
3512 {
3513#define STRETCH_ROW(type) \
3514do { \
3515 const type *s = (const type *)sbuf; \
3516 type *d = (type *)dbuf; \
3517 for (x = sx = 0; x < dst_width; ++x, sx += xinc) \
3518 d[x] = s[sx >> 16]; \
3519} while(0)
3520
3522 {
3523 case 1:
3525 break;
3526 case 2:
3528 break;
3529 case 4:
3531 break;
3532 case 3:
3533 {
3536 for (
x = sx = 0;
x < dst_width;
x++, sx+= xinc)
3537 {
3539
3540 s = sbuf + 3 * (sx >> 16);
3541 pixel =
s[0] | (
s[1] << 8) | (
s[2] << 16);
3542 d[0] = (pixel ) & 0xff;
3543 d[1] = (pixel >> 8) & 0xff;
3544 d[2] = (pixel >> 16) & 0xff;
3546 }
3547 break;
3548 }
3549 default:
3550 FIXME(
"Stretched blit not implemented for bpp %u.\n",
bpp * 8);
3553 }
3554#undef STRETCH_ROW
3555 }
3556 dbuf += dst_map.row_pitch;
3557 last_sy = sy;
3558 }
3559 }
3560 }
3561 else
3562 {
3563 LONG dstyinc = dst_map.row_pitch, dstxinc =
bpp;
3564 DWORD keylow = 0xffffffff, keyhigh = 0, keymask = 0xffffffff;
3565 DWORD destkeylow = 0x0, destkeyhigh = 0xffffffff, destkeymask = 0xffffffff;
3568 {
3569
3571 {
3572 keylow = src_texture->
async.src_blt_color_key.color_space_low_value;
3573 keyhigh = src_texture->
async.src_blt_color_key.color_space_high_value;
3574 }
3576 {
3577 keylow =
fx->src_color_key.color_space_low_value;
3578 keyhigh =
fx->src_color_key.color_space_high_value;
3579 }
3580
3582 {
3583
3584 destkeylow = src_texture->
async.dst_blt_color_key.color_space_low_value;
3585 destkeyhigh = src_texture->
async.dst_blt_color_key.color_space_high_value;
3586 }
3588 {
3589 destkeylow =
fx->dst_color_key.color_space_low_value;
3590 destkeyhigh =
fx->dst_color_key.color_space_high_value;
3591 }
3592
3594 {
3595 keymask = 0xff;
3596 }
3597 else
3598 {
3602 }
3605 }
3606
3608 {
3609 BYTE *dTopLeft, *dTopRight, *dBottomLeft, *dBottomRight, *tmp;
3611 dTopLeft = dbuf;
3612 dTopRight = dbuf + ((dst_width - 1) *
bpp);
3613 dBottomLeft = dTopLeft + ((dst_height - 1) * dst_map.row_pitch);
3614 dBottomRight = dBottomLeft + ((dst_width - 1) *
bpp);
3615
3617 {
3618
3619 WARN(
"Nothing done for WINEDDBLTFX_ARITHSTRETCHY.\n");
3620 }
3622 {
3623 tmp = dTopRight;
3624 dTopRight = dTopLeft;
3625 dTopLeft = tmp;
3626 tmp = dBottomRight;
3627 dBottomRight = dBottomLeft;
3628 dBottomLeft = tmp;
3629 dstxinc = dstxinc * -1;
3630 }
3632 {
3633 tmp = dTopLeft;
3634 dTopLeft = dBottomLeft;
3635 dBottomLeft = tmp;
3636 tmp = dTopRight;
3637 dTopRight = dBottomRight;
3638 dBottomRight = tmp;
3639 dstyinc = dstyinc * -1;
3640 }
3642 {
3643
3644 WARN(
"Nothing done for WINEDDBLTFX_NOTEARING.\n");
3645 }
3647 {
3648 tmp = dBottomRight;
3649 dBottomRight = dTopLeft;
3650 dTopLeft = tmp;
3651 tmp = dBottomLeft;
3652 dBottomLeft = dTopRight;
3653 dTopRight = tmp;
3654 dstxinc = dstxinc * -1;
3655 dstyinc = dstyinc * -1;
3656 }
3658 {
3659 tmp = dTopLeft;
3660 dTopLeft = dBottomLeft;
3661 dBottomLeft = dBottomRight;
3662 dBottomRight = dTopRight;
3663 dTopRight = tmp;
3664 tmpxy = dstxinc;
3665 dstxinc = dstyinc;
3666 dstyinc = tmpxy;
3667 dstxinc = dstxinc * -1;
3668 }
3670 {
3671 tmp = dTopLeft;
3672 dTopLeft = dTopRight;
3673 dTopRight = dBottomRight;
3674 dBottomRight = dBottomLeft;
3675 dBottomLeft = tmp;
3676 tmpxy = dstxinc;
3677 dstxinc = dstyinc;
3678 dstyinc = tmpxy;
3679 dstyinc = dstyinc * -1;
3680 }
3682 {
3683
3684 WARN(
"Nothing done for WINEDDBLTFX_ZBUFFERBASEDEST.\n");
3685 }
3686 dbuf = dTopLeft;
3688 }
3689
3690#define COPY_COLORKEY_FX(type) \
3691do { \
3692 const type *s; \
3693 type *d = (type *)dbuf, *dx, tmp; \
3694 for (y = sy = 0; y < dst_height; ++y, sy += yinc) \
3695 { \
3696 s = (const type *)(sbase + (sy >> 16) * src_map.row_pitch); \
3697 dx = d; \
3698 for (x = sx = 0; x < dst_width; ++x, sx += xinc) \
3699 { \
3700 tmp = s[sx >> 16]; \
3701 if (((tmp & keymask) < keylow || (tmp & keymask) > keyhigh) \
3702 && ((dx[0] & destkeymask) >= destkeylow && (dx[0] & destkeymask) <= destkeyhigh)) \
3703 { \
3704 dx[0] = tmp; \
3705 } \
3706 dx = (type *)(((BYTE *)dx) + dstxinc); \
3707 } \
3708 d = (type *)(((BYTE *)d) + dstyinc); \
3709 } \
3710} while(0)
3711
3713 {
3714 case 1:
3716 break;
3717 case 2:
3719 break;
3720 case 4:
3722 break;
3723 case 3:
3724 {
3727 for (
y = sy = 0;
y < dst_height; ++
y, sy += yinc)
3728 {
3729 sbuf = sbase + (sy >> 16) * src_map.row_pitch;
3731 for (
x = sx = 0;
x < dst_width; ++
x, sx+= xinc)
3732 {
3733 DWORD pixel, dpixel = 0;
3734 s = sbuf + 3 * (sx>>16);
3735 pixel =
s[0] | (
s[1] << 8) | (
s[2] << 16);
3736 dpixel =
dx[0] | (
dx[1] << 8 ) | (
dx[2] << 16);
3737 if (((pixel & keymask) < keylow || (pixel & keymask) > keyhigh)
3738 && ((dpixel & keymask) >= destkeylow || (dpixel & keymask) <= keyhigh))
3739 {
3740 dx[0] = (pixel ) & 0xff;
3741 dx[1] = (pixel >> 8) & 0xff;
3742 dx[2] = (pixel >> 16) & 0xff;
3743 }
3745 }
3747 }
3748 break;
3749 }
3750 default:
3751 FIXME(
"%s color-keyed blit not implemented for bpp %u.\n",
3755#undef COPY_COLORKEY_FX
3756 }
3757 }
3758
3762
3763release:
3765 if (!same_sub_resource)
3768 {
3771 dst_texture->
swapchain->swapchain_ops->swapchain_frontbuffer_updated(dst_texture->
swapchain);
3772 }
3773 if (converted_texture)
3777
3779}
#define STRETCH_ROW(type)
static void get_color_masks(const struct wined3d_format *format, DWORD *masks)
static struct wined3d_texture * surface_convert_format(struct wined3d_texture *src_texture, unsigned int sub_resource_idx, const struct wined3d_format *dst_format)
static HRESULT surface_cpu_blt_compressed(const BYTE *src_data, BYTE *dst_data, UINT src_pitch, UINT dst_pitch, UINT update_w, UINT update_h, const struct wined3d_format *format, DWORD flags, const struct wined3d_blt_fx *fx)
#define COPY_COLORKEY_FX(type)
ULONG CDECL wined3d_texture_decref(struct wined3d_texture *texture)
const char * debug_box(const struct wined3d_box *box)
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
#define memmove(s1, s2, n)
#define WINEDDBLTFX_ROTATE270
#define WINEDDBLTFX_NOTEARING
#define WINEDDBLTFX_MIRRORUPDOWN
#define WINEDDBLTFX_ROTATE90
#define WINED3DERR_NOTAVAILABLE
#define WINEDDBLTFX_ZBUFFERBASEDEST
#define WINEDDBLTFX_ARITHSTRETCHY
#define WINEDDBLTFX_ROTATE180
#define WINEDDBLTFX_MIRRORLEFTRIGHT
#define WINED3DFMT_FLAG_BLOCKS
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)