Mesa (master): anv/state: Take explicit sample locations in emit helpers

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jan 27 23:35:39 UTC 2021


Module: Mesa
Branch: master
Commit: cb082d826050240ff1abb0e04c0d1cf1a11dc738
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=cb082d826050240ff1abb0e04c0d1cf1a11dc738

Author: Eleni Maria Stea <estea at igalia.com>
Date:   Thu Mar 14 18:20:12 2019 -0500

anv/state: Take explicit sample locations in emit helpers

This commit adds a "locations" parameter to emit_multisample and
emit_sample_pattern which, if provided, will override the default
sample locations.

Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/1887>

---

 src/intel/common/gen_sample_positions.h |  57 +++++++++++++++++
 src/intel/vulkan/anv_genX.h             |   6 +-
 src/intel/vulkan/genX_pipeline.c        |   2 +-
 src/intel/vulkan/genX_state.c           | 109 +++++++++++++++++++++++++-------
 4 files changed, 148 insertions(+), 26 deletions(-)

diff --git a/src/intel/common/gen_sample_positions.h b/src/intel/common/gen_sample_positions.h
index da48dcb5ed0..d4149fce95b 100644
--- a/src/intel/common/gen_sample_positions.h
+++ b/src/intel/common/gen_sample_positions.h
@@ -28,6 +28,63 @@
  * Vulkan.  These correspond to the Vulkan "standard sample locations".
  */
 
+/* Examples:
+ * in case of GEN_GEN < 8:
+ * GEN_SAMPLE_POS_ELEM(ms.Sample, info->pSampleLocations, 0); expands to:
+ *    ms.Sample0XOffset = info->pSampleLocations[0].x;
+ *    ms.Sample0YOffset = info->pSampleLocations[0].y;
+ *
+ * in case of GEN_GEN >= 8:
+ * GEN_SAMPLE_POS_ELEM(sp._16xSample, info->pSampleLocations, 0); expands to:
+ *    sp._16xSample0XOffset = info->pSampleLocations[0].x;
+ *    sp._16xSample0YOffset = info->pSampleLocations[0].y;
+ */
+
+#define GEN_SAMPLE_POS_ELEM(prefix, arr, sample_idx) \
+prefix##sample_idx##XOffset = arr[sample_idx].x; \
+prefix##sample_idx##YOffset = arr[sample_idx].y;
+
+#define GEN_SAMPLE_POS_1X_ARRAY(prefix, arr)\
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 0);
+
+#define GEN_SAMPLE_POS_2X_ARRAY(prefix, arr) \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 0); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 1);
+
+#define GEN_SAMPLE_POS_4X_ARRAY(prefix, arr) \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 0); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 1); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 2); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 3);
+
+#define GEN_SAMPLE_POS_8X_ARRAY(prefix, arr) \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 0); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 1); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 2); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 3); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 4); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 5); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 6); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 7);
+
+#define GEN_SAMPLE_POS_16X_ARRAY(prefix, arr) \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 0); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 1); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 2); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 3); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 4); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 5); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 6); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 7); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 8); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 9); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 10); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 11); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 12); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 13); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 14); \
+   GEN_SAMPLE_POS_ELEM(prefix, arr, 15);
+
 /**
  * 1x MSAA has a single sample at the center: (0.5, 0.5) -> (0x8, 0x8).
  */
diff --git a/src/intel/vulkan/anv_genX.h b/src/intel/vulkan/anv_genX.h
index e69c641a93a..e16be7ade5c 100644
--- a/src/intel/vulkan/anv_genX.h
+++ b/src/intel/vulkan/anv_genX.h
@@ -97,9 +97,11 @@ genX(emit_urb_setup)(struct anv_device *device, struct anv_batch *batch,
                      const unsigned entry_size[4],
                      enum gen_urb_deref_block_size *deref_block_size);
 
-void genX(emit_multisample)(struct anv_batch *batch, uint32_t samples);
+void genX(emit_multisample)(struct anv_batch *batch, uint32_t samples,
+                            const VkSampleLocationEXT *locations);
 
-void genX(emit_sample_pattern)(struct anv_batch *batch);
+void genX(emit_sample_pattern)(struct anv_batch *batch, uint32_t samples,
+                               const VkSampleLocationEXT *locations);
 
 void genX(cmd_buffer_so_memcpy)(struct anv_cmd_buffer *cmd_buffer,
                                 struct anv_address dst, struct anv_address src,
diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c
index 06dabad6464..3aeeaf943bf 100644
--- a/src/intel/vulkan/genX_pipeline.c
+++ b/src/intel/vulkan/genX_pipeline.c
@@ -738,7 +738,7 @@ emit_ms_state(struct anv_graphics_pipeline *pipeline,
 {
    uint32_t samples = info ? info->rasterizationSamples : 1;
 
-   genX(emit_multisample)(&pipeline->base.batch, samples);
+   genX(emit_multisample)(&pipeline->base.batch, samples, NULL);
 
    /* From the Vulkan 1.0 spec:
     *    If pSampleMask is NULL, it is treated as if the mask has all bits
diff --git a/src/intel/vulkan/genX_state.c b/src/intel/vulkan/genX_state.c
index d944df2ed5d..5e67e7adc7d 100644
--- a/src/intel/vulkan/genX_state.c
+++ b/src/intel/vulkan/genX_state.c
@@ -156,7 +156,7 @@ genX(init_device_state)(struct anv_device *device)
 #if GEN_GEN >= 8
    anv_batch_emit(&batch, GENX(3DSTATE_WM_CHROMAKEY), ck);
 
-   genX(emit_sample_pattern)(&batch);
+   genX(emit_sample_pattern)(&batch, 0, NULL);
 
    /* The BDW+ docs describe how to use the 3DSTATE_WM_HZ_OP instruction in the
     * section titled, "Optimized Depth Buffer Clear and/or Stencil Buffer
@@ -310,7 +310,8 @@ genX(init_device_state)(struct anv_device *device)
 }
 
 void
-genX(emit_multisample)(struct anv_batch *batch, uint32_t samples)
+genX(emit_multisample)(struct anv_batch *batch, uint32_t samples,
+                       const VkSampleLocationEXT *locations)
 {
    anv_batch_emit(batch, GENX(3DSTATE_MULTISAMPLE), ms) {
       ms.NumberofMultisamples       = __builtin_ffs(samples) - 1;
@@ -325,21 +326,40 @@ genX(emit_multisample)(struct anv_batch *batch, uint32_t samples)
       ms.PixelPositionOffsetEnable  = false;
 #else
 
-      switch (samples) {
-      case 1:
-         GEN_SAMPLE_POS_1X(ms.Sample);
-         break;
-      case 2:
-         GEN_SAMPLE_POS_2X(ms.Sample);
-         break;
-      case 4:
-         GEN_SAMPLE_POS_4X(ms.Sample);
-         break;
-      case 8:
-         GEN_SAMPLE_POS_8X(ms.Sample);
-         break;
-      default:
-         break;
+      if (locations) {
+         switch (samples) {
+         case 1:
+            GEN_SAMPLE_POS_1X_ARRAY(ms.Sample, locations);
+            break;
+         case 2:
+            GEN_SAMPLE_POS_2X_ARRAY(ms.Sample, locations);
+            break;
+         case 4:
+            GEN_SAMPLE_POS_4X_ARRAY(ms.Sample, locations);
+            break;
+         case 8:
+            GEN_SAMPLE_POS_8X_ARRAY(ms.Sample, locations);
+            break;
+         default:
+            break;
+         }
+      } else {
+         switch (samples) {
+         case 1:
+            GEN_SAMPLE_POS_1X(ms.Sample);
+            break;
+         case 2:
+            GEN_SAMPLE_POS_2X(ms.Sample);
+            break;
+         case 4:
+            GEN_SAMPLE_POS_4X(ms.Sample);
+            break;
+         case 8:
+            GEN_SAMPLE_POS_8X(ms.Sample);
+            break;
+         default:
+            break;
+         }
       }
 #endif
    }
@@ -347,19 +367,62 @@ genX(emit_multisample)(struct anv_batch *batch, uint32_t samples)
 
 #if GEN_GEN >= 8
 void
-genX(emit_sample_pattern)(struct anv_batch *batch)
+genX(emit_sample_pattern)(struct anv_batch *batch, uint32_t samples,
+                          const VkSampleLocationEXT *locations)
 {
    /* See the Vulkan 1.0 spec Table 24.1 "Standard sample locations" and
     * VkPhysicalDeviceFeatures::standardSampleLocations.
     */
    anv_batch_emit(batch, GENX(3DSTATE_SAMPLE_PATTERN), sp) {
-      GEN_SAMPLE_POS_1X(sp._1xSample);
-      GEN_SAMPLE_POS_2X(sp._2xSample);
-      GEN_SAMPLE_POS_4X(sp._4xSample);
-      GEN_SAMPLE_POS_8X(sp._8xSample);
+      if (locations) {
+         /* The Skylake PRM Vol. 2a "3DSTATE_SAMPLE_PATTERN" says:
+          *
+          *    "When programming the sample offsets (for NUMSAMPLES_4 or _8
+          *    and MSRASTMODE_xxx_PATTERN), the order of the samples 0 to 3
+          *    (or 7 for 8X, or 15 for 16X) must have monotonically increasing
+          *    distance from the pixel center. This is required to get the
+          *    correct centroid computation in the device."
+          *
+          * However, the Vulkan spec seems to require that the the samples
+          * occur in the order provided through the API. The standard sample
+          * patterns have the above property that they have monotonically
+          * increasing distances from the center but client-provided ones do
+          * not. As long as this only affects centroid calculations as the
+          * docs say, we should be ok because OpenGL and Vulkan only require
+          * that the centroid be some lit sample and that it's the same for
+          * all samples in a pixel; they have no requirement that it be the
+          * one closest to center.
+          */
+         switch (samples) {
+         case 1:
+            GEN_SAMPLE_POS_1X_ARRAY(sp._1xSample, locations);
+            break;
+         case 2:
+            GEN_SAMPLE_POS_2X_ARRAY(sp._2xSample, locations);
+            break;
+         case 4:
+            GEN_SAMPLE_POS_4X_ARRAY(sp._4xSample, locations);
+            break;
+         case 8:
+            GEN_SAMPLE_POS_8X_ARRAY(sp._8xSample, locations);
+            break;
 #if GEN_GEN >= 9
-      GEN_SAMPLE_POS_16X(sp._16xSample);
+         case 16:
+            GEN_SAMPLE_POS_16X_ARRAY(sp._16xSample, locations);
+            break;
 #endif
+         default:
+            break;
+         }
+      } else {
+         GEN_SAMPLE_POS_1X(sp._1xSample);
+         GEN_SAMPLE_POS_2X(sp._2xSample);
+         GEN_SAMPLE_POS_4X(sp._4xSample);
+         GEN_SAMPLE_POS_8X(sp._8xSample);
+#if GEN_GEN >= 9
+         GEN_SAMPLE_POS_16X(sp._16xSample);
+#endif
+      }
    }
 }
 #endif



More information about the mesa-commit mailing list