From 3c9771b434bcc4fc0b65557100e9b6c10cdadefe Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 5 Oct 2022 11:57:39 -0400 Subject: [PATCH] zink: add ZINK_DEBUG=shaderdb this should enable shader-db support with zink Part-of: --- src/gallium/drivers/zink/zink_context.c | 21 +++++ src/gallium/drivers/zink/zink_device_info.py | 1 + src/gallium/drivers/zink/zink_program.c | 96 +++++++++++++++++++- src/gallium/drivers/zink/zink_screen.c | 3 + src/gallium/drivers/zink/zink_types.h | 1 + 5 files changed, 119 insertions(+), 3 deletions(-) diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index a58af193f4e..1febaa2bfd9 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -4845,6 +4845,27 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) if (screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints) VKCTX(CmdSetPatchControlPointsEXT)(ctx->batch.state->cmdbuf, 1); + if (!is_copy_only && zink_debug & ZINK_DEBUG_SHADERDB) { + if (!screen->info.have_EXT_vertex_input_dynamic_state) { + struct pipe_vertex_element velems[32] = {0}; + for (unsigned i = 0; i < ARRAY_SIZE(velems); i++) + velems[i].src_format = PIPE_FORMAT_R8G8B8_UNORM; + void *state = ctx->base.create_vertex_elements_state(&ctx->base, ARRAY_SIZE(velems), velems); + ctx->base.bind_vertex_elements_state(&ctx->base, state); + } + ctx->gfx_pipeline_state.sample_mask = BITFIELD_MASK(32); + struct pipe_framebuffer_state fb = {0}; + fb.cbufs[0] = ctx->dummy_surface[0]; + fb.nr_cbufs = 1; + fb.width = fb.height = 256; + ctx->base.set_framebuffer_state(&ctx->base, &fb); + ctx->disable_color_writes = true; + struct pipe_depth_stencil_alpha_state dsa = {0}; + void *state = ctx->base.create_depth_stencil_alpha_state(&ctx->base, &dsa); + ctx->base.bind_depth_stencil_alpha_state(&ctx->base, state); + zink_batch_rp(ctx); + } + if (!(flags & PIPE_CONTEXT_PREFER_THREADED) || flags & PIPE_CONTEXT_COMPUTE_ONLY) { return &ctx->base; } diff --git a/src/gallium/drivers/zink/zink_device_info.py b/src/gallium/drivers/zink/zink_device_info.py index 1e774a434ff..d71b7fdb29f 100644 --- a/src/gallium/drivers/zink/zink_device_info.py +++ b/src/gallium/drivers/zink/zink_device_info.py @@ -67,6 +67,7 @@ EXTENSIONS = [ Extension("VK_KHR_external_memory"), Extension("VK_KHR_external_memory_fd"), Extension("VK_KHR_vulkan_memory_model"), + Extension("VK_KHR_pipeline_executable_properties", alias="pipestats", features=True), Extension("VK_KHR_external_semaphore_fd"), Extension("VK_KHR_create_renderpass2", required=True), Extension("VK_KHR_synchronization2", diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c index ce8a4054c6c..776092a3e50 100644 --- a/src/gallium/drivers/zink/zink_program.c +++ b/src/gallium/drivers/zink/zink_program.c @@ -1566,6 +1566,87 @@ zink_create_pipeline_lib(struct zink_screen *screen, struct zink_gfx_program *pr return gkey; } +static const char * +print_exe_stages(VkShaderStageFlags stages) +{ + if (stages == VK_SHADER_STAGE_VERTEX_BIT) + return "VS"; + if (stages == (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_GEOMETRY_BIT)) + return "VS+GS"; + if (stages == (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)) + return "VS+TCS+TES"; + if (stages == (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | VK_SHADER_STAGE_GEOMETRY_BIT)) + return "VS+TCS+TES+GS"; + if (stages == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) + return "TCS"; + if (stages == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) + return "TES"; + if (stages == VK_SHADER_STAGE_GEOMETRY_BIT) + return "GS"; + if (stages == VK_SHADER_STAGE_FRAGMENT_BIT) + return "FS"; + if (stages == VK_SHADER_STAGE_COMPUTE_BIT) + return "CS"; + unreachable("unhandled combination of stages!"); +} + +static void +print_pipeline_stats(struct zink_screen *screen, VkPipeline pipeline) +{ + VkPipelineInfoKHR pinfo = { + VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR, + NULL, + pipeline + }; + unsigned exe_count = 0; + VkPipelineExecutablePropertiesKHR props[10] = {0}; + for (unsigned i = 0; i < ARRAY_SIZE(props); i++) { + props[i].sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_PROPERTIES_KHR; + props[i].pNext = NULL; + } + VKSCR(GetPipelineExecutablePropertiesKHR)(screen->dev, &pinfo, &exe_count, NULL); + VKSCR(GetPipelineExecutablePropertiesKHR)(screen->dev, &pinfo, &exe_count, props); + printf("PIPELINE STATISTICS:"); + for (unsigned e = 0; e < exe_count; e++) { + VkPipelineExecutableInfoKHR info = { + VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR, + NULL, + pipeline, + e + }; + unsigned count = 0; + printf("\n\t%s (%s): ", print_exe_stages(props[e].stages), props[e].name); + VkPipelineExecutableStatisticKHR *stats = NULL; + VKSCR(GetPipelineExecutableStatisticsKHR)(screen->dev, &info, &count, NULL); + stats = calloc(count, sizeof(VkPipelineExecutableStatisticKHR)); + for (unsigned i = 0; i < count; i++) + stats[i].sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR; + VKSCR(GetPipelineExecutableStatisticsKHR)(screen->dev, &info, &count, stats); + + for (unsigned i = 0; i < count; i++) { + if (i) + printf(", "); + switch (stats[i].format) { + case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR: + printf("%s: %u", stats[i].name, stats[i].value.b32); + break; + case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_INT64_KHR: + printf("%s: %" PRIi64, stats[i].name, stats[i].value.i64); + break; + case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR: + printf("%s: %" PRIu64, stats[i].name, stats[i].value.u64); + break; + case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_FLOAT64_KHR: + printf("%s: %g", stats[i].name, stats[i].value.f64); + break; + default: + unreachable("unknown statistic"); + } + } + } + printf("\n"); +} + static void precompile_job(void *data, void *gdata, int thread_index) { @@ -1615,8 +1696,17 @@ zink_link_gfx_shader(struct pipe_context *pctx, void **shaders) assert(prog->shaders[i]); _mesa_hash_table_insert_pre_hashed(ht, hash, prog->shaders, prog); simple_mtx_unlock(&ctx->program_lock[zink_program_cache_stages(shader_stages)]); - // precompile_job(prog, ctx, 0); - util_queue_add_job(&zink_screen(pctx->screen)->cache_get_thread, prog, &prog->base.cache_fence, precompile_job, NULL, 0); + if (zink_debug & ZINK_DEBUG_SHADERDB) { + struct zink_screen *screen = zink_screen(pctx->screen); + if (screen->optimal_keys) + generate_gfx_program_modules_optimal(ctx, screen, prog, &ctx->gfx_pipeline_state); + else + generate_gfx_program_modules(ctx, screen, prog, &ctx->gfx_pipeline_state); + VkPipeline pipeline = zink_create_gfx_pipeline(screen, prog, &ctx->gfx_pipeline_state, ctx->gfx_pipeline_state.element_state->binding_map, shaders[MESA_SHADER_TESS_EVAL] ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, true); + print_pipeline_stats(screen, pipeline); + } else { + util_queue_add_job(&zink_screen(pctx->screen)->cache_get_thread, prog, &prog->base.cache_fence, precompile_job, NULL, 0); + } } void @@ -1665,7 +1755,7 @@ zink_program_init(struct zink_context *ctx) STATIC_ASSERT(sizeof(union zink_shader_key_optimal) == sizeof(uint32_t)); - if (zink_screen(ctx->base.screen)->info.have_EXT_graphics_pipeline_library) + if (zink_screen(ctx->base.screen)->info.have_EXT_graphics_pipeline_library || zink_debug & ZINK_DEBUG_SHADERDB) ctx->base.link_shader = zink_link_gfx_shader; } diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index c52edaf73a8..c38a9e98dd2 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -78,6 +78,7 @@ zink_debug_options[] = { { "compact", ZINK_DEBUG_COMPACT, "Use only 4 descriptor sets" }, { "noreorder", ZINK_DEBUG_NOREORDER, "Do not reorder command streams" }, { "gpl", ZINK_DEBUG_GPL, "Force using Graphics Pipeline Library for all shaders" }, + { "shaderdb", ZINK_DEBUG_SHADERDB, "Do stuff to make shader-db work" }, DEBUG_NAMED_VALUE_END }; @@ -205,6 +206,8 @@ get_video_mem(struct zink_screen *screen) static bool disk_cache_init(struct zink_screen *screen) { + if (zink_debug & ZINK_DEBUG_SHADERDB) + return true; #ifdef ENABLE_SHADER_CACHE static char buf[1000]; snprintf(buf, sizeof(buf), "zink_%x04x", screen->info.props.vendorID); diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h index 01b1af15236..7b0817ef0ec 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -187,6 +187,7 @@ enum zink_debug { ZINK_DEBUG_COMPACT = (1<<5), ZINK_DEBUG_NOREORDER = (1<<6), ZINK_DEBUG_GPL = (1<<7), + ZINK_DEBUG_SHADERDB = (1<<8), };