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