radv: Keep shader code ptr in a separately allocated buffer.
authorTatsuyuki Ishi <ishitatsuyuki@gmail.com>
Fri, 24 Feb 2023 09:27:04 +0000 (18:27 +0900)
committerMarge Bot <emma+marge@anholt.net>
Mon, 27 Feb 2023 07:16:48 +0000 (07:16 +0000)
RGP traces need a dump of shader code in order to display ISA and
instruction trace. Previously, this was read back from GPU at trace
creation time. However, for future changes that implements upload shader
to invisible VRAM, the upload destination will be a temporary staging
buffer and will be only accessible during shader creation.

To allow dumping in such cases, copy the shader code to a separate buffer
at creation time, if thread tracing is enabled.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21513>

src/amd/vulkan/layers/radv_sqtt_layer.c
src/amd/vulkan/radv_shader.c
src/amd/vulkan/radv_shader.h

index 11775d6..61616ff 100644 (file)
@@ -182,7 +182,7 @@ radv_sqtt_reloc_graphics_shaders(struct radv_device *device,
       reloc->va[i] = slab_va + slab_offset;
 
       void *dest_ptr = slab_ptr + slab_offset;
-      memcpy(dest_ptr, shader->code_ptr, shader->code_size);
+      memcpy(dest_ptr, shader->code, shader->code_size);
 
       slab_offset += align(shader->code_size, RADV_SHADER_ALLOC_ALIGNMENT);
    }
@@ -1133,7 +1133,7 @@ radv_add_code_object(struct radv_device *device, struct radv_pipeline *pipeline)
          free(record);
          return VK_ERROR_OUT_OF_HOST_MEMORY;
       }
-      memcpy(code, shader->code_ptr, shader->code_size);
+      memcpy(code, shader->code, shader->code_size);
 
       va = radv_sqtt_shader_get_va_reloc(pipeline, i);
 
index 9278435..426db4d 100644 (file)
@@ -33,6 +33,7 @@
 #include "util/memstream.h"
 #include "util/mesa-sha1.h"
 #include "util/u_atomic.h"
+#include "util/streaming-load-memcpy.h"
 #include "radv_debug.h"
 #include "radv_meta.h"
 #include "radv_private.h"
@@ -2040,6 +2041,14 @@ radv_shader_binary_upload(struct radv_device *device, const struct radv_shader_b
 
    dest_ptr = shader->alloc->arena->ptr + shader->alloc->offset;
 
+   if (device->thread_trace.bo) {
+      shader->code = calloc(shader->code_size, 1);
+      if (!shader->code) {
+         radv_shader_unref(device, shader);
+         return false;
+      }
+   }
+
    if (binary->type == RADV_BINARY_TYPE_RTLD) {
 #if !defined(USE_LIBELF)
       return false;
@@ -2063,8 +2072,14 @@ radv_shader_binary_upload(struct radv_device *device, const struct radv_shader_b
          return false;
       }
 
-      shader->code_ptr = dest_ptr;
       ac_rtld_close(&rtld_binary);
+
+      if (shader->code) {
+         /* Instead of running RTLD twice, just copy the relocated binary back from VRAM.
+          * Use streaming memcpy to reduce penalty of copying from uncachable memory.
+          */
+         util_streaming_load_memcpy(shader->code, dest_ptr, shader->code_size);
+      }
 #endif
    } else {
       struct radv_shader_binary_legacy *bin = (struct radv_shader_binary_legacy *)binary;
@@ -2075,7 +2090,9 @@ radv_shader_binary_upload(struct radv_device *device, const struct radv_shader_b
       for (unsigned i = 0; i < DEBUGGER_NUM_MARKERS; i++)
          ptr32[i] = DEBUGGER_END_OF_CODE_MARKER;
 
-      shader->code_ptr = dest_ptr;
+      if (shader->code) {
+         memcpy(shader->code, bin->data + bin->stats_size, bin->code_size);
+      }
    }
 
    return true;
@@ -2667,6 +2684,7 @@ radv_shader_destroy(struct radv_device *device, struct radv_shader *shader)
 
    radv_free_shader_memory(device, shader->alloc);
 
+   free(shader->code);
    free(shader->spirv);
    free(shader->nir_string);
    free(shader->disasm_string);
index c36c18f..cc07443 100644 (file)
@@ -492,11 +492,13 @@ struct radv_shader {
    uint64_t va;
 
    struct ac_shader_config config;
-   uint8_t *code_ptr;
    uint32_t code_size;
    uint32_t exec_size;
    struct radv_shader_info info;
 
+   /* sqtt only */
+   void *code;
+
    /* debug only */
    char *spirv;
    uint32_t spirv_size;