summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Whitwell <keith@tungstengraphics.com>2005-02-07 16:56:02 +0000
committerKeith Whitwell <keith@tungstengraphics.com>2005-02-07 16:56:02 +0000
commit291082b4f8cc39cd7c455dbe28a2e271bdeac172 (patch)
tree441a6a1780e5a1a45ccf08172b39e1ee075193ab
parente780b1081f9a45b286abe3c059a0036a430c242f (diff)
Get breadcrumb/fence code working correctly.
Use this widely in place of polling the engine status register. Release textures according to this vs. their last usage. Get texture swap-in/swap-out and aging working correctly.
-rw-r--r--src/mesa/drivers/dri/unichrome/via_context.c5
-rw-r--r--src/mesa/drivers/dri/unichrome/via_context.h19
-rw-r--r--src/mesa/drivers/dri/unichrome/via_fb.c130
-rw-r--r--src/mesa/drivers/dri/unichrome/via_fb.h7
-rw-r--r--src/mesa/drivers/dri/unichrome/via_ioctl.c151
-rw-r--r--src/mesa/drivers/dri/unichrome/via_ioctl.h4
-rw-r--r--src/mesa/drivers/dri/unichrome/via_span.c4
-rw-r--r--src/mesa/drivers/dri/unichrome/via_tex.c215
-rw-r--r--src/mesa/drivers/dri/unichrome/via_tex.h3
9 files changed, 364 insertions, 174 deletions
diff --git a/src/mesa/drivers/dri/unichrome/via_context.c b/src/mesa/drivers/dri/unichrome/via_context.c
index 3308d371f2..6b0f73e753 100644
--- a/src/mesa/drivers/dri/unichrome/via_context.c
+++ b/src/mesa/drivers/dri/unichrome/via_context.c
@@ -289,6 +289,7 @@ static const struct dri_debug_control debug_control[] =
{ "sync", DEBUG_SYNC },
{ "sleep", DEBUG_SLEEP },
{ "pix", DEBUG_PIXEL },
+ { "2d", DEBUG_2D },
{ NULL, 0 }
};
@@ -405,6 +406,10 @@ viaCreateContext(const __GLcontextModes *mesaVis,
break;
}
+ make_empty_list(&vmesa->freed_tex_buffers);
+ make_empty_list(&vmesa->tex_image_list[VIA_MEM_VIDEO]);
+ make_empty_list(&vmesa->tex_image_list[VIA_MEM_AGP]);
+ make_empty_list(&vmesa->tex_image_list[VIA_MEM_SYSTEM]);
_mesa_init_driver_functions(&functions);
viaInitTextureFuncs(&functions);
diff --git a/src/mesa/drivers/dri/unichrome/via_context.h b/src/mesa/drivers/dri/unichrome/via_context.h
index 1447be9cd6..7c4f5626ad 100644
--- a/src/mesa/drivers/dri/unichrome/via_context.h
+++ b/src/mesa/drivers/dri/unichrome/via_context.h
@@ -101,6 +101,7 @@ struct via_buffer {
struct via_tex_buffer {
struct via_tex_buffer *next, *prev;
+ struct via_texture_image *image;
GLuint index;
GLuint offset;
GLuint size;
@@ -114,7 +115,7 @@ struct via_tex_buffer {
struct via_texture_image {
struct gl_texture_image image;
- struct via_tex_buffer texMem;
+ struct via_tex_buffer *texMem;
GLint pitchLog2;
};
@@ -137,10 +138,6 @@ struct via_texture_object {
};
-struct via_work {
- struct via_work *next;
- void (*do_work)( struct via_context * );
-};
struct via_context {
GLint refcount;
@@ -327,15 +324,20 @@ struct via_context {
GLuint pfCurrentOffset;
GLboolean allowPageFlip;
- struct via_work *work;
+ GLuint lastBreadcrumbRead;
+ GLuint lastBreadcrumbWrite;
+ GLuint lastSwap[2];
+ GLuint lastDma;
+
+ struct via_tex_buffer tex_image_list[VIA_MEM_SYSTEM+1];
+ struct via_tex_buffer freed_tex_buffers;
+
};
#define VIA_CONTEXT(ctx) ((struct via_context *)(ctx->DriverCtx))
-#define GET_DISPATCH_AGE(vmesa) vmesa->sarea->lastDispatch
-#define GET_ENQUEUE_AGE(vmesa) vmesa->sarea->lastEnqueue
/* Lock the hardware and validate our state.
@@ -372,6 +374,7 @@ extern GLuint VIA_DEBUG;
#define DEBUG_SYNC 0x400
#define DEBUG_SLEEP 0x800
#define DEBUG_PIXEL 0x1000
+#define DEBUG_2D 0x2000
extern void viaGetLock(struct via_context *vmesa, GLuint flags);
diff --git a/src/mesa/drivers/dri/unichrome/via_fb.c b/src/mesa/drivers/dri/unichrome/via_fb.c
index d0c7a82d3b..35a19cd12c 100644
--- a/src/mesa/drivers/dri/unichrome/via_fb.c
+++ b/src/mesa/drivers/dri/unichrome/via_fb.c
@@ -29,6 +29,7 @@
#include "via_fb.h"
#include "xf86drm.h"
#include "imports.h"
+#include "simple_list.h"
#include <sys/ioctl.h>
GLboolean
@@ -96,9 +97,23 @@ via_free_dma_buffer(struct via_context *vmesa)
vmesa->dma = 0;
}
-GLboolean
-via_alloc_texture(struct via_context *vmesa, struct via_tex_buffer *t)
+
+/* These functions now allocate and free the via_tex_buffer struct as well:
+ */
+struct via_tex_buffer *
+via_alloc_texture(struct via_context *vmesa,
+ GLuint size,
+ GLuint memType)
{
+ struct via_tex_buffer *t = CALLOC_STRUCT(via_tex_buffer);
+
+ if (!t)
+ goto cleanup;
+
+ t->size = size;
+ t->memType = memType;
+ insert_at_tail(&vmesa->tex_image_list[memType], t);
+
if (t->memType == VIA_MEM_AGP ||
t->memType == VIA_MEM_VIDEO) {
drm_via_mem_t fb;
@@ -108,15 +123,11 @@ via_alloc_texture(struct via_context *vmesa, struct via_tex_buffer *t)
fb.type = t->memType;
if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb) != 0 ||
- fb.index == 0) {
- if (VIA_DEBUG & (DEBUG_IOCTL|DEBUG_TEXTURE))
- fprintf(stderr, "via_alloc_texture fail\n");
- t->index = 0;
- return GL_FALSE;
- }
+ fb.index == 0)
+ goto cleanup;
if (0)
- fprintf(stderr, "offset %x index %x\n", fb.offset, fb.index);
+ fprintf(stderr, "offset %lx index %lx\n", fb.offset, fb.index);
t->offset = fb.offset;
t->index = fb.index;
@@ -130,44 +141,87 @@ via_alloc_texture(struct via_context *vmesa, struct via_tex_buffer *t)
t->texBase = fb.offset;
}
- return GL_TRUE;
+ return t;
}
else if (t->memType == VIA_MEM_SYSTEM) {
t->bufAddr = MESA_PBUFFER_ALLOC(t->size);
- t->texBase = 0;
- t->offset = 0;
- t->index = 0;
-
- return t->bufAddr != NULL;
+ if (!t->bufAddr)
+ goto cleanup;
+
+ return t;
}
- else
- return GL_FALSE;
+
+ cleanup:
+ if (t) {
+ remove_from_list(t);
+ FREE(t);
+ }
+
+ return NULL;
+}
+
+
+static void
+via_do_free_texture(struct via_context *vmesa, struct via_tex_buffer *t)
+{
+ drm_via_mem_t fb;
+
+ remove_from_list( t );
+
+ fb.context = vmesa->hHWContext;
+ fb.index = t->index;
+ fb.type = t->memType;
+
+ if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb)) {
+ fprintf(stderr, "via_free_texture fail\n");
+ }
+
+ FREE(t);
}
+/* Release textures which were potentially still being referenced by
+ * hardware at the time when they were originally freed.
+ */
+void
+via_release_pending_textures( struct via_context *vmesa )
+{
+ struct via_tex_buffer *s, *tmp;
+
+ foreach_s( s, tmp, &vmesa->freed_tex_buffers ) {
+ if (s->lastUsed <= vmesa->lastBreadcrumbRead) {
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "%s: release tex sz %d lastUsed %x\n",__FUNCTION__, s->size, s->lastUsed);
+ remove_from_list(s);
+ via_do_free_texture(vmesa, s);
+ }
+ }
+}
+
+
+
void
via_free_texture(struct via_context *vmesa, struct via_tex_buffer *t)
{
- if (t->memType == VIA_MEM_SYSTEM) {
- MESA_PBUFFER_FREE(t->bufAddr);
- t->bufAddr = 0;
- }
- else if (t->index) {
- drm_via_mem_t fb;
-
- fb.context = vmesa->hHWContext;
- fb.index = t->index;
- fb.type = t->memType;
-
- if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb)) {
- fb.context = vmesa->hHWContext;
- if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb)) {
- fprintf(stderr, "via_free_texture fail\n");
- }
- }
-
- t->bufAddr = NULL;
- t->index = 0;
- }
+ if (!t) {
+ return;
+ }
+ else if (t->memType == VIA_MEM_SYSTEM) {
+ remove_from_list(t);
+ MESA_PBUFFER_FREE(t->bufAddr);
+ FREE(t);
+ }
+ else if (t->index && viaCheckBreadcrumb(vmesa, t->lastUsed)) {
+ remove_from_list(t);
+ via_do_free_texture( vmesa, t );
+ }
+ else {
+ /* Close current breadcrumb so that we can free this eventually:
+ */
+ if (t->lastUsed == vmesa->lastBreadcrumbWrite)
+ viaEmitBreadcrumb(vmesa);
+
+ move_to_tail( &vmesa->freed_tex_buffers, t );
+ }
}
diff --git a/src/mesa/drivers/dri/unichrome/via_fb.h b/src/mesa/drivers/dri/unichrome/via_fb.h
index 3b3c0a1cac..7ee153f474 100644
--- a/src/mesa/drivers/dri/unichrome/via_fb.h
+++ b/src/mesa/drivers/dri/unichrome/via_fb.h
@@ -29,9 +29,14 @@
extern GLboolean via_alloc_draw_buffer(struct via_context *vmesa, struct via_buffer *buf);
extern GLboolean via_alloc_dma_buffer(struct via_context *vmesa);
-extern GLboolean via_alloc_texture(struct via_context *vmesa, struct via_tex_buffer *t);
+
+struct via_tex_buffer *
+via_alloc_texture(struct via_context *vmesa,
+ GLuint size,
+ GLuint memType);
extern void via_free_draw_buffer(struct via_context *vmesa, struct via_buffer *buf);
extern void via_free_dma_buffer(struct via_context *vmesa);
extern void via_free_texture(struct via_context *vmesa, struct via_tex_buffer *t);
+void via_release_pending_textures( struct via_context *vmesa );
#endif
diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.c b/src/mesa/drivers/dri/unichrome/via_ioctl.c
index 3f179bc31b..6e94c6a9b9 100644
--- a/src/mesa/drivers/dri/unichrome/via_ioctl.c
+++ b/src/mesa/drivers/dri/unichrome/via_ioctl.c
@@ -35,6 +35,7 @@
#include "via_tris.h"
#include "via_ioctl.h"
#include "via_state.h"
+#include "via_fb.h"
#include "via_3d_reg.h"
#include "vblank.h"
@@ -117,7 +118,7 @@ static void viaBlit(struct via_context *vmesa, GLuint bpp,
GLuint dwGEMode, srcX, dstX, cmd;
RING_VARS;
- if (VIA_DEBUG & DEBUG_IOCTL)
+ if (VIA_DEBUG & DEBUG_2D)
fprintf(stderr, "%s bpp %d src %x/%x dst %x/%x w %d h %d mode: %x color: 0x%08x mask 0x%08x\n",
__FUNCTION__, bpp, srcBase, srcPitch, dstBase, dstPitch, w,h, blitMode, color, nMask);
@@ -237,7 +238,7 @@ static void viaClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
mask &= ~DD_STENCIL_BIT;
}
else {
- if (VIA_DEBUG & DEBUG_IOCTL)
+ if (VIA_DEBUG & DEBUG_2D)
fprintf(stderr, "XXX: Clear stencil writemask %x -- need triangles (or a ROP?)\n",
ctx->Stencil.WriteMask[0]);
}
@@ -351,20 +352,20 @@ static void viaDoSwapBuffers(struct via_context *vmesa,
w, h,
VIA_BLIT_COPY, 0, 0);
}
+
+ viaFlushDmaLocked(vmesa, VIA_NO_CLIPRECTS); /* redundant */
}
-static void viaEmitBreadcrumb( struct via_context *vmesa, GLuint value )
+static void viaEmitBreadcrumbLocked( struct via_context *vmesa )
{
struct via_buffer *buffer = &vmesa->breadcrumb;
+ GLuint value = vmesa->lastBreadcrumbWrite + 1;
- if (VIA_DEBUG & DEBUG_IOCTL)
- fprintf(stderr, "emit %x offset %x pitch %x\n", value, buffer->offset, buffer->pitch);
+ if (VIA_DEBUG & DEBUG_IOCTL)
+ fprintf(stderr, "%s %d\n", __FUNCTION__, value);
- /* BUG: with this flush uncommented, the emit-breadcrumb blit
- * has no effect:
- */
-/* VIA_FLUSH_DMA(vmesa); */
+ assert(!vmesa->dmaLow);
viaBlit(vmesa,
buffer->bpp,
@@ -373,48 +374,75 @@ static void viaEmitBreadcrumb( struct via_context *vmesa, GLuint value )
1, 1,
VIA_BLIT_FILL, value, 0);
- VIA_FLUSH_DMA(vmesa);
+ viaFlushDmaLocked(vmesa, VIA_NO_CLIPRECTS); /* often redundant */
+ vmesa->lastBreadcrumbWrite = value;
}
-
-static GLboolean viaReceivedBreadcrumb( struct via_context *vmesa )
+void viaEmitBreadcrumb( struct via_context *vmesa )
{
- GLuint *buf = (GLuint *)vmesa->breadcrumb.map;
- GLuint value;
-
- if (vmesa->vblank_flags == VBLANK_FLAG_SYNC || vmesa->swap_count == 0)
- value = vmesa->swap_count;
- else
- value = vmesa->swap_count - 1;
-
- if (VIA_DEBUG & DEBUG_IOCTL)
- fprintf(stderr, "want %x got %x, addr %p\n", value, *buf, buf);
+ LOCK_HARDWARE(vmesa);
+ if (vmesa->dmaLow)
+ viaFlushDmaLocked(vmesa, 0);
- if (value <= *buf)
- return GL_TRUE;
+ viaEmitBreadcrumbLocked( vmesa );
+ UNLOCK_HARDWARE(vmesa);
+}
- if ((((GLuint)*vmesa->regEngineStatus) & 0xFFFEFFFF) == 0x00020000) {
- if (VIA_DEBUG & DEBUG_IOCTL)
- fprintf(stderr, "failsafe - engine is idle\n");
+static GLboolean viaCheckIdle( struct via_context *vmesa )
+{
+ if ((vmesa->regEngineStatus[0] & 0xFFFEFFFF) == 0x00020000) {
return GL_TRUE;
}
-
return GL_FALSE;
}
-static GLboolean viaCheckIdle( struct via_context *vmesa )
+
+GLboolean viaCheckBreadcrumb( struct via_context *vmesa, GLuint value )
+{
+ GLuint *buf = (GLuint *)vmesa->breadcrumb.map;
+ vmesa->lastBreadcrumbRead = *buf;
+
+ if (VIA_DEBUG & DEBUG_IOCTL)
+ fprintf(stderr, "%s %d <= %d: %d\n", __FUNCTION__, value, vmesa->lastBreadcrumbRead,
+ value <= vmesa->lastBreadcrumbRead);
+
+ return value <= vmesa->lastBreadcrumbRead;
+}
+
+static void viaWaitBreadcrumb( struct via_context *vmesa, GLuint value )
{
- return (vmesa->regEngineStatus[0] & 0xFFFEFFFF) == 0x00020000;
+ if (VIA_DEBUG & DEBUG_IOCTL)
+ fprintf(stderr, "%s %d\n", __FUNCTION__, value);
+
+ assert(value < vmesa->lastBreadcrumbWrite);
+
+ while (!viaCheckBreadcrumb( vmesa, value )) {
+ viaSwapOutWork( vmesa );
+ via_release_pending_textures( vmesa );
+ }
}
void viaWaitIdle( struct via_context *vmesa )
{
- while (!viaCheckIdle( vmesa )) {
- if (vmesa->work) {
- vmesa->work->do_work( vmesa );
- }
+ VIA_FLUSH_DMA(vmesa);
+
+ if (VIA_DEBUG & DEBUG_IOCTL)
+ fprintf(stderr, "%s lastDma %d lastBreadcrumbWrite %d\n",
+ __FUNCTION__, vmesa->lastDma, vmesa->lastBreadcrumbWrite);
+
+ /* Need to emit a new breadcrumb?
+ */
+ if (vmesa->lastDma == vmesa->lastBreadcrumbWrite) {
+ LOCK_HARDWARE(vmesa);
+ viaEmitBreadcrumbLocked( vmesa );
+ UNLOCK_HARDWARE(vmesa);
}
+
+ /* Need to wait?
+ */
+ if (vmesa->lastDma > vmesa->lastBreadcrumbRead)
+ viaWaitBreadcrumb( vmesa, vmesa->lastDma );
}
@@ -423,18 +451,32 @@ void viaWaitIdle( struct via_context *vmesa )
* except that WAIT_IDLE() will spin the CPU polling, while this is
* IRQ driven.
*/
-static void viaWaitIdleVBlank( const __DRIdrawablePrivate *dPriv, struct via_context *vmesa )
+static void viaWaitIdleVBlank( const __DRIdrawablePrivate *dPriv,
+ struct via_context *vmesa,
+ GLuint value )
{
GLboolean missed_target;
- viaEmitBreadcrumb(vmesa, vmesa->swap_count);
+ VIA_FLUSH_DMA(vmesa);
+
+ if (vmesa->thrashing)
+ viaSwapOutWork(vmesa);
+
+ if (!value)
+ return;
- while (!viaReceivedBreadcrumb(vmesa)) {
- if (vmesa->work) {
- vmesa->work->do_work( vmesa );
+ assert(value < vmesa->lastBreadcrumbWrite);
+
+ if (value <= vmesa->lastBreadcrumbRead)
+ return;
+
+ while (!viaCheckBreadcrumb(vmesa, value)) {
+ if (viaSwapOutWork(vmesa)) {
+ continue;
}
else if (vmesa->vblank_flags == VBLANK_FLAG_SYNC) {
- driWaitForVBlank( dPriv, & vmesa->vbl_seq, vmesa->vblank_flags, & missed_target );
+ driWaitForVBlank( dPriv, & vmesa->vbl_seq,
+ vmesa->vblank_flags, & missed_target );
if ( missed_target ) {
vmesa->swap_missed_count++;
vmesa->get_ust( &vmesa->swap_missed_ust );
@@ -443,7 +485,8 @@ static void viaWaitIdleVBlank( const __DRIdrawablePrivate *dPriv, struct via_con
}
vmesa->thrashing = 0; /* reset flag on swap */
- vmesa->swap_count++;
+ vmesa->swap_count++;
+ via_release_pending_textures( vmesa );
}
@@ -452,7 +495,7 @@ static void viaDoPageFlipLocked(struct via_context *vmesa, GLuint offset)
{
RING_VARS;
- if (VIA_DEBUG & DEBUG_IOCTL)
+ if (VIA_DEBUG & DEBUG_2D)
fprintf(stderr, "%s %x\n", __FUNCTION__, offset);
if (!vmesa->nDoneFirstFlip) {
@@ -473,13 +516,14 @@ static void viaDoPageFlipLocked(struct via_context *vmesa, GLuint offset)
((offset & 0xFF000000) >> 24) | 0x0100);
ADVANCE_RING();
- viaFlushDmaLocked(vmesa, VIA_NO_CLIPRECTS);
vmesa->pfCurrentOffset = vmesa->sarea->pfCurrentOffset = offset;
+
+ viaFlushDmaLocked(vmesa, VIA_NO_CLIPRECTS); /* often redundant */
}
void viaResetPageFlippingLocked(struct via_context *vmesa)
{
- if (VIA_DEBUG & DEBUG_IOCTL)
+ if (VIA_DEBUG & DEBUG_2D)
fprintf(stderr, "%s\n", __FUNCTION__);
viaDoPageFlipLocked( vmesa, 0 );
@@ -503,7 +547,8 @@ void viaCopyBuffer(const __DRIdrawablePrivate *dPriv)
{
struct via_context *vmesa = (struct via_context *)dPriv->driContextPriv->driverPrivate;
- viaWaitIdleVBlank(dPriv, vmesa);
+ VIA_FLUSH_DMA(vmesa);
+ viaWaitIdleVBlank(dPriv, vmesa, vmesa->lastSwap[1]);
LOCK_HARDWARE(vmesa);
@@ -512,14 +557,15 @@ void viaCopyBuffer(const __DRIdrawablePrivate *dPriv)
*/
if (dPriv->numClipRects && vmesa->sarea->pfCurrentOffset != 0) {
viaResetPageFlippingLocked(vmesa);
- UNLOCK_HARDWARE(vmesa);
return;
}
-
- viaDoSwapBuffers(vmesa, dPriv->pClipRects, dPriv->numClipRects);
- viaFlushDmaLocked(vmesa, VIA_NO_CLIPRECTS);
+ viaDoSwapBuffers(vmesa, dPriv->pClipRects, dPriv->numClipRects);
+ vmesa->lastSwap[1] = vmesa->lastSwap[0];
+ vmesa->lastSwap[0] = vmesa->lastBreadcrumbWrite;
+ viaEmitBreadcrumbLocked(vmesa);
UNLOCK_HARDWARE(vmesa);
+
vmesa->get_ust( &vmesa->swap_ust );
}
@@ -530,11 +576,15 @@ void viaPageFlip(const __DRIdrawablePrivate *dPriv)
struct via_buffer buffer_tmp;
VIA_FLUSH_DMA(vmesa);
+ viaWaitIdleVBlank(dPriv, vmesa, vmesa->lastSwap[0]);
+
LOCK_HARDWARE(vmesa);
viaDoPageFlipLocked(vmesa, vmesa->back.offset);
+ vmesa->lastSwap[1] = vmesa->lastSwap[0];
+ vmesa->lastSwap[0] = vmesa->lastBreadcrumbWrite;
+ viaEmitBreadcrumbLocked(vmesa);
UNLOCK_HARDWARE(vmesa);
- viaWaitIdleVBlank(dPriv, vmesa);
vmesa->get_ust( &vmesa->swap_ust );
@@ -742,6 +792,7 @@ void viaFlushDmaLocked(struct via_context *vmesa, GLuint flags)
__FUNCTION__, vmesa->dmaLow);
}
+ vmesa->lastDma = vmesa->lastBreadcrumbWrite;
if (VIA_DEBUG & DEBUG_DMA)
dump_dma( vmesa );
diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.h b/src/mesa/drivers/dri/unichrome/via_ioctl.h
index dfa20892d4..19df625b70 100644
--- a/src/mesa/drivers/dri/unichrome/via_ioctl.h
+++ b/src/mesa/drivers/dri/unichrome/via_ioctl.h
@@ -39,6 +39,10 @@ void viaCheckDma(struct via_context *vmesa, GLuint bytes);
void viaResetPageFlippingLocked(struct via_context *vmesa);
void viaWaitIdle(struct via_context *vmesa);
+GLboolean viaCheckBreadcrumb( struct via_context *vmesa, GLuint value );
+void viaEmitBreadcrumb( struct via_context *vmesa );
+
+
#define VIA_FINISH_PRIM(vmesa) do { \
if (vmesa->dmaLastPrim) \
viaFinishPrimitive( vmesa ); \
diff --git a/src/mesa/drivers/dri/unichrome/via_span.c b/src/mesa/drivers/dri/unichrome/via_span.c
index 6c33c6f03e..ba73cccb67 100644
--- a/src/mesa/drivers/dri/unichrome/via_span.c
+++ b/src/mesa/drivers/dri/unichrome/via_span.c
@@ -194,10 +194,8 @@ static void viaSetBuffer(GLcontext *ctx, GLframebuffer *colorBuffer,
void viaSpanRenderStart( GLcontext *ctx )
{
struct via_context *vmesa = VIA_CONTEXT(ctx);
- VIA_FINISH_PRIM(vmesa);
- LOCK_HARDWARE(vmesa);
- viaFlushDmaLocked(vmesa, 0);
viaWaitIdle(vmesa);
+ LOCK_HARDWARE(vmesa);
}
void viaSpanRenderFinish( GLcontext *ctx )
diff --git a/src/mesa/drivers/dri/unichrome/via_tex.c b/src/mesa/drivers/dri/unichrome/via_tex.c
index c8a8e9b92f..97766c43f8 100644
--- a/src/mesa/drivers/dri/unichrome/via_tex.c
+++ b/src/mesa/drivers/dri/unichrome/via_tex.c
@@ -33,6 +33,7 @@
#include "colortab.h"
#include "convolve.h"
#include "context.h"
+#include "simple_list.h"
#include "texcompress.h"
#include "texformat.h"
#include "texobj.h"
@@ -215,28 +216,25 @@ static const char *get_memtype_name( GLint memType )
}
-static GLboolean viaMoveTexObject( struct via_context *vmesa,
- struct via_texture_object *viaObj,
- GLint newMemType )
+static GLboolean viaMoveTexBuffers( struct via_context *vmesa,
+ struct via_tex_buffer **buffers,
+ GLuint nr,
+ GLint newMemType )
{
- struct via_texture_image **viaImage =
- (struct via_texture_image **)&viaObj->obj.Image[0][0];
-
- struct via_tex_buffer newTexBuf[VIA_MAX_TEXLEVELS];
+ struct via_tex_buffer *newTexBuf[VIA_MAX_TEXLEVELS];
GLint i;
if (VIA_DEBUG & DEBUG_TEXTURE)
- fprintf(stderr, "%s, from %s to %s\n",
+ fprintf(stderr, "%s to %s\n",
__FUNCTION__,
- get_memtype_name(viaObj->memType),
get_memtype_name(newMemType));
memset(newTexBuf, 0, sizeof(newTexBuf));
/* First do all the allocations (or fail):
*/
- for (i = viaObj->firstLevel; i <= viaObj->lastLevel; i++) {
- if (viaImage[i]->texMem.memType != newMemType) {
+ for (i = 0; i < nr; i++) {
+ if (buffers[i]->memType != newMemType) {
/* Don't allow uploads in a thrash state. Should try and
* catch this earlier.
@@ -244,9 +242,10 @@ static GLboolean viaMoveTexObject( struct via_context *vmesa,
if (vmesa->thrashing && newMemType != VIA_MEM_SYSTEM)
goto cleanup;
- newTexBuf[i].size = viaImage[i]->texMem.size;
- newTexBuf[i].memType = newMemType;
- if (!via_alloc_texture(vmesa, &newTexBuf[i]))
+ newTexBuf[i] = via_alloc_texture(vmesa,
+ buffers[i]->size,
+ newMemType);
+ if (!newTexBuf[i])
goto cleanup;
}
}
@@ -254,24 +253,24 @@ static GLboolean viaMoveTexObject( struct via_context *vmesa,
/* Now copy all the image data and free the old texture memory.
*/
- for (i = viaObj->firstLevel; i <= viaObj->lastLevel; i++) {
- if (viaImage[i]->texMem.memType != newMemType) {
- memcpy(newTexBuf[i].bufAddr,
- viaImage[i]->texMem.bufAddr,
- viaImage[i]->texMem.size);
-
- via_free_texture(vmesa, &viaImage[i]->texMem);
- viaImage[i]->texMem = newTexBuf[i];
- viaImage[i]->image.Data = viaImage[i]->texMem.bufAddr;
-
-/* move_to_head( &viaImage[i], &vmesa->image_list[newMemType] ); */
+ for (i = 0; i < nr; i++) {
+ if (newTexBuf[i]) {
+ memcpy(newTexBuf[i]->bufAddr,
+ buffers[i]->bufAddr,
+ buffers[i]->size);
+
+ newTexBuf[i]->image = buffers[i]->image;
+ newTexBuf[i]->image->texMem = newTexBuf[i];
+ newTexBuf[i]->image->image.Data = newTexBuf[i]->bufAddr;
+ via_free_texture(vmesa, buffers[i]);
+ insert_at_head( newTexBuf[i],
+ &vmesa->tex_image_list[newMemType] );
}
}
if (VIA_DEBUG & DEBUG_TEXTURE)
fprintf(stderr, "%s - success\n", __FUNCTION__);
- viaObj->memType = newMemType;
return GL_TRUE;
cleanup:
@@ -280,9 +279,9 @@ static GLboolean viaMoveTexObject( struct via_context *vmesa,
if (VIA_DEBUG & DEBUG_TEXTURE)
fprintf(stderr, "%s - failed\n", __FUNCTION__);
- for (i = viaObj->firstLevel; i <= viaObj->lastLevel; i++) {
- if (newTexBuf[i].index) {
- via_free_texture(vmesa, &newTexBuf[i]);
+ for (i = 0; i < nr; i++) {
+ if (newTexBuf[i]) {
+ via_free_texture(vmesa, newTexBuf[i]);
}
}
@@ -290,16 +289,34 @@ static GLboolean viaMoveTexObject( struct via_context *vmesa,
}
+static GLboolean viaMoveTexObject( struct via_context *vmesa,
+ struct via_texture_object *viaObj,
+ GLint newMemType )
+{
+ struct via_texture_image **viaImage =
+ (struct via_texture_image **)&viaObj->obj.Image[0][0];
+ struct via_tex_buffer *buffers[VIA_MAX_TEXLEVELS];
+ GLuint i, nr = 0;
+
+ for (i = viaObj->firstLevel; i <= viaObj->lastLevel; i++)
+ buffers[nr++] = viaImage[i]->texMem;
+ if (viaMoveTexBuffers( vmesa, &buffers[0], nr, newMemType )) {
+ viaObj->memType = newMemType;
+ return GL_TRUE;
+ }
+
+ return GL_FALSE;
+}
+
+
+#if 0
static GLboolean viaSwapOutTexObject( struct via_context *vmesa,
struct via_texture_object *viaObj )
{
return viaMoveTexObject( vmesa, viaObj, VIA_MEM_SYSTEM );
}
-
-
-
-
+#endif
static GLboolean viaSwapInTexObject( struct via_context *vmesa,
@@ -308,33 +325,74 @@ static GLboolean viaSwapInTexObject( struct via_context *vmesa,
const struct via_texture_image *baseImage =
(struct via_texture_image *)viaObj->obj.Image[0][viaObj->obj.BaseLevel];
- if (baseImage->texMem.memType != VIA_MEM_SYSTEM)
- return viaMoveTexObject( vmesa, viaObj, baseImage->texMem.memType );
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "%s\n", __FUNCTION__);
+
+ if (baseImage->texMem->memType != VIA_MEM_SYSTEM)
+ return viaMoveTexObject( vmesa, viaObj, baseImage->texMem->memType );
return (viaMoveTexObject( vmesa, viaObj, VIA_MEM_AGP ) ||
viaMoveTexObject( vmesa, viaObj, VIA_MEM_VIDEO ));
}
-void viaSwapOutWork( struct via_context *vmesa,
- GLboolean (*checkIdle)( struct via_context * ))
-{
-/* for (i = VIA_MEM_VIDEO; i < VIA_MEM_AGP; i++) { */
-/* foreach_s( viaImage, ) */
-/* } */
-}
-
-/* Free any resources pending on values upto 'fence'
+/* Speculatively move texture images which haven't been used in a
+ * while back to system memory. Do at most one image per call.
+ *
+ * TODO: only do this when texture memory is low.
+ *
+ * TODO: use dma.
+ *
+ * TODO: keep the fb/agp version hanging around and use the local
+ * version as backing store, so re-upload might be avoided.
+ *
+ * TODO: do this properly in the kernel...
*/
-void viaTexRetireFence( struct via_context *vmesa,
- GLuint fence )
+GLboolean viaSwapOutWork( struct via_context *vmesa )
{
-/* foreach_s(viaImage, tmp, vmesa->deleted_tex_image_queue) { */
-
+ struct via_tex_buffer *s, *tmp;
+ GLuint done = 0;
+ GLuint heap, target;
+
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "%s\n", __FUNCTION__);
+
+ if (vmesa->thrashing)
+ target = 64*1024*1024;
+ else
+ target = 64*1024;
+ for (heap = VIA_MEM_VIDEO; heap <= VIA_MEM_AGP; heap++) {
+ foreach_s( s, tmp, &vmesa->tex_image_list[heap] ) {
+ if (s->lastUsed < vmesa->lastSwap[1]) {
+ struct via_texture_object *viaObj =
+ (struct via_texture_object *) s->image->image.TexObject;
+
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr,
+ "back copy tex sz %d, lastUsed %d lastSwap %d\n",
+ s->size, s->lastUsed, vmesa->lastSwap);
+
+ done += s->size;
+ viaMoveTexBuffers( vmesa, &s, 1, VIA_MEM_SYSTEM );
+ viaObj->memType = VIA_MEM_MIXED;
+ }
+ else {
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr,
+ "don't touch tex sz %d, lastUsed %d lastSwap %d\n",
+ s->size, s->lastUsed, vmesa->lastSwap);
+ }
+
+ if (done > target)
+ return GL_TRUE;
+ }
+ }
+ return done != 0;
}
+
/* Basically, just collect the image dimensions and addresses for each
* image and update the texture object state accordingly.
*/
@@ -428,6 +486,7 @@ static GLboolean viaSetTexImages(GLcontext *ctx,
if (viaObj->memType == VIA_MEM_MIXED ||
viaObj->memType == VIA_MEM_SYSTEM) {
+ fprintf(stderr, "swapin\n");
if (!viaSwapInTexObject(vmesa, viaObj)) {
if (VIA_DEBUG & DEBUG_TEXTURE)
if (!vmesa->thrashing)
@@ -451,16 +510,20 @@ static GLboolean viaSetTexImages(GLcontext *ctx,
h = viaImage->image.HeightLog2;
p = viaImage->pitchLog2;
- texBase = viaImage->texMem.texBase;
+ assert(viaImage->texMem->memType == viaObj->memType);
+
+ texBase = viaImage->texMem->texBase;
if (!texBase) {
if (VIA_DEBUG & DEBUG_TEXTURE)
- fprintf(stderr, "%s: no texBase[%d]\n", __FUNCTION__, i);
+ fprintf(stderr, "%s: no texBase[%d]\n", __FUNCTION__, i);
return GL_FALSE;
}
/* Image has to remain resident until the coming fence is retired.
*/
-/* viaImage->lastUse = vmesa->currentFence; */
+ move_to_head( viaImage->texMem,
+ &vmesa->tex_image_list[viaImage->texMem->memType] );
+ viaImage->texMem->lastUsed = vmesa->lastBreadcrumbWrite;
viaObj->regTexBaseAndPitch[i].baseL = (((HC_SubA_HTXnL0BasL + i) << 24) |
@@ -556,6 +619,11 @@ static void viaTexImage(GLcontext *ctx,
struct via_texture_image *viaImage = (struct via_texture_image *)texImage;
int heaps[3], nheaps, i;
+ if (!is_empty_list(&vmesa->freed_tex_buffers)) {
+ viaCheckBreadcrumb(vmesa, 0);
+ via_release_pending_textures(vmesa);
+ }
+
if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
_mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
&postConvHeight);
@@ -600,8 +668,6 @@ static void viaTexImage(GLcontext *ctx,
* TODO: make room in agp if this fails.
* TODO: use fb ram for textures as well.
*/
- viaImage->texMem.size = sizeInBytes;
- viaImage->texMem.memType = viaObj->memType;
switch (viaObj->memType) {
@@ -617,36 +683,44 @@ static void viaTexImage(GLcontext *ctx,
heaps[1] = VIA_MEM_SYSTEM;
nheaps = 2;
break;
- case VIA_MEM_SYSTEM:
case VIA_MEM_MIXED:
+/* for ( */
+/* break; */
+ case VIA_MEM_SYSTEM:
default:
- heaps[1] = VIA_MEM_SYSTEM;
+ heaps[0] = VIA_MEM_SYSTEM;
nheaps = 1;
break;
}
- for (i = 0; i < nheaps; i++) {
- viaImage->texMem.memType = heaps[i];
- if (via_alloc_texture(vmesa, &viaImage->texMem))
- break;
+ for (i = 0; i < nheaps && !viaImage->texMem; i++) {
+ if (VIA_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "try %s (obj %s)\n", get_memtype_name(heaps[i]),
+ get_memtype_name(viaObj->memType));
+ viaImage->texMem = via_alloc_texture(vmesa, sizeInBytes, heaps[i]);
}
- texImage->Data = viaImage->texMem.bufAddr;
- if (!texImage->Data) {
+ if (!viaImage->texMem) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
return;
}
+ if (viaImage->texMem->memType == VIA_MEM_SYSTEM)
+ fprintf(stderr, "upload to VIA_MEM_SYSTEM!\n");
+
+ viaImage->texMem->image = viaImage;
+ texImage->Data = viaImage->texMem->bufAddr;
+
if (viaObj->memType == VIA_MEM_UNKNOWN)
- viaObj->memType = viaImage->texMem.memType;
- else if (viaObj->memType != viaImage->texMem.memType)
+ viaObj->memType = viaImage->texMem->memType;
+ else if (viaObj->memType != viaImage->texMem->memType)
viaObj->memType = VIA_MEM_MIXED;
if (VIA_DEBUG & DEBUG_TEXTURE)
fprintf(stderr, "%s, obj %s, image : %s\n",
__FUNCTION__,
get_memtype_name(viaObj->memType),
- get_memtype_name(viaImage->texMem.memType));
+ get_memtype_name(viaImage->texMem->memType));
vmesa->clearTexCache = 1;
@@ -804,16 +878,9 @@ static void viaFreeTextureImageData( GLcontext *ctx,
struct via_context *vmesa = VIA_CONTEXT(ctx);
struct via_texture_image *image = (struct via_texture_image *)texImage;
- if (image->texMem.index) {
- /* Actually just doing a flush here isn't enough to ensure
- * synchronization - need to make sure that any outstanding
- * drawing with this texture has completed.
- */
- VIA_FLUSH_DMA(vmesa);
- via_free_texture(vmesa, &image->texMem);
- }
- else if (texImage->Data && !texImage->IsClientData) {
- MESA_PBUFFER_FREE( texImage->Data );
+ if (image->texMem) {
+ via_free_texture(vmesa, image->texMem);
+ image->texMem = NULL;
}
texImage->Data = NULL;
diff --git a/src/mesa/drivers/dri/unichrome/via_tex.h b/src/mesa/drivers/dri/unichrome/via_tex.h
index b46a764ef2..f6c024e438 100644
--- a/src/mesa/drivers/dri/unichrome/via_tex.h
+++ b/src/mesa/drivers/dri/unichrome/via_tex.h
@@ -28,7 +28,10 @@
#include "mtypes.h"
+struct via_context;
+
GLboolean viaUpdateTextureState(GLcontext *ctx);
void viaInitTextureFuncs(struct dd_function_table * functions);
+GLboolean viaSwapOutWork( struct via_context *vmesa );
#endif