svga: fix ordering of mksstats counter strings
[mesa.git] / src / gallium / drivers / svga / svga_state_sampler.c
index c5d52bbfd149d2165e5477bae729e2cf2188c839..420a5667efb0fb929bd1b11fd4829831d4979191 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "pipe/p_defines.h"
 #include "util/u_bitmask.h"
+#include "util/u_format.h"
 #include "util/u_inlines.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
@@ -90,7 +91,7 @@ svga_check_sampler_view_resource_collision(struct svga_context *svga,
  * Create a DX ShaderResourceSamplerView for the given pipe_sampler_view,
  * if needed.
  */
-static enum pipe_error
+enum pipe_error
 svga_validate_pipe_sampler_view(struct svga_context *svga,
                                 struct svga_pipe_sampler_view *sv)
 {
@@ -103,8 +104,21 @@ svga_validate_pipe_sampler_view(struct svga_context *svga,
       SVGA3dSurfaceFormat format;
       SVGA3dResourceType resourceDim;
       SVGA3dShaderResourceViewDesc viewDesc;
+      enum pipe_format pformat = sv->base.format;
+
+      /* vgpu10 cannot create a BGRX view for a BGRA resource, so force it to
+       * create a BGRA view (and vice versa).
+       */
+      if (pformat == PIPE_FORMAT_B8G8R8X8_UNORM &&
+          sv->base.texture->format == PIPE_FORMAT_B8G8R8A8_UNORM) {
+         pformat = PIPE_FORMAT_B8G8R8A8_UNORM;
+      }
+      else if (pformat == PIPE_FORMAT_B8G8R8A8_UNORM &&
+          sv->base.texture->format == PIPE_FORMAT_B8G8R8X8_UNORM) {
+         pformat = PIPE_FORMAT_B8G8R8X8_UNORM;
+      }
 
-      format = svga_translate_format(ss, sv->base.format,
+      format = svga_translate_format(ss, pformat,
                                      PIPE_BIND_SAMPLER_VIEW);
       assert(format != SVGA3D_FORMAT_INVALID);
 
@@ -112,9 +126,10 @@ svga_validate_pipe_sampler_view(struct svga_context *svga,
       format = svga_sampler_format(format);
 
       if (texture->target == PIPE_BUFFER) {
-         viewDesc.buffer.firstElement = sv->base.u.buf.first_element;
-         viewDesc.buffer.numElements = (sv->base.u.buf.last_element -
-                                        sv->base.u.buf.first_element + 1);
+         unsigned elem_size = util_format_get_blocksize(sv->base.format);
+
+         viewDesc.buffer.firstElement = sv->base.u.buf.offset / elem_size;
+         viewDesc.buffer.numElements = sv->base.u.buf.size / elem_size;
       }
       else {
          viewDesc.tex.mostDetailedMip = sv->base.u.tex.first_level;
@@ -190,6 +205,7 @@ update_sampler_resources(struct svga_context *svga, unsigned dirty)
    for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) {
       SVGA3dShaderResourceViewId ids[PIPE_MAX_SAMPLERS];
       struct svga_winsys_surface *surfaces[PIPE_MAX_SAMPLERS];
+      struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
       unsigned count;
       unsigned nviews;
       unsigned i;
@@ -198,10 +214,9 @@ update_sampler_resources(struct svga_context *svga, unsigned dirty)
       for (i = 0; i < count; i++) {
          struct svga_pipe_sampler_view *sv =
             svga_pipe_sampler_view(svga->curr.sampler_views[shader][i]);
-         struct svga_winsys_surface *surface;
 
          if (sv) {
-            surface = svga_resource_handle(sv->base.texture);
+            surfaces[i] = svga_resource_handle(sv->base.texture);
 
             ret = svga_validate_pipe_sampler_view(svga, sv);
             if (ret != PIPE_OK)
@@ -209,39 +224,19 @@ update_sampler_resources(struct svga_context *svga, unsigned dirty)
 
             assert(sv->id != SVGA3D_INVALID_ID);
             ids[i] = sv->id;
+            sampler_views[i] = &sv->base;
          }
          else {
-            surface = NULL;
+            surfaces[i] = NULL;
             ids[i] = SVGA3D_INVALID_ID;
+            sampler_views[i] = NULL;
          }
-         surfaces[i] = surface;
       }
 
-      for (; i < Elements(ids); i++) {
+      for (; i < svga->state.hw_draw.num_sampler_views[shader]; i++) {
          ids[i] = SVGA3D_INVALID_ID;
          surfaces[i] = NULL;
-      }
-
-      if (shader == PIPE_SHADER_FRAGMENT) {
-         /* Handle polygon stipple sampler view */
-         if (svga->curr.rast->templ.poly_stipple_enable) {
-            const unsigned unit = svga->state.hw_draw.fs->pstipple_sampler_unit;
-            struct svga_pipe_sampler_view *sv =
-               svga->polygon_stipple.sampler_view;
-
-            assert(sv);
-            if (!sv) {
-               return PIPE_OK;  /* probably out of memory */
-            }
-
-            ret = svga_validate_pipe_sampler_view(svga, sv);
-            if (ret != PIPE_OK)
-               return ret;
-
-            ids[unit] = sv->id;
-            surfaces[unit] = svga_resource_handle(sv->base.texture);
-            count = MAX2(count, unit+1);
-         }
+         sampler_views[i] = NULL;
       }
 
       /* Number of ShaderResources that need to be modified. This includes
@@ -249,20 +244,53 @@ update_sampler_resources(struct svga_context *svga, unsigned dirty)
        */
       nviews = MAX2(svga->state.hw_draw.num_sampler_views[shader], count);
       if (nviews > 0) {
-         ret = SVGA3D_vgpu10_SetShaderResources(svga->swc,
+         if (count != svga->state.hw_draw.num_sampler_views[shader] ||
+             memcmp(sampler_views, svga->state.hw_draw.sampler_views[shader],
+                    count * sizeof(sampler_views[0])) != 0) {
+            ret = SVGA3D_vgpu10_SetShaderResources(svga->swc,
                                                 svga_shader_type(shader),
                                                 0, /* startView */
                                                 nviews,
                                                 ids,
                                                 surfaces);
-         if (ret != PIPE_OK)
-            return ret;
-      }
+            if (ret != PIPE_OK)
+               return ret;
 
-      /* Number of sampler views enabled in the device */
-      svga->state.hw_draw.num_sampler_views[shader] = count;
+            /* Save referenced sampler views in the hw draw state.  */
+            svga->state.hw_draw.num_sampler_views[shader] = count;
+            for (i = 0; i < nviews; i++) {
+               pipe_sampler_view_reference(
+                  &svga->state.hw_draw.sampler_views[shader][i],
+                  sampler_views[i]);
+            }
+         }
+      }
    }
 
+   /* Handle polygon stipple sampler view */
+   if (svga->curr.rast->templ.poly_stipple_enable) {
+      const unsigned unit = svga->state.hw_draw.fs->pstipple_sampler_unit;
+      struct svga_pipe_sampler_view *sv = svga->polygon_stipple.sampler_view;
+      struct svga_winsys_surface *surface;
+
+      assert(sv);
+      if (!sv) {
+         return PIPE_OK;  /* probably out of memory */
+      }
+
+      ret = svga_validate_pipe_sampler_view(svga, sv);
+      if (ret != PIPE_OK)
+         return ret;
+
+      surface = svga_resource_handle(sv->base.texture);
+      ret = SVGA3D_vgpu10_SetShaderResources(
+               svga->swc,
+               svga_shader_type(PIPE_SHADER_FRAGMENT),
+               unit, /* startView */
+               1,
+               &sv->id,
+               &surface);
+   }
    return ret;
 }
 
@@ -289,6 +317,7 @@ update_samplers(struct svga_context *svga, unsigned dirty )
       const unsigned count = svga->curr.num_samplers[shader];
       SVGA3dSamplerId ids[PIPE_MAX_SAMPLERS];
       unsigned i;
+      unsigned nsamplers;
 
       for (i = 0; i < count; i++) {
          if (svga->curr.sampler[shader][i]) {
@@ -300,14 +329,27 @@ update_samplers(struct svga_context *svga, unsigned dirty )
          }
       }
 
-      if (count > 0) {
-         ret = SVGA3D_vgpu10_SetSamplers(svga->swc,
-                                         count,
-                                         0,                        /* start */
-                                         svga_shader_type(shader), /* type */
-                                         ids);
-         if (ret != PIPE_OK)
-            return ret;
+      for (; i < svga->state.hw_draw.num_samplers[shader]; i++) {
+         ids[i] = SVGA3D_INVALID_ID;
+      }
+
+      nsamplers = MAX2(svga->state.hw_draw.num_samplers[shader], count);
+      if (nsamplers > 0) {
+         if (count != svga->state.hw_draw.num_samplers[shader] ||
+             memcmp(ids, svga->state.hw_draw.samplers[shader],
+                    count * sizeof(ids[0])) != 0) {
+            /* HW state is really changing */
+            ret = SVGA3D_vgpu10_SetSamplers(svga->swc,
+                                            nsamplers,
+                                            0,                       /* start */
+                                            svga_shader_type(shader), /* type */
+                                            ids);
+            if (ret != PIPE_OK)
+               return ret;
+            memcpy(svga->state.hw_draw.samplers[shader], ids,
+                   nsamplers * sizeof(ids[0]));
+            svga->state.hw_draw.num_samplers[shader] = count;
+         }
       }
    }
 
@@ -321,11 +363,20 @@ update_samplers(struct svga_context *svga, unsigned dirty )
          return PIPE_OK; /* probably out of memory */
       }
 
-      ret = SVGA3D_vgpu10_SetSamplers(svga->swc,
-                                      1, /* count */
-                                      unit, /* start */
-                                      SVGA3D_SHADERTYPE_PS,
-                                      &sampler->id);
+      if (svga->state.hw_draw.samplers[PIPE_SHADER_FRAGMENT][unit]
+          != sampler->id) {
+         ret = SVGA3D_vgpu10_SetSamplers(svga->swc,
+                                         1, /* count */
+                                         unit, /* start */
+                                         SVGA3D_SHADERTYPE_PS,
+                                         &sampler->id);
+         if (ret != PIPE_OK)
+            return ret;
+
+         /* save the polygon stipple sampler in the hw draw state */
+         svga->state.hw_draw.samplers[PIPE_SHADER_FRAGMENT][unit] =
+            sampler->id;
+      }
    }
 
    return ret;