<div dir="ltr"><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Mar 14, 2019 at 7:08 PM Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">From: Eleni Maria Stea <<a href="mailto:estea@igalia.com" target="_blank">estea@igalia.com</a>><br>
<br>
Added support for setting the locations when the pipeline has been<br>
created with the dynamic state bit enabled according to the Vulkan<br>
Specification section [26.5. Custom Sample Locations] for the function:<br>
<br>
'vkCmdSetSampleLocationsEXT'<br>
<br>
The reason that we preferred to store the boolean valid inside the<br>
dynamic state struct for locations instead of using a dirty bit<br>
(ANV_CMD_DIRTY_SAMPLE_LOCATIONS for example) is that other functions<br>
can modify the value of the dirty bits causing unexpected behavior.<br>
<br>
v2: Removed all the anv* structs used with sample locations to store<br>
    the locations in order for dynamic case. (see also the patch for<br>
    the non-dynamic case. (Jason Ekstrand)<br>
---<br>
 src/intel/vulkan/anv_cmd_buffer.c  | 17 +++++++++++++++++<br>
 src/intel/vulkan/anv_private.h     |  6 ++++++<br>
 src/intel/vulkan/genX_cmd_buffer.c | 11 +++++++++++<br>
 3 files changed, 34 insertions(+)<br>
<br>
diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c<br>
index 1b34644a434..7f31300857b 100644<br>
--- a/src/intel/vulkan/anv_cmd_buffer.c<br>
+++ b/src/intel/vulkan/anv_cmd_buffer.c<br>
@@ -558,6 +558,23 @@ void anv_CmdSetStencilReference(<br>
    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE;<br>
 }<br>
<br>
+void<br>
+anv_CmdSetSampleLocationsEXT(VkCommandBuffer commandBuffer,<br>
+                             const VkSampleLocationsInfoEXT *pSampleLocationsInfo)<br>
+{<br>
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);<br>
+<br>
+   struct anv_dynamic_state *dyn_state = &cmd_buffer->state.gfx.dynamic;<br>
+   uint32_t samples = pSampleLocationsInfo->sampleLocationsPerPixel;<br>
+<br>
+   assert(pSampleLocationsInfo);<br>
+   dyn_state->sample_locations.samples = samples;<br>
+   typed_memcpy(dyn_state->sample_locations.locations,<br>
+                pSampleLocationsInfo->pSampleLocations, samples);<br>
+<br>
+   dyn_state->sample_locations.valid = true;<br>
+}<br>
+<br>
 static void<br>
 anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer,<br>
                                    VkPipelineBindPoint bind_point,<br>
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h<br>
index a39195733cd..94c9db14028 100644<br>
--- a/src/intel/vulkan/anv_private.h<br>
+++ b/src/intel/vulkan/anv_private.h<br>
@@ -2124,6 +2124,12 @@ struct anv_dynamic_state {<br>
       uint32_t                                  front;<br>
       uint32_t                                  back;<br>
    } stencil_reference;<br>
+<br>
+   struct {<br>
+      bool                                      valid;<br>
+      uint32_t                                  samples;<br>
+      VkSampleLocationEXT                       locations[MAX_SAMPLE_LOCATIONS];<br>
+   } sample_locations;<br>
 };<br>
<br>
 extern const struct anv_dynamic_state default_dynamic_state;<br>
diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c<br>
index 7687507e6b7..5d2b17cf8ae 100644<br>
--- a/src/intel/vulkan/genX_cmd_buffer.c<br>
+++ b/src/intel/vulkan/genX_cmd_buffer.c<br>
@@ -2796,6 +2796,17 @@ genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer)<br>
                                       ANV_CMD_DIRTY_RENDER_TARGETS))<br>
       gen7_cmd_buffer_emit_scissor(cmd_buffer);<br>
<br>
+   if (cmd_buffer->state.gfx.dynamic.sample_locations.valid) {<br>
+      uint32_t samples = cmd_buffer->state.gfx.dynamic.sample_locations.samples;<br>
+      const VkSampleLocationEXT *locations =<br>
+         cmd_buffer->state.gfx.dynamic.sample_locations.locations;<br>
+      genX(emit_multisample)(&cmd_buffer->batch, samples, locations);<br>
+#if GEN_GEN >= 8<br>
+      genX(emit_sample_pattern)(&cmd_buffer->batch, samples, locations);<br>
+#endif<br>
+      cmd_buffer->state.gfx.dynamic.sample_locations.valid = false;<br></blockquote><div><br></div><div>I'm not sure this is actually going to be correct.  With dynamic state, you're required to set it before you use it.  With pipeline state, it gets set every time the pipeline is bound.  Effectively, the pipeline state is a big bag of dynamic state.  With both of these, however, there are no defaults and you're required to bind a pipeline containing the state or explicitly set it on the command buffer before it gets used.  VK_EXT_sample_locations is different though because it does have a default.  So the question I'm coming around to is: When does the default get applied?  The only sensible thing I can think of is at the top of the command buffer or maybe the top of the subpass.  If this is the case, then we need to emit sample positions at the start of every subpass.  Does the spec talk about this at all?</div><div><br></div><div>--Jason<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

</blockquote></div></div>