927 { |
930 { |
928 fail(ctx, "Unknown source register type."); |
931 fail(ctx, "Unknown source register type."); |
929 return ""; |
932 return ""; |
930 } // if |
933 } // if |
931 |
934 |
|
935 const char *rel_lbracket = ""; |
|
936 const char *rel_rbracket = ""; |
|
937 char rel_swizzle[4] = { '\0' }; |
|
938 char rel_regnum_str[16] = { '\0' }; |
|
939 const char *rel_regtype_str = ""; |
|
940 if (arg->relative) |
|
941 { |
|
942 rel_swizzle[0] = '.'; |
|
943 rel_swizzle[1] = swizzle_channels[arg->relative_component]; |
|
944 rel_swizzle[2] = '\0'; |
|
945 rel_lbracket = "["; |
|
946 rel_rbracket = "]"; |
|
947 rel_regtype_str = get_D3D_register_string(ctx, arg->relative_regtype, |
|
948 arg->relative_regnum, |
|
949 rel_regnum_str, |
|
950 sizeof (rel_regnum_str)); |
|
951 |
|
952 if (regtype_str == NULL) |
|
953 { |
|
954 fail(ctx, "Unknown relative source register type."); |
|
955 return ""; |
|
956 } // if |
|
957 } // if |
|
958 |
932 char swizzle_str[6]; |
959 char swizzle_str[6]; |
933 int i = 0; |
960 int i = 0; |
934 if (arg->swizzle != 0xE4) // 0xE4 == 11100100 ... 3 2 1 0. No swizzle. |
961 if (arg->swizzle != 0xE4) // 0xE4 == 11100100 ... 3 2 1 0. No swizzle. |
935 { |
962 { |
936 swizzle_str[i++] = '.'; |
963 swizzle_str[i++] = '.'; |
944 i--; |
971 i--; |
945 } // if |
972 } // if |
946 swizzle_str[i] = '\0'; |
973 swizzle_str[i] = '\0'; |
947 assert(i < sizeof (swizzle_str)); |
974 assert(i < sizeof (swizzle_str)); |
948 |
975 |
949 snprintf(buf, buflen, "%s%s%s%s%s", |
976 snprintf(buf, buflen, "%s%s%s%s%s%s%s%s%s%s", |
950 premod_str, regtype_str, regnum_str, postmod_str, swizzle_str); |
977 premod_str, regtype_str, regnum_str, postmod_str, |
|
978 rel_lbracket, rel_regtype_str, rel_regnum_str, rel_swizzle, |
|
979 rel_rbracket, swizzle_str); |
951 // !!! FIXME: make sure the scratch buffer was large enough. |
980 // !!! FIXME: make sure the scratch buffer was large enough. |
952 return buf; |
981 return buf; |
953 } // make_D3D_sourcearg_string_in_buf |
982 } // make_D3D_sourcearg_string_in_buf |
954 |
983 |
955 |
984 |
2941 { |
2970 { |
2942 if (!shader_is_vertex(ctx)) |
2971 if (!shader_is_vertex(ctx)) |
2943 return fail(ctx, "Relative addressing in non-vertex shader"); |
2972 return fail(ctx, "Relative addressing in non-vertex shader"); |
2944 else if (!shader_version_atleast(ctx, 3, 0)) |
2973 else if (!shader_version_atleast(ctx, 3, 0)) |
2945 return fail(ctx, "Relative addressing in vertex shader version < 3.0"); |
2974 return fail(ctx, "Relative addressing in vertex shader version < 3.0"); |
2946 return fail(ctx, "Relative addressing is unsupported"); // !!! FIXME |
2975 // !!! FIXME: I don't have a shader that has a relative dest currently. |
|
2976 return fail(ctx, "Relative addressing of dest tokens is unsupported"); |
2947 } // if |
2977 } // if |
2948 |
2978 |
2949 const int s = info->result_shift; |
2979 const int s = info->result_shift; |
2950 if (s != 0) |
2980 if (s != 0) |
2951 { |
2981 { |
3021 |
3053 |
3022 if (info->relative) |
3054 if (info->relative) |
3023 { |
3055 { |
3024 if ( (shader_is_pixel(ctx)) && (!shader_version_atleast(ctx, 3, 0)) ) |
3056 if ( (shader_is_pixel(ctx)) && (!shader_version_atleast(ctx, 3, 0)) ) |
3025 return fail(ctx, "Relative addressing in pixel shader version < 3.0"); |
3057 return fail(ctx, "Relative addressing in pixel shader version < 3.0"); |
3026 return fail(ctx, "Relative addressing is unsupported"); // !!! FIXME |
3058 |
|
3059 if (ctx->tokencount == 0) |
|
3060 return fail(ctx, "Out of tokens in relative source parameter"); |
|
3061 |
|
3062 const uint32 reltoken = SWAP32(*(ctx->tokens)); |
|
3063 ctx->tokens++; // swallow token for now, for multiple calls in a row. |
|
3064 ctx->tokencount--; // swallow token for now, for multiple calls in a row. |
|
3065 |
|
3066 const int relswiz = (int) ((reltoken >> 16) & 0xFF); |
|
3067 info->relative_component = relswiz & 0x3; |
|
3068 info->relative_regnum = (int) (reltoken & 0x7ff); |
|
3069 info->relative_regtype = (RegisterType) |
|
3070 (((reltoken >> 28) & 0x7) | |
|
3071 ((reltoken >> 8) & 0x18)); |
|
3072 |
|
3073 if (((reltoken >> 31) & 0x1) == 0) |
|
3074 return fail(ctx, "bit #31 in relative address must be set"); |
|
3075 |
|
3076 if ((reltoken & 0xF00E000) != 0) // usused bits. |
|
3077 return fail(ctx, "relative address reserved bit must be zero"); |
|
3078 |
|
3079 switch (info->relative_regtype) |
|
3080 { |
|
3081 case REG_TYPE_LOOP: |
|
3082 case REG_TYPE_ADDRESS: |
|
3083 break; |
|
3084 default: |
|
3085 return fail(ctx, "invalid register for relative address"); |
|
3086 break; |
|
3087 } // switch |
|
3088 |
|
3089 if (info->relative_regnum != 0) // true for now. |
|
3090 return fail(ctx, "invalid register for relative address"); |
|
3091 |
|
3092 switch (info->regtype) |
|
3093 { |
|
3094 case REG_TYPE_CONST: |
|
3095 case REG_TYPE_CONST2: |
|
3096 case REG_TYPE_CONST3: |
|
3097 case REG_TYPE_CONST4: |
|
3098 break; |
|
3099 default: |
|
3100 return fail(ctx, "relative addressing of non-const register"); |
|
3101 break; |
|
3102 } // switch |
|
3103 |
|
3104 if (!replicate_swizzle(relswiz)) |
|
3105 return fail(ctx, "relative address needs replicate swizzle"); |
|
3106 |
|
3107 set_used_register(ctx, info->relative_regtype, info->relative_regnum); |
|
3108 retval++; |
3027 } // if |
3109 } // if |
3028 |
3110 |
3029 if ( info->src_mod >= SRCMOD_TOTAL ) |
3111 if ( info->src_mod >= SRCMOD_TOTAL ) |
3030 return fail(ctx, "Unknown source modifier"); |
3112 return fail(ctx, "Unknown source modifier"); |
3031 |
3113 |
3032 set_used_register(ctx, info->regtype, info->regnum); |
3114 set_used_register(ctx, info->regtype, info->regnum); |
3033 return 1; |
3115 return retval; |
3034 } // parse_source_token |
3116 } // parse_source_token |
3035 |
3117 |
3036 |
3118 |
3037 static int parse_predicated_token(Context *ctx) |
3119 static int parse_predicated_token(Context *ctx) |
3038 { |
3120 { |
3226 } // parse_args_DCL |
3320 } // parse_args_DCL |
3227 |
3321 |
3228 |
3322 |
3229 static int parse_args_D(Context *ctx) |
3323 static int parse_args_D(Context *ctx) |
3230 { |
3324 { |
3231 if (parse_destination_token(ctx, &ctx->dest_args[0]) == FAIL) return FAIL; |
3325 int retval = 1; |
3232 return 2; |
3326 retval += parse_destination_token(ctx, &ctx->dest_args[0]); |
|
3327 return isfail(ctx) ? FAIL : retval; |
3233 } // parse_args_D |
3328 } // parse_args_D |
3234 |
3329 |
3235 |
3330 |
3236 static int parse_args_S(Context *ctx) |
3331 static int parse_args_S(Context *ctx) |
3237 { |
3332 { |
3238 if (parse_source_token(ctx, &ctx->source_args[0]) == FAIL) return FAIL; |
3333 int retval = 1; |
3239 return 2; |
3334 retval += parse_source_token(ctx, &ctx->source_args[0]); |
|
3335 return isfail(ctx) ? FAIL : retval; |
3240 } // parse_args_S |
3336 } // parse_args_S |
3241 |
3337 |
3242 |
3338 |
3243 static int parse_args_SS(Context *ctx) |
3339 static int parse_args_SS(Context *ctx) |
3244 { |
3340 { |
3245 if (parse_source_token(ctx, &ctx->source_args[0]) == FAIL) return FAIL; |
3341 int retval = 1; |
3246 if (parse_source_token(ctx, &ctx->source_args[1]) == FAIL) return FAIL; |
3342 retval += parse_source_token(ctx, &ctx->source_args[0]); |
3247 return 3; |
3343 retval += parse_source_token(ctx, &ctx->source_args[1]); |
|
3344 return isfail(ctx) ? FAIL : retval; |
3248 } // parse_args_SS |
3345 } // parse_args_SS |
3249 |
3346 |
3250 |
3347 |
3251 static int parse_args_DS(Context *ctx) |
3348 static int parse_args_DS(Context *ctx) |
3252 { |
3349 { |
3253 if (parse_destination_token(ctx, &ctx->dest_args[0]) == FAIL) return FAIL; |
3350 int retval = 1; |
3254 if (parse_source_token(ctx, &ctx->source_args[0]) == FAIL) return FAIL; |
3351 retval += parse_destination_token(ctx, &ctx->dest_args[0]); |
3255 return 3; |
3352 retval += parse_source_token(ctx, &ctx->source_args[0]); |
|
3353 return isfail(ctx) ? FAIL : retval; |
3256 } // parse_args_DS |
3354 } // parse_args_DS |
3257 |
3355 |
3258 |
3356 |
3259 static int parse_args_DSS(Context *ctx) |
3357 static int parse_args_DSS(Context *ctx) |
3260 { |
3358 { |
3261 if (parse_destination_token(ctx, &ctx->dest_args[0]) == FAIL) return FAIL; |
3359 int retval = 1; |
3262 if (parse_source_token(ctx, &ctx->source_args[0]) == FAIL) return FAIL; |
3360 retval += parse_destination_token(ctx, &ctx->dest_args[0]); |
3263 if (parse_source_token(ctx, &ctx->source_args[1]) == FAIL) return FAIL; |
3361 retval += parse_source_token(ctx, &ctx->source_args[0]); |
3264 return 4; |
3362 retval += parse_source_token(ctx, &ctx->source_args[1]); |
|
3363 return isfail(ctx) ? FAIL : retval; |
3265 } // parse_args_DSS |
3364 } // parse_args_DSS |
3266 |
3365 |
3267 |
3366 |
3268 static int parse_args_DSSS(Context *ctx) |
3367 static int parse_args_DSSS(Context *ctx) |
3269 { |
3368 { |
3270 if (parse_destination_token(ctx, &ctx->dest_args[0]) == FAIL) return FAIL; |
3369 int retval = 1; |
3271 if (parse_source_token(ctx, &ctx->source_args[0]) == FAIL) return FAIL; |
3370 retval += parse_destination_token(ctx, &ctx->dest_args[0]); |
3272 if (parse_source_token(ctx, &ctx->source_args[1]) == FAIL) return FAIL; |
3371 retval += parse_source_token(ctx, &ctx->source_args[0]); |
3273 if (parse_source_token(ctx, &ctx->source_args[2]) == FAIL) return FAIL; |
3372 retval += parse_source_token(ctx, &ctx->source_args[1]); |
3274 return 5; |
3373 retval += parse_source_token(ctx, &ctx->source_args[2]); |
|
3374 return isfail(ctx) ? FAIL : retval; |
3275 } // parse_args_DSSS |
3375 } // parse_args_DSSS |
3276 |
3376 |
3277 |
3377 |
3278 static int parse_args_DSSSS(Context *ctx) |
3378 static int parse_args_DSSSS(Context *ctx) |
3279 { |
3379 { |
3280 if (parse_destination_token(ctx, &ctx->dest_args[0]) == FAIL) return FAIL; |
3380 int retval = 1; |
3281 if (parse_source_token(ctx, &ctx->source_args[0]) == FAIL) return FAIL; |
3381 retval += parse_destination_token(ctx, &ctx->dest_args[0]); |
3282 if (parse_source_token(ctx, &ctx->source_args[1]) == FAIL) return FAIL; |
3382 retval += parse_source_token(ctx, &ctx->source_args[0]); |
3283 if (parse_source_token(ctx, &ctx->source_args[2]) == FAIL) return FAIL; |
3383 retval += parse_source_token(ctx, &ctx->source_args[1]); |
3284 if (parse_source_token(ctx, &ctx->source_args[3]) == FAIL) return FAIL; |
3384 retval += parse_source_token(ctx, &ctx->source_args[2]); |
3285 return 6; |
3385 retval += parse_source_token(ctx, &ctx->source_args[3]); |
|
3386 return isfail(ctx) ? FAIL : retval; |
3286 } // parse_args_DSSSS |
3387 } // parse_args_DSSSS |
3287 |
3388 |
3288 |
3389 |
3289 static int parse_args_SINCOS(Context *ctx) |
3390 static int parse_args_SINCOS(Context *ctx) |
3290 { |
3391 { |