gallium: add PIPE_SHADER_CAP_GLSL_16BIT_TEMPS for LowerPrecisionTemporaries
[mesa.git] / src / gallium / drivers / svga / svga_resource_texture.c
index bfedbee7a488af813af190ed1d50903119f5f820..137d15bcb4fd928f37b017fd858b8ff34203cf2c 100644 (file)
@@ -29,7 +29,7 @@
 #include "pipe/p_state.h"
 #include "pipe/p_defines.h"
 #include "os/os_thread.h"
-#include "util/u_format.h"
+#include "util/format/u_format.h"
 #include "util/u_inlines.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
@@ -58,7 +58,6 @@ svga_transfer_dma_band(struct svga_context *svga,
 {
    struct svga_texture *texture = svga_texture(st->base.resource);
    SVGA3dCopyBox box;
-   enum pipe_error ret;
 
    assert(!st->use_direct_map);
 
@@ -87,12 +86,7 @@ svga_transfer_dma_band(struct svga_context *svga,
             (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, flags);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags);
-      assert(ret == PIPE_OK);
-   }
+   SVGA_RETRY(svga, SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags));
 }
 
 
@@ -202,7 +196,7 @@ svga_transfer_dma(struct svga_context *svga,
 
 
 
-static boolean
+static bool
 svga_texture_get_handle(struct pipe_screen *screen,
                         struct pipe_resource *texture,
                         struct winsys_handle *whandle)
@@ -274,40 +268,28 @@ need_tex_readback(struct svga_transfer *st)
 }
 
 
-static enum pipe_error
+static void
 readback_image_vgpu9(struct svga_context *svga,
                    struct svga_winsys_surface *surf,
                    unsigned slice,
                    unsigned level)
 {
-   enum pipe_error ret;
-
-   ret = SVGA3D_ReadbackGBImage(svga->swc, surf, slice, level);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = SVGA3D_ReadbackGBImage(svga->swc, surf, slice, level);
-   }
-   return ret;
+   SVGA_RETRY(svga, SVGA3D_ReadbackGBImage(svga->swc, surf, slice, level));
 }
 
 
-static enum pipe_error
+static void
 readback_image_vgpu10(struct svga_context *svga,
                     struct svga_winsys_surface *surf,
                     unsigned slice,
                     unsigned level,
                     unsigned numMipLevels)
 {
-   enum pipe_error ret;
    unsigned subResource;
 
    subResource = slice * numMipLevels + level;
-   ret = SVGA3D_vgpu10_ReadbackSubResource(svga->swc, surf, subResource);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = SVGA3D_vgpu10_ReadbackSubResource(svga->swc, surf, subResource);
-   }
-   return ret;
+   SVGA_RETRY(svga, SVGA3D_vgpu10_ReadbackSubResource(svga->swc, surf,
+                                                      subResource));
 }
 
 
@@ -397,25 +379,20 @@ svga_texture_transfer_map_direct(struct svga_context *svga,
    unsigned usage = st->base.usage;
 
    if (need_tex_readback(st)) {
-      enum pipe_error ret;
-
       svga_surfaces_flush(svga);
 
       if (!svga->swc->force_coherent || tex->imported) {
          for (i = 0; i < st->box.d; i++) {
             if (svga_have_vgpu10(svga)) {
-               ret = readback_image_vgpu10(svga, surf, st->slice + i, level,
-                                           tex->b.b.last_level + 1);
+               readback_image_vgpu10(svga, surf, st->slice + i, level,
+                                     tex->b.b.last_level + 1);
             } else {
-               ret = readback_image_vgpu9(svga, surf, st->slice + i, level);
+               readback_image_vgpu9(svga, surf, st->slice + i, level);
             }
          }
          svga->hud.num_readbacks++;
          SVGA_STATS_COUNT_INC(sws, SVGA_STATS_COUNT_TEXREADBACK);
 
-         assert(ret == PIPE_OK);
-         (void) ret;
-
          svga_context_flush(svga, NULL);
       }
       /*
@@ -457,18 +434,39 @@ svga_texture_transfer_map_direct(struct svga_context *svga,
    {
       SVGA3dSize baseLevelSize;
       uint8_t *map;
-      boolean retry;
+      boolean retry, rebind;
       unsigned offset, mip_width, mip_height;
+      struct svga_winsys_context *swc = svga->swc;
+
+      if (swc->force_coherent) {
+         usage |= PIPE_TRANSFER_PERSISTENT | PIPE_TRANSFER_COHERENT;
+      }
+
+      map = SVGA_TRY_MAP(svga->swc->surface_map
+                         (svga->swc, surf, usage, &retry, &rebind), retry);
 
-      map = svga->swc->surface_map(svga->swc, surf, usage, &retry);
       if (map == NULL && retry) {
          /*
           * At this point, the svga_surfaces_flush() should already have
           * called in svga_texture_get_transfer().
           */
          svga->hud.surface_write_flushes++;
+         svga_retry_enter(svga);
+         svga_context_flush(svga, NULL);
+         map = svga->swc->surface_map(svga->swc, surf, usage, &retry, &rebind);
+         svga_retry_exit(svga);
+      }
+
+      if (map && rebind) {
+         enum pipe_error ret;
+
+         ret = SVGA3D_BindGBSurface(swc, surf);
+         if (ret != PIPE_OK) {
+            svga_context_flush(svga, NULL);
+            ret = SVGA3D_BindGBSurface(swc, surf);
+            assert(ret == PIPE_OK);
+         }
          svga_context_flush(svga, NULL);
-         map = svga->swc->surface_map(svga->swc, surf, usage, &retry);
       }
 
       /*
@@ -531,7 +529,7 @@ svga_texture_transfer_map(struct pipe_context *pipe,
    struct svga_transfer *st;
    struct svga_winsys_surface *surf = tex->handle;
    boolean use_direct_map = svga_have_gb_objects(svga) &&
-                            !svga_have_gb_dma(svga);
+       (!svga_have_gb_dma(svga) || (usage & PIPE_TRANSFER_WRITE));
    void *map = NULL;
    int64_t begin = svga_get_time(svga);
 
@@ -598,9 +596,12 @@ svga_texture_transfer_map(struct pipe_context *pipe,
    pipe_resource_reference(&st->base.resource, texture);
 
    /* If this is the first time mapping to the surface in this
-    * command buffer, clear the dirty masks of this surface.
+    * command buffer and there is no pending primitives, clear
+    * the dirty masks of this surface.
     */
-   if (sws->surface_is_flushed(sws, surf)) {
+   if (sws->surface_is_flushed(sws, surf) &&
+       (svga_have_vgpu10(svga) ||
+        !svga_hwtnl_has_pending_prim(svga->hwtnl))) {
       svga_clear_texture_dirty(tex);
    }
 
@@ -688,46 +689,23 @@ svga_texture_surface_unmap(struct svga_context *svga,
 
    swc->surface_unmap(swc, surf, &rebind);
    if (rebind) {
-      enum pipe_error ret;
-      ret = SVGA3D_BindGBSurface(swc, surf);
-      if (ret != PIPE_OK) {
-         /* flush and retry */
-         svga_context_flush(svga, NULL);
-         ret = SVGA3D_BindGBSurface(swc, surf);
-         assert(ret == PIPE_OK);
-      }
-      if (swc->force_coherent) {
-         ret = SVGA3D_UpdateGBSurface(swc, surf);
-         if (ret != PIPE_OK) {
-            /* flush and retry */
-            svga_context_flush(svga, NULL);
-            ret = SVGA3D_UpdateGBSurface(swc, surf);
-            assert(ret == PIPE_OK);
-         }
-      }
+      SVGA_RETRY(svga, SVGA3D_BindGBSurface(swc, surf));
    }
 }
 
 
-static enum pipe_error
+static void
 update_image_vgpu9(struct svga_context *svga,
                    struct svga_winsys_surface *surf,
                    const SVGA3dBox *box,
                    unsigned slice,
                    unsigned level)
 {
-   enum pipe_error ret;
-
-   ret = SVGA3D_UpdateGBImage(svga->swc, surf, box, slice, level);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = SVGA3D_UpdateGBImage(svga->swc, surf, box, slice, level);
-   }
-   return ret;
+   SVGA_RETRY(svga, SVGA3D_UpdateGBImage(svga->swc, surf, box, slice, level));
 }
 
 
-static enum pipe_error
+static void
 update_image_vgpu10(struct svga_context *svga,
                     struct svga_winsys_surface *surf,
                     const SVGA3dBox *box,
@@ -735,17 +713,12 @@ update_image_vgpu10(struct svga_context *svga,
                     unsigned level,
                     unsigned numMipLevels)
 {
-   enum pipe_error ret;
    unsigned subResource;
 
    subResource = slice * numMipLevels + level;
 
-   ret = SVGA3D_vgpu10_UpdateSubResource(svga->swc, surf, box, subResource);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = SVGA3D_vgpu10_UpdateSubResource(svga->swc, surf, box, subResource);
-   }
-   return ret;
+   SVGA_RETRY(svga, SVGA3D_vgpu10_UpdateSubResource(svga->swc, surf, box,
+                                                    subResource));
 }
 
 
@@ -758,7 +731,7 @@ svga_texture_transfer_unmap_dma(struct svga_context *svga,
 {
    struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
 
-   if (st->hwbuf)
+   if (!st->swbuf)
       sws->buffer_unmap(sws, st->hwbuf);
 
    if (st->base.usage & PIPE_TRANSFER_WRITE) {
@@ -800,7 +773,6 @@ svga_texture_transfer_unmap_direct(struct svga_context *svga,
    /* Now send an update command to update the content in the backend. */
    if (st->base.usage & PIPE_TRANSFER_WRITE) {
       struct svga_winsys_surface *surf = tex->handle;
-      enum pipe_error ret;
 
       assert(svga_have_gb_objects(svga));
 
@@ -832,19 +804,16 @@ svga_texture_transfer_unmap_direct(struct svga_context *svga,
             unsigned i;
 
             for (i = 0; i < nlayers; i++) {
-               ret = update_image_vgpu10(svga, surf, &box,
-                                         st->slice + i, transfer->level,
-                                         tex->b.b.last_level + 1);
-               assert(ret == PIPE_OK);
+               update_image_vgpu10(svga, surf, &box,
+                                   st->slice + i, transfer->level,
+                                   tex->b.b.last_level + 1);
             }
          } else {
             assert(nlayers == 1);
-            ret = update_image_vgpu9(svga, surf, &box, st->slice,
-                                     transfer->level);
-            assert(ret == PIPE_OK);
+            update_image_vgpu9(svga, surf, &box, st->slice,
+                               transfer->level);
          }
       }
-      (void) ret;
    }
 }
 
@@ -929,7 +898,7 @@ svga_texture_create(struct pipe_screen *screen,
 
    /* Verify the number of mipmap levels isn't impossibly large.  For example,
     * if the base 2D image is 16x16, we can't have 8 mipmap levels.
-    * The state tracker should never ask us to create a resource with invalid
+    * the gallium frontend should never ask us to create a resource with invalid
     * parameters.
     */
    {
@@ -1111,7 +1080,7 @@ svga_texture_create(struct pipe_screen *screen,
     * and it always requests PIPE_BIND_RENDER_TARGET, therefore
     * passing the SVGA3D_SURFACE_HINT_RENDERTARGET here defeats its purpose.
     *
-    * However, this was changed since other state trackers
+    * However, this was changed since other gallium frontends
     * (XA for example) uses it accurately and certain device versions
     * relies on it in certain situations to render correctly.
     */
@@ -1279,7 +1248,7 @@ out_unref:
    return NULL;
 }
 
-boolean
+bool
 svga_texture_generate_mipmap(struct pipe_context *pipe,
                              struct pipe_resource *pt,
                              enum pipe_format format,
@@ -1292,25 +1261,24 @@ svga_texture_generate_mipmap(struct pipe_context *pipe,
    struct svga_pipe_sampler_view *sv;
    struct svga_context *svga = svga_context(pipe);
    struct svga_texture *tex = svga_texture(pt);
-   enum pipe_error ret;
 
    assert(svga_have_vgpu10(svga));
 
    /* Only support 2D texture for now */
    if (pt->target != PIPE_TEXTURE_2D)
-      return FALSE;
+      return false;
 
    /* Fallback to the mipmap generation utility for those formats that
     * do not support hw generate mipmap
     */
    if (!svga_format_support_gen_mips(format))
-      return FALSE;
+      return false;
 
    /* Make sure the texture surface was created with
     * SVGA3D_SURFACE_BIND_RENDER_TARGET
     */
    if (!tex->handle || !(tex->key.flags & SVGA3D_SURFACE_BIND_RENDER_TARGET))
-      return FALSE;
+      return false;
 
    templ.format = format;
    templ.u.tex.first_layer = first_layer;
@@ -1320,26 +1288,17 @@ svga_texture_generate_mipmap(struct pipe_context *pipe,
 
    psv = pipe->create_sampler_view(pipe, pt, &templ);
    if (psv == NULL)
-      return FALSE;
+      return false;
 
    sv = svga_pipe_sampler_view(psv);
-   ret = svga_validate_pipe_sampler_view(svga, sv);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = svga_validate_pipe_sampler_view(svga, sv);
-      assert(ret == PIPE_OK);
-   }
+   SVGA_RETRY(svga, svga_validate_pipe_sampler_view(svga, sv));
 
-   ret = SVGA3D_vgpu10_GenMips(svga->swc, sv->id, tex->handle);
-   if (ret != PIPE_OK) {
-      svga_context_flush(svga, NULL);
-      ret = SVGA3D_vgpu10_GenMips(svga->swc, sv->id, tex->handle);
-   }
+   SVGA_RETRY(svga, SVGA3D_vgpu10_GenMips(svga->swc, sv->id, tex->handle));
    pipe_sampler_view_reference(&psv, NULL);
 
    svga->hud.num_generate_mipmap++;
 
-   return TRUE;
+   return true;
 }
 
 
@@ -1502,7 +1461,6 @@ svga_texture_transfer_unmap_upload(struct svga_context *svga,
    struct svga_winsys_surface *dstsurf;
    struct pipe_resource *texture = st->base.resource;
    struct svga_texture *tex = svga_texture(texture);
-   enum pipe_error ret;
    unsigned subResource;
    unsigned numMipLevels;
    unsigned i, layer;
@@ -1526,22 +1484,12 @@ svga_texture_transfer_unmap_upload(struct svga_context *svga,
       /* send a transferFromBuffer command to update the host texture surface */
       assert((offset & 15) == 0);
 
-      ret = SVGA3D_vgpu10_TransferFromBuffer(svga->swc, srcsurf,
-                                             offset,
-                                             st->base.stride,
-                                             st->base.layer_stride,
-                                             dstsurf, subResource,
-                                             &st->upload.box);
-      if (ret != PIPE_OK) {
-         svga_context_flush(svga, NULL);
-         ret = SVGA3D_vgpu10_TransferFromBuffer(svga->swc, srcsurf,
-                                                offset,
-                                                st->base.stride,
-                                                st->base.layer_stride,
-                                                dstsurf, subResource,
-                                                &st->upload.box);
-         assert(ret == PIPE_OK);
-      }
+      SVGA_RETRY(svga, SVGA3D_vgpu10_TransferFromBuffer(svga->swc, srcsurf,
+                                                        offset,
+                                                        st->base.stride,
+                                                        st->base.layer_stride,
+                                                        dstsurf, subResource,
+                                                        &st->upload.box));
       offset += st->base.layer_stride;
 
       /* Set rendered-to flag */