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