mojoshader_assembler.c
changeset 1288 259d3bba6b66
parent 1287 c5a53296dbd5
child 1290 2febe5ae83ad
equal deleted inserted replaced
1287:c5a53296dbd5 1288:259d3bba6b66
   126 static inline int isfail(const Context *ctx)
   126 static inline int isfail(const Context *ctx)
   127 {
   127 {
   128     return ctx->isfail;
   128     return ctx->isfail;
   129 } // isfail
   129 } // isfail
   130 
   130 
       
   131 static int vecsize_from_writemask(const uint8 m)
       
   132 {
       
   133     return (m & 1) + ((m >> 1) & 1) + ((m >> 2) & 1) + ((m >> 3) & 1);
       
   134 } // vecsize_from_writemask
       
   135 
       
   136 static void set_dstarg_writemask(DestArgInfo *dst, const uint8 mask)
       
   137 {
       
   138     dst->writemask = mask;
       
   139     dst->writemask0 = ((mask >> 0) & 1);
       
   140     dst->writemask1 = ((mask >> 1) & 1);
       
   141     dst->writemask2 = ((mask >> 2) & 1);
       
   142     dst->writemask3 = ((mask >> 3) & 1);
       
   143 } // set_dstarg_writemask
   131 
   144 
   132 // Shader model version magic...
   145 // Shader model version magic...
   133 
   146 
   134 static inline uint32 ver_ui32(const uint8 major, const uint8 minor)
   147 static inline uint32 ver_ui32(const uint8 major, const uint8 minor)
   135 {
   148 {
   551     // !!! FIXME: can dest registers do relative addressing?
   564     // !!! FIXME: can dest registers do relative addressing?
   552 
   565 
   553     int invalid_writemask = 0;
   566     int invalid_writemask = 0;
   554     if (nexttoken(ctx) != ((Token) '.'))
   567     if (nexttoken(ctx) != ((Token) '.'))
   555     {
   568     {
   556         info->writemask = ctx->default_writemask;
   569         set_dstarg_writemask(info, ctx->default_writemask);
   557         info->writemask0 = ((info->writemask >> 0) & 0x1);
   570         pushback(ctx);  // no explicit writemask; do default mask.
   558         info->writemask1 = ((info->writemask >> 1) & 0x1);
       
   559         info->writemask2 = ((info->writemask >> 2) & 0x1);
       
   560         info->writemask3 = ((info->writemask >> 3) & 0x1);
       
   561         pushback(ctx);  // no explicit writemask; do full mask.
       
   562     } // if
   571     } // if
   563     else if (nexttoken(ctx) != TOKEN_IDENTIFIER)
   572     else if (nexttoken(ctx) != TOKEN_IDENTIFIER)
   564     {
   573     {
   565         invalid_writemask = 1;
   574         invalid_writemask = 1;
   566     } // else if
   575     } // else if
   568     {
   577     {
   569         char tokenbytes[5] = { '\0', '\0', '\0', '\0', '\0' };
   578         char tokenbytes[5] = { '\0', '\0', '\0', '\0', '\0' };
   570         const unsigned int tokenlen = ctx->tokenlen;
   579         const unsigned int tokenlen = ctx->tokenlen;
   571         memcpy(tokenbytes, ctx->token, ((tokenlen < 4) ? tokenlen : 4));
   580         memcpy(tokenbytes, ctx->token, ((tokenlen < 4) ? tokenlen : 4));
   572         char *ptr = tokenbytes;
   581         char *ptr = tokenbytes;
   573 
   582         uint8 writemask = 0;
   574         if ((*ptr == 'r') || (*ptr == 'x')) { info->writemask0 = 1; ptr++; }
   583         if ((*ptr == 'r') || (*ptr == 'x')) { writemask |= (1<<0); ptr++; }
   575         if ((*ptr == 'g') || (*ptr == 'y')) { info->writemask1 = 1; ptr++; }
   584         if ((*ptr == 'g') || (*ptr == 'y')) { writemask |= (1<<1); ptr++; }
   576         if ((*ptr == 'b') || (*ptr == 'z')) { info->writemask2 = 1; ptr++; }
   585         if ((*ptr == 'b') || (*ptr == 'z')) { writemask |= (1<<2); ptr++; }
   577         if ((*ptr == 'a') || (*ptr == 'w')) { info->writemask3 = 1; ptr++; }
   586         if ((*ptr == 'a') || (*ptr == 'w')) { writemask |= (1<<3); ptr++; }
   578 
   587 
   579         if (*ptr != '\0')
   588         if (*ptr != '\0')
   580             invalid_writemask = 1;
   589             invalid_writemask = 1;
   581 
       
   582         info->writemask = ( ((info->writemask0 & 0x1) << 0) |
       
   583                             ((info->writemask1 & 0x1) << 1) |
       
   584                             ((info->writemask2 & 0x1) << 2) |
       
   585                             ((info->writemask3 & 0x1) << 3) );
       
   586 
   590 
   587         // Cg generates code with oDepth.z, and Microsoft's tools accept
   591         // Cg generates code with oDepth.z, and Microsoft's tools accept
   588         //  oFog.x and probably others. For safety's sake, we'll allow
   592         //  oFog.x and probably others. For safety's sake, we'll allow
   589         //  any single channel to be specified and will just wipe out the
   593         //  any single channel to be specified and will just wipe out the
   590         //  writemask as if it wasn't specified at all. More than one
   594         //  writemask as if it wasn't specified at all. More than one
   591         //  channel will be a fail, though.
   595         //  channel will be a fail, though.
   592         if (!invalid_writemask && scalar_register(ctx->shader_type, info->regtype, info->regnum))
   596         if (!invalid_writemask && scalar_register(ctx->shader_type, info->regtype, info->regnum))
   593         {
   597         {
   594             const int numchans = info->writemask0 + info->writemask1 + info->writemask2 + info->writemask3;
   598             const int numchans = vecsize_from_writemask(writemask);
   595             if (numchans != 1)
   599             if (numchans != 1)
   596                 fail(ctx, "Non-scalar writemask specified for scalar register");
   600                 fail(ctx, "Non-scalar writemask specified for scalar register");
   597             info->writemask = 0xF;
   601             writemask = 0xF;
   598             info->writemask0 = info->writemask1 = info->writemask2 = info->writemask3 = 1;
       
   599         } // if
   602         } // if
       
   603 
       
   604         set_dstarg_writemask(info, writemask);
   600     } // else
   605     } // else
   601 
   606 
   602     if (invalid_writemask)
   607     if (invalid_writemask)
   603         fail(ctx, "Invalid writemask");
   608         fail(ctx, "Invalid writemask");
   604 
   609