From: Marek Olšák <[email protected]> GFX9 hangs instead of writing VM faults to dmesg.
Reviewed-by: Nicolai Hähnle <[email protected]> --- src/gallium/auxiliary/util/u_tests.c | 9 ++++--- src/gallium/auxiliary/util/u_tests.h | 4 +++ src/gallium/drivers/radeon/r600_pipe_common.c | 3 +++ src/gallium/drivers/radeon/r600_pipe_common.h | 3 +++ src/gallium/drivers/radeonsi/si_pipe.c | 37 +++++++++++++++++++++++++++ 5 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/gallium/auxiliary/util/u_tests.c b/src/gallium/auxiliary/util/u_tests.c index 687e511..30eb589 100644 --- a/src/gallium/auxiliary/util/u_tests.c +++ b/src/gallium/auxiliary/util/u_tests.c @@ -390,35 +390,36 @@ null_sampler_view(struct pipe_context *ctx, unsigned tgsi_tex_target) /* Cleanup. */ cso_destroy_context(cso); ctx->delete_vs_state(ctx, vs); ctx->delete_fs_state(ctx, fs); pipe_resource_reference(&cb, NULL); util_report_result_helper(pass, "%s: %s", __func__, tgsi_texture_names[tgsi_tex_target]); } -static void -null_constant_buffer(struct pipe_context *ctx) +void +util_test_constant_buffer(struct pipe_context *ctx, + struct pipe_resource *constbuf) { struct cso_context *cso; struct pipe_resource *cb; void *fs, *vs; bool pass = true; static const float zero[] = {0, 0, 0, 0}; cso = cso_create_context(ctx, 0); cb = util_create_texture2d(ctx->screen, 256, 256, PIPE_FORMAT_R8G8B8A8_UNORM); util_set_common_states_and_clear(cso, ctx, cb); - ctx->set_constant_buffer(ctx, PIPE_SHADER_FRAGMENT, 0, NULL); + pipe_set_constant_buffer(ctx, PIPE_SHADER_FRAGMENT, 0, constbuf); /* Fragment shader. */ { static const char *text = /* I don't like ureg... */ "FRAG\n" "DCL CONST[0]\n" "DCL OUT[0], COLOR\n" "MOV OUT[0], CONST[0]\n" "END\n"; @@ -495,17 +496,17 @@ null_fragment_shader(struct pipe_context *ctx) */ void util_run_tests(struct pipe_screen *screen) { struct pipe_context *ctx = screen->context_create(screen, NULL, 0); null_fragment_shader(ctx); tgsi_vs_window_space_position(ctx); null_sampler_view(ctx, TGSI_TEXTURE_2D); null_sampler_view(ctx, TGSI_TEXTURE_BUFFER); - null_constant_buffer(ctx); + util_test_constant_buffer(ctx, NULL); ctx->destroy(ctx); puts("Done. Exiting.."); exit(0); } diff --git a/src/gallium/auxiliary/util/u_tests.h b/src/gallium/auxiliary/util/u_tests.h index 106b0a0..5ac5d83 100644 --- a/src/gallium/auxiliary/util/u_tests.h +++ b/src/gallium/auxiliary/util/u_tests.h @@ -28,18 +28,22 @@ #ifndef U_TESTS_H #define U_TESTS_H #include "pipe/p_compiler.h" #ifdef __cplusplus extern "C" { #endif struct pipe_screen; +struct pipe_context; +struct pipe_resource; +void util_test_constant_buffer(struct pipe_context *ctx, + struct pipe_resource *constbuf); void util_run_tests(struct pipe_screen *screen); #ifdef __cplusplus } #endif #endif diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c index c33b457..4607e71 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.c +++ b/src/gallium/drivers/radeon/r600_pipe_common.c @@ -702,20 +702,23 @@ static const struct debug_named_value common_debug_options[] = { { "tcs", DBG_TCS, "Print tessellation control shaders" }, { "tes", DBG_TES, "Print tessellation evaluation shaders" }, { "noir", DBG_NO_IR, "Don't print the LLVM IR"}, { "notgsi", DBG_NO_TGSI, "Don't print the TGSI"}, { "noasm", DBG_NO_ASM, "Don't print disassembled shaders"}, { "preoptir", DBG_PREOPT_IR, "Print the LLVM IR before initial optimizations" }, { "checkir", DBG_CHECK_IR, "Enable additional sanity checks on shader IR" }, { "nooptvariant", DBG_NO_OPT_VARIANT, "Disable compiling optimized shader variants." }, { "testdma", DBG_TEST_DMA, "Invoke SDMA tests and exit." }, + { "testvmfaultcp", DBG_TEST_VMFAULT_CP, "Invoke a CP VM fault test and exit." }, + { "testvmfaultsdma", DBG_TEST_VMFAULT_SDMA, "Invoke a SDMA VM fault test and exit." }, + { "testvmfaultshader", DBG_TEST_VMFAULT_SHADER, "Invoke a shader VM fault test and exit." }, /* features */ { "nodma", DBG_NO_ASYNC_DMA, "Disable asynchronous DMA" }, { "nohyperz", DBG_NO_HYPERZ, "Disable Hyper-Z" }, /* GL uses the word INVALIDATE, gallium uses the word DISCARD */ { "noinvalrange", DBG_NO_DISCARD_RANGE, "Disable handling of INVALIDATE_RANGE map flags" }, { "no2d", DBG_NO_2D_TILING, "Disable 2D tiling" }, { "notiling", DBG_NO_TILING, "Disable tiling" }, { "switch_on_eop", DBG_SWITCH_ON_EOP, "Program WD/IA to switch on end-of-packet." }, { "forcedma", DBG_FORCE_DMA, "Use asynchronous DMA for all operations when possible." }, diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index 6a52247..70b2836 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -100,20 +100,23 @@ #define DBG_NO_WC (1llu << 41) #define DBG_CHECK_VM (1llu << 42) #define DBG_NO_DCC (1llu << 43) #define DBG_NO_DCC_CLEAR (1llu << 44) #define DBG_NO_RB_PLUS (1llu << 45) #define DBG_SI_SCHED (1llu << 46) #define DBG_MONOLITHIC_SHADERS (1llu << 47) #define DBG_NO_CE (1llu << 48) #define DBG_UNSAFE_MATH (1llu << 49) #define DBG_NO_DCC_FB (1llu << 50) +#define DBG_TEST_VMFAULT_CP (1llu << 51) +#define DBG_TEST_VMFAULT_SDMA (1llu << 52) +#define DBG_TEST_VMFAULT_SHADER (1llu << 53) #define R600_MAP_BUFFER_ALIGNMENT 64 #define R600_MAX_VIEWPORTS 16 #define SI_MAX_VARIABLE_THREADS_PER_BLOCK 1024 enum r600_coherency { R600_COHERENCY_NONE, /* no cache flushes needed */ R600_COHERENCY_SHADER, R600_COHERENCY_CB_META, diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index c32546f..3b5b111 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -22,20 +22,21 @@ */ #include "si_pipe.h" #include "si_public.h" #include "si_shader_internal.h" #include "sid.h" #include "radeon/radeon_uvd.h" #include "util/u_memory.h" #include "util/u_suballoc.h" +#include "util/u_tests.h" #include "vl/vl_decoder.h" #include "../ddebug/dd_util.h" #define SI_LLVM_DEFAULT_FEATURES \ "+DumpCode,+vgpr-spilling,-fp32-denormals,-xnack" /* * pipe_context */ static void si_destroy_context(struct pipe_context *context) @@ -769,20 +770,51 @@ static void si_handle_env_var_force_family(struct si_screen *sscreen) /* Don't submit any IBs. */ setenv("RADEON_NOOP", "1", 1); return; } } fprintf(stderr, "radeonsi: Unknown family: %s\n", family); exit(1); } +static void si_test_vmfault(struct si_screen *sscreen) +{ + struct pipe_context *ctx = sscreen->b.aux_context; + struct si_context *sctx = (struct si_context *)ctx; + struct pipe_resource *buf = + pipe_buffer_create(&sscreen->b.b, 0, PIPE_USAGE_DEFAULT, 64); + + if (!buf) { + puts("Buffer allocation failed."); + exit(1); + } + + r600_resource(buf)->gpu_address = 0; /* cause a VM fault */ + + if (sscreen->b.debug_flags & DBG_TEST_VMFAULT_CP) { + si_copy_buffer(sctx, buf, buf, 0, 4, 4, 0); + ctx->flush(ctx, NULL, 0); + puts("VM fault test: CP - done."); + } + if (sscreen->b.debug_flags & DBG_TEST_VMFAULT_SDMA) { + sctx->b.dma_clear_buffer(ctx, buf, 0, 4, 0); + ctx->flush(ctx, NULL, 0); + puts("VM fault test: SDMA - done."); + } + if (sscreen->b.debug_flags & DBG_TEST_VMFAULT_SHADER) { + util_test_constant_buffer(ctx, buf); + puts("VM fault test: Shader - done."); + } + exit(0); +} + struct pipe_screen *radeonsi_screen_create(struct radeon_winsys *ws) { struct si_screen *sscreen = CALLOC_STRUCT(si_screen); unsigned num_cpus, num_compiler_threads, i; if (!sscreen) { return NULL; } /* Set functions first. */ @@ -875,12 +907,17 @@ struct pipe_screen *radeonsi_screen_create(struct radeon_winsys *ws) for (i = 0; i < num_compiler_threads; i++) sscreen->tm[i] = si_create_llvm_target_machine(sscreen); /* Create the auxiliary context. This must be done last. */ sscreen->b.aux_context = sscreen->b.b.context_create(&sscreen->b.b, NULL, 0); if (sscreen->b.debug_flags & DBG_TEST_DMA) r600_test_dma(&sscreen->b); + if (sscreen->b.debug_flags & (DBG_TEST_VMFAULT_CP | + DBG_TEST_VMFAULT_SDMA | + DBG_TEST_VMFAULT_SHADER)) + si_test_vmfault(sscreen); + return &sscreen->b.b; } -- 2.7.4 _______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
