[g3dvl] move z-coord generation for multiple render targets into vertex shader
[mesa.git] / src / mesa / drivers / dri / unichrome / via_fb.c
index b590e833b690401d5bb042697aa7a8ca9bce9c03..bebf0619d0b49d2f408c8e14cf21d0cb5068e311 100644 (file)
 #include "via_ioctl.h"
 #include "via_fb.h"
 #include "xf86drm.h"
+#include "main/imports.h"
+#include "main/simple_list.h"
 #include <sys/ioctl.h>
 
 GLboolean
-via_alloc_draw_buffer(viaContextPtr vmesa, viaBuffer *buf)
+via_alloc_draw_buffer(struct via_context *vmesa, struct via_renderbuffer *buf)
 {
    drm_via_mem_t mem;
    mem.context = vmesa->hHWContext;
    mem.size = buf->size;
-   mem.type = VIDEO;
+   mem.type = VIA_MEM_VIDEO;
+   mem.offset = 0;
+   mem.index = 0;
 
    if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &mem)) 
       return GL_FALSE;
@@ -49,7 +53,7 @@ via_alloc_draw_buffer(viaContextPtr vmesa, viaBuffer *buf)
 }
 
 void
-via_free_draw_buffer(viaContextPtr vmesa, viaBuffer *buf)
+via_free_draw_buffer(struct via_context *vmesa, struct via_renderbuffer *buf)
 {
    drm_via_mem_t mem;
 
@@ -57,135 +61,183 @@ via_free_draw_buffer(viaContextPtr vmesa, viaBuffer *buf)
 
    mem.context = vmesa->hHWContext;
    mem.index = buf->index;
-   mem.type = VIDEO;
+   mem.type = VIA_MEM_VIDEO;
+   mem.offset = buf->offset;
+   mem.size = buf->size;
+
    ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &mem);
    buf->map = NULL;
 }
 
 
 GLboolean
-via_alloc_dma_buffer(viaContextPtr vmesa)
+via_alloc_dma_buffer(struct via_context *vmesa)
 {
    drm_via_dma_init_t init;
 
-   if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
    vmesa->dma = (GLubyte *) malloc(VIA_DMA_BUFSIZ);
     
    /*
     * Check whether AGP DMA has been initialized.
     */
+   memset(&init, 0, sizeof(init));
    init.func = VIA_DMA_INITIALIZED;
+
    vmesa->useAgp = 
      ( 0 == drmCommandWrite(vmesa->driFd, DRM_VIA_DMA_INIT, 
                             &init, sizeof(init)));
-   if (VIA_DEBUG) {
+   if (VIA_DEBUG & DEBUG_DMA) {
       if (vmesa->useAgp) 
          fprintf(stderr, "unichrome_dri.so: Using AGP.\n");
       else
          fprintf(stderr, "unichrome_dri.so: Using PCI.\n");
-   
-      fprintf(stderr, "%s - out\n", __FUNCTION__);
    }
       
    return ((vmesa->dma) ? GL_TRUE : GL_FALSE);
 }
 
 void
-via_free_dma_buffer(viaContextPtr vmesa)
+via_free_dma_buffer(struct via_context *vmesa)
 {
     if (!vmesa) return;
     free(vmesa->dma);
     vmesa->dma = 0;
 } 
 
-GLboolean
-via_alloc_texture(viaContextPtr vmesa, viaTextureObjectPtr 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)
 {
-    drm_via_mem_t fb;
-    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
-    fb.context = vmesa->hHWContext;
-    fb.size = t->texMem.size;
-    fb.type = VIDEO;
-    if (VIA_DEBUG) {
-       fprintf(stderr, "texture size = %d\n", fb.size);
-       fprintf(stderr, "texture type = %d\n", fb.type);
-    }
-    if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb)) {
-       fprintf(stderr, "via_alloc_texture fail\n");
-        return GL_FALSE;
-    }  
-    
-    t->texMem.offset = fb.offset;
-    t->texMem.index = fb.index;
-    if (VIA_DEBUG) fprintf(stderr, "texture index = %d\n", (GLuint)fb.index);
-    
-    t->bufAddr = (unsigned char *)(fb.offset + (GLuint)vmesa->driScreen->pFB);
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
-    return GL_TRUE;
+   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;
+
+      fb.context = vmesa->hHWContext;
+      fb.size = t->size;
+      fb.type = t->memType;
+      fb.offset = 0;
+      fb.index = 0;
+
+      if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb) != 0 || 
+         fb.index == 0) 
+        goto cleanup;
+
+      if (0)
+        fprintf(stderr, "offset %lx index %lx\n", fb.offset, fb.index);
+
+      t->offset = fb.offset;
+      t->index = fb.index;
+      
+      if (t->memType == VIA_MEM_AGP) {
+        t->bufAddr = (GLubyte *)((unsigned long)vmesa->viaScreen->agpLinearStart +
+                                 fb.offset);   
+        t->texBase = vmesa->agpBase + fb.offset;
+      }
+      else {
+        t->bufAddr = (GLubyte *)((unsigned long)vmesa->driScreen->pFB + fb.offset);
+        t->texBase = fb.offset;
+      }
+
+      vmesa->total_alloc[t->memType] += t->size;
+      return t;
+   }
+   else if (t->memType == VIA_MEM_SYSTEM) {
+      
+      t->bufAddr = malloc(t->size);      
+      if (!t->bufAddr)
+        goto cleanup;
+
+      vmesa->total_alloc[t->memType] += t->size;
+      return t;
+   }
+
+ cleanup:
+   if (t) {
+      remove_from_list(t);
+      FREE(t);
+   }
+
+   return NULL;
 }
-/*=* John Sheng [2003.5.31]  agp tex *=*/
-GLboolean
-via_alloc_texture_agp(viaContextPtr vmesa, viaTextureObjectPtr t)
+
+
+static void
+via_do_free_texture(struct via_context *vmesa, struct via_tex_buffer *t)
 {
-    drm_via_mem_t fb;
-    if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
-    fb.context = vmesa->hHWContext;
-    fb.size = t->texMem.size;
-    fb.type = AGP;
-    if (VIA_DEBUG) {
-       fprintf(stderr, "texture_agp size = %d\n", fb.size);
-       fprintf(stderr, "texture type = %d\n", fb.type);
-    }
-    if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb)) {
-       fprintf(stderr, "via_alloc_texture_agp fail\n");
-        return GL_FALSE;
-    }  
-    
-    t->texMem.offset = fb.offset;
-    t->texMem.index = fb.index;
-    if (VIA_DEBUG) fprintf(stderr, "texture agp index = %d\n", (GLuint)fb.index);
-    
-    t->bufAddr = (unsigned char *)((GLuint)vmesa->viaScreen->agpLinearStart + fb.offset);      
-    /*=* John Sheng [2003.5.31]  agp tex *=*/
-    t->inAGP = GL_TRUE;
-    if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);    
-    return GL_TRUE;
+   drm_via_mem_t fb;
+
+   remove_from_list( t );
+
+   vmesa->total_alloc[t->memType] -= t->size;
+
+   fb.context = vmesa->hHWContext;
+   fb.index = t->index;
+   fb.offset = t->offset;
+   fb.type = t->memType;
+   fb.size = t->size;
+
+   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 (!VIA_GEQ_WRAP(s->lastUsed, vmesa->lastBreadcrumbRead)) {
+        if (VIA_DEBUG & DEBUG_TEXTURE)
+           fprintf(stderr, "%s: release tex sz %d lastUsed %x\n",
+                   __FUNCTION__, s->size, s->lastUsed); 
+        via_do_free_texture(vmesa, s);
+      }
+   }
 }
+      
+
 
 void
-via_free_texture(viaContextPtr vmesa, viaTextureObjectPtr t)
+via_free_texture(struct via_context *vmesa, struct via_tex_buffer *t)
 {
-    drm_via_mem_t fb;
-    if (VIA_DEBUG) {
-       fprintf(stderr, "via_free_texture: index = %d\n",
-            t->texMem.index);
-       fprintf(stderr, "via_free_texture: size = %d\n",
-            t->texMem.size);
-    }
-    if (!vmesa) {
-       fprintf(stderr, "!mesa\n");
-       return;
-    }
-    
-    fb.context = vmesa->hHWContext;
-    fb.index = t->texMem.index;
-    
-    /*=* John Sheng [2003.5.31]  agp tex *=*/
-    if(t->inAGP)
-       fb.type = AGP;
-    else
-        fb.type = VIDEO;
-           
-    if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb)) {
-       if(vmesa->shareCtx) {
-           fb.context = ((viaContextPtr)((GLcontext *)(vmesa->shareCtx)->DriverCtx))->hHWContext;
-           if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb)) {
-               fprintf(stderr, "via_free_texture fail\n");
-           }
-       }
-       else
-           fprintf(stderr, "via_free_texture fail\n");
-    }
-
-    t->bufAddr = NULL;
+   if (!t) {
+      return;
+   }
+   else if (t->memType == VIA_MEM_SYSTEM) {
+      remove_from_list(t);
+      vmesa->total_alloc[t->memType] -= t->size;
+      free(t->bufAddr);
+      free(t);
+   }
+   else if (t->index && viaCheckBreadcrumb(vmesa, t->lastUsed)) {
+      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 );
+   }
 }