[Mesa-dev] [PATCH] anv: implement basic VK_AMD_shader_info support
Timothy Arceri
tarceri at itsqueeze.com
Tue Jun 12 05:07:28 UTC 2018
From: Timothy Arceri <tarceri at localhost.localdomain>
For now this just allows an app to query
VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD which for now only returns
shader-db information. This will allow us to use anv with
vkpipeline-db.
We should add shader disassembly in the future so that RenderDoc
can display it, but that will require a bunch of changes as
currently all the helper functions just fprintf everything to
stderr.
---
src/intel/vulkan/anv_device.c | 19 +++-
src/intel/vulkan/anv_extensions.py | 1 +
src/intel/vulkan/anv_pipeline.c | 129 ++++++++++++++++++++++++--
src/intel/vulkan/anv_pipeline_cache.c | 1 +
src/intel/vulkan/anv_private.h | 5 +
5 files changed, 147 insertions(+), 8 deletions(-)
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index b02e1a2749..f140c6e8e5 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -36,6 +36,7 @@
#include "util/debug.h"
#include "util/build_id.h"
#include "util/mesa-sha1.h"
+#include "util/string_buffer.h"
#include "vk_util.h"
#include "common/gen_defines.h"
@@ -43,7 +44,15 @@
static void
compiler_debug_log(void *data, const char *fmt, ...)
-{ }
+{
+ struct _mesa_string_buffer *buf = (struct _mesa_string_buffer *)data;
+ va_list args;
+
+ va_start(args, fmt);
+ _mesa_string_buffer_vprintf(buf, fmt, args);
+ _mesa_string_buffer_printf(buf, "\n");
+ va_end(args);
+}
static void
compiler_perf_log(void *data, const char *fmt, ...)
@@ -1456,6 +1465,8 @@ VkResult anv_CreateDevice(
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);
+ bool store_shader_info = false;
+
struct anv_device_extension_table enabled_extensions = { };
for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
int idx;
@@ -1471,6 +1482,11 @@ VkResult anv_CreateDevice(
if (!physical_device->supported_extensions.extensions[idx])
return vk_error(VK_ERROR_EXTENSION_NOT_PRESENT);
+ if (strcmp(pCreateInfo->ppEnabledExtensionNames[i],
+ VK_AMD_SHADER_INFO_EXTENSION_NAME) == 0) {
+ store_shader_info = true;
+ }
+
enabled_extensions.extensions[idx] = true;
}
@@ -1516,6 +1532,7 @@ VkResult anv_CreateDevice(
device->chipset_id = physical_device->chipset_id;
device->no_hw = physical_device->no_hw;
device->lost = false;
+ device->store_shader_info = store_shader_info;
if (pAllocator)
device->alloc = *pAllocator;
diff --git a/src/intel/vulkan/anv_extensions.py b/src/intel/vulkan/anv_extensions.py
index 8160864685..bcff5e848b 100644
--- a/src/intel/vulkan/anv_extensions.py
+++ b/src/intel/vulkan/anv_extensions.py
@@ -68,6 +68,7 @@ MAX_API_VERSION = None # Computed later
# the those extension strings, then tests dEQP-VK.api.info.instance.extensions
# and dEQP-VK.api.info.device fail due to the duplicated strings.
EXTENSIONS = [
+ Extension('VK_AMD_shader_info', 1, True),
Extension('VK_ANDROID_native_buffer', 5, 'ANDROID'),
Extension('VK_KHR_16bit_storage', 1, 'device->info.gen >= 8'),
Extension('VK_KHR_bind_memory2', 1, True),
diff --git a/src/intel/vulkan/anv_pipeline.c b/src/intel/vulkan/anv_pipeline.c
index 240bde036d..8be349ed19 100644
--- a/src/intel/vulkan/anv_pipeline.c
+++ b/src/intel/vulkan/anv_pipeline.c
@@ -28,6 +28,7 @@
#include <fcntl.h>
#include "util/mesa-sha1.h"
+#include "util/string_buffer.h"
#include "common/gen_l3_config.h"
#include "anv_private.h"
#include "compiler/brw_nir.h"
@@ -81,6 +82,55 @@ void anv_DestroyShaderModule(
vk_free2(&device->alloc, pAllocator, module);
}
+VkResult anv_GetShaderInfoAMD(
+ VkDevice _device,
+ VkPipeline _pipeline,
+ VkShaderStageFlagBits shaderStage,
+ VkShaderInfoTypeAMD infoType,
+ size_t* pInfoSize,
+ void* pInfo)
+{
+ ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline);
+
+ gl_shader_stage stage = vk_to_mesa_shader_stage(shaderStage);
+ struct anv_shader_bin *shader = pipeline->shaders[stage];
+ VkResult result = VK_SUCCESS;
+
+ /* Spec doesn't indicate what to do if the stage is invalid, so just
+ * return no info for this.
+ */
+ if (!shader)
+ return vk_error(VK_ERROR_FEATURE_NOT_PRESENT);
+
+ switch (infoType) {
+ case VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD: {
+ /* Need to include the null terminator. */
+ size_t length = strlen(shader->shader_info) + 1;
+
+ if (!pInfo) {
+ *pInfoSize = length;
+ } else {
+ size_t size = *pInfoSize;
+ *pInfoSize = length;
+
+ memcpy(pInfo, shader->shader_info, MIN2(size, length));
+
+ if (size < length)
+ result = VK_INCOMPLETE;
+ }
+ break;
+ }
+ default:
+ /* VK_SHADER_INFO_TYPE_BINARY_AMD and VK_SHADER_INFO_TYPE_STATISTICS_AMD
+ * are unimplemented.
+ */
+ result = VK_ERROR_FEATURE_NOT_PRESENT;
+ break;
+ }
+
+ return result;
+}
+
#define SPIR_V_MAGIC_NUMBER 0x07230203
static const uint64_t stage_to_debug[] = {
@@ -557,8 +607,12 @@ anv_pipeline_compile_vs(struct anv_pipeline *pipeline,
nir->info.outputs_written,
nir->info.separate_shader);
+ struct _mesa_string_buffer *shader_info = NULL;
+ if (pipeline->device->store_shader_info)
+ shader_info = _mesa_string_buffer_create(mem_ctx, 256);
+
const unsigned *shader_code =
- brw_compile_vs(compiler, NULL, mem_ctx, &key, &prog_data, nir,
+ brw_compile_vs(compiler, shader_info, mem_ctx, &key, &prog_data, nir,
-1, NULL);
if (shader_code == NULL) {
ralloc_free(mem_ctx);
@@ -575,6 +629,13 @@ anv_pipeline_compile_vs(struct anv_pipeline *pipeline,
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
}
+ if (shader_info) {
+ bin->shader_info =
+ vk_alloc(&pipeline->device->alloc, shader_info->length + 1, 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
+ memcpy(bin->shader_info, shader_info->buf, shader_info->length + 1);
+ }
+
ralloc_free(mem_ctx);
}
@@ -720,12 +781,19 @@ anv_pipeline_compile_tcs_tes(struct anv_pipeline *pipeline,
tes_key.inputs_read = tcs_key.outputs_written;
tes_key.patch_inputs_read = tcs_key.patch_outputs_written;
+ struct _mesa_string_buffer *shader_info_tes = NULL;
+ struct _mesa_string_buffer *shader_info_tcs = NULL;
+ if (pipeline->device->store_shader_info) {
+ shader_info_tes = _mesa_string_buffer_create(mem_ctx, 256);
+ shader_info_tcs = _mesa_string_buffer_create(mem_ctx, 256);
+ }
+
const int shader_time_index = -1;
const unsigned *shader_code;
shader_code =
- brw_compile_tcs(compiler, NULL, mem_ctx, &tcs_key, &tcs_prog_data,
- tcs_nir, shader_time_index, NULL);
+ brw_compile_tcs(compiler, shader_info_tcs, mem_ctx, &tcs_key,
+ &tcs_prog_data, tcs_nir, shader_time_index, NULL);
if (shader_code == NULL) {
ralloc_free(mem_ctx);
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
@@ -744,7 +812,7 @@ anv_pipeline_compile_tcs_tes(struct anv_pipeline *pipeline,
}
shader_code =
- brw_compile_tes(compiler, NULL, mem_ctx, &tes_key,
+ brw_compile_tes(compiler, shader_info_tes, mem_ctx, &tes_key,
&tcs_prog_data.base.vue_map, &tes_prog_data, tes_nir,
NULL, shader_time_index, NULL);
if (shader_code == NULL) {
@@ -764,6 +832,20 @@ anv_pipeline_compile_tcs_tes(struct anv_pipeline *pipeline,
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
}
+ if (pipeline->device->store_shader_info) {
+ tcs_bin->shader_info =
+ vk_alloc(&pipeline->device->alloc, shader_info_tcs->length + 1, 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
+ memcpy(tcs_bin->shader_info, shader_info_tcs->buf,
+ shader_info_tcs->length + 1);
+
+ tes_bin->shader_info =
+ vk_alloc(&pipeline->device->alloc, shader_info_tes->length + 1, 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
+ memcpy(tes_bin->shader_info, shader_info_tes->buf,
+ shader_info_tes->length + 1);
+ }
+
ralloc_free(mem_ctx);
}
@@ -826,8 +908,12 @@ anv_pipeline_compile_gs(struct anv_pipeline *pipeline,
nir->info.outputs_written,
nir->info.separate_shader);
+ struct _mesa_string_buffer *shader_info = NULL;
+ if (pipeline->device->store_shader_info)
+ shader_info = _mesa_string_buffer_create(mem_ctx, 256);
+
const unsigned *shader_code =
- brw_compile_gs(compiler, NULL, mem_ctx, &key, &prog_data, nir,
+ brw_compile_gs(compiler, shader_info, mem_ctx, &key, &prog_data, nir,
NULL, -1, NULL);
if (shader_code == NULL) {
ralloc_free(mem_ctx);
@@ -845,6 +931,13 @@ anv_pipeline_compile_gs(struct anv_pipeline *pipeline,
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
}
+ if (shader_info) {
+ bin->shader_info =
+ vk_alloc(&pipeline->device->alloc, shader_info->length + 1, 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
+ memcpy(bin->shader_info, shader_info->buf, shader_info->length + 1);
+ }
+
ralloc_free(mem_ctx);
}
@@ -977,8 +1070,12 @@ anv_pipeline_compile_fs(struct anv_pipeline *pipeline,
anv_fill_binding_table(&prog_data.base, num_rts);
+ struct _mesa_string_buffer *shader_info = NULL;
+ if (pipeline->device->store_shader_info)
+ shader_info = _mesa_string_buffer_create(mem_ctx, 256);
+
const unsigned *shader_code =
- brw_compile_fs(compiler, NULL, mem_ctx, &key, &prog_data, nir,
+ brw_compile_fs(compiler, shader_info, mem_ctx, &key, &prog_data, nir,
NULL, -1, -1, true, false, NULL, NULL);
if (shader_code == NULL) {
ralloc_free(mem_ctx);
@@ -995,6 +1092,13 @@ anv_pipeline_compile_fs(struct anv_pipeline *pipeline,
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
}
+ if (shader_info) {
+ bin->shader_info =
+ vk_alloc(&pipeline->device->alloc, shader_info->length + 1, 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
+ memcpy(bin->shader_info, shader_info->buf, shader_info->length + 1);
+ }
+
ralloc_free(mem_ctx);
}
@@ -1053,8 +1157,12 @@ anv_pipeline_compile_cs(struct anv_pipeline *pipeline,
anv_fill_binding_table(&prog_data.base, 1);
+ struct _mesa_string_buffer *shader_info = NULL;
+ if (pipeline->device->store_shader_info)
+ shader_info = _mesa_string_buffer_create(mem_ctx, 256);
+
const unsigned *shader_code =
- brw_compile_cs(compiler, NULL, mem_ctx, &key, &prog_data, nir,
+ brw_compile_cs(compiler, shader_info, mem_ctx, &key, &prog_data, nir,
-1, NULL);
if (shader_code == NULL) {
ralloc_free(mem_ctx);
@@ -1071,6 +1179,13 @@ anv_pipeline_compile_cs(struct anv_pipeline *pipeline,
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
}
+ if (shader_info) {
+ bin->shader_info =
+ vk_alloc(&pipeline->device->alloc, shader_info->length + 1, 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
+ memcpy(bin->shader_info, shader_info->buf, shader_info->length + 1);
+ }
+
ralloc_free(mem_ctx);
}
diff --git a/src/intel/vulkan/anv_pipeline_cache.c b/src/intel/vulkan/anv_pipeline_cache.c
index 82551e9f81..9865eaa84e 100644
--- a/src/intel/vulkan/anv_pipeline_cache.c
+++ b/src/intel/vulkan/anv_pipeline_cache.c
@@ -89,6 +89,7 @@ anv_shader_bin_destroy(struct anv_device *device,
{
assert(shader->ref_cnt == 0);
anv_state_pool_free(&device->instruction_state_pool, shader->kernel);
+ vk_free(&device->alloc, shader->shader_info);
vk_free(&device->alloc, shader);
}
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index b47420f89e..4d675a64ec 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -980,6 +980,8 @@ struct anv_device {
pthread_mutex_t mutex;
pthread_cond_t queue_submit;
bool lost;
+
+ bool store_shader_info;
};
static inline struct anv_state_pool *
@@ -2296,6 +2298,9 @@ struct anv_shader_bin {
uint32_t prog_data_size;
struct anv_pipeline_bind_map bind_map;
+
+ /* Disassembly/shader information use by VK_AMD_shader_info */
+ char *shader_info;
};
struct anv_shader_bin *
--
2.17.1
More information about the mesa-dev
mailing list