ReactOS 0.4.17-dev-966-gf06eace
preshader.c
Go to the documentation of this file.
1/*
2 * Copyright 2016 Paul Gofman
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19
20#include "d3dx9_private.h"
21
22#include <float.h>
23#include <math.h>
24#include <assert.h>
25
27
29{
55};
56
57typedef double (*pres_op_func)(double *args, int n);
58
59static double to_signed_nan(double v)
60{
61 static const union
62 {
63 ULONG64 ulong64_value;
64 double double_value;
65 }
66 signed_nan =
67 {
68 0xfff8000000000000
69 };
70
71 return isnan(v) ? signed_nan.double_value : v;
72}
73
74static double pres_mov(double *args, int n) {return args[0];}
75static double pres_add(double *args, int n) {return args[0] + args[1];}
76static double pres_mul(double *args, int n) {return args[0] * args[1];}
77static double pres_dot(double *args, int n)
78{
79 int i;
80 double sum;
81
82 sum = 0.0;
83 for (i = 0; i < n; ++i)
84 sum += args[i] * args[i + n];
85 return sum;
86}
87
88static double pres_dotswiz6(double *args, int n)
89{
90 return pres_dot(args, 3);
91}
92
93static double pres_dotswiz8(double *args, int n)
94{
95 return pres_dot(args, 4);
96}
97
98static double pres_neg(double *args, int n) {return -args[0];}
99static double pres_rcp(double *args, int n) {return 1.0 / args[0];}
100static double pres_lt(double *args, int n) {return args[0] < args[1] ? 1.0 : 0.0;}
101static double pres_ge(double *args, int n) {return args[0] >= args[1] ? 1.0 : 0.0;}
102static double pres_frc(double *args, int n) {return args[0] - floor(args[0]);}
103static double pres_min(double *args, int n) {return fmin(args[0], args[1]);}
104static double pres_max(double *args, int n) {return fmax(args[0], args[1]);}
105static double pres_cmp(double *args, int n) {return args[0] >= 0.0 ? args[1] : args[2];}
106static double pres_sin(double *args, int n) {return sin(args[0]);}
107static double pres_cos(double *args, int n) {return cos(args[0]);}
108static double pres_rsq(double *args, int n)
109{
110 double v;
111
112 v = fabs(args[0]);
113 if (v == 0.0)
114 return INFINITY;
115 else
116 return 1.0 / sqrt(v);
117}
118static double pres_exp(double *args, int n) {return pow(2.0, args[0]);}
119static double pres_log(double *args, int n)
120{
121 double v;
122
123 v = fabs(args[0]);
124 if (v == 0.0)
125 return 0.0;
126 else
127 return log2(v);
128}
129static double pres_asin(double *args, int n) {return to_signed_nan(asin(args[0]));}
130static double pres_acos(double *args, int n) {return to_signed_nan(acos(args[0]));}
131static double pres_atan(double *args, int n) {return atan(args[0]);}
132static double pres_atan2(double *args, int n) {return atan2(args[0], args[1]);}
133
134/* According to the test results 'div' operation always returns 0. Compiler does not seem to ever
135 * generate it, using rcp + mul instead, so probably it is not implemented in native d3dx. */
136static double pres_div(double *args, int n) {return 0.0;}
137
138#define PRES_OPCODE_MASK 0x7ff00000
139#define PRES_OPCODE_SHIFT 20
140#define PRES_SCALAR_FLAG 0x80000000
141#define PRES_NCOMP_MASK 0x0000ffff
142
143#define FOURCC_PRES 0x53455250
144#define FOURCC_CLIT 0x54494c43
145#define FOURCC_FXLC 0x434c5846
146#define FOURCC_PRSI 0x49535250
147#define PRES_SIGN 0x46580000
148
150{
151 unsigned int opcode;
152 char mnem[16];
153 unsigned int input_count;
156};
157
158static const struct op_info pres_op_info[] =
159{
160 {0x000, "nop", 0, 0, NULL }, /* PRESHADER_OP_NOP */
161 {0x100, "mov", 1, 0, pres_mov}, /* PRESHADER_OP_MOV */
162 {0x101, "neg", 1, 0, pres_neg}, /* PRESHADER_OP_NEG */
163 {0x103, "rcp", 1, 0, pres_rcp}, /* PRESHADER_OP_RCP */
164 {0x104, "frc", 1, 0, pres_frc}, /* PRESHADER_OP_FRC */
165 {0x105, "exp", 1, 0, pres_exp}, /* PRESHADER_OP_EXP */
166 {0x106, "log", 1, 0, pres_log}, /* PRESHADER_OP_LOG */
167 {0x107, "rsq", 1, 0, pres_rsq}, /* PRESHADER_OP_RSQ */
168 {0x108, "sin", 1, 0, pres_sin}, /* PRESHADER_OP_SIN */
169 {0x109, "cos", 1, 0, pres_cos}, /* PRESHADER_OP_COS */
170 {0x10a, "asin", 1, 0, pres_asin}, /* PRESHADER_OP_ASIN */
171 {0x10b, "acos", 1, 0, pres_acos}, /* PRESHADER_OP_ACOS */
172 {0x10c, "atan", 1, 0, pres_atan}, /* PRESHADER_OP_ATAN */
173 {0x200, "min", 2, 0, pres_min}, /* PRESHADER_OP_MIN */
174 {0x201, "max", 2, 0, pres_max}, /* PRESHADER_OP_MAX */
175 {0x202, "lt", 2, 0, pres_lt }, /* PRESHADER_OP_LT */
176 {0x203, "ge", 2, 0, pres_ge }, /* PRESHADER_OP_GE */
177 {0x204, "add", 2, 0, pres_add}, /* PRESHADER_OP_ADD */
178 {0x205, "mul", 2, 0, pres_mul}, /* PRESHADER_OP_MUL */
179 {0x206, "atan2", 2, 0, pres_atan2}, /* PRESHADER_OP_ATAN2 */
180 {0x208, "div", 2, 0, pres_div}, /* PRESHADER_OP_DIV */
181 {0x300, "cmp", 3, 0, pres_cmp}, /* PRESHADER_OP_CMP */
182 {0x500, "dot", 2, 1, pres_dot}, /* PRESHADER_OP_DOT */
183 {0x70e, "d3ds_dotswiz", 6, 0, pres_dotswiz6}, /* PRESHADER_OP_DOTSWIZ6 */
184 {0x70e, "d3ds_dotswiz", 8, 0, pres_dotswiz8}, /* PRESHADER_OP_DOTSWIZ8 */
185};
186
188{
195
196static const struct
197{
198 unsigned int component_size;
200}
201table_info[] =
202{
203 {sizeof(double), PRES_VT_DOUBLE}, /* PRES_REGTAB_IMMED */
204 {sizeof(float), PRES_VT_FLOAT }, /* PRES_REGTAB_CONST */
205 {sizeof(float), PRES_VT_FLOAT }, /* PRES_REGTAB_INPUT */
206 {sizeof(float), PRES_VT_FLOAT }, /* PRES_REGTAB_OCONST */
207 {sizeof(BOOL), PRES_VT_BOOL }, /* PRES_REGTAB_OBCONST */
208 {sizeof(int), PRES_VT_INT, }, /* PRES_REGTAB_OICONST */
209 /* TODO: use double precision for 64 bit */
210 {sizeof(float), PRES_VT_FLOAT } /* PRES_REGTAB_TEMP */
212
213static const char *table_symbol[] =
214{
215 "imm", "c", "v", "oc", "ob", "oi", "r", "(null)",
216};
217
219{
220 PRES_REGTAB_OBCONST, /* D3DXRS_BOOL */
221 PRES_REGTAB_OICONST, /* D3DXRS_INT4 */
222 PRES_REGTAB_CONST, /* D3DXRS_FLOAT4 */
223 PRES_REGTAB_COUNT, /* D3DXRS_SAMPLER */
224};
225
227{
228 PRES_REGTAB_OBCONST, /* D3DXRS_BOOL */
229 PRES_REGTAB_OICONST, /* D3DXRS_INT4 */
230 PRES_REGTAB_OCONST, /* D3DXRS_FLOAT4 */
231 PRES_REGTAB_COUNT, /* D3DXRS_SAMPLER */
232};
233
235{
237 /* offset is component index, not register index, e. g.
238 offset for component c3.y is 13 (3 * 4 + 1) */
239 unsigned int offset;
240};
241
243{
246};
247
248#define MAX_INPUTS_COUNT 8
249
251{
253 /* first input argument is scalar,
254 scalar component is propagated */
256 unsigned int component_count;
259};
260
262{
264 unsigned int major, minor;
265 unsigned int major_stride;
266 unsigned int major_count;
267 unsigned int count;
268 unsigned int minor_remainder;
269};
270
272{
273 switch (type)
274 {
275 case D3DXPT_FLOAT:
276 return PRES_VT_FLOAT;
277 case D3DXPT_INT:
278 return PRES_VT_INT;
279 case D3DXPT_BOOL:
280 return PRES_VT_BOOL;
281 default:
282 FIXME("Unsupported type %u.\n", type);
283 return PRES_VT_COUNT;
284 }
285}
286
287static unsigned int get_reg_offset(unsigned int table, unsigned int offset)
288{
289 return table == PRES_REGTAB_OBCONST ? offset : offset >> 2;
290}
291
292static unsigned int get_offset_reg(unsigned int table, unsigned int reg_idx)
293{
294 return table == PRES_REGTAB_OBCONST ? reg_idx : reg_idx << 2;
295}
296
297static unsigned int get_reg_components(unsigned int table)
298{
299 return get_offset_reg(table, 1);
300}
301
302#define PRES_BITMASK_BLOCK_SIZE (sizeof(unsigned int) * 8)
303
304static HRESULT regstore_alloc_table(struct d3dx_regstore *rs, unsigned int table)
305{
306 unsigned int size;
307
308 size = get_offset_reg(table, rs->table_sizes[table]) * table_info[table].component_size;
309 if (size)
310 {
311 rs->tables[table] = calloc(1, size);
312 if (!rs->tables[table])
313 return E_OUTOFMEMORY;
314 }
315 return D3D_OK;
316}
317
318static void regstore_free_tables(struct d3dx_regstore *rs)
319{
320 unsigned int i;
321
322 for (i = 0; i < PRES_REGTAB_COUNT; ++i)
323 {
324 free(rs->tables[i]);
325 }
326}
327
328static void regstore_set_values(struct d3dx_regstore *rs, unsigned int table, const void *data,
329 unsigned int start_offset, unsigned int count)
330{
331 BYTE *dst = rs->tables[table];
332 const BYTE *src = data;
333 unsigned int size;
334
335 dst += start_offset * table_info[table].component_size;
336 size = count * table_info[table].component_size;
337 assert((src < dst && size <= dst - src) || (src > dst && size <= src - dst));
338 memcpy(dst, src, size);
339}
340
341static double regstore_get_double(struct d3dx_regstore *rs, unsigned int table, unsigned int offset)
342{
343 BYTE *p;
344
345 p = (BYTE *)rs->tables[table] + table_info[table].component_size * offset;
347 {
348 case PRES_VT_FLOAT:
349 return *(float *)p;
350 case PRES_VT_DOUBLE:
351 return *(double *)p;
352 default:
353 FIXME("Unexpected preshader input from table %u.\n", table);
354 return NAN;
355 }
356}
357
358static void regstore_set_double(struct d3dx_regstore *rs, unsigned int table, unsigned int offset, double v)
359{
360 BYTE *p;
361
362 p = (BYTE *)rs->tables[table] + table_info[table].component_size * offset;
364 {
365 case PRES_VT_FLOAT : *(float *)p = v; break;
366 case PRES_VT_DOUBLE: *(double *)p = v; break;
367 case PRES_VT_INT : *(int *)p = lrint(v); break;
368 case PRES_VT_BOOL : *(BOOL *)p = !!v; break;
369 default:
370 FIXME("Bad type %u.\n", table_info[table].type);
371 break;
372 }
373}
374
375static void dump_bytecode(void *data, unsigned int size)
376{
377 unsigned int *bytecode = (unsigned int *)data;
378 unsigned int i, j, n;
379
380 size /= sizeof(*bytecode);
381 i = 0;
382 while (i < size)
383 {
384 n = min(size - i, 8);
385 for (j = 0; j < n; ++j)
386 TRACE("0x%08x,", bytecode[i + j]);
387 i += n;
388 TRACE("\n");
389 }
390}
391
392static unsigned int *find_bytecode_comment(unsigned int *ptr, unsigned int count,
393 unsigned int fourcc, unsigned int *size)
394{
395 /* Provide at least one value in comment section on non-NULL return. */
396 while (count > 2 && (*ptr & 0xffff) == 0xfffe)
397 {
398 unsigned int section_size;
399
400 section_size = (*ptr >> 16);
401 if (!section_size || section_size + 1 > count)
402 break;
403 if (*(ptr + 1) == fourcc)
404 {
405 *size = section_size;
406 return ptr + 2;
407 }
408 count -= section_size + 1;
409 ptr += section_size + 1;
410 }
411 return NULL;
412}
413
414static unsigned int *parse_pres_reg(unsigned int *ptr, struct d3dx_pres_reg *reg)
415{
416 static const enum pres_reg_tables reg_table[8] =
417 {
420 };
421
422 if (*ptr >= ARRAY_SIZE(reg_table) || reg_table[*ptr] == PRES_REGTAB_COUNT)
423 {
424 FIXME("Unsupported register table %#x.\n", *ptr);
425 return NULL;
426 }
427
428 reg->table = reg_table[*ptr++];
429 reg->offset = *ptr++;
430 return ptr;
431}
432
433static unsigned int *parse_pres_arg(unsigned int *ptr, unsigned int count, struct d3dx_pres_operand *opr)
434{
435 if (count < 3 || (*ptr && count < 5))
436 {
437 WARN("Byte code buffer ends unexpectedly, count %u.\n", count);
438 return NULL;
439 }
440
441 if (*ptr)
442 {
443 if (*ptr != 1)
444 {
445 FIXME("Unknown relative addressing flag, word %#x.\n", *ptr);
446 return NULL;
447 }
448 ptr = parse_pres_reg(ptr + 1, &opr->index_reg);
449 if (!ptr)
450 return NULL;
451 }
452 else
453 {
454 opr->index_reg.table = PRES_REGTAB_COUNT;
455 ++ptr;
456 }
457
458 ptr = parse_pres_reg(ptr, &opr->reg);
459
460 if (opr->reg.table == PRES_REGTAB_OBCONST)
461 opr->reg.offset /= 4;
462 return ptr;
463}
464
465static unsigned int *parse_pres_ins(unsigned int *ptr, unsigned int count, struct d3dx_pres_ins *ins)
466{
467 unsigned int ins_code, ins_raw;
468 unsigned int input_count;
469 unsigned int i;
470
471 if (count < 2)
472 {
473 WARN("Byte code buffer ends unexpectedly.\n");
474 return NULL;
475 }
476
477 ins_raw = *ptr++;
478 ins_code = (ins_raw & PRES_OPCODE_MASK) >> PRES_OPCODE_SHIFT;
479 ins->component_count = ins_raw & PRES_NCOMP_MASK;
480 ins->scalar_op = !!(ins_raw & PRES_SCALAR_FLAG);
481
482 if (ins->component_count < 1 || ins->component_count > 4)
483 {
484 FIXME("Unsupported number of components %u.\n", ins->component_count);
485 return NULL;
486 }
487 input_count = *ptr++;
488 count -= 2;
489 for (i = 0; i < ARRAY_SIZE(pres_op_info); ++i)
490 if (ins_code == pres_op_info[i].opcode && input_count == pres_op_info[i].input_count)
491 break;
492 if (i == ARRAY_SIZE(pres_op_info))
493 {
494 FIXME("Unknown opcode %#x, input_count %u, raw %#x.\n", ins_code, input_count, ins_raw);
495 return NULL;
496 }
497 ins->op = i;
498 if (input_count > ARRAY_SIZE(ins->inputs))
499 {
500 FIXME("Actual input args count %u exceeds inputs array size, instruction %s.\n", input_count,
501 pres_op_info[i].mnem);
502 return NULL;
503 }
504 for (i = 0; i < input_count; ++i)
505 {
506 unsigned int *p;
507
508 p = parse_pres_arg(ptr, count, &ins->inputs[i]);
509 if (!p)
510 return NULL;
511 count -= p - ptr;
512 ptr = p;
513 }
514 ptr = parse_pres_arg(ptr, count, &ins->output);
515 if (ins->output.index_reg.table != PRES_REGTAB_COUNT)
516 {
517 FIXME("Relative addressing in output register not supported.\n");
518 return NULL;
519 }
520 if (get_reg_offset(ins->output.reg.table, ins->output.reg.offset
521 + (pres_op_info[ins->op].func_all_comps ? 0 : ins->component_count - 1))
522 != get_reg_offset(ins->output.reg.table, ins->output.reg.offset))
523 {
524 FIXME("Instructions outputting multiple registers are not supported.\n");
525 return NULL;
526 }
527 return ptr;
528}
529
530static HRESULT get_ctab_constant_desc(ID3DXConstantTable *ctab, D3DXHANDLE hc, D3DXCONSTANT_DESC *desc,
531 WORD *constantinfo_reserved)
532{
533 const struct ctab_constant *constant = d3dx_shader_get_ctab_constant(ctab, hc);
534
535 if (!constant)
536 {
537 FIXME("Could not get constant desc.\n");
540 return D3DERR_INVALIDCALL;
541 }
542 *desc = constant->desc;
544 *constantinfo_reserved = constant->constantinfo_reserved;
545 return D3D_OK;
546}
547
549 struct const_upload_info *info)
550{
551 struct d3dx_parameter *param = const_set->param;
552 unsigned int table = const_set->table;
553
554 info->transpose = (const_set->constant_class == D3DXPC_MATRIX_COLUMNS && param->class == D3DXPC_MATRIX_ROWS)
555 || (param->class == D3DXPC_MATRIX_COLUMNS && const_set->constant_class == D3DXPC_MATRIX_ROWS);
556 if (const_set->constant_class == D3DXPC_MATRIX_COLUMNS)
557 {
558 info->major = param->columns;
559 info->minor = param->rows;
560 }
561 else
562 {
563 info->major = param->rows;
564 info->minor = param->columns;
565 }
566
567 if (get_reg_components(table) == 1)
568 {
569 unsigned int const_length = get_offset_reg(table, const_set->register_count);
570
571 info->major_stride = info->minor;
572 info->major_count = const_length / info->major_stride;
573 info->minor_remainder = const_length % info->major_stride;
574 }
575 else
576 {
577 info->major_stride = get_reg_components(table);
578 info->major_count = const_set->register_count;
579 info->minor_remainder = 0;
580 }
581 info->count = info->major_count * info->minor + info->minor_remainder;
582}
583
584#define INITIAL_CONST_SET_SIZE 16
585
587{
588 if (const_tab->const_set_count >= const_tab->const_set_size)
589 {
590 unsigned int new_size;
591 struct d3dx_const_param_eval_output *new_alloc;
592
593 if (!const_tab->const_set_size)
594 {
596 new_alloc = malloc(sizeof(*const_tab->const_set) * new_size);
597 if (!new_alloc)
598 {
599 ERR("Out of memory.\n");
600 return E_OUTOFMEMORY;
601 }
602 }
603 else
604 {
605 new_size = const_tab->const_set_size * 2;
606 new_alloc = realloc(const_tab->const_set, sizeof(*const_tab->const_set) * new_size);
607 if (!new_alloc)
608 {
609 ERR("Out of memory.\n");
610 return E_OUTOFMEMORY;
611 }
612 }
613 const_tab->const_set = new_alloc;
614 const_tab->const_set_size = new_size;
615 }
616 const_tab->const_set[const_tab->const_set_count++] = *set;
617 return D3D_OK;
618}
619
621 struct d3dx_preshader *pres)
622{
623 unsigned int i;
624 struct d3dx_const_param_eval_output const_set = {NULL};
625
626 for (i = 0; i < pres->ins_count; ++i)
627 {
628 const struct d3dx_pres_ins *ins = &pres->ins[i];
629 const struct d3dx_pres_reg *reg = &ins->output.reg;
630
631 if (reg->table == PRES_REGTAB_TEMP)
632 continue;
633
634 const_set.register_index = get_reg_offset(reg->table, reg->offset);
635 const_set.register_count = 1;
636 const_set.table = reg->table;
638 const_set.element_count = 1;
639 append_const_set(const_tab, &const_set);
640 }
641}
642
643static int __cdecl compare_const_set(const void *a, const void *b)
644{
645 const struct d3dx_const_param_eval_output *r1 = a;
646 const struct d3dx_const_param_eval_output *r2 = b;
647
648 if (r1->table != r2->table)
649 return r1->table - r2->table;
650 return r1->register_index - r2->register_index;
651}
652
654 struct d3dx_parameter *param, unsigned int index)
655{
656 unsigned int i, start_index = index;
657 DWORD *current_data;
658 enum pres_reg_tables current_table;
659 unsigned int current_start_offset, element_count;
660 struct d3dx_const_param_eval_output *first_const;
661
662 if (!const_tab->const_set_count)
663 return D3D_OK;
664
665 while (index < const_tab->const_set_count - 1)
666 {
667 first_const = &const_tab->const_set[index];
668 current_data = first_const->param->data;
669 current_table = first_const->table;
670 current_start_offset = get_offset_reg(current_table, first_const->register_index);
671 element_count = 0;
672 for (i = index; i < const_tab->const_set_count; ++i)
673 {
674 struct d3dx_const_param_eval_output *const_set = &const_tab->const_set[i];
675 unsigned int count = get_offset_reg(const_set->table,
676 const_set->register_count * const_set->element_count);
677 unsigned int start_offset = get_offset_reg(const_set->table, const_set->register_index);
678
679 if (!(const_set->table == current_table && current_start_offset == start_offset
680 && const_set->direct_copy == first_const->direct_copy
681 && current_data == const_set->param->data
682 && (const_set->direct_copy || (first_const->param->type == const_set->param->type
683 && first_const->param->class == const_set->param->class
684 && first_const->param->columns == const_set->param->columns
685 && first_const->param->rows == const_set->param->rows
686 && first_const->register_count == const_set->register_count
687 && (i == const_tab->const_set_count - 1
688 || first_const->param->element_count == const_set->param->element_count)))))
689 break;
690
691 current_start_offset += count;
692 current_data += const_set->direct_copy ? count : const_set->param->rows
693 * const_set->param->columns * const_set->element_count;
694 element_count += const_set->element_count;
695 }
696
697 if (i > index + 1)
698 {
699 TRACE("Merging %u child parameters for %s, not merging %u, direct_copy %#x.\n", i - index,
700 debugstr_a(param->name), const_tab->const_set_count - i, first_const->direct_copy);
701
702 first_const->element_count = element_count;
703 if (first_const->direct_copy)
704 {
705 first_const->element_count = 1;
706 if (index == start_index
707 && !(param->type == D3DXPT_VOID && param->class == D3DXPC_STRUCT))
708 {
710 return D3DERR_INVALIDCALL;
711 first_const->param = param;
712 }
713 first_const->register_count = get_reg_offset(current_table, current_start_offset)
714 - first_const->register_index;
715 }
716 memmove(&const_tab->const_set[index + 1], &const_tab->const_set[i],
717 sizeof(*const_tab->const_set) * (const_tab->const_set_count - i));
718 const_tab->const_set_count -= i - index - 1;
719 }
720 else
721 {
722 TRACE("Not merging %u child parameters for %s, direct_copy %#x.\n",
723 const_tab->const_set_count - i, debugstr_a(param->name), first_const->direct_copy);
724 }
725 index = i;
726 }
727 return D3D_OK;
728}
729
730static HRESULT init_set_constants_param(struct d3dx_const_tab *const_tab, ID3DXConstantTable *ctab,
731 D3DXHANDLE hc, struct d3dx_parameter *param)
732{
734 unsigned int const_count, param_count, i;
736 struct d3dx_const_param_eval_output const_set;
737 struct const_upload_info info;
738 enum pres_value_type table_type;
739 HRESULT hr;
740
741 if (FAILED(get_ctab_constant_desc(ctab, hc, &desc, NULL)))
742 return D3DERR_INVALIDCALL;
743
744 if (param->element_count)
745 {
746 param_count = param->element_count;
747 const_count = desc.Elements;
749 }
750 else
751 {
752 if (desc.Elements > 1)
753 {
754 FIXME("Unexpected number of constant elements %u.\n", desc.Elements);
755 return D3DERR_INVALIDCALL;
756 }
757 param_count = param->member_count;
758 const_count = desc.StructMembers;
760 }
761 if (const_count != param_count)
762 {
763 FIXME("Number of elements or struct members differs between parameter (%u) and constant (%u).\n",
764 param_count, const_count);
765 return D3DERR_INVALIDCALL;
766 }
767 if (const_count)
768 {
770 D3DXHANDLE hc_element;
771 unsigned int index = const_tab->const_set_count;
772
773 for (i = 0; i < const_count; ++i)
774 {
775 if (get_element)
776 hc_element = ID3DXConstantTable_GetConstantElement(ctab, hc, i);
777 else
778 hc_element = ID3DXConstantTable_GetConstant(ctab, hc, i);
779 if (!hc_element)
780 {
781 FIXME("Could not get constant.\n");
783 }
784 else
785 {
786 hr = init_set_constants_param(const_tab, ctab, hc_element, &param->members[i]);
787 }
788 if (FAILED(hr))
789 ret = hr;
790 }
791 if (FAILED(ret))
792 return ret;
793 return merge_const_set_entries(const_tab, param, index);
794 }
795
796 TRACE("Constant %s, rows %u, columns %u, class %u, bytes %u.\n",
797 debugstr_a(desc.Name), desc.Rows, desc.Columns, desc.Class, desc.Bytes);
798 TRACE("Parameter %s, rows %u, columns %u, class %u, flags %#x, bytes %u.\n",
799 debugstr_a(param->name), param->rows, param->columns, param->class,
800 param->flags, param->bytes);
801
802 const_set.element_count = 1;
803 const_set.param = param;
804 const_set.constant_class = desc.Class;
805 if (desc.RegisterSet >= ARRAY_SIZE(shad_regset2table))
806 {
807 FIXME("Unknown register set %u.\n", desc.RegisterSet);
808 return D3DERR_INVALIDCALL;
809 }
810 const_set.register_index = desc.RegisterIndex;
811 const_set.table = const_tab->regset2table[desc.RegisterSet];
812 if (const_set.table >= PRES_REGTAB_COUNT)
813 {
814 ERR("Unexpected register set %u.\n", desc.RegisterSet);
815 return D3DERR_INVALIDCALL;
816 }
817 assert(table_info[const_set.table].component_size == sizeof(unsigned int));
818 assert(param->bytes / (param->rows * param->columns) == sizeof(unsigned int));
819 const_set.register_count = desc.RegisterCount;
820 table_type = table_info[const_set.table].type;
821 get_const_upload_info(&const_set, &info);
822 if (!info.count)
823 {
824 TRACE("%s has zero count, skipping.\n", debugstr_a(param->name));
825 return D3D_OK;
826 }
827
829 return D3DERR_INVALIDCALL;
830
831 const_set.direct_copy = table_type_from_param_type(param->type) == table_type
832 && !info.transpose && info.minor == info.major_stride
833 && info.count == get_offset_reg(const_set.table, const_set.register_count)
834 && info.count * sizeof(unsigned int) <= param->bytes;
835 if (info.minor_remainder && !const_set.direct_copy && !info.transpose)
836 FIXME("Incomplete last row for not transposed matrix which cannot be directly copied, parameter %s.\n",
837 debugstr_a(param->name));
838
839 if (info.major_count > info.major
840 || (info.major_count == info.major && info.minor_remainder))
841 {
842 WARN("Constant dimensions exceed parameter size.\n");
843 return D3DERR_INVALIDCALL;
844 }
845
846 if (FAILED(hr = append_const_set(const_tab, &const_set)))
847 return hr;
848
849 return D3D_OK;
850}
851
852static HRESULT get_constants_desc(unsigned int *byte_code, struct d3dx_const_tab *out,
853 struct d3dx_parameters_store *parameters, const char **skip_constants,
854 unsigned int skip_constants_count, struct d3dx_preshader *pres)
855{
856 ID3DXConstantTable *ctab;
857 D3DXCONSTANT_DESC *cdesc;
858 struct d3dx_parameter **inputs_param;
860 HRESULT hr;
861 D3DXHANDLE hc;
862 unsigned int i, j;
863
864 hr = D3DXGetShaderConstantTable((DWORD *)byte_code, &ctab);
865 if (FAILED(hr) || !ctab)
866 {
867 TRACE("Could not get CTAB data, hr %#lx.\n", hr);
868 /* returning OK, shaders and preshaders without CTAB are valid */
869 return D3D_OK;
870 }
872 {
873 FIXME("Could not get CTAB desc, hr %#lx.\n", hr);
874 goto cleanup;
875 }
876
877 out->inputs = cdesc = malloc(sizeof(*cdesc) * desc.Constants);
878 out->inputs_param = inputs_param = malloc(sizeof(*inputs_param) * desc.Constants);
879 if (!cdesc || !inputs_param)
880 {
882 goto cleanup;
883 }
884
885 for (i = 0; i < desc.Constants; ++i)
886 {
887 unsigned int index = out->input_count;
888 WORD constantinfo_reserved;
889
891 if (!hc)
892 {
893 FIXME("Null constant handle.\n");
894 goto cleanup;
895 }
896 if (FAILED(hr = get_ctab_constant_desc(ctab, hc, &cdesc[index], &constantinfo_reserved)))
897 goto cleanup;
898 inputs_param[index] = get_parameter_by_name(parameters, NULL, cdesc[index].Name);
899 if (!inputs_param[index])
900 {
901 WARN("Could not find parameter %s in effect.\n", cdesc[index].Name);
902 continue;
903 }
904 if (cdesc[index].Class == D3DXPC_OBJECT)
905 {
906 TRACE("Object %s, parameter %p.\n", cdesc[index].Name, inputs_param[index]);
907 if (cdesc[index].RegisterSet != D3DXRS_SAMPLER || inputs_param[index]->class != D3DXPC_OBJECT
908 || !is_param_type_sampler(inputs_param[index]->type))
909 {
910 WARN("Unexpected object type, constant %s.\n", debugstr_a(cdesc[index].Name));
912 goto cleanup;
913 }
914 if (max(inputs_param[index]->element_count, 1) < cdesc[index].RegisterCount)
915 {
916 WARN("Register count exceeds parameter size, constant %s.\n", debugstr_a(cdesc[index].Name));
918 goto cleanup;
919 }
920 }
921 if (!is_top_level_parameter(inputs_param[index]))
922 {
923 WARN("Expected top level parameter '%s'.\n", debugstr_a(cdesc[index].Name));
924 hr = E_FAIL;
925 goto cleanup;
926 }
927
928 for (j = 0; j < skip_constants_count; ++j)
929 {
930 if (!strcmp(cdesc[index].Name, skip_constants[j]))
931 {
932 if (!constantinfo_reserved)
933 {
934 WARN("skip_constants parameter %s is not register bound.\n",
935 cdesc[index].Name);
937 goto cleanup;
938 }
939 TRACE("Skipping constant %s.\n", cdesc[index].Name);
940 break;
941 }
942 }
943 if (j < skip_constants_count)
944 continue;
945 ++out->input_count;
946 if (inputs_param[index]->class == D3DXPC_OBJECT)
947 continue;
948 if (FAILED(hr = init_set_constants_param(out, ctab, hc, inputs_param[index])))
949 goto cleanup;
950 }
951 if (pres)
953 if (out->const_set_count)
954 {
955 struct d3dx_const_param_eval_output *new_alloc;
956
957 qsort(out->const_set, out->const_set_count, sizeof(*out->const_set), compare_const_set);
958
959 i = 0;
960 while (i < out->const_set_count - 1)
961 {
962 if (out->const_set[i].constant_class == D3DXPC_FORCE_DWORD
963 && out->const_set[i + 1].constant_class == D3DXPC_FORCE_DWORD
964 && out->const_set[i].table == out->const_set[i + 1].table
965 && out->const_set[i].register_index + out->const_set[i].register_count
966 >= out->const_set[i + 1].register_index)
967 {
968 assert(out->const_set[i].register_index + out->const_set[i].register_count
969 <= out->const_set[i + 1].register_index + 1);
970 out->const_set[i].register_count = out->const_set[i + 1].register_index + 1
971 - out->const_set[i].register_index;
972 memmove(&out->const_set[i + 1], &out->const_set[i + 2], sizeof(out->const_set[i])
973 * (out->const_set_count - i - 2));
974 --out->const_set_count;
975 }
976 else
977 {
978 ++i;
979 }
980 }
981
982 new_alloc = realloc(out->const_set, sizeof(*out->const_set) * out->const_set_count);
983 if (new_alloc)
984 {
985 out->const_set = new_alloc;
986 out->const_set_size = out->const_set_count;
987 }
988 else
989 {
990 WARN("Out of memory.\n");
991 }
992 }
993cleanup:
995 return hr;
996}
997
998static void update_table_size(unsigned int *table_sizes, unsigned int table, unsigned int max_register)
999{
1001 table_sizes[table] = max(table_sizes[table], max_register + 1);
1002}
1003
1004static void update_table_sizes_consts(unsigned int *table_sizes, struct d3dx_const_tab *ctab)
1005{
1006 unsigned int i, table, max_register;
1007
1008 for (i = 0; i < ctab->input_count; ++i)
1009 {
1010 if (!ctab->inputs[i].RegisterCount)
1011 continue;
1012 max_register = ctab->inputs[i].RegisterIndex + ctab->inputs[i].RegisterCount - 1;
1013 table = ctab->regset2table[ctab->inputs[i].RegisterSet];
1014 update_table_size(table_sizes, table, max_register);
1015 }
1016}
1017
1018static void dump_arg(struct d3dx_regstore *rs, const struct d3dx_pres_operand *arg, int component_count)
1019{
1020 static const char *xyzw_str = "xyzw";
1021 unsigned int i, table, reg_offset;
1022
1023 table = arg->reg.table;
1024 if (table == PRES_REGTAB_IMMED && arg->index_reg.table == PRES_REGTAB_COUNT)
1025 {
1026 TRACE("(");
1027 for (i = 0; i < component_count; ++i)
1028 TRACE(i < component_count - 1 ? "%.16e, " : "%.16e",
1029 ((double *)rs->tables[PRES_REGTAB_IMMED])[arg->reg.offset + i]);
1030 TRACE(")");
1031 }
1032 else
1033 {
1034 reg_offset = get_reg_offset(table, arg->reg.offset);
1035
1036 if (arg->index_reg.table == PRES_REGTAB_COUNT)
1037 {
1038 if (table == PRES_REGTAB_INPUT && reg_offset < 2)
1039 TRACE("%s%s.", table_symbol[table], reg_offset ? "PSize" : "Pos");
1040 else
1041 TRACE("%s%u.", table_symbol[table], reg_offset);
1042 }
1043 else
1044 {
1045 unsigned int index_reg;
1046
1047 index_reg = get_reg_offset(arg->index_reg.table, arg->index_reg.offset);
1048 TRACE("%s[%u + %s%u.%c].", table_symbol[table], reg_offset,
1049 table_symbol[arg->index_reg.table], index_reg,
1050 xyzw_str[arg->index_reg.offset - get_offset_reg(arg->index_reg.table, index_reg)]);
1051 }
1052 for (i = 0; i < component_count; ++i)
1053 TRACE("%c", xyzw_str[(arg->reg.offset + i) % 4]);
1054 }
1055}
1056
1057static void dump_registers(struct d3dx_const_tab *ctab)
1058{
1059 unsigned int table, i;
1060
1061 for (i = 0; i < ctab->input_count; ++i)
1062 {
1063 table = ctab->regset2table[ctab->inputs[i].RegisterSet];
1064 TRACE("// %-12s %s%-4u %u\n", ctab->inputs_param[i] ? ctab->inputs_param[i]->name : "(nil)",
1066 }
1067}
1068
1069static void dump_ins(struct d3dx_regstore *rs, const struct d3dx_pres_ins *ins)
1070{
1071 unsigned int i;
1072
1073 TRACE("%s ", pres_op_info[ins->op].mnem);
1074 dump_arg(rs, &ins->output, pres_op_info[ins->op].func_all_comps ? 1 : ins->component_count);
1075 for (i = 0; i < pres_op_info[ins->op].input_count; ++i)
1076 {
1077 TRACE(", ");
1078 dump_arg(rs, &ins->inputs[i], ins->scalar_op && !i ? 1 : ins->component_count);
1079 }
1080 TRACE("\n");
1081}
1082
1083static void dump_preshader(struct d3dx_preshader *pres)
1084{
1085 unsigned int i, immediate_count = pres->regs.table_sizes[PRES_REGTAB_IMMED] * 4;
1086 const double *immediates = pres->regs.tables[PRES_REGTAB_IMMED];
1087
1088 if (immediate_count)
1089 TRACE("// Immediates:\n");
1090 for (i = 0; i < immediate_count; ++i)
1091 {
1092 if (!(i % 4))
1093 TRACE("// ");
1094 TRACE("%.8e", immediates[i]);
1095 if (i % 4 == 3)
1096 TRACE("\n");
1097 else
1098 TRACE(", ");
1099 }
1100 TRACE("// Preshader registers:\n");
1101 dump_registers(&pres->inputs);
1102 TRACE("preshader\n");
1103 for (i = 0; i < pres->ins_count; ++i)
1104 dump_ins(&pres->regs, &pres->ins[i]);
1105}
1106
1107static HRESULT parse_preshader(struct d3dx_preshader *pres, unsigned int *ptr, unsigned int count,
1109{
1110 unsigned int *p;
1111 unsigned int i, j, const_count, magic;
1112 double *dconst;
1113 HRESULT hr;
1114 unsigned int saved_word;
1115 unsigned int section_size;
1116
1117 magic = *ptr;
1118
1119 TRACE("Preshader version %#x.\n", *ptr);
1120
1121 if (!count)
1122 {
1123 WARN("Unexpected end of byte code buffer.\n");
1124 return D3DXERR_INVALIDDATA;
1125 }
1126
1127 p = find_bytecode_comment(ptr + 1, count - 1, FOURCC_CLIT, &section_size);
1128 if (p)
1129 {
1130 const_count = *p++;
1131 if (const_count > (section_size - 1) / (sizeof(double) / sizeof(unsigned int)))
1132 {
1133 WARN("Byte code buffer ends unexpectedly.\n");
1134 return D3DXERR_INVALIDDATA;
1135 }
1136 dconst = (double *)p;
1137 }
1138 else
1139 {
1140 const_count = 0;
1141 dconst = NULL;
1142 }
1143 TRACE("%u double constants.\n", const_count);
1144
1145 p = find_bytecode_comment(ptr + 1, count - 1, FOURCC_FXLC, &section_size);
1146 if (!p)
1147 {
1148 WARN("Could not find preshader code.\n");
1149 return D3D_OK;
1150 }
1151 pres->ins_count = *p++;
1152 --section_size;
1153 if (pres->ins_count > UINT_MAX / sizeof(*pres->ins))
1154 {
1155 WARN("Invalid instruction count %u.\n", pres->ins_count);
1156 return D3DXERR_INVALIDDATA;
1157 }
1158 TRACE("%u instructions.\n", pres->ins_count);
1159 pres->ins = calloc(pres->ins_count, sizeof(*pres->ins));
1160 if (!pres->ins)
1161 return E_OUTOFMEMORY;
1162 for (i = 0; i < pres->ins_count; ++i)
1163 {
1164 unsigned int *ptr_next;
1165
1166 ptr_next = parse_pres_ins(p, section_size, &pres->ins[i]);
1167 if (!ptr_next)
1168 return D3DXERR_INVALIDDATA;
1169 section_size -= ptr_next - p;
1170 p = ptr_next;
1171 }
1172
1173 pres->inputs.regset2table = pres_regset2table;
1174
1175 saved_word = *ptr;
1176 *ptr = 0xfffe0000;
1178 *ptr = saved_word;
1179 if (FAILED(hr))
1180 return hr;
1181
1182 if (const_count % get_reg_components(PRES_REGTAB_IMMED))
1183 {
1184 FIXME("const_count %u is not a multiple of %u.\n", const_count,
1186 return D3DXERR_INVALIDDATA;
1187 }
1188 pres->regs.table_sizes[PRES_REGTAB_IMMED] = get_reg_offset(PRES_REGTAB_IMMED, const_count);
1189 if (magic == FOURCC_TX_1)
1190 pres->regs.table_sizes[PRES_REGTAB_INPUT] = 2;
1191
1192 update_table_sizes_consts(pres->regs.table_sizes, &pres->inputs);
1193 for (i = 0; i < pres->ins_count; ++i)
1194 {
1195 for (j = 0; j < pres_op_info[pres->ins[i].op].input_count; ++j)
1196 {
1198 unsigned int reg_idx;
1199
1200 if (pres->ins[i].inputs[j].index_reg.table == PRES_REGTAB_COUNT)
1201 {
1202 unsigned int last_component_index = pres->ins[i].scalar_op && !j ? 0
1203 : pres->ins[i].component_count - 1;
1204
1205 table = pres->ins[i].inputs[j].reg.table;
1206 reg_idx = get_reg_offset(table, pres->ins[i].inputs[j].reg.offset
1207 + last_component_index);
1208 }
1209 else
1210 {
1211 table = pres->ins[i].inputs[j].index_reg.table;
1212 reg_idx = get_reg_offset(table, pres->ins[i].inputs[j].index_reg.offset);
1213 }
1214 if (reg_idx >= pres->regs.table_sizes[table])
1215 {
1216 /* Native accepts these broken preshaders. */
1217 FIXME("Out of bounds register index, i %u, j %u, table %u, reg_idx %u, preshader parsing failed.\n",
1218 i, j, table, reg_idx);
1219 return D3DXERR_INVALIDDATA;
1220 }
1221 }
1222 update_table_size(pres->regs.table_sizes, pres->ins[i].output.reg.table,
1223 get_reg_offset(pres->ins[i].output.reg.table, pres->ins[i].output.reg.offset));
1224 }
1226 return E_OUTOFMEMORY;
1227 regstore_set_values(&pres->regs, PRES_REGTAB_IMMED, dconst, 0, const_count);
1228
1229 return D3D_OK;
1230}
1231
1232HRESULT d3dx_create_param_eval(struct d3dx_parameters_store *parameters, void *byte_code, unsigned int byte_code_size,
1233 D3DXPARAMETER_TYPE type, struct d3dx_param_eval **peval_out, ULONG64 *version_counter,
1234 const char **skip_constants, unsigned int skip_constants_count)
1235{
1236 struct d3dx_param_eval *peval;
1237 unsigned int *ptr, *shader_ptr = NULL;
1238 unsigned int i;
1239 BOOL shader;
1240 unsigned int count, pres_size;
1241 HRESULT ret;
1242
1243 TRACE("parameters %p, byte_code %p, byte_code_size %u, type %u, peval_out %p.\n",
1244 parameters, byte_code, byte_code_size, type, peval_out);
1245
1246 count = byte_code_size / sizeof(unsigned int);
1247 if (!byte_code || !count)
1248 {
1249 *peval_out = NULL;
1250 return D3D_OK;
1251 }
1252
1253 peval = calloc(1, sizeof(*peval));
1254 if (!peval)
1255 {
1257 goto err_out;
1258 }
1260
1261 peval->param_type = type;
1262 switch (type)
1263 {
1265 case D3DXPT_PIXELSHADER:
1266 shader = TRUE;
1267 break;
1268 default:
1269 shader = FALSE;
1270 break;
1271 }
1272 peval->shader_inputs.regset2table = shad_regset2table;
1273
1274 ptr = (unsigned int *)byte_code;
1275 if (shader)
1276 {
1277 if ((*ptr & 0xfffe0000) != 0xfffe0000)
1278 {
1279 FIXME("Invalid shader signature %#x.\n", *ptr);
1281 goto err_out;
1282 }
1283 TRACE("Shader version %#x.\n", *ptr & 0xffff);
1284 shader_ptr = ptr;
1285 ptr = find_bytecode_comment(ptr + 1, count - 1, FOURCC_PRES, &pres_size);
1286 if (!ptr)
1287 TRACE("No preshader found.\n");
1288 }
1289 else
1290 {
1291 pres_size = count;
1292 }
1293
1294 if (ptr && FAILED(ret = parse_preshader(&peval->pres, ptr, pres_size, parameters)))
1295 {
1296 FIXME("Failed parsing preshader, byte code for analysis follows.\n");
1297 dump_bytecode(byte_code, byte_code_size);
1298 goto err_out;
1299 }
1300
1301 if (shader)
1302 {
1303 if (FAILED(ret = get_constants_desc(shader_ptr, &peval->shader_inputs, parameters,
1304 skip_constants, skip_constants_count, &peval->pres)))
1305 {
1306 TRACE("Could not get shader constant table, hr %#lx.\n", ret);
1307 goto err_out;
1308 }
1309 update_table_sizes_consts(peval->pres.regs.table_sizes, &peval->shader_inputs);
1310 }
1311
1313 {
1314 if (FAILED(ret = regstore_alloc_table(&peval->pres.regs, i)))
1315 goto err_out;
1316 }
1317
1318 if (TRACE_ON(d3dx))
1319 {
1320 dump_bytecode(byte_code, byte_code_size);
1321 dump_preshader(&peval->pres);
1322 if (shader)
1323 {
1324 TRACE("// Shader registers:\n");
1326 }
1327 }
1328 *peval_out = peval;
1329 TRACE("Created parameter evaluator %p.\n", *peval_out);
1330 return D3D_OK;
1331
1332err_out:
1333 WARN("Error creating parameter evaluator.\n");
1334 if (TRACE_ON(d3dx))
1335 dump_bytecode(byte_code, byte_code_size);
1336
1337 d3dx_free_param_eval(peval);
1338 *peval_out = NULL;
1339 return ret;
1340}
1341
1342static void d3dx_free_const_tab(struct d3dx_const_tab *ctab)
1343{
1344 free(ctab->inputs);
1345 free(ctab->inputs_param);
1346 free(ctab->const_set);
1347}
1348
1350{
1351 free(pres->ins);
1352
1353 regstore_free_tables(&pres->regs);
1354 d3dx_free_const_tab(&pres->inputs);
1355}
1356
1358{
1359 TRACE("peval %p.\n", peval);
1360
1361 if (!peval)
1362 return;
1363
1364 d3dx_free_preshader(&peval->pres);
1366 free(peval);
1367}
1368
1369static void pres_int_from_float(void *out, const void *in, unsigned int count)
1370{
1371 unsigned int i;
1372 const float *in_float = in;
1373 int *out_int = out;
1374
1375 for (i = 0; i < count; ++i)
1376 out_int[i] = in_float[i];
1377}
1378
1379static void pres_bool_from_value(void *out, const void *in, unsigned int count)
1380{
1381 unsigned int i;
1382 const DWORD *in_dword = in;
1383 BOOL *out_bool = out;
1384
1385 for (i = 0; i < count; ++i)
1386 out_bool[i] = !!in_dword[i];
1387}
1388
1389static void pres_float_from_int(void *out, const void *in, unsigned int count)
1390{
1391 unsigned int i;
1392 const int *in_int = in;
1393 float *out_float = out;
1394
1395 for (i = 0; i < count; ++i)
1396 out_float[i] = in_int[i];
1397}
1398
1399static void pres_float_from_bool(void *out, const void *in, unsigned int count)
1400{
1401 unsigned int i;
1402 const BOOL *in_bool = in;
1403 float *out_float = out;
1404
1405 for (i = 0; i < count; ++i)
1406 out_float[i] = !!in_bool[i];
1407}
1408
1409static void pres_int_from_bool(void *out, const void *in, unsigned int count)
1410{
1411 unsigned int i;
1412 const float *in_bool = in;
1413 int *out_int = out;
1414
1415 for (i = 0; i < count; ++i)
1416 out_int[i] = !!in_bool[i];
1417}
1418
1419static void regstore_set_data(struct d3dx_regstore *rs, unsigned int table,
1420 unsigned int offset, const unsigned int *in, unsigned int count, enum pres_value_type param_type)
1421{
1422 typedef void (*conv_func)(void *out, const void *in, unsigned int count);
1423 static const conv_func set_const_funcs[PRES_VT_COUNT][PRES_VT_COUNT] =
1424 {
1426 {NULL, NULL, NULL, NULL},
1429 };
1430 enum pres_value_type table_type = table_info[table].type;
1431
1432 if (param_type == table_type)
1433 {
1435 return;
1436 }
1437
1438 set_const_funcs[param_type][table_type]((unsigned int *)rs->tables[table] + offset, in, count);
1439}
1440
1441static HRESULT set_constants_device(ID3DXEffectStateManager *manager, struct IDirect3DDevice9 *device,
1443 unsigned int start, unsigned int count)
1444{
1446 {
1447 switch(table)
1448 {
1449 case PRES_REGTAB_OCONST:
1450 return SET_D3D_STATE_(manager, device, SetVertexShaderConstantF, start, ptr, count);
1452 return SET_D3D_STATE_(manager, device, SetVertexShaderConstantI, start, ptr, count);
1454 return SET_D3D_STATE_(manager, device, SetVertexShaderConstantB, start, ptr, count);
1455 default:
1456 FIXME("Unexpected register table %u.\n", table);
1457 return D3DERR_INVALIDCALL;
1458 }
1459 }
1460 else if (type == D3DXPT_PIXELSHADER)
1461 {
1462 switch(table)
1463 {
1464 case PRES_REGTAB_OCONST:
1465 return SET_D3D_STATE_(manager, device, SetPixelShaderConstantF, start, ptr, count);
1467 return SET_D3D_STATE_(manager, device, SetPixelShaderConstantI, start, ptr, count);
1469 return SET_D3D_STATE_(manager, device, SetPixelShaderConstantB, start, ptr, count);
1470 default:
1471 FIXME("Unexpected register table %u.\n", table);
1472 return D3DERR_INVALIDCALL;
1473 }
1474 }
1475 else
1476 {
1477 FIXME("Unexpected parameter type %u.\n", type);
1478 return D3DERR_INVALIDCALL;
1479 }
1480}
1481
1482static HRESULT set_constants(struct d3dx_regstore *rs, struct d3dx_const_tab *const_tab,
1483 ULONG64 new_update_version, ID3DXEffectStateManager *manager, struct IDirect3DDevice9 *device,
1484 D3DXPARAMETER_TYPE type, BOOL device_update_all, BOOL pres_dirty)
1485{
1486 unsigned int const_idx;
1487 unsigned int current_start = 0, current_count = 0;
1488 enum pres_reg_tables current_table = PRES_REGTAB_COUNT;
1489 BOOL update_device = manager || device;
1491 ULONG64 update_version = const_tab->update_version;
1492
1493 for (const_idx = 0; const_idx < const_tab->const_set_count; ++const_idx)
1494 {
1495 struct d3dx_const_param_eval_output *const_set = &const_tab->const_set[const_idx];
1496 enum pres_reg_tables table = const_set->table;
1497 struct d3dx_parameter *param = const_set->param;
1498 unsigned int element, i, j, start_offset;
1499 struct const_upload_info info;
1500 unsigned int *data;
1501 enum pres_value_type param_type;
1502
1503 if (!(param && is_param_dirty(param, update_version)))
1504 continue;
1505
1506 data = param->data;
1507 start_offset = get_offset_reg(table, const_set->register_index);
1508 if (const_set->direct_copy)
1509 {
1510 regstore_set_values(rs, table, data, start_offset,
1511 get_offset_reg(table, const_set->register_count));
1512 continue;
1513 }
1514 param_type = table_type_from_param_type(param->type);
1515 if (const_set->constant_class == D3DXPC_SCALAR || const_set->constant_class == D3DXPC_VECTOR)
1516 {
1517 unsigned int count = max(param->rows, param->columns);
1518
1520 {
1521 regstore_set_data(rs, table, start_offset, data,
1522 count * const_set->element_count, param_type);
1523 }
1524 else
1525 {
1526 for (element = 0; element < const_set->element_count; ++element)
1527 regstore_set_data(rs, table, start_offset + get_offset_reg(table, element),
1528 &data[element * count], count, param_type);
1529 }
1530 continue;
1531 }
1532 get_const_upload_info(const_set, &info);
1533 for (element = 0; element < const_set->element_count; ++element)
1534 {
1535 unsigned int *out = (unsigned int *)rs->tables[table] + start_offset;
1536
1537 /* Store reshaped but (possibly) not converted yet data temporarily in the same constants buffer.
1538 * All the supported types of parameters and table values have the same size. */
1539 if (info.transpose)
1540 {
1541 for (i = 0; i < info.major_count; ++i)
1542 for (j = 0; j < info.minor; ++j)
1543 out[i * info.major_stride + j] = data[i + j * info.major];
1544
1545 for (j = 0; j < info.minor_remainder; ++j)
1546 out[i * info.major_stride + j] = data[i + j * info.major];
1547 }
1548 else
1549 {
1550 for (i = 0; i < info.major_count; ++i)
1551 for (j = 0; j < info.minor; ++j)
1552 out[i * info.major_stride + j] = data[i * info.minor + j];
1553 }
1554 start_offset += get_offset_reg(table, const_set->register_count);
1555 data += param->rows * param->columns;
1556 }
1557 start_offset = get_offset_reg(table, const_set->register_index);
1558 if (table_info[table].type != param_type)
1559 regstore_set_data(rs, table, start_offset, (unsigned int *)rs->tables[table] + start_offset,
1560 get_offset_reg(table, const_set->register_count) * const_set->element_count, param_type);
1561 }
1562 const_tab->update_version = new_update_version;
1563 if (!update_device)
1564 return D3D_OK;
1565
1566 for (const_idx = 0; const_idx < const_tab->const_set_count; ++const_idx)
1567 {
1568 struct d3dx_const_param_eval_output *const_set = &const_tab->const_set[const_idx];
1569
1570 if (device_update_all || (const_set->param
1571 ? is_param_dirty(const_set->param, update_version) : pres_dirty))
1572 {
1573 enum pres_reg_tables table = const_set->table;
1574
1575 if (table == current_table && current_start + current_count == const_set->register_index)
1576 {
1577 current_count += const_set->register_count * const_set->element_count;
1578 }
1579 else
1580 {
1581 if (current_count)
1582 {
1583 if (FAILED(hr = set_constants_device(manager, device, type, current_table,
1584 (DWORD *)rs->tables[current_table]
1585 + get_offset_reg(current_table, current_start), current_start, current_count)))
1586 result = hr;
1587 }
1588 current_table = table;
1589 current_start = const_set->register_index;
1590 current_count = const_set->register_count * const_set->element_count;
1591 }
1592 }
1593 }
1594 if (current_count)
1595 {
1596 if (FAILED(hr = set_constants_device(manager, device, type, current_table,
1597 (DWORD *)rs->tables[current_table]
1598 + get_offset_reg(current_table, current_start), current_start, current_count)))
1599 result = hr;
1600 }
1601 return result;
1602}
1603
1604static double exec_get_reg_value(struct d3dx_regstore *rs, enum pres_reg_tables table, unsigned int offset)
1605{
1606 return regstore_get_double(rs, table, offset);
1607}
1608
1609static double exec_get_arg(struct d3dx_regstore *rs, const struct d3dx_pres_operand *opr, unsigned int comp)
1610{
1611 unsigned int offset, base_index, reg_index, table;
1612
1613 table = opr->reg.table;
1614
1615 if (opr->index_reg.table == PRES_REGTAB_COUNT)
1616 base_index = 0;
1617 else
1618 base_index = lrint(exec_get_reg_value(rs, opr->index_reg.table, opr->index_reg.offset));
1619
1620 offset = get_offset_reg(table, base_index) + opr->reg.offset + comp;
1621 reg_index = get_reg_offset(table, offset);
1622
1623 if (reg_index >= rs->table_sizes[table])
1624 {
1625 unsigned int wrap_size;
1626
1627 if (table == PRES_REGTAB_CONST)
1628 {
1629 /* As it can be guessed from tests, offset into floating constant table is wrapped
1630 * to the nearest power of 2 and not to the actual table size. */
1631 for (wrap_size = 1; wrap_size < rs->table_sizes[table]; wrap_size <<= 1)
1632 ;
1633 }
1634 else
1635 {
1636 wrap_size = rs->table_sizes[table];
1637 }
1638 WARN("Wrapping register index %u, table %u, wrap_size %u, table size %u.\n",
1639 reg_index, table, wrap_size, rs->table_sizes[table]);
1640 reg_index %= wrap_size;
1641
1642 if (reg_index >= rs->table_sizes[table])
1643 return 0.0;
1644
1646 }
1647
1648 return exec_get_reg_value(rs, table, offset);
1649}
1650
1651static void exec_set_arg(struct d3dx_regstore *rs, const struct d3dx_pres_reg *reg,
1652 unsigned int comp, double res)
1653{
1654 regstore_set_double(rs, reg->table, reg->offset + comp, res);
1655}
1656
1657#define ARGS_ARRAY_SIZE 8
1659{
1660 unsigned int i, j, k;
1661 double args[ARGS_ARRAY_SIZE];
1662 double res;
1663
1664 for (i = 0; i < pres->ins_count; ++i)
1665 {
1666 const struct d3dx_pres_ins *ins;
1667 const struct op_info *oi;
1668
1669 ins = &pres->ins[i];
1670 oi = &pres_op_info[ins->op];
1671 if (oi->func_all_comps)
1672 {
1674 {
1675 FIXME("Too many arguments (%u) for one instruction.\n", oi->input_count * ins->component_count);
1676 return E_FAIL;
1677 }
1678 for (k = 0; k < oi->input_count; ++k)
1679 for (j = 0; j < ins->component_count; ++j)
1680 args[k * ins->component_count + j] = exec_get_arg(&pres->regs, &ins->inputs[k],
1681 ins->scalar_op && !k ? 0 : j);
1682 res = oi->func(args, ins->component_count);
1683
1684 /* only 'dot' instruction currently falls here */
1685 exec_set_arg(&pres->regs, &ins->output.reg, 0, res);
1686 }
1687 else
1688 {
1689 for (j = 0; j < ins->component_count; ++j)
1690 {
1691 for (k = 0; k < oi->input_count; ++k)
1692 args[k] = exec_get_arg(&pres->regs, &ins->inputs[k], ins->scalar_op && !k ? 0 : j);
1693 res = oi->func(args, ins->component_count);
1694 exec_set_arg(&pres->regs, &ins->output.reg, j, res);
1695 }
1696 }
1697 }
1698 return D3D_OK;
1699}
1700
1701static BOOL is_const_tab_input_dirty(struct d3dx_const_tab *ctab, ULONG64 update_version)
1702{
1703 unsigned int i;
1704
1705 if (update_version == ULONG64_MAX)
1706 update_version = ctab->update_version;
1707 for (i = 0; i < ctab->input_count; ++i)
1708 {
1710 update_version))
1711 return TRUE;
1712 }
1713 return FALSE;
1714}
1715
1717{
1718 return is_const_tab_input_dirty(&peval->pres.inputs, update_version)
1719 || is_const_tab_input_dirty(&peval->shader_inputs, update_version);
1720}
1721
1723 void *param_value)
1724{
1725 HRESULT hr;
1726 unsigned int i;
1727 unsigned int elements, elements_param, elements_table;
1728 BOOL is_dirty;
1729 float *oc;
1730
1731 TRACE("peval %p, param %p, param_value %p.\n", peval, param, param_value);
1732
1733 if ((is_dirty = is_const_tab_input_dirty(&peval->pres.inputs, ULONG64_MAX)))
1734 {
1735 set_constants(&peval->pres.regs, &peval->pres.inputs,
1737 peval->param_type, FALSE, FALSE);
1738 }
1739
1740 if (is_dirty || peval->pres.regs.table_sizes[PRES_REGTAB_INPUT])
1741 {
1742 if (FAILED(hr = execute_preshader(&peval->pres)))
1743 return hr;
1744 }
1745
1746 elements_table = get_offset_reg(PRES_REGTAB_OCONST, peval->pres.regs.table_sizes[PRES_REGTAB_OCONST]);
1747 elements_param = param->bytes / sizeof(unsigned int);
1748 elements = min(elements_table, elements_param);
1749 oc = (float *)peval->pres.regs.tables[PRES_REGTAB_OCONST];
1750 for (i = 0; i < elements; ++i)
1751 set_number((unsigned int *)param_value + i, param->type, oc + i, D3DXPT_FLOAT);
1752 return D3D_OK;
1753}
1754
1756 struct d3dx_param_eval *peval, BOOL update_all)
1757{
1758 HRESULT hr;
1759 struct d3dx_preshader *pres = &peval->pres;
1760 struct d3dx_regstore *rs = &pres->regs;
1761 ULONG64 new_update_version = next_update_version(peval->version_counter);
1762 BOOL pres_dirty = FALSE;
1763
1764 TRACE("device %p, peval %p, param_type %u.\n", device, peval, peval->param_type);
1765
1767 {
1768 set_constants(rs, &pres->inputs, new_update_version,
1769 NULL, NULL, peval->param_type, FALSE, FALSE);
1770 if (FAILED(hr = execute_preshader(pres)))
1771 return hr;
1772 pres_dirty = TRUE;
1773 }
1774
1775 return set_constants(rs, &peval->shader_inputs, new_update_version,
1776 manager, device, peval->param_type, update_all, pres_dirty);
1777}
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define index(s, c)
Definition: various.h:29
#define ARRAY_SIZE(A)
Definition: main.h:20
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
Definition: _set.h:50
#define D3DERR_INVALIDCALL
Definition: d3d10_private.h:42
unsigned int component_count
#define D3D_OK
Definition: d3d.h:106
#define D3DXERR_INVALIDDATA
Definition: compiler.c:53
const struct ctab_constant * d3dx_shader_get_ctab_constant(ID3DXConstantTable *iface, D3DXHANDLE constant)
Definition: shader.c:969
static BOOL is_param_type_sampler(D3DXPARAMETER_TYPE type)
static struct d3dx_top_level_parameter * top_level_parameter_from_parameter(struct d3dx_parameter *param)
static BOOL is_param_dirty(struct d3dx_parameter *param, ULONG64 update_version)
static ULONG64 next_update_version(ULONG64 *version_counter)
static void set_number(void *outdata, D3DXPARAMETER_TYPE outtype, const void *indata, D3DXPARAMETER_TYPE intype)
#define ULONG64_MAX
Definition: d3dx9_private.h:32
struct d3dx_parameter * get_parameter_by_name(struct d3dx_parameters_store *store, struct d3dx_parameter *parameter, const char *name)
Definition: effect.c:1041
static BOOL is_top_level_parameter(struct d3dx_parameter *param)
#define FOURCC_TX_1
Definition: d3dx9_private.h:34
pres_reg_tables
@ PRES_REGTAB_COUNT
@ PRES_REGTAB_FIRST_SHADER
@ PRES_REGTAB_OICONST
@ PRES_REGTAB_IMMED
@ PRES_REGTAB_TEMP
@ PRES_REGTAB_CONST
@ PRES_REGTAB_INPUT
@ PRES_REGTAB_OCONST
@ PRES_REGTAB_OBCONST
static BOOL is_top_level_param_dirty(struct d3dx_top_level_parameter *param, ULONG64 update_version)
#define SET_D3D_STATE_(manager, device, method,...)
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_FAIL
Definition: ddrawi.h:102
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
HRESULT hr
Definition: delayimp.cpp:582
LPWSTR Name
Definition: desk.c:124
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
HRESULT WINAPI D3DXGetShaderConstantTable(const DWORD *byte_code, ID3DXConstantTable **constant_table)
Definition: shader.c:2097
#define TRACE_ON(x)
Definition: compat.h:75
static void cleanup(void)
Definition: main.c:1335
#define assert(_expr)
Definition: assert.h:32
#define __cdecl
Definition: corecrt.h:121
#define UINT_MAX
Definition: limits.h:27
#define isnan(x)
Definition: math.h:360
_ACRTIMP double __cdecl sqrt(double)
Definition: sqrt.c:5
_ACRTIMP double __cdecl fabs(double)
_ACRTIMP double __cdecl atan(double)
Definition: atan.c:44
_ACRTIMP __msvcrt_long __cdecl lrint(double)
Definition: mingw_math.h:371
_ACRTIMP double __cdecl log2(double)
Definition: stubs.c:62
_ACRTIMP double __cdecl sin(double)
Definition: sin.c:21
_ACRTIMP double __cdecl fmin(double, double)
#define NAN
Definition: math.h:273
_ACRTIMP double __cdecl fmax(double, double)
#define INFINITY
Definition: math.h:272
_ACRTIMP double __cdecl floor(double)
Definition: floor.c:18
_ACRTIMP double __cdecl asin(double)
Definition: asin.c:31
_ACRTIMP double __cdecl cos(double)
Definition: cos.c:21
_ACRTIMP double __cdecl atan2(double, double)
Definition: atan2.c:52
_ACRTIMP double __cdecl acos(double)
Definition: acos.c:28
_ACRTIMP void __cdecl qsort(void *, size_t, size_t, int(__cdecl *)(const void *, const void *))
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3324
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
return ret
Definition: mutex.c:147
switch(r->id)
Definition: btrfs.c:3046
@ D3DXPC_SCALAR
Definition: d3dx9shader.h:62
@ D3DXPC_MATRIX_COLUMNS
Definition: d3dx9shader.h:65
@ D3DXPC_STRUCT
Definition: d3dx9shader.h:67
@ D3DXPC_MATRIX_ROWS
Definition: d3dx9shader.h:64
@ D3DXPC_FORCE_DWORD
Definition: d3dx9shader.h:68
@ D3DXPC_VECTOR
Definition: d3dx9shader.h:63
@ D3DXPC_OBJECT
Definition: d3dx9shader.h:66
#define ID3DXConstantTable_GetDesc(p, a)
Definition: d3dx9shader.h:182
@ D3DXRS_SAMPLER
Definition: d3dx9shader.h:56
#define ID3DXConstantTable_GetConstantElement(p, a, b)
Definition: d3dx9shader.h:187
#define ID3DXConstantTable_Release(p)
Definition: d3dx9shader.h:177
const char * D3DXHANDLE
Definition: d3dx9shader.h:48
D3DXPARAMETER_TYPE
Definition: d3dx9shader.h:72
@ D3DXPT_VERTEXSHADER
Definition: d3dx9shader.h:89
@ D3DXPT_FLOAT
Definition: d3dx9shader.h:76
@ D3DXPT_PIXELSHADER
Definition: d3dx9shader.h:88
@ D3DXPT_BOOL
Definition: d3dx9shader.h:74
@ D3DXPT_INT
Definition: d3dx9shader.h:75
@ D3DXPT_VOID
Definition: d3dx9shader.h:73
#define ID3DXConstantTable_GetConstant(p, a, b)
Definition: d3dx9shader.h:185
DWORD IDirect3DDevice9
Definition: dxva2api.idl:22
static xmlNodePtr get_element(const domelem *This)
Definition: element.c:63
size_t const new_size
Definition: expand.cpp:66
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
double pow(double x, double y)
Definition: freeldr.c:179
GLuint start
Definition: gl.h:1545
const GLdouble * v
Definition: gl.h:2040
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble n
Definition: glext.h:7729
GLuint res
Definition: glext.h:9613
GLenum src
Definition: glext.h:6340
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
GLuint shader
Definition: glext.h:6030
GLuint index
Definition: glext.h:6031
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLuint in
Definition: glext.h:9616
GLenum GLenum dst
Definition: glext.h:6340
GLuint64EXT * result
Definition: glext.h:11304
GLfloat GLfloat p
Definition: glext.h:8902
GLfloat param
Definition: glext.h:5796
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
static int reg
Definition: i386-dis.c:1290
#define FAILED(hr)
Definition: intsafe.h:51
#define a
Definition: ke_i.h:78
#define b
Definition: ke_i.h:79
#define debugstr_a
Definition: kernel32.h:31
if(dx< 0)
Definition: linetemp.h:194
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
unsigned __int64 ULONG64
Definition: imports.h:198
static PVOID ptr
Definition: dispmode.c:27
D3D11_SHADER_VARIABLE_DESC desc
Definition: reflection.c:1683
static DNS_RECORDW r1
Definition: record.c:37
static DNS_RECORDW r2
Definition: record.c:38
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:91
static ULONG ** element_count
Definition: exception.c:124
static float(__cdecl *square_half_float)(float x
static BYTE parameters[]
Definition: asn.c:558
#define min(a, b)
Definition: monoChain.cc:55
int k
Definition: mpi.c:3369
#define BOOL
Definition: nt_native.h:43
static HRESULT parse_preshader(struct d3dx_preshader *pres, unsigned int *ptr, unsigned int count, struct d3dx_parameters_store *parameters)
Definition: preshader.c:1107
static double pres_frc(double *args, int n)
Definition: preshader.c:102
static double pres_div(double *args, int n)
Definition: preshader.c:136
static enum pres_value_type table_type_from_param_type(D3DXPARAMETER_TYPE type)
Definition: preshader.c:271
HRESULT d3dx_param_eval_set_shader_constants(ID3DXEffectStateManager *manager, struct IDirect3DDevice9 *device, struct d3dx_param_eval *peval, BOOL update_all)
Definition: preshader.c:1755
#define PRES_OPCODE_MASK
Definition: preshader.c:138
static void regstore_set_double(struct d3dx_regstore *rs, unsigned int table, unsigned int offset, double v)
Definition: preshader.c:358
static void regstore_free_tables(struct d3dx_regstore *rs)
Definition: preshader.c:318
static double pres_sin(double *args, int n)
Definition: preshader.c:106
static HRESULT get_ctab_constant_desc(ID3DXConstantTable *ctab, D3DXHANDLE hc, D3DXCONSTANT_DESC *desc, WORD *constantinfo_reserved)
Definition: preshader.c:530
double(* pres_op_func)(double *args, int n)
Definition: preshader.c:57
static void pres_float_from_bool(void *out, const void *in, unsigned int count)
Definition: preshader.c:1399
static double pres_dotswiz6(double *args, int n)
Definition: preshader.c:88
HRESULT d3dx_create_param_eval(struct d3dx_parameters_store *parameters, void *byte_code, unsigned int byte_code_size, D3DXPARAMETER_TYPE type, struct d3dx_param_eval **peval_out, ULONG64 *version_counter, const char **skip_constants, unsigned int skip_constants_count)
Definition: preshader.c:1232
static double pres_mov(double *args, int n)
Definition: preshader.c:74
BOOL is_param_eval_input_dirty(struct d3dx_param_eval *peval, ULONG64 update_version)
Definition: preshader.c:1716
static void d3dx_free_preshader(struct d3dx_preshader *pres)
Definition: preshader.c:1349
static double pres_cmp(double *args, int n)
Definition: preshader.c:105
static void dump_preshader(struct d3dx_preshader *pres)
Definition: preshader.c:1083
#define PRES_OPCODE_SHIFT
Definition: preshader.c:139
static double exec_get_reg_value(struct d3dx_regstore *rs, enum pres_reg_tables table, unsigned int offset)
Definition: preshader.c:1604
#define FOURCC_PRES
Definition: preshader.c:143
static HRESULT append_const_set(struct d3dx_const_tab *const_tab, struct d3dx_const_param_eval_output *set)
Definition: preshader.c:586
static double exec_get_arg(struct d3dx_regstore *rs, const struct d3dx_pres_operand *opr, unsigned int comp)
Definition: preshader.c:1609
static double pres_cos(double *args, int n)
Definition: preshader.c:107
static double pres_lt(double *args, int n)
Definition: preshader.c:100
static const struct @283 table_info[]
static void exec_set_arg(struct d3dx_regstore *rs, const struct d3dx_pres_reg *reg, unsigned int comp, double res)
Definition: preshader.c:1651
static double pres_dot(double *args, int n)
Definition: preshader.c:77
static unsigned int * find_bytecode_comment(unsigned int *ptr, unsigned int count, unsigned int fourcc, unsigned int *size)
Definition: preshader.c:392
static double pres_mul(double *args, int n)
Definition: preshader.c:76
static unsigned int * parse_pres_arg(unsigned int *ptr, unsigned int count, struct d3dx_pres_operand *opr)
Definition: preshader.c:433
static void pres_float_from_int(void *out, const void *in, unsigned int count)
Definition: preshader.c:1389
static double regstore_get_double(struct d3dx_regstore *rs, unsigned int table, unsigned int offset)
Definition: preshader.c:341
static double pres_exp(double *args, int n)
Definition: preshader.c:118
#define PRES_NCOMP_MASK
Definition: preshader.c:141
static HRESULT merge_const_set_entries(struct d3dx_const_tab *const_tab, struct d3dx_parameter *param, unsigned int index)
Definition: preshader.c:653
static unsigned int * parse_pres_ins(unsigned int *ptr, unsigned int count, struct d3dx_pres_ins *ins)
Definition: preshader.c:465
HRESULT d3dx_evaluate_parameter(struct d3dx_param_eval *peval, const struct d3dx_parameter *param, void *param_value)
Definition: preshader.c:1722
static const struct op_info pres_op_info[]
Definition: preshader.c:158
static BOOL is_const_tab_input_dirty(struct d3dx_const_tab *ctab, ULONG64 update_version)
Definition: preshader.c:1701
static enum pres_reg_tables pres_regset2table[]
Definition: preshader.c:218
static void dump_registers(struct d3dx_const_tab *ctab)
Definition: preshader.c:1057
static HRESULT set_constants_device(ID3DXEffectStateManager *manager, struct IDirect3DDevice9 *device, D3DXPARAMETER_TYPE type, enum pres_reg_tables table, void *ptr, unsigned int start, unsigned int count)
Definition: preshader.c:1441
static double pres_rcp(double *args, int n)
Definition: preshader.c:99
static void update_table_size(unsigned int *table_sizes, unsigned int table, unsigned int max_register)
Definition: preshader.c:998
static HRESULT execute_preshader(struct d3dx_preshader *pres)
Definition: preshader.c:1658
static void update_table_sizes_consts(unsigned int *table_sizes, struct d3dx_const_tab *ctab)
Definition: preshader.c:1004
static void regstore_set_data(struct d3dx_regstore *rs, unsigned int table, unsigned int offset, const unsigned int *in, unsigned int count, enum pres_value_type param_type)
Definition: preshader.c:1419
static double pres_neg(double *args, int n)
Definition: preshader.c:98
pres_ops
Definition: preshader.c:29
@ PRESHADER_OP_ATAN
Definition: preshader.c:42
@ PRESHADER_OP_SIN
Definition: preshader.c:38
@ PRESHADER_OP_MUL
Definition: preshader.c:48
@ PRESHADER_OP_NOP
Definition: preshader.c:30
@ PRESHADER_OP_ASIN
Definition: preshader.c:40
@ PRESHADER_OP_DOT
Definition: preshader.c:52
@ PRESHADER_OP_ACOS
Definition: preshader.c:41
@ PRESHADER_OP_LOG
Definition: preshader.c:36
@ PRESHADER_OP_NEG
Definition: preshader.c:32
@ PRESHADER_OP_LT
Definition: preshader.c:45
@ PRESHADER_OP_MIN
Definition: preshader.c:43
@ PRESHADER_OP_COS
Definition: preshader.c:39
@ PRESHADER_OP_DIV
Definition: preshader.c:50
@ PRESHADER_OP_CMP
Definition: preshader.c:51
@ PRESHADER_OP_FRC
Definition: preshader.c:34
@ PRESHADER_OP_RSQ
Definition: preshader.c:37
@ PRESHADER_OP_ATAN2
Definition: preshader.c:49
@ PRESHADER_OP_RCP
Definition: preshader.c:33
@ PRESHADER_OP_MOV
Definition: preshader.c:31
@ PRESHADER_OP_MAX
Definition: preshader.c:44
@ PRESHADER_OP_DOTSWIZ8
Definition: preshader.c:54
@ PRESHADER_OP_GE
Definition: preshader.c:46
@ PRESHADER_OP_DOTSWIZ6
Definition: preshader.c:53
@ PRESHADER_OP_EXP
Definition: preshader.c:35
@ PRESHADER_OP_ADD
Definition: preshader.c:47
static void append_pres_const_sets_for_shader_input(struct d3dx_const_tab *const_tab, struct d3dx_preshader *pres)
Definition: preshader.c:620
static double pres_atan(double *args, int n)
Definition: preshader.c:131
static HRESULT set_constants(struct d3dx_regstore *rs, struct d3dx_const_tab *const_tab, ULONG64 new_update_version, ID3DXEffectStateManager *manager, struct IDirect3DDevice9 *device, D3DXPARAMETER_TYPE type, BOOL device_update_all, BOOL pres_dirty)
Definition: preshader.c:1482
static enum pres_reg_tables shad_regset2table[]
Definition: preshader.c:226
#define INITIAL_CONST_SET_SIZE
Definition: preshader.c:584
#define ARGS_ARRAY_SIZE
Definition: preshader.c:1657
static void dump_arg(struct d3dx_regstore *rs, const struct d3dx_pres_operand *arg, int component_count)
Definition: preshader.c:1018
static void pres_bool_from_value(void *out, const void *in, unsigned int count)
Definition: preshader.c:1379
static unsigned int get_reg_offset(unsigned int table, unsigned int offset)
Definition: preshader.c:287
static double to_signed_nan(double v)
Definition: preshader.c:59
#define FOURCC_FXLC
Definition: preshader.c:145
static double pres_add(double *args, int n)
Definition: preshader.c:75
static void d3dx_free_const_tab(struct d3dx_const_tab *ctab)
Definition: preshader.c:1342
static double pres_asin(double *args, int n)
Definition: preshader.c:129
static void pres_int_from_bool(void *out, const void *in, unsigned int count)
Definition: preshader.c:1409
static HRESULT get_constants_desc(unsigned int *byte_code, struct d3dx_const_tab *out, struct d3dx_parameters_store *parameters, const char **skip_constants, unsigned int skip_constants_count, struct d3dx_preshader *pres)
Definition: preshader.c:852
static const char * table_symbol[]
Definition: preshader.c:213
static unsigned int get_offset_reg(unsigned int table, unsigned int reg_idx)
Definition: preshader.c:292
static unsigned int * parse_pres_reg(unsigned int *ptr, struct d3dx_pres_reg *reg)
Definition: preshader.c:414
static void regstore_set_values(struct d3dx_regstore *rs, unsigned int table, const void *data, unsigned int start_offset, unsigned int count)
Definition: preshader.c:328
enum pres_value_type type
Definition: preshader.c:199
static double pres_atan2(double *args, int n)
Definition: preshader.c:132
#define FOURCC_CLIT
Definition: preshader.c:144
static HRESULT init_set_constants_param(struct d3dx_const_tab *const_tab, ID3DXConstantTable *ctab, D3DXHANDLE hc, struct d3dx_parameter *param)
Definition: preshader.c:730
void d3dx_free_param_eval(struct d3dx_param_eval *peval)
Definition: preshader.c:1357
static double pres_max(double *args, int n)
Definition: preshader.c:104
static HRESULT regstore_alloc_table(struct d3dx_regstore *rs, unsigned int table)
Definition: preshader.c:304
static double pres_acos(double *args, int n)
Definition: preshader.c:130
static void get_const_upload_info(struct d3dx_const_param_eval_output *const_set, struct const_upload_info *info)
Definition: preshader.c:548
static void dump_ins(struct d3dx_regstore *rs, const struct d3dx_pres_ins *ins)
Definition: preshader.c:1069
static double pres_log(double *args, int n)
Definition: preshader.c:119
#define PRES_SCALAR_FLAG
Definition: preshader.c:140
static void pres_int_from_float(void *out, const void *in, unsigned int count)
Definition: preshader.c:1369
pres_value_type
Definition: preshader.c:188
@ PRES_VT_DOUBLE
Definition: preshader.c:190
@ PRES_VT_FLOAT
Definition: preshader.c:189
@ PRES_VT_BOOL
Definition: preshader.c:192
@ PRES_VT_COUNT
Definition: preshader.c:193
@ PRES_VT_INT
Definition: preshader.c:191
static double pres_ge(double *args, int n)
Definition: preshader.c:101
static double pres_min(double *args, int n)
Definition: preshader.c:103
static int __cdecl compare_const_set(const void *a, const void *b)
Definition: preshader.c:643
static double pres_dotswiz8(double *args, int n)
Definition: preshader.c:93
#define MAX_INPUTS_COUNT
Definition: preshader.c:248
static void dump_bytecode(void *data, unsigned int size)
Definition: preshader.c:375
static unsigned int get_reg_components(unsigned int table)
Definition: preshader.c:297
static double pres_rsq(double *args, int n)
Definition: preshader.c:108
unsigned int component_size
Definition: preshader.c:198
for(i=0;i< sizeof(testsuite)/sizeof(testsuite[0]);++i) ok(call_test(testsuite[i].func)
static int sum(int x_, int y_)
Definition: ptr2_test.cpp:35
#define calloc
Definition: rosglue.h:14
#define args
Definition: format.c:66
#define TRACE(s)
Definition: solgame.cpp:4
D3DXREGISTER_SET RegisterSet
Definition: d3dx9shader.h:106
Definition: match.c:390
unsigned int major_count
Definition: preshader.c:266
unsigned int count
Definition: preshader.c:267
unsigned int minor
Definition: preshader.c:264
unsigned int major
Definition: preshader.c:264
unsigned int major_stride
Definition: preshader.c:265
unsigned int minor_remainder
Definition: preshader.c:268
WORD constantinfo_reserved
enum D3DXPARAMETER_CLASS constant_class
enum pres_reg_tables table
struct d3dx_parameter * param
struct d3dx_parameter ** inputs_param
struct d3dx_const_param_eval_output * const_set
unsigned int const_set_count
ULONG64 update_version
unsigned int const_set_size
D3DXCONSTANT_DESC * inputs
unsigned int input_count
enum pres_reg_tables * regset2table
struct d3dx_const_tab shader_inputs
struct d3dx_preshader pres
ULONG64 * version_counter
D3DXPARAMETER_TYPE param_type
BOOL scalar_op
Definition: preshader.c:255
enum pres_ops op
Definition: preshader.c:252
struct d3dx_pres_operand inputs[MAX_INPUTS_COUNT]
Definition: preshader.c:257
unsigned int component_count
Definition: preshader.c:256
struct d3dx_pres_operand output
Definition: preshader.c:258
struct d3dx_pres_reg index_reg
Definition: preshader.c:245
struct d3dx_pres_reg reg
Definition: preshader.c:244
unsigned int offset
Definition: preshader.c:239
enum pres_reg_tables table
Definition: preshader.c:236
unsigned int ins_count
struct d3dx_const_tab inputs
struct d3dx_pres_ins * ins
struct d3dx_regstore regs
void * tables[PRES_REGTAB_COUNT]
unsigned int table_sizes[PRES_REGTAB_COUNT]
Definition: devices.h:37
unsigned int count
Definition: notification.c:73
char mnem[16]
Definition: preshader.c:152
unsigned int input_count
Definition: preshader.c:153
BOOL func_all_comps
Definition: preshader.c:154
pres_op_func func
Definition: preshader.c:155
unsigned int opcode
Definition: preshader.c:151
#define max(a, b)
Definition: svc.c:63
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
unsigned char BYTE
Definition: xxhash.c:193