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@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17344>
This commit is contained in:
Gert Wollny 2022-07-02 10:06:27 +02:00 committed by Marge Bot
parent 198bcf7726
commit bf29ebc0a7
4 changed files with 22 additions and 4 deletions

View File

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

View File

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

View File

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

View File

@ -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.
*/