From patchwork Tue Apr 16 09:39:18 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 236878 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id A965A2C00EB for ; Tue, 16 Apr 2013 19:40:27 +1000 (EST) Received: from localhost ([::1]:48787 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1US2NF-0001YY-76 for incoming@patchwork.ozlabs.org; Tue, 16 Apr 2013 05:40:25 -0400 Received: from eggs.gnu.org ([208.118.235.92]:47367) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1US2MZ-0001Rm-OH for qemu-devel@nongnu.org; Tue, 16 Apr 2013 05:39:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1US2MX-0006sw-9W for qemu-devel@nongnu.org; Tue, 16 Apr 2013 05:39:43 -0400 Received: from mx1.redhat.com ([209.132.183.28]:4766) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1US2MX-0006sb-0p for qemu-devel@nongnu.org; Tue, 16 Apr 2013 05:39:41 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r3G9de4U000747 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 16 Apr 2013 05:39:40 -0400 Received: from rincewind.home.kraxel.org (ovpn-116-37.ams2.redhat.com [10.36.116.37]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r3G9dcA5027173; Tue, 16 Apr 2013 05:39:39 -0400 Received: by rincewind.home.kraxel.org (Postfix, from userid 500) id 790DA40E92; Tue, 16 Apr 2013 11:39:38 +0200 (CEST) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Tue, 16 Apr 2013 11:39:18 +0200 Message-Id: <1366105178-26744-5-git-send-email-kraxel@redhat.com> In-Reply-To: <1366105178-26744-1-git-send-email-kraxel@redhat.com> References: <1366105178-26744-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Gerd Hoffmann Subject: [Qemu-devel] [PATCH 04/24] hw/vmware_vga.c: various vmware vga fixes. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Hardcode depth to 32 bpp. It effectively was that way before because that is the default surface depth, this just makes it explicit in the code. Rename depth to new_depth to make it consistent with the new_width + new_height names. In theory we can make new_depth changeable (i.e. allow the guest to fill in -- say -- 16 there). In practice the guests don't try, the X-Server refuses to start if you ask it to use 16bpp depth (via DefaultDepth in the Screen section). Always return the correct rmask+gmask+bmask values for the given new_depth. Fix mode setting to also verify at new_depth to make sure we have a correct DisplaySurface, even if the current video mode happes to be 16bpp (set by vgabios via bochs vbe interface). While being at it switch over to use qemu_create_displaysurface_from, so the surface is backed by guest-visible video memory and we save a memcpy. Signed-off-by: Gerd Hoffmann --- hw/display/vmware_vga.c | 57 +++++++++++++++++++++++++---------------------- trace-events | 1 + 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c index 20e3a28..05befe4 100644 --- a/hw/display/vmware_vga.c +++ b/hw/display/vmware_vga.c @@ -39,8 +39,6 @@ struct vmsvga_state_s { VGACommonState vga; int invalidated; - int depth; - int bypp; int enable; int config; struct { @@ -55,6 +53,7 @@ struct vmsvga_state_s { uint32_t *scratch; int new_width; int new_height; + int new_depth; uint32_t guest; uint32_t svgaid; int syncing; @@ -721,6 +720,7 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address) uint32_t caps; struct vmsvga_state_s *s = opaque; DisplaySurface *surface = qemu_console_surface(s->vga.con); + PixelFormat pf; uint32_t ret; switch (s->index) { @@ -733,11 +733,11 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address) break; case SVGA_REG_WIDTH: - ret = surface_width(surface); + ret = s->new_width ? s->new_width : surface_width(surface); break; case SVGA_REG_HEIGHT: - ret = surface_height(surface); + ret = s->new_height ? s->new_height : surface_height(surface); break; case SVGA_REG_MAX_WIDTH: @@ -749,11 +749,12 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address) break; case SVGA_REG_DEPTH: - ret = s->depth; + ret = (s->new_depth == 32) ? 24 : s->new_depth; break; case SVGA_REG_BITS_PER_PIXEL: - ret = (s->depth + 7) & ~7; + case SVGA_REG_HOST_BITS_PER_PIXEL: + ret = s->new_depth; break; case SVGA_REG_PSEUDOCOLOR: @@ -761,19 +762,26 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address) break; case SVGA_REG_RED_MASK: - ret = surface->pf.rmask; + pf = qemu_default_pixelformat(s->new_depth); + ret = pf.rmask; break; case SVGA_REG_GREEN_MASK: - ret = surface->pf.gmask; + pf = qemu_default_pixelformat(s->new_depth); + ret = pf.gmask; break; case SVGA_REG_BLUE_MASK: - ret = surface->pf.bmask; + pf = qemu_default_pixelformat(s->new_depth); + ret = pf.bmask; break; case SVGA_REG_BYTES_PER_LINE: - ret = s->bypp * s->new_width; + if (s->new_width) { + ret = (s->new_depth * s->new_width) / 8; + } else { + ret = surface_stride(surface); + } break; case SVGA_REG_FB_START: { @@ -852,10 +860,6 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address) ret = s->cursor.on; break; - case SVGA_REG_HOST_BITS_PER_PIXEL: - ret = (s->depth + 7) & ~7; - break; - case SVGA_REG_SCRATCH_SIZE: ret = s->scratch_size; break; @@ -936,9 +940,10 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value) break; case SVGA_REG_BITS_PER_PIXEL: - if (value != s->depth) { + if (value != 32) { printf("%s: Bad bits per pixel: %i bits\n", __func__, value); s->config = 0; + s->invalidated = 1; } break; @@ -1034,8 +1039,14 @@ static inline void vmsvga_check_size(struct vmsvga_state_s *s) DisplaySurface *surface = qemu_console_surface(s->vga.con); if (s->new_width != surface_width(surface) || - s->new_height != surface_height(surface)) { - qemu_console_resize(s->vga.con, s->new_width, s->new_height); + s->new_height != surface_height(surface) || + s->new_depth != surface_bits_per_pixel(surface)) { + int stride = (s->new_depth * s->new_width) / 8; + trace_vmware_setmode(s->new_width, s->new_height, s->new_depth); + surface = qemu_create_displaysurface_from(s->new_width, s->new_height, + s->new_depth, stride, + s->vga.vram_ptr, false); + dpy_gfx_replace_surface(s->vga.con, surface); s->invalidated = 1; } } @@ -1069,8 +1080,6 @@ static void vmsvga_update_display(void *opaque) } if (s->invalidated || dirty) { s->invalidated = 0; - memcpy(surface_data(surface), s->vga.vram_ptr, - surface_stride(surface) * surface_height(surface)); dpy_gfx_update(s->vga.con, 0, 0, surface_width(surface), surface_height(surface)); } @@ -1162,7 +1171,7 @@ static const VMStateDescription vmstate_vmware_vga_internal = { .minimum_version_id_old = 0, .post_load = vmsvga_post_load, .fields = (VMStateField[]) { - VMSTATE_INT32_EQUAL(depth, struct vmsvga_state_s), + VMSTATE_INT32_EQUAL(new_depth, struct vmsvga_state_s), VMSTATE_INT32(enable, struct vmsvga_state_s), VMSTATE_INT32(config, struct vmsvga_state_s), VMSTATE_INT32(cursor.id, struct vmsvga_state_s), @@ -1198,8 +1207,6 @@ static const VMStateDescription vmstate_vmware_vga = { static void vmsvga_init(struct vmsvga_state_s *s, MemoryRegion *address_space, MemoryRegion *io) { - DisplaySurface *surface; - s->scratch_size = SVGA_SCRATCH_SIZE; s->scratch = g_malloc(s->scratch_size * 4); @@ -1207,7 +1214,6 @@ static void vmsvga_init(struct vmsvga_state_s *s, vmsvga_invalidate_display, vmsvga_screen_dump, vmsvga_text_update, s); - surface = qemu_console_surface(s->vga.con); s->fifo_size = SVGA_FIFO_SIZE; memory_region_init_ram(&s->fifo_ram, "vmsvga.fifo", s->fifo_size); @@ -1217,10 +1223,7 @@ static void vmsvga_init(struct vmsvga_state_s *s, vga_common_init(&s->vga); vga_init(&s->vga, address_space, io, true); vmstate_register(NULL, 0, &vmstate_vga_common, &s->vga); - /* Save some values here in case they are changed later. - * This is suspicious and needs more though why it is needed. */ - s->depth = surface_bits_per_pixel(surface); - s->bypp = surface_bytes_per_pixel(surface); + s->new_depth = 32; } static uint64_t vmsvga_io_read(void *opaque, hwaddr addr, unsigned size) diff --git a/trace-events b/trace-events index 6c795dc..b4d69d6 100644 --- a/trace-events +++ b/trace-events @@ -976,6 +976,7 @@ vmware_palette_read(uint32_t index, uint32_t value) "index %d, value 0x%x" vmware_palette_write(uint32_t index, uint32_t value) "index %d, value 0x%x" vmware_scratch_read(uint32_t index, uint32_t value) "index %d, value 0x%x" vmware_scratch_write(uint32_t index, uint32_t value) "index %d, value 0x%x" +vmware_setmode(uint32_t w, uint32_t h, uint32_t bpp) "%dx%d @ %d bpp" # savevm.c