3002 // LOGP is just low-precision LOG, but we'll take the higher precision. |
3002 // LOGP is just low-precision LOG, but we'll take the higher precision. |
3003 emit_GLSL_LOG(ctx); |
3003 emit_GLSL_LOG(ctx); |
3004 } // emit_GLSL_LOGP |
3004 } // emit_GLSL_LOGP |
3005 |
3005 |
3006 // common code between CMP and CND. |
3006 // common code between CMP and CND. |
3007 // !!! FIXME: this code stinks. |
|
3008 static void emit_GLSL_comparison_operations(Context *ctx, const char *cmp) |
3007 static void emit_GLSL_comparison_operations(Context *ctx, const char *cmp) |
3009 { |
3008 { |
3010 const DestArgInfo *dst = &ctx->dest_arg; |
3009 int i, j; |
3011 const char *src0 = get_GLSL_srcarg_varname(ctx, 0); |
3010 DestArgInfo *dst = &ctx->dest_arg; |
3012 const char *src1 = get_GLSL_srcarg_varname(ctx, 1); |
3011 const SourceArgInfo *srcarg0 = &ctx->source_args[0]; |
3013 const char *src2 = get_GLSL_srcarg_varname(ctx, 2); |
3012 const int origmask = dst->writemask; |
3014 |
3013 int used_swiz[4] = { 0, 0, 0, 0 }; |
3015 if (dst->writemask == 0) |
3014 const int writemask[4] = { dst->writemask0, dst->writemask1, |
3016 return; // nothing to do, drop out early. |
3015 dst->writemask2, dst->writemask3 }; |
3017 |
3016 const int src0swiz[4] = { srcarg0->swizzle_x, srcarg0->swizzle_y, |
3018 // !!! FIXME: for replicate swizzles, don't redo compares... |
3017 srcarg0->swizzle_z, srcarg0->swizzle_w }; |
3019 |
3018 |
3020 if (replicate_swizzle(ctx->source_args[0].swizzle)) |
3019 for (i = 0; i < 4; i++) |
3021 { |
3020 { |
3022 const char swiz = swizzle_channels[ctx->source_args[0].swizzle_x]; |
3021 int mask = (1 << i); |
3023 if (writemask_xyzw(dst->writemask)) |
3022 |
|
3023 if (!writemask[i]) continue; |
|
3024 if (used_swiz[i]) continue; |
|
3025 |
|
3026 // This is a swizzle we haven't checked yet. |
|
3027 used_swiz[i] = 1; |
|
3028 |
|
3029 // see if there are any other elements swizzled to match (.yyyy) |
|
3030 for (j = i + 1; j < 4; j++) |
3024 { |
3031 { |
3025 const char *code = make_GLSL_destarg_assign(ctx, |
3032 if (!writemask[j]) continue; |
3026 "((%s.%c %s) ? %s : %s)", |
3033 if (src0swiz[i] != src0swiz[j]) continue; |
3027 src0, swiz, cmp, src1, src2); |
3034 mask |= (1 << j); |
3028 output_line(ctx, "%s", code); |
3035 used_swiz[j] = 1; |
3029 } // if |
3036 } // for |
3030 else |
3037 |
3031 { |
3038 // okay, (mask) should be the writemask of swizzles we like. |
3032 const char *dst0 = get_GLSL_destarg_varname(ctx); |
3039 |
3033 const char *x1 = (dst->writemask0) ? src1 : dst0; |
3040 //return make_GLSL_srcarg_string(ctx, idx, (1 << 0)); |
3034 const char *y1 = (dst->writemask1) ? src1 : dst0; |
3041 |
3035 const char *z1 = (dst->writemask2) ? src1 : dst0; |
3042 const char *src0 = make_GLSL_srcarg_string(ctx, 0, (1 << i)); |
3036 const char *w1 = (dst->writemask3) ? src1 : dst0; |
3043 const char *src1 = make_GLSL_srcarg_string(ctx, 1, mask); |
3037 const char *x2 = (dst->writemask0) ? src2 : dst0; |
3044 const char *src2 = make_GLSL_srcarg_string(ctx, 2, mask); |
3038 const char *y2 = (dst->writemask1) ? src2 : dst0; |
3045 |
3039 const char *z2 = (dst->writemask2) ? src2 : dst0; |
3046 dst->writemask = mask; |
3040 const char *w2 = (dst->writemask3) ? src2 : dst0; |
3047 dst->writemask0 = ((mask >> 0) & 1); |
3041 const char *code1 = make_GLSL_destarg_assign(ctx, |
3048 dst->writemask1 = ((mask >> 1) & 1); |
3042 "vec4(%s.x, %s.y, %s.z, %s.w)", |
3049 dst->writemask2 = ((mask >> 2) & 1); |
3043 x1, y1, z1, w1); |
3050 dst->writemask3 = ((mask >> 3) & 1); |
3044 const char *code2 = make_GLSL_destarg_assign(ctx, |
3051 |
3045 "vec4(%s.x, %s.y, %s.z, %s.w)", |
3052 const char *code = make_GLSL_destarg_assign(ctx, "((%s %s) ? %s : %s)", |
3046 x2, y2, z2, w2); |
3053 src0, cmp, src1, src2); |
3047 |
3054 dst->writemask = origmask; |
3048 output_line(ctx, "if (%s.%c %s) {", src0, swiz, cmp); |
3055 dst->writemask0 = ((origmask >> 0) & 1); |
3049 ctx->indent++; output_line(ctx, "%s", code1); ctx->indent--; |
3056 dst->writemask1 = ((origmask >> 1) & 1); |
3050 output_line(ctx, "} else {"); |
3057 dst->writemask2 = ((origmask >> 2) & 1); |
3051 ctx->indent++; output_line(ctx, "%s", code2); ctx->indent--; |
3058 dst->writemask3 = ((origmask >> 3) & 1); |
3052 output_line(ctx, "}"); |
3059 output_line(ctx, "%s", code); |
3053 } // else |
3060 } // for |
3054 } // if |
|
3055 |
|
3056 else |
|
3057 { |
|
3058 if (dst->writemask0) |
|
3059 { |
|
3060 fail(ctx, "!!! FIXME: need to figure out source swizzle here"); |
|
3061 const char *code = make_GLSL_destarg_assign(ctx, "((%s.x %s) ? %s.x : %s.x)", src0, cmp, src1, src2); |
|
3062 output_line(ctx, "%s", code); |
|
3063 } // if |
|
3064 if (dst->writemask1) |
|
3065 { |
|
3066 fail(ctx, "!!! FIXME: need to figure out source swizzle here"); |
|
3067 const char *code = make_GLSL_destarg_assign(ctx, "((%s.y %s) ? %s.y : %s.y)", src0, cmp, src1, src2); |
|
3068 output_line(ctx, "%s", code); |
|
3069 } // if |
|
3070 if (dst->writemask2) |
|
3071 { |
|
3072 fail(ctx, "!!! FIXME: need to figure out source swizzle here"); |
|
3073 const char *code = make_GLSL_destarg_assign(ctx, "((%s.z %s) ? %s.z : %s.z)", src0, cmp, src1, src2); |
|
3074 output_line(ctx, "%s", code); |
|
3075 } // if |
|
3076 if (dst->writemask3) |
|
3077 { |
|
3078 fail(ctx, "!!! FIXME: need to figure out source swizzle here"); |
|
3079 const char *code = make_GLSL_destarg_assign(ctx, "((%s.w %s) ? %s.w : %s.w)", src0, cmp, src1, src2); |
|
3080 output_line(ctx, "%s", code); |
|
3081 } // if |
|
3082 } // else |
|
3083 } // emit_GLSL_comparison_operations |
3061 } // emit_GLSL_comparison_operations |
3084 |
3062 |
3085 static void emit_GLSL_CND(Context *ctx) |
3063 static void emit_GLSL_CND(Context *ctx) |
3086 { |
3064 { |
3087 emit_GLSL_comparison_operations(ctx, "> 0.5"); |
3065 emit_GLSL_comparison_operations(ctx, "> 0.5"); |