wined3d: Avoid wasting a uniform.
[wine] / dlls / wined3d / glsl_shader.c
1 /*
2  * GLSL pixel and vertex shader implementation
3  *
4  * Copyright 2006 Jason Green 
5  * Copyright 2006 Henri Verbeet
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include "config.h"
23 #include <stdio.h>
24 #include "wined3d_private.h"
25
26 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
27
28 #define GLINFO_LOCATION      (*gl_info)
29
30 /** Prints the GLSL info log which will contain error messages if they exist */
31 void print_glsl_info_log(WineD3D_GL_Info *gl_info, GLhandleARB obj) {
32     
33     int infologLength = 0;
34     char *infoLog;
35
36     GL_EXTCALL(glGetObjectParameterivARB(obj,
37                GL_OBJECT_INFO_LOG_LENGTH_ARB,
38                &infologLength));
39
40     /* A size of 1 is just a null-terminated string, so the log should be bigger than
41      * that if there are errors. */
42     if (infologLength > 1)
43     {
44         infoLog = (char *)HeapAlloc(GetProcessHeap(), 0, infologLength);
45         GL_EXTCALL(glGetInfoLogARB(obj, infologLength, NULL, infoLog));
46         FIXME("Error received from GLSL shader #%u: %s\n", obj, debugstr_a(infoLog));
47         HeapFree(GetProcessHeap(), 0, infoLog);
48     }
49 }
50
51 /**
52  * Loads (pixel shader) samplers
53  */
54 void shader_glsl_load_psamplers(
55     WineD3D_GL_Info *gl_info,
56     IWineD3DStateBlock* iface) {
57
58     IWineD3DStateBlockImpl* stateBlock = (IWineD3DStateBlockImpl*) iface;
59     GLhandleARB programId = stateBlock->glsl_program->programId;
60     GLhandleARB name_loc;
61     int i;
62     char sampler_name[20];
63
64     for (i=0; i< GL_LIMITS(samplers); ++i) {
65         if (stateBlock->textures[i] != NULL) {
66            snprintf(sampler_name, sizeof(sampler_name), "Psampler%d", i);
67            name_loc = GL_EXTCALL(glGetUniformLocationARB(programId, sampler_name));
68            if (name_loc != -1) {
69                TRACE_(d3d_shader)("Loading %s for texture %d\n", sampler_name, i);
70                GL_EXTCALL(glUniform1iARB(name_loc, i));
71                checkGLcall("glUniform1iARB");
72            }
73         }
74     }
75 }
76
77 /** 
78  * Loads floating point constants (aka uniforms) into the currently set GLSL program.
79  * When constant_list == NULL, it will load all the constants.
80  */
81 static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl* This, WineD3D_GL_Info *gl_info,
82         unsigned int max_constants, float* constants, GLhandleARB *constant_locations,
83         struct list *constant_list) {
84     local_constant* lconst;
85     GLhandleARB tmp_loc;
86     int i;
87
88     if (!constant_list) {
89         if (TRACE_ON(d3d_shader)) {
90             for (i = 0; i < max_constants; ++i) {
91                 tmp_loc = constant_locations[i];
92                 if (tmp_loc != -1) {
93                     TRACE("Loading constants %i: %f, %f, %f, %f\n", i,
94                             constants[i * 4 + 0], constants[i * 4 + 1],
95                             constants[i * 4 + 2], constants[i * 4 + 3]);
96                 }
97             }
98         }
99         for (i = 0; i < max_constants; ++i) {
100             tmp_loc = constant_locations[i];
101             if (tmp_loc != -1) {
102                 /* We found this uniform name in the program - go ahead and send the data */
103                 GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, constants + (i * 4)));
104             }
105         }
106         checkGLcall("glUniform4fvARB()");
107     } else {
108         constant_entry *constant;
109         if (TRACE_ON(d3d_shader)) {
110             LIST_FOR_EACH_ENTRY(constant, constant_list, constant_entry, entry) {
111                 i = constant->idx;
112                 tmp_loc = constant_locations[i];
113                 if (tmp_loc != -1) {
114                     TRACE("Loading constants %i: %f, %f, %f, %f\n", i,
115                             constants[i * 4 + 0], constants[i * 4 + 1],
116                             constants[i * 4 + 2], constants[i * 4 + 3]);
117                 }
118             }
119         }
120         LIST_FOR_EACH_ENTRY(constant, constant_list, constant_entry, entry) {
121             i = constant->idx;
122             tmp_loc = constant_locations[i];
123             if (tmp_loc != -1) {
124                 /* We found this uniform name in the program - go ahead and send the data */
125                 GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, constants + (i * 4)));
126             }
127         }
128         checkGLcall("glUniform4fvARB()");
129     }
130
131     /* Load immediate constants */
132     if (TRACE_ON(d3d_shader)) {
133         LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
134             tmp_loc = constant_locations[lconst->idx];
135             if (tmp_loc != -1) {
136                 GLfloat* values = (GLfloat*)lconst->value;
137                 TRACE("Loading local constants %i: %f, %f, %f, %f\n", lconst->idx,
138                         values[0], values[1], values[2], values[3]);
139             }
140         }
141     }
142     LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
143         tmp_loc = constant_locations[lconst->idx];
144         if (tmp_loc != -1) {
145             /* We found this uniform name in the program - go ahead and send the data */
146             GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, (GLfloat*)lconst->value));
147         }
148     }
149     checkGLcall("glUniform4fvARB()");
150 }
151
152 /** 
153  * Loads integer constants (aka uniforms) into the currently set GLSL program.
154  * When @constants_set == NULL, it will load all the constants.
155  */
156 void shader_glsl_load_constantsI(
157     IWineD3DBaseShaderImpl* This,
158     WineD3D_GL_Info *gl_info,
159     GLhandleARB programId,
160     unsigned max_constants,
161     int* constants,
162     BOOL* constants_set) {
163     
164     GLhandleARB tmp_loc;
165     int i;
166     char tmp_name[8];
167     char is_pshader = shader_is_pshader_version(This->baseShader.hex_version);
168     const char* prefix = is_pshader? "PI":"VI";
169     struct list* ptr;
170
171     for (i=0; i<max_constants; ++i) {
172         if (NULL == constants_set || constants_set[i]) {
173
174             TRACE("Loading constants %i: %i, %i, %i, %i\n",
175                   i, constants[i*4], constants[i*4+1], constants[i*4+2], constants[i*4+3]);
176
177             /* TODO: Benchmark and see if it would be beneficial to store the 
178              * locations of the constants to avoid looking up each time */
179             snprintf(tmp_name, sizeof(tmp_name), "%s[%i]", prefix, i);
180             tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, tmp_name));
181             if (tmp_loc != -1) {
182                 /* We found this uniform name in the program - go ahead and send the data */
183                 GL_EXTCALL(glUniform4ivARB(tmp_loc, 1, &constants[i*4]));
184                 checkGLcall("glUniform4ivARB");
185             }
186         }
187     }
188
189     /* Load immediate constants */
190     ptr = list_head(&This->baseShader.constantsI);
191     while (ptr) {
192         local_constant* lconst = LIST_ENTRY(ptr, struct local_constant, entry);
193         unsigned int idx = lconst->idx;
194         GLint* values = (GLint*) lconst->value;
195
196         TRACE("Loading local constants %i: %i, %i, %i, %i\n", idx,
197             values[0], values[1], values[2], values[3]);
198
199         snprintf(tmp_name, sizeof(tmp_name), "%s[%i]", prefix, idx);
200         tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, tmp_name));
201         if (tmp_loc != -1) {
202             /* We found this uniform name in the program - go ahead and send the data */
203             GL_EXTCALL(glUniform4ivARB(tmp_loc, 1, values));
204             checkGLcall("glUniform4ivARB");
205         }
206         ptr = list_next(&This->baseShader.constantsI, ptr);
207     }
208 }
209
210 /** 
211  * Loads boolean constants (aka uniforms) into the currently set GLSL program.
212  * When @constants_set == NULL, it will load all the constants.
213  */
214 void shader_glsl_load_constantsB(
215     IWineD3DBaseShaderImpl* This,
216     WineD3D_GL_Info *gl_info,
217     GLhandleARB programId,
218     unsigned max_constants,
219     BOOL* constants,
220     BOOL* constants_set) {
221     
222     GLhandleARB tmp_loc;
223     int i;
224     char tmp_name[8];
225     char is_pshader = shader_is_pshader_version(This->baseShader.hex_version);
226     const char* prefix = is_pshader? "PB":"VB";
227     struct list* ptr;
228
229     for (i=0; i<max_constants; ++i) {
230         if (NULL == constants_set || constants_set[i]) {
231
232             TRACE("Loading constants %i: %i;\n", i, constants[i*4]);
233
234             /* TODO: Benchmark and see if it would be beneficial to store the 
235              * locations of the constants to avoid looking up each time */
236             snprintf(tmp_name, sizeof(tmp_name), "%s[%i]", prefix, i);
237             tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, tmp_name));
238             if (tmp_loc != -1) {
239                 /* We found this uniform name in the program - go ahead and send the data */
240                 GL_EXTCALL(glUniform1ivARB(tmp_loc, 1, &constants[i*4]));
241                 checkGLcall("glUniform1ivARB");
242             }
243         }
244     }
245
246     /* Load immediate constants */
247     ptr = list_head(&This->baseShader.constantsB);
248     while (ptr) {
249         local_constant* lconst = LIST_ENTRY(ptr, struct local_constant, entry);
250         unsigned int idx = lconst->idx;
251         GLint* values = (GLint*) lconst->value;
252
253         TRACE("Loading local constants %i: %i\n", idx, values[0]);
254
255         snprintf(tmp_name, sizeof(tmp_name), "%s[%i]", prefix, idx);
256         tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, tmp_name));
257         if (tmp_loc != -1) {
258             /* We found this uniform name in the program - go ahead and send the data */
259             GL_EXTCALL(glUniform1ivARB(tmp_loc, 1, values));
260             checkGLcall("glUniform1ivARB");
261         }
262         ptr = list_next(&This->baseShader.constantsB, ptr);
263     }
264 }
265
266
267
268 /**
269  * Loads the app-supplied constants into the currently set GLSL program.
270  */
271 void shader_glsl_load_constants(
272     IWineD3DStateBlock* iface,
273     char usePixelShader,
274     char useVertexShader) {
275     
276     IWineD3DStateBlockImpl* stateBlock = (IWineD3DStateBlockImpl*) iface;
277     WineD3D_GL_Info *gl_info = &((IWineD3DImpl*)stateBlock->wineD3DDevice->wineD3D)->gl_info;
278     GLhandleARB *constant_locations;
279     struct list *constant_list;
280     GLhandleARB programId;
281     
282     if (!stateBlock->glsl_program) {
283         /* No GLSL program set - nothing to do. */
284         return;
285     }
286     programId = stateBlock->glsl_program->programId;
287
288     if (useVertexShader) {
289         IWineD3DBaseShaderImpl* vshader = (IWineD3DBaseShaderImpl*) stateBlock->vertexShader;
290         IWineD3DVertexShaderImpl* vshader_impl = (IWineD3DVertexShaderImpl*) vshader;
291         GLint pos;
292
293         IWineD3DVertexDeclarationImpl* vertexDeclaration =
294             (IWineD3DVertexDeclarationImpl*) vshader_impl->vertexDeclaration;
295
296         constant_locations = stateBlock->glsl_program->vuniformF_locations;
297         constant_list = &stateBlock->set_vconstantsF;
298
299         if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) {
300             /* Load DirectX 8 float constants/uniforms for vertex shader */
301             shader_glsl_load_constantsF(vshader, gl_info, GL_LIMITS(vshader_constantsF),
302                     vertexDeclaration->constants, constant_locations, NULL);
303         }
304
305         /* Load DirectX 9 float constants/uniforms for vertex shader */
306         shader_glsl_load_constantsF(vshader, gl_info, GL_LIMITS(vshader_constantsF),
307                 stateBlock->vertexShaderConstantF, constant_locations, constant_list);
308
309         /* Load DirectX 9 integer constants/uniforms for vertex shader */
310         shader_glsl_load_constantsI(vshader, gl_info, programId, MAX_CONST_I,
311                                     stateBlock->vertexShaderConstantI,
312                                     stateBlock->set.vertexShaderConstantsI);
313
314         /* Load DirectX 9 boolean constants/uniforms for vertex shader */
315         shader_glsl_load_constantsB(vshader, gl_info, programId, MAX_CONST_B,
316                                     stateBlock->vertexShaderConstantB,
317                                     stateBlock->set.vertexShaderConstantsB);
318
319         /* Upload the position fixup params */
320         pos = GL_EXTCALL(glGetUniformLocationARB(programId, "posFixup"));
321         checkGLcall("glGetUniformLocationARB");
322         glUniform4fvARB(pos, 1, &vshader_impl->wineD3DDevice->posFixup[0]);
323         checkGLcall("glUniform4fvARB");
324     }
325
326     if (usePixelShader) {
327
328         IWineD3DBaseShaderImpl* pshader = (IWineD3DBaseShaderImpl*) stateBlock->pixelShader;
329
330         constant_locations = stateBlock->glsl_program->puniformF_locations;
331         constant_list = &stateBlock->set_pconstantsF;
332
333         /* Load pixel shader samplers */
334         shader_glsl_load_psamplers(gl_info, iface);
335
336         /* Load DirectX 9 float constants/uniforms for pixel shader */
337         shader_glsl_load_constantsF(pshader, gl_info, GL_LIMITS(pshader_constantsF),
338                 stateBlock->pixelShaderConstantF, constant_locations, constant_list);
339
340         /* Load DirectX 9 integer constants/uniforms for pixel shader */
341         shader_glsl_load_constantsI(pshader, gl_info, programId, MAX_CONST_I,
342                                     stateBlock->pixelShaderConstantI, 
343                                     stateBlock->set.pixelShaderConstantsI);
344         
345         /* Load DirectX 9 boolean constants/uniforms for pixel shader */
346         shader_glsl_load_constantsB(pshader, gl_info, programId, MAX_CONST_B,
347                                     stateBlock->pixelShaderConstantB, 
348                                     stateBlock->set.pixelShaderConstantsB);
349     }
350 }
351
352 /** Generate the variable & register declarations for the GLSL output target */
353 void shader_generate_glsl_declarations(
354     IWineD3DBaseShader *iface,
355     shader_reg_maps* reg_maps,
356     SHADER_BUFFER* buffer,
357     WineD3D_GL_Info* gl_info) {
358
359     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
360     int i;
361
362     /* There are some minor differences between pixel and vertex shaders */
363     char pshader = shader_is_pshader_version(This->baseShader.hex_version);
364     char prefix = pshader ? 'P' : 'V';
365
366     /* Prototype the subroutines */
367     for (i = 0; i < This->baseShader.limits.label; i++) {
368         if (reg_maps->labels[i])
369             shader_addline(buffer, "void subroutine%lu();\n", i);
370     }
371
372     /* Declare the constants (aka uniforms) */
373     if (This->baseShader.limits.constant_float > 0) {
374         unsigned max_constantsF = min(This->baseShader.limits.constant_float, 
375                 (pshader ? GL_LIMITS(pshader_constantsF) : GL_LIMITS(vshader_constantsF)));
376         shader_addline(buffer, "uniform vec4 %cC[%u];\n", prefix, max_constantsF);
377     }
378
379     if (This->baseShader.limits.constant_int > 0)
380         shader_addline(buffer, "uniform ivec4 %cI[%u];\n", prefix, This->baseShader.limits.constant_int);
381
382     if (This->baseShader.limits.constant_bool > 0)
383         shader_addline(buffer, "uniform bool %cB[%u];\n", prefix, This->baseShader.limits.constant_bool);
384
385     if(!pshader)
386         shader_addline(buffer, "uniform vec4 posFixup;\n");
387
388     /* Declare texture samplers */ 
389     for (i = 0; i < This->baseShader.limits.sampler; i++) {
390         if (reg_maps->samplers[i]) {
391
392             DWORD stype = reg_maps->samplers[i] & WINED3DSP_TEXTURETYPE_MASK;
393             switch (stype) {
394
395                 case WINED3DSTT_1D:
396                     shader_addline(buffer, "uniform sampler1D %csampler%lu;\n", prefix, i);
397                     break;
398                 case WINED3DSTT_2D:
399                     shader_addline(buffer, "uniform sampler2D %csampler%lu;\n", prefix, i);
400                     break;
401                 case WINED3DSTT_CUBE:
402                     shader_addline(buffer, "uniform samplerCube %csampler%lu;\n", prefix, i);
403                     break;
404                 case WINED3DSTT_VOLUME:
405                     shader_addline(buffer, "uniform sampler3D %csampler%lu;\n", prefix, i);
406                     break;
407                 default:
408                     shader_addline(buffer, "uniform unsupported_sampler %csampler%lu;\n", prefix, i);
409                     FIXME("Unrecognized sampler type: %#lx\n", stype);
410                     break;
411             }
412         }
413     }
414     
415     /* Declare address variables */
416     for (i = 0; i < This->baseShader.limits.address; i++) {
417         if (reg_maps->address[i])
418             shader_addline(buffer, "ivec4 A%ld;\n", i);
419     }
420
421     /* Declare texture coordinate temporaries and initialize them */
422     for (i = 0; i < This->baseShader.limits.texcoord; i++) {
423         if (reg_maps->texcoord[i]) 
424             shader_addline(buffer, "vec4 T%lu = gl_TexCoord[%lu];\n", i, i);
425     }
426
427     /* Declare input register temporaries */
428     for (i=0; i < This->baseShader.limits.packed_input; i++) {
429         if (reg_maps->packed_input[i])
430             shader_addline(buffer, "vec4 IN%lu;\n", i);
431     }
432
433     /* Declare output register temporaries */
434     for (i = 0; i < This->baseShader.limits.packed_output; i++) {
435         if (reg_maps->packed_output[i])
436             shader_addline(buffer, "vec4 OUT%lu;\n", i);
437     }
438
439     /* Declare temporary variables */
440     for(i = 0; i < This->baseShader.limits.temporary; i++) {
441         if (reg_maps->temporary[i])
442             shader_addline(buffer, "vec4 R%lu;\n", i);
443     }
444
445     /* Declare attributes */
446     for (i = 0; i < This->baseShader.limits.attributes; i++) {
447         if (reg_maps->attributes[i])
448             shader_addline(buffer, "attribute vec4 attrib%i;\n", i);
449     }
450
451     /* Declare loop register aL */
452     if (reg_maps->loop) {
453         shader_addline(buffer, "int aL;\n");
454         shader_addline(buffer, "int tmpInt;\n");
455     }
456     
457     /* Temporary variables for matrix operations */
458     shader_addline(buffer, "vec4 tmp0;\n");
459     shader_addline(buffer, "vec4 tmp1;\n");
460
461     /* Start the main program */
462     shader_addline(buffer, "void main() {\n");
463 }
464
465 /*****************************************************************************
466  * Functions to generate GLSL strings from DirectX Shader bytecode begin here.
467  *
468  * For more information, see http://wiki.winehq.org/DirectX-Shaders
469  ****************************************************************************/
470
471 /* Prototypes */
472 static void shader_glsl_add_param(
473     SHADER_OPCODE_ARG* arg,
474     const DWORD param,
475     const DWORD addr_token,
476     BOOL is_input,
477     char *reg_name,
478     char *reg_mask,
479     char *out_str);
480
481 /** Used for opcode modifiers - They multiply the result by the specified amount */
482 static const char* shift_glsl_tab[] = {
483     "",           /*  0 (none) */ 
484     "2.0 * ",     /*  1 (x2)   */ 
485     "4.0 * ",     /*  2 (x4)   */ 
486     "8.0 * ",     /*  3 (x8)   */ 
487     "16.0 * ",    /*  4 (x16)  */ 
488     "32.0 * ",    /*  5 (x32)  */ 
489     "",           /*  6 (x64)  */ 
490     "",           /*  7 (x128) */ 
491     "",           /*  8 (d256) */ 
492     "",           /*  9 (d128) */ 
493     "",           /* 10 (d64)  */ 
494     "",           /* 11 (d32)  */ 
495     "0.0625 * ",  /* 12 (d16)  */ 
496     "0.125 * ",   /* 13 (d8)   */ 
497     "0.25 * ",    /* 14 (d4)   */ 
498     "0.5 * "      /* 15 (d2)   */ 
499 };
500
501 /** Print the beginning of the generated GLSL string. example: "reg_name.xyzw = vec4("
502  * Will also change the reg_mask if necessary (not all register types are equal in DX vs GL)  */
503 static void shader_glsl_add_dst(DWORD param, const char* reg_name, char* reg_mask, char* outStr) {
504
505     int shift = (param & D3DSP_DSTSHIFT_MASK) >> D3DSP_DSTSHIFT_SHIFT;
506     char cast[6];
507     
508     if ((shader_get_regtype(param) == D3DSPR_RASTOUT)
509          && ((param & D3DSP_REGNUM_MASK) != 0)) {
510         /* gl_FogFragCoord or glPointSize - both floats */
511         strcpy(cast, "float");
512         strcpy(reg_mask, "");
513
514     } else if (reg_name[0] == 'A') {
515         /* Address register for vertex shaders (ivec4) */
516         strcpy(cast, "ivec4");
517         
518     } else {
519         /* Everything else should be a 4 component float vector */
520         strcpy(cast, "vec4");
521     }
522     
523     sprintf(outStr, "%s%s = %s%s(", reg_name, reg_mask, shift_glsl_tab[shift], cast); 
524 }
525
526 /* Generate a GLSL parameter that does the input modifier computation and return the input register/mask to use */
527 static void shader_glsl_gen_modifier (
528     const DWORD instr,
529     const char *in_reg,
530     const char *in_regswizzle,
531     char *out_str) {
532
533     out_str[0] = 0;
534     
535     if (instr == D3DSIO_TEXKILL)
536         return;
537
538     switch (instr & D3DSP_SRCMOD_MASK) {
539     case D3DSPSM_NONE:
540         sprintf(out_str, "%s%s", in_reg, in_regswizzle);
541         break;
542     case D3DSPSM_NEG:
543         sprintf(out_str, "-%s%s", in_reg, in_regswizzle);
544         break;
545     case D3DSPSM_NOT:
546         sprintf(out_str, "!%s%s", in_reg, in_regswizzle);
547         break;
548     case D3DSPSM_BIAS:
549         sprintf(out_str, "(%s%s - vec4(0.5)%s)", in_reg, in_regswizzle, in_regswizzle);
550         break;
551     case D3DSPSM_BIASNEG:
552         sprintf(out_str, "-(%s%s - vec4(0.5)%s)", in_reg, in_regswizzle, in_regswizzle);
553         break;
554     case D3DSPSM_SIGN:
555         sprintf(out_str, "(2.0 * (%s%s - 0.5))", in_reg, in_regswizzle);
556         break;
557     case D3DSPSM_SIGNNEG:
558         sprintf(out_str, "-(2.0 * (%s%s - 0.5))", in_reg, in_regswizzle);
559         break;
560     case D3DSPSM_COMP:
561         sprintf(out_str, "(1.0 - %s%s)", in_reg, in_regswizzle);
562         break;
563     case D3DSPSM_X2:
564         sprintf(out_str, "(2.0 * %s%s)", in_reg, in_regswizzle);
565         break;
566     case D3DSPSM_X2NEG:
567         sprintf(out_str, "-(2.0 * %s%s)", in_reg, in_regswizzle);
568         break;
569     case D3DSPSM_DZ:    /* reg1_db = { reg1.r/b, reg1.g/b, ...}  The g & a components are undefined, so we'll leave them alone */
570         sprintf(out_str, "vec4(%s.r / %s.b, %s.g / %s.b, %s.b, %s.a)", in_reg, in_reg, in_reg, in_reg, in_reg, in_reg);
571         break;
572     case D3DSPSM_DW:
573         sprintf(out_str, "vec4(%s.r / %s.a, %s.g / %s.a, %s.b, %s.a)", in_reg, in_reg, in_reg, in_reg, in_reg, in_reg);
574         break;
575     case D3DSPSM_ABS:
576         sprintf(out_str, "abs(%s%s)", in_reg, in_regswizzle);
577         break;
578     case D3DSPSM_ABSNEG:
579         sprintf(out_str, "-abs(%s%s)", in_reg, in_regswizzle);
580         break;
581     default:
582         FIXME("Unhandled modifier %lu\n", (instr & D3DSP_SRCMOD_MASK));
583         sprintf(out_str, "%s%s", in_reg, in_regswizzle);
584     }
585 }
586
587 /** Writes the GLSL variable name that corresponds to the register that the
588  * DX opcode parameter is trying to access */
589 static void shader_glsl_get_register_name(
590     const DWORD param,
591     const DWORD addr_token,
592     char* regstr,
593     BOOL* is_color,
594     SHADER_OPCODE_ARG* arg) {
595
596     /* oPos, oFog and oPts in D3D */
597     const char* hwrastout_reg_names[] = { "gl_Position", "gl_FogFragCoord", "gl_PointSize" };
598
599     WineD3D_GL_Info *gl_info = &((IWineD3DImpl*)((IWineD3DPixelShaderImpl*)arg->shader)->wineD3DDevice->wineD3D)->gl_info;
600     DWORD reg = param & D3DSP_REGNUM_MASK;
601     DWORD regtype = shader_get_regtype(param);
602     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) arg->shader;
603     char pshader = shader_is_pshader_version(This->baseShader.hex_version);
604     char tmpStr[50];
605
606     *is_color = FALSE;   
607  
608     switch (regtype) {
609     case D3DSPR_TEMP:
610         sprintf(tmpStr, "R%lu", reg);
611     break;
612     case D3DSPR_INPUT:
613         if (pshader) {
614             /* Pixel shaders >= 3.0 */
615             if (D3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) >= 3)
616                 sprintf(tmpStr, "IN%lu", reg);
617              else {
618                 if (reg==0)
619                     strcpy(tmpStr, "gl_Color");
620                 else
621                     strcpy(tmpStr, "gl_SecondaryColor");
622             }
623         } else {
624             if (vshader_input_is_color((IWineD3DVertexShader*) This, reg))
625                *is_color = TRUE;
626             sprintf(tmpStr, "attrib%lu", reg);
627         } 
628         break;
629     case D3DSPR_CONST:
630     {
631         const char* prefix = pshader? "PC":"VC";
632
633         /* Relative addressing */
634         if (param & D3DVS_ADDRMODE_RELATIVE) {
635
636            /* Relative addressing on shaders 2.0+ have a relative address token, 
637             * prior to that, it was hard-coded as "A0.x" because there's only 1 register */
638            if (D3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) >= 2)  {
639                char relStr[100], relReg[50], relMask[6];
640                shader_glsl_add_param(arg, addr_token, 0, TRUE, relReg, relMask, relStr);
641                sprintf(tmpStr, "%s[%s + %lu]", prefix, relStr, reg);
642            } else
643                sprintf(tmpStr, "%s[A0.x + %lu]", prefix, reg);
644
645         } else
646              sprintf(tmpStr, "%s[%lu]", prefix, reg);
647
648         break;
649     }
650     case D3DSPR_CONSTINT:
651         if (pshader)
652             sprintf(tmpStr, "PI[%lu]", reg);
653         else
654             sprintf(tmpStr, "VI[%lu]", reg);
655         break;
656     case D3DSPR_CONSTBOOL:
657         if (pshader)
658             sprintf(tmpStr, "PB[%lu]", reg);
659         else
660             sprintf(tmpStr, "VB[%lu]", reg);
661         break;
662     case D3DSPR_TEXTURE: /* case D3DSPR_ADDR: */
663         if (pshader) {
664             sprintf(tmpStr, "T%lu", reg);
665         } else {
666             sprintf(tmpStr, "A%lu", reg);
667         }
668     break;
669     case D3DSPR_LOOP:
670         sprintf(tmpStr, "aL");
671     break;
672     case D3DSPR_SAMPLER:
673         if (pshader)
674             sprintf(tmpStr, "Psampler%lu", reg);
675         else
676             sprintf(tmpStr, "Vsampler%lu", reg);
677     break;
678     case D3DSPR_COLOROUT:
679         if (GL_SUPPORT(ARB_DRAW_BUFFERS)) {
680             sprintf(tmpStr, "gl_FragData[%lu]", reg);
681             if (reg > 0) {
682                 /* TODO: See GL_ARB_draw_buffers */
683                 FIXME("Unsupported write to render target %lu\n", reg);
684             }
685         } else { /* On older cards with GLSL support like the GeforceFX there's only one buffer. */
686             if (reg > 0)
687                 WARN("This OpenGL implementation doesn't support writing to multiple render targets!\n");
688             else
689                 sprintf(tmpStr, "gl_FragColor");
690         }
691     break;
692     case D3DSPR_RASTOUT:
693         sprintf(tmpStr, "%s", hwrastout_reg_names[reg]);
694     break;
695     case D3DSPR_DEPTHOUT:
696         sprintf(tmpStr, "gl_FragDepth");
697     break;
698     case D3DSPR_ATTROUT:
699         if (reg == 0) {
700             sprintf(tmpStr, "gl_FrontColor");
701         } else {
702             sprintf(tmpStr, "gl_FrontSecondaryColor");
703         }
704     break;
705     case D3DSPR_TEXCRDOUT:
706         /* Vertex shaders >= 3.0: D3DSPR_OUTPUT */
707         if (D3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) >= 3)
708             sprintf(tmpStr, "OUT%lu", reg);
709         else
710             sprintf(tmpStr, "gl_TexCoord[%lu]", reg);
711     break;
712     default:
713         FIXME("Unhandled register name Type(%ld)\n", regtype);
714         sprintf(tmpStr, "unrecognized_register");
715     break;
716     }
717
718     strcat(regstr, tmpStr);
719 }
720
721 /* Writes the GLSL writemask for the destination register */
722 static void shader_glsl_get_output_register_swizzle(
723     const DWORD param,
724     char *write_mask) {
725    
726     *write_mask = 0;
727     if ((param & D3DSP_WRITEMASK_ALL) != D3DSP_WRITEMASK_ALL) {
728         strcat(write_mask, ".");
729         if (param & D3DSP_WRITEMASK_0) strcat(write_mask, "x");
730         if (param & D3DSP_WRITEMASK_1) strcat(write_mask, "y");
731         if (param & D3DSP_WRITEMASK_2) strcat(write_mask, "z");
732         if (param & D3DSP_WRITEMASK_3) strcat(write_mask, "w");
733     }
734 }
735
736 static void shader_glsl_get_input_register_swizzle(
737     const DWORD param,
738     BOOL is_color,
739     char *reg_mask) {
740     
741     const char swizzle_reg_chars_color_fix[] = "zyxw";
742     const char swizzle_reg_chars[] = "xyzw";
743     const char* swizzle_regs = NULL;
744    
745     /** operand input */
746     DWORD swizzle = (param & D3DVS_SWIZZLE_MASK) >> D3DVS_SWIZZLE_SHIFT;
747     DWORD swizzle_x = swizzle & 0x03;
748     DWORD swizzle_y = (swizzle >> 2) & 0x03;
749     DWORD swizzle_z = (swizzle >> 4) & 0x03;
750     DWORD swizzle_w = (swizzle >> 6) & 0x03;
751
752     if (is_color) {
753       swizzle_regs = swizzle_reg_chars_color_fix;
754     } else {
755       swizzle_regs = swizzle_reg_chars;
756     }
757
758     /**
759      * swizzle bits fields:
760      *  WWZZYYXX
761      */
762     if ((D3DVS_NOSWIZZLE >> D3DVS_SWIZZLE_SHIFT) == swizzle) { /* D3DVS_NOSWIZZLE == 0xE4 << D3DVS_SWIZZLE_SHIFT */
763       if (is_color) {
764             sprintf(reg_mask, ".%c%c%c%c",
765                 swizzle_regs[swizzle_x],
766                 swizzle_regs[swizzle_y],
767                 swizzle_regs[swizzle_z],
768                 swizzle_regs[swizzle_w]);
769       }
770       return ;
771     }
772     if (swizzle_x == swizzle_y &&
773         swizzle_x == swizzle_z &&
774         swizzle_x == swizzle_w)
775     {
776       sprintf(reg_mask, ".%c", swizzle_regs[swizzle_x]);
777     } else {
778       sprintf(reg_mask, ".%c%c%c%c",
779               swizzle_regs[swizzle_x],
780               swizzle_regs[swizzle_y],
781               swizzle_regs[swizzle_z],
782               swizzle_regs[swizzle_w]);
783     }
784 }
785
786 /** From a given parameter token, generate the corresponding GLSL string.
787  * Also, return the actual register name and swizzle in case the 
788  * caller needs this information as well. */
789 static void shader_glsl_add_param(
790     SHADER_OPCODE_ARG* arg,
791     const DWORD param,
792     const DWORD addr_token,
793     BOOL is_input,
794     char *reg_name,
795     char *reg_mask,
796     char *out_str) {
797
798     BOOL is_color = FALSE;
799     reg_mask[0] = reg_name[0] = out_str[0] = 0;
800
801     shader_glsl_get_register_name(param, addr_token, reg_name, &is_color, arg);
802     
803     if (is_input) {
804         shader_glsl_get_input_register_swizzle(param, is_color, reg_mask);
805         shader_glsl_gen_modifier(param, reg_name, reg_mask, out_str);
806     } else {
807         shader_glsl_get_output_register_swizzle(param, reg_mask);
808         sprintf(out_str, "%s%s", reg_name, reg_mask);
809     }
810 }
811
812 /** Process GLSL instruction modifiers */
813 void shader_glsl_add_instruction_modifiers(SHADER_OPCODE_ARG* arg) {
814     
815     DWORD mask = arg->dst & D3DSP_DSTMOD_MASK;
816  
817     if (arg->opcode->dst_token && mask != 0) {
818         char dst_reg[50];
819         char dst_mask[6];
820         char dst_str[100];
821        
822         shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
823
824         if (mask & D3DSPDM_SATURATE) {
825             /* _SAT means to clamp the value of the register to between 0 and 1 */
826             shader_addline(arg->buffer, "%s%s = clamp(%s%s, 0.0, 1.0);\n", dst_reg, dst_mask, dst_reg, dst_mask);
827         }
828         if (mask & D3DSPDM_MSAMPCENTROID) {
829             FIXME("_centroid modifier not handled\n");
830         }
831         if (mask & D3DSPDM_PARTIALPRECISION) {
832             /* MSDN says this modifier can be safely ignored, so that's what we'll do. */
833         }
834     }
835 }
836
837 static inline const char* shader_get_comp_op(
838     const DWORD opcode) {
839
840     DWORD op = (opcode & INST_CONTROLS_MASK) >> INST_CONTROLS_SHIFT;
841     switch (op) {
842         case COMPARISON_GT: return ">";
843         case COMPARISON_EQ: return "==";
844         case COMPARISON_GE: return ">=";
845         case COMPARISON_LT: return "<";
846         case COMPARISON_NE: return "!=";
847         case COMPARISON_LE: return "<=";
848         default:
849             FIXME("Unrecognized comparison value: %lu\n", op);
850             return "(\?\?)";
851     }
852 }
853
854 /*****************************************************************************
855  * 
856  * Begin processing individual instruction opcodes
857  * 
858  ****************************************************************************/
859
860 /* Generate GLSL arithmetic functions (dst = src1 + src2) */
861 void shader_glsl_arith(SHADER_OPCODE_ARG* arg) {
862
863     CONST SHADER_OPCODE* curOpcode = arg->opcode;
864     SHADER_BUFFER* buffer = arg->buffer;
865     char tmpLine[256];
866     char dst_reg[50], src0_reg[50], src1_reg[50];
867     char dst_mask[6], src0_mask[6], src1_mask[6];
868     char dst_str[100], src0_str[100], src1_str[100];
869
870     shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
871     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
872     shader_glsl_add_param(arg, arg->src[1], arg->src_addr[1], TRUE, src1_reg, src1_mask, src1_str);
873     shader_glsl_add_dst(arg->dst, dst_reg, dst_mask, tmpLine);
874     strcat(tmpLine, "vec4(");
875     strcat(tmpLine, src0_str);
876     strcat(tmpLine, ")");
877
878     /* Determine the GLSL operator to use based on the opcode */
879     switch (curOpcode->opcode) {
880         case D3DSIO_MUL:    strcat(tmpLine, " * "); break;
881         case D3DSIO_ADD:    strcat(tmpLine, " + "); break;
882         case D3DSIO_SUB:    strcat(tmpLine, " - "); break;
883         default:
884             FIXME("Opcode %s not yet handled in GLSL\n", curOpcode->name);
885             break;
886     }
887     shader_addline(buffer, "%svec4(%s))%s;\n", tmpLine, src1_str, dst_mask);
888 }
889
890 /* Process the D3DSIO_MOV opcode using GLSL (dst = src) */
891 void shader_glsl_mov(SHADER_OPCODE_ARG* arg) {
892
893     SHADER_BUFFER* buffer = arg->buffer;
894     char tmpLine[256];
895     char dst_str[100], src0_str[100];
896     char dst_reg[50], src0_reg[50];
897     char dst_mask[6], src0_mask[6];
898
899     shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
900     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
901     shader_glsl_add_dst(arg->dst, dst_reg, dst_mask, tmpLine);
902     shader_addline(buffer, "%s%s)%s;\n", tmpLine, src0_str, dst_mask);
903 }
904
905 /* Process the dot product operators DP3 and DP4 in GLSL (dst = dot(src0, src1)) */
906 void shader_glsl_dot(SHADER_OPCODE_ARG* arg) {
907
908     CONST SHADER_OPCODE* curOpcode = arg->opcode;
909     SHADER_BUFFER* buffer = arg->buffer;
910     char tmpDest[100];
911     char dst_str[100], src0_str[100], src1_str[100];
912     char dst_reg[50], src0_reg[50], src1_reg[50];
913     char dst_mask[6], src0_mask[6], src1_mask[6];
914     char cast[6];
915
916     shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
917     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
918     shader_glsl_add_param(arg, arg->src[1], arg->src_addr[1], TRUE, src1_reg, src1_mask, src1_str);
919
920     shader_glsl_add_dst(arg->dst, dst_reg, dst_mask, tmpDest);
921  
922     /* Need to cast the src vectors to vec3 for dp3, and vec4 for dp4 */
923     if (curOpcode->opcode == D3DSIO_DP4)
924         strcpy(cast, "vec4(");
925     else
926         strcpy(cast, "vec3(");
927     
928     shader_addline(buffer, "%sdot(%s%s), %s%s)))%s;\n",
929                    tmpDest, cast, src0_str, cast, src1_str, dst_mask);
930 }
931
932 /* Map the opcode 1-to-1 to the GL code (arg->dst = instruction(src0, src1, ...) */
933 void shader_glsl_map2gl(SHADER_OPCODE_ARG* arg) {
934
935     CONST SHADER_OPCODE* curOpcode = arg->opcode;
936     SHADER_BUFFER* buffer = arg->buffer;
937     char tmpLine[256];
938     char dst_str[100], src_str[100];
939     char dst_reg[50], src_reg[50];
940     char dst_mask[6], src_mask[6];
941     unsigned i;
942     
943     shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
944
945     shader_glsl_add_dst(arg->dst, dst_reg, dst_mask, tmpLine);
946  
947     /* Determine the GLSL function to use based on the opcode */
948     /* TODO: Possibly make this a table for faster lookups */
949     switch (curOpcode->opcode) {
950             case D3DSIO_MIN:    strcat(tmpLine, "min"); break;
951             case D3DSIO_MAX:    strcat(tmpLine, "max"); break;
952             case D3DSIO_RSQ:    strcat(tmpLine, "inversesqrt"); break;
953             case D3DSIO_ABS:    strcat(tmpLine, "abs"); break;
954             case D3DSIO_FRC:    strcat(tmpLine, "fract"); break;
955             case D3DSIO_POW:    strcat(tmpLine, "pow"); break;
956             case D3DSIO_CRS:    strcat(tmpLine, "cross"); break;
957             case D3DSIO_NRM:    strcat(tmpLine, "normalize"); break;
958             case D3DSIO_LOGP:
959             case D3DSIO_LOG:    strcat(tmpLine, "log2"); break;
960             case D3DSIO_EXP:    strcat(tmpLine, "exp2"); break;
961             case D3DSIO_SGE:    strcat(tmpLine, "greaterThanEqual"); break;
962             case D3DSIO_SLT:    strcat(tmpLine, "lessThan"); break;
963             case D3DSIO_SGN:    strcat(tmpLine, "sign"); break;
964         default:
965             FIXME("Opcode %s not yet handled in GLSL\n", curOpcode->name);
966             break;
967     }
968
969     strcat(tmpLine, "(");
970
971     if (curOpcode->num_params > 0) {
972         strcat(tmpLine, "vec4(");
973         shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src_reg, src_mask, src_str);
974         strcat(tmpLine, src_str);
975         strcat(tmpLine, ")");
976         for (i = 2; i < curOpcode->num_params; ++i) {
977             strcat(tmpLine, ", vec4(");
978             shader_glsl_add_param(arg, arg->src[i-1], arg->src_addr[i-1], TRUE, src_reg, src_mask, src_str);
979             strcat(tmpLine, src_str);
980             strcat(tmpLine, ")");
981         }
982     }
983     shader_addline(buffer, "%s))%s;\n", tmpLine, dst_mask);
984
985 }
986
987 /** Process the D3DSIO_EXPP instruction in GLSL:
988  * For shader model 1.x, do the following (and honor the writemask, so use a temporary variable):
989  *   dst.x = 2^(floor(src))
990  *   dst.y = src - floor(src)
991  *   dst.z = 2^src   (partial precision is allowed, but optional)
992  *   dst.w = 1.0;
993  * For 2.0 shaders, just do this (honoring writemask and swizzle):
994  *   dst = 2^src;    (partial precision is allowed, but optional)
995  */
996 void shader_glsl_expp(SHADER_OPCODE_ARG* arg) {
997
998     char tmpLine[256];
999     char dst_str[100], src_str[100];
1000     char dst_reg[50], src_reg[50];
1001     char dst_mask[6], src_mask[6];
1002     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
1003     DWORD hex_version = This->baseShader.hex_version;
1004     
1005     shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
1006     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src_reg, src_mask, src_str);
1007     shader_glsl_add_dst(arg->dst, dst_reg, dst_mask, tmpLine);
1008
1009     if (hex_version < D3DPS_VERSION(2,0)) {
1010         shader_addline(arg->buffer, "tmp0.x = vec4(exp2(floor(%s))).x;\n", src_str);
1011         shader_addline(arg->buffer, "tmp0.y = vec4(%s - floor(%s)).y;\n", src_str, src_str);
1012         shader_addline(arg->buffer, "tmp0.z = vec4(exp2(%s)).x;\n", src_str);
1013         shader_addline(arg->buffer, "tmp0.w = 1.0;\n");
1014         shader_addline(arg->buffer, "%svec4(tmp0))%s;\n", tmpLine, dst_mask);
1015     } else {
1016         shader_addline(arg->buffer, "%svec4(exp2(%s)))%s;\n", tmpLine, src_str, dst_mask);
1017     }
1018 }
1019
1020 /** Process the RCP (reciprocal or inverse) opcode in GLSL (dst = 1 / src) */
1021 void shader_glsl_rcp(SHADER_OPCODE_ARG* arg) {
1022
1023     char tmpLine[256];
1024     char dst_str[100], src_str[100];
1025     char dst_reg[50], src_reg[50];
1026     char dst_mask[6], src_mask[6];
1027     
1028     shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
1029     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src_reg, src_mask, src_str);
1030     shader_glsl_add_dst(arg->dst, dst_reg, dst_mask, tmpLine);
1031     strcat(tmpLine, "1.0 / ");
1032     shader_addline(arg->buffer, "%s%s)%s;\n", tmpLine, src_str, dst_mask);
1033 }
1034
1035 /** Process signed comparison opcodes in GLSL. */
1036 void shader_glsl_compare(SHADER_OPCODE_ARG* arg) {
1037
1038     char tmpLine[256];
1039     char dst_str[100], src0_str[100], src1_str[100];
1040     char dst_reg[50], src0_reg[50], src1_reg[50];
1041     char dst_mask[6], src0_mask[6], src1_mask[6];
1042     
1043     shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
1044     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
1045     shader_glsl_add_dst(arg->dst, dst_reg, dst_mask, tmpLine);
1046
1047     /* If we are comparing vectors and not scalars, we should process this through map2gl using the GLSL functions. */
1048     if (strlen(src0_mask) != 2) {
1049         shader_glsl_map2gl(arg);
1050     } else {
1051         char compareStr[3];
1052         compareStr[0] = 0;
1053         shader_glsl_add_param(arg, arg->src[1], arg->src_addr[1], TRUE, src1_reg, src1_mask, src1_str);
1054
1055         switch (arg->opcode->opcode) {
1056             case D3DSIO_SLT:    strcpy(compareStr, "<"); break;
1057             case D3DSIO_SGE:    strcpy(compareStr, ">="); break;
1058             default:
1059                 FIXME("Can't handle opcode %s\n", arg->opcode->name);
1060         }
1061         shader_addline(arg->buffer, "%s(float(%s) %s float(%s)) ? 1.0 : 0.0)%s;\n",
1062                        tmpLine, src0_str, compareStr, src1_str, dst_mask);
1063     }
1064 }
1065
1066 /** Process CMP instruction in GLSL (dst = src0.x > 0.0 ? src1.x : src2.x), per channel */
1067 void shader_glsl_cmp(SHADER_OPCODE_ARG* arg) {
1068
1069     char tmpLine[256];
1070     char dst_str[100], src0_str[100], src1_str[100], src2_str[100];
1071     char dst_reg[50], src0_reg[50], src1_reg[50], src2_reg[50];
1072     char dst_mask[6], src0_mask[6], src1_mask[6], src2_mask[6];
1073    
1074     shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
1075     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
1076     shader_glsl_add_param(arg, arg->src[1], arg->src_addr[1], TRUE, src1_reg, src1_mask, src1_str);
1077     shader_glsl_add_param(arg, arg->src[2], arg->src_addr[2], TRUE, src2_reg, src2_mask, src2_str);
1078
1079     shader_glsl_add_dst(arg->dst, dst_reg, dst_mask, tmpLine);
1080     shader_addline(arg->buffer, "%smix(vec4(%s), vec4(%s), vec4(lessThan(vec4(%s), vec4(0.0)))))%s;\n",
1081         tmpLine, src1_str, src2_str, src0_str, dst_mask);
1082 }
1083
1084 /** Process the CND opcode in GLSL (dst = (src0 < 0.5) ? src1 : src2) */
1085 void shader_glsl_cnd(SHADER_OPCODE_ARG* arg) {
1086
1087     char tmpLine[256];
1088     char dst_str[100], src0_str[100], src1_str[100], src2_str[100];
1089     char dst_reg[50], src0_reg[50], src1_reg[50], src2_reg[50];
1090     char dst_mask[6], src0_mask[6], src1_mask[6], src2_mask[6];
1091  
1092     shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
1093     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
1094     shader_glsl_add_param(arg, arg->src[1], arg->src_addr[1], TRUE, src1_reg, src1_mask, src1_str);
1095     shader_glsl_add_param(arg, arg->src[2], arg->src_addr[2], TRUE, src2_reg, src2_mask, src2_str);   
1096     shader_glsl_add_dst(arg->dst, dst_reg, dst_mask, tmpLine);
1097     shader_addline(arg->buffer, "%s(%s < 0.5) ? %s : %s)%s;\n", 
1098                    tmpLine, src0_str, src1_str, src2_str, dst_mask);
1099 }
1100
1101 /** GLSL code generation for D3DSIO_MAD: Multiply the first 2 opcodes, then add the last */
1102 void shader_glsl_mad(SHADER_OPCODE_ARG* arg) {
1103
1104     char tmpLine[256];
1105     char dst_str[100], src0_str[100], src1_str[100], src2_str[100];
1106     char dst_reg[50], src0_reg[50], src1_reg[50], src2_reg[50];
1107     char dst_mask[6], src0_mask[6], src1_mask[6], src2_mask[6];
1108     
1109     shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
1110     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
1111     shader_glsl_add_param(arg, arg->src[1], arg->src_addr[1], TRUE, src1_reg, src1_mask, src1_str);
1112     shader_glsl_add_param(arg, arg->src[2], arg->src_addr[2], TRUE, src2_reg, src2_mask, src2_str);     
1113     shader_glsl_add_dst(arg->dst, dst_reg, dst_mask, tmpLine);
1114
1115     shader_addline(arg->buffer, "%s(vec4(%s) * vec4(%s)) + vec4(%s))%s;\n",
1116                    tmpLine, src0_str, src1_str, src2_str, dst_mask);
1117 }
1118
1119 /** Handles transforming all D3DSIO_M?x? opcodes for 
1120     Vertex shaders to GLSL codes */
1121 void shader_glsl_mnxn(SHADER_OPCODE_ARG* arg) {
1122     int i;
1123     int nComponents = 0;
1124     SHADER_OPCODE_ARG tmpArg;
1125    
1126     memset(&tmpArg, 0, sizeof(SHADER_OPCODE_ARG));
1127
1128     /* Set constants for the temporary argument */
1129     tmpArg.shader      = arg->shader;
1130     tmpArg.buffer      = arg->buffer;
1131     tmpArg.src[0]      = arg->src[0];
1132     tmpArg.src_addr[0] = arg->src_addr[0];
1133     tmpArg.src_addr[1] = arg->src_addr[1];
1134     tmpArg.reg_maps = arg->reg_maps; 
1135     
1136     switch(arg->opcode->opcode) {
1137         case D3DSIO_M4x4:
1138             nComponents = 4;
1139             tmpArg.opcode = &IWineD3DVertexShaderImpl_shader_ins[D3DSIO_DP4];
1140             break;
1141         case D3DSIO_M4x3:
1142             nComponents = 3;
1143             tmpArg.opcode = &IWineD3DVertexShaderImpl_shader_ins[D3DSIO_DP4];
1144             break;
1145         case D3DSIO_M3x4:
1146             nComponents = 4;
1147             tmpArg.opcode = &IWineD3DVertexShaderImpl_shader_ins[D3DSIO_DP3];
1148             break;
1149         case D3DSIO_M3x3:
1150             nComponents = 3;
1151             tmpArg.opcode = &IWineD3DVertexShaderImpl_shader_ins[D3DSIO_DP3];
1152             break;
1153         case D3DSIO_M3x2:
1154             nComponents = 2;
1155             tmpArg.opcode = &IWineD3DVertexShaderImpl_shader_ins[D3DSIO_DP3];
1156             break;
1157         default:
1158             break;
1159     }
1160
1161     for (i = 0; i < nComponents; i++) {
1162         tmpArg.dst = ((arg->dst) & ~D3DSP_WRITEMASK_ALL)|(D3DSP_WRITEMASK_0<<i);
1163         tmpArg.src[1]      = arg->src[1]+i;
1164         shader_glsl_dot(&tmpArg);
1165     }
1166 }
1167
1168 /**
1169     The LRP instruction performs a component-wise linear interpolation 
1170     between the second and third operands using the first operand as the
1171     blend factor.  Equation:  (dst = src2 * (src1 - src0) + src0)
1172 */
1173 void shader_glsl_lrp(SHADER_OPCODE_ARG* arg) {
1174
1175     char tmpLine[256];
1176     char dst_str[100], src0_str[100], src1_str[100], src2_str[100];
1177     char dst_reg[50], src0_reg[50], src1_reg[50], src2_reg[50];
1178     char dst_mask[6], src0_mask[6], src1_mask[6], src2_mask[6];
1179    
1180     shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
1181     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
1182     shader_glsl_add_param(arg, arg->src[1], arg->src_addr[1], TRUE, src1_reg, src1_mask, src1_str);
1183     shader_glsl_add_param(arg, arg->src[2], arg->src_addr[2], TRUE, src2_reg, src2_mask, src2_str);     
1184
1185     shader_glsl_add_dst(arg->dst, dst_reg, dst_mask, tmpLine);
1186     
1187     shader_addline(arg->buffer, "%s%s + %s * (%s - %s))%s;\n",
1188                    tmpLine, src2_str, src0_str, src1_str, src2_str, dst_mask);
1189 }
1190
1191 /** Process the D3DSIO_LIT instruction in GLSL:
1192  * dst.x = dst.w = 1.0
1193  * dst.y = (src0.x > 0) ? src0.x
1194  * dst.z = (src0.x > 0) ? ((src0.y > 0) ? pow(src0.y, src.w) : 0) : 0
1195  *                                        where src.w is clamped at +- 128
1196  */
1197 void shader_glsl_lit(SHADER_OPCODE_ARG* arg) {
1198
1199     char dst_str[100], src0_str[100];
1200     char dst_reg[50], src0_reg[50];
1201     char dst_mask[6], src0_mask[6];
1202    
1203     shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
1204     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
1205
1206     shader_addline(arg->buffer,
1207         "%s = vec4(1.0, (%s.x > 0.0 ? %s.x : 0.0), (%s.x > 0.0 ? ((%s.y > 0.0) ? pow(%s.y, clamp(%s.w, -128.0, 128.0)) : 0.0) : 0.0), 1.0)%s;\n",
1208         dst_str, src0_reg, src0_reg, src0_reg, src0_reg, src0_reg, src0_reg, dst_mask);
1209 }
1210
1211 /** Process the D3DSIO_DST instruction in GLSL:
1212  * dst.x = 1.0
1213  * dst.y = src0.x * src0.y
1214  * dst.z = src0.z
1215  * dst.w = src1.w
1216  */
1217 void shader_glsl_dst(SHADER_OPCODE_ARG* arg) {
1218
1219     char dst_str[100], src0_str[100], src1_str[100];
1220     char dst_reg[50], src0_reg[50], src1_reg[50];
1221     char dst_mask[6], src0_mask[6], src1_mask[6];
1222    
1223     shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
1224     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
1225     shader_glsl_add_param(arg, arg->src[1], arg->src_addr[1], TRUE, src1_reg, src1_mask, src1_str);
1226
1227     shader_addline(arg->buffer, "%s = vec4(1.0, %s.x * %s.y, %s.z, %s.w)%s;\n",
1228                    dst_str, src0_reg, src1_reg, src0_reg, src1_reg, dst_mask);
1229 }
1230
1231 /** Process the D3DSIO_SINCOS instruction in GLSL:
1232  * VS 2.0 requires that specific cosine and sine constants be passed to this instruction so the hardware
1233  * can handle it.  But, these functions are built-in for GLSL, so we can just ignore the last 2 params.
1234  * 
1235  * dst.x = cos(src0.?)
1236  * dst.y = sin(src0.?)
1237  * dst.z = dst.z
1238  * dst.w = dst.w
1239  */
1240 void shader_glsl_sincos(SHADER_OPCODE_ARG* arg) {
1241     
1242     char dst_str[100], src0_str[100];
1243     char dst_reg[50], src0_reg[50];
1244     char dst_mask[6], src0_mask[6];
1245    
1246     shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
1247     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
1248
1249     shader_addline(arg->buffer, "%s = vec4(cos(%s), sin(%s), %s.z, %s.w)%s;\n",
1250                    dst_str, src0_str, src0_str, dst_reg, dst_reg, dst_mask);
1251 }
1252
1253 /** Process the D3DSIO_LOOP instruction in GLSL:
1254  * Start a for() loop where src0.y is the initial value of aL,
1255  *  increment aL by src0.z for a total of src0.x iterations.
1256  *  Need to use a temporary variable for this operation.
1257  */
1258 void shader_glsl_loop(SHADER_OPCODE_ARG* arg) {
1259     
1260     char src1_str[100];
1261     char src1_reg[50];
1262     char src1_mask[6];
1263     
1264     shader_glsl_add_param(arg, arg->src[1], arg->src_addr[1], TRUE, src1_reg, src1_mask, src1_str);
1265   
1266     shader_addline(arg->buffer, "for (tmpInt = 0, aL = %s.y; tmpInt < %s.x; tmpInt++, aL += %s.z) {\n",
1267                    src1_reg, src1_reg, src1_reg);
1268 }
1269
1270 void shader_glsl_end(SHADER_OPCODE_ARG* arg) {
1271     shader_addline(arg->buffer, "}\n");
1272 }
1273
1274 void shader_glsl_rep(SHADER_OPCODE_ARG* arg) {
1275
1276     char src0_str[100];
1277     char src0_reg[50];
1278     char src0_mask[6];
1279
1280     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
1281     shader_addline(arg->buffer, "for (tmpInt = 0; tmpInt < %s.x; tmpInt++) {\n", src0_reg);
1282 }
1283
1284 void shader_glsl_if(SHADER_OPCODE_ARG* arg) {
1285
1286     char src0_str[100];
1287     char src0_reg[50];
1288     char src0_mask[6];
1289
1290     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
1291     shader_addline(arg->buffer, "if (%s) {\n", src0_str); 
1292 }
1293
1294 void shader_glsl_ifc(SHADER_OPCODE_ARG* arg) {
1295
1296     char src0_str[100], src1_str[100];
1297     char src0_reg[50], src1_reg[50];
1298     char src0_mask[6], src1_mask[6];
1299
1300     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
1301     shader_glsl_add_param(arg, arg->src[1], arg->src_addr[1], TRUE, src1_reg, src1_mask, src1_str);
1302
1303     shader_addline(arg->buffer, "if (%s %s %s) {\n",
1304         src0_str, shader_get_comp_op(arg->opcode_token), src1_str);
1305 }
1306
1307 void shader_glsl_else(SHADER_OPCODE_ARG* arg) {
1308     shader_addline(arg->buffer, "} else {\n");
1309 }
1310
1311 void shader_glsl_break(SHADER_OPCODE_ARG* arg) {
1312     shader_addline(arg->buffer, "break;\n");
1313 }
1314
1315 void shader_glsl_breakc(SHADER_OPCODE_ARG* arg) {
1316
1317     char src0_str[100], src1_str[100];
1318     char src0_reg[50], src1_reg[50];
1319     char src0_mask[6], src1_mask[6];
1320
1321     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
1322     shader_glsl_add_param(arg, arg->src[1], arg->src_addr[1], TRUE, src1_reg, src1_mask, src1_str);
1323
1324     shader_addline(arg->buffer, "if (%s %s %s) break;\n",
1325         src0_str, shader_get_comp_op(arg->opcode_token), src1_str);
1326 }
1327
1328 void shader_glsl_label(SHADER_OPCODE_ARG* arg) {
1329
1330     DWORD snum = (arg->src[0]) & D3DSP_REGNUM_MASK;
1331     shader_addline(arg->buffer, "}\n");
1332     shader_addline(arg->buffer, "void subroutine%lu () {\n",  snum);
1333 }
1334
1335 void shader_glsl_call(SHADER_OPCODE_ARG* arg) {
1336     DWORD snum = (arg->src[0]) & D3DSP_REGNUM_MASK;
1337     shader_addline(arg->buffer, "subroutine%lu();\n", snum);
1338 }
1339
1340 void shader_glsl_callnz(SHADER_OPCODE_ARG* arg) {
1341
1342     char src1_str[100];
1343     char src1_reg[50];
1344     char src1_mask[6];
1345    
1346     DWORD snum = (arg->src[0]) & D3DSP_REGNUM_MASK;
1347     shader_glsl_add_param(arg, arg->src[1], arg->src_addr[1], TRUE, src1_reg, src1_mask, src1_str);
1348     shader_addline(arg->buffer, "if (%s) subroutine%lu();\n", src1_str, snum);
1349 }
1350
1351 /*********************************************
1352  * Pixel Shader Specific Code begins here
1353  ********************************************/
1354 void pshader_glsl_tex(SHADER_OPCODE_ARG* arg) {
1355
1356     /* FIXME: Make this work for more than just 2D textures */
1357     
1358     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
1359     SHADER_BUFFER* buffer = arg->buffer;
1360     DWORD hex_version = This->baseShader.hex_version;
1361
1362     char dst_str[100],   dst_reg[50],  dst_mask[6];
1363     char coord_str[100], coord_reg[50], coord_mask[6];
1364     char sampler_str[100], sampler_reg[50], sampler_mask[6];
1365     DWORD reg_dest_code = arg->dst & D3DSP_REGNUM_MASK;
1366     DWORD sampler_code, sampler_type;
1367
1368     /* All versions have a destination register */
1369     shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
1370
1371     /* 1.0-1.3: Use destination register as coordinate source.
1372        1.4+: Use provided coordinate source register. */
1373     if (hex_version < D3DPS_VERSION(1,4))
1374        strcpy(coord_reg, dst_reg);
1375     else
1376        shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, coord_reg, coord_mask, coord_str);
1377
1378     /* 1.0-1.4: Use destination register as coordinate source.
1379      * 2.0+: Use provided coordinate source register. */
1380     if (hex_version < D3DPS_VERSION(2,0)) {
1381         sprintf(sampler_str, "Psampler%lu", reg_dest_code); 
1382         sampler_code = reg_dest_code;
1383     }       
1384     else {
1385         shader_glsl_add_param(arg, arg->src[1], arg->src_addr[1], TRUE, sampler_reg, sampler_mask, sampler_str);
1386         sampler_code = arg->src[1] & D3DSP_REGNUM_MASK;
1387     }         
1388
1389     sampler_type = arg->reg_maps->samplers[sampler_code] & WINED3DSP_TEXTURETYPE_MASK;
1390     if(This->wineD3DDevice->stateBlock->textureState[sampler_code][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED) {
1391         switch(sampler_type) {
1392
1393             case WINED3DSTT_2D:
1394                 shader_addline(buffer, "%s = texture2DProj(%s, %s);\n", dst_str, sampler_str, coord_reg);
1395                 break;
1396             case WINED3DSTT_CUBE:
1397                 shader_addline(buffer, "%s = textureCubeProj(%s, %s);\n", dst_str, sampler_str, coord_reg);
1398                 break;
1399             case WINED3DSTT_VOLUME:
1400                 shader_addline(buffer, "%s = texture3DProj(%s, %s);\n", dst_str, sampler_str, coord_reg);
1401                 break;
1402             default:
1403                 shader_addline(buffer, "%s = unrecognized_stype(%s, %s.stp);\n", dst_str, sampler_str, coord_reg);
1404                 FIXME("Unrecognized sampler type: %#lx;\n", sampler_type);
1405                 break;
1406         }
1407     } else {
1408         switch(sampler_type) {
1409
1410             case WINED3DSTT_2D:
1411                 shader_addline(buffer, "%s = texture2D(%s, %s.st);\n", dst_str, sampler_str, coord_reg);
1412                 break;
1413             case WINED3DSTT_CUBE:
1414                 shader_addline(buffer, "%s = textureCube(%s, %s.stp);\n", dst_str, sampler_str, coord_reg);
1415                 break;
1416             case WINED3DSTT_VOLUME:
1417                 shader_addline(buffer, "%s = texture3D(%s, %s.stp);\n", dst_str, sampler_str, coord_reg);
1418                 break;
1419             default:
1420                 shader_addline(buffer, "%s = unrecognized_stype(%s, %s.stp);\n", dst_str, sampler_str, coord_reg);
1421                 FIXME("Unrecognized sampler type: %#lx;\n", sampler_type);
1422                 break;
1423         }
1424     }
1425 }
1426
1427 void pshader_glsl_texcoord(SHADER_OPCODE_ARG* arg) {
1428
1429     /* FIXME: Make this work for more than just 2D textures */
1430     
1431     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
1432     SHADER_BUFFER* buffer = arg->buffer;
1433     DWORD hex_version = This->baseShader.hex_version;
1434
1435     char tmpStr[100];
1436     char tmpReg[50];
1437     char tmpMask[6];
1438     tmpReg[0] = 0;
1439
1440     shader_glsl_add_param(arg, arg->dst, 0, FALSE, tmpReg, tmpMask, tmpStr);
1441
1442     if (hex_version != D3DPS_VERSION(1,4)) {
1443         DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
1444         shader_addline(buffer, "%s = clamp(gl_TexCoord[%lu], 0.0, 1.0);\n", tmpReg, reg);
1445     } else {
1446         DWORD reg2 = arg->src[0] & D3DSP_REGNUM_MASK;
1447         shader_addline(buffer, "%s = gl_TexCoord[%lu]%s;\n", tmpStr, reg2, tmpMask);
1448    }
1449 }
1450
1451 /** Process the D3DSIO_TEXDP3TEX instruction in GLSL:
1452  * Take a 3-component dot product of the TexCoord[dstreg] and src,
1453  * then perform a 1D texture lookup from stage dstregnum, place into dst. */
1454 void pshader_glsl_texdp3tex(SHADER_OPCODE_ARG* arg) {
1455
1456     DWORD dstreg = arg->dst & D3DSP_REGNUM_MASK;
1457     char src0_str[100], dst_str[100];
1458     char src0_name[50], dst_name[50];
1459     char src0_mask[6],  dst_mask[6];
1460
1461     shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_name, dst_mask, dst_str);
1462     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_name, src0_mask, src0_str);
1463
1464     shader_addline(arg->buffer, "tmp0.x = dot(vec3(gl_TexCoord[%lu]), vec3(%s));\n", dstreg, src0_str);
1465     shader_addline(arg->buffer, "%s = vec4(texture1D(Psampler%lu, tmp0.x))%s;\n", dst_str, dstreg, dst_mask);
1466 }
1467
1468 /** Process the D3DSIO_TEXDP3 instruction in GLSL:
1469  * Take a 3-component dot product of the TexCoord[dstreg] and src. */
1470 void pshader_glsl_texdp3(SHADER_OPCODE_ARG* arg) {
1471
1472     DWORD dstreg = arg->dst & D3DSP_REGNUM_MASK;
1473     char src0_str[100], dst_str[100];
1474     char src0_name[50], dst_name[50];
1475     char src0_mask[6],  dst_mask[6];
1476
1477     shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_name, dst_mask, dst_str);
1478     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_name, src0_mask, src0_str);
1479
1480     shader_addline(arg->buffer, "%s = vec4(dot(vec3(T%lu), vec3(%s)))%s;\n",
1481             dst_str, dstreg, src0_str, dst_mask);
1482 }
1483
1484 /** Process the D3DSIO_TEXDEPTH instruction in GLSL:
1485  * Calculate the depth as dst.x / dst.y   */
1486 void pshader_glsl_texdepth(SHADER_OPCODE_ARG* arg) {
1487     
1488     char dst_str[100];
1489     char dst_reg[50];
1490     char dst_mask[6];
1491    
1492     shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
1493
1494     shader_addline(arg->buffer, "gl_FragDepth = %s.x / %s.y;\n", dst_reg, dst_reg);
1495 }
1496
1497 /** Process the D3DSIO_TEXM3X2DEPTH instruction in GLSL:
1498  * Last row of a 3x2 matrix multiply, use the result to calculate the depth:
1499  * Calculate tmp0.y = TexCoord[dstreg] . src.xyz;  (tmp0.x has already been calculated)
1500  * depth = (tmp0.y == 0.0) ? 1.0 : tmp0.x / tmp0.y
1501  */
1502 void pshader_glsl_texm3x2depth(SHADER_OPCODE_ARG* arg) {
1503     
1504     DWORD dstreg = arg->dst & D3DSP_REGNUM_MASK;
1505     char src0_str[100], dst_str[100];
1506     char src0_name[50], dst_name[50];
1507     char src0_mask[6],  dst_mask[6];
1508
1509     shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_name, dst_mask, dst_str);
1510     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_name, src0_mask, src0_str);
1511
1512     shader_addline(arg->buffer, "tmp0.y = dot(vec3(T%lu), vec3(%s));\n", dstreg, src0_str);
1513     shader_addline(arg->buffer, "gl_FragDepth = vec4((tmp0.y == 0.0) ? 1.0 : tmp0.x / tmp0.y)%s;\n", dst_str, dst_name);
1514 }
1515
1516 /** Process the D3DSIO_TEXM3X2PAD instruction in GLSL
1517  * Calculate the 1st of a 2-row matrix multiplication. */
1518 void pshader_glsl_texm3x2pad(SHADER_OPCODE_ARG* arg) {
1519
1520     DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
1521     SHADER_BUFFER* buffer = arg->buffer;
1522     char src0_str[100];
1523     char src0_name[50];
1524     char src0_mask[6];
1525
1526     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_name, src0_mask, src0_str);
1527     shader_addline(buffer, "tmp0.x = dot(vec3(T%lu), vec3(%s));\n", reg, src0_str);
1528 }
1529
1530 /** Process the D3DSIO_TEXM3X3PAD instruction in GLSL
1531  * Calculate the 1st or 2nd row of a 3-row matrix multiplication. */
1532 void pshader_glsl_texm3x3pad(SHADER_OPCODE_ARG* arg) {
1533
1534     IWineD3DPixelShaderImpl* shader = (IWineD3DPixelShaderImpl*) arg->shader;
1535     DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
1536     SHADER_BUFFER* buffer = arg->buffer;
1537     SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state;
1538     char src0_str[100];
1539     char src0_name[50];
1540     char src0_mask[6];
1541
1542     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_name, src0_mask, src0_str);
1543     shader_addline(buffer, "tmp0.%c = dot(vec3(T%lu), vec3(%s));\n", 'x' + current_state->current_row, reg, src0_str);
1544     current_state->texcoord_w[current_state->current_row++] = reg;
1545 }
1546
1547 void pshader_glsl_texm3x2tex(SHADER_OPCODE_ARG* arg) {
1548
1549     /* FIXME: Make this work for more than just 2D textures */
1550     
1551     DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
1552     SHADER_BUFFER* buffer = arg->buffer;
1553     char src0_str[100];
1554     char src0_name[50];
1555     char src0_mask[6];
1556
1557     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_name, src0_mask, src0_str);
1558     shader_addline(buffer, "tmp0.y = dot(vec3(T%lu), vec3(%s));\n", reg, src0_str);
1559     shader_addline(buffer, "T%lu = texture2D(Psampler%lu, tmp0.st);\n", reg, reg);
1560 }
1561
1562 /** Process the D3DSIO_TEXM3X3TEX instruction in GLSL
1563  * Perform the 3rd row of a 3x3 matrix multiply, then sample the texture using the calculate coordinates */
1564 void pshader_glsl_texm3x3tex(SHADER_OPCODE_ARG* arg) {
1565
1566     char src0_str[100];
1567     char src0_name[50];
1568     char src0_mask[6];
1569     char dimensions[5];
1570     DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
1571     DWORD src0_regnum = arg->src[0] & D3DSP_REGNUM_MASK;
1572     DWORD stype = arg->reg_maps->samplers[src0_regnum] & WINED3DSP_TEXTURETYPE_MASK;
1573     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
1574     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
1575     
1576     switch (stype) {
1577         case WINED3DSTT_2D:     strcpy(dimensions, "2D");   break;
1578         case WINED3DSTT_CUBE:   strcpy(dimensions, "Cube"); break;
1579         case WINED3DSTT_VOLUME: strcpy(dimensions, "3D");   break;
1580         default:
1581             strcpy(dimensions, "");
1582             FIXME("Unrecognized sampler type: %#lx\n", stype);
1583             break;
1584     }
1585
1586     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_name, src0_mask, src0_str);
1587     shader_addline(arg->buffer, "tmp0.z = dot(vec3(T%lu), vec3(%s));\n", reg, src0_str);
1588     shader_addline(arg->buffer, "T%lu = texture%s(Psampler%lu, tmp0.%s);\n", 
1589             reg, dimensions, reg, (stype == WINED3DSTT_2D) ? "xy" : "xyz");
1590     current_state->current_row = 0;
1591 }
1592
1593 /** Process the D3DSIO_TEXM3X3 instruction in GLSL
1594  * Perform the 3rd row of a 3x3 matrix multiply */
1595 void pshader_glsl_texm3x3(SHADER_OPCODE_ARG* arg) {
1596
1597     char src0_str[100];
1598     char src0_name[50];
1599     char src0_mask[6];
1600     DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
1601     IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
1602     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
1603     
1604     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_name, src0_mask, src0_str);
1605     
1606     shader_addline(arg->buffer, "tmp0.z = dot(vec3(T%lu), vec3(%s));\n", reg, src0_str);
1607     shader_addline(arg->buffer, "T%lu = vec4(tmp0.x, tmp0.y, tmp0.z, 1.0);\n", reg);
1608     current_state->current_row = 0;
1609 }
1610
1611 /** Process the D3DSIO_TEXM3X3SPEC instruction in GLSL 
1612  * Peform the final texture lookup based on the previous 2 3x3 matrix multiplies */
1613 void pshader_glsl_texm3x3spec(SHADER_OPCODE_ARG* arg) {
1614
1615     IWineD3DPixelShaderImpl* shader = (IWineD3DPixelShaderImpl*) arg->shader;
1616     DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
1617     char dimensions[5];
1618     char src0_str[100], src0_name[50], src0_mask[6];
1619     char src1_str[100], src1_name[50], src1_mask[6];
1620     SHADER_BUFFER* buffer = arg->buffer;
1621     SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state;
1622     DWORD stype = arg->reg_maps->samplers[reg] & WINED3DSP_TEXTURETYPE_MASK;
1623
1624     switch (stype) {
1625         case WINED3DSTT_2D:     strcpy(dimensions, "2D");   break;
1626         case WINED3DSTT_CUBE:   strcpy(dimensions, "Cube"); break;
1627         case WINED3DSTT_VOLUME: strcpy(dimensions, "3D");   break;
1628         default:
1629             strcpy(dimensions, "");
1630             FIXME("Unrecognized sampler type: %#lx\n", stype);
1631             break;
1632     }
1633
1634     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_name, src0_mask, src0_str);
1635     shader_glsl_add_param(arg, arg->src[1], arg->src_addr[1], TRUE, src1_name, src1_mask, src1_str);
1636
1637     /* Perform the last matrix multiply operation */
1638     shader_addline(buffer, "tmp0.z = dot(vec3(T%lu), vec3(%s));\n", reg, src0_str);
1639
1640     /* Calculate reflection vector */
1641     shader_addline(buffer, "tmp0.xyz = reflect(-vec3(%s), vec3(tmp0));\n", src1_str);
1642
1643     /* Sample the texture */
1644     shader_addline(buffer, "T%lu = texture%s(Psampler%lu, tmp0.%s);\n", 
1645             reg, dimensions, reg, (stype == WINED3DSTT_2D) ? "xy" : "xyz");
1646     current_state->current_row = 0;
1647 }
1648
1649 /** Process the D3DSIO_TEXM3X3VSPEC instruction in GLSL 
1650  * Peform the final texture lookup based on the previous 2 3x3 matrix multiplies */
1651 void pshader_glsl_texm3x3vspec(SHADER_OPCODE_ARG* arg) {
1652
1653     IWineD3DPixelShaderImpl* shader = (IWineD3DPixelShaderImpl*) arg->shader;
1654     DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
1655     SHADER_BUFFER* buffer = arg->buffer;
1656     SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state;
1657     char src0_str[100], src0_name[50], src0_mask[6];
1658
1659     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_name, src0_mask, src0_str);
1660
1661     /* Perform the last matrix multiply operation */
1662     shader_addline(buffer, "tmp0.z = dot(vec3(T%lu), vec3(%s));\n", reg, src0_str);
1663
1664     /* Construct the eye-ray vector from w coordinates */
1665     shader_addline(buffer, "tmp1.x = gl_TexCoord[%lu].w;\n", current_state->texcoord_w[0]);
1666     shader_addline(buffer, "tmp1.y = gl_TexCoord[%lu].w;\n", current_state->texcoord_w[1]);
1667     shader_addline(buffer, "tmp1.z = gl_TexCoord[%lu].w;\n", reg);
1668
1669     /* Calculate reflection vector (Assume normal is normalized): RF = 2*(N.E)*N -E */
1670     shader_addline(buffer, "tmp0.x = dot(vec3(tmp0), vec3(tmp1));\n");
1671     shader_addline(buffer, "tmp0 = tmp0.w * tmp0;\n");
1672     shader_addline(buffer, "tmp0 = (2.0 * tmp0) - tmp1;\n");
1673
1674     /* FIXME:
1675      * We don't really know if a Cube or a Volume texture is being sampled, but since Cube textures
1676      * are used more commonly, we'll default to that.
1677      * We probably need to push back the pixel shader generation code until drawPrimitive() for 
1678      * shader versions < 2.0, since that's the only time we can guarantee that we're sampling
1679      * the correct type of texture because we can lookup what textures are bound at that point.
1680      */
1681     shader_addline(buffer, "T%lu = textureCube(Psampler%lu, tmp0.xyz);\n", reg, reg);
1682     current_state->current_row = 0;
1683 }
1684
1685 /** Process the D3DSIO_TEXBEM instruction in GLSL.
1686  * Apply a fake bump map transform.
1687  * FIXME: Should apply the BUMPMAPENV matrix.  For now, just sample the texture */
1688 void pshader_glsl_texbem(SHADER_OPCODE_ARG* arg) {
1689
1690     DWORD reg1 = arg->dst & D3DSP_REGNUM_MASK;
1691     DWORD reg2 = arg->src[0] & D3DSP_REGNUM_MASK;
1692
1693     FIXME("Not applying the BUMPMAPENV matrix for pixel shader instruction texbem.\n");
1694     shader_addline(arg->buffer, "T%lu = texture2D(Psampler%lu, gl_TexCoord[%lu].xy + T%lu.xy);\n",
1695             reg1, reg1, reg1, reg2);
1696 }
1697
1698 /** Process the D3DSIO_TEXREG2AR instruction in GLSL
1699  * Sample 2D texture at dst using the alpha & red (wx) components of src as texture coordinates */
1700 void pshader_glsl_texreg2ar(SHADER_OPCODE_ARG* arg) {
1701     
1702     char tmpLine[255];
1703     char dst_str[100], src0_str[100];
1704     char dst_reg[50], src0_reg[50];
1705     char dst_mask[6], src0_mask[6];
1706     DWORD src0_regnum = arg->src[0] & D3DSP_REGNUM_MASK;
1707
1708     shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
1709     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
1710
1711     shader_glsl_add_dst(arg->dst, dst_reg, dst_mask, tmpLine);
1712     shader_addline(arg->buffer, "%stexture2D(Psampler%lu, %s.yz))%s;\n",
1713             tmpLine, src0_regnum, dst_reg, dst_mask);
1714 }
1715
1716 /** Process the D3DSIO_TEXREG2GB instruction in GLSL
1717  * Sample 2D texture at dst using the green & blue (yz) components of src as texture coordinates */
1718 void pshader_glsl_texreg2gb(SHADER_OPCODE_ARG* arg) {
1719
1720     char tmpLine[255];
1721     char dst_str[100], src0_str[100];
1722     char dst_reg[50], src0_reg[50];
1723     char dst_mask[6], src0_mask[6];
1724     DWORD src0_regnum = arg->src[0] & D3DSP_REGNUM_MASK;
1725
1726     shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
1727     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
1728
1729     shader_glsl_add_dst(arg->dst, dst_reg, dst_mask, tmpLine);
1730     shader_addline(arg->buffer, "%stexture2D(Psampler%lu, %s.yz))%s;\n",
1731             tmpLine, src0_regnum, dst_reg, dst_mask);
1732 }
1733
1734 /** Process the D3DSIO_TEXREG2RGB instruction in GLSL
1735  * Sample texture at dst using the rgb (xyz) components of src as texture coordinates */
1736 void pshader_glsl_texreg2rgb(SHADER_OPCODE_ARG* arg) {
1737
1738     char tmpLine[255];
1739     char dst_str[100], src0_str[100];
1740     char dst_reg[50], src0_reg[50];
1741     char dst_mask[6], src0_mask[6];
1742     char dimensions[5];
1743     DWORD src0_regnum = arg->src[0] & D3DSP_REGNUM_MASK;
1744     DWORD stype = arg->reg_maps->samplers[src0_regnum] & WINED3DSP_TEXTURETYPE_MASK;
1745     switch (stype) {
1746         case WINED3DSTT_2D:     strcpy(dimensions, "2D");   break;
1747         case WINED3DSTT_CUBE:   strcpy(dimensions, "Cube"); break;
1748         case WINED3DSTT_VOLUME: strcpy(dimensions, "3D");   break;
1749         default:
1750             strcpy(dimensions, "");
1751             FIXME("Unrecognized sampler type: %#lx\n", stype);
1752             break;
1753     }
1754
1755     shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
1756     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
1757
1758     shader_glsl_add_dst(arg->dst, dst_reg, dst_mask, tmpLine);
1759     shader_addline(arg->buffer, "%stexture%s(Psampler%lu, %s.%s))%s;\n",
1760             tmpLine, dimensions, src0_regnum, dst_reg, (stype == WINED3DSTT_2D) ? "xy" : "xyz", dst_mask);
1761 }
1762
1763 /** Process the D3DSIO_TEXKILL instruction in GLSL.
1764  * If any of the first 3 components are < 0, discard this pixel */
1765 void pshader_glsl_texkill(SHADER_OPCODE_ARG* arg) {
1766
1767     char dst_str[100], dst_name[50], dst_mask[6];
1768
1769     shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_name, dst_mask, dst_str);
1770     shader_addline(arg->buffer, "if (any(lessThan(%s.xyz, vec3(0.0)))) discard;\n", dst_name);
1771 }
1772
1773 /** Process the D3DSIO_DP2ADD instruction in GLSL.
1774  * dst = dot2(src0, src1) + src2 */
1775 void pshader_glsl_dp2add(SHADER_OPCODE_ARG* arg) {
1776
1777     char tmpLine[256];
1778     char dst_str[100], src0_str[100], src1_str[100], src2_str[100];
1779     char dst_reg[50], src0_reg[50], src1_reg[50], src2_reg[50];
1780     char dst_mask[6], src0_mask[6], src1_mask[6], src2_mask[6];
1781  
1782     shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
1783     shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
1784     shader_glsl_add_param(arg, arg->src[1], arg->src_addr[1], TRUE, src1_reg, src1_mask, src1_str);
1785     shader_glsl_add_param(arg, arg->src[2], arg->src_addr[2], TRUE, src2_reg, src2_mask, src2_str);   
1786     shader_glsl_add_dst(arg->dst, dst_reg, dst_mask, tmpLine);
1787     shader_addline(arg->buffer, "%sdot(vec2(%s), vec2(%s)) + %s)%s;\n",
1788                    tmpLine, src0_str, src1_str, src2_str, dst_mask);
1789 }
1790
1791 void pshader_glsl_input_pack(
1792    SHADER_BUFFER* buffer,
1793    semantic* semantics_in) {
1794
1795    unsigned int i;
1796
1797    for (i = 0; i < MAX_REG_INPUT; i++) {
1798
1799        DWORD usage_token = semantics_in[i].usage;
1800        DWORD register_token = semantics_in[i].reg;
1801        DWORD usage, usage_idx;
1802        char reg_mask[6];
1803
1804        /* Uninitialized */
1805        if (!usage_token) continue;
1806        usage = (usage_token & D3DSP_DCL_USAGE_MASK) >> D3DSP_DCL_USAGE_SHIFT;
1807        usage_idx = (usage_token & D3DSP_DCL_USAGEINDEX_MASK) >> D3DSP_DCL_USAGEINDEX_SHIFT;
1808        shader_glsl_get_output_register_swizzle(register_token, reg_mask);
1809
1810        switch(usage) {
1811
1812            case D3DDECLUSAGE_COLOR:
1813                if (usage_idx == 0)
1814                    shader_addline(buffer, "IN%lu%s = vec4(gl_Color)%s;\n",
1815                        i, reg_mask, reg_mask);
1816                else if (usage_idx == 1)
1817                    shader_addline(buffer, "IN%lu%s = vec4(gl_SecondaryColor)%s;\n",
1818                        i, reg_mask, reg_mask);
1819                else
1820                    shader_addline(buffer, "IN%lu%s = vec4(unsupported_color_input)%s;\n",
1821                        i, reg_mask, reg_mask);
1822                break;
1823
1824            case D3DDECLUSAGE_TEXCOORD:
1825                shader_addline(buffer, "IN%lu%s = vec4(gl_TexCoord[%lu])%s;\n",
1826                    i, reg_mask, usage_idx, reg_mask );
1827                break;
1828
1829            case D3DDECLUSAGE_FOG:
1830                shader_addline(buffer, "IN%lu%s = vec4(gl_FogFragCoord)%s;\n",
1831                    i, reg_mask, reg_mask);
1832                break;
1833
1834            default:
1835                shader_addline(buffer, "IN%lu%s = vec4(unsupported_input)%s;\n",
1836                    i, reg_mask, reg_mask);
1837         }
1838     }
1839 }
1840
1841 /*********************************************
1842  * Vertex Shader Specific Code begins here
1843  ********************************************/
1844
1845 void vshader_glsl_output_unpack(
1846    SHADER_BUFFER* buffer,
1847    semantic* semantics_out) {
1848
1849    unsigned int i;
1850
1851    for (i = 0; i < MAX_REG_OUTPUT; i++) {
1852
1853        DWORD usage_token = semantics_out[i].usage;
1854        DWORD register_token = semantics_out[i].reg;
1855        DWORD usage, usage_idx;
1856        char reg_mask[6];
1857
1858        /* Uninitialized */
1859        if (!usage_token) continue;
1860
1861        usage = (usage_token & D3DSP_DCL_USAGE_MASK) >> D3DSP_DCL_USAGE_SHIFT;
1862        usage_idx = (usage_token & D3DSP_DCL_USAGEINDEX_MASK) >> D3DSP_DCL_USAGEINDEX_SHIFT;
1863        shader_glsl_get_output_register_swizzle(register_token, reg_mask);
1864
1865        switch(usage) {
1866
1867            case D3DDECLUSAGE_COLOR:
1868                if (usage_idx == 0)
1869                    shader_addline(buffer, "gl_FrontColor%s = OUT%lu%s;\n", reg_mask, i, reg_mask);
1870                else if (usage_idx == 1)
1871                    shader_addline(buffer, "gl_FrontSecondaryColor%s = OUT%lu%s;\n", reg_mask, i, reg_mask);
1872                else
1873                    shader_addline(buffer, "unsupported_color_output%s = OUT%lu%s;\n", reg_mask, i, reg_mask);
1874                break;
1875
1876            case D3DDECLUSAGE_POSITION:
1877                shader_addline(buffer, "gl_Position%s = OUT%lu%s;\n", reg_mask, i, reg_mask);
1878                break;
1879  
1880            case D3DDECLUSAGE_TEXCOORD:
1881                shader_addline(buffer, "gl_TexCoord[%lu]%s = OUT%lu%s;\n",
1882                    usage_idx, reg_mask, i, reg_mask);
1883                break;
1884
1885            case WINED3DSHADERDECLUSAGE_PSIZE:
1886                shader_addline(buffer, "gl_PointSize = OUT%lu.x;\n", i);
1887                break;
1888
1889            case WINED3DSHADERDECLUSAGE_FOG:
1890                shader_addline(buffer, "gl_FogFragCoord%s = OUT%lu%s;\n", reg_mask, i, reg_mask);
1891                break;
1892
1893            default:
1894                shader_addline(buffer, "unsupported_output%s = OUT%lu%s;\n", reg_mask, i, reg_mask);
1895        }
1896     }
1897 }