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@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12800>
This commit is contained in:
Emma Anholt 2021-09-09 13:13:41 -07:00 committed by Marge Bot
parent 4e3e149ffd
commit 22a332f5ac
4 changed files with 48 additions and 7 deletions

View File

@ -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(

View File

@ -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;
}

View File

@ -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;

View File

@ -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;