<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jun 28, 2017 at 2:14 PM, Nanley Chery <span dir="ltr"><<a href="mailto:nanleychery@gmail.com" target="_blank">nanleychery@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">We'll be performing a GPU memcpy in more places to copy small amounts of<br>
data. Add an alternate function that thrashes less state.<br>
<br>
v2:<br>
- Make a new function (Jason Ekstrand).<br>
- Move the #define into the function.<br>
v3:<br>
- Update the function name (Jason).<br>
- Update comments.<br>
<br>
Signed-off-by: Nanley Chery <<a href="mailto:nanley.g.chery@intel.com">nanley.g.chery@intel.com</a>><br>
---<br>
 src/intel/vulkan/anv_genX.h        |  5 +++++<br>
 src/intel/vulkan/genX_gpu_<wbr>memcpy.c | 40 ++++++++++++++++++++++++++++++<wbr>++++++++<br>
 2 files changed, 45 insertions(+)<br>
<br>
diff --git a/src/intel/vulkan/anv_genX.h b/src/intel/vulkan/anv_genX.h<br>
index 8da5e075dc..0b7322e281 100644<br>
--- a/src/intel/vulkan/anv_genX.h<br>
+++ b/src/intel/vulkan/anv_genX.h<br>
@@ -69,5 +69,10 @@ void genX(cmd_buffer_so_memcpy)(<wbr>struct anv_cmd_buffer *cmd_buffer,<br>
                                 struct anv_bo *src, uint32_t src_offset,<br>
                                 uint32_t size);<br>
<br>
+void genX(cmd_buffer_mi_memcpy)(<wbr>struct anv_cmd_buffer *cmd_buffer,<br>
+                                struct anv_bo *dst, uint32_t dst_offset,<br>
+                                struct anv_bo *src, uint32_t src_offset,<br>
+                                uint32_t size);<br>
+<br>
 void genX(blorp_exec)(struct blorp_batch *batch,<br>
                       const struct blorp_params *params);<br>
diff --git a/src/intel/vulkan/genX_gpu_<wbr>memcpy.c b/src/intel/vulkan/genX_gpu_<wbr>memcpy.c<br>
index 5ef35e6283..9c6b46de94 100644<br>
--- a/src/intel/vulkan/genX_gpu_<wbr>memcpy.c<br>
+++ b/src/intel/vulkan/genX_gpu_<wbr>memcpy.c<br>
@@ -52,6 +52,46 @@ gcd_pow2_u64(uint64_t a, uint64_t b)<br>
 }<br>
<br>
 void<br>
+genX(cmd_buffer_mi_memcpy)(<wbr>struct anv_cmd_buffer *cmd_buffer,<br>
+                           struct anv_bo *dst, uint32_t dst_offset,<br>
+                           struct anv_bo *src, uint32_t src_offset,<br>
+                           uint32_t size)<br>
+{<br>
+   /* This memcpy operates in units of dwords. */<br>
+   assert(size % 4 == 0);<br>
+   assert(dst_offset % 4 == 0);<br>
+   assert(src_offset % 4 == 0);<br>
+<br>
+   for (uint32_t i = 0; i < size; i += 4) {<br>
+      const struct anv_address src_addr =<br>
+         (struct anv_address) { src, src_offset + i};<br>
+      const struct anv_address dst_addr =<br>
+         (struct anv_address) { dst, dst_offset + i};<br>
+#if GEN_GEN >= 8<br>
+      anv_batch_emit(&cmd_buffer-><wbr>batch, GENX(MI_COPY_MEM_MEM), cp) {<br>
+         cp.DestinationMemoryAddress = dst_addr;<br>
+         cp.SourceMemoryAddress = src_addr;<br>
+      }<br>
+#else<br>
+      /* IVB does not have a general purpose register for command streamer<br>
+       * commands. Therefore, we use an alternate temporary register.<br>
+       */<br>
+#define TEMP_REG 0x2400 /* MI_PREDICATE_SRC0 */<br></blockquote><div><br></div><div>Using the predicate register seems a bit sketchy.  Vulkan doesn't support predication today so it's probably safe but I don't know what form predication will take in the future (there's a decent chance it'll get added) so I have no idea if this will end up being safe.  Why not use one of the indirect dispatch/draw registers?  Those will be safe because we only ever set them immediately before 3DPRIMITIVE or GPGPU_WALKER.<br><br></div><div>--Jason<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+      anv_batch_emit(&cmd_buffer-><wbr>batch, GENX(MI_LOAD_REGISTER_MEM), load) {<br>
+         load.RegisterAddress = TEMP_REG;<br>
+         load.MemoryAddress = src_addr;<br>
+      }<br>
+      anv_batch_emit(&cmd_buffer-><wbr>batch, GENX(MI_STORE_REGISTER_MEM), store) {<br>
+         store.RegisterAddress = TEMP_REG;<br>
+         store.MemoryAddress = dst_addr;<br>
+      }<br>
+#undef TEMP_REG<br>
+#endif<br>
+   }<br>
+   return;<br>
+}<br>
+<br>
+void<br>
 genX(cmd_buffer_so_memcpy)(<wbr>struct anv_cmd_buffer *cmd_buffer,<br>
                            struct anv_bo *dst, uint32_t dst_offset,<br>
                            struct anv_bo *src, uint32_t src_offset,<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.13.1<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>