From 5ef758ac583af2fb7160016cde5294d8d286ae70 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 20 Jul 2020 14:52:00 -0400 Subject: [PATCH] Assembler now deals with scalar registers specifying a write mask better. --- mojoshader_assembler.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/mojoshader_assembler.c b/mojoshader_assembler.c index 5315636..c41f7fb 100644 --- a/mojoshader_assembler.c +++ b/mojoshader_assembler.c @@ -550,21 +550,16 @@ static int parse_destination_token(Context *ctx) // !!! FIXME: can dest registers do relative addressing? int invalid_writemask = 0; - int implicit_writemask = 0; if (nexttoken(ctx) != ((Token) '.')) { - implicit_writemask = 1; info->writemask = 0xF; info->writemask0 = info->writemask1 = info->writemask2 = info->writemask3 = 1; pushback(ctx); // no explicit writemask; do full mask. } // if - - // !!! FIXME: Cg generates code with oDepth.z ... this is a bug, I think. - //else if (scalar_register(ctx->shader_type, info->regtype, info->regnum)) - else if ( (scalar_register(ctx->shader_type, info->regtype, info->regnum)) && (info->regtype != REG_TYPE_DEPTHOUT) ) - fail(ctx, "Writemask specified for scalar register"); else if (nexttoken(ctx) != TOKEN_IDENTIFIER) + { invalid_writemask = 1; + } // else if else { char tokenbytes[5] = { '\0', '\0', '\0', '\0', '\0' }; @@ -584,19 +579,25 @@ static int parse_destination_token(Context *ctx) ((info->writemask1 & 0x1) << 1) | ((info->writemask2 & 0x1) << 2) | ((info->writemask3 & 0x1) << 3) ); + + // Cg generates code with oDepth.z, and Microsoft's tools accept + // oFog.x and probably others. For safety's sake, we'll allow + // any single channel to be specified and will just wipe out the + // writemask as if it wasn't specified at all. More than one + // channel will be a fail, though. + if (!invalid_writemask && scalar_register(ctx->shader_type, info->regtype, info->regnum)) + { + const int numchans = info->writemask0 + info->writemask1 + info->writemask2 + info->writemask3; + if (numchans != 1) + fail(ctx, "Non-scalar writemask specified for scalar register"); + info->writemask = 0xF; + info->writemask0 = info->writemask1 = info->writemask2 = info->writemask3 = 1; + } // if } // else if (invalid_writemask) fail(ctx, "Invalid writemask"); - // !!! FIXME: Cg generates code with oDepth.z ... this is a bug, I think. - if (info->regtype == REG_TYPE_DEPTHOUT) - { - if ( (!implicit_writemask) && ((info->writemask0 + info->writemask1 + - info->writemask2 + info->writemask3) > 1) ) - fail(ctx, "Writemask specified for scalar register"); - } // if - info->orig_writemask = info->writemask; if (tokenbuf_overflow(ctx))