mojoshader.c
changeset 1104 9147482e1ec7
parent 1103 8b7c29c019d5
child 1106 2bef26cc20f9
equal deleted inserted replaced
1103:8b7c29c019d5 1104:9147482e1ec7
    87     const uint32 *orig_tokens;
    87     const uint32 *orig_tokens;
    88     const uint32 *tokens;
    88     const uint32 *tokens;
    89     uint32 tokencount;
    89     uint32 tokencount;
    90     const MOJOSHADER_swizzle *swizzles;
    90     const MOJOSHADER_swizzle *swizzles;
    91     unsigned int swizzles_count;
    91     unsigned int swizzles_count;
       
    92     const MOJOSHADER_samplerMap *samplermap;
       
    93     unsigned int samplermap_count;
    92     Buffer *output;
    94     Buffer *output;
    93     Buffer *preflight;
    95     Buffer *preflight;
    94     Buffer *globals;
    96     Buffer *globals;
    95     Buffer *helpers;
    97     Buffer *helpers;
    96     Buffer *subroutines;
    98     Buffer *subroutines;
   485             end += 2;
   487             end += 2;
   486         *end = '\0';  // chop extra '0' or all decimal places off.
   488         *end = '\0';  // chop extra '0' or all decimal places off.
   487     } // else
   489     } // else
   488 } // floatstr
   490 } // floatstr
   489 
   491 
       
   492 static inline TextureType cvtMojoToD3DSamplerType(const MOJOSHADER_samplerType type)
       
   493 {
       
   494     return (TextureType) (((int) type) + 2);
       
   495 } // cvtMojoToD3DSamplerType
       
   496 
       
   497 static inline MOJOSHADER_samplerType cvtD3DToMojoSamplerType(const TextureType type)
       
   498 {
       
   499     return (MOJOSHADER_samplerType) (((int) type) - 2);
       
   500 } // cvtD3DToMojoSamplerType
       
   501 
   490 
   502 
   491 // Deal with register lists...  !!! FIXME: I sort of hate this.
   503 // Deal with register lists...  !!! FIXME: I sort of hate this.
   492 
   504 
   493 static void free_reglist(MOJOSHADER_free f, void *d, RegisterList *item)
   505 static void free_reglist(MOJOSHADER_free f, void *d, RegisterList *item)
   494 {
   506 {
   625         ctx->uses_pointsize = 1;  // note that we have to check this later.
   637         ctx->uses_pointsize = 1;  // note that we have to check this later.
   626     else if ((rtype == REG_TYPE_OUTPUT) && (usage == MOJOSHADER_USAGE_FOG))
   638     else if ((rtype == REG_TYPE_OUTPUT) && (usage == MOJOSHADER_USAGE_FOG))
   627         ctx->uses_fog = 1;  // note that we have to check this later.
   639         ctx->uses_fog = 1;  // note that we have to check this later.
   628 } // add_attribute_register
   640 } // add_attribute_register
   629 
   641 
   630 static inline void add_sampler(Context *ctx, const RegisterType rtype,
   642 static inline void add_sampler(Context *ctx, const int regnum,
   631                                const int regnum, const TextureType ttype,
   643                                TextureType ttype, const int texbem)
   632                                const int texbem)
   644 {
   633 {
   645     const RegisterType rtype = REG_TYPE_SAMPLER;
       
   646 
   634     // !!! FIXME: make sure it doesn't exist?
   647     // !!! FIXME: make sure it doesn't exist?
   635     // !!! FIXME:  (ps_1_1 assume we can add it multiple times...)
   648     // !!! FIXME:  (ps_1_1 assume we can add it multiple times...)
   636     RegisterList *item = reglist_insert(ctx, &ctx->samplers, rtype, regnum);
   649     RegisterList *item = reglist_insert(ctx, &ctx->samplers, rtype, regnum);
       
   650 
       
   651     if (ctx->samplermap != NULL)
       
   652     {
       
   653         unsigned int i;
       
   654         for (i = 0; i < ctx->samplermap_count; i++)
       
   655         {
       
   656             if (ctx->samplermap[i].index == regnum)
       
   657             {
       
   658                 ttype = cvtMojoToD3DSamplerType(ctx->samplermap[i].type);
       
   659                 break;
       
   660             } // if
       
   661         } // for
       
   662     } // if
       
   663 
   637     item->index = (int) ttype;
   664     item->index = (int) ttype;
   638     item->misc |= texbem;
   665     item->misc |= texbem;
   639 } // add_sampler
   666 } // add_sampler
   640 
   667 
   641 
   668 
  7009     } // if
  7036     } // if
  7010 
  7037 
  7011     else if (shader_is_pixel(ctx))
  7038     else if (shader_is_pixel(ctx))
  7012     {
  7039     {
  7013         if (regtype == REG_TYPE_SAMPLER)
  7040         if (regtype == REG_TYPE_SAMPLER)
  7014             add_sampler(ctx, regtype, regnum, (TextureType) ctx->dwords[0], 0);
  7041             add_sampler(ctx, regnum, (TextureType) ctx->dwords[0], 0);
  7015         else
  7042         else
  7016         {
  7043         {
  7017             const MOJOSHADER_usage usage = (MOJOSHADER_usage) ctx->dwords[0];
  7044             const MOJOSHADER_usage usage = (MOJOSHADER_usage) ctx->dwords[0];
  7018             const int index = ctx->dwords[1];
  7045             const int index = ctx->dwords[1];
  7019             add_attribute_register(ctx, regtype, regnum, usage, index, wmask, mods);
  7046             add_attribute_register(ctx, regtype, regnum, usage, index, wmask, mods);
  7436         failf(ctx, "%s dest must be a higher register than source", opcode);
  7463         failf(ctx, "%s dest must be a higher register than source", opcode);
  7437 
  7464 
  7438     if (dims)
  7465     if (dims)
  7439     {
  7466     {
  7440         TextureType ttyp = (dims == 2) ? TEXTURE_TYPE_2D : TEXTURE_TYPE_VOLUME;
  7467         TextureType ttyp = (dims == 2) ? TEXTURE_TYPE_2D : TEXTURE_TYPE_VOLUME;
  7441         add_sampler(ctx, REG_TYPE_SAMPLER, dst->regnum, ttyp, texbem);
  7468         add_sampler(ctx, dst->regnum, ttyp, texbem);
  7442     } // if
  7469     } // if
  7443 
  7470 
  7444     add_attribute_register(ctx, REG_TYPE_TEXTURE, dst->regnum,
  7471     add_attribute_register(ctx, REG_TYPE_TEXTURE, dst->regnum,
  7445                            MOJOSHADER_USAGE_TEXCOORD, dst->regnum, 0xF, 0);
  7472                            MOJOSHADER_USAGE_TEXCOORD, dst->regnum, 0xF, 0);
  7446 
  7473 
  7623         // !!! FIXME: checks for ps_1_4 version here...
  7650         // !!! FIXME: checks for ps_1_4 version here...
  7624     } // else if
  7651     } // else if
  7625 
  7652 
  7626     else
  7653     else
  7627     {
  7654     {
  7628         // !!! FIXME: cubemaps? can you do that in ps_1_1?
       
  7629         // !!! FIXME: add (other?) checks for ps_1_1 version here...
  7655         // !!! FIXME: add (other?) checks for ps_1_1 version here...
  7630         const DestArgInfo *info = &ctx->dest_arg;
  7656         const DestArgInfo *info = &ctx->dest_arg;
  7631         const int sampler = info->regnum;
  7657         const int sampler = info->regnum;
  7632         if (info->regtype != REG_TYPE_TEXTURE)
  7658         if (info->regtype != REG_TYPE_TEXTURE)
  7633             fail(ctx, "TEX param must be a texture register");
  7659             fail(ctx, "TEX param must be a texture register");
  7634         add_sampler(ctx, REG_TYPE_SAMPLER, sampler, TEXTURE_TYPE_2D, 0);
  7660         add_sampler(ctx, sampler, TEXTURE_TYPE_2D, 0);
  7635         add_attribute_register(ctx, REG_TYPE_TEXTURE, sampler,
  7661         add_attribute_register(ctx, REG_TYPE_TEXTURE, sampler,
  7636                                MOJOSHADER_USAGE_TEXCOORD, sampler, 0xF, 0);
  7662                                MOJOSHADER_USAGE_TEXCOORD, sampler, 0xF, 0);
  7637     } // else
  7663     } // else
  7638 } // state_TEXLD
  7664 } // state_TEXLD
  7639 
  7665 
  8488 static Context *build_context(const char *profile,
  8514 static Context *build_context(const char *profile,
  8489                               const unsigned char *tokenbuf,
  8515                               const unsigned char *tokenbuf,
  8490                               const unsigned int bufsize,
  8516                               const unsigned int bufsize,
  8491                               const MOJOSHADER_swizzle *swiz,
  8517                               const MOJOSHADER_swizzle *swiz,
  8492                               const unsigned int swizcount,
  8518                               const unsigned int swizcount,
       
  8519                               const MOJOSHADER_samplerMap *smap,
       
  8520                               const unsigned int smapcount,
  8493                               MOJOSHADER_malloc m, MOJOSHADER_free f, void *d)
  8521                               MOJOSHADER_malloc m, MOJOSHADER_free f, void *d)
  8494 {
  8522 {
  8495     if (m == NULL) m = MOJOSHADER_internal_malloc;
  8523     if (m == NULL) m = MOJOSHADER_internal_malloc;
  8496     if (f == NULL) f = MOJOSHADER_internal_free;
  8524     if (f == NULL) f = MOJOSHADER_internal_free;
  8497 
  8525 
  8506     ctx->tokens = (const uint32 *) tokenbuf;
  8534     ctx->tokens = (const uint32 *) tokenbuf;
  8507     ctx->orig_tokens = (const uint32 *) tokenbuf;
  8535     ctx->orig_tokens = (const uint32 *) tokenbuf;
  8508     ctx->tokencount = bufsize / sizeof (uint32);
  8536     ctx->tokencount = bufsize / sizeof (uint32);
  8509     ctx->swizzles = swiz;
  8537     ctx->swizzles = swiz;
  8510     ctx->swizzles_count = swizcount;
  8538     ctx->swizzles_count = swizcount;
       
  8539     ctx->samplermap = smap;
       
  8540     ctx->samplermap_count = smapcount;
  8511     ctx->endline = ENDLINE_STR;
  8541     ctx->endline = ENDLINE_STR;
  8512     ctx->endline_len = strlen(ctx->endline);
  8542     ctx->endline_len = strlen(ctx->endline);
  8513     ctx->last_address_reg_component = -1;
  8543     ctx->last_address_reg_component = -1;
  8514     ctx->current_position = MOJOSHADER_POSITION_BEFORE;
  8544     ctx->current_position = MOJOSHADER_POSITION_BEFORE;
  8515     ctx->texm3x2pad_dst0 = -1;
  8545     ctx->texm3x2pad_dst0 = -1;
  8777     MOJOSHADER_sampler *retval = (MOJOSHADER_sampler *) Malloc(ctx, len);
  8807     MOJOSHADER_sampler *retval = (MOJOSHADER_sampler *) Malloc(ctx, len);
  8778 
  8808 
  8779     if (retval != NULL)
  8809     if (retval != NULL)
  8780     {
  8810     {
  8781         RegisterList *item = ctx->samplers.next;
  8811         RegisterList *item = ctx->samplers.next;
  8782         MOJOSHADER_samplerType type = MOJOSHADER_SAMPLER_2D;
       
  8783         int i;
  8812         int i;
  8784 
  8813 
  8785         memset(retval, '\0', len);
  8814         memset(retval, '\0', len);
  8786 
  8815 
  8787         for (i = 0; i < ctx->sampler_count; i++)
  8816         for (i = 0; i < ctx->sampler_count; i++)
  8791                 fail(ctx, "BUG: mismatched sampler list and count");
  8820                 fail(ctx, "BUG: mismatched sampler list and count");
  8792                 break;
  8821                 break;
  8793             } // if
  8822             } // if
  8794 
  8823 
  8795             assert(item->regtype == REG_TYPE_SAMPLER);
  8824             assert(item->regtype == REG_TYPE_SAMPLER);
  8796             switch ((const TextureType) item->index)
  8825             retval[i].type = cvtD3DToMojoSamplerType((TextureType) item->index);
  8797             {
       
  8798                 case TEXTURE_TYPE_2D:
       
  8799                     type = MOJOSHADER_SAMPLER_2D;
       
  8800                     break;
       
  8801 
       
  8802                 case TEXTURE_TYPE_CUBE:
       
  8803                     type = MOJOSHADER_SAMPLER_CUBE;
       
  8804                     break;
       
  8805 
       
  8806                 case TEXTURE_TYPE_VOLUME:
       
  8807                     type = MOJOSHADER_SAMPLER_VOLUME;
       
  8808                     break;
       
  8809 
       
  8810                 default:
       
  8811                     fail(ctx, "Unknown sampler type");
       
  8812                     break;
       
  8813             } // switch
       
  8814 
       
  8815             retval[i].type = type;
       
  8816             retval[i].index = item->regnum;
  8826             retval[i].index = item->regnum;
  8817             retval[i].name = alloc_varname(ctx, item);
  8827             retval[i].name = alloc_varname(ctx, item);
  8818             retval[i].texbem = (item->misc != 0) ? 1 : 0;
  8828             retval[i].texbem = (item->misc != 0) ? 1 : 0;
  8819             item = item->next;
  8829             item = item->next;
  8820         } // for
  8830         } // for
  9283 const MOJOSHADER_parseData *MOJOSHADER_parse(const char *profile,
  9293 const MOJOSHADER_parseData *MOJOSHADER_parse(const char *profile,
  9284                                              const unsigned char *tokenbuf,
  9294                                              const unsigned char *tokenbuf,
  9285                                              const unsigned int bufsize,
  9295                                              const unsigned int bufsize,
  9286                                              const MOJOSHADER_swizzle *swiz,
  9296                                              const MOJOSHADER_swizzle *swiz,
  9287                                              const unsigned int swizcount,
  9297                                              const unsigned int swizcount,
       
  9298                                              const MOJOSHADER_samplerMap *smap,
       
  9299                                              const unsigned int smapcount,
  9288                                              MOJOSHADER_malloc m,
  9300                                              MOJOSHADER_malloc m,
  9289                                              MOJOSHADER_free f, void *d)
  9301                                              MOJOSHADER_free f, void *d)
  9290 {
  9302 {
  9291     MOJOSHADER_parseData *retval = NULL;
  9303     MOJOSHADER_parseData *retval = NULL;
  9292     Context *ctx = NULL;
  9304     Context *ctx = NULL;
  9294     int failed = 0;
  9306     int failed = 0;
  9295 
  9307 
  9296     if ( ((m == NULL) && (f != NULL)) || ((m != NULL) && (f == NULL)) )
  9308     if ( ((m == NULL) && (f != NULL)) || ((m != NULL) && (f == NULL)) )
  9297         return &MOJOSHADER_out_of_mem_data;  // supply both or neither.
  9309         return &MOJOSHADER_out_of_mem_data;  // supply both or neither.
  9298 
  9310 
  9299     ctx = build_context(profile, tokenbuf, bufsize, swiz, swizcount, m, f, d);
  9311     ctx = build_context(profile, tokenbuf, bufsize, swiz, swizcount,
       
  9312                         smap, smapcount, m, f, d);
  9300     if (ctx == NULL)
  9313     if (ctx == NULL)
  9301         return &MOJOSHADER_out_of_mem_data;
  9314         return &MOJOSHADER_out_of_mem_data;
  9302 	
  9315 	
  9303     if (isfail(ctx))
  9316     if (isfail(ctx))
  9304     {
  9317     {