svga: fix assorted whitespace issues, add copyright comment
[mesa.git] / src / gallium / drivers / svga / svga_resource_texture.c
index 994f30719ae443c44e1ace385b3d145b4a7b285f..d3748420c0af690cc0509f30a9802b9158758b14 100644 (file)
@@ -33,6 +33,7 @@
 #include "util/u_math.h"
 #include "util/u_memory.h"
 
+#include "svga_format.h"
 #include "svga_screen.h"
 #include "svga_context.h"
 #include "svga_resource_texture.h"
 #define SVGA3D_SURFACE_HINT_SCANOUT (1 << 9)
 
 
-static unsigned int
-svga_texture_is_referenced( struct pipe_context *pipe,
-                            struct pipe_resource *texture,
-                            unsigned level, int layer)
-{
-   struct svga_texture *tex = svga_texture(texture);
-   struct svga_screen *ss = svga_screen(pipe->screen);
-
-   /**
-    * The screen does not cache texture writes.
-    */
-
-   if (!tex->handle || ss->sws->surface_is_flushed(ss->sws, tex->handle))
-      return PIPE_UNREFERENCED;
-
-   /**
-    * sws->surface_is_flushed() does not distinguish between read references
-    * and write references. So assume a reference is both.
-    */
-
-   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
-}
-
-
-
-/*
- * Helper function and arrays
- */
-
-SVGA3dSurfaceFormat
-svga_translate_format(enum pipe_format format)
-{
-   switch(format) {
-   
-   case PIPE_FORMAT_B8G8R8A8_UNORM:
-      return SVGA3D_A8R8G8B8;
-   case PIPE_FORMAT_B8G8R8X8_UNORM:
-      return SVGA3D_X8R8G8B8;
-
-      /* Required for GL2.1:
-       */
-   case PIPE_FORMAT_B8G8R8A8_SRGB:
-      return SVGA3D_A8R8G8B8;
-
-   case PIPE_FORMAT_B5G6R5_UNORM:
-      return SVGA3D_R5G6B5;
-   case PIPE_FORMAT_B5G5R5A1_UNORM:
-      return SVGA3D_A1R5G5B5;
-   case PIPE_FORMAT_B4G4R4A4_UNORM:
-      return SVGA3D_A4R4G4B4;
-
-      
-   /* XXX: Doesn't seem to work properly.
-   case PIPE_FORMAT_Z32_UNORM:
-      return SVGA3D_Z_D32;
-    */
-   case PIPE_FORMAT_Z16_UNORM:
-      return SVGA3D_Z_D16;
-   case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
-      return SVGA3D_Z_D24S8;
-   case PIPE_FORMAT_X8Z24_UNORM:
-      return SVGA3D_Z_D24X8;
-
-   case PIPE_FORMAT_A8_UNORM:
-      return SVGA3D_ALPHA8;
-   case PIPE_FORMAT_L8_UNORM:
-      return SVGA3D_LUMINANCE8;
-
-   case PIPE_FORMAT_DXT1_RGB:
-   case PIPE_FORMAT_DXT1_RGBA:
-      return SVGA3D_DXT1;
-   case PIPE_FORMAT_DXT3_RGBA:
-      return SVGA3D_DXT3;
-   case PIPE_FORMAT_DXT5_RGBA:
-      return SVGA3D_DXT5;
-
-   default:
-      return SVGA3D_FORMAT_INVALID;
-   }
-}
-
-
-SVGA3dSurfaceFormat
-svga_translate_format_render(enum pipe_format format)
-{
-   switch(format) { 
-   case PIPE_FORMAT_B8G8R8A8_UNORM:
-   case PIPE_FORMAT_B8G8R8X8_UNORM:
-   case PIPE_FORMAT_B5G5R5A1_UNORM:
-   case PIPE_FORMAT_B4G4R4A4_UNORM:
-   case PIPE_FORMAT_B5G6R5_UNORM:
-   case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
-   case PIPE_FORMAT_X8Z24_UNORM:
-   case PIPE_FORMAT_Z32_UNORM:
-   case PIPE_FORMAT_Z16_UNORM:
-   case PIPE_FORMAT_L8_UNORM:
-      return svga_translate_format(format);
-
-   default:
-      return SVGA3D_FORMAT_INVALID;
-   }
-}
-
-
 static INLINE void
 svga_transfer_dma_band(struct svga_context *svga,
                        struct svga_transfer *st,
                        SVGA3dTransferType transfer,
-                       unsigned y, unsigned h, unsigned srcy)
+                       unsigned y, unsigned h, unsigned srcy,
+                       SVGA3dSurfaceDMAFlags flags)
 {
    struct svga_texture *texture = svga_texture(st->base.resource); 
    SVGA3dCopyBox box;
@@ -192,10 +90,10 @@ svga_transfer_dma_band(struct svga_context *svga,
                 util_format_get_blocksize(texture->b.b.format) * 8 /
                 (util_format_get_blockwidth(texture->b.b.format)*util_format_get_blockheight(texture->b.b.format)));
 
-   ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1);
+   ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags);
    if(ret != PIPE_OK) {
       svga_context_flush(svga, NULL);
-      ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1);
+      ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags);
       assert(ret == PIPE_OK);
    }
 }
@@ -204,7 +102,8 @@ svga_transfer_dma_band(struct svga_context *svga,
 static INLINE void
 svga_transfer_dma(struct svga_context *svga,
                   struct svga_transfer *st,
-                  SVGA3dTransferType transfer)
+                  SVGA3dTransferType transfer,
+                  SVGA3dSurfaceDMAFlags flags)
 {
    struct svga_texture *texture = svga_texture(st->base.resource); 
    struct svga_screen *screen = svga_screen(texture->b.b.screen);
@@ -223,7 +122,9 @@ svga_transfer_dma(struct svga_context *svga,
    if(!st->swbuf) {
       /* Do the DMA transfer in a single go */
 
-      svga_transfer_dma_band(svga, st, transfer, st->base.box.y, st->base.box.height, 0);
+      svga_transfer_dma_band(svga, st, transfer,
+                             st->base.box.y, st->base.box.height, 0,
+                             flags);
 
       if(transfer == SVGA3D_READ_HOST_VRAM) {
          svga_context_flush(svga, &fence);
@@ -252,24 +153,32 @@ svga_transfer_dma(struct svga_context *svga,
 
          sw = (uint8_t *)st->swbuf + offset;
 
-         if(transfer == SVGA3D_WRITE_HOST_VRAM) {
+         if (transfer == SVGA3D_WRITE_HOST_VRAM) {
+            unsigned usage = PIPE_TRANSFER_WRITE;
+
             /* Wait for the previous DMAs to complete */
             /* TODO: keep one DMA (at half the size) in the background */
-            if(y) {
-               svga_context_flush(svga, &fence);
-               sws->fence_finish(sws, fence, 0);
-               sws->fence_reference(sws, &fence, NULL);
+            if (y) {
+               svga_context_flush(svga, NULL);
+               usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
             }
 
-            hw = sws->buffer_map(sws, st->hwbuf, PIPE_TRANSFER_WRITE);
+            hw = sws->buffer_map(sws, st->hwbuf, usage);
             assert(hw);
-            if(hw) {
+            if (hw) {
                memcpy(hw, sw, length);
                sws->buffer_unmap(sws, st->hwbuf);
             }
          }
 
-         svga_transfer_dma_band(svga, st, transfer, y, h, srcy);
+         svga_transfer_dma_band(svga, st, transfer, y, h, srcy, flags);
+
+         /*
+          * Prevent the texture contents to be discarded on the next band
+          * upload.
+          */
+
+         flags.discard = FALSE;
 
          if(transfer == SVGA3D_READ_HOST_VRAM) {
             svga_context_flush(svga, &fence);
@@ -287,9 +196,6 @@ svga_transfer_dma(struct svga_context *svga,
 }
 
 
-
-
-
 static boolean 
 svga_texture_get_handle(struct pipe_screen *screen,
                                struct pipe_resource *texture,
@@ -327,11 +233,6 @@ svga_texture_destroy(struct pipe_screen *screen,
 }
 
 
-
-
-
-
-
 /* XXX: Still implementing this as if it was a screen function, but
  * can now modify it to queue transfers on the context.
  */
@@ -350,7 +251,7 @@ svga_texture_get_transfer(struct pipe_context *pipe,
    unsigned nblocksy = util_format_get_nblocksy(texture->format, box->height);
 
    /* We can't map texture storage directly */
-   if (usage & PIPE_TRANSFER_MAP_DIRECTLY)
+   if (usage & (PIPE_TRANSFER_MAP_DIRECTLY | PIPE_TRANSFER_MAP_PERMANENTLY))
       return NULL;
 
    assert(box->depth == 1);
@@ -398,8 +299,11 @@ svga_texture_get_transfer(struct pipe_context *pipe,
          goto no_swbuf;
    }
 
-   if (usage & PIPE_TRANSFER_READ)
-      svga_transfer_dma(svga, st, SVGA3D_READ_HOST_VRAM);
+   if (usage & PIPE_TRANSFER_READ) {
+      SVGA3dSurfaceDMAFlags flags;
+      memset(&flags, 0, sizeof flags);
+      svga_transfer_dma(svga, st, SVGA3D_READ_HOST_VRAM, flags);
+   }
 
    return &st->base;
 
@@ -458,7 +362,17 @@ svga_texture_transfer_destroy(struct pipe_context *pipe,
    struct svga_transfer *st = svga_transfer(transfer);
 
    if (st->base.usage & PIPE_TRANSFER_WRITE) {
-      svga_transfer_dma(svga, st, SVGA3D_WRITE_HOST_VRAM);
+      SVGA3dSurfaceDMAFlags flags;
+
+      memset(&flags, 0, sizeof flags);
+      if (transfer->usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) {
+         flags.discard = TRUE;
+      }
+      if (transfer->usage & PIPE_TRANSFER_UNSYNCHRONIZED) {
+         flags.unsynchronized = TRUE;
+      }
+
+      svga_transfer_dma(svga, st, SVGA3D_WRITE_HOST_VRAM, flags);
       ss->texture_timestamp++;
       tex->view_age[transfer->level] = ++(tex->age);
       if (transfer->resource->target == PIPE_TEXTURE_CUBE)
@@ -474,14 +388,10 @@ svga_texture_transfer_destroy(struct pipe_context *pipe,
 }
 
 
-
-
-
 struct u_resource_vtbl svga_texture_vtbl = 
 {
    svga_texture_get_handle,          /* get_handle */
    svga_texture_destroy,             /* resource_destroy */
-   svga_texture_is_referenced,       /* is_resource_referenced */
    svga_texture_get_transfer,        /* get_transfer */
    svga_texture_transfer_destroy,     /* transfer_destroy */
    svga_texture_transfer_map,        /* transfer_map */
@@ -491,8 +401,6 @@ struct u_resource_vtbl svga_texture_vtbl =
 };
 
 
-
-
 struct pipe_resource *
 svga_texture_create(struct pipe_screen *screen,
                     const struct pipe_resource *template)
@@ -539,11 +447,12 @@ svga_texture_create(struct pipe_screen *screen,
       tex->key.cachable = 0;
    }
 
-   if (template->bind & PIPE_BIND_SCANOUT) {
+   if (template->bind & (PIPE_BIND_SCANOUT |
+                         PIPE_BIND_CURSOR)) {
       tex->key.flags |= SVGA3D_SURFACE_HINT_SCANOUT;
       tex->key.cachable = 0;
    }
-   
+
    /* 
     * XXX: Never pass the SVGA3D_SURFACE_HINT_RENDERTARGET hint. Mesa cannot
     * know beforehand whether a texture will be used as a rendertarget or not
@@ -561,7 +470,7 @@ svga_texture_create(struct pipe_screen *screen,
    
    tex->key.numMipLevels = template->last_level + 1;
    
-   tex->key.format = svga_translate_format(template->format);
+   tex->key.format = svga_translate_format(svgascreen, template->format, template->bind);
    if(tex->key.format == SVGA3D_FORMAT_INVALID)
       goto error2;
 
@@ -582,8 +491,6 @@ error1:
 }
 
 
-
-
 struct pipe_resource *
 svga_texture_from_handle(struct pipe_screen *screen,
                         const struct pipe_resource *template,
@@ -608,14 +515,15 @@ svga_texture_from_handle(struct pipe_screen *screen,
    if (!srf)
       return NULL;
 
-   if (svga_translate_format(template->format) != format) {
-      unsigned f1 = svga_translate_format(template->format);
+   if (svga_translate_format(svga_screen(screen), template->format, template->bind) != format) {
+      unsigned f1 = svga_translate_format(svga_screen(screen), template->format, template->bind);
       unsigned f2 = format;
 
       /* It's okay for XRGB and ARGB or depth with/out stencil to get mixed up */
       if ( !( (f1 == SVGA3D_X8R8G8B8 && f2 == SVGA3D_A8R8G8B8) ||
               (f1 == SVGA3D_A8R8G8B8 && f2 == SVGA3D_X8R8G8B8) ||
-              (f1 == SVGA3D_Z_D24X8 && f2 == SVGA3D_Z_D24S8) ) ) {
+              (f1 == SVGA3D_Z_D24X8 && f2 == SVGA3D_Z_D24S8) ||
+              (f1 == SVGA3D_Z_DF24 && f2 == SVGA3D_Z_D24S8_INT) ) ) {
          debug_printf("%s wrong format %u != %u\n", __FUNCTION__, f1, f2);
          return NULL;
       }
@@ -645,4 +553,3 @@ svga_texture_from_handle(struct pipe_screen *screen,
 
    return &tex->b.b;
 }
-