po: Update French translation.
[wine] / dlls / wined3d / shader.c
1 /*
2  * Copyright 2002-2003 Jason Edmeades
3  * Copyright 2002-2003 Raphael Junqueira
4  * Copyright 2004 Christian Costa
5  * Copyright 2005 Oliver Stieber
6  * Copyright 2006 Ivan Gyurdiev
7  * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
8  * Copyright 2009-2011 Henri Verbeet for CodeWeavers
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24
25 #include "config.h"
26
27 #include <math.h>
28 #include <stdio.h>
29 #include <string.h>
30
31 #include "wined3d_private.h"
32
33 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
34 WINE_DECLARE_DEBUG_CHANNEL(d3d);
35
36 static const char * const shader_opcode_names[] =
37 {
38     /* WINED3DSIH_ABS           */ "abs",
39     /* WINED3DSIH_ADD           */ "add",
40     /* WINED3DSIH_AND           */ "and",
41     /* WINED3DSIH_BEM           */ "bem",
42     /* WINED3DSIH_BREAK         */ "break",
43     /* WINED3DSIH_BREAKC        */ "breakc",
44     /* WINED3DSIH_BREAKP        */ "breakp",
45     /* WINED3DSIH_CALL          */ "call",
46     /* WINED3DSIH_CALLNZ        */ "callnz",
47     /* WINED3DSIH_CMP           */ "cmp",
48     /* WINED3DSIH_CND           */ "cnd",
49     /* WINED3DSIH_CRS           */ "crs",
50     /* WINED3DSIH_CUT           */ "cut",
51     /* WINED3DSIH_DCL           */ "dcl",
52     /* WINED3DSIH_DEF           */ "def",
53     /* WINED3DSIH_DEFB          */ "defb",
54     /* WINED3DSIH_DEFI          */ "defi",
55     /* WINED3DSIH_DIV           */ "div",
56     /* WINED3DSIH_DP2ADD        */ "dp2add",
57     /* WINED3DSIH_DP3           */ "dp3",
58     /* WINED3DSIH_DP4           */ "dp4",
59     /* WINED3DSIH_DST           */ "dst",
60     /* WINED3DSIH_DSX           */ "dsx",
61     /* WINED3DSIH_DSY           */ "dsy",
62     /* WINED3DSIH_ELSE          */ "else",
63     /* WINED3DSIH_EMIT          */ "emit",
64     /* WINED3DSIH_ENDIF         */ "endif",
65     /* WINED3DSIH_ENDLOOP       */ "endloop",
66     /* WINED3DSIH_ENDREP        */ "endrep",
67     /* WINED3DSIH_EQ            */ "eq",
68     /* WINED3DSIH_EXP           */ "exp",
69     /* WINED3DSIH_EXPP          */ "expp",
70     /* WINED3DSIH_FRC           */ "frc",
71     /* WINED3DSIH_FTOI          */ "ftoi",
72     /* WINED3DSIH_GE            */ "ge",
73     /* WINED3DSIH_IADD          */ "iadd",
74     /* WINED3DSIH_IEQ           */ "ieq",
75     /* WINED3DSIH_IF            */ "if",
76     /* WINED3DSIH_IFC           */ "ifc",
77     /* WINED3DSIH_IGE           */ "ige",
78     /* WINED3DSIH_IMUL          */ "imul",
79     /* WINED3DSIH_ITOF          */ "itof",
80     /* WINED3DSIH_LABEL         */ "label",
81     /* WINED3DSIH_LD            */ "ld",
82     /* WINED3DSIH_LIT           */ "lit",
83     /* WINED3DSIH_LOG           */ "log",
84     /* WINED3DSIH_LOGP          */ "logp",
85     /* WINED3DSIH_LOOP          */ "loop",
86     /* WINED3DSIH_LRP           */ "lrp",
87     /* WINED3DSIH_LT            */ "lt",
88     /* WINED3DSIH_M3x2          */ "m3x2",
89     /* WINED3DSIH_M3x3          */ "m3x3",
90     /* WINED3DSIH_M3x4          */ "m3x4",
91     /* WINED3DSIH_M4x3          */ "m4x3",
92     /* WINED3DSIH_M4x4          */ "m4x4",
93     /* WINED3DSIH_MAD           */ "mad",
94     /* WINED3DSIH_MAX           */ "max",
95     /* WINED3DSIH_MIN           */ "min",
96     /* WINED3DSIH_MOV           */ "mov",
97     /* WINED3DSIH_MOVA          */ "mova",
98     /* WINED3DSIH_MOVC          */ "movc",
99     /* WINED3DSIH_MUL           */ "mul",
100     /* WINED3DSIH_NOP           */ "nop",
101     /* WINED3DSIH_NRM           */ "nrm",
102     /* WINED3DSIH_PHASE         */ "phase",
103     /* WINED3DSIH_POW           */ "pow",
104     /* WINED3DSIH_RCP           */ "rcp",
105     /* WINED3DSIH_REP           */ "rep",
106     /* WINED3DSIH_RET           */ "ret",
107     /* WINED3DSIH_ROUND_NI      */ "round_ni",
108     /* WINED3DSIH_RSQ           */ "rsq",
109     /* WINED3DSIH_SAMPLE        */ "sample",
110     /* WINED3DSIH_SAMPLE_GRAD   */ "sample_d",
111     /* WINED3DSIH_SAMPLE_LOD    */ "sample_l",
112     /* WINED3DSIH_SETP          */ "setp",
113     /* WINED3DSIH_SGE           */ "sge",
114     /* WINED3DSIH_SGN           */ "sgn",
115     /* WINED3DSIH_SINCOS        */ "sincos",
116     /* WINED3DSIH_SLT           */ "slt",
117     /* WINED3DSIH_SQRT          */ "sqrt",
118     /* WINED3DSIH_SUB           */ "sub",
119     /* WINED3DSIH_TEX           */ "texld",
120     /* WINED3DSIH_TEXBEM        */ "texbem",
121     /* WINED3DSIH_TEXBEML       */ "texbeml",
122     /* WINED3DSIH_TEXCOORD      */ "texcrd",
123     /* WINED3DSIH_TEXDEPTH      */ "texdepth",
124     /* WINED3DSIH_TEXDP3        */ "texdp3",
125     /* WINED3DSIH_TEXDP3TEX     */ "texdp3tex",
126     /* WINED3DSIH_TEXKILL       */ "texkill",
127     /* WINED3DSIH_TEXLDD        */ "texldd",
128     /* WINED3DSIH_TEXLDL        */ "texldl",
129     /* WINED3DSIH_TEXM3x2DEPTH  */ "texm3x2depth",
130     /* WINED3DSIH_TEXM3x2PAD    */ "texm3x2pad",
131     /* WINED3DSIH_TEXM3x2TEX    */ "texm3x2tex",
132     /* WINED3DSIH_TEXM3x3       */ "texm3x3",
133     /* WINED3DSIH_TEXM3x3DIFF   */ "texm3x3diff",
134     /* WINED3DSIH_TEXM3x3PAD    */ "texm3x3pad",
135     /* WINED3DSIH_TEXM3x3SPEC   */ "texm3x3spec",
136     /* WINED3DSIH_TEXM3x3TEX    */ "texm3x3tex",
137     /* WINED3DSIH_TEXM3x3VSPEC  */ "texm3x3vspec",
138     /* WINED3DSIH_TEXREG2AR     */ "texreg2ar",
139     /* WINED3DSIH_TEXREG2GB     */ "texreg2gb",
140     /* WINED3DSIH_TEXREG2RGB    */ "texreg2rgb",
141     /* WINED3DSIH_UDIV          */ "udiv",
142     /* WINED3DSIH_USHR          */ "ushr",
143     /* WINED3DSIH_UTOF          */ "utof",
144     /* WINED3DSIH_XOR           */ "xor",
145 };
146
147 static const char * const semantic_names[] =
148 {
149     /* WINED3D_DECL_USAGE_POSITION      */ "SV_POSITION",
150     /* WINED3D_DECL_USAGE_BLEND_WEIGHT  */ "BLENDWEIGHT",
151     /* WINED3D_DECL_USAGE_BLEND_INDICES */ "BLENDINDICES",
152     /* WINED3D_DECL_USAGE_NORMAL        */ "NORMAL",
153     /* WINED3D_DECL_USAGE_PSIZE         */ "PSIZE",
154     /* WINED3D_DECL_USAGE_TEXCOORD      */ "TEXCOORD",
155     /* WINED3D_DECL_USAGE_TANGENT       */ "TANGENT",
156     /* WINED3D_DECL_USAGE_BINORMAL      */ "BINORMAL",
157     /* WINED3D_DECL_USAGE_TESS_FACTOR   */ "TESSFACTOR",
158     /* WINED3D_DECL_USAGE_POSITIONT     */ "POSITIONT",
159     /* WINED3D_DECL_USAGE_COLOR         */ "COLOR",
160     /* WINED3D_DECL_USAGE_FOG           */ "FOG",
161     /* WINED3D_DECL_USAGE_DEPTH         */ "DEPTH",
162     /* WINED3D_DECL_USAGE_SAMPLE        */ "SAMPLE",
163 };
164
165 static const char *shader_semantic_name_from_usage(enum wined3d_decl_usage usage)
166 {
167     if (usage >= sizeof(semantic_names) / sizeof(*semantic_names))
168     {
169         FIXME("Unrecognized usage %#x.\n", usage);
170         return "UNRECOGNIZED";
171     }
172
173     return semantic_names[usage];
174 }
175
176 static enum wined3d_decl_usage shader_usage_from_semantic_name(const char *name)
177 {
178     unsigned int i;
179
180     for (i = 0; i < sizeof(semantic_names) / sizeof(*semantic_names); ++i)
181     {
182         if (!strcmp(name, semantic_names[i])) return i;
183     }
184
185     return ~0U;
186 }
187
188 BOOL shader_match_semantic(const char *semantic_name, enum wined3d_decl_usage usage)
189 {
190     return !strcmp(semantic_name, shader_semantic_name_from_usage(usage));
191 }
192
193 static void shader_signature_from_semantic(struct wined3d_shader_signature_element *e,
194         const struct wined3d_shader_semantic *s)
195 {
196     e->semantic_name = shader_semantic_name_from_usage(s->usage);
197     e->semantic_idx = s->usage_idx;
198     e->sysval_semantic = 0;
199     e->component_type = 0;
200     e->register_idx = s->reg.reg.idx;
201     e->mask = s->reg.write_mask;
202 }
203
204 static void shader_signature_from_usage(struct wined3d_shader_signature_element *e,
205         enum wined3d_decl_usage usage, UINT usage_idx, UINT reg_idx, DWORD write_mask)
206 {
207     e->semantic_name = shader_semantic_name_from_usage(usage);
208     e->semantic_idx = usage_idx;
209     e->sysval_semantic = 0;
210     e->component_type = 0;
211     e->register_idx = reg_idx;
212     e->mask = write_mask;
213 }
214
215 static const struct wined3d_shader_frontend *shader_select_frontend(DWORD version_token)
216 {
217     switch (version_token >> 16)
218     {
219         case WINED3D_SM1_VS:
220         case WINED3D_SM1_PS:
221             return &sm1_shader_frontend;
222
223         case WINED3D_SM4_PS:
224         case WINED3D_SM4_VS:
225         case WINED3D_SM4_GS:
226             return &sm4_shader_frontend;
227
228         default:
229             FIXME("Unrecognised version token %#x\n", version_token);
230             return NULL;
231     }
232 }
233
234 void shader_buffer_clear(struct wined3d_shader_buffer *buffer)
235 {
236     buffer->buffer[0] = '\0';
237     buffer->bsize = 0;
238     buffer->lineNo = 0;
239     buffer->newline = TRUE;
240 }
241
242 BOOL shader_buffer_init(struct wined3d_shader_buffer *buffer)
243 {
244     buffer->buffer = HeapAlloc(GetProcessHeap(), 0, SHADER_PGMSIZE);
245     if (!buffer->buffer)
246     {
247         ERR("Failed to allocate shader buffer memory.\n");
248         return FALSE;
249     }
250
251     shader_buffer_clear(buffer);
252     return TRUE;
253 }
254
255 void shader_buffer_free(struct wined3d_shader_buffer *buffer)
256 {
257     HeapFree(GetProcessHeap(), 0, buffer->buffer);
258 }
259
260 int shader_vaddline(struct wined3d_shader_buffer *buffer, const char *format, va_list args)
261 {
262     char *base = buffer->buffer + buffer->bsize;
263     int rc;
264
265     rc = vsnprintf(base, SHADER_PGMSIZE - 1 - buffer->bsize, format, args);
266
267     if (rc < 0 /* C89 */ || (unsigned int)rc > SHADER_PGMSIZE - 1 - buffer->bsize /* C99 */)
268     {
269         ERR("The buffer allocated for the shader program string "
270             "is too small at %d bytes.\n", SHADER_PGMSIZE);
271         buffer->bsize = SHADER_PGMSIZE - 1;
272         return -1;
273     }
274
275     if (buffer->newline)
276     {
277         TRACE("GL HW (%u, %u) : %s", buffer->lineNo + 1, buffer->bsize, base);
278         buffer->newline = FALSE;
279     }
280     else
281     {
282         TRACE("%s", base);
283     }
284
285     buffer->bsize += rc;
286     if (buffer->buffer[buffer->bsize-1] == '\n')
287     {
288         ++buffer->lineNo;
289         buffer->newline = TRUE;
290     }
291
292     return 0;
293 }
294
295 int shader_addline(struct wined3d_shader_buffer *buffer, const char *format, ...)
296 {
297     va_list args;
298     int ret;
299
300     va_start(args, format);
301     ret = shader_vaddline(buffer, format, args);
302     va_end(args);
303
304     return ret;
305 }
306
307 static void shader_init(struct wined3d_shader *shader, struct wined3d_device *device,
308         void *parent, const struct wined3d_parent_ops *parent_ops)
309 {
310     shader->ref = 1;
311     shader->device = device;
312     shader->parent = parent;
313     shader->parent_ops = parent_ops;
314     list_init(&shader->linked_programs);
315     list_add_head(&device->shaders, &shader->shader_list_entry);
316 }
317
318 /* Convert floating point offset relative to a register file to an absolute
319  * offset for float constants. */
320 static unsigned int shader_get_float_offset(enum wined3d_shader_register_type register_type, UINT register_idx)
321 {
322     switch (register_type)
323     {
324         case WINED3DSPR_CONST: return register_idx;
325         case WINED3DSPR_CONST2: return 2048 + register_idx;
326         case WINED3DSPR_CONST3: return 4096 + register_idx;
327         case WINED3DSPR_CONST4: return 6144 + register_idx;
328         default:
329             FIXME("Unsupported register type: %u.\n", register_type);
330             return register_idx;
331     }
332 }
333
334 static void shader_delete_constant_list(struct list *clist)
335 {
336     struct wined3d_shader_lconst *constant;
337     struct list *ptr;
338
339     ptr = list_head(clist);
340     while (ptr)
341     {
342         constant = LIST_ENTRY(ptr, struct wined3d_shader_lconst, entry);
343         ptr = list_next(clist, ptr);
344         HeapFree(GetProcessHeap(), 0, constant);
345     }
346     list_init(clist);
347 }
348
349 static inline void set_bitmap_bit(DWORD *bitmap, DWORD bit)
350 {
351     DWORD idx, shift;
352     idx = bit >> 5;
353     shift = bit & 0x1f;
354     bitmap[idx] |= (1 << shift);
355 }
356
357 static void shader_record_register_usage(struct wined3d_shader *shader, struct wined3d_shader_reg_maps *reg_maps,
358         const struct wined3d_shader_register *reg, enum wined3d_shader_type shader_type)
359 {
360     switch (reg->type)
361     {
362         case WINED3DSPR_TEXTURE: /* WINED3DSPR_ADDR */
363             if (shader_type == WINED3D_SHADER_TYPE_PIXEL) reg_maps->texcoord |= 1 << reg->idx;
364             else reg_maps->address |= 1 << reg->idx;
365             break;
366
367         case WINED3DSPR_TEMP:
368             reg_maps->temporary |= 1 << reg->idx;
369             break;
370
371         case WINED3DSPR_INPUT:
372             if (shader_type == WINED3D_SHADER_TYPE_PIXEL)
373             {
374                 if (reg->rel_addr)
375                 {
376                     /* If relative addressing is used, we must assume that all registers
377                      * are used. Even if it is a construct like v3[aL], we can't assume
378                      * that v0, v1 and v2 aren't read because aL can be negative */
379                     unsigned int i;
380                     for (i = 0; i < MAX_REG_INPUT; ++i)
381                     {
382                         shader->u.ps.input_reg_used[i] = TRUE;
383                     }
384                 }
385                 else
386                 {
387                     shader->u.ps.input_reg_used[reg->idx] = TRUE;
388                 }
389             }
390             else reg_maps->input_registers |= 1 << reg->idx;
391             break;
392
393         case WINED3DSPR_RASTOUT:
394             if (reg->idx == 1) reg_maps->fog = 1;
395             break;
396
397         case WINED3DSPR_MISCTYPE:
398             if (shader_type == WINED3D_SHADER_TYPE_PIXEL)
399             {
400                 if (!reg->idx) reg_maps->vpos = 1;
401                 else if (reg->idx == 1) reg_maps->usesfacing = 1;
402             }
403             break;
404
405         case WINED3DSPR_CONST:
406             if (reg->rel_addr)
407             {
408                 if (reg->idx < reg_maps->min_rel_offset) reg_maps->min_rel_offset = reg->idx;
409                 if (reg->idx > reg_maps->max_rel_offset) reg_maps->max_rel_offset = reg->idx;
410                 reg_maps->usesrelconstF = TRUE;
411             }
412             else
413             {
414                 set_bitmap_bit(reg_maps->constf, reg->idx);
415             }
416             break;
417
418         case WINED3DSPR_CONSTINT:
419             reg_maps->integer_constants |= (1 << reg->idx);
420             break;
421
422         case WINED3DSPR_CONSTBOOL:
423             reg_maps->boolean_constants |= (1 << reg->idx);
424             break;
425
426         case WINED3DSPR_COLOROUT:
427             reg_maps->rt_mask |= (1 << reg->idx);
428             break;
429
430         default:
431             TRACE("Not recording register of type %#x and idx %u\n", reg->type, reg->idx);
432             break;
433     }
434 }
435
436 static unsigned int get_instr_extra_regcount(enum WINED3D_SHADER_INSTRUCTION_HANDLER instr, unsigned int param)
437 {
438     switch (instr)
439     {
440         case WINED3DSIH_M4x4:
441         case WINED3DSIH_M3x4:
442             return param == 1 ? 3 : 0;
443
444         case WINED3DSIH_M4x3:
445         case WINED3DSIH_M3x3:
446             return param == 1 ? 2 : 0;
447
448         case WINED3DSIH_M3x2:
449             return param == 1 ? 1 : 0;
450
451         default:
452             return 0;
453     }
454 }
455
456 /* Note that this does not count the loop register as an address register. */
457 static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const struct wined3d_shader_frontend *fe,
458         struct wined3d_shader_reg_maps *reg_maps, struct wined3d_shader_signature_element *input_signature,
459         struct wined3d_shader_signature_element *output_signature, const DWORD *byte_code, DWORD constf_size)
460 {
461     unsigned int cur_loop_depth = 0, max_loop_depth = 0;
462     void *fe_data = shader->frontend_data;
463     struct wined3d_shader_version shader_version;
464     const DWORD *ptr = byte_code;
465
466     memset(reg_maps, 0, sizeof(*reg_maps));
467     reg_maps->min_rel_offset = ~0U;
468
469     fe->shader_read_header(fe_data, &ptr, &shader_version);
470     reg_maps->shader_version = shader_version;
471
472     reg_maps->constf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
473             sizeof(*reg_maps->constf) * ((constf_size + 31) / 32));
474     if (!reg_maps->constf)
475     {
476         ERR("Failed to allocate constant map memory.\n");
477         return E_OUTOFMEMORY;
478     }
479
480     while (!fe->shader_is_end(fe_data, &ptr))
481     {
482         struct wined3d_shader_instruction ins;
483         const char *comment;
484         UINT comment_size;
485         UINT param_size;
486
487         /* Skip comments. */
488         fe->shader_read_comment(&ptr, &comment, &comment_size);
489         if (comment) continue;
490
491         /* Fetch opcode. */
492         fe->shader_read_opcode(fe_data, &ptr, &ins, &param_size);
493
494         /* Unhandled opcode, and its parameters. */
495         if (ins.handler_idx == WINED3DSIH_TABLE_SIZE)
496         {
497             TRACE("Skipping unrecognized instruction.\n");
498             ptr += param_size;
499             continue;
500         }
501
502         /* Handle declarations. */
503         if (ins.handler_idx == WINED3DSIH_DCL)
504         {
505             struct wined3d_shader_semantic semantic;
506
507             fe->shader_read_semantic(&ptr, &semantic);
508
509             switch (semantic.reg.reg.type)
510             {
511                 /* Mark input registers used. */
512                 case WINED3DSPR_INPUT:
513                     reg_maps->input_registers |= 1 << semantic.reg.reg.idx;
514                     shader_signature_from_semantic(&input_signature[semantic.reg.reg.idx], &semantic);
515                     break;
516
517                 /* Vertex shader: mark 3.0 output registers used, save token. */
518                 case WINED3DSPR_OUTPUT:
519                     reg_maps->output_registers |= 1 << semantic.reg.reg.idx;
520                     shader_signature_from_semantic(&output_signature[semantic.reg.reg.idx], &semantic);
521                     if (semantic.usage == WINED3D_DECL_USAGE_FOG)
522                         reg_maps->fog = 1;
523                     break;
524
525                 /* Save sampler usage token. */
526                 case WINED3DSPR_SAMPLER:
527                     reg_maps->sampler_type[semantic.reg.reg.idx] = semantic.sampler_type;
528                     break;
529
530                 default:
531                     TRACE("Not recording DCL register type %#x.\n", semantic.reg.reg.type);
532                     break;
533             }
534         }
535         else if (ins.handler_idx == WINED3DSIH_DEF)
536         {
537             struct wined3d_shader_src_param rel_addr;
538             struct wined3d_shader_dst_param dst;
539
540             struct wined3d_shader_lconst *lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(*lconst));
541             if (!lconst) return E_OUTOFMEMORY;
542
543             fe->shader_read_dst_param(fe_data, &ptr, &dst, &rel_addr);
544             lconst->idx = dst.reg.idx;
545
546             memcpy(lconst->value, ptr, 4 * sizeof(DWORD));
547             ptr += 4;
548
549             /* In pixel shader 1.X shaders, the constants are clamped between [-1;1] */
550             if (shader_version.major == 1 && shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
551             {
552                 float *value = (float *)lconst->value;
553                 if (value[0] < -1.0f) value[0] = -1.0f;
554                 else if (value[0] > 1.0f) value[0] = 1.0f;
555                 if (value[1] < -1.0f) value[1] = -1.0f;
556                 else if (value[1] > 1.0f) value[1] = 1.0f;
557                 if (value[2] < -1.0f) value[2] = -1.0f;
558                 else if (value[2] > 1.0f) value[2] = 1.0f;
559                 if (value[3] < -1.0f) value[3] = -1.0f;
560                 else if (value[3] > 1.0f) value[3] = 1.0f;
561             }
562
563             list_add_head(&shader->constantsF, &lconst->entry);
564         }
565         else if (ins.handler_idx == WINED3DSIH_DEFI)
566         {
567             struct wined3d_shader_src_param rel_addr;
568             struct wined3d_shader_dst_param dst;
569
570             struct wined3d_shader_lconst *lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(*lconst));
571             if (!lconst) return E_OUTOFMEMORY;
572
573             fe->shader_read_dst_param(fe_data, &ptr, &dst, &rel_addr);
574             lconst->idx = dst.reg.idx;
575
576             memcpy(lconst->value, ptr, 4 * sizeof(DWORD));
577             ptr += 4;
578
579             list_add_head(&shader->constantsI, &lconst->entry);
580             reg_maps->local_int_consts |= (1 << dst.reg.idx);
581         }
582         else if (ins.handler_idx == WINED3DSIH_DEFB)
583         {
584             struct wined3d_shader_src_param rel_addr;
585             struct wined3d_shader_dst_param dst;
586
587             struct wined3d_shader_lconst *lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(*lconst));
588             if (!lconst) return E_OUTOFMEMORY;
589
590             fe->shader_read_dst_param(fe_data, &ptr, &dst, &rel_addr);
591             lconst->idx = dst.reg.idx;
592
593             memcpy(lconst->value, ptr, sizeof(DWORD));
594             ++ptr;
595
596             list_add_head(&shader->constantsB, &lconst->entry);
597             reg_maps->local_bool_consts |= (1 << dst.reg.idx);
598         }
599         /* For subroutine prototypes. */
600         else if (ins.handler_idx == WINED3DSIH_LABEL)
601         {
602             struct wined3d_shader_src_param src, rel_addr;
603
604             fe->shader_read_src_param(fe_data, &ptr, &src, &rel_addr);
605             reg_maps->labels |= 1 << src.reg.idx;
606         }
607         /* Set texture, address, temporary registers. */
608         else
609         {
610             BOOL color0_mov = FALSE;
611             unsigned int i, limit;
612
613             /* This will loop over all the registers and try to
614              * make a bitmask of the ones we're interested in.
615              *
616              * Relative addressing tokens are ignored, but that's
617              * okay, since we'll catch any address registers when
618              * they are initialized (required by spec). */
619             for (i = 0; i < ins.dst_count; ++i)
620             {
621                 struct wined3d_shader_src_param dst_rel_addr;
622                 struct wined3d_shader_dst_param dst_param;
623
624                 fe->shader_read_dst_param(fe_data, &ptr, &dst_param, &dst_rel_addr);
625
626                 shader_record_register_usage(shader, reg_maps, &dst_param.reg, shader_version.type);
627
628                 /* WINED3DSPR_TEXCRDOUT is the same as WINED3DSPR_OUTPUT. _OUTPUT can be > MAX_REG_TEXCRD and
629                  * is used in >= 3.0 shaders. Filter 3.0 shaders to prevent overflows, and also filter pixel
630                  * shaders because TECRDOUT isn't used in them, but future register types might cause issues */
631                 if (shader_version.type == WINED3D_SHADER_TYPE_VERTEX && shader_version.major < 3)
632                 {
633                     UINT idx = dst_param.reg.idx;
634
635                     switch (dst_param.reg.type)
636                     {
637                         case WINED3DSPR_RASTOUT:
638                             switch (idx)
639                             {
640                                 case 0: /* oPos */
641                                     reg_maps->output_registers |= 1 << 10;
642                                     shader_signature_from_usage(&output_signature[10],
643                                             WINED3D_DECL_USAGE_POSITION, 0, 10, WINED3DSP_WRITEMASK_ALL);
644                                     break;
645
646                                 case 1: /* oFog */
647                                     reg_maps->output_registers |= 1 << 11;
648                                     shader_signature_from_usage(&output_signature[11],
649                                             WINED3D_DECL_USAGE_FOG, 0, 11, WINED3DSP_WRITEMASK_0);
650                                     break;
651
652                                 case 2: /* oPts */
653                                     reg_maps->output_registers |= 1 << 11;
654                                     shader_signature_from_usage(&output_signature[11],
655                                             WINED3D_DECL_USAGE_PSIZE, 0, 11, WINED3DSP_WRITEMASK_1);
656                                     break;
657                             }
658                             break;
659
660                         case WINED3DSPR_ATTROUT:
661                             if (idx < 2)
662                             {
663                                 idx += 8;
664                                 if (reg_maps->output_registers & (1 << idx))
665                                 {
666                                     output_signature[idx].mask |= dst_param.write_mask;
667                                 }
668                                 else
669                                 {
670                                     reg_maps->output_registers |= 1 << idx;
671                                     shader_signature_from_usage(&output_signature[idx],
672                                             WINED3D_DECL_USAGE_COLOR, idx - 8, idx, dst_param.write_mask);
673                                 }
674                             }
675                             break;
676
677                         case WINED3DSPR_TEXCRDOUT:
678
679                             reg_maps->texcoord_mask[idx] |= dst_param.write_mask;
680                             if (reg_maps->output_registers & (1 << idx))
681                             {
682                                 output_signature[idx].mask |= dst_param.write_mask;
683                             }
684                             else
685                             {
686                                 reg_maps->output_registers |= 1 << idx;
687                                 shader_signature_from_usage(&output_signature[idx],
688                                         WINED3D_DECL_USAGE_TEXCOORD, idx, idx, dst_param.write_mask);
689                             }
690                             break;
691
692                         default:
693                             break;
694                     }
695                 }
696
697                 if (shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
698                 {
699                     if (dst_param.reg.type == WINED3DSPR_COLOROUT && !dst_param.reg.idx)
700                     {
701                         /* Many 2.0 and 3.0 pixel shaders end with a MOV from a temp register to
702                          * COLOROUT 0. If we know this in advance, the ARB shader backend can skip
703                          * the mov and perform the sRGB write correction from the source register.
704                          *
705                          * However, if the mov is only partial, we can't do this, and if the write
706                          * comes from an instruction other than MOV it is hard to do as well. If
707                          * COLOROUT 0 is overwritten partially later, the marker is dropped again. */
708                         shader->u.ps.color0_mov = FALSE;
709                         if (ins.handler_idx == WINED3DSIH_MOV
710                                 && dst_param.write_mask == WINED3DSP_WRITEMASK_ALL)
711                         {
712                             /* Used later when the source register is read. */
713                             color0_mov = TRUE;
714                         }
715                     }
716                     /* Also drop the MOV marker if the source register is overwritten prior to the shader
717                      * end
718                      */
719                     else if (dst_param.reg.type == WINED3DSPR_TEMP
720                             && dst_param.reg.idx == shader->u.ps.color0_reg)
721                     {
722                         shader->u.ps.color0_mov = FALSE;
723                     }
724                 }
725
726                 /* Declare 1.x samplers implicitly, based on the destination reg. number. */
727                 if (shader_version.major == 1
728                         && (ins.handler_idx == WINED3DSIH_TEX
729                             || ins.handler_idx == WINED3DSIH_TEXBEM
730                             || ins.handler_idx == WINED3DSIH_TEXBEML
731                             || ins.handler_idx == WINED3DSIH_TEXDP3TEX
732                             || ins.handler_idx == WINED3DSIH_TEXM3x2TEX
733                             || ins.handler_idx == WINED3DSIH_TEXM3x3SPEC
734                             || ins.handler_idx == WINED3DSIH_TEXM3x3TEX
735                             || ins.handler_idx == WINED3DSIH_TEXM3x3VSPEC
736                             || ins.handler_idx == WINED3DSIH_TEXREG2AR
737                             || ins.handler_idx == WINED3DSIH_TEXREG2GB
738                             || ins.handler_idx == WINED3DSIH_TEXREG2RGB))
739                 {
740                     /* Fake sampler usage, only set reserved bit and type. */
741                     DWORD sampler_code = dst_param.reg.idx;
742
743                     TRACE("Setting fake 2D sampler for 1.x pixelshader.\n");
744                     reg_maps->sampler_type[sampler_code] = WINED3DSTT_2D;
745
746                     /* texbem is only valid with < 1.4 pixel shaders */
747                     if (ins.handler_idx == WINED3DSIH_TEXBEM
748                             || ins.handler_idx == WINED3DSIH_TEXBEML)
749                     {
750                         reg_maps->bumpmat |= 1 << dst_param.reg.idx;
751                         if (ins.handler_idx == WINED3DSIH_TEXBEML)
752                         {
753                             reg_maps->luminanceparams |= 1 << dst_param.reg.idx;
754                         }
755                     }
756                 }
757                 else if (ins.handler_idx == WINED3DSIH_BEM)
758                 {
759                     reg_maps->bumpmat |= 1 << dst_param.reg.idx;
760                 }
761             }
762
763             if (ins.handler_idx == WINED3DSIH_NRM) reg_maps->usesnrm = 1;
764             else if (ins.handler_idx == WINED3DSIH_DSY) reg_maps->usesdsy = 1;
765             else if (ins.handler_idx == WINED3DSIH_DSX) reg_maps->usesdsx = 1;
766             else if (ins.handler_idx == WINED3DSIH_TEXLDD) reg_maps->usestexldd = 1;
767             else if (ins.handler_idx == WINED3DSIH_TEXLDL) reg_maps->usestexldl = 1;
768             else if (ins.handler_idx == WINED3DSIH_MOVA) reg_maps->usesmova = 1;
769             else if (ins.handler_idx == WINED3DSIH_IFC) reg_maps->usesifc = 1;
770             else if (ins.handler_idx == WINED3DSIH_CALL) reg_maps->usescall = 1;
771             else if (ins.handler_idx == WINED3DSIH_POW) reg_maps->usespow = 1;
772             else if (ins.handler_idx == WINED3DSIH_LOOP
773                     || ins.handler_idx == WINED3DSIH_REP)
774             {
775                 ++cur_loop_depth;
776                 if (cur_loop_depth > max_loop_depth)
777                     max_loop_depth = cur_loop_depth;
778             }
779             else if (ins.handler_idx == WINED3DSIH_ENDLOOP
780                     || ins.handler_idx == WINED3DSIH_ENDREP)
781                 --cur_loop_depth;
782
783             limit = ins.src_count + (ins.predicate ? 1 : 0);
784             for (i = 0; i < limit; ++i)
785             {
786                 struct wined3d_shader_src_param src_param, src_rel_addr;
787                 unsigned int count;
788
789                 fe->shader_read_src_param(fe_data, &ptr, &src_param, &src_rel_addr);
790                 count = get_instr_extra_regcount(ins.handler_idx, i);
791
792                 shader_record_register_usage(shader, reg_maps, &src_param.reg, shader_version.type);
793                 while (count)
794                 {
795                     ++src_param.reg.idx;
796                     shader_record_register_usage(shader, reg_maps, &src_param.reg, shader_version.type);
797                     --count;
798                 }
799
800                 if (color0_mov)
801                 {
802                     if (src_param.reg.type == WINED3DSPR_TEMP
803                             && src_param.swizzle == WINED3DSP_NOSWIZZLE)
804                     {
805                         shader->u.ps.color0_mov = TRUE;
806                         shader->u.ps.color0_reg = src_param.reg.idx;
807                     }
808                 }
809             }
810         }
811     }
812     reg_maps->loop_depth = max_loop_depth;
813
814     /* PS before 2.0 don't have explicit color outputs. Instead the value of
815      * R0 is written to the render target. */
816     if (shader_version.major < 2 && shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
817         reg_maps->rt_mask |= (1 << 0);
818
819     shader->functionLength = ((const char *)ptr - (const char *)byte_code);
820
821     return WINED3D_OK;
822 }
823
824 unsigned int shader_find_free_input_register(const struct wined3d_shader_reg_maps *reg_maps, unsigned int max)
825 {
826     DWORD map = 1 << max;
827     map |= map - 1;
828     map &= reg_maps->shader_version.major < 3 ? ~reg_maps->texcoord : ~reg_maps->input_registers;
829
830     return wined3d_log2i(map);
831 }
832
833 static void shader_dump_decl_usage(const struct wined3d_shader_semantic *semantic,
834         const struct wined3d_shader_version *shader_version)
835 {
836     TRACE("dcl");
837
838     if (semantic->reg.reg.type == WINED3DSPR_SAMPLER)
839     {
840         switch (semantic->sampler_type)
841         {
842             case WINED3DSTT_2D: TRACE("_2d"); break;
843             case WINED3DSTT_CUBE: TRACE("_cube"); break;
844             case WINED3DSTT_VOLUME: TRACE("_volume"); break;
845             default: TRACE("_unknown_ttype(0x%08x)", semantic->sampler_type);
846         }
847     }
848     else
849     {
850         /* Pixel shaders 3.0 don't have usage semantics. */
851         if (shader_version->major < 3 && shader_version->type == WINED3D_SHADER_TYPE_PIXEL) return;
852         else TRACE("_");
853
854         switch (semantic->usage)
855         {
856             case WINED3D_DECL_USAGE_POSITION:
857                 TRACE("position%u", semantic->usage_idx);
858                 break;
859
860             case WINED3D_DECL_USAGE_BLEND_INDICES:
861                 TRACE("blend");
862                 break;
863
864             case WINED3D_DECL_USAGE_BLEND_WEIGHT:
865                 TRACE("weight");
866                 break;
867
868             case WINED3D_DECL_USAGE_NORMAL:
869                 TRACE("normal%u", semantic->usage_idx);
870                 break;
871
872             case WINED3D_DECL_USAGE_PSIZE:
873                 TRACE("psize");
874                 break;
875
876             case WINED3D_DECL_USAGE_COLOR:
877                 if (!semantic->usage_idx) TRACE("color");
878                 else TRACE("specular%u", (semantic->usage_idx - 1));
879                 break;
880
881             case WINED3D_DECL_USAGE_TEXCOORD:
882                 TRACE("texture%u", semantic->usage_idx);
883                 break;
884
885             case WINED3D_DECL_USAGE_TANGENT:
886                 TRACE("tangent");
887                 break;
888
889             case WINED3D_DECL_USAGE_BINORMAL:
890                 TRACE("binormal");
891                 break;
892
893             case WINED3D_DECL_USAGE_TESS_FACTOR:
894                 TRACE("tessfactor");
895                 break;
896
897             case WINED3D_DECL_USAGE_POSITIONT:
898                 TRACE("positionT%u", semantic->usage_idx);
899                 break;
900
901             case WINED3D_DECL_USAGE_FOG:
902                 TRACE("fog");
903                 break;
904
905             case WINED3D_DECL_USAGE_DEPTH:
906                 TRACE("depth");
907                 break;
908
909             case WINED3D_DECL_USAGE_SAMPLE:
910                 TRACE("sample");
911                 break;
912
913             default:
914                 FIXME("unknown_semantics(0x%08x)", semantic->usage);
915         }
916     }
917 }
918
919 static void shader_dump_register(const struct wined3d_shader_register *reg,
920         const struct wined3d_shader_version *shader_version)
921 {
922     static const char * const rastout_reg_names[] = {"oPos", "oFog", "oPts"};
923     static const char * const misctype_reg_names[] = {"vPos", "vFace"};
924     UINT offset = reg->idx;
925
926     switch (reg->type)
927     {
928         case WINED3DSPR_TEMP:
929             TRACE("r");
930             break;
931
932         case WINED3DSPR_INPUT:
933             TRACE("v");
934             break;
935
936         case WINED3DSPR_CONST:
937         case WINED3DSPR_CONST2:
938         case WINED3DSPR_CONST3:
939         case WINED3DSPR_CONST4:
940             TRACE("c");
941             offset = shader_get_float_offset(reg->type, reg->idx);
942             break;
943
944         case WINED3DSPR_TEXTURE: /* vs: case WINED3DSPR_ADDR */
945             TRACE("%c", shader_version->type == WINED3D_SHADER_TYPE_PIXEL ? 't' : 'a');
946             break;
947
948         case WINED3DSPR_RASTOUT:
949             TRACE("%s", rastout_reg_names[reg->idx]);
950             break;
951
952         case WINED3DSPR_COLOROUT:
953             TRACE("oC");
954             break;
955
956         case WINED3DSPR_DEPTHOUT:
957             TRACE("oDepth");
958             break;
959
960         case WINED3DSPR_ATTROUT:
961             TRACE("oD");
962             break;
963
964         case WINED3DSPR_TEXCRDOUT:
965             /* Vertex shaders >= 3.0 use general purpose output registers
966              * (WINED3DSPR_OUTPUT), which can include an address token. */
967             if (shader_version->major >= 3) TRACE("o");
968             else TRACE("oT");
969             break;
970
971         case WINED3DSPR_CONSTINT:
972             TRACE("i");
973             break;
974
975         case WINED3DSPR_CONSTBOOL:
976             TRACE("b");
977             break;
978
979         case WINED3DSPR_LABEL:
980             TRACE("l");
981             break;
982
983         case WINED3DSPR_LOOP:
984             TRACE("aL");
985             break;
986
987         case WINED3DSPR_SAMPLER:
988             TRACE("s");
989             break;
990
991         case WINED3DSPR_MISCTYPE:
992             if (reg->idx > 1) FIXME("Unhandled misctype register %u.\n", reg->idx);
993             else TRACE("%s", misctype_reg_names[reg->idx]);
994             break;
995
996         case WINED3DSPR_PREDICATE:
997             TRACE("p");
998             break;
999
1000         case WINED3DSPR_IMMCONST:
1001             TRACE("l");
1002             break;
1003
1004         case WINED3DSPR_CONSTBUFFER:
1005             TRACE("cb");
1006             break;
1007
1008         case WINED3DSPR_NULL:
1009             TRACE("null");
1010             break;
1011
1012         case WINED3DSPR_RESOURCE:
1013             TRACE("t");
1014             break;
1015
1016         default:
1017             TRACE("unhandled_rtype(%#x)", reg->type);
1018             break;
1019     }
1020
1021     if (reg->type == WINED3DSPR_IMMCONST)
1022     {
1023         TRACE("(");
1024         switch (reg->immconst_type)
1025         {
1026             case WINED3D_IMMCONST_SCALAR:
1027                 TRACE("%.8e", *(const float *)reg->immconst_data);
1028                 break;
1029
1030             case WINED3D_IMMCONST_VEC4:
1031                 TRACE("%.8e, %.8e, %.8e, %.8e",
1032                         *(const float *)&reg->immconst_data[0], *(const float *)&reg->immconst_data[1],
1033                         *(const float *)&reg->immconst_data[2], *(const float *)&reg->immconst_data[3]);
1034                 break;
1035
1036             default:
1037                 TRACE("<unhandled immconst_type %#x>", reg->immconst_type);
1038                 break;
1039         }
1040         TRACE(")");
1041     }
1042     else if (reg->type != WINED3DSPR_RASTOUT
1043             && reg->type != WINED3DSPR_MISCTYPE
1044             && reg->type != WINED3DSPR_NULL)
1045     {
1046         if (reg->array_idx != ~0U)
1047         {
1048             TRACE("%u[%u", offset, reg->array_idx);
1049             if (reg->rel_addr)
1050             {
1051                 TRACE(" + ");
1052                 shader_dump_src_param(reg->rel_addr, shader_version);
1053             }
1054             TRACE("]");
1055         }
1056         else
1057         {
1058             if (reg->rel_addr)
1059             {
1060                 TRACE("[");
1061                 shader_dump_src_param(reg->rel_addr, shader_version);
1062                 TRACE(" + ");
1063             }
1064             TRACE("%u", offset);
1065             if (reg->rel_addr) TRACE("]");
1066         }
1067     }
1068 }
1069
1070 void shader_dump_dst_param(const struct wined3d_shader_dst_param *param,
1071         const struct wined3d_shader_version *shader_version)
1072 {
1073     DWORD write_mask = param->write_mask;
1074
1075     shader_dump_register(&param->reg, shader_version);
1076
1077     if (write_mask && write_mask != WINED3DSP_WRITEMASK_ALL)
1078     {
1079         static const char *write_mask_chars = "xyzw";
1080
1081         TRACE(".");
1082         if (write_mask & WINED3DSP_WRITEMASK_0) TRACE("%c", write_mask_chars[0]);
1083         if (write_mask & WINED3DSP_WRITEMASK_1) TRACE("%c", write_mask_chars[1]);
1084         if (write_mask & WINED3DSP_WRITEMASK_2) TRACE("%c", write_mask_chars[2]);
1085         if (write_mask & WINED3DSP_WRITEMASK_3) TRACE("%c", write_mask_chars[3]);
1086     }
1087 }
1088
1089 void shader_dump_src_param(const struct wined3d_shader_src_param *param,
1090         const struct wined3d_shader_version *shader_version)
1091 {
1092     enum wined3d_shader_src_modifier src_modifier = param->modifiers;
1093     DWORD swizzle = param->swizzle;
1094
1095     if (src_modifier == WINED3DSPSM_NEG
1096             || src_modifier == WINED3DSPSM_BIASNEG
1097             || src_modifier == WINED3DSPSM_SIGNNEG
1098             || src_modifier == WINED3DSPSM_X2NEG
1099             || src_modifier == WINED3DSPSM_ABSNEG)
1100         TRACE("-");
1101     else if (src_modifier == WINED3DSPSM_COMP)
1102         TRACE("1-");
1103     else if (src_modifier == WINED3DSPSM_NOT)
1104         TRACE("!");
1105
1106     if (src_modifier == WINED3DSPSM_ABS || src_modifier == WINED3DSPSM_ABSNEG)
1107         TRACE("abs(");
1108
1109     shader_dump_register(&param->reg, shader_version);
1110
1111     if (src_modifier)
1112     {
1113         switch (src_modifier)
1114         {
1115             case WINED3DSPSM_NONE:    break;
1116             case WINED3DSPSM_NEG:     break;
1117             case WINED3DSPSM_NOT:     break;
1118             case WINED3DSPSM_BIAS:    TRACE("_bias"); break;
1119             case WINED3DSPSM_BIASNEG: TRACE("_bias"); break;
1120             case WINED3DSPSM_SIGN:    TRACE("_bx2"); break;
1121             case WINED3DSPSM_SIGNNEG: TRACE("_bx2"); break;
1122             case WINED3DSPSM_COMP:    break;
1123             case WINED3DSPSM_X2:      TRACE("_x2"); break;
1124             case WINED3DSPSM_X2NEG:   TRACE("_x2"); break;
1125             case WINED3DSPSM_DZ:      TRACE("_dz"); break;
1126             case WINED3DSPSM_DW:      TRACE("_dw"); break;
1127             case WINED3DSPSM_ABSNEG:  TRACE(")"); break;
1128             case WINED3DSPSM_ABS:     TRACE(")"); break;
1129             default:                  TRACE("_unknown_modifier(%#x)", src_modifier);
1130         }
1131     }
1132
1133     if (swizzle != WINED3DSP_NOSWIZZLE)
1134     {
1135         static const char *swizzle_chars = "xyzw";
1136         DWORD swizzle_x = swizzle & 0x03;
1137         DWORD swizzle_y = (swizzle >> 2) & 0x03;
1138         DWORD swizzle_z = (swizzle >> 4) & 0x03;
1139         DWORD swizzle_w = (swizzle >> 6) & 0x03;
1140
1141         if (swizzle_x == swizzle_y
1142                 && swizzle_x == swizzle_z
1143                 && swizzle_x == swizzle_w)
1144         {
1145             TRACE(".%c", swizzle_chars[swizzle_x]);
1146         }
1147         else
1148         {
1149             TRACE(".%c%c%c%c", swizzle_chars[swizzle_x], swizzle_chars[swizzle_y],
1150                     swizzle_chars[swizzle_z], swizzle_chars[swizzle_w]);
1151         }
1152     }
1153 }
1154
1155 /* Shared code in order to generate the bulk of the shader string.
1156  * NOTE: A description of how to parse tokens can be found on MSDN. */
1157 void shader_generate_main(const struct wined3d_shader *shader, struct wined3d_shader_buffer *buffer,
1158         const struct wined3d_shader_reg_maps *reg_maps, const DWORD *byte_code, void *backend_ctx)
1159 {
1160     struct wined3d_device *device = shader->device;
1161     const struct wined3d_shader_frontend *fe = shader->frontend;
1162     void *fe_data = shader->frontend_data;
1163     struct wined3d_shader_src_param dst_rel_addr[2];
1164     struct wined3d_shader_src_param src_rel_addr[4];
1165     struct wined3d_shader_dst_param dst_param[2];
1166     struct wined3d_shader_src_param src_param[4];
1167     struct wined3d_shader_version shader_version;
1168     struct wined3d_shader_loop_state loop_state;
1169     struct wined3d_shader_instruction ins;
1170     struct wined3d_shader_tex_mx tex_mx;
1171     struct wined3d_shader_context ctx;
1172     const DWORD *ptr = byte_code;
1173     DWORD i;
1174
1175     /* Initialize current parsing state. */
1176     tex_mx.current_row = 0;
1177     loop_state.current_depth = 0;
1178     loop_state.current_reg = 0;
1179
1180     ctx.shader = shader;
1181     ctx.gl_info = &device->adapter->gl_info;
1182     ctx.reg_maps = reg_maps;
1183     ctx.buffer = buffer;
1184     ctx.tex_mx = &tex_mx;
1185     ctx.loop_state = &loop_state;
1186     ctx.backend_data = backend_ctx;
1187
1188     ins.ctx = &ctx;
1189     ins.dst = dst_param;
1190     ins.src = src_param;
1191
1192     fe->shader_read_header(fe_data, &ptr, &shader_version);
1193
1194     while (!fe->shader_is_end(fe_data, &ptr))
1195     {
1196         const char *comment;
1197         UINT comment_size;
1198         UINT param_size;
1199
1200         /* Skip comment tokens. */
1201         fe->shader_read_comment(&ptr, &comment, &comment_size);
1202         if (comment) continue;
1203
1204         /* Read opcode. */
1205         fe->shader_read_opcode(fe_data, &ptr, &ins, &param_size);
1206
1207         /* Unknown opcode and its parameters. */
1208         if (ins.handler_idx == WINED3DSIH_TABLE_SIZE)
1209         {
1210             TRACE("Skipping unrecognized instruction.\n");
1211             ptr += param_size;
1212             continue;
1213         }
1214
1215         /* Nothing to do. */
1216         if (ins.handler_idx == WINED3DSIH_DCL
1217                 || ins.handler_idx == WINED3DSIH_NOP
1218                 || ins.handler_idx == WINED3DSIH_DEF
1219                 || ins.handler_idx == WINED3DSIH_DEFI
1220                 || ins.handler_idx == WINED3DSIH_DEFB
1221                 || ins.handler_idx == WINED3DSIH_PHASE)
1222         {
1223             ptr += param_size;
1224             continue;
1225         }
1226
1227         /* Destination tokens */
1228         for (i = 0; i < ins.dst_count; ++i)
1229         {
1230             fe->shader_read_dst_param(fe_data, &ptr, &dst_param[i], &dst_rel_addr[i]);
1231         }
1232
1233         /* Predication token */
1234         if (ins.predicate)
1235         {
1236             FIXME("Predicates not implemented.\n");
1237             ins.predicate = *ptr++;
1238         }
1239
1240         /* Other source tokens */
1241         for (i = 0; i < ins.src_count; ++i)
1242         {
1243             fe->shader_read_src_param(fe_data, &ptr, &src_param[i], &src_rel_addr[i]);
1244         }
1245
1246         /* Call appropriate function for output target */
1247         device->shader_backend->shader_handle_instruction(&ins);
1248     }
1249 }
1250
1251 static void shader_dump_ins_modifiers(const struct wined3d_shader_dst_param *dst)
1252 {
1253     DWORD mmask = dst->modifiers;
1254
1255     switch (dst->shift)
1256     {
1257         case 0: break;
1258         case 13: TRACE("_d8"); break;
1259         case 14: TRACE("_d4"); break;
1260         case 15: TRACE("_d2"); break;
1261         case 1: TRACE("_x2"); break;
1262         case 2: TRACE("_x4"); break;
1263         case 3: TRACE("_x8"); break;
1264         default: TRACE("_unhandled_shift(%d)", dst->shift); break;
1265     }
1266
1267     if (mmask & WINED3DSPDM_SATURATE)         TRACE("_sat");
1268     if (mmask & WINED3DSPDM_PARTIALPRECISION) TRACE("_pp");
1269     if (mmask & WINED3DSPDM_MSAMPCENTROID)    TRACE("_centroid");
1270
1271     mmask &= ~(WINED3DSPDM_SATURATE | WINED3DSPDM_PARTIALPRECISION | WINED3DSPDM_MSAMPCENTROID);
1272     if (mmask) FIXME("_unrecognized_modifier(%#x)", mmask);
1273 }
1274
1275 static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe_data, const DWORD *byte_code)
1276 {
1277     struct wined3d_shader_version shader_version;
1278     const DWORD *ptr = byte_code;
1279     const char *type_prefix;
1280     DWORD i;
1281
1282     TRACE("Parsing %p.\n", byte_code);
1283
1284     fe->shader_read_header(fe_data, &ptr, &shader_version);
1285
1286     switch (shader_version.type)
1287     {
1288         case WINED3D_SHADER_TYPE_VERTEX:
1289             type_prefix = "vs";
1290             break;
1291
1292         case WINED3D_SHADER_TYPE_GEOMETRY:
1293             type_prefix = "gs";
1294             break;
1295
1296         case WINED3D_SHADER_TYPE_PIXEL:
1297             type_prefix = "ps";
1298             break;
1299
1300         default:
1301             FIXME("Unhandled shader type %#x.\n", shader_version.type);
1302             type_prefix = "unknown";
1303             break;
1304     }
1305
1306     TRACE("%s_%u_%u\n", type_prefix, shader_version.major, shader_version.minor);
1307
1308     while (!fe->shader_is_end(fe_data, &ptr))
1309     {
1310         struct wined3d_shader_instruction ins;
1311         const char *comment;
1312         UINT comment_size;
1313         UINT param_size;
1314
1315         /* comment */
1316         fe->shader_read_comment(&ptr, &comment, &comment_size);
1317         if (comment)
1318         {
1319             if (comment_size > 4 && *(const DWORD *)comment == WINEMAKEFOURCC('T', 'E', 'X', 'T'))
1320             {
1321                 const char *end = comment + comment_size;
1322                 const char *ptr = comment + 4;
1323                 const char *line = ptr;
1324
1325                 TRACE("// TEXT\n");
1326                 while (ptr != end)
1327                 {
1328                     if (*ptr == '\n')
1329                     {
1330                         UINT len = ptr - line;
1331                         if (len && *(ptr - 1) == '\r') --len;
1332                         TRACE("// %s\n", debugstr_an(line, len));
1333                         line = ++ptr;
1334                     }
1335                     else ++ptr;
1336                 }
1337                 if (line != ptr) TRACE("// %s\n", debugstr_an(line, ptr - line));
1338             }
1339             else TRACE("// %s\n", debugstr_an(comment, comment_size));
1340             continue;
1341         }
1342
1343         fe->shader_read_opcode(fe_data, &ptr, &ins, &param_size);
1344         if (ins.handler_idx == WINED3DSIH_TABLE_SIZE)
1345         {
1346             TRACE("Skipping unrecognized instruction.\n");
1347             ptr += param_size;
1348             continue;
1349         }
1350
1351         if (ins.handler_idx == WINED3DSIH_DCL)
1352         {
1353             struct wined3d_shader_semantic semantic;
1354
1355             fe->shader_read_semantic(&ptr, &semantic);
1356
1357             shader_dump_decl_usage(&semantic, &shader_version);
1358             shader_dump_ins_modifiers(&semantic.reg);
1359             TRACE(" ");
1360             shader_dump_dst_param(&semantic.reg, &shader_version);
1361         }
1362         else if (ins.handler_idx == WINED3DSIH_DEF)
1363         {
1364             struct wined3d_shader_src_param rel_addr;
1365             struct wined3d_shader_dst_param dst;
1366
1367             fe->shader_read_dst_param(fe_data, &ptr, &dst, &rel_addr);
1368
1369             TRACE("def c%u = %f, %f, %f, %f", shader_get_float_offset(dst.reg.type, dst.reg.idx),
1370                     *(const float *)(ptr),
1371                     *(const float *)(ptr + 1),
1372                     *(const float *)(ptr + 2),
1373                     *(const float *)(ptr + 3));
1374             ptr += 4;
1375         }
1376         else if (ins.handler_idx == WINED3DSIH_DEFI)
1377         {
1378             struct wined3d_shader_src_param rel_addr;
1379             struct wined3d_shader_dst_param dst;
1380
1381             fe->shader_read_dst_param(fe_data, &ptr, &dst, &rel_addr);
1382
1383             TRACE("defi i%u = %d, %d, %d, %d", dst.reg.idx,
1384                     *(ptr),
1385                     *(ptr + 1),
1386                     *(ptr + 2),
1387                     *(ptr + 3));
1388             ptr += 4;
1389         }
1390         else if (ins.handler_idx == WINED3DSIH_DEFB)
1391         {
1392             struct wined3d_shader_src_param rel_addr;
1393             struct wined3d_shader_dst_param dst;
1394
1395             fe->shader_read_dst_param(fe_data, &ptr, &dst, &rel_addr);
1396
1397             TRACE("defb b%u = %s", dst.reg.idx, *ptr ? "true" : "false");
1398             ++ptr;
1399         }
1400         else
1401         {
1402             struct wined3d_shader_src_param dst_rel_addr[2];
1403             struct wined3d_shader_src_param src_rel_addr;
1404             struct wined3d_shader_dst_param dst_param[2];
1405             struct wined3d_shader_src_param src_param;
1406
1407             for (i = 0; i < ins.dst_count; ++i)
1408             {
1409                 fe->shader_read_dst_param(fe_data, &ptr, &dst_param[i], &dst_rel_addr[i]);
1410             }
1411
1412             /* Print out predication source token first - it follows
1413              * the destination token. */
1414             if (ins.predicate)
1415             {
1416                 fe->shader_read_src_param(fe_data, &ptr, &src_param, &src_rel_addr);
1417                 TRACE("(");
1418                 shader_dump_src_param(&src_param, &shader_version);
1419                 TRACE(") ");
1420             }
1421
1422             /* PixWin marks instructions with the coissue flag with a '+' */
1423             if (ins.coissue) TRACE("+");
1424
1425             TRACE("%s", shader_opcode_names[ins.handler_idx]);
1426
1427             if (ins.handler_idx == WINED3DSIH_IFC
1428                     || ins.handler_idx == WINED3DSIH_BREAKC)
1429             {
1430                 switch (ins.flags)
1431                 {
1432                     case WINED3D_SHADER_REL_OP_GT: TRACE("_gt"); break;
1433                     case WINED3D_SHADER_REL_OP_EQ: TRACE("_eq"); break;
1434                     case WINED3D_SHADER_REL_OP_GE: TRACE("_ge"); break;
1435                     case WINED3D_SHADER_REL_OP_LT: TRACE("_lt"); break;
1436                     case WINED3D_SHADER_REL_OP_NE: TRACE("_ne"); break;
1437                     case WINED3D_SHADER_REL_OP_LE: TRACE("_le"); break;
1438                     default: TRACE("_(%u)", ins.flags);
1439                 }
1440             }
1441             else if (ins.handler_idx == WINED3DSIH_TEX
1442                     && shader_version.major >= 2
1443                     && (ins.flags & WINED3DSI_TEXLD_PROJECT))
1444             {
1445                 TRACE("p");
1446             }
1447
1448             /* We already read the destination tokens, print them. */
1449             for (i = 0; i < ins.dst_count; ++i)
1450             {
1451                 shader_dump_ins_modifiers(&dst_param[i]);
1452                 TRACE(!i ? " " : ", ");
1453                 shader_dump_dst_param(&dst_param[i], &shader_version);
1454             }
1455
1456             /* Other source tokens */
1457             for (i = ins.dst_count; i < (ins.dst_count + ins.src_count); ++i)
1458             {
1459                 fe->shader_read_src_param(fe_data, &ptr, &src_param, &src_rel_addr);
1460                 TRACE(!i ? " " : ", ");
1461                 shader_dump_src_param(&src_param, &shader_version);
1462             }
1463         }
1464         TRACE("\n");
1465     }
1466 }
1467
1468 static void shader_cleanup(struct wined3d_shader *shader)
1469 {
1470     shader->device->shader_backend->shader_destroy(shader);
1471     HeapFree(GetProcessHeap(), 0, shader->reg_maps.constf);
1472     HeapFree(GetProcessHeap(), 0, shader->function);
1473     shader_delete_constant_list(&shader->constantsF);
1474     shader_delete_constant_list(&shader->constantsB);
1475     shader_delete_constant_list(&shader->constantsI);
1476     list_remove(&shader->shader_list_entry);
1477
1478     if (shader->frontend && shader->frontend_data)
1479         shader->frontend->shader_free(shader->frontend_data);
1480 }
1481
1482 static void shader_none_handle_instruction(const struct wined3d_shader_instruction *ins) {}
1483 static void shader_none_select(const struct wined3d_context *context, BOOL usePS, BOOL useVS) {}
1484 static void shader_none_select_depth_blt(void *shader_priv, const struct wined3d_gl_info *gl_info,
1485         enum tex_types tex_type, const SIZE *ds_mask_size) {}
1486 static void shader_none_deselect_depth_blt(void *shader_priv, const struct wined3d_gl_info *gl_info) {}
1487 static void shader_none_update_float_vertex_constants(struct wined3d_device *device, UINT start, UINT count) {}
1488 static void shader_none_update_float_pixel_constants(struct wined3d_device *device, UINT start, UINT count) {}
1489 static void shader_none_load_constants(const struct wined3d_context *context, char usePS, char useVS) {}
1490 static void shader_none_load_np2fixup_constants(void *shader_priv,
1491         const struct wined3d_gl_info *gl_info, const struct wined3d_state *state) {}
1492 static void shader_none_destroy(struct wined3d_shader *shader) {}
1493 static HRESULT shader_none_alloc(struct wined3d_device *device) {return WINED3D_OK;}
1494 static void shader_none_free(struct wined3d_device *device) {}
1495 static void shader_none_context_destroyed(void *shader_priv, const struct wined3d_context *context) {}
1496
1497 static void shader_none_get_caps(const struct wined3d_gl_info *gl_info, struct shader_caps *caps)
1498 {
1499     /* Set the shader caps to 0 for the none shader backend */
1500     caps->VertexShaderVersion = 0;
1501     caps->MaxVertexShaderConst = 0;
1502     caps->PixelShaderVersion = 0;
1503     caps->PixelShader1xMaxValue = 0.0f;
1504     caps->MaxPixelShaderConst = 0;
1505     caps->VSClipping = FALSE;
1506 }
1507
1508 static BOOL shader_none_color_fixup_supported(struct color_fixup_desc fixup)
1509 {
1510     if (TRACE_ON(d3d_shader) && TRACE_ON(d3d))
1511     {
1512         TRACE("Checking support for fixup:\n");
1513         dump_color_fixup_desc(fixup);
1514     }
1515
1516     /* Faked to make some apps happy. */
1517     if (!is_complex_fixup(fixup))
1518     {
1519         TRACE("[OK]\n");
1520         return TRUE;
1521     }
1522
1523     TRACE("[FAILED]\n");
1524     return FALSE;
1525 }
1526
1527 const struct wined3d_shader_backend_ops none_shader_backend =
1528 {
1529     shader_none_handle_instruction,
1530     shader_none_select,
1531     shader_none_select_depth_blt,
1532     shader_none_deselect_depth_blt,
1533     shader_none_update_float_vertex_constants,
1534     shader_none_update_float_pixel_constants,
1535     shader_none_load_constants,
1536     shader_none_load_np2fixup_constants,
1537     shader_none_destroy,
1538     shader_none_alloc,
1539     shader_none_free,
1540     shader_none_context_destroyed,
1541     shader_none_get_caps,
1542     shader_none_color_fixup_supported,
1543 };
1544
1545 static HRESULT shader_set_function(struct wined3d_shader *shader, const DWORD *byte_code,
1546         const struct wined3d_shader_signature *output_signature, DWORD float_const_count,
1547         enum wined3d_shader_type type, unsigned int max_version)
1548 {
1549     struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
1550     const struct wined3d_shader_frontend *fe;
1551     HRESULT hr;
1552     unsigned int backend_version;
1553
1554     TRACE("shader %p, byte_code %p, output_signature %p, float_const_count %u.\n",
1555             shader, byte_code, output_signature, float_const_count);
1556
1557     fe = shader_select_frontend(*byte_code);
1558     if (!fe)
1559     {
1560         FIXME("Unable to find frontend for shader.\n");
1561         return WINED3DERR_INVALIDCALL;
1562     }
1563     shader->frontend = fe;
1564     shader->frontend_data = fe->shader_init(byte_code, output_signature);
1565     if (!shader->frontend_data)
1566     {
1567         FIXME("Failed to initialize frontend.\n");
1568         return WINED3DERR_INVALIDCALL;
1569     }
1570
1571     /* First pass: trace shader. */
1572     if (TRACE_ON(d3d_shader))
1573         shader_trace_init(fe, shader->frontend_data, byte_code);
1574
1575     /* Initialize immediate constant lists. */
1576     list_init(&shader->constantsF);
1577     list_init(&shader->constantsB);
1578     list_init(&shader->constantsI);
1579
1580     /* Second pass: figure out which registers are used, what the semantics are, etc. */
1581     hr = shader_get_registers_used(shader, fe,
1582             reg_maps, shader->input_signature, shader->output_signature,
1583             byte_code, float_const_count);
1584     if (FAILED(hr)) return hr;
1585
1586     if (reg_maps->shader_version.type != type)
1587     {
1588         WARN("Wrong shader type %d.\n", reg_maps->shader_version.type);
1589         return WINED3DERR_INVALIDCALL;
1590     }
1591     if (reg_maps->shader_version.major > max_version)
1592     {
1593         WARN("Shader version %d not supported by this D3D API version.\n", reg_maps->shader_version.major);
1594         return WINED3DERR_INVALIDCALL;
1595     }
1596     switch (type)
1597     {
1598         case WINED3D_SHADER_TYPE_VERTEX:
1599             backend_version = shader->device->vshader_version;
1600             break;
1601         case WINED3D_SHADER_TYPE_PIXEL:
1602             backend_version = shader->device->pshader_version;
1603             break;
1604         default:
1605             FIXME("No backend version-checking for this shader type\n");
1606             backend_version = 0;
1607     }
1608     if (reg_maps->shader_version.major > backend_version)
1609     {
1610         WARN("Shader version %d.%d not supported by your GPU with the current shader backend.\n",
1611                 reg_maps->shader_version.major, reg_maps->shader_version.minor);
1612         return WINED3DERR_INVALIDCALL;
1613     }
1614
1615     shader->function = HeapAlloc(GetProcessHeap(), 0, shader->functionLength);
1616     if (!shader->function)
1617         return E_OUTOFMEMORY;
1618     memcpy(shader->function, byte_code, shader->functionLength);
1619
1620     return WINED3D_OK;
1621 }
1622
1623 ULONG CDECL wined3d_shader_incref(struct wined3d_shader *shader)
1624 {
1625     ULONG refcount = InterlockedIncrement(&shader->ref);
1626
1627     TRACE("%p increasing refcount to %u.\n", shader, refcount);
1628
1629     return refcount;
1630 }
1631
1632 /* Do not call while under the GL lock. */
1633 ULONG CDECL wined3d_shader_decref(struct wined3d_shader *shader)
1634 {
1635     ULONG refcount = InterlockedDecrement(&shader->ref);
1636
1637     TRACE("%p decreasing refcount to %u.\n", shader, refcount);
1638
1639     if (!refcount)
1640     {
1641         shader_cleanup(shader);
1642         shader->parent_ops->wined3d_object_destroyed(shader->parent);
1643         HeapFree(GetProcessHeap(), 0, shader);
1644     }
1645
1646     return refcount;
1647 }
1648
1649 void * CDECL wined3d_shader_get_parent(const struct wined3d_shader *shader)
1650 {
1651     TRACE("shader %p.\n", shader);
1652
1653     return shader->parent;
1654 }
1655
1656 HRESULT CDECL wined3d_shader_get_byte_code(const struct wined3d_shader *shader,
1657         void *byte_code, UINT *byte_code_size)
1658 {
1659     TRACE("shader %p, byte_code %p, byte_code_size %p.\n", shader, byte_code, byte_code_size);
1660
1661     if (!byte_code)
1662     {
1663         *byte_code_size = shader->functionLength;
1664         return WINED3D_OK;
1665     }
1666
1667     if (*byte_code_size < shader->functionLength)
1668     {
1669         /* MSDN claims (for d3d8 at least) that if *byte_code_size is smaller
1670          * than the required size we should write the required size and
1671          * return D3DERR_MOREDATA. That's not actually true. */
1672         return WINED3DERR_INVALIDCALL;
1673     }
1674
1675     memcpy(byte_code, shader->function, shader->functionLength);
1676
1677     return WINED3D_OK;
1678 }
1679
1680 /* Set local constants for d3d8 shaders. */
1681 HRESULT CDECL wined3d_shader_set_local_constants_float(struct wined3d_shader *shader,
1682         UINT start_idx, const float *src_data, UINT count)
1683 {
1684     UINT end_idx = start_idx + count;
1685     UINT i;
1686
1687     TRACE("shader %p, start_idx %u, src_data %p, count %u.\n", shader, start_idx, src_data, count);
1688
1689     if (end_idx > shader->limits.constant_float)
1690     {
1691         WARN("end_idx %u > float constants limit %u.\n",
1692                 end_idx, shader->limits.constant_float);
1693         end_idx = shader->limits.constant_float;
1694     }
1695
1696     for (i = start_idx; i < end_idx; ++i)
1697     {
1698         struct wined3d_shader_lconst *lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(*lconst));
1699         if (!lconst)
1700             return E_OUTOFMEMORY;
1701
1702         lconst->idx = i;
1703         memcpy(lconst->value, src_data + (i - start_idx) * 4 /* 4 components */, 4 * sizeof(float));
1704         list_add_head(&shader->constantsF, &lconst->entry);
1705     }
1706
1707     return WINED3D_OK;
1708 }
1709
1710 void find_vs_compile_args(const struct wined3d_state *state,
1711         const struct wined3d_shader *shader, struct vs_compile_args *args)
1712 {
1713     args->fog_src = state->render_states[WINED3D_RS_FOGTABLEMODE]
1714             == WINED3D_FOG_NONE ? VS_FOG_COORD : VS_FOG_Z;
1715     args->clip_enabled = state->render_states[WINED3D_RS_CLIPPING]
1716             && state->render_states[WINED3D_RS_CLIPPLANEENABLE];
1717     args->swizzle_map = shader->device->strided_streams.swizzle_map;
1718 }
1719
1720 static BOOL match_usage(BYTE usage1, BYTE usage_idx1, BYTE usage2, BYTE usage_idx2)
1721 {
1722     if (usage_idx1 != usage_idx2)
1723         return FALSE;
1724     if (usage1 == usage2)
1725         return TRUE;
1726     if (usage1 == WINED3D_DECL_USAGE_POSITION && usage2 == WINED3D_DECL_USAGE_POSITIONT)
1727         return TRUE;
1728     if (usage2 == WINED3D_DECL_USAGE_POSITION && usage1 == WINED3D_DECL_USAGE_POSITIONT)
1729         return TRUE;
1730
1731     return FALSE;
1732 }
1733
1734 BOOL vshader_get_input(const struct wined3d_shader *shader,
1735         BYTE usage_req, BYTE usage_idx_req, unsigned int *regnum)
1736 {
1737     WORD map = shader->reg_maps.input_registers;
1738     unsigned int i;
1739
1740     for (i = 0; map; map >>= 1, ++i)
1741     {
1742         if (!(map & 1)) continue;
1743
1744         if (match_usage(shader->u.vs.attributes[i].usage,
1745                 shader->u.vs.attributes[i].usage_idx, usage_req, usage_idx_req))
1746         {
1747             *regnum = i;
1748             return TRUE;
1749         }
1750     }
1751     return FALSE;
1752 }
1753
1754 static void vertexshader_set_limits(struct wined3d_shader *shader)
1755 {
1756     DWORD shader_version = WINED3D_SHADER_VERSION(shader->reg_maps.shader_version.major,
1757             shader->reg_maps.shader_version.minor);
1758     struct wined3d_device *device = shader->device;
1759
1760     shader->limits.texcoord = 0;
1761     shader->limits.attributes = 16;
1762     shader->limits.packed_input = 0;
1763
1764     switch (shader_version)
1765     {
1766         case WINED3D_SHADER_VERSION(1, 0):
1767         case WINED3D_SHADER_VERSION(1, 1):
1768             shader->limits.temporary = 12;
1769             shader->limits.constant_bool = 0;
1770             shader->limits.constant_int = 0;
1771             shader->limits.address = 1;
1772             shader->limits.packed_output = 12;
1773             shader->limits.sampler = 0;
1774             shader->limits.label = 0;
1775             /* TODO: vs_1_1 has a minimum of 96 constants. What happens when
1776              * a vs_1_1 shader is used on a vs_3_0 capable card that has 256
1777              * constants? */
1778             shader->limits.constant_float = min(256, device->d3d_vshader_constantF);
1779             break;
1780
1781         case WINED3D_SHADER_VERSION(2, 0):
1782         case WINED3D_SHADER_VERSION(2, 1):
1783             shader->limits.temporary = 12;
1784             shader->limits.constant_bool = 16;
1785             shader->limits.constant_int = 16;
1786             shader->limits.address = 1;
1787             shader->limits.packed_output = 12;
1788             shader->limits.sampler = 0;
1789             shader->limits.label = 16;
1790             shader->limits.constant_float = min(256, device->d3d_vshader_constantF);
1791             break;
1792
1793         case WINED3D_SHADER_VERSION(4, 0):
1794             FIXME("Using 3.0 limits for 4.0 shader.\n");
1795             /* Fall through. */
1796
1797         case WINED3D_SHADER_VERSION(3, 0):
1798             shader->limits.temporary = 32;
1799             shader->limits.constant_bool = 32;
1800             shader->limits.constant_int = 32;
1801             shader->limits.address = 1;
1802             shader->limits.packed_output = 12;
1803             shader->limits.sampler = 4;
1804             shader->limits.label = 16; /* FIXME: 2048 */
1805             /* DX10 cards on Windows advertise a d3d9 constant limit of 256
1806              * even though they are capable of supporting much more (GL
1807              * drivers advertise 1024). d3d9.dll and d3d8.dll clamp the
1808              * wined3d-advertised maximum. Clamp the constant limit for <= 3.0
1809              * shaders to 256. */
1810             shader->limits.constant_float = min(256, device->d3d_vshader_constantF);
1811             break;
1812
1813         default:
1814             shader->limits.temporary = 12;
1815             shader->limits.constant_bool = 16;
1816             shader->limits.constant_int = 16;
1817             shader->limits.address = 1;
1818             shader->limits.packed_output = 12;
1819             shader->limits.sampler = 0;
1820             shader->limits.label = 16;
1821             shader->limits.constant_float = min(256, device->d3d_vshader_constantF);
1822             FIXME("Unrecognized vertex shader version \"%u.%u\".\n",
1823                     shader->reg_maps.shader_version.major,
1824                     shader->reg_maps.shader_version.minor);
1825     }
1826 }
1827
1828 static HRESULT vertexshader_init(struct wined3d_shader *shader, struct wined3d_device *device,
1829         const DWORD *byte_code, const struct wined3d_shader_signature *output_signature,
1830         void *parent, const struct wined3d_parent_ops *parent_ops, unsigned int max_version)
1831 {
1832     struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
1833     unsigned int i;
1834     HRESULT hr;
1835     WORD map;
1836
1837     if (!byte_code) return WINED3DERR_INVALIDCALL;
1838
1839     shader_init(shader, device, parent, parent_ops);
1840     hr = shader_set_function(shader, byte_code, output_signature, device->d3d_vshader_constantF,
1841             WINED3D_SHADER_TYPE_VERTEX, max_version);
1842     if (FAILED(hr))
1843     {
1844         WARN("Failed to set function, hr %#x.\n", hr);
1845         shader_cleanup(shader);
1846         return hr;
1847     }
1848
1849     map = reg_maps->input_registers;
1850     for (i = 0; map; map >>= 1, ++i)
1851     {
1852         if (!(map & 1) || !shader->input_signature[i].semantic_name)
1853             continue;
1854
1855         shader->u.vs.attributes[i].usage =
1856                 shader_usage_from_semantic_name(shader->input_signature[i].semantic_name);
1857         shader->u.vs.attributes[i].usage_idx = shader->input_signature[i].semantic_idx;
1858     }
1859
1860     if (output_signature)
1861     {
1862         for (i = 0; i < output_signature->element_count; ++i)
1863         {
1864             struct wined3d_shader_signature_element *e = &output_signature->elements[i];
1865             reg_maps->output_registers |= 1 << e->register_idx;
1866             shader->output_signature[e->register_idx] = *e;
1867         }
1868     }
1869
1870     vertexshader_set_limits(shader);
1871
1872     shader->load_local_constsF = reg_maps->usesrelconstF
1873             && !list_empty(&shader->constantsF);
1874
1875     return WINED3D_OK;
1876 }
1877
1878 static HRESULT geometryshader_init(struct wined3d_shader *shader, struct wined3d_device *device,
1879         const DWORD *byte_code, const struct wined3d_shader_signature *output_signature,
1880         void *parent, const struct wined3d_parent_ops *parent_ops, unsigned int max_version)
1881 {
1882     HRESULT hr;
1883
1884     shader_init(shader, device, parent, parent_ops);
1885     hr = shader_set_function(shader, byte_code, output_signature, 0,
1886             WINED3D_SHADER_TYPE_GEOMETRY, max_version);
1887     if (FAILED(hr))
1888     {
1889         WARN("Failed to set function, hr %#x.\n", hr);
1890         shader_cleanup(shader);
1891         return hr;
1892     }
1893
1894     shader->load_local_constsF = FALSE;
1895
1896     return WINED3D_OK;
1897 }
1898
1899 void find_ps_compile_args(const struct wined3d_state *state,
1900         const struct wined3d_shader *shader, struct ps_compile_args *args)
1901 {
1902     struct wined3d_device *device = shader->device;
1903     const struct wined3d_texture *texture;
1904     UINT i;
1905
1906     memset(args, 0, sizeof(*args)); /* FIXME: Make sure all bits are set. */
1907     if (state->render_states[WINED3D_RS_SRGBWRITEENABLE])
1908     {
1909         const struct wined3d_surface *rt = state->fb->render_targets[0];
1910         if (rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE) args->srgb_correction = 1;
1911     }
1912
1913     if (shader->reg_maps.shader_version.major == 1
1914             && shader->reg_maps.shader_version.minor <= 3)
1915     {
1916         for (i = 0; i < 4; ++i)
1917         {
1918             DWORD flags = state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS];
1919
1920             if (flags & WINED3D_TTFF_PROJECTED)
1921             {
1922                 DWORD tex_transform = flags & ~WINED3D_TTFF_PROJECTED;
1923
1924                 if (!state->vertex_shader)
1925                 {
1926                     unsigned int j;
1927                     unsigned int index = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX];
1928                     DWORD max_valid = WINED3D_TTFF_COUNT4;
1929                     enum wined3d_sampler_texture_type sampler_type = shader->reg_maps.sampler_type[i];
1930
1931                     for (j = 0; j < state->vertex_declaration->element_count; ++j)
1932                     {
1933                         struct wined3d_vertex_declaration_element *element =
1934                                 &state->vertex_declaration->elements[j];
1935
1936                         if (element->usage == WINED3D_DECL_USAGE_TEXCOORD
1937                                 && element->usage_idx == index)
1938                         {
1939                             max_valid = element->format->component_count;
1940                             break;
1941                         }
1942                     }
1943                     if (!tex_transform || tex_transform > max_valid)
1944                     {
1945                         WARN("Fixing up projected texture transform flags from %#x to %#x.\n",
1946                                 tex_transform, max_valid);
1947                         tex_transform = max_valid;
1948                     }
1949                     if ((sampler_type == WINED3DSTT_1D && tex_transform > WINED3D_TTFF_COUNT1)
1950                             || (sampler_type == WINED3DSTT_2D && tex_transform > WINED3D_TTFF_COUNT2)
1951                             || (sampler_type == WINED3DSTT_VOLUME && tex_transform > WINED3D_TTFF_COUNT3))
1952                         tex_transform |= WINED3D_PSARGS_PROJECTED;
1953                     else
1954                     {
1955                         WARN("Application requested projected texture with unsuitable texture coordinates.\n");
1956                         WARN("(texture unit %u, transform flags %#x, sampler type %u).\n",
1957                                 i, tex_transform, sampler_type);
1958                     }
1959                 }
1960                 else
1961                     tex_transform = WINED3D_TTFF_COUNT4 | WINED3D_PSARGS_PROJECTED;
1962
1963                 args->tex_transform |= tex_transform << i * WINED3D_PSARGS_TEXTRANSFORM_SHIFT;
1964             }
1965         }
1966     }
1967
1968     for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
1969     {
1970         if (!shader->reg_maps.sampler_type[i])
1971             continue;
1972
1973         texture = state->textures[i];
1974         if (!texture)
1975         {
1976             args->color_fixup[i] = COLOR_FIXUP_IDENTITY;
1977             continue;
1978         }
1979         args->color_fixup[i] = texture->resource.format->color_fixup;
1980
1981         if (texture->resource.format->flags & WINED3DFMT_FLAG_SHADOW)
1982             args->shadow |= 1 << i;
1983
1984         /* Flag samplers that need NP2 texcoord fixup. */
1985         if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
1986             args->np2_fixup |= (1 << i);
1987     }
1988     if (shader->reg_maps.shader_version.major >= 3)
1989     {
1990         if (device->strided_streams.position_transformed)
1991         {
1992             args->vp_mode = pretransformed;
1993         }
1994         else if (use_vs(state))
1995         {
1996             args->vp_mode = vertexshader;
1997         }
1998         else
1999         {
2000             args->vp_mode = fixedfunction;
2001         }
2002         args->fog = FOG_OFF;
2003     }
2004     else
2005     {
2006         args->vp_mode = vertexshader;
2007         if (state->render_states[WINED3D_RS_FOGENABLE])
2008         {
2009             switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
2010             {
2011                 case WINED3D_FOG_NONE:
2012                     if (device->strided_streams.position_transformed || use_vs(state))
2013                     {
2014                         args->fog = FOG_LINEAR;
2015                         break;
2016                     }
2017
2018                     switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
2019                     {
2020                         case WINED3D_FOG_NONE: /* Fall through. */
2021                         case WINED3D_FOG_LINEAR: args->fog = FOG_LINEAR; break;
2022                         case WINED3D_FOG_EXP:    args->fog = FOG_EXP;    break;
2023                         case WINED3D_FOG_EXP2:   args->fog = FOG_EXP2;   break;
2024                     }
2025                     break;
2026
2027                 case WINED3D_FOG_LINEAR: args->fog = FOG_LINEAR; break;
2028                 case WINED3D_FOG_EXP:    args->fog = FOG_EXP;    break;
2029                 case WINED3D_FOG_EXP2:   args->fog = FOG_EXP2;   break;
2030             }
2031         }
2032         else
2033         {
2034             args->fog = FOG_OFF;
2035         }
2036     }
2037 }
2038
2039 static void pixelshader_set_limits(struct wined3d_shader *shader)
2040 {
2041     DWORD shader_version = WINED3D_SHADER_VERSION(shader->reg_maps.shader_version.major,
2042             shader->reg_maps.shader_version.minor);
2043
2044     shader->limits.attributes = 0;
2045     shader->limits.address = 0;
2046     shader->limits.packed_output = 0;
2047
2048     switch (shader_version)
2049     {
2050         case WINED3D_SHADER_VERSION(1, 0):
2051         case WINED3D_SHADER_VERSION(1, 1):
2052         case WINED3D_SHADER_VERSION(1, 2):
2053         case WINED3D_SHADER_VERSION(1, 3):
2054             shader->limits.temporary = 2;
2055             shader->limits.constant_float = 8;
2056             shader->limits.constant_int = 0;
2057             shader->limits.constant_bool = 0;
2058             shader->limits.texcoord = 4;
2059             shader->limits.sampler = 4;
2060             shader->limits.packed_input = 0;
2061             shader->limits.label = 0;
2062             break;
2063
2064         case WINED3D_SHADER_VERSION(1, 4):
2065             shader->limits.temporary = 6;
2066             shader->limits.constant_float = 8;
2067             shader->limits.constant_int = 0;
2068             shader->limits.constant_bool = 0;
2069             shader->limits.texcoord = 6;
2070             shader->limits.sampler = 6;
2071             shader->limits.packed_input = 0;
2072             shader->limits.label = 0;
2073             break;
2074
2075         /* FIXME: Temporaries must match D3DPSHADERCAPS2_0.NumTemps. */
2076         case WINED3D_SHADER_VERSION(2, 0):
2077             shader->limits.temporary = 32;
2078             shader->limits.constant_float = 32;
2079             shader->limits.constant_int = 16;
2080             shader->limits.constant_bool = 16;
2081             shader->limits.texcoord = 8;
2082             shader->limits.sampler = 16;
2083             shader->limits.packed_input = 0;
2084             break;
2085
2086         case WINED3D_SHADER_VERSION(2, 1):
2087             shader->limits.temporary = 32;
2088             shader->limits.constant_float = 32;
2089             shader->limits.constant_int = 16;
2090             shader->limits.constant_bool = 16;
2091             shader->limits.texcoord = 8;
2092             shader->limits.sampler = 16;
2093             shader->limits.packed_input = 0;
2094             shader->limits.label = 16;
2095             break;
2096
2097         case WINED3D_SHADER_VERSION(4, 0):
2098             FIXME("Using 3.0 limits for 4.0 shader.\n");
2099             /* Fall through. */
2100
2101         case WINED3D_SHADER_VERSION(3, 0):
2102             shader->limits.temporary = 32;
2103             shader->limits.constant_float = 224;
2104             shader->limits.constant_int = 16;
2105             shader->limits.constant_bool = 16;
2106             shader->limits.texcoord = 0;
2107             shader->limits.sampler = 16;
2108             shader->limits.packed_input = 12;
2109             shader->limits.label = 16; /* FIXME: 2048 */
2110             break;
2111
2112         default:
2113             shader->limits.temporary = 32;
2114             shader->limits.constant_float = 32;
2115             shader->limits.constant_int = 16;
2116             shader->limits.constant_bool = 16;
2117             shader->limits.texcoord = 8;
2118             shader->limits.sampler = 16;
2119             shader->limits.packed_input = 0;
2120             shader->limits.label = 0;
2121             FIXME("Unrecognized pixel shader version %u.%u\n",
2122                     shader->reg_maps.shader_version.major,
2123                     shader->reg_maps.shader_version.minor);
2124     }
2125 }
2126
2127 static HRESULT pixelshader_init(struct wined3d_shader *shader, struct wined3d_device *device,
2128         const DWORD *byte_code, const struct wined3d_shader_signature *output_signature,
2129         void *parent, const struct wined3d_parent_ops *parent_ops, unsigned int max_version)
2130 {
2131     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2132     unsigned int i, highest_reg_used = 0, num_regs_used = 0;
2133     HRESULT hr;
2134
2135     if (!byte_code) return WINED3DERR_INVALIDCALL;
2136
2137     shader_init(shader, device, parent, parent_ops);
2138     hr = shader_set_function(shader, byte_code, output_signature, device->d3d_pshader_constantF,
2139             WINED3D_SHADER_TYPE_PIXEL, max_version);
2140     if (FAILED(hr))
2141     {
2142         WARN("Failed to set function, hr %#x.\n", hr);
2143         shader_cleanup(shader);
2144         return hr;
2145     }
2146
2147     pixelshader_set_limits(shader);
2148
2149     for (i = 0; i < MAX_REG_INPUT; ++i)
2150     {
2151         if (shader->u.ps.input_reg_used[i])
2152         {
2153             ++num_regs_used;
2154             highest_reg_used = i;
2155         }
2156     }
2157
2158     /* Don't do any register mapping magic if it is not needed, or if we can't
2159      * achieve anything anyway */
2160     if (highest_reg_used < (gl_info->limits.glsl_varyings / 4)
2161             || num_regs_used > (gl_info->limits.glsl_varyings / 4))
2162     {
2163         if (num_regs_used > (gl_info->limits.glsl_varyings / 4))
2164         {
2165             /* This happens with relative addressing. The input mapper function
2166              * warns about this if the higher registers are declared too, so
2167              * don't write a FIXME here */
2168             WARN("More varying registers used than supported\n");
2169         }
2170
2171         for (i = 0; i < MAX_REG_INPUT; ++i)
2172         {
2173             shader->u.ps.input_reg_map[i] = i;
2174         }
2175
2176         shader->u.ps.declared_in_count = highest_reg_used + 1;
2177     }
2178     else
2179     {
2180         shader->u.ps.declared_in_count = 0;
2181         for (i = 0; i < MAX_REG_INPUT; ++i)
2182         {
2183             if (shader->u.ps.input_reg_used[i])
2184                 shader->u.ps.input_reg_map[i] = shader->u.ps.declared_in_count++;
2185             else shader->u.ps.input_reg_map[i] = ~0U;
2186         }
2187     }
2188
2189     shader->load_local_constsF = FALSE;
2190
2191     return WINED3D_OK;
2192 }
2193
2194 void pixelshader_update_samplers(struct wined3d_shader_reg_maps *reg_maps, struct wined3d_texture * const *textures)
2195 {
2196     enum wined3d_sampler_texture_type *sampler_type = reg_maps->sampler_type;
2197     unsigned int i;
2198
2199     if (reg_maps->shader_version.major != 1) return;
2200
2201     for (i = 0; i < max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS); ++i)
2202     {
2203         /* We don't sample from this sampler. */
2204         if (!sampler_type[i]) continue;
2205
2206         if (!textures[i])
2207         {
2208             WARN("No texture bound to sampler %u, using 2D.\n", i);
2209             sampler_type[i] = WINED3DSTT_2D;
2210             continue;
2211         }
2212
2213         switch (textures[i]->target)
2214         {
2215             case GL_TEXTURE_RECTANGLE_ARB:
2216             case GL_TEXTURE_2D:
2217                 /* We have to select between texture rectangles and 2D
2218                  * textures later because 2.0 and 3.0 shaders only have
2219                  * WINED3DSTT_2D as well. */
2220                 sampler_type[i] = WINED3DSTT_2D;
2221                 break;
2222
2223             case GL_TEXTURE_3D:
2224                 sampler_type[i] = WINED3DSTT_VOLUME;
2225                 break;
2226
2227             case GL_TEXTURE_CUBE_MAP_ARB:
2228                 sampler_type[i] = WINED3DSTT_CUBE;
2229                 break;
2230
2231             default:
2232                 FIXME("Unrecognized texture type %#x, using 2D.\n", textures[i]->target);
2233                 sampler_type[i] = WINED3DSTT_2D;
2234         }
2235     }
2236 }
2237
2238 HRESULT CDECL wined3d_shader_create_gs(struct wined3d_device *device, const DWORD *byte_code,
2239         const struct wined3d_shader_signature *output_signature, void *parent,
2240         const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader, unsigned int max_version)
2241 {
2242     struct wined3d_shader *object;
2243     HRESULT hr;
2244
2245     TRACE("device %p, byte_code %p, output_signature %p, parent %p, parent_ops %p, shader %p.\n",
2246             device, byte_code, output_signature, parent, parent_ops, shader);
2247
2248     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
2249     if (!object)
2250     {
2251         ERR("Failed to allocate shader memory.\n");
2252         return E_OUTOFMEMORY;
2253     }
2254
2255     hr = geometryshader_init(object, device, byte_code, output_signature, parent, parent_ops, max_version);
2256     if (FAILED(hr))
2257     {
2258         WARN("Failed to initialize geometry shader, hr %#x.\n", hr);
2259         HeapFree(GetProcessHeap(), 0, object);
2260         return hr;
2261     }
2262
2263     TRACE("Created geometry shader %p.\n", object);
2264     *shader = object;
2265
2266     return WINED3D_OK;
2267 }
2268
2269 HRESULT CDECL wined3d_shader_create_ps(struct wined3d_device *device, const DWORD *byte_code,
2270         const struct wined3d_shader_signature *output_signature, void *parent,
2271         const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader, unsigned int max_version)
2272 {
2273     struct wined3d_shader *object;
2274     HRESULT hr;
2275
2276     TRACE("device %p, byte_code %p, output_signature %p, parent %p, parent_ops %p, shader %p.\n",
2277             device, byte_code, output_signature, parent, parent_ops, shader);
2278
2279     if (device->ps_selected_mode == SHADER_NONE)
2280         return WINED3DERR_INVALIDCALL;
2281
2282     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
2283     if (!object)
2284     {
2285         ERR("Failed to allocate shader memory.\n");
2286         return E_OUTOFMEMORY;
2287     }
2288
2289     hr = pixelshader_init(object, device, byte_code, output_signature, parent, parent_ops, max_version);
2290     if (FAILED(hr))
2291     {
2292         WARN("Failed to initialize pixel shader, hr %#x.\n", hr);
2293         HeapFree(GetProcessHeap(), 0, object);
2294         return hr;
2295     }
2296
2297     TRACE("Created pixel shader %p.\n", object);
2298     *shader = object;
2299
2300     return WINED3D_OK;
2301 }
2302
2303 HRESULT CDECL wined3d_shader_create_vs(struct wined3d_device *device, const DWORD *byte_code,
2304         const struct wined3d_shader_signature *output_signature, void *parent,
2305         const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader, unsigned int max_version)
2306 {
2307     struct wined3d_shader *object;
2308     HRESULT hr;
2309
2310     TRACE("device %p, byte_code %p, output_signature %p, parent %p, parent_ops %p, shader %p.\n",
2311             device, byte_code, output_signature, parent, parent_ops, shader);
2312
2313     if (device->vs_selected_mode == SHADER_NONE)
2314         return WINED3DERR_INVALIDCALL;
2315
2316     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
2317     if (!object)
2318     {
2319         ERR("Failed to allocate shader memory.\n");
2320         return E_OUTOFMEMORY;
2321     }
2322
2323     hr = vertexshader_init(object, device, byte_code, output_signature, parent, parent_ops, max_version);
2324     if (FAILED(hr))
2325     {
2326         WARN("Failed to initialize vertex shader, hr %#x.\n", hr);
2327         HeapFree(GetProcessHeap(), 0, object);
2328         return hr;
2329     }
2330
2331     TRACE("Created vertex shader %p.\n", object);
2332     *shader = object;
2333
2334     return WINED3D_OK;
2335 }