wined3d: Move set_tex_op(_nvrc) to their specific files.
authorStefan Dösinger <stefan@codeweavers.com>
Sat, 12 Jul 2008 16:45:33 +0000 (11:45 -0500)
committerAlexandre Julliard <julliard@winehq.org>
Tue, 22 Jul 2008 11:01:45 +0000 (13:01 +0200)
dlls/wined3d/nvidia_texture_shader.c
dlls/wined3d/state.c
dlls/wined3d/utils.c
dlls/wined3d/wined3d_private.h

index 6844a9b..e217678 100644 (file)
@@ -65,6 +65,391 @@ void nvts_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, W
     }
 }
 
+typedef struct {
+    GLenum input[3];
+    GLenum mapping[3];
+    GLenum component_usage[3];
+} tex_op_args;
+
+static GLenum d3dta_to_combiner_input(DWORD d3dta, DWORD stage, INT texture_idx) {
+    switch (d3dta) {
+        case WINED3DTA_DIFFUSE:
+            return GL_PRIMARY_COLOR_NV;
+
+        case WINED3DTA_CURRENT:
+            if (stage) return GL_SPARE0_NV;
+            else return GL_PRIMARY_COLOR_NV;
+
+        case WINED3DTA_TEXTURE:
+            if (texture_idx > -1) return GL_TEXTURE0_ARB + texture_idx;
+            else return GL_PRIMARY_COLOR_NV;
+
+        case WINED3DTA_TFACTOR:
+            return GL_CONSTANT_COLOR0_NV;
+
+        case WINED3DTA_SPECULAR:
+            return GL_SECONDARY_COLOR_NV;
+
+        case WINED3DTA_TEMP:
+            return GL_SPARE1_NV;
+
+        case WINED3DTA_CONSTANT:
+            /* TODO: Support per stage constants (WINED3DTSS_CONSTANT, NV_register_combiners2) */
+            FIXME("WINED3DTA_CONSTANT, not properly supported.\n");
+            return GL_CONSTANT_COLOR1_NV;
+
+        default:
+            FIXME("Unrecognized texture arg %#x\n", d3dta);
+            return GL_TEXTURE;
+    }
+}
+
+static GLenum invert_mapping(GLenum mapping) {
+    if (mapping == GL_UNSIGNED_INVERT_NV) return GL_SIGNED_IDENTITY_NV;
+    else if (mapping == GL_SIGNED_IDENTITY_NV) return GL_UNSIGNED_INVERT_NV;
+
+    FIXME("Unhandled mapping %#x\n", mapping);
+    return mapping;
+}
+
+static void get_src_and_opr_nvrc(DWORD stage, DWORD arg, BOOL is_alpha, GLenum* input, GLenum* mapping, GLenum *component_usage, INT texture_idx) {
+    /* The WINED3DTA_COMPLEMENT flag specifies the complement of the input should
+    * be used. */
+    if (arg & WINED3DTA_COMPLEMENT) *mapping = GL_UNSIGNED_INVERT_NV;
+    else *mapping = GL_SIGNED_IDENTITY_NV;
+
+    /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the input
+    * should be used for all input components. */
+    if (is_alpha || arg & WINED3DTA_ALPHAREPLICATE) *component_usage = GL_ALPHA;
+    else *component_usage = GL_RGB;
+
+    *input = d3dta_to_combiner_input(arg & WINED3DTA_SELECTMASK, stage, texture_idx);
+}
+
+void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx, DWORD dst) {
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl*)iface;
+    tex_op_args tex_op_args = {{0}, {0}, {0}};
+    GLenum portion = is_alpha ? GL_ALPHA : GL_RGB;
+    GLenum target = GL_COMBINER0_NV + stage;
+    GLenum output;
+    IWineD3DStateBlockImpl *stateblock = This->stateBlock; /* For GLINFO_LOCATION */
+
+    TRACE("stage %d, is_alpha %d, op %s, arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
+          stage, is_alpha, debug_d3dtop(op), arg1, arg2, arg3, texture_idx);
+
+    /* If a texture stage references an invalid texture unit the stage just
+    * passes through the result from the previous stage */
+    if (is_invalid_op(This, stage, op, arg1, arg2, arg3)) {
+        arg1 = WINED3DTA_CURRENT;
+        op = WINED3DTOP_SELECTARG1;
+    }
+
+    get_src_and_opr_nvrc(stage, arg1, is_alpha, &tex_op_args.input[0],
+                         &tex_op_args.mapping[0], &tex_op_args.component_usage[0], texture_idx);
+    get_src_and_opr_nvrc(stage, arg2, is_alpha, &tex_op_args.input[1],
+                         &tex_op_args.mapping[1], &tex_op_args.component_usage[1], texture_idx);
+    get_src_and_opr_nvrc(stage, arg3, is_alpha, &tex_op_args.input[2],
+                         &tex_op_args.mapping[2], &tex_op_args.component_usage[2], texture_idx);
+
+
+    if(dst == WINED3DTA_TEMP) {
+        output = GL_SPARE1_NV;
+    } else {
+        output = GL_SPARE0_NV;
+    }
+
+    /* This is called by a state handler which has the gl lock held and a context for the thread */
+    switch(op)
+    {
+        case WINED3DTOP_DISABLE:
+            /* Only for alpha */
+            if (!is_alpha) ERR("Shouldn't be called for WINED3DTSS_COLOROP (WINED3DTOP_DISABLE)\n");
+            /* Input, prev_alpha*1 */
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+                       GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+                       GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
+
+            /* Output */
+            GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
+                       GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+            break;
+
+        case WINED3DTOP_SELECTARG1:
+        case WINED3DTOP_SELECTARG2:
+            /* Input, arg*1 */
+            if (op == WINED3DTOP_SELECTARG1) {
+                GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+                           tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
+            } else {
+                GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+                           tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
+            }
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+                       GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+
+            /* Output */
+            GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
+                       GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+            break;
+
+        case WINED3DTOP_MODULATE:
+        case WINED3DTOP_MODULATE2X:
+        case WINED3DTOP_MODULATE4X:
+            /* Input, arg1*arg2 */
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+                       tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+                       tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
+
+            /* Output */
+            if (op == WINED3DTOP_MODULATE) {
+                GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
+                           GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+            } else if (op == WINED3DTOP_MODULATE2X) {
+                GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
+                           GL_DISCARD_NV, GL_SCALE_BY_TWO_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+            } else if (op == WINED3DTOP_MODULATE4X) {
+                GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
+                           GL_DISCARD_NV, GL_SCALE_BY_FOUR_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+            }
+            break;
+
+        case WINED3DTOP_ADD:
+        case WINED3DTOP_ADDSIGNED:
+        case WINED3DTOP_ADDSIGNED2X:
+            /* Input, arg1*1+arg2*1 */
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+                       tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+                       GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
+                       tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
+                       GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+
+            /* Output */
+            if (op == WINED3DTOP_ADD) {
+                GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
+                           output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+            } else if (op == WINED3DTOP_ADDSIGNED) {
+                GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
+                           output, GL_NONE, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
+            } else if (op == WINED3DTOP_ADDSIGNED2X) {
+                GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
+                           output, GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
+            }
+            break;
+
+        case WINED3DTOP_SUBTRACT:
+            /* Input, arg1*1+-arg2*1 */
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+                       tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+                       GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
+                       tex_op_args.input[1], GL_SIGNED_NEGATE_NV, tex_op_args.component_usage[1]));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
+                       GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+
+            /* Output */
+            GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
+                       output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+            break;
+
+        case WINED3DTOP_ADDSMOOTH:
+            /* Input, arg1*1+(1-arg1)*arg2 */
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+                       tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+                       GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
+                       tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
+                       tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
+
+            /* Output */
+            GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
+                       output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+            break;
+
+        case WINED3DTOP_BLENDDIFFUSEALPHA:
+        case WINED3DTOP_BLENDTEXTUREALPHA:
+        case WINED3DTOP_BLENDFACTORALPHA:
+        case WINED3DTOP_BLENDTEXTUREALPHAPM:
+        case WINED3DTOP_BLENDCURRENTALPHA:
+        {
+            GLenum alpha_src = GL_PRIMARY_COLOR_NV;
+            if (op == WINED3DTOP_BLENDDIFFUSEALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_DIFFUSE, stage, texture_idx);
+            else if (op == WINED3DTOP_BLENDTEXTUREALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
+            else if (op == WINED3DTOP_BLENDFACTORALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TFACTOR, stage, texture_idx);
+            else if (op == WINED3DTOP_BLENDTEXTUREALPHAPM) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
+            else if (op == WINED3DTOP_BLENDCURRENTALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_CURRENT, stage, texture_idx);
+            else FIXME("Unhandled WINED3DTOP %s, shouldn't happen\n", debug_d3dtop(op));
+
+            /* Input, arg1*alpha_src+arg2*(1-alpha_src) */
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+                       tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
+            if (op == WINED3DTOP_BLENDTEXTUREALPHAPM)
+            {
+                GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+                           GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+            } else {
+                GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+                           alpha_src, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
+            }
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
+                       tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
+                       alpha_src, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
+
+            /* Output */
+            GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
+                       output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+            break;
+        }
+
+        case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
+            /* Input, arg1_alpha*arg2_rgb+arg1_rgb*1 */
+            if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEALPHA_ADDCOLOR)\n");
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+                       tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+                       tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
+                       tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
+                       GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+
+            /* Output */
+            GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
+                       output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+            break;
+
+        case WINED3DTOP_MODULATECOLOR_ADDALPHA:
+            /* Input, arg1_rgb*arg2_rgb+arg1_alpha*1 */
+            if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATECOLOR_ADDALPHA)\n");
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+                       tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+                       tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
+                       tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
+                       GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+
+            /* Output */
+            GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
+                       output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+            break;
+
+        case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
+            /* Input, (1-arg1_alpha)*arg2_rgb+arg1_rgb*1 */
+            if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVALPHA_ADDCOLOR)\n");
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+                       tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), GL_ALPHA));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+                       tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
+                       tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
+                       GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+
+            /* Output */
+            GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
+                       output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+            break;
+
+        case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
+            /* Input, (1-arg1_rgb)*arg2_rgb+arg1_alpha*1 */
+            if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVCOLOR_ADDALPHA)\n");
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+                       tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+                       tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
+                       tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
+                       GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+
+            /* Output */
+            GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
+                       output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+            break;
+
+        case WINED3DTOP_DOTPRODUCT3:
+            /* Input, arg1 . arg2 */
+            /* FIXME: DX7 uses a different calculation? */
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+                       tex_op_args.input[0], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[0]));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+                       tex_op_args.input[1], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[1]));
+
+            /* Output */
+            GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
+                       GL_DISCARD_NV, GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE));
+            break;
+
+        case WINED3DTOP_MULTIPLYADD:
+            /* Input, arg3*1+arg1*arg2 */
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+                       tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+                       GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
+                       tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
+                       tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
+
+            /* Output */
+            GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
+                       output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+            break;
+
+        case WINED3DTOP_LERP:
+            /* Input, arg3*arg1+(1-arg3)*arg2 */
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+                       tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+                       tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
+                       tex_op_args.input[2], invert_mapping(tex_op_args.mapping[2]), tex_op_args.component_usage[2]));
+            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
+                       tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
+
+            /* Output */
+            GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
+                       output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+            break;
+
+        case WINED3DTOP_BUMPENVMAPLUMINANCE:
+        case WINED3DTOP_BUMPENVMAP:
+            if(GL_SUPPORT(NV_TEXTURE_SHADER)) {
+                /* The bump map stage itself isn't exciting, just read the texture. But tell the next stage to
+                 * perform bump mapping and source from the current stage. Pretty much a SELECTARG2.
+                 * ARG2 is passed through unmodified(apps will most likely use D3DTA_CURRENT for arg2, arg1
+                 * (which will most likely be D3DTA_TEXTURE) is available as a texture shader input for the next stage
+                 */
+                GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
+                           tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
+                GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
+                           GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
+                /* Always pass through to CURRENT, ignore temp arg */
+                GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
+                           GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
+                break;
+            }
+
+        default:
+            FIXME("Unhandled WINED3DTOP: stage %d, is_alpha %d, op %s (%#x), arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
+                  stage, is_alpha, debug_d3dtop(op), op, arg1, arg2, arg3, texture_idx);
+    }
+
+    checkGLcall("set_tex_op_nvrc()\n");
+
+}
+
+
 static void nvrc_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
index 9ff10a1..9e29d78 100644 (file)
@@ -1840,6 +1840,1115 @@ static void state_ckeyblend(DWORD state, IWineD3DStateBlockImpl *stateblock, Win
     }
 }
 
+/* Set texture operations up - The following avoids lots of ifdefs in this routine!*/
+#if defined (GL_VERSION_1_3)
+# define useext(A) A
+#elif defined (GL_EXT_texture_env_combine)
+# define useext(A) A##_EXT
+#elif defined (GL_ARB_texture_env_combine)
+# define useext(A) A##_ARB
+#endif
+
+static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
+    /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
+    * input should be used for all input components. The WINED3DTA_COMPLEMENT
+    * flag specifies the complement of the input should be used. */
+    BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
+    BOOL complement = arg & WINED3DTA_COMPLEMENT;
+
+    /* Calculate the operand */
+    if (complement) {
+        if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
+        else *operand = GL_ONE_MINUS_SRC_COLOR;
+    } else {
+        if (from_alpha) *operand = GL_SRC_ALPHA;
+        else *operand = GL_SRC_COLOR;
+    }
+
+    /* Calculate the source */
+    switch (arg & WINED3DTA_SELECTMASK) {
+        case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
+        case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
+        case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
+        case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
+        case WINED3DTA_SPECULAR:
+            /*
+            * According to the GL_ARB_texture_env_combine specs, SPECULAR is
+            * 'Secondary color' and isn't supported until base GL supports it
+            * There is no concept of temp registers as far as I can tell
+            */
+            FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
+            *source = GL_TEXTURE;
+            break;
+        default:
+            FIXME("Unrecognized texture arg %#x\n", arg);
+            *source = GL_TEXTURE;
+            break;
+    }
+}
+
+/* Setup the texture operations texture stage states */
+static void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
+{
+    GLenum src1, src2, src3;
+    GLenum opr1, opr2, opr3;
+    GLenum comb_target;
+    GLenum src0_target, src1_target, src2_target;
+    GLenum opr0_target, opr1_target, opr2_target;
+    GLenum scal_target;
+    GLenum opr=0, invopr, src3_target, opr3_target;
+    BOOL Handled = FALSE;
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    IWineD3DStateBlockImpl *stateblock = This->stateBlock; /* for GLINFO_LOCATION */
+
+    TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
+
+    /* This is called by a state handler which has the gl lock held and a context for the thread */
+
+        /* Note: Operations usually involve two ars, src0 and src1 and are operations of
+    the form (a1 <operation> a2). However, some of the more complex operations
+    take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
+    in a third parameter called a0. Therefore these are operations of the form
+    a0 <operation> a1 <operation> a2, i.e., the new parameter goes to the front.
+
+    However, below we treat the new (a0) parameter as src2/opr2, so in the actual
+    functions below, expect their syntax to differ slightly to those listed in the
+    manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
+    This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP                     */
+
+    if (isAlpha) {
+        comb_target = useext(GL_COMBINE_ALPHA);
+        src0_target = useext(GL_SOURCE0_ALPHA);
+        src1_target = useext(GL_SOURCE1_ALPHA);
+        src2_target = useext(GL_SOURCE2_ALPHA);
+        opr0_target = useext(GL_OPERAND0_ALPHA);
+        opr1_target = useext(GL_OPERAND1_ALPHA);
+        opr2_target = useext(GL_OPERAND2_ALPHA);
+        scal_target = GL_ALPHA_SCALE;
+    }
+    else {
+        comb_target = useext(GL_COMBINE_RGB);
+        src0_target = useext(GL_SOURCE0_RGB);
+        src1_target = useext(GL_SOURCE1_RGB);
+        src2_target = useext(GL_SOURCE2_RGB);
+        opr0_target = useext(GL_OPERAND0_RGB);
+        opr1_target = useext(GL_OPERAND1_RGB);
+        opr2_target = useext(GL_OPERAND2_RGB);
+        scal_target = useext(GL_RGB_SCALE);
+    }
+
+        /* If a texture stage references an invalid texture unit the stage just
+        * passes through the result from the previous stage */
+    if (is_invalid_op(This, Stage, op, arg1, arg2, arg3)) {
+        arg1 = WINED3DTA_CURRENT;
+        op = WINED3DTOP_SELECTARG1;
+    }
+
+        /* From MSDN (WINED3DTSS_ALPHAARG1) :
+    The default argument is WINED3DTA_TEXTURE. If no texture is set for this stage,
+    then the default argument is WINED3DTA_DIFFUSE.
+    FIXME? If texture added/removed, may need to reset back as well?    */
+    if (isAlpha && This->stateBlock->textures[Stage] == NULL && arg1 == WINED3DTA_TEXTURE) {
+        get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
+    } else {
+        get_src_and_opr(arg1, isAlpha, &src1, &opr1);
+    }
+    get_src_and_opr(arg2, isAlpha, &src2, &opr2);
+    get_src_and_opr(arg3, isAlpha, &src3, &opr3);
+
+    TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
+
+    Handled = TRUE; /* Assume will be handled */
+
+    /* Other texture operations require special extensions: */
+    if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
+        if (isAlpha) {
+            opr = GL_SRC_ALPHA;
+            invopr = GL_ONE_MINUS_SRC_ALPHA;
+            src3_target = GL_SOURCE3_ALPHA_NV;
+            opr3_target = GL_OPERAND3_ALPHA_NV;
+        } else {
+            opr = GL_SRC_COLOR;
+            invopr = GL_ONE_MINUS_SRC_COLOR;
+            src3_target = GL_SOURCE3_RGB_NV;
+            opr3_target = GL_OPERAND3_RGB_NV;
+        }
+        switch (op) {
+            case WINED3DTOP_DISABLE: /* Only for alpha */
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+                checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
+                checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
+                glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+                checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+                glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
+                checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
+                break;
+                case WINED3DTOP_SELECTARG1:                                          /* = a1 * 1 + 0 * 0 */
+                case WINED3DTOP_SELECTARG2:                                          /* = a2 * 1 + 0 * 0 */
+                    glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+                    checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+                    if (op == WINED3DTOP_SELECTARG1) {
+                        glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+                        checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                        glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+                        checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+                    } else {
+                        glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
+                        checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
+                        glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
+                        checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
+                    }
+                    glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+                    checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+                    glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+                    checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+                    glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
+                    checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
+                    glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
+                    checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
+                    glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+                    checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+                    glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
+                    checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
+                    break;
+
+            case WINED3DTOP_MODULATE:
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+                checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
+                checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+                glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+                checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+                glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
+                checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+                break;
+            case WINED3DTOP_MODULATE2X:
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+                checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
+                checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+                glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+                checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+                glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
+                checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
+                checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
+                break;
+            case WINED3DTOP_MODULATE4X:
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+                checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
+                checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+                glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+                checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+                glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
+                checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
+                checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
+                break;
+
+            case WINED3DTOP_ADD:
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+                checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+                checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+                glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+                checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+                glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
+                checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
+                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+                break;
+
+            case WINED3DTOP_ADDSIGNED:
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
+                checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+                checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+                checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+                glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+                checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+                glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
+                checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
+                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+                break;
+
+            case WINED3DTOP_ADDSIGNED2X:
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
+                checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+                checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+                checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+                glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+                checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+                glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
+                checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
+                glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
+                checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
+                break;
+
+            case WINED3DTOP_ADDSMOOTH:
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+                checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+                checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+                glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
+                switch (opr1) {
+                    case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
+                    case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
+                    case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+                    case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
+                }
+                glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
+                checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
+                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+                break;
+
+            case WINED3DTOP_BLENDDIFFUSEALPHA:
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR));
+                checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)");
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+                checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+                glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR));
+                checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)");
+                glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
+                checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
+                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+                break;
+            case WINED3DTOP_BLENDTEXTUREALPHA:
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
+                checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+                checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+                glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
+                checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
+                glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
+                checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
+                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+                break;
+            case WINED3DTOP_BLENDFACTORALPHA:
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT));
+                checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)");
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+                checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+                glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT));
+                checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)");
+                glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
+                checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
+                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+                break;
+            case WINED3DTOP_BLENDTEXTUREALPHAPM:
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+                checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+                checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+                glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
+                checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
+                glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
+                checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
+                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+                break;
+            case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");  /* Add = a0*a1 + a2*a3 */
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);        /*   a0 = src1/opr1    */
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");    /*   a1 = 1 (see docs) */
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+                checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);        /*   a2 = arg2         */
+                checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");     /*  a3 = src1 alpha   */
+                glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
+                switch (opr) {
+                    case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
+                    case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+                }
+                glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
+                checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
+                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+                break;
+            case WINED3DTOP_MODULATECOLOR_ADDALPHA:
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+                checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
+                switch (opr1) {
+                    case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
+                    case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+                }
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
+                glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+                checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+                glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
+                checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
+                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+                break;
+            case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+                checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+                checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+                glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
+                switch (opr1) {
+                    case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+                    case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
+                    case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+                    case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
+                }
+                glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
+                checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
+                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+                break;
+            case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                switch (opr1) {
+                    case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
+                    case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
+                    case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+                    case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
+                }
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+                checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
+                switch (opr1) {
+                    case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
+                    case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+                }
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
+                glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
+                checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
+                glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
+                checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
+                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+                break;
+            case WINED3DTOP_MULTIPLYADD:
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
+                checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+                glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
+                checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
+                glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
+                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+                break;
+
+            case WINED3DTOP_BUMPENVMAP:
+            {
+            }
+
+            case WINED3DTOP_BUMPENVMAPLUMINANCE:
+                FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
+
+            default:
+                Handled = FALSE;
+        }
+        if (Handled) {
+            glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
+            checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
+
+            return;
+        }
+    } /* GL_NV_texture_env_combine4 */
+
+    Handled = TRUE; /* Again, assume handled */
+    switch (op) {
+        case WINED3DTOP_DISABLE: /* Only for alpha */
+            glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
+            checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
+            glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
+            checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
+            glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
+            checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
+            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+            break;
+        case WINED3DTOP_SELECTARG1:
+            glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
+            checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
+            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+            break;
+        case WINED3DTOP_SELECTARG2:
+            glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
+            checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
+            glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
+            checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
+            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
+            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
+            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+            break;
+        case WINED3DTOP_MODULATE:
+            glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
+            checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
+            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+            glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+            checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+            glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+            checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+            break;
+        case WINED3DTOP_MODULATE2X:
+            glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
+            checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
+            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+            glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+            checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+            glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+            checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+            glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
+            checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
+            break;
+        case WINED3DTOP_MODULATE4X:
+            glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
+            checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
+            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+            glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+            checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+            glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+            checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+            glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
+            checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
+            break;
+        case WINED3DTOP_ADD:
+            glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
+            checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
+            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+            glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+            checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+            glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+            checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+            break;
+        case WINED3DTOP_ADDSIGNED:
+            glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
+            checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)");
+            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+            glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+            checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+            glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+            checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+            break;
+        case WINED3DTOP_ADDSIGNED2X:
+            glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
+            checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
+            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+            glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+            checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+            glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+            checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+            glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
+            checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
+            break;
+        case WINED3DTOP_SUBTRACT:
+            if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) {
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)");
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+                checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+            } else {
+                FIXME("This version of opengl does not support GL_SUBTRACT\n");
+            }
+            break;
+
+        case WINED3DTOP_BLENDDIFFUSEALPHA:
+            glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
+            checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
+            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+            glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+            checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+            glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+            checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+            glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR));
+            checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
+            glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
+            checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
+            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+            break;
+        case WINED3DTOP_BLENDTEXTUREALPHA:
+            glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
+            checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
+            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+            glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+            checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+            glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+            checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+            glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
+            checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
+            glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
+            checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
+            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+            break;
+        case WINED3DTOP_BLENDFACTORALPHA:
+            glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
+            checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
+            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+            glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+            checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+            glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+            checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+            glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT));
+            checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
+            glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
+            checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
+            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+            break;
+        case WINED3DTOP_BLENDCURRENTALPHA:
+            glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
+            checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
+            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+            glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+            checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+            glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+            checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+            glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS));
+            checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
+            glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
+            checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
+            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+            break;
+        case WINED3DTOP_DOTPRODUCT3:
+            if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) {
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
+            } else if (GL_SUPPORT(EXT_TEXTURE_ENV_DOT3)) {
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
+            } else {
+                FIXME("This version of opengl does not support GL_DOT3\n");
+            }
+            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+            glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+            checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+            glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+            checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+            break;
+        case WINED3DTOP_LERP:
+            glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
+            checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
+            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+            glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
+            checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
+            glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
+            checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
+            glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
+            checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
+            glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
+            checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
+            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+            break;
+        case WINED3DTOP_ADDSMOOTH:
+            if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                switch (opr1) {
+                    case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
+                    case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
+                    case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+                    case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
+                }
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+                checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+            } else
+                Handled = FALSE;
+                break;
+        case WINED3DTOP_BLENDTEXTUREALPHAPM:
+            if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+                checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+            } else
+                Handled = FALSE;
+                break;
+        case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
+            if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                switch (opr1) {
+                    case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
+                    case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+                    case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
+                    case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+                }
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+                checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+            } else
+                Handled = FALSE;
+                break;
+        case WINED3DTOP_MODULATECOLOR_ADDALPHA:
+            if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
+                switch (opr1) {
+                    case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
+                    case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+                    case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
+                    case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+                }
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+                checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+            } else
+                Handled = FALSE;
+                break;
+        case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
+            if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                switch (opr1) {
+                    case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+                    case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
+                    case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+                    case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
+                }
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+                checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+            } else
+                Handled = FALSE;
+                break;
+        case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
+            if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                switch (opr1) {
+                    case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
+                    case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
+                    case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+                    case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
+                }
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
+                switch (opr1) {
+                    case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
+                    case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+                    case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
+                    case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
+                }
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+                checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+            } else
+                Handled = FALSE;
+                break;
+        case WINED3DTOP_MULTIPLYADD:
+            if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
+                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, src3);
+                checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+                checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
+                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
+            } else
+                Handled = FALSE;
+                break;
+        case WINED3DTOP_BUMPENVMAPLUMINANCE:
+            if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
+                    /* Some apps use BUMPENVMAPLUMINANCE instead of D3DTOP_BUMPENVMAP, although
+                * they check for the non-luminance cap flag. Well, give them what they asked
+                * for :-)
+                    */
+                WARN("Application uses WINED3DTOP_BUMPENVMAPLUMINANCE\n");
+            } else {
+                Handled = FALSE;
+                break;
+            }
+            /* Fall through */
+        case WINED3DTOP_BUMPENVMAP:
+            if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
+                TRACE("Using ati bumpmap on stage %d, target %d\n", Stage, Stage + 1);
+                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI);
+                checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI)");
+                glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1);
+                checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1)");
+                glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src3");
+                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
+                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3");
+                glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
+                checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
+                glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
+                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
+                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
+                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
+
+                Handled = TRUE;
+                break;
+            } else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
+                /* Technically texture shader support without register combiners is possible, but not expected to occur
+                 * on real world cards, so for now a fixme should be enough
+                 */
+                FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
+            }
+        default:
+            Handled = FALSE;
+    }
+
+    if (Handled) {
+        BOOL  combineOK = TRUE;
+        if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
+            DWORD op2;
+
+            if (isAlpha) {
+                op2 = This->stateBlock->textureState[Stage][WINED3DTSS_COLOROP];
+            } else {
+                op2 = This->stateBlock->textureState[Stage][WINED3DTSS_ALPHAOP];
+            }
+
+            /* Note: If COMBINE4 in effect can't go back to combine! */
+            switch (op2) {
+                case WINED3DTOP_ADDSMOOTH:
+                case WINED3DTOP_BLENDTEXTUREALPHAPM:
+                case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
+                case WINED3DTOP_MODULATECOLOR_ADDALPHA:
+                case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
+                case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
+                case WINED3DTOP_MULTIPLYADD:
+                    /* Ignore those implemented in both cases */
+                    switch (op) {
+                        case WINED3DTOP_SELECTARG1:
+                        case WINED3DTOP_SELECTARG2:
+                            combineOK = FALSE;
+                            Handled   = FALSE;
+                            break;
+                        default:
+                            FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
+                            return;
+                    }
+            }
+        }
+
+        if (combineOK) {
+            glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
+            checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
+
+            return;
+        }
+    }
+
+    /* After all the extensions, if still unhandled, report fixme */
+    FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
+}
+
+
 static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
index 245c2c2..dd18b27 100644 (file)
@@ -942,7 +942,7 @@ const char* debug_d3dtexturestate(DWORD state) {
   }
 }
 
-static const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
+const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) {
     switch (d3dtop) {
 #define D3DTOP_TO_STR(u) case u: return #u
         D3DTOP_TO_STR(WINED3DTOP_DISABLE);
@@ -1107,68 +1107,7 @@ GLenum CompareFunc(DWORD func) {
     }
 }
 
-static GLenum d3dta_to_combiner_input(DWORD d3dta, DWORD stage, INT texture_idx) {
-    switch (d3dta) {
-        case WINED3DTA_DIFFUSE:
-            return GL_PRIMARY_COLOR_NV;
-
-        case WINED3DTA_CURRENT:
-            if (stage) return GL_SPARE0_NV;
-            else return GL_PRIMARY_COLOR_NV;
-
-        case WINED3DTA_TEXTURE:
-            if (texture_idx > -1) return GL_TEXTURE0_ARB + texture_idx;
-            else return GL_PRIMARY_COLOR_NV;
-
-        case WINED3DTA_TFACTOR:
-            return GL_CONSTANT_COLOR0_NV;
-
-        case WINED3DTA_SPECULAR:
-            return GL_SECONDARY_COLOR_NV;
-
-        case WINED3DTA_TEMP:
-            return GL_SPARE1_NV;
-
-        case WINED3DTA_CONSTANT:
-            /* TODO: Support per stage constants (WINED3DTSS_CONSTANT, NV_register_combiners2) */
-            FIXME("WINED3DTA_CONSTANT, not properly supported.\n");
-            return GL_CONSTANT_COLOR1_NV;
-
-        default:
-            FIXME("Unrecognized texture arg %#x\n", d3dta);
-            return GL_TEXTURE;
-    }
-}
-
-static GLenum invert_mapping(GLenum mapping) {
-    if (mapping == GL_UNSIGNED_INVERT_NV) return GL_SIGNED_IDENTITY_NV;
-    else if (mapping == GL_SIGNED_IDENTITY_NV) return GL_UNSIGNED_INVERT_NV;
-
-    FIXME("Unhandled mapping %#x\n", mapping);
-    return mapping;
-}
-
-static void get_src_and_opr_nvrc(DWORD stage, DWORD arg, BOOL is_alpha, GLenum* input, GLenum* mapping, GLenum *component_usage, INT texture_idx) {
-    /* The WINED3DTA_COMPLEMENT flag specifies the complement of the input should
-     * be used. */
-    if (arg & WINED3DTA_COMPLEMENT) *mapping = GL_UNSIGNED_INVERT_NV;
-    else *mapping = GL_SIGNED_IDENTITY_NV;
-
-    /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the input
-     * should be used for all input components. */
-    if (is_alpha || arg & WINED3DTA_ALPHAREPLICATE) *component_usage = GL_ALPHA;
-    else *component_usage = GL_RGB;
-
-    *input = d3dta_to_combiner_input(arg & WINED3DTA_SELECTMASK, stage, texture_idx);
-}
-
-typedef struct {
-    GLenum input[3];
-    GLenum mapping[3];
-    GLenum component_usage[3];
-} tex_op_args;
-
-static BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
+BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) {
     if (op == WINED3DTOP_DISABLE) return FALSE;
     if (This->stateBlock->textures[stage]) return FALSE;
 
@@ -1182,1436 +1121,6 @@ static BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP
     return FALSE;
 }
 
-void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx, DWORD dst) {
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl*)iface;
-    tex_op_args tex_op_args = {{0}, {0}, {0}};
-    GLenum portion = is_alpha ? GL_ALPHA : GL_RGB;
-    GLenum target = GL_COMBINER0_NV + stage;
-    GLenum output;
-
-    TRACE("stage %d, is_alpha %d, op %s, arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
-            stage, is_alpha, debug_d3dtop(op), arg1, arg2, arg3, texture_idx);
-
-    /* If a texture stage references an invalid texture unit the stage just
-     * passes through the result from the previous stage */
-    if (is_invalid_op(This, stage, op, arg1, arg2, arg3)) {
-        arg1 = WINED3DTA_CURRENT;
-        op = WINED3DTOP_SELECTARG1;
-    }
-
-    get_src_and_opr_nvrc(stage, arg1, is_alpha, &tex_op_args.input[0],
-            &tex_op_args.mapping[0], &tex_op_args.component_usage[0], texture_idx);
-    get_src_and_opr_nvrc(stage, arg2, is_alpha, &tex_op_args.input[1],
-            &tex_op_args.mapping[1], &tex_op_args.component_usage[1], texture_idx);
-    get_src_and_opr_nvrc(stage, arg3, is_alpha, &tex_op_args.input[2],
-            &tex_op_args.mapping[2], &tex_op_args.component_usage[2], texture_idx);
-
-
-    if(dst == WINED3DTA_TEMP) {
-        output = GL_SPARE1_NV;
-    } else {
-        output = GL_SPARE0_NV;
-    }
-
-    /* This is called by a state handler which has the gl lock held and a context for the thread */
-    switch(op)
-    {
-        case WINED3DTOP_DISABLE:
-            /* Only for alpha */
-            if (!is_alpha) ERR("Shouldn't be called for WINED3DTSS_COLOROP (WINED3DTOP_DISABLE)\n");
-            /* Input, prev_alpha*1 */
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
-                    GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
-                    GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
-
-            /* Output */
-            GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
-                    GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
-            break;
-
-        case WINED3DTOP_SELECTARG1:
-        case WINED3DTOP_SELECTARG2:
-            /* Input, arg*1 */
-            if (op == WINED3DTOP_SELECTARG1) {
-                GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
-                        tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
-            } else {
-                GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
-                        tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
-            }
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
-                    GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
-
-            /* Output */
-            GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
-                    GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
-            break;
-
-        case WINED3DTOP_MODULATE:
-        case WINED3DTOP_MODULATE2X:
-        case WINED3DTOP_MODULATE4X:
-            /* Input, arg1*arg2 */
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
-                    tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
-                    tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
-
-            /* Output */
-            if (op == WINED3DTOP_MODULATE) {
-                GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
-                        GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
-            } else if (op == WINED3DTOP_MODULATE2X) {
-                GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
-                        GL_DISCARD_NV, GL_SCALE_BY_TWO_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
-            } else if (op == WINED3DTOP_MODULATE4X) {
-                GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
-                        GL_DISCARD_NV, GL_SCALE_BY_FOUR_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
-            }
-            break;
-
-        case WINED3DTOP_ADD:
-        case WINED3DTOP_ADDSIGNED:
-        case WINED3DTOP_ADDSIGNED2X:
-            /* Input, arg1*1+arg2*1 */
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
-                    tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
-                    GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
-                    tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
-                    GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
-
-            /* Output */
-            if (op == WINED3DTOP_ADD) {
-                GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
-                           output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
-            } else if (op == WINED3DTOP_ADDSIGNED) {
-                GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
-                           output, GL_NONE, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
-            } else if (op == WINED3DTOP_ADDSIGNED2X) {
-                GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
-                           output, GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE));
-            }
-            break;
-
-        case WINED3DTOP_SUBTRACT:
-            /* Input, arg1*1+-arg2*1 */
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
-                    tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
-                    GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
-                    tex_op_args.input[1], GL_SIGNED_NEGATE_NV, tex_op_args.component_usage[1]));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
-                    GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
-
-            /* Output */
-            GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
-                       output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
-            break;
-
-        case WINED3DTOP_ADDSMOOTH:
-            /* Input, arg1*1+(1-arg1)*arg2 */
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
-                    tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
-                    GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
-                    tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
-                    tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
-
-            /* Output */
-            GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
-                       output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
-            break;
-
-        case WINED3DTOP_BLENDDIFFUSEALPHA:
-        case WINED3DTOP_BLENDTEXTUREALPHA:
-        case WINED3DTOP_BLENDFACTORALPHA:
-        case WINED3DTOP_BLENDTEXTUREALPHAPM:
-        case WINED3DTOP_BLENDCURRENTALPHA:
-        {
-            GLenum alpha_src = GL_PRIMARY_COLOR_NV;
-            if (op == WINED3DTOP_BLENDDIFFUSEALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_DIFFUSE, stage, texture_idx);
-            else if (op == WINED3DTOP_BLENDTEXTUREALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
-            else if (op == WINED3DTOP_BLENDFACTORALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TFACTOR, stage, texture_idx);
-            else if (op == WINED3DTOP_BLENDTEXTUREALPHAPM) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx);
-            else if (op == WINED3DTOP_BLENDCURRENTALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_CURRENT, stage, texture_idx);
-            else FIXME("Unhandled WINED3DTOP %s, shouldn't happen\n", debug_d3dtop(op));
-
-            /* Input, arg1*alpha_src+arg2*(1-alpha_src) */
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
-                    tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
-            if (op == WINED3DTOP_BLENDTEXTUREALPHAPM)
-            {
-                GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
-                        GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
-            } else {
-                GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
-                        alpha_src, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA));
-            }
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
-                    tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
-                    alpha_src, GL_UNSIGNED_INVERT_NV, GL_ALPHA));
-
-            /* Output */
-            GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
-                       output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
-            break;
-        }
-
-        case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
-            /* Input, arg1_alpha*arg2_rgb+arg1_rgb*1 */
-            if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEALPHA_ADDCOLOR)\n");
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
-                    tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
-                    tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
-                    tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
-                    GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
-
-            /* Output */
-            GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
-                       output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
-            break;
-
-        case WINED3DTOP_MODULATECOLOR_ADDALPHA:
-            /* Input, arg1_rgb*arg2_rgb+arg1_alpha*1 */
-            if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATECOLOR_ADDALPHA)\n");
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
-                    tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
-                    tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
-                    tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
-                    GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
-
-            /* Output */
-            GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
-                       output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
-            break;
-
-        case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
-            /* Input, (1-arg1_alpha)*arg2_rgb+arg1_rgb*1 */
-            if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVALPHA_ADDCOLOR)\n");
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
-                    tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), GL_ALPHA));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
-                    tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
-                    tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
-                    GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
-
-            /* Output */
-            GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
-                       output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
-            break;
-
-        case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
-            /* Input, (1-arg1_rgb)*arg2_rgb+arg1_alpha*1 */
-            if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVCOLOR_ADDALPHA)\n");
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
-                    tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0]));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
-                    tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
-                    tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
-                    GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
-
-            /* Output */
-            GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
-                       output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
-            break;
-
-        case WINED3DTOP_DOTPRODUCT3:
-            /* Input, arg1 . arg2 */
-            /* FIXME: DX7 uses a different calculation? */
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
-                    tex_op_args.input[0], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[0]));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
-                    tex_op_args.input[1], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[1]));
-
-            /* Output */
-            GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV,
-                    GL_DISCARD_NV, GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE));
-            break;
-
-        case WINED3DTOP_MULTIPLYADD:
-            /* Input, arg3*1+arg1*arg2 */
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
-                    tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
-                    GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
-                    tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
-                    tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
-
-            /* Output */
-            GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
-                       output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
-            break;
-
-        case WINED3DTOP_LERP:
-            /* Input, arg3*arg1+(1-arg3)*arg2 */
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
-                    tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2]));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
-                    tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0]));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV,
-                    tex_op_args.input[2], invert_mapping(tex_op_args.mapping[2]), tex_op_args.component_usage[2]));
-            GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV,
-                    tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
-
-            /* Output */
-            GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV,
-                       output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
-            break;
-
-        case WINED3DTOP_BUMPENVMAPLUMINANCE:
-        case WINED3DTOP_BUMPENVMAP:
-            if(GL_SUPPORT(NV_TEXTURE_SHADER)) {
-                /* The bump map stage itself isn't exciting, just read the texture. But tell the next stage to
-                 * perform bump mapping and source from the current stage. Pretty much a SELECTARG2.
-                 * ARG2 is passed through unmodified(apps will most likely use D3DTA_CURRENT for arg2, arg1
-                 * (which will most likely be D3DTA_TEXTURE) is available as a texture shader input for the next stage
-                 */
-                GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV,
-                        tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1]));
-                GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV,
-                        GL_ZERO, GL_UNSIGNED_INVERT_NV, portion));
-                /* Always pass through to CURRENT, ignore temp arg */
-                GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV,
-                        GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE));
-                break;
-            }
-
-        default:
-            FIXME("Unhandled WINED3DTOP: stage %d, is_alpha %d, op %s (%#x), arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n",
-                    stage, is_alpha, debug_d3dtop(op), op, arg1, arg2, arg3, texture_idx);
-    }
-
-    checkGLcall("set_tex_op_nvrc()\n");
-
-}
-
-static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
-    /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
-     * input should be used for all input components. The WINED3DTA_COMPLEMENT
-     * flag specifies the complement of the input should be used. */
-    BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
-    BOOL complement = arg & WINED3DTA_COMPLEMENT;
-
-    /* Calculate the operand */
-    if (complement) {
-        if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
-        else *operand = GL_ONE_MINUS_SRC_COLOR;
-    } else {
-        if (from_alpha) *operand = GL_SRC_ALPHA;
-        else *operand = GL_SRC_COLOR;
-    }
-
-    /* Calculate the source */
-    switch (arg & WINED3DTA_SELECTMASK) {
-        case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
-        case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
-        case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
-        case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
-        case WINED3DTA_SPECULAR:
-            /*
-             * According to the GL_ARB_texture_env_combine specs, SPECULAR is
-             * 'Secondary color' and isn't supported until base GL supports it
-             * There is no concept of temp registers as far as I can tell
-             */
-            FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
-            *source = GL_TEXTURE;
-            break;
-        default:
-            FIXME("Unrecognized texture arg %#x\n", arg);
-            *source = GL_TEXTURE;
-            break;
-    }
-}
-
-/* Set texture operations up - The following avoids lots of ifdefs in this routine!*/
-#if defined (GL_VERSION_1_3)
-# define useext(A) A
-#elif defined (GL_EXT_texture_env_combine)
-# define useext(A) A##_EXT
-#elif defined (GL_ARB_texture_env_combine)
-# define useext(A) A##_ARB
-#endif
-
-/* Setup the texture operations texture stage states */
-void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
-{
-        GLenum src1, src2, src3;
-        GLenum opr1, opr2, opr3;
-        GLenum comb_target;
-        GLenum src0_target, src1_target, src2_target;
-        GLenum opr0_target, opr1_target, opr2_target;
-        GLenum scal_target;
-        GLenum opr=0, invopr, src3_target, opr3_target;
-        BOOL Handled = FALSE;
-        IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-
-        TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
-
-        /* This is called by a state handler which has the gl lock held and a context for the thread */
-
-        /* Note: Operations usually involve two ars, src0 and src1 and are operations of
-           the form (a1 <operation> a2). However, some of the more complex operations
-           take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
-           in a third parameter called a0. Therefore these are operations of the form
-           a0 <operation> a1 <operation> a2, i.e., the new parameter goes to the front.
-
-           However, below we treat the new (a0) parameter as src2/opr2, so in the actual
-           functions below, expect their syntax to differ slightly to those listed in the
-           manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
-           This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP                     */
-
-        if (isAlpha) {
-                comb_target = useext(GL_COMBINE_ALPHA);
-                src0_target = useext(GL_SOURCE0_ALPHA);
-                src1_target = useext(GL_SOURCE1_ALPHA);
-                src2_target = useext(GL_SOURCE2_ALPHA);
-                opr0_target = useext(GL_OPERAND0_ALPHA);
-                opr1_target = useext(GL_OPERAND1_ALPHA);
-                opr2_target = useext(GL_OPERAND2_ALPHA);
-                scal_target = GL_ALPHA_SCALE;
-        }
-        else {
-                comb_target = useext(GL_COMBINE_RGB);
-                src0_target = useext(GL_SOURCE0_RGB);
-                src1_target = useext(GL_SOURCE1_RGB);
-                src2_target = useext(GL_SOURCE2_RGB);
-                opr0_target = useext(GL_OPERAND0_RGB);
-                opr1_target = useext(GL_OPERAND1_RGB);
-                opr2_target = useext(GL_OPERAND2_RGB);
-                scal_target = useext(GL_RGB_SCALE);
-        }
-
-        /* If a texture stage references an invalid texture unit the stage just
-         * passes through the result from the previous stage */
-        if (is_invalid_op(This, Stage, op, arg1, arg2, arg3)) {
-            arg1 = WINED3DTA_CURRENT;
-            op = WINED3DTOP_SELECTARG1;
-        }
-
-        /* From MSDN (WINED3DTSS_ALPHAARG1) :
-           The default argument is WINED3DTA_TEXTURE. If no texture is set for this stage,
-                   then the default argument is WINED3DTA_DIFFUSE.
-                   FIXME? If texture added/removed, may need to reset back as well?    */
-        if (isAlpha && This->stateBlock->textures[Stage] == NULL && arg1 == WINED3DTA_TEXTURE) {
-            get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
-        } else {
-            get_src_and_opr(arg1, isAlpha, &src1, &opr1);
-        }
-        get_src_and_opr(arg2, isAlpha, &src2, &opr2);
-        get_src_and_opr(arg3, isAlpha, &src3, &opr3);
-
-        TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
-
-        Handled = TRUE; /* Assume will be handled */
-
-        /* Other texture operations require special extensions: */
-        if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
-          if (isAlpha) {
-            opr = GL_SRC_ALPHA;
-            invopr = GL_ONE_MINUS_SRC_ALPHA;
-            src3_target = GL_SOURCE3_ALPHA_NV;
-            opr3_target = GL_OPERAND3_ALPHA_NV;
-          } else {
-            opr = GL_SRC_COLOR;
-            invopr = GL_ONE_MINUS_SRC_COLOR;
-            src3_target = GL_SOURCE3_RGB_NV;
-            opr3_target = GL_OPERAND3_RGB_NV;
-          }
-          switch (op) {
-          case WINED3DTOP_DISABLE: /* Only for alpha */
-            glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
-            checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
-            glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
-            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-            glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
-            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-            glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
-            checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
-            glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
-            checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
-            glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
-            checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
-            break;
-          case WINED3DTOP_SELECTARG1:                                          /* = a1 * 1 + 0 * 0 */
-          case WINED3DTOP_SELECTARG2:                                          /* = a2 * 1 + 0 * 0 */
-            glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
-            checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
-            if (op == WINED3DTOP_SELECTARG1) {
-              glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-              checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-              glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-              checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-            } else {
-              glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
-              checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
-              glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
-              checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
-            }
-            glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
-            checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
-            glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
-            checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
-            glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
-            checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
-            break;
-
-          case WINED3DTOP_MODULATE:
-            glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
-            checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
-            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-            glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
-            checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
-            checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
-            glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
-            glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
-            checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
-            glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
-            checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
-            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-            break;
-          case WINED3DTOP_MODULATE2X:
-            glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
-            checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
-            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-            glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
-            checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
-            checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
-            glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
-            glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
-            checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
-            glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
-            checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
-            glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
-            checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
-            break;
-          case WINED3DTOP_MODULATE4X:
-            glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
-            checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
-            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-            glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
-            checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
-            checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
-            glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
-            glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
-            checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
-            glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
-            checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
-            glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
-            checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
-            break;
-
-          case WINED3DTOP_ADD:
-            glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
-            checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
-            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-            glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
-            checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
-            glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
-            checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
-            glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
-            checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
-            glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
-            checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
-            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-            break;
-
-          case WINED3DTOP_ADDSIGNED:
-            glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
-            checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
-            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-            glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
-            checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
-            glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
-            checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
-            glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
-            checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
-            glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
-            checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
-            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-            break;
-
-          case WINED3DTOP_ADDSIGNED2X:
-            glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
-            checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
-            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-            glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
-            checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
-            glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
-            checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
-            glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
-            checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
-            glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
-            checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
-            glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
-            checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
-            break;
-
-          case WINED3DTOP_ADDSMOOTH:
-            glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
-            checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
-            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-            glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
-            checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
-            glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
-            checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
-            glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
-            checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
-            glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
-            checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
-            switch (opr1) {
-            case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
-            case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
-            case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
-            case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
-            }
-            glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
-            checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
-            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-            break;
-
-          case WINED3DTOP_BLENDDIFFUSEALPHA:
-            glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
-            checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
-            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-            glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR));
-            checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)");
-            glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
-            checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
-            glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
-            checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
-            glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
-            checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
-            glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR));
-            checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)");
-            glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
-            checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
-            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-            break;
-          case WINED3DTOP_BLENDTEXTUREALPHA:
-            glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
-            checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
-            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-            glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
-            checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
-            glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
-            checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
-            glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
-            checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
-            glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
-            checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
-            glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
-            checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
-            glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
-            checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
-            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-            break;
-          case WINED3DTOP_BLENDFACTORALPHA:
-            glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
-            checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
-            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-            glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT));
-            checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)");
-            glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
-            checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
-            glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
-            checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
-            glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
-            checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
-            glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT));
-            checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)");
-            glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
-            checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
-            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-            break;
-          case WINED3DTOP_BLENDTEXTUREALPHAPM:
-            glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
-            checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
-            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-            glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
-            checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
-            glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
-            checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
-            glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
-            checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
-            glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
-            checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
-            glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
-            checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
-            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-            break;
-          case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
-            glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
-            checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");  /* Add = a0*a1 + a2*a3 */
-            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);        /*   a0 = src1/opr1    */
-            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");    /*   a1 = 1 (see docs) */
-            glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
-            checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
-            glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);        /*   a2 = arg2         */
-            checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
-            glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
-            checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");     /*  a3 = src1 alpha   */
-            glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
-            checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
-            switch (opr) {
-            case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
-            case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
-            }
-            glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
-            checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
-            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-            break;
-          case WINED3DTOP_MODULATECOLOR_ADDALPHA:
-            glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
-            checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
-            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-            glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
-            checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
-            glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
-            checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
-            glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
-            checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
-            switch (opr1) {
-            case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
-            case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
-            }
-            glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
-            checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
-            glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
-            checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
-            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-            break;
-          case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
-            glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
-            checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
-            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-            glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
-            checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
-            glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
-            checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
-            glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
-            checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
-            glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
-            checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
-            switch (opr1) {
-            case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
-            case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
-            case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
-            case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
-            }
-            glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
-            checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
-            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-            break;
-          case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
-            glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
-            checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
-            glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-            switch (opr1) {
-            case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
-            case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
-            case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
-            case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
-            }
-            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
-            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
-            glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
-            checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
-            glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
-            checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
-            glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
-            checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
-            switch (opr1) {
-            case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
-            case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
-            }
-            glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
-            checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
-            glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
-            checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
-            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-            break;
-          case WINED3DTOP_MULTIPLYADD:
-            glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
-            checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
-            glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
-            checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-            glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
-            checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-            glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
-            checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
-            glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
-            checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
-            glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
-            checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
-            glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
-            checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
-            glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
-            checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
-            glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
-            checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
-            glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-            checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-            break;
-
-          case WINED3DTOP_BUMPENVMAP:
-            {
-            }
-
-          case WINED3DTOP_BUMPENVMAPLUMINANCE:
-                FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
-
-          default:
-            Handled = FALSE;
-          }
-          if (Handled) {
-            glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
-            checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
-
-            return;
-          }
-        } /* GL_NV_texture_env_combine4 */
-
-        Handled = TRUE; /* Again, assume handled */
-        switch (op) {
-        case WINED3DTOP_DISABLE: /* Only for alpha */
-                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
-                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
-                glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
-                checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
-                glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
-                checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
-                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-                break;
-        case WINED3DTOP_SELECTARG1:
-                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
-                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
-                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-                break;
-        case WINED3DTOP_SELECTARG2:
-                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
-                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
-                glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
-                checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
-                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
-                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
-                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-                break;
-        case WINED3DTOP_MODULATE:
-                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
-                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
-                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-                glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
-                checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
-                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
-                checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
-                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-                break;
-        case WINED3DTOP_MODULATE2X:
-                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
-                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
-                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-                glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
-                checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
-                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
-                checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
-                glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
-                checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
-                break;
-        case WINED3DTOP_MODULATE4X:
-                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
-                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
-                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-                glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
-                checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
-                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
-                checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
-                glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
-                checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
-                break;
-        case WINED3DTOP_ADD:
-                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
-                checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
-                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-                glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
-                checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
-                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
-                checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
-                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-                break;
-        case WINED3DTOP_ADDSIGNED:
-                glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
-                checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)");
-                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-                glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
-                checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
-                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
-                checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
-                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-                break;
-        case WINED3DTOP_ADDSIGNED2X:
-                glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
-                checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
-                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-                glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
-                checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
-                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
-                checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
-                glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
-                checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
-                break;
-        case WINED3DTOP_SUBTRACT:
-          if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) {
-                glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
-                checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)");
-                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-                glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
-                checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
-                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
-                checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
-                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-          } else {
-                FIXME("This version of opengl does not support GL_SUBTRACT\n");
-          }
-          break;
-
-        case WINED3DTOP_BLENDDIFFUSEALPHA:
-                glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
-                checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
-                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-                glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
-                checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
-                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
-                checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
-                glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR));
-                checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
-                glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
-                checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
-                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-                break;
-        case WINED3DTOP_BLENDTEXTUREALPHA:
-                glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
-                checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
-                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-                glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
-                checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
-                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
-                checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
-                glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
-                checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
-                glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
-                checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
-                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-                break;
-        case WINED3DTOP_BLENDFACTORALPHA:
-                glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
-                checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
-                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-                glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
-                checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
-                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
-                checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
-                glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT));
-                checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
-                glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
-                checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
-                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-                break;
-        case WINED3DTOP_BLENDCURRENTALPHA:
-                glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
-                checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
-                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-                glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
-                checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
-                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
-                checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
-                glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS));
-                checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
-                glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
-                checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
-                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-                break;
-        case WINED3DTOP_DOTPRODUCT3:
-                if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) {
-                  glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
-                  checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
-                } else if (GL_SUPPORT(EXT_TEXTURE_ENV_DOT3)) {
-                  glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
-                  checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
-                } else {
-                  FIXME("This version of opengl does not support GL_DOT3\n");
-                }
-                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-                glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
-                checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
-                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
-                checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
-                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-                break;
-        case WINED3DTOP_LERP:
-                glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
-                checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
-                glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-                checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-                glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-                checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-                glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
-                checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
-                glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
-                checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
-                glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
-                checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
-                glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
-                checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
-                glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-                checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-                break;
-        case WINED3DTOP_ADDSMOOTH:
-                if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
-                  glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
-                  checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
-                  glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-                  checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-                  switch (opr1) {
-                  case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
-                  case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
-                  case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
-                  case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
-                  }
-                  glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
-                  checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
-                  glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
-                  checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
-                  glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
-                  checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
-                  glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
-                  checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
-                  glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
-                  checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
-                  glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-                  checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-                } else
-                  Handled = FALSE;
-                break;
-        case WINED3DTOP_BLENDTEXTUREALPHAPM:
-                if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
-                  glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
-                  checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
-                  glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
-                  checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
-                  glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
-                  checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
-                  glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
-                  checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
-                  glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
-                  checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
-                  glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
-                  checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
-                  glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
-                  checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
-                  glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-                  checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-                } else
-                  Handled = FALSE;
-                break;
-        case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
-                if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
-                  glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
-                  checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
-                  glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-                  checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-                  switch (opr1) {
-                  case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
-                  case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
-                  case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
-                  case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
-                  }
-                  glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
-                  checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
-                  glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
-                  checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
-                  glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
-                  checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
-                  glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
-                  checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
-                  glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
-                  checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
-                  glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-                  checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-                } else
-                  Handled = FALSE;
-                break;
-        case WINED3DTOP_MODULATECOLOR_ADDALPHA:
-                if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
-                  glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
-                  checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
-                  glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-                  checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-                  glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-                  checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-                  glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
-                  checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
-                  switch (opr1) {
-                  case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
-                  case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
-                  case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
-                  case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
-                  }
-                  glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
-                  checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
-                  glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
-                  checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
-                  glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
-                  checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
-                  glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-                  checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-                } else
-                  Handled = FALSE;
-                break;
-        case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
-                if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
-                  glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
-                  checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
-                  glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-                  checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-                  switch (opr1) {
-                  case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
-                  case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
-                  case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
-                  case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
-                  }
-                  glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
-                  checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
-                  glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
-                  checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
-                  glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
-                  checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
-                  glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
-                  checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
-                  glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
-                  checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
-                  glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-                  checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-                } else
-                  Handled = FALSE;
-                break;
-        case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
-                if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
-                  glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
-                  checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
-                  glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-                  checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-                  switch (opr1) {
-                  case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
-                  case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
-                  case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
-                  case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
-                  }
-                  glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
-                  checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
-                  glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
-                  checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
-                  switch (opr1) {
-                  case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
-                  case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
-                  case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
-                  case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
-                  }
-                  glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
-                  checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
-                  glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
-                  checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
-                  glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
-                  checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
-                  glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-                  checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-                } else
-                  Handled = FALSE;
-                break;
-        case WINED3DTOP_MULTIPLYADD:
-                if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
-                  glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
-                  checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
-                  glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
-                  checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-                  glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
-                  checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
-                  glTexEnvi(GL_TEXTURE_ENV, src1_target, src3);
-                  checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
-                  glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3);
-                  checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
-                  glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
-                  checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
-                  glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
-                  checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
-                  glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
-                  checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
-                } else
-                  Handled = FALSE;
-                break;
-        case WINED3DTOP_BUMPENVMAPLUMINANCE:
-                if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
-                    /* Some apps use BUMPENVMAPLUMINANCE instead of D3DTOP_BUMPENVMAP, although
-                     * they check for the non-luminance cap flag. Well, give them what they asked
-                     * for :-)
-                     */
-                    WARN("Application uses WINED3DTOP_BUMPENVMAPLUMINANCE\n");
-                } else {
-                    Handled = FALSE;
-                    break;
-                }
-                /* Fall through */
-        case WINED3DTOP_BUMPENVMAP:
-                if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
-                    TRACE("Using ati bumpmap on stage %d, target %d\n", Stage, Stage + 1);
-                    glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI);
-                    checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI)");
-                    glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1);
-                    checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1)");
-                    glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
-                    checkGLcall("GL_TEXTURE_ENV, src0_target, src3");
-                    glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
-                    checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3");
-                    glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
-                    checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-                    glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
-                    checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
-                    glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
-                    checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
-                    glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
-                    checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
-
-                    Handled = TRUE;
-                    break;
-                } else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
-                    /* Technically texture shader support without register combiners is possible, but not expected to occur
-                     * on real world cards, so for now a fixme should be enough
-                     */
-                    FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
-                }
-        default:
-                Handled = FALSE;
-        }
-
-        if (Handled) {
-          BOOL  combineOK = TRUE;
-          if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
-            DWORD op2;
-
-            if (isAlpha) {
-              op2 = This->stateBlock->textureState[Stage][WINED3DTSS_COLOROP];
-            } else {
-              op2 = This->stateBlock->textureState[Stage][WINED3DTSS_ALPHAOP];
-            }
-
-            /* Note: If COMBINE4 in effect can't go back to combine! */
-            switch (op2) {
-            case WINED3DTOP_ADDSMOOTH:
-            case WINED3DTOP_BLENDTEXTUREALPHAPM:
-            case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
-            case WINED3DTOP_MODULATECOLOR_ADDALPHA:
-            case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
-            case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
-            case WINED3DTOP_MULTIPLYADD:
-              /* Ignore those implemented in both cases */
-              switch (op) {
-              case WINED3DTOP_SELECTARG1:
-              case WINED3DTOP_SELECTARG2:
-                combineOK = FALSE;
-                Handled   = FALSE;
-                break;
-              default:
-                FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
-                return;
-              }
-            }
-          }
-
-          if (combineOK) {
-            glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
-            checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
-
-            return;
-          }
-        }
-
-        /* After all the extensions, if still unhandled, report fixme */
-        FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
-#undef GLINFO_LOCATION
-}
-
 /* Setup this textures matrix according to the texture flags*/
 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype)
 {
@@ -2701,6 +1210,7 @@ void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, B
     glLoadMatrixf(mat);
     checkGLcall("glLoadMatrixf(mat)");
 }
+#undef GLINFO_LOCATION
 
 #define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
 
index fdbb4a3..61b2983 100644 (file)
@@ -1730,11 +1730,12 @@ const char *debug_fbostatus(GLenum status);
 const char *debug_glerror(GLenum error);
 const char *debug_d3dbasis(WINED3DBASISTYPE basis);
 const char *debug_d3ddegree(WINED3DDEGREETYPE order);
+const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop);
 
 /* Routines for GL <-> D3D values */
 GLenum StencilOp(DWORD op);
 GLenum CompareFunc(DWORD func);
-void   set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3);
+BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3);
 void   set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx, DWORD dst);
 void   set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype);
 void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context);