From d5efa766aa5fad4a56f66412c1c3dea5853f13b2 Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Tue, 6 Nov 2018 12:42:11 +0100 Subject: [PATCH] vrend: Add possibility for the guest to add debug flags For this to work to host will have to add "guestallow" to the debug flags. Reviewed-by: Gurchetan Singh Tested-by: Jakob Bornecrantz Signed-off-by: Gert Wollny Signed-off-by: Jakob Bornecrantz --- src/virgl_hw.h | 1 + src/virgl_protocol.h | 9 ++++++++- src/vrend_debug.c | 25 +++++++++++++++++++++++++ src/vrend_debug.h | 7 +++++++ src/vrend_decode.c | 29 +++++++++++++++++++++++++++++ src/vrend_renderer.c | 12 ++++++++++++ 6 files changed, 82 insertions(+), 1 deletion(-) diff --git a/src/virgl_hw.h b/src/virgl_hw.h index 7736ceb..e682c75 100644 --- a/src/virgl_hw.h +++ b/src/virgl_hw.h @@ -231,6 +231,7 @@ enum virgl_formats { #define VIRGL_CAP_SHADER_CLOCK (1 << 11) #define VIRGL_CAP_TEXTURE_BARRIER (1 << 12) #define VIRGL_CAP_TGSI_COMPONENTS (1 << 13) +#define VIRGL_CAP_GUEST_MAY_INIT_LOG (1 << 14) /* virgl bind flags - these are compatible with mesa 10.5 gallium. * but are fixed, no other should be passed to virgl either. diff --git a/src/virgl_protocol.h b/src/virgl_protocol.h index 9228a0d..d4babad 100644 --- a/src/virgl_protocol.h +++ b/src/virgl_protocol.h @@ -23,6 +23,8 @@ #ifndef VIRGL_PROTOCOL_H #define VIRGL_PROTOCOL_H +#include + #define VIRGL_QUERY_STATE_NEW 0 #define VIRGL_QUERY_STATE_DONE 1 #define VIRGL_QUERY_STATE_WAIT_HOST 2 @@ -94,7 +96,8 @@ enum virgl_context_cmd { VIRGL_CCMD_SET_FRAMEBUFFER_STATE_NO_ATTACH, VIRGL_CCMD_TEXTURE_BARRIER, VIRGL_CCMD_SET_ATOMIC_BUFFERS, - VIRGL_MAX_COMMANDS, + VIRGL_CCMD_SET_DEBUG_FLAGS, + VIRGL_MAX_COMMANDS }; /* @@ -556,4 +559,8 @@ enum virgl_context_cmd { #define VIRGL_SET_ATOMIC_BUFFER_LENGTH(x) ((x) * VIRGL_SET_ATOMIC_BUFFER_ELEMENT_SIZE + 3) #define VIRGL_SET_ATOMIC_BUFFER_RES_HANDLE(x) ((x) * VIRGL_SET_ATOMIC_BUFFER_ELEMENT_SIZE + 4) +/* set debug flags */ +#define VIRGL_SET_DEBUG_FLAGS_MIN_SIZE 2 +#define VIRGL_SET_DEBUG_FLAGSTRING_OFFSET 1 + #endif diff --git a/src/vrend_debug.c b/src/vrend_debug.c index d6e58c3..316c67c 100644 --- a/src/vrend_debug.c +++ b/src/vrend_debug.c @@ -112,11 +112,31 @@ static const struct debug_named_value vrend_debug_options[] = { {"copyres", dbg_copy_resource, "Debug copy resource code path"}, {"feat", dbg_features, "Log features found"}, {"tex", dbg_tex, "Log texture operations"}, + {"guestallow", dbg_allow_guest_override, "Allow the guest to override the debug flags"}, DEBUG_NAMED_VALUE_END }; static uint64_t vrend_debug_flags = 0; static int vrend_debug_flags_initalized = 0; + +int vrend_get_debug_flags(const char *flagstring) +{ + int retval; + char buf[1024] = ""; + + /* Unfortunately the available function to scan the flags take the string + * from the environment. The alternative to using setenv would be to + * duplicate code or to change the gallium/util intefaces and diverge more + * from mesa. So just stick to the environment variable. */ + snprintf(buf, 1024, "VREND_TEMP_DEBUG_STRING_%d", getpid()); + setenv(buf, flagstring, 1); + + retval = (int)debug_get_flags_option(buf, + vrend_debug_options, 0); + unsetenv(buf); + return retval; +} + void vrend_init_debug_flags() { if (!vrend_debug_flags_initalized) { @@ -135,3 +155,8 @@ void vrend_debug_add_flag(enum virgl_debug_flags flag) { vrend_debug_flags |= flag; } + +int vrend_debug_can_override(void) +{ + return vrend_debug_flags & dbg_allow_guest_override; +} diff --git a/src/vrend_debug.h b/src/vrend_debug.h index 54d176b..f5b1440 100644 --- a/src/vrend_debug.h +++ b/src/vrend_debug.h @@ -41,6 +41,7 @@ enum virgl_debug_flags { dbg_copy_resource = 1 << 6, dbg_features = 1 << 7, dbg_tex = 1 << 8, + dbg_allow_guest_override = 1 << 16, dbg_feature_use = 1 << 17, }; @@ -51,6 +52,12 @@ const char *vrend_get_object_type_name(enum virgl_object_type cmd); void vrend_init_debug_flags(void); +int vrend_debug_can_override(void); + +int vrend_get_debug_flags(const char *flagstring); + +void vrend_context_set_debug_flags(struct vrend_context *ctx, const char *flags); + unsigned vrend_debug(struct vrend_context *ctx, enum virgl_debug_flags flag); void vrend_debug_add_flag(enum virgl_debug_flags flag); diff --git a/src/vrend_decode.c b/src/vrend_decode.c index 42e54c0..909c754 100644 --- a/src/vrend_decode.c +++ b/src/vrend_decode.c @@ -1262,6 +1262,32 @@ static int vrend_decode_texture_barrier(struct vrend_decode_ctx *ctx, uint16_t l return 0; } +static int vrend_decode_set_debug_mask(struct vrend_decode_ctx *ctx, int length) +{ + char *flagstring; + int slen = sizeof(uint32_t) * length; + uint32_t *buf; + + if (length < VIRGL_SET_DEBUG_FLAGS_MIN_SIZE) + return EINVAL; + + buf = get_buf_ptr(ctx, VIRGL_SET_DEBUG_FLAGSTRING_OFFSET); + flagstring = malloc(slen+1); + + if (!flagstring) { + return ENOMEM; + } + + memcpy(flagstring, buf, slen); + flagstring[slen] = 0; + vrend_context_set_debug_flags(ctx->grctx, flagstring); + + free(flagstring); + + return 0; +} + + void vrend_renderer_context_create_internal(uint32_t handle, uint32_t nlen, const char *debug_name) { @@ -1493,6 +1519,9 @@ int vrend_decode_block(uint32_t ctx_id, uint32_t *block, int ndw) case VIRGL_CCMD_TEXTURE_BARRIER: ret = vrend_decode_texture_barrier(gdctx, len); break; + case VIRGL_CCMD_SET_DEBUG_FLAGS: + ret = vrend_decode_set_debug_mask(gdctx, len); + break; default: ret = EINVAL; } diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c index 037eb91..d147cd5 100644 --- a/src/vrend_renderer.c +++ b/src/vrend_renderer.c @@ -8402,6 +8402,9 @@ static void vrend_renderer_fill_caps_v2(int gl_ver, int gles_ver, union virgl_c * of the caps setting */ if (vrend_debug(NULL, dbg_features)) vrend_debug_add_flag(dbg_feature_use); + + /* always enable, only indicates that the CMD is supported */ + caps->v2.capability_bits |= VIRGL_CAP_GUEST_MAY_INIT_LOG; } void vrend_renderer_fill_caps(uint32_t set, UNUSED uint32_t version, @@ -8611,6 +8614,15 @@ static struct vrend_resource *vrend_renderer_ctx_res_lookup(struct vrend_context return res; } +void vrend_context_set_debug_flags(struct vrend_context *ctx, const char *flagstring) +{ + if (vrend_debug_can_override()) { + ctx->debug_flags |= vrend_get_debug_flags(flagstring); + if (ctx->debug_flags & dbg_features) + vrend_debug_add_flag(dbg_feature_use); + } +} + int vrend_renderer_resource_get_info(int res_handle, struct vrend_renderer_resource_info *info) {