From e643cb40a3f762148e4ab79767a2bc7cd49a38a9 Mon Sep 17 00:00:00 2001 From: Emma Anholt Date: Fri, 8 Oct 2021 11:00:26 -0700 Subject: [PATCH] virgl: Move tex immediate operands to a temp to avoid virglrenderer bug. Prior to the noted MR, virglrenderer encoded the tex operands in a limited-size temp buffer which we could easily overflow with TGSI immediates. GLSL-to-TGSI always emitted an extra MOV, so keep that behavior when nir-to-tgsi feeds us more optimized TGSI. Reviewed-by: Gert Wollny Part-of: --- src/gallium/drivers/virgl/virgl_tgsi.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/gallium/drivers/virgl/virgl_tgsi.c b/src/gallium/drivers/virgl/virgl_tgsi.c index 4b71c7e..a473f3d 100644 --- a/src/gallium/drivers/virgl/virgl_tgsi.c +++ b/src/gallium/drivers/virgl/virgl_tgsi.c @@ -56,10 +56,13 @@ struct virgl_transform_context { struct tgsi_transform_context base; bool cull_enabled; bool has_precise; + bool has_textures; bool fake_fp64; unsigned next_temp; + unsigned tex_temp; + unsigned writemask_fixup_outs[5]; unsigned writemask_fixup_temps; unsigned num_writemask_fixups; @@ -125,6 +128,10 @@ virgl_tgsi_transform_declaration(struct tgsi_transform_context *ctx, case TGSI_FILE_TEMPORARY: vtctx->next_temp = MAX2(vtctx->next_temp, decl->Range.Last + 1); break; + case TGSI_FILE_SAMPLER: + case TGSI_FILE_SAMPLER_VIEW: + vtctx->has_textures = true; + break; default: break; } @@ -182,6 +189,11 @@ virgl_tgsi_transform_prolog(struct tgsi_transform_context * ctx) { struct virgl_transform_context *vtctx = (struct virgl_transform_context *)ctx; + if (vtctx->has_textures) { + vtctx->tex_temp = vtctx->next_temp++; + tgsi_transform_temp_decl(ctx, vtctx->tex_temp); + } + if (vtctx->num_writemask_fixups) { vtctx->writemask_fixup_temps = vtctx->next_temp; vtctx->next_temp += vtctx->num_writemask_fixups; @@ -260,6 +272,24 @@ virgl_tgsi_transform_instruction(struct tgsi_transform_context *ctx, if (!vtctx->has_precise && inst->Instruction.Precise) inst->Instruction.Precise = 0; + /* virglrenderer can run out of space in internal buffers for immediates as + * tex operands. Move the first immediate tex arg to a temp to save space in + * the buffer. + * + * https://gitlab.freedesktop.org/virgl/virglrenderer/-/merge_requests/582 + */ + if (tgsi_get_opcode_info(inst->Instruction.Opcode)->is_tex && + inst->Src[0].Register.File == TGSI_FILE_IMMEDIATE) { + assert(vtctx->has_textures); + tgsi_transform_op1_inst(ctx, TGSI_OPCODE_MOV, + TGSI_FILE_TEMPORARY, vtctx->tex_temp, + TGSI_WRITEMASK_XYZW, + inst->Src[0].Register.File, + inst->Src[0].Register.Index); + inst->Src[0].Register.File = TGSI_FILE_TEMPORARY; + inst->Src[0].Register.Index = vtctx->tex_temp; + } + for (unsigned i = 0; i < inst->Instruction.NumDstRegs; i++) { /* virglrenderer would fail to compile on clipdist, clipvertex, and some * two-sided-related color writes without a full writemask. So, we write -- 2.7.4