From patchwork Wed Jul 3 10:56:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: BALATON Zoltan X-Patchwork-Id: 11029355 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2F2C41398 for ; Wed, 3 Jul 2019 11:07:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1EF452879E for ; Wed, 3 Jul 2019 11:07:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 13276287B5; Wed, 3 Jul 2019 11:07:36 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 80A4B2879E for ; Wed, 3 Jul 2019 11:07:35 +0000 (UTC) Received: from localhost ([::1]:34912 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hid6s-0007S4-Ql for patchwork-qemu-devel@patchwork.kernel.org; Wed, 03 Jul 2019 07:07:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:59961) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hid1E-0000mE-Og for qemu-devel@nongnu.org; Wed, 03 Jul 2019 07:01:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hid1D-0005EK-Bd for qemu-devel@nongnu.org; Wed, 03 Jul 2019 07:01:44 -0400 Received: from zero.eik.bme.hu ([2001:738:2001:2001::2001]:44208) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hid1C-00054V-RV for qemu-devel@nongnu.org; Wed, 03 Jul 2019 07:01:43 -0400 Received: from zero.eik.bme.hu (blah.eik.bme.hu [152.66.115.182]) by localhost (Postfix) with SMTP id 9E4787461AA; Wed, 3 Jul 2019 13:01:38 +0200 (CEST) Received: by zero.eik.bme.hu (Postfix, from userid 432) id 149AA7462AA; Wed, 3 Jul 2019 13:01:38 +0200 (CEST) Message-Id: <04b67ff483223d4722b0b044192558e7d17b36b5.1562151410.git.balaton@eik.bme.hu> In-Reply-To: References: From: BALATON Zoltan Date: Wed, 03 Jul 2019 12:56:50 +0200 MIME-Version: 1.0 To: qemu-devel@nongnu.org X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:738:2001:2001::2001 Subject: [Qemu-devel] [PATCH 1/3] ati-vga: Improve readability of ati_2d_blt function X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Move common parts before the switch to remove code duplication and improve readibility. Signed-off-by: BALATON Zoltan --- hw/display/ati_2d.c | 80 ++++++++++++++++++++++------------------------------- 1 file changed, 33 insertions(+), 47 deletions(-) diff --git a/hw/display/ati_2d.c b/hw/display/ati_2d.c index 2dbf53f039..c31142af6e 100644 --- a/hw/display/ati_2d.c +++ b/hw/display/ati_2d.c @@ -42,6 +42,8 @@ static int ati_bpp_from_datatype(ATIVGAState *s) } } +#define DEFAULT_CNTL (s->regs.dp_gui_master_cntl & GMC_DST_PITCH_OFFSET_CNTL) + void ati_2d_blt(ATIVGAState *s) { /* FIXME it is probably more complex than this and may need to be */ @@ -51,6 +53,22 @@ void ati_2d_blt(ATIVGAState *s) s->vga.vbe_start_addr, surface_data(ds), surface_stride(ds), surface_bits_per_pixel(ds), (s->regs.dp_mix & GMC_ROP3_MASK) >> 16); + int bpp = ati_bpp_from_datatype(s); + int dst_stride = DEFAULT_CNTL ? s->regs.dst_pitch : s->regs.default_pitch; + uint8_t *dst_bits = s->vga.vram_ptr + (DEFAULT_CNTL ? + s->regs.dst_offset : s->regs.default_offset); + + if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) { + dst_bits += s->regs.crtc_offset & 0x07ffffff; + dst_stride *= bpp; + } + uint8_t *end = s->vga.vram_ptr + s->vga.vram_size; + if (dst_bits >= end || + dst_bits + s->regs.dst_x + (s->regs.dst_y + s->regs.dst_height) * + dst_stride >= end) { + qemu_log_mask(LOG_UNIMP, "blt outside vram not implemented\n"); + return; + } DPRINTF("%d %d %d, %d %d %d, (%d,%d) -> (%d,%d) %dx%d\n", s->regs.src_offset, s->regs.dst_offset, s->regs.default_offset, s->regs.src_pitch, s->regs.dst_pitch, s->regs.default_pitch, @@ -59,41 +77,28 @@ void ati_2d_blt(ATIVGAState *s) switch (s->regs.dp_mix & GMC_ROP3_MASK) { case ROP3_SRCCOPY: { - uint8_t *src_bits, *dst_bits, *end; - int src_stride, dst_stride, bpp = ati_bpp_from_datatype(s); - src_bits = s->vga.vram_ptr + - (s->regs.dp_gui_master_cntl & GMC_SRC_PITCH_OFFSET_CNTL ? - s->regs.src_offset : s->regs.default_offset); - dst_bits = s->vga.vram_ptr + - (s->regs.dp_gui_master_cntl & GMC_DST_PITCH_OFFSET_CNTL ? - s->regs.dst_offset : s->regs.default_offset); - src_stride = (s->regs.dp_gui_master_cntl & GMC_SRC_PITCH_OFFSET_CNTL ? - s->regs.src_pitch : s->regs.default_pitch); - dst_stride = (s->regs.dp_gui_master_cntl & GMC_DST_PITCH_OFFSET_CNTL ? - s->regs.dst_pitch : s->regs.default_pitch); + int src_stride = DEFAULT_CNTL ? + s->regs.src_pitch : s->regs.default_pitch; + uint8_t *src_bits = s->vga.vram_ptr + (DEFAULT_CNTL ? + s->regs.src_offset : s->regs.default_offset); if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) { src_bits += s->regs.crtc_offset & 0x07ffffff; - dst_bits += s->regs.crtc_offset & 0x07ffffff; src_stride *= bpp; - dst_stride *= bpp; } + if (src_bits >= end || + src_bits + s->regs.src_x + (s->regs.src_y + s->regs.dst_height) * + src_stride >= end) { + qemu_log_mask(LOG_UNIMP, "blt outside vram not implemented\n"); + return; + } + src_stride /= sizeof(uint32_t); dst_stride /= sizeof(uint32_t); - DPRINTF("pixman_blt(%p, %p, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)\n", src_bits, dst_bits, src_stride, dst_stride, bpp, bpp, s->regs.src_x, s->regs.src_y, s->regs.dst_x, s->regs.dst_y, s->regs.dst_width, s->regs.dst_height); - end = s->vga.vram_ptr + s->vga.vram_size; - if (src_bits >= end || dst_bits >= end || - src_bits + s->regs.src_x + (s->regs.src_y + s->regs.dst_height) * - src_stride * sizeof(uint32_t) >= end || - dst_bits + s->regs.dst_x + (s->regs.dst_y + s->regs.dst_height) * - dst_stride * sizeof(uint32_t) >= end) { - qemu_log_mask(LOG_UNIMP, "blt outside vram not implemented\n"); - return; - } pixman_blt((uint32_t *)src_bits, (uint32_t *)dst_bits, src_stride, dst_stride, bpp, bpp, s->regs.src_x, s->regs.src_y, @@ -115,20 +120,7 @@ void ati_2d_blt(ATIVGAState *s) case ROP3_BLACKNESS: case ROP3_WHITENESS: { - uint8_t *dst_bits, *end; - int dst_stride, bpp = ati_bpp_from_datatype(s); uint32_t filler = 0; - dst_bits = s->vga.vram_ptr + - (s->regs.dp_gui_master_cntl & GMC_DST_PITCH_OFFSET_CNTL ? - s->regs.dst_offset : s->regs.default_offset); - dst_stride = (s->regs.dp_gui_master_cntl & GMC_DST_PITCH_OFFSET_CNTL ? - s->regs.dst_pitch : s->regs.default_pitch); - - if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) { - dst_bits += s->regs.crtc_offset & 0x07ffffff; - dst_stride *= bpp; - } - dst_stride /= sizeof(uint32_t); switch (s->regs.dp_mix & GMC_ROP3_MASK) { case ROP3_PATCOPY: @@ -144,22 +136,16 @@ void ati_2d_blt(ATIVGAState *s) break; } + dst_stride /= sizeof(uint32_t); DPRINTF("pixman_fill(%p, %d, %d, %d, %d, %d, %d, %x)\n", dst_bits, dst_stride, bpp, s->regs.dst_x, s->regs.dst_y, s->regs.dst_width, s->regs.dst_height, filler); - end = s->vga.vram_ptr + s->vga.vram_size; - if (dst_bits >= end || - dst_bits + s->regs.dst_x + (s->regs.dst_y + s->regs.dst_height) * - dst_stride * sizeof(uint32_t) >= end) { - qemu_log_mask(LOG_UNIMP, "blt outside vram not implemented\n"); - return; - } pixman_fill((uint32_t *)dst_bits, dst_stride, bpp, - s->regs.dst_x, s->regs.dst_y, - s->regs.dst_width, s->regs.dst_height, - filler); + s->regs.dst_x, s->regs.dst_y, + s->regs.dst_width, s->regs.dst_height, + filler); if (dst_bits >= s->vga.vram_ptr + s->vga.vbe_start_addr && dst_bits < s->vga.vram_ptr + s->vga.vbe_start_addr + s->vga.vbe_regs[VBE_DISPI_INDEX_YRES] * s->vga.vbe_line_offset) { From patchwork Wed Jul 3 10:56:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: BALATON Zoltan X-Patchwork-Id: 11029357 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 125A51398 for ; Wed, 3 Jul 2019 11:09:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 017C62879E for ; Wed, 3 Jul 2019 11:09:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E80EE287B5; Wed, 3 Jul 2019 11:09:02 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8CF8D2879E for ; Wed, 3 Jul 2019 11:09:02 +0000 (UTC) Received: from localhost ([::1]:34930 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hid8H-0001AL-DQ for patchwork-qemu-devel@patchwork.kernel.org; Wed, 03 Jul 2019 07:09:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:59958) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hid1E-0000le-Gq for qemu-devel@nongnu.org; Wed, 03 Jul 2019 07:01:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hid1D-0005EF-As for qemu-devel@nongnu.org; Wed, 03 Jul 2019 07:01:44 -0400 Received: from zero.eik.bme.hu ([2001:738:2001:2001::2001]:44209) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hid1C-00054W-Ua for qemu-devel@nongnu.org; Wed, 03 Jul 2019 07:01:43 -0400 Received: from zero.eik.bme.hu (blah.eik.bme.hu [152.66.115.182]) by localhost (Postfix) with SMTP id 9FD097461AE; Wed, 3 Jul 2019 13:01:38 +0200 (CEST) Received: by zero.eik.bme.hu (Postfix, from userid 432) id 257447462BB; Wed, 3 Jul 2019 13:01:38 +0200 (CEST) Message-Id: <439aa85061f103446df7b42632d730971a372432.1562151410.git.balaton@eik.bme.hu> In-Reply-To: References: From: BALATON Zoltan Date: Wed, 03 Jul 2019 12:56:50 +0200 MIME-Version: 1.0 To: qemu-devel@nongnu.org X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:738:2001:2001::2001 Subject: [Qemu-devel] [PATCH 2/3] ati-vga: Fix frame buffer endianness for big endian target X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP The extended mode frame buffer should be little endian even when emulating big endian machine (such as PPC). This fixes color problems with MorphOS. Signed-off-by: BALATON Zoltan --- hw/display/ati.c | 1 + hw/display/ati_2d.c | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/hw/display/ati.c b/hw/display/ati.c index c1d9d1518f..590362ea56 100644 --- a/hw/display/ati.c +++ b/hw/display/ati.c @@ -89,6 +89,7 @@ static void ati_vga_switch_mode(ATIVGAState *s) DPRINTF("Switching to %dx%d %d %d @ %x\n", h, v, stride, bpp, offs); vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_ENABLE); vbe_ioport_write_data(&s->vga, 0, VBE_DISPI_DISABLED); + s->vga.big_endian_fb = false; /* reset VBE regs then set up mode */ s->vga.vbe_regs[VBE_DISPI_INDEX_XRES] = h; s->vga.vbe_regs[VBE_DISPI_INDEX_YRES] = v; diff --git a/hw/display/ati_2d.c b/hw/display/ati_2d.c index c31142af6e..b09753320a 100644 --- a/hw/display/ati_2d.c +++ b/hw/display/ati_2d.c @@ -124,15 +124,15 @@ void ati_2d_blt(ATIVGAState *s) switch (s->regs.dp_mix & GMC_ROP3_MASK) { case ROP3_PATCOPY: - filler = bswap32(s->regs.dp_brush_frgd_clr); + filler = s->regs.dp_brush_frgd_clr; break; case ROP3_BLACKNESS: - filler = rgb_to_pixel32(s->vga.palette[0], s->vga.palette[1], - s->vga.palette[2]) << 8 | 0xff; + filler = 0xffUL << 24 | rgb_to_pixel32(s->vga.palette[0], + s->vga.palette[1], s->vga.palette[2]); break; case ROP3_WHITENESS: - filler = rgb_to_pixel32(s->vga.palette[3], s->vga.palette[4], - s->vga.palette[5]) << 8 | 0xff; + filler = 0xffUL << 24 | rgb_to_pixel32(s->vga.palette[3], + s->vga.palette[4], s->vga.palette[5]); break; } From patchwork Wed Jul 3 10:56:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: BALATON Zoltan X-Patchwork-Id: 11029353 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9BF10112C for ; Wed, 3 Jul 2019 11:07:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8BA612879E for ; Wed, 3 Jul 2019 11:07:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7ECB2287B5; Wed, 3 Jul 2019 11:07:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 04E5C2879E for ; Wed, 3 Jul 2019 11:07:10 +0000 (UTC) Received: from localhost ([::1]:34908 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hid6T-0007ER-CX for patchwork-qemu-devel@patchwork.kernel.org; Wed, 03 Jul 2019 07:07:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:59974) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hid1F-0000oX-Uo for qemu-devel@nongnu.org; Wed, 03 Jul 2019 07:01:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hid1D-0005ER-BT for qemu-devel@nongnu.org; Wed, 03 Jul 2019 07:01:44 -0400 Received: from zero.eik.bme.hu ([2001:738:2001:2001::2001]:44210) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hid1C-00054c-RV for qemu-devel@nongnu.org; Wed, 03 Jul 2019 07:01:43 -0400 Received: from zero.eik.bme.hu (blah.eik.bme.hu [152.66.115.182]) by localhost (Postfix) with SMTP id A88937462B7; Wed, 3 Jul 2019 13:01:38 +0200 (CEST) Received: by zero.eik.bme.hu (Postfix, from userid 432) id 1FE477462B8; Wed, 3 Jul 2019 13:01:38 +0200 (CEST) Message-Id: <045b82d2c5167e0b2a23dfbf8a80085b0550e4ca.1562151410.git.balaton@eik.bme.hu> In-Reply-To: References: From: BALATON Zoltan Date: Wed, 03 Jul 2019 12:56:50 +0200 MIME-Version: 1.0 To: qemu-devel@nongnu.org X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:738:2001:2001::2001 Subject: [Qemu-devel] [PATCH 3/3] ati-vga: Fix reverse bit blts X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP The pixman library only supports blts with left to right, top to bottom order but the ATI VGA engine can also do different directions. Fix support for these via a temporary buffer for now. This fixes rendering issues related to such blts (such as moving windows) but some other glitches still remain. Signed-off-by: BALATON Zoltan --- hw/display/ati_2d.c | 53 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/hw/display/ati_2d.c b/hw/display/ati_2d.c index b09753320a..07a776c31d 100644 --- a/hw/display/ati_2d.c +++ b/hw/display/ati_2d.c @@ -53,6 +53,10 @@ void ati_2d_blt(ATIVGAState *s) s->vga.vbe_start_addr, surface_data(ds), surface_stride(ds), surface_bits_per_pixel(ds), (s->regs.dp_mix & GMC_ROP3_MASK) >> 16); + int dst_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ? + s->regs.dst_x : s->regs.dst_x + 1 - s->regs.dst_width); + int dst_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ? + s->regs.dst_y : s->regs.dst_y + 1 - s->regs.dst_height); int bpp = ati_bpp_from_datatype(s); int dst_stride = DEFAULT_CNTL ? s->regs.dst_pitch : s->regs.default_pitch; uint8_t *dst_bits = s->vga.vram_ptr + (DEFAULT_CNTL ? @@ -63,20 +67,25 @@ void ati_2d_blt(ATIVGAState *s) dst_stride *= bpp; } uint8_t *end = s->vga.vram_ptr + s->vga.vram_size; - if (dst_bits >= end || - dst_bits + s->regs.dst_x + (s->regs.dst_y + s->regs.dst_height) * + if (dst_bits >= end || dst_bits + dst_x + (dst_y + s->regs.dst_height) * dst_stride >= end) { qemu_log_mask(LOG_UNIMP, "blt outside vram not implemented\n"); return; } - DPRINTF("%d %d %d, %d %d %d, (%d,%d) -> (%d,%d) %dx%d\n", + DPRINTF("%d %d %d, %d %d %d, (%d,%d) -> (%d,%d) %dx%d %c %c\n", s->regs.src_offset, s->regs.dst_offset, s->regs.default_offset, s->regs.src_pitch, s->regs.dst_pitch, s->regs.default_pitch, s->regs.src_x, s->regs.src_y, s->regs.dst_x, s->regs.dst_y, - s->regs.dst_width, s->regs.dst_height); + s->regs.dst_width, s->regs.dst_height, + (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ? '>' : '<'), + (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ? 'v' : '^')); switch (s->regs.dp_mix & GMC_ROP3_MASK) { case ROP3_SRCCOPY: { + int src_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ? + s->regs.src_x : s->regs.src_x + 1 - s->regs.dst_width); + int src_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ? + s->regs.src_y : s->regs.src_y + 1 - s->regs.dst_height); int src_stride = DEFAULT_CNTL ? s->regs.src_pitch : s->regs.default_pitch; uint8_t *src_bits = s->vga.vram_ptr + (DEFAULT_CNTL ? @@ -86,9 +95,8 @@ void ati_2d_blt(ATIVGAState *s) src_bits += s->regs.crtc_offset & 0x07ffffff; src_stride *= bpp; } - if (src_bits >= end || - src_bits + s->regs.src_x + (s->regs.src_y + s->regs.dst_height) * - src_stride >= end) { + if (src_bits >= end || src_bits + src_x + + (src_y + s->regs.dst_height) * src_stride >= end) { qemu_log_mask(LOG_UNIMP, "blt outside vram not implemented\n"); return; } @@ -97,19 +105,34 @@ void ati_2d_blt(ATIVGAState *s) dst_stride /= sizeof(uint32_t); DPRINTF("pixman_blt(%p, %p, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)\n", src_bits, dst_bits, src_stride, dst_stride, bpp, bpp, - s->regs.src_x, s->regs.src_y, s->regs.dst_x, s->regs.dst_y, + src_x, src_y, dst_x, dst_y, s->regs.dst_width, s->regs.dst_height); - pixman_blt((uint32_t *)src_bits, (uint32_t *)dst_bits, - src_stride, dst_stride, bpp, bpp, - s->regs.src_x, s->regs.src_y, - s->regs.dst_x, s->regs.dst_y, - s->regs.dst_width, s->regs.dst_height); + if (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT && + s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM) { + pixman_blt((uint32_t *)src_bits, (uint32_t *)dst_bits, + src_stride, dst_stride, bpp, bpp, + src_x, src_y, dst_x, dst_y, + s->regs.dst_width, s->regs.dst_height); + } else { + /* FIXME: We only really need a temporary if src and dst overlap */ + uint32_t *tmp = g_malloc(src_stride * sizeof(uint32_t) * + s->regs.dst_height); + pixman_blt((uint32_t *)src_bits, tmp, + src_stride, src_stride, bpp, bpp, + src_x, src_y, 0, 0, + s->regs.dst_width, s->regs.dst_height); + pixman_blt(tmp, (uint32_t *)dst_bits, + src_stride, dst_stride, bpp, bpp, + 0, 0, dst_x, dst_y, + s->regs.dst_width, s->regs.dst_height); + g_free(tmp); + } if (dst_bits >= s->vga.vram_ptr + s->vga.vbe_start_addr && dst_bits < s->vga.vram_ptr + s->vga.vbe_start_addr + s->vga.vbe_regs[VBE_DISPI_INDEX_YRES] * s->vga.vbe_line_offset) { memory_region_set_dirty(&s->vga.vram, s->vga.vbe_start_addr + s->regs.dst_offset + - s->regs.dst_y * surface_stride(ds), + dst_y * surface_stride(ds), s->regs.dst_height * surface_stride(ds)); } s->regs.dst_x += s->regs.dst_width; @@ -151,7 +174,7 @@ void ati_2d_blt(ATIVGAState *s) s->vga.vbe_regs[VBE_DISPI_INDEX_YRES] * s->vga.vbe_line_offset) { memory_region_set_dirty(&s->vga.vram, s->vga.vbe_start_addr + s->regs.dst_offset + - s->regs.dst_y * surface_stride(ds), + dst_y * surface_stride(ds), s->regs.dst_height * surface_stride(ds)); } s->regs.dst_y += s->regs.dst_height;