[Mesa-dev] [PATCH 5/9] anv: Added support for dynamic sample locations on Gen8+

Eleni Maria Stea estea at igalia.com
Mon Mar 11 15:04:55 UTC 2019


Added support for setting the locations when the pipeline has been
created with the dynamic state bit enabled according to the Vulkan
Specification section [26.5. Custom Sample Locations] for the function:

'vkCmdSetSampleLocationsEXT'

The reason that we preferred to store the boolean valid inside the
dynamic state struct for locations instead of using a dirty bit
(ANV_CMD_DIRTY_SAMPLE_LOCATIONS for example) is that other functions
can modify the value of the dirty bits causing unexpected behavior.
---
 src/intel/vulkan/anv_cmd_buffer.c  | 19 ++++++++++++
 src/intel/vulkan/anv_genX.h        |  6 +++-
 src/intel/vulkan/anv_private.h     |  6 ++++
 src/intel/vulkan/genX_cmd_buffer.c | 27 ++++++++++++++++++
 src/intel/vulkan/genX_pipeline.c   | 46 ++++--------------------------
 src/intel/vulkan/genX_state.c      | 41 +++++++++++++++++++++++---
 6 files changed, 99 insertions(+), 46 deletions(-)

diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c
index 1b34644a434..101c1375430 100644
--- a/src/intel/vulkan/anv_cmd_buffer.c
+++ b/src/intel/vulkan/anv_cmd_buffer.c
@@ -28,6 +28,7 @@
 #include <fcntl.h>
 
 #include "anv_private.h"
+#include "anv_sample_locations.h"
 
 #include "vk_format_info.h"
 #include "vk_util.h"
@@ -558,6 +559,24 @@ void anv_CmdSetStencilReference(
    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE;
 }
 
+void
+anv_CmdSetSampleLocationsEXT(VkCommandBuffer commandBuffer,
+                             const VkSampleLocationsInfoEXT *pSampleLocationsInfo)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
+   assert(pSampleLocationsInfo);
+
+   struct anv_dynamic_state *dyn_state = &cmd_buffer->state.gfx.dynamic;
+   dyn_state->sample_locations.num_samples =
+      pSampleLocationsInfo->sampleLocationsPerPixel;
+
+   anv_calc_sample_locations(dyn_state->sample_locations.anv_samples,
+                             dyn_state->sample_locations.num_samples,
+                             pSampleLocationsInfo);
+
+   cmd_buffer->state.gfx.dynamic.sample_locations.valid = true;
+}
+
 static void
 anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
                                    VkPipelineBindPoint bind_point,
diff --git a/src/intel/vulkan/anv_genX.h b/src/intel/vulkan/anv_genX.h
index 52415c04a45..f84fe457152 100644
--- a/src/intel/vulkan/anv_genX.h
+++ b/src/intel/vulkan/anv_genX.h
@@ -89,7 +89,11 @@ void genX(cmd_buffer_mi_memset)(struct anv_cmd_buffer *cmd_buffer,
 void genX(blorp_exec)(struct blorp_batch *batch,
                       const struct blorp_params *params);
 
+void genX(emit_multisample)(struct anv_batch *batch,
+                            uint32_t samples,
+                            uint32_t log2_samples);
+
 void genX(emit_sample_locations)(struct anv_batch *batch,
+                                 const struct anv_sample *anv_samples,
                                  uint32_t num_samples,
-                                 const VkSampleLocationsInfoEXT *sl,
                                  bool custom_locations);
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 981956e5706..a2e1756cd99 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -2135,6 +2135,12 @@ struct anv_dynamic_state {
       uint32_t                                  front;
       uint32_t                                  back;
    } stencil_reference;
+
+   struct {
+      struct anv_sample                         anv_samples[MAX_SAMPLE_LOCATIONS];
+      uint32_t                                  num_samples;
+      bool                                      valid;
+   } sample_locations;
 };
 
 extern const struct anv_dynamic_state default_dynamic_state;
diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c
index 7687507e6b7..9229df84caa 100644
--- a/src/intel/vulkan/genX_cmd_buffer.c
+++ b/src/intel/vulkan/genX_cmd_buffer.c
@@ -25,11 +25,13 @@
 #include <stdbool.h>
 
 #include "anv_private.h"
+#include "anv_sample_locations.h"
 #include "vk_format_info.h"
 #include "vk_util.h"
 #include "util/fast_idiv_by_const.h"
 
 #include "common/gen_l3_config.h"
+#include "common/gen_sample_positions.h"
 #include "genxml/gen_macros.h"
 #include "genxml/genX_pack.h"
 
@@ -2638,6 +2640,26 @@ cmd_buffer_flush_push_constants(struct anv_cmd_buffer *cmd_buffer,
    cmd_buffer->state.push_constants_dirty &= ~flushed;
 }
 
+static void
+cmd_buffer_emit_sample_locations(struct anv_cmd_buffer *cmd_buffer)
+{
+#if GEN_GEN >= 8
+   const struct anv_sample *anv_samples;
+   uint32_t log2_samples;
+   uint32_t samples;
+
+   samples = cmd_buffer->state.gfx.dynamic.sample_locations.num_samples;
+   assert(samples > 0);
+
+   log2_samples = __builtin_ffs(samples) - 1;
+   anv_samples = cmd_buffer->state.gfx.dynamic.sample_locations.anv_samples;
+
+   genX(emit_multisample)(&cmd_buffer->batch, samples, log2_samples);
+   genX(emit_sample_locations)(&cmd_buffer->batch, anv_samples, samples,
+                              true);
+#endif
+}
+
 void
 genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer)
 {
@@ -2796,6 +2818,11 @@ genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer)
                                       ANV_CMD_DIRTY_RENDER_TARGETS))
       gen7_cmd_buffer_emit_scissor(cmd_buffer);
 
+   if (cmd_buffer->state.gfx.dynamic.sample_locations.valid) {
+      cmd_buffer_emit_sample_locations(cmd_buffer);
+      cmd_buffer->state.gfx.dynamic.sample_locations.valid = false;
+   }
+
    genX(cmd_buffer_flush_dynamic_state)(cmd_buffer);
 
    genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer);
diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c
index feb431e10cd..fa42e622077 100644
--- a/src/intel/vulkan/genX_pipeline.c
+++ b/src/intel/vulkan/genX_pipeline.c
@@ -572,52 +572,15 @@ emit_sample_mask(struct anv_pipeline *pipeline,
    }
 }
 
-static void
-emit_multisample(struct anv_pipeline *pipeline,
-                 uint32_t samples,
-                 uint32_t log2_samples)
-{
-   anv_batch_emit(&pipeline->batch, GENX(3DSTATE_MULTISAMPLE), ms) {
-      ms.NumberofMultisamples       = log2_samples;
-
-      ms.PixelLocation              = CENTER;
-#if GEN_GEN >= 8
-      /* The PRM says that this bit is valid only for DX9:
-       *
-       *    SW can choose to set this bit only for DX9 API. DX10/OGL API's
-       *    should not have any effect by setting or not setting this bit.
-       */
-      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;
-      }
-#endif
-   }
-}
-
 static void
 emit_ms_state(struct anv_pipeline *pipeline,
               const VkPipelineMultisampleStateCreateInfo *info,
               const VkPipelineDynamicStateCreateInfo *dinfo)
 {
 #if GEN_GEN >= 8
-   bool custom_locations = false;
+   struct anv_sample anv_samples[MAX_SAMPLE_LOCATIONS];
    VkSampleLocationsInfoEXT *sl;
+   bool custom_locations = false;
 #endif
 
    uint32_t samples = 1;
@@ -649,6 +612,7 @@ emit_ms_state(struct anv_pipeline *pipeline,
                   samples = sl->sampleLocationsPerPixel;
 
                custom_locations = true;
+               anv_calc_sample_locations(anv_samples, samples, sl);
             }
          }
       }
@@ -657,10 +621,10 @@ emit_ms_state(struct anv_pipeline *pipeline,
       log2_samples = __builtin_ffs(samples) - 1;
    }
 
-   emit_multisample(pipeline, samples, log2_samples);
+   genX(emit_multisample(&pipeline->batch, samples, log2_samples));
 
 #if GEN_GEN >= 8
-   genX(emit_sample_locations)(&pipeline->batch, samples, sl,
+   genX(emit_sample_locations)(&pipeline->batch, anv_samples, samples,
                                custom_locations);
 #endif
 }
diff --git a/src/intel/vulkan/genX_state.c b/src/intel/vulkan/genX_state.c
index c14e502a68d..44cfc925ed5 100644
--- a/src/intel/vulkan/genX_state.c
+++ b/src/intel/vulkan/genX_state.c
@@ -437,22 +437,55 @@ VkResult genX(CreateSampler)(
    return VK_SUCCESS;
 }
 
+void
+genX(emit_multisample)(struct anv_batch *batch,
+                       uint32_t samples,
+                       uint32_t log2_samples)
+{
+   anv_batch_emit(batch, GENX(3DSTATE_MULTISAMPLE), ms) {
+      ms.NumberofMultisamples = log2_samples;
+      ms.PixelLocation = CENTER;
+#if GEN_GEN >= 8
+      /* The PRM says that this bit is valid only for DX9:
+       *
+       *    SW can choose to set this bit only for DX9 API. DX10/OGL API's
+       *    should not have any effect by setting or not setting this bit.
+       */
+      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;
+      }
+#endif
+   }
+}
+
 void
 genX(emit_sample_locations)(struct anv_batch *batch,
+                            const struct anv_sample *anv_samples,
                             uint32_t num_samples,
-                            const VkSampleLocationsInfoEXT *sl,
                             bool custom_locations)
 {
 #if GEN_GEN >= 8
-   struct anv_sample anv_samples[MAX_SAMPLE_LOCATIONS];
 
 #if GEN_GEN == 10
    gen10_emit_wa_cs_stall_flush(batch);
 #endif
 
    if (custom_locations) {
-      anv_calc_sample_locations(anv_samples, num_samples, sl);
-
       anv_batch_emit(batch,  GENX(3DSTATE_SAMPLE_PATTERN), sp) {
          switch (num_samples) {
          case 1:
-- 
2.20.1



More information about the mesa-dev mailing list