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