From 95fa851769b2a3461fb710f6d035bc5b2bf164e0 Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Mon, 7 Mar 2005 12:19:49 +0000 Subject: Tracked down random lockups related to command DMA that occurred in Quake3 after ~5min: buffer aging was subtly broken. Part of this may have also affected vertex DMA buffer aging and client-side texture heap aging, though with less fatal consequences. Bumped minor version and driver date. --- shared-core/savage_bci.c | 25 ++++++++++++++++--------- shared-core/savage_drv.h | 7 ++++--- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/shared-core/savage_bci.c b/shared-core/savage_bci.c index 8c58873a..3bf865dd 100644 --- a/shared-core/savage_bci.c +++ b/shared-core/savage_bci.c @@ -303,10 +303,10 @@ static int savage_dma_init(drm_savage_private_t *dev_priv) return DRM_ERR(ENOMEM); for (i = 0; i < dev_priv->nr_dma_pages; ++i) { - dev_priv->dma_pages[i].age.event = 0; - dev_priv->dma_pages[i].age.wrap = 0; + SET_AGE(&dev_priv->dma_pages[i].age, 0, 0); dev_priv->dma_pages[i].used = 0; } + SET_AGE(&dev_priv->last_dma_age, 0, 0); dev_priv->first_dma_page = 0; dev_priv->current_dma_page = 0; @@ -324,6 +324,7 @@ void savage_dma_reset(drm_savage_private_t *dev_priv) SET_AGE(&dev_priv->dma_pages[i].age, event, wrap); dev_priv->dma_pages[i].used = 0; } + SET_AGE(&dev_priv->last_dma_age, event, wrap); dev_priv->first_dma_page = dev_priv->current_dma_page = 0; } @@ -345,8 +346,9 @@ void savage_dma_wait(drm_savage_private_t *dev_priv, unsigned int page) if (event > dev_priv->event_counter) wrap--; /* hardware hasn't passed the last wrap yet */ - if (dev_priv->dma_pages[page].age.wrap >= wrap && - dev_priv->dma_pages[page].age.event > event) { + if (dev_priv->dma_pages[page].age.wrap > wrap || + (dev_priv->dma_pages[page].age.wrap == wrap && + dev_priv->dma_pages[page].age.event > event)) { if (dev_priv->wait_evnt(dev_priv, dev_priv->dma_pages[page].age.event) < 0) @@ -379,9 +381,8 @@ uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv, unsigned int n) } else { dev_priv->dma_flush(dev_priv); nr_pages = (n + SAVAGE_DMA_PAGE_SIZE-1) / SAVAGE_DMA_PAGE_SIZE; - for (i = cur+1; i < dev_priv->nr_dma_pages; ++i) { - dev_priv->dma_pages[i].age = - dev_priv->dma_pages[cur].age; + for (i = cur; i < dev_priv->nr_dma_pages; ++i) { + dev_priv->dma_pages[i].age = dev_priv->last_dma_age; dev_priv->dma_pages[i].used = 0; } dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle; @@ -424,7 +425,9 @@ static void savage_dma_flush(drm_savage_private_t *dev_priv) /* pad to multiples of 8 entries (really needed? 2 should do it) */ pad = -dev_priv->dma_pages[cur].used & 7; - DRM_DEBUG("used=%d, pad=%u\n", dev_priv->dma_pages[cur].used, pad); + DRM_DEBUG("first=%u, cur=%u, cur->used=%u, pad=%u\n", + dev_priv->first_dma_page, cur, dev_priv->dma_pages[cur].used, + pad); if (pad) { uint32_t *dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle + @@ -461,11 +464,15 @@ static void savage_dma_flush(drm_savage_private_t *dev_priv) SET_AGE(&dev_priv->dma_pages[i].age, event, wrap); dev_priv->dma_pages[i].used = 0; } + SET_AGE(&dev_priv->last_dma_age, event, wrap); /* advance to next page */ if (i == dev_priv->nr_dma_pages) i = 0; dev_priv->first_dma_page = dev_priv->current_dma_page = i; + + DRM_DEBUG("first=cur=%u, cur->used=%u\n", i, + dev_priv->dma_pages[i].used); } static void savage_fake_dma_flush(drm_savage_private_t *dev_priv) @@ -953,7 +960,7 @@ int savage_bci_event_wait(DRM_IOCTL_ARGS) * - event counter wrapped since the event was emitted or * - the hardware has advanced up to or over the event to wait for. */ - if (event_w < hw_w || event_e <= hw_e ) + if (event_w < hw_w || (event_w == hw_w && event_e <= hw_e) ) return 0; else return dev_priv->wait_evnt(dev_priv, event_e); diff --git a/shared-core/savage_drv.h b/shared-core/savage_drv.h index ae37a48f..6475f604 100644 --- a/shared-core/savage_drv.h +++ b/shared-core/savage_drv.h @@ -30,11 +30,11 @@ #define DRIVER_NAME "savage" #define DRIVER_DESC "Savage3D/MX/IX, Savage4, SuperSavage, Twister, ProSavage[DDR]" -#define DRIVER_DATE "20050305" +#define DRIVER_DATE "20050307" #define DRIVER_MAJOR 2 #define DRIVER_MINOR 4 -#define DRIVER_PATCHLEVEL 0 +#define DRIVER_PATCHLEVEL 1 /* Interface history: * * 1.x The DRM driver from the VIA/S3 code drop, basically a dummy @@ -171,6 +171,7 @@ typedef struct drm_savage_private { /* Savage4 command DMA */ drm_savage_dma_page_t *dma_pages; unsigned int nr_dma_pages, first_dma_page, current_dma_page; + drm_savage_age_t last_dma_age; /* saved hw state for global/local check on S3D */ uint32_t hw_draw_ctrl, hw_zbuf_ctrl; @@ -576,6 +577,6 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv, } while(0) #define TEST_AGE( age, e, w ) \ - ( (age)->wrap < (w) || (age)->event <= (e) ) + ( (age)->wrap < (w) || ( (age)->wrap == (w) && (age)->event <= (e) ) ) #endif /* __SAVAGE_DRV_H__ */ -- cgit v1.2.3