Mesa (main): virgl: Add support for NIR shaders when VIRGL_DEBUG=nir.
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Oct 6 04:34:01 UTC 2021
Module: Mesa
Branch: main
Commit: 22a332f5acee1c8897fec905407097190c7235a2
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=22a332f5acee1c8897fec905407097190c7235a2
Author: Emma Anholt <emma at anholt.net>
Date: Thu Sep 9 13:13:41 2021 -0700
virgl: Add support for NIR shaders when VIRGL_DEBUG=nir.
This will let me incrementally fix nir-to-tgsi against virgl without
having to carry around the whole "remove TGSI from mesa/st" MR.
Reviewed-by: Gert Wollny <gert.wollny at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12800>
---
src/gallium/drivers/virgl/meson.build | 2 +-
src/gallium/drivers/virgl/virgl_context.c | 30 +++++++++++++++++++++++++++---
src/gallium/drivers/virgl/virgl_screen.c | 22 +++++++++++++++++++---
src/gallium/drivers/virgl/virgl_screen.h | 1 +
4 files changed, 48 insertions(+), 7 deletions(-)
diff --git a/src/gallium/drivers/virgl/meson.build b/src/gallium/drivers/virgl/meson.build
index 6526b3b6e3c..b3adb120719 100644
--- a/src/gallium/drivers/virgl/meson.build
+++ b/src/gallium/drivers/virgl/meson.build
@@ -37,7 +37,7 @@ libvirgl = static_library(
[ files_libvirgl ],
gnu_symbol_visibility : 'hidden',
include_directories : [inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux, inc_virtio],
- dependencies : [dep_libdrm, idep_mesautil, idep_xmlconfig],
+ dependencies : [dep_libdrm, idep_mesautil, idep_xmlconfig, idep_nir],
)
driver_virgl = declare_dependency(
diff --git a/src/gallium/drivers/virgl/virgl_context.c b/src/gallium/drivers/virgl/virgl_context.c
index b90674c1cc5..ee16ea91966 100644
--- a/src/gallium/drivers/virgl/virgl_context.c
+++ b/src/gallium/drivers/virgl/virgl_context.c
@@ -24,10 +24,12 @@
#include <libsync.h>
#include "pipe/p_shader_tokens.h"
+#include "compiler/nir/nir.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
#include "pipe/p_state.h"
+#include "nir/nir_to_tgsi.h"
#include "util/u_draw.h"
#include "util/u_inlines.h"
#include "util/u_memory.h"
@@ -680,10 +682,19 @@ static void *virgl_shader_encoder(struct pipe_context *ctx,
{
struct virgl_context *vctx = virgl_context(ctx);
uint32_t handle;
+ const struct tgsi_token *tokens;
+ const struct tgsi_token *ntt_tokens = NULL;
struct tgsi_token *new_tokens;
int ret;
- new_tokens = virgl_tgsi_transform((struct virgl_screen *)vctx->base.screen, shader->tokens);
+ if (shader->type == PIPE_SHADER_IR_NIR) {
+ nir_shader *s = nir_shader_clone(NULL, shader->ir.nir);
+ ntt_tokens = tokens = nir_to_tgsi(s, vctx->base.screen); /* takes ownership */
+ } else {
+ tokens = shader->tokens;
+ }
+
+ new_tokens = virgl_tgsi_transform((struct virgl_screen *)vctx->base.screen, tokens);
if (!new_tokens)
return NULL;
@@ -693,9 +704,11 @@ static void *virgl_shader_encoder(struct pipe_context *ctx,
&shader->stream_output, 0,
new_tokens);
if (ret) {
+ FREE((void *)ntt_tokens);
return NULL;
}
+ FREE((void *)ntt_tokens);
FREE(new_tokens);
return (void *)(unsigned long)handle;
@@ -1353,19 +1366,30 @@ static void *virgl_create_compute_state(struct pipe_context *ctx,
{
struct virgl_context *vctx = virgl_context(ctx);
uint32_t handle;
- const struct tgsi_token *new_tokens = state->prog;
+ const struct tgsi_token *ntt_tokens = NULL;
+ const struct tgsi_token *tokens;
struct pipe_stream_output_info so_info = {};
int ret;
+ if (state->ir_type == PIPE_SHADER_IR_NIR) {
+ nir_shader *s = nir_shader_clone(NULL, state->prog);
+ ntt_tokens = tokens = nir_to_tgsi(s, vctx->base.screen); /* takes ownership */
+ } else {
+ tokens = state->prog;
+ }
+
handle = virgl_object_assign_handle();
ret = virgl_encode_shader_state(vctx, handle, PIPE_SHADER_COMPUTE,
&so_info,
state->req_local_mem,
- new_tokens);
+ tokens);
if (ret) {
+ FREE((void *)ntt_tokens);
return NULL;
}
+ FREE((void *)ntt_tokens);
+
return (void *)(unsigned long)handle;
}
diff --git a/src/gallium/drivers/virgl/virgl_screen.c b/src/gallium/drivers/virgl/virgl_screen.c
index 45b2a14a063..a832f98461d 100644
--- a/src/gallium/drivers/virgl/virgl_screen.c
+++ b/src/gallium/drivers/virgl/virgl_screen.c
@@ -31,6 +31,7 @@
#include "util/xmlconfig.h"
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
+#include "nir/nir_to_tgsi.h"
#include "tgsi/tgsi_exec.h"
@@ -45,6 +46,7 @@ int virgl_debug = 0;
static const struct debug_named_value virgl_debug_options[] = {
{ "verbose", VIRGL_DEBUG_VERBOSE, NULL },
{ "tgsi", VIRGL_DEBUG_TGSI, NULL },
+ { "nir", VIRGL_DEBUG_NIR, NULL },
{ "noemubgra", VIRGL_DEBUG_NO_EMULATE_BGRA, "Disable tweak to emulate BGRA as RGBA on GLES hosts"},
{ "nobgraswz", VIRGL_DEBUG_NO_BGRA_DEST_SWIZZLE,"Disable tweak to swizzle emulated BGRA on GLES hosts" },
{ "sync", VIRGL_DEBUG_SYNC, "Sync after every flush" },
@@ -190,6 +192,7 @@ virgl_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
+ case PIPE_CAP_NIR_IMAGES_AS_DEREF:
return 0;
case PIPE_CAP_QUERY_TIMESTAMP:
return 1;
@@ -425,8 +428,10 @@ virgl_get_shader_param(struct pipe_screen *screen,
return vscreen->caps.caps.v2.max_shader_image_frag_compute;
else
return vscreen->caps.caps.v2.max_shader_image_other_stages;
+ case PIPE_SHADER_CAP_PREFERRED_IR:
+ return (virgl_debug & VIRGL_DEBUG_NIR) ? PIPE_SHADER_IR_NIR : PIPE_SHADER_IR_TGSI;
case PIPE_SHADER_CAP_SUPPORTED_IRS:
- return (1 << PIPE_SHADER_IR_TGSI);
+ return (1 << PIPE_SHADER_IR_TGSI) | ((virgl_debug & VIRGL_DEBUG_NIR) ? (1 << PIPE_SHADER_IR_NIR) : 0);
case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
return vscreen->caps.caps.v2.max_atomic_counters[shader];
case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
@@ -906,13 +911,23 @@ static void virgl_disk_cache_create(struct virgl_screen *screen)
{
const struct build_id_note *note =
build_id_find_nhdr_for_addr(virgl_disk_cache_create);
- assert(note && build_id_length(note) == 20); /* sha1 */
+ unsigned build_id_len = build_id_length(note);
+ assert(note && build_id_len == 20); /* sha1 */
const uint8_t *id_sha1 = build_id_data(note);
assert(id_sha1);
+ struct mesa_sha1 sha1_ctx;
+ _mesa_sha1_init(&sha1_ctx);
+ _mesa_sha1_update(&sha1_ctx, id_sha1, build_id_len);
+
+ uint32_t shader_debug_flags = virgl_debug & VIRGL_DEBUG_NIR;
+ _mesa_sha1_update(&sha1_ctx, &shader_debug_flags, sizeof(shader_debug_flags));
+
+ uint8_t sha1[20];
+ _mesa_sha1_final(&sha1_ctx, sha1);
char timestamp[41];
- _mesa_sha1_format(timestamp, id_sha1);
+ _mesa_sha1_format(timestamp, sha1);
screen->disk_cache = disk_cache_create("virgl", timestamp, 0);
}
@@ -969,6 +984,7 @@ virgl_create_screen(struct virgl_winsys *vws, const struct pipe_screen_config *c
screen->base.get_shader_param = virgl_get_shader_param;
screen->base.get_compute_param = virgl_get_compute_param;
screen->base.get_paramf = virgl_get_paramf;
+ screen->base.get_compiler_options = nir_to_tgsi_get_compiler_options;
screen->base.is_format_supported = virgl_is_format_supported;
screen->base.destroy = virgl_destroy_screen;
screen->base.context_create = virgl_context_create;
diff --git a/src/gallium/drivers/virgl/virgl_screen.h b/src/gallium/drivers/virgl/virgl_screen.h
index a604c6bb431..c44509f3ffb 100644
--- a/src/gallium/drivers/virgl/virgl_screen.h
+++ b/src/gallium/drivers/virgl/virgl_screen.h
@@ -36,6 +36,7 @@ enum virgl_debug_flags {
VIRGL_DEBUG_SYNC = 1 << 4,
VIRGL_DEBUG_XFER = 1 << 5,
VIRGL_DEBUG_NO_COHERENT = 1 << 6,
+ VIRGL_DEBUG_NIR = 1 << 7,
};
extern int virgl_debug;
More information about the mesa-commit
mailing list