Mesa (main): virgl: Submit the TGSI_PROPERTY_SEPARABLE_PROGRAM when the host understands it

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jul 7 10:20:31 UTC 2022


Module: Mesa
Branch: main
Commit: bf29ebc0a79d61c4f12380ba5f9b107ff77b03c0
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=bf29ebc0a79d61c4f12380ba5f9b107ff77b03c0

Author: Gert Wollny <gert.wollny at collabora.com>
Date:   Sat Jul  2 10:06:27 2022 +0200

virgl: Submit the TGSI_PROPERTY_SEPARABLE_PROGRAM when the host understands it

We can't unconditionally support separable shader objects on the host,
so submit the property only if the shader is actually separable, the
host knows about the property, and supports SSO.

Without support for SSOs, the  host can still compile and link the shaders,
it needs to do more  work on interface matching though.

Signed-off-by: Gert Wollny <gert.wollny at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17344>

---

 src/gallium/drivers/virgl/virgl_context.c |  9 +++++++--
 src/gallium/drivers/virgl/virgl_context.h |  3 ++-
 src/gallium/drivers/virgl/virgl_tgsi.c    | 13 ++++++++++++-
 src/virtio/virtio-gpu/virgl_hw.h          |  1 +
 4 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/src/gallium/drivers/virgl/virgl_context.c b/src/gallium/drivers/virgl/virgl_context.c
index b78ca18f15b..c90b3ea7ec8 100644
--- a/src/gallium/drivers/virgl/virgl_context.c
+++ b/src/gallium/drivers/virgl/virgl_context.c
@@ -682,18 +682,23 @@ static void *virgl_shader_encoder(struct pipe_context *ctx,
    const struct tgsi_token *ntt_tokens = NULL;
    struct tgsi_token *new_tokens;
    int ret;
+   bool is_separable = false;
 
    if (shader->type == PIPE_SHADER_IR_NIR) {
       struct nir_to_tgsi_options options = {
          .unoptimized_ra = true
       };
       nir_shader *s = nir_shader_clone(NULL, shader->ir.nir);
+
+      /* Propagare the separable shader property to the host, unless
+       * it is an internal shader - these are marked separable even though they are not. */
+      is_separable = s->info.separate_shader && !s->info.internal;
       ntt_tokens = tokens = nir_to_tgsi_options(s, vctx->base.screen, &options); /* takes ownership */
    } else {
       tokens = shader->tokens;
    }
 
-   new_tokens = virgl_tgsi_transform((struct virgl_screen *)vctx->base.screen, tokens);
+   new_tokens = virgl_tgsi_transform((struct virgl_screen *)vctx->base.screen, tokens, is_separable);
    if (!new_tokens)
       return NULL;
 
@@ -1378,7 +1383,7 @@ static void *virgl_create_compute_state(struct pipe_context *ctx,
       tokens = state->prog;
    }
 
-   void *new_tokens = virgl_tgsi_transform((struct virgl_screen *)vctx->base.screen, tokens);
+   void *new_tokens = virgl_tgsi_transform((struct virgl_screen *)vctx->base.screen, tokens, false);
    if (!new_tokens)
       return NULL;
 
diff --git a/src/gallium/drivers/virgl/virgl_context.h b/src/gallium/drivers/virgl/virgl_context.h
index 924f1a82227..3b6ee900214 100644
--- a/src/gallium/drivers/virgl/virgl_context.h
+++ b/src/gallium/drivers/virgl/virgl_context.h
@@ -127,7 +127,8 @@ void virgl_init_blit_functions(struct virgl_context *vctx);
 void virgl_init_query_functions(struct virgl_context *vctx);
 void virgl_init_so_functions(struct virgl_context *vctx);
 
-struct tgsi_token *virgl_tgsi_transform(struct virgl_screen *vscreen, const struct tgsi_token *tokens_in);
+struct tgsi_token *virgl_tgsi_transform(struct virgl_screen *vscreen, const struct tgsi_token *tokens_in,
+                                        bool is_separable);
 
 bool
 virgl_can_rebind_resource(struct virgl_context *vctx,
diff --git a/src/gallium/drivers/virgl/virgl_tgsi.c b/src/gallium/drivers/virgl/virgl_tgsi.c
index a98a74ea2eb..c4bec480512 100644
--- a/src/gallium/drivers/virgl/virgl_tgsi.c
+++ b/src/gallium/drivers/virgl/virgl_tgsi.c
@@ -59,6 +59,7 @@ struct virgl_transform_context {
    bool cull_enabled;
    bool has_precise;
    bool fake_fp64;
+   bool is_separable;
 
    unsigned next_temp;
 
@@ -186,6 +187,14 @@ virgl_tgsi_transform_prolog(struct tgsi_transform_context * ctx)
 {
    struct virgl_transform_context *vtctx = (struct virgl_transform_context *)ctx;
 
+   if (vtctx->is_separable) {
+      struct tgsi_full_property prop = tgsi_default_full_property();
+      prop.Property.PropertyName = TGSI_PROPERTY_SEPARABLE_PROGRAM;
+      prop.Property.NrTokens += 1;
+      prop.u[0].Data = 1;
+      ctx->emit_property(ctx, &prop);
+   }
+
    vtctx->src_temp = vtctx->next_temp;
    vtctx->next_temp += 4;
    tgsi_transform_temps_decl(ctx, vtctx->src_temp, vtctx->src_temp + 3);
@@ -418,7 +427,8 @@ virgl_tgsi_transform_instruction(struct tgsi_transform_context *ctx,
    }
 }
 
-struct tgsi_token *virgl_tgsi_transform(struct virgl_screen *vscreen, const struct tgsi_token *tokens_in)
+struct tgsi_token *virgl_tgsi_transform(struct virgl_screen *vscreen, const struct tgsi_token *tokens_in,
+                                        bool is_separable)
 {
    struct virgl_transform_context transform;
    const uint newLen = tgsi_num_tokens(tokens_in);
@@ -432,6 +442,7 @@ struct tgsi_token *virgl_tgsi_transform(struct virgl_screen *vscreen, const stru
    transform.has_precise = vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_TGSI_PRECISE;
    transform.fake_fp64 =
       vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_FAKE_FP64;
+   transform.is_separable = is_separable && (vscreen->caps.caps.v2.capability_bits_v2 & VIRGL_CAP_V2_SSO);
 
    for (int i = 0; i < ARRAY_SIZE(transform.input_temp); i++)
       transform.input_temp[i].index = ~0;
diff --git a/src/virtio/virtio-gpu/virgl_hw.h b/src/virtio/virtio-gpu/virgl_hw.h
index 330ee79b020..eafc0b41912 100644
--- a/src/virtio/virtio-gpu/virgl_hw.h
+++ b/src/virtio/virtio-gpu/virgl_hw.h
@@ -445,6 +445,7 @@ enum virgl_formats {
 #define VIRGL_CAP_V2_IMPLICIT_MSAA        (1 << 6)
 #define VIRGL_CAP_V2_COPY_TRANSFER_BOTH_DIRECTIONS (1 << 7)
 #define VIRGL_CAP_V2_SCANOUT_USES_GBM     (1 << 8)
+#define VIRGL_CAP_V2_SSO                  (1 << 9)
 /* virgl bind flags - these are compatible with mesa 10.5 gallium.
  * but are fixed, no other should be passed to virgl either.
  */



More information about the mesa-commit mailing list