summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--display/driver.c84
-rw-r--r--display/surface.c14
2 files changed, 89 insertions, 9 deletions
diff --git a/display/driver.c b/display/driver.c
index 54913b8..00dd7ec 100644
--- a/display/driver.c
+++ b/display/driver.c
@@ -937,7 +937,11 @@ VOID DrvDisableSurface(DHPDEV in_pdev)
DEBUG_PRINT((pdev, 1, "%s: 0x%lx\n", __FUNCTION__, pdev));
- DisableQXLPrimarySurface(pdev, 1 /* hide mouse */);
+ // Don't destroy the primary - it's destroyed by destroy_all_surfaces
+ // at AssertModeDisable. Also, msdn specifically mentions DrvDisableSurface
+ // should not touch the hardware, that should be done just via DrvAssertMode
+ // (http://msdn.microsoft.com/en-us/library/ff556200%28VS.85%29.aspx)
+ pdev->surf_enable = FALSE;
UnmapFB(pdev);
if (pdev->surf) {
@@ -951,15 +955,56 @@ VOID DrvDisableSurface(DHPDEV in_pdev)
pdev->mem_slots = NULL;
}
- DEBUG_PRINT((NULL, 1, "%s: 0x%lx exit\n", __FUNCTION__, pdev));
+ DEBUG_PRINT((pdev, 1, "%s: 0x%lx exit\n", __FUNCTION__, pdev));
}
-BOOL DrvAssertMode(DHPDEV in_pdev, BOOL enable)
+static BOOL AssertModeDisable(PDev *pdev)
{
- PDev* pdev = (PDev*)in_pdev;
+ DEBUG_PRINT((pdev, 3, "%s entry\n", __FUNCTION__));
+ /* flush command ring and update all surfaces */
+ async_io(pdev, ASYNCABLE_FLUSH_SURFACES, 0);
+ async_io(pdev, ASYNCABLE_DESTROY_ALL_SURFACES, 0);
+ /* move all surfaces from device to system memory */
+ if (!MoveAllSurfacesToRam(pdev)) {
+ return FALSE;
+ }
+ /* Free release ring contents */
+ ReleaseCacheDeviceMemoryResources(pdev);
+ EmptyReleaseRing(pdev);
+ /* Get the last free list onto the release ring */
+ sync_io(pdev, pdev->flush_release_port, 0);
+ DEBUG_PRINT((pdev, 4, "%s after FLUSH_RELEASE\n", __FUNCTION__));
+ /* And release that. mspace allocators should be clean after. */
+ EmptyReleaseRing(pdev);
+ RemoveVRamSlot(pdev);
+ DebugCountAliveSurfaces(pdev);
+ DEBUG_PRINT((pdev, 4, "%s: [%d,%d] [%d,%d] [%d,%d] %lx\n", __FUNCTION__,
+ pdev->cmd_ring->prod, pdev->cmd_ring->cons,
+ pdev->cursor_ring->prod, pdev->cursor_ring->cons,
+ pdev->release_ring->prod, pdev->release_ring->cons,
+ pdev->Res->free_outputs));
+ DEBUG_PRINT((pdev, 4, "%s exit\n", __FUNCTION__));
+ return TRUE;
+}
- DEBUG_PRINT((pdev, 1, "%s: 0x%lx %d\n", __FUNCTION__, pdev, enable));
+static void AssertModeEnable(PDev *pdev)
+{
+ InitResources(pdev);
+ InitDeviceMemoryResources(pdev);
+ DEBUG_PRINT((pdev, 3, "%s: [%d,%d] [%d,%d] [%d,%d] %lx\n", __FUNCTION__,
+ pdev->cmd_ring->prod, pdev->cmd_ring->cons,
+ pdev->cursor_ring->prod, pdev->cursor_ring->cons,
+ pdev->release_ring->prod, pdev->release_ring->cons,
+ pdev->Res->free_outputs));
+ EnableQXLPrimarySurface(pdev);
+ CreateVRamSlot(pdev);
+ DebugCountAliveSurfaces(pdev);
+ MoveAllSurfacesToVideoRam(pdev);
+ DebugCountAliveSurfaces(pdev);
+}
+BOOL DrvAssertModeOld(PDev *pdev, BOOL enable)
+{
if (enable) {
InitResources(pdev);
EnableQXLPrimarySurface(pdev);
@@ -972,6 +1017,35 @@ BOOL DrvAssertMode(DHPDEV in_pdev, BOOL enable)
return TRUE;
}
+BOOL DrvAssertMode(DHPDEV in_pdev, BOOL enable)
+{
+ PDev* pdev = (PDev*)in_pdev;
+ BOOL ret = TRUE;
+
+ DEBUG_PRINT((pdev, 1, "%s: 0x%lx %d\n", __FUNCTION__, pdev, enable));
+ if (pdev->pci_revision < QXL_REVISION_STABLE_V10) {
+ return DrvAssertModeOld(pdev, enable);
+ }
+ /* new implementation that works correctly only with newer devices
+ * that implement QXL_IO_FLUSH_RELEASE */
+ if (pdev->enabled == enable) {
+ DEBUG_PRINT((pdev, 1, "%s: called twice with same argument (%d)\n", __FUNCTION__,
+ enable));
+ return TRUE;
+ }
+ pdev->enabled = enable;
+ if (enable) {
+ AssertModeEnable(pdev);
+ } else {
+ ret = AssertModeDisable(pdev);
+ if (!ret) {
+ pdev->enabled = !enable;
+ }
+ }
+ DEBUG_PRINT((pdev, 1, "%s: 0x%lx exit %d\n", __FUNCTION__, pdev, enable));
+ return ret;
+}
+
ULONG DrvGetModes(HANDLE driver, ULONG dev_modes_size, DEVMODEW *dev_modes)
{
PVIDEO_MODE_INFORMATION video_modes;
diff --git a/display/surface.c b/display/surface.c
index 519d613..b40721d 100644
--- a/display/surface.c
+++ b/display/surface.c
@@ -136,11 +136,15 @@ static UINT8 *CreateSurfaceHelper(PDev *pdev, UINT32 surface_id,
}
static void SendSurfaceCreateCommand(PDev *pdev, UINT32 surface_id, SIZEL size,
- UINT32 surface_format, INT32 stride, QXLPHYSICAL phys_mem)
+ UINT32 surface_format, INT32 stride, QXLPHYSICAL phys_mem,
+ int keep_data)
{
QXLSurfaceCmd *surface;
surface = SurfaceCmd(pdev, QXL_SURFACE_CMD_CREATE, surface_id);
+ if (keep_data) {
+ surface->flags |= QXL_SURF_FLAG_KEEP_DATA;
+ }
surface->u.surface_create.format = surface_format;
surface->u.surface_create.width = size.cx;
surface->u.surface_create.height = size.cy;
@@ -185,7 +189,7 @@ HBITMAP CreateDeviceBitmap(PDev *pdev, SIZEL size, ULONG format, QXLPHYSICAL *ph
}
if (allocation_type != DEVICE_BITMAP_ALLOCATION_TYPE_SURF0) {
- SendSurfaceCreateCommand(pdev, surface_id, size, surface_format, -stride, *phys_mem);
+ SendSurfaceCreateCommand(pdev, surface_id, size, surface_format, -stride, *phys_mem, 0);
}
return hbitmap;
@@ -269,7 +273,7 @@ BOOL MoveSurfaceToVideoRam(PDev *pdev, UINT32 surface_id)
EngFreeMem(surface_info->copy);
surface_info->copy = NULL;
SendSurfaceCreateCommand(pdev, surface_id, surface_info->size, surface_format,
- -stride, phys_mem);
+ -stride, phys_mem, 1);
return TRUE;
}
@@ -356,7 +360,9 @@ BOOL MoveAllSurfacesToRam(PDev *pdev)
__FUNCTION__, surface_id));
phys_mem = SurfaceToPhysical(pdev, surface_info->draw_area.base_mem);
SendSurfaceCreateCommand(pdev, surface_id, surf_obj->sizlBitmap,
- surface_info->bitmap_format, -surf_obj->lDelta, phys_mem);
+ surface_info->bitmap_format, -surf_obj->lDelta, phys_mem,
+ /* the surface is still there, tell server not to erase */
+ 1);
return FALSE;
}
QXLDelSurface(pdev, surface_info->draw_area.base_mem, DEVICE_BITMAP_ALLOCATION_TYPE_VRAM);