ReactOS 0.4.17-dev-934-g091855f
msl.c
Go to the documentation of this file.
1/*
2 * Copyright 2024 Feifan He for CodeWeavers
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
20
21struct msl_src
22{
24};
25
26struct msl_dst
27{
31};
32
34{
40 unsigned int indent;
41 const char *prefix;
42 bool failed;
43
46};
47
48static void VKD3D_PRINTF_FUNC(3, 4) msl_compiler_error(struct msl_generator *gen,
50{
52
54 vkd3d_shader_verror(gen->message_context, &gen->location, error, fmt, args);
55 va_end(args);
56 gen->failed = true;
57}
58
59static const char *msl_get_prefix(enum vkd3d_shader_type type)
60{
61 switch (type)
62 {
64 return "vs";
66 return "hs";
68 return "ds";
70 return "gs";
72 return "ps";
74 return "cs";
75 default:
76 return NULL;
77 }
78}
79
80static void msl_print_indent(struct vkd3d_string_buffer *buffer, unsigned int indent)
81{
83}
84
86 struct msl_generator *gen, enum vkd3d_data_type data_type)
87{
89 switch (data_type)
90 {
93 break;
94 case VKD3D_DATA_INT:
96 break;
97 case VKD3D_DATA_UINT:
99 break;
100 default:
101 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
102 "Internal compiler error: Unhandled register datatype %#x.", data_type);
103 vkd3d_string_buffer_printf(buffer, "<unrecognised register datatype %#x>", data_type);
104 break;
105 }
106}
107
109 struct msl_generator *gen, const struct vkd3d_shader_register *reg)
110{
111 switch (reg->type)
112 {
113 case VKD3DSPR_TEMP:
114 vkd3d_string_buffer_printf(buffer, "r[%u]", reg->idx[0].offset);
115 msl_print_register_datatype(buffer, gen, reg->data_type);
116 break;
117
118 case VKD3DSPR_INPUT:
119 if (reg->idx_count != 1)
120 {
121 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
122 "Internal compiler error: Unhandled input register index count %u.", reg->idx_count);
123 vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type);
124 break;
125 }
126 if (reg->idx[0].rel_addr)
127 {
128 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
129 "Internal compiler error: Unhandled input register indirect addressing.");
130 vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type);
131 break;
132 }
133 vkd3d_string_buffer_printf(buffer, "v[%u]", reg->idx[0].offset);
134 msl_print_register_datatype(buffer, gen, reg->data_type);
135 break;
136
137 case VKD3DSPR_OUTPUT:
138 if (reg->idx_count != 1)
139 {
140 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
141 "Internal compiler error: Unhandled output register index count %u.", reg->idx_count);
142 vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type);
143 break;
144 }
145 if (reg->idx[0].rel_addr)
146 {
147 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
148 "Internal compiler error: Unhandled output register indirect addressing.");
149 vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type);
150 break;
151 }
152 vkd3d_string_buffer_printf(buffer, "o[%u]", reg->idx[0].offset);
153 msl_print_register_datatype(buffer, gen, reg->data_type);
154 break;
155
157 if (reg->idx_count != 3)
158 {
159 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
160 "Internal compiler error: Unhandled constant buffer register index count %u.", reg->idx_count);
161 vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type);
162 break;
163 }
164 if (reg->idx[0].rel_addr || reg->idx[2].rel_addr)
165 {
166 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
167 "Internal compiler error: Unhandled constant buffer register indirect addressing.");
168 vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type);
169 break;
170 }
171 vkd3d_string_buffer_printf(buffer, "descriptors.cb_%u[%u]", reg->idx[0].offset, reg->idx[2].offset);
172 msl_print_register_datatype(buffer, gen, reg->data_type);
173 break;
174
175 default:
176 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
177 "Internal compiler error: Unhandled register type %#x.", reg->type);
178 vkd3d_string_buffer_printf(buffer, "<unrecognised register %#x>", reg->type);
179 break;
180 }
181}
182
184{
185 const char swizzle_chars[] = "xyzw";
186 unsigned int i;
187
189 for (i = 0; i < VKD3D_VEC4_SIZE; ++i)
190 {
191 if (mask & (VKD3DSP_WRITEMASK_0 << i))
193 }
194}
195
197{
199 if (write_mask & VKD3DSP_WRITEMASK_0)
201 if (write_mask & VKD3DSP_WRITEMASK_1)
203 if (write_mask & VKD3DSP_WRITEMASK_2)
205 if (write_mask & VKD3DSP_WRITEMASK_3)
207}
208
210{
212}
213
214static void msl_src_init(struct msl_src *msl_src, struct msl_generator *gen,
215 const struct vkd3d_shader_src_param *vsir_src, uint32_t mask)
216{
217 const struct vkd3d_shader_register *reg = &vsir_src->reg;
218
220
221 if (reg->non_uniform)
222 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
223 "Internal compiler error: Unhandled 'non-uniform' modifier.");
224 if (vsir_src->modifiers)
225 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
226 "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers);
227
229 if (reg->dimension == VSIR_DIMENSION_VEC4)
231}
232
234{
236 vkd3d_string_buffer_release(cache, dst->register_name);
237}
238
240 const struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_dst_param *vsir_dst)
241{
242 uint32_t write_mask = vsir_dst->write_mask;
243
244 if (ins->flags & VKD3DSI_PRECISE_XYZW)
245 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
246 "Internal compiler error: Unhandled 'precise' modifier.");
247 if (vsir_dst->reg.non_uniform)
248 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
249 "Internal compiler error: Unhandled 'non-uniform' modifier.");
250
251 msl_dst->vsir = vsir_dst;
254
256 msl_print_write_mask(msl_dst->mask, write_mask);
257
258 return write_mask;
259}
260
261static void VKD3D_PRINTF_FUNC(3, 4) msl_print_assignment(
262 struct msl_generator *gen, struct msl_dst *dst, const char *format, ...)
263{
265
266 if (dst->vsir->shift)
267 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
268 "Internal compiler error: Unhandled destination shift %#x.", dst->vsir->shift);
269 if (dst->vsir->modifiers)
270 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
271 "Internal compiler error: Unhandled destination modifier(s) %#x.", dst->vsir->modifiers);
272
273 msl_print_indent(gen->buffer, gen->indent);
274 vkd3d_string_buffer_printf(gen->buffer, "%s%s = ", dst->register_name->buffer, dst->mask->buffer);
275
278 va_end(args);
279
280 vkd3d_string_buffer_printf(gen->buffer, ";\n");
281}
282
283static void msl_unhandled(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins)
284{
285 msl_print_indent(gen->buffer, gen->indent);
286 vkd3d_string_buffer_printf(gen->buffer, "/* <unhandled instruction %#x> */\n", ins->opcode);
287 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
288 "Internal compiler error: Unhandled instruction %#x.", ins->opcode);
289}
290
291static void msl_mov(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins)
292{
293 struct msl_src src;
294 struct msl_dst dst;
296
297 mask = msl_dst_init(&dst, gen, ins, &ins->dst[0]);
298 msl_src_init(&src, gen, &ins->src[0], mask);
299
300 msl_print_assignment(gen, &dst, "%s", src.str->buffer);
301
304}
305
306static void msl_ret(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins)
307{
308 msl_print_indent(gen->buffer, gen->indent);
309 vkd3d_string_buffer_printf(gen->buffer, "return;\n");
310}
311
312static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins)
313{
314 gen->location = ins->location;
315
316 switch (ins->opcode)
317 {
321 case VKD3DSIH_NOP:
322 break;
323 case VKD3DSIH_MOV:
324 msl_mov(gen, ins);
325 break;
326 case VKD3DSIH_RET:
327 msl_ret(gen, ins);
328 break;
329 default:
330 msl_unhandled(gen, ins);
331 break;
332 }
333}
334
335static bool msl_check_shader_visibility(const struct msl_generator *gen,
336 enum vkd3d_shader_visibility visibility)
337{
338 enum vkd3d_shader_type t = gen->program->shader_version.type;
339
340 switch (visibility)
341 {
343 return true;
345 return t == VKD3D_SHADER_TYPE_VERTEX;
347 return t == VKD3D_SHADER_TYPE_HULL;
349 return t == VKD3D_SHADER_TYPE_DOMAIN;
353 return t == VKD3D_SHADER_TYPE_PIXEL;
356 default:
357 WARN("Invalid shader visibility %#x.\n", visibility);
358 return false;
359 }
360}
361
362static bool msl_get_cbv_binding(const struct msl_generator *gen,
363 unsigned int register_space, unsigned int register_idx, unsigned int *binding_idx)
364{
367 unsigned int i;
368
369 if (!interface_info)
370 return false;
371
372 for (i = 0; i < interface_info->binding_count; ++i)
373 {
374 binding = &interface_info->bindings[i];
375
377 continue;
378 if (binding->register_space != register_space)
379 continue;
380 if (binding->register_index != register_idx)
381 continue;
382 if (!msl_check_shader_visibility(gen, binding->shader_visibility))
383 continue;
385 continue;
386 *binding_idx = i;
387 return true;
388 }
389
390 return false;
391}
392
394 const struct vkd3d_shader_descriptor_info1 *cbv)
395{
397 struct vkd3d_string_buffer *buffer = gen->buffer;
398 unsigned int binding_idx;
399 size_t size;
400
401 if (cbv->count != 1)
402 {
403 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND,
404 "Constant buffer %u has unsupported descriptor array size %u.", cbv->register_id, cbv->count);
405 return;
406 }
407
408 if (!msl_get_cbv_binding(gen, cbv->register_space, cbv->register_index, &binding_idx))
409 {
410 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND,
411 "No descriptor binding specified for constant buffer %u.", cbv->register_id);
412 return;
413 }
414
415 binding = &gen->interface_info->bindings[binding_idx].binding;
416
417 if (binding->set != 0)
418 {
419 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND,
420 "Unsupported binding set %u specified for constant buffer %u.", binding->set, cbv->register_id);
421 return;
422 }
423
424 if (binding->count != 1)
425 {
426 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND,
427 "Unsupported binding count %u specified for constant buffer %u.", binding->count, cbv->register_id);
428 return;
429 }
430
431 size = align(cbv->buffer_size, VKD3D_VEC4_SIZE * sizeof(uint32_t));
432 size /= VKD3D_VEC4_SIZE * sizeof(uint32_t);
433
435 "constant vkd3d_vec4 *cb_%u [[id(%u)]];", cbv->register_id, binding->binding);
436};
437
439{
442 struct vkd3d_string_buffer *buffer = gen->buffer;
443 unsigned int i;
444
445 if (!info->descriptor_count)
446 return;
447
448 vkd3d_string_buffer_printf(buffer, "struct vkd3d_%s_descriptors\n{\n", gen->prefix);
449
450 for (i = 0; i < info->descriptor_count; ++i)
451 {
452 descriptor = &info->descriptors[i];
453
455 switch (descriptor->type)
456 {
459 break;
460
461 default:
462 vkd3d_string_buffer_printf(buffer, "/* <unhandled descriptor type %#x> */", descriptor->type);
463 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
464 "Internal compiler error: Unhandled descriptor type %#x.", descriptor->type);
465 break;
466 }
468 }
469
471}
472
474{
475 const struct shader_signature *signature = &gen->program->input_signature;
476 enum vkd3d_shader_type type = gen->program->shader_version.type;
477 struct vkd3d_string_buffer *buffer = gen->buffer;
478 const struct signature_element *e;
479 unsigned int i;
480
481 vkd3d_string_buffer_printf(buffer, "struct vkd3d_%s_in\n{\n", gen->prefix);
482
483 for (i = 0; i < signature->element_count; ++i)
484 {
485 e = &signature->elements[i];
486
487 if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED)
488 continue;
489
490 if (e->sysval_semantic)
491 {
492 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
493 "Internal compiler error: Unhandled system value %#x.", e->sysval_semantic);
494 continue;
495 }
496
497 if (e->min_precision != VKD3D_SHADER_MINIMUM_PRECISION_NONE)
498 {
499 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
500 "Internal compiler error: Unhandled minimum precision %#x.", e->min_precision);
501 continue;
502 }
503
504 if (e->interpolation_mode != VKD3DSIM_NONE)
505 {
506 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
507 "Internal compiler error: Unhandled interpolation mode %#x.", e->interpolation_mode);
508 continue;
509 }
510
511 if(e->register_count > 1)
512 {
513 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
514 "Internal compiler error: Unhandled register count %u.", e->register_count);
515 continue;
516 }
517
518 msl_print_indent(gen->buffer, 1);
519
520 switch(e->component_type)
521 {
524 break;
527 break;
530 break;
531 default:
532 vkd3d_string_buffer_printf(buffer, "<unhandled component type %#x> ", e->component_type);
533 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
534 "Internal compiler error: Unhandled component type %#x.", e->component_type);
535 break;
536 }
537
538 vkd3d_string_buffer_printf(buffer, "shader_in_%u ", i);
539
540 switch (type)
541 {
543 vkd3d_string_buffer_printf(gen->buffer, "[[attribute(%u)]]", e->target_location);
544 break;
546 vkd3d_string_buffer_printf(gen->buffer, "[[user(locn%u)]]", e->target_location);
547 break;
548 default:
549 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
550 "Internal compiler error: Unhandled shader type %#x.", type);
551 break;
552 }
553
555 }
556
558}
559
561{
562 switch (e->sysval_semantic)
563 {
565 vkd3d_string_buffer_printf(gen->buffer, "[[position]]");
566 break;
568 vkd3d_string_buffer_printf(gen->buffer, "[[user(locn%u)]]", e->target_location);
569 break;
570 default:
571 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
572 "Internal compiler error: Unhandled vertex shader system value %#x.", e->sysval_semantic);
573 break;
574 }
575}
576
578{
579 switch (e->sysval_semantic)
580 {
582 vkd3d_string_buffer_printf(gen->buffer, "[[color(%u)]]", e->target_location);
583 break;
584 default:
585 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
586 "Internal compiler error: Unhandled pixel shader system value %#x.", e->sysval_semantic);
587 break;
588 }
589}
590
592{
593 const struct shader_signature *signature = &gen->program->output_signature;
594 enum vkd3d_shader_type type = gen->program->shader_version.type;
595 struct vkd3d_string_buffer *buffer = gen->buffer;
596 const struct signature_element *e;
597 unsigned int i;
598
599 vkd3d_string_buffer_printf(buffer, "struct vkd3d_%s_out\n{\n", gen->prefix);
600
601 for (i = 0; i < signature->element_count; ++i)
602 {
603 e = &signature->elements[i];
604
605 if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED)
606 continue;
607
608 if (e->min_precision != VKD3D_SHADER_MINIMUM_PRECISION_NONE)
609 {
610 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
611 "Internal compiler error: Unhandled minimum precision %#x.", e->min_precision);
612 continue;
613 }
614
615 if (e->interpolation_mode != VKD3DSIM_NONE)
616 {
617 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
618 "Internal compiler error: Unhandled interpolation mode %#x.", e->interpolation_mode);
619 continue;
620 }
621
622 if(e->register_count > 1)
623 {
624 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
625 "Internal compiler error: Unhandled register count %u.", e->register_count);
626 continue;
627 }
628
629 msl_print_indent(gen->buffer, 1);
630
631 switch(e->component_type)
632 {
635 break;
638 break;
641 break;
642 default:
643 vkd3d_string_buffer_printf(buffer, "<unhandled component type %#x> ", e->component_type);
644 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
645 "Internal compiler error: Unhandled component type %#x.", e->component_type);
646 break;
647 }
648
649 vkd3d_string_buffer_printf(buffer, "shader_out_%u ", i);
650
651 switch (type)
652 {
655 break;
658 break;
659 default:
660 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
661 "Internal compiler error: Unhandled shader type %#x.", type);
662 break;
663 }
664
666 }
667
669}
670
672{
673 const struct shader_signature *signature = &gen->program->input_signature;
674 struct vkd3d_string_buffer *buffer = gen->buffer;
675 const struct signature_element *e;
676 unsigned int i;
677
678 for (i = 0; i < signature->element_count; ++i)
679 {
680 e = &signature->elements[i];
681
682 if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED)
683 continue;
684
685 vkd3d_string_buffer_printf(buffer, " %s_in[%u]", gen->prefix, e->register_index);
686 if (e->sysval_semantic == VKD3D_SHADER_SV_NONE)
687 {
690 vkd3d_string_buffer_printf(buffer, " = input.shader_in_%u", i);
692 }
693 else
694 {
695 vkd3d_string_buffer_printf(buffer, " = <unhandled sysval %#x>", e->sysval_semantic);
696 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
697 "Internal compiler error: Unhandled system value %#x input.", e->sysval_semantic);
698 }
700 }
701}
702
704{
705 const struct shader_signature *signature = &gen->program->output_signature;
706 struct vkd3d_string_buffer *buffer = gen->buffer;
707 const struct signature_element *e;
708 unsigned int i;
709
710 for (i = 0; i < signature->element_count; ++i)
711 {
712 e = &signature->elements[i];
713
714 if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED)
715 continue;
716
717 switch (e->sysval_semantic)
718 {
722 vkd3d_string_buffer_printf(buffer, " output.shader_out_%u", i);
724 vkd3d_string_buffer_printf(buffer, " = %s_out[%u]", gen->prefix, e->register_index);
727 break;
728 default:
729 vkd3d_string_buffer_printf(buffer, " <unhandled sysval %#x>", e->sysval_semantic);
730 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
731 "Internal compiler error: Unhandled system value %#x input.", e->sysval_semantic);
732 }
734 }
735}
736
738{
739 enum vkd3d_shader_type type = gen->program->shader_version.type;
740
741 switch (type)
742 {
744 vkd3d_string_buffer_printf(gen->buffer, "vertex ");
745 break;
747 vkd3d_string_buffer_printf(gen->buffer, "fragment ");
748 break;
749 default:
750 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
751 "Internal compiler error: Unhandled shader type %#x.", type);
752 return;
753 }
754
755 vkd3d_string_buffer_printf(gen->buffer, "vkd3d_%s_out shader_entry(\n", gen->prefix);
756
757 if (gen->descriptor_info->descriptor_count)
758 {
759 msl_print_indent(gen->buffer, 2);
760 /* TODO: Configurable argument buffer binding location. */
762 "constant vkd3d_%s_descriptors& descriptors [[buffer(0)]],\n", gen->prefix);
763 }
764
765 msl_print_indent(gen->buffer, 2);
766 vkd3d_string_buffer_printf(gen->buffer, "vkd3d_%s_in input [[stage_in]])\n{\n", gen->prefix);
767
768 /* TODO: declare #maximum_register + 1 */
769 vkd3d_string_buffer_printf(gen->buffer, " vkd3d_vec4 %s_in[%u];\n", gen->prefix, 32);
770 vkd3d_string_buffer_printf(gen->buffer, " vkd3d_vec4 %s_out[%u];\n", gen->prefix, 32);
771 vkd3d_string_buffer_printf(gen->buffer, " vkd3d_%s_out output;\n", gen->prefix);
772
774
775 vkd3d_string_buffer_printf(gen->buffer, " %s_main(%s_in, %s_out", gen->prefix, gen->prefix, gen->prefix);
776 if (gen->descriptor_info->descriptor_count)
777 vkd3d_string_buffer_printf(gen->buffer, ", descriptors");
779
781
782 vkd3d_string_buffer_printf(gen->buffer, " return output;\n}\n");
783}
784
786{
787 const struct vkd3d_shader_instruction_array *instructions = &gen->program->instructions;
788 unsigned int i;
789
790 MESSAGE("Generating a MSL shader. This is unsupported; you get to keep all the pieces if it breaks.\n");
791
792 vkd3d_string_buffer_printf(gen->buffer, "/* Generated by %s. */\n\n", vkd3d_shader_get_version(NULL, NULL));
793
794 if (gen->program->global_flags)
795 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
796 "Internal compiler error: Unhandled global flags %#"PRIx64".", (uint64_t)gen->program->global_flags);
797
798 vkd3d_string_buffer_printf(gen->buffer, "union vkd3d_vec4\n{\n");
799 vkd3d_string_buffer_printf(gen->buffer, " uint4 u;\n");
800 vkd3d_string_buffer_printf(gen->buffer, " int4 i;\n");
801 vkd3d_string_buffer_printf(gen->buffer, " float4 f;\n};\n\n");
802
806
808 "void %s_main(thread vkd3d_vec4 *v, "
809 "thread vkd3d_vec4 *o",
810 gen->prefix);
811 if (gen->descriptor_info->descriptor_count)
812 vkd3d_string_buffer_printf(gen->buffer, ", constant vkd3d_%s_descriptors& descriptors", gen->prefix);
813 vkd3d_string_buffer_printf(gen->buffer, ")\n{\n");
814
815 ++gen->indent;
816
817 if (gen->program->temp_count)
818 {
819 msl_print_indent(gen->buffer, gen->indent);
820 vkd3d_string_buffer_printf(gen->buffer, "vkd3d_vec4 r[%u];\n\n", gen->program->temp_count);
821 }
822
823 for (i = 0; i < instructions->count; ++i)
824 {
825 msl_handle_instruction(gen, &instructions->elements[i]);
826 }
827
828 --gen->indent;
829
830 vkd3d_string_buffer_printf(gen->buffer, "}\n\n");
831
833
834 if (TRACE_ON())
836
837 if (gen->failed)
839
841
842 return VKD3D_OK;
843}
844
845static void msl_generator_cleanup(struct msl_generator *gen)
846{
849}
850
851static int msl_generator_init(struct msl_generator *gen, struct vsir_program *program,
852 const struct vkd3d_shader_compile_info *compile_info,
853 const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info,
854 struct vkd3d_shader_message_context *message_context)
855{
856 enum vkd3d_shader_type type = program->shader_version.type;
857
858 memset(gen, 0, sizeof(*gen));
859 gen->program = program;
861 if (!(gen->buffer = vkd3d_string_buffer_get(&gen->string_buffers)))
862 {
865 }
866 gen->message_context = message_context;
867 if (!(gen->prefix = msl_get_prefix(type)))
868 {
869 msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
870 "Internal compiler error: Unhandled shader type %#x.", type);
872 }
874 gen->descriptor_info = descriptor_info;
875
876 return VKD3D_OK;
877}
878
879int msl_compile(struct vsir_program *program, uint64_t config_flags,
880 const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info,
881 const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out,
882 struct vkd3d_shader_message_context *message_context)
883{
884 struct msl_generator generator;
885 int ret;
886
887 if ((ret = vsir_program_transform(program, config_flags, compile_info, message_context)) < 0)
888 return ret;
889
890 VKD3D_ASSERT(program->normalisation_level == VSIR_FULLY_NORMALISED_IO);
891
892 if ((ret = msl_generator_init(&generator, program, compile_info, descriptor_info, message_context)) < 0)
893 return ret;
894 ret = msl_generator_generate(&generator, out);
895 msl_generator_cleanup(&generator);
896
897 return ret;
898}
#define WARN(fmt,...)
Definition: precomp.h:61
#define NULL
Definition: types.h:112
UINT32 uint32_t
Definition: types.h:75
UINT64 uint64_t
Definition: types.h:77
static const WCHAR indent[]
Definition: object.c:1231
#define TRACE_ON(x)
Definition: compat.h:75
#define PRIx64
Definition: inttypes.h:29
#define va_end(v)
Definition: stdarg.h:28
#define va_start(v, l)
Definition: stdarg.h:26
char * va_list
Definition: vadefs.h:50
return ret
Definition: mutex.c:147
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble GLdouble t
Definition: gl.h:2047
GLenum src
Definition: glext.h:6340
GLuint GLenum swizzle
Definition: glext.h:9511
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLenum GLint GLuint mask
Definition: glext.h:6028
GLuint program
Definition: glext.h:6723
GLenum GLenum dst
Definition: glext.h:6340
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
enum wined3d_data_type data_type
Definition: glsl_shader.c:71
static int reg
Definition: i386-dis.c:1290
enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context)
Definition: ir.c:8324
#define e
Definition: ke_i.h:82
#define error(str)
Definition: mkdosfs.c:1605
#define MESSAGE
Definition: options.h:86
static RPC_BINDING_HANDLE binding
Definition: server.c:166
static void msl_src_init(struct msl_src *msl_src, struct msl_generator *gen, const struct vkd3d_shader_src_param *vsir_src, uint32_t mask)
Definition: msl.c:214
static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader_code *out)
Definition: msl.c:785
static void msl_print_register_name(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, const struct vkd3d_shader_register *reg)
Definition: msl.c:108
static void msl_mov(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins)
Definition: msl.c:291
static void msl_print_swizzle(struct vkd3d_string_buffer *buffer, uint32_t swizzle, uint32_t mask)
Definition: msl.c:183
static void msl_generate_cbv_declaration(struct msl_generator *gen, const struct vkd3d_shader_descriptor_info1 *cbv)
Definition: msl.c:393
static void msl_unhandled(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins)
Definition: msl.c:283
static void msl_generator_cleanup(struct msl_generator *gen)
Definition: msl.c:845
static void msl_print_write_mask(struct vkd3d_string_buffer *buffer, uint32_t write_mask)
Definition: msl.c:196
static void msl_dst_cleanup(struct msl_dst *dst, struct vkd3d_string_buffer_cache *cache)
Definition: msl.c:233
static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins)
Definition: msl.c:312
static const char * msl_get_prefix(enum vkd3d_shader_type type)
Definition: msl.c:59
static uint32_t msl_dst_init(struct msl_dst *msl_dst, struct msl_generator *gen, const struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_dst_param *vsir_dst)
Definition: msl.c:239
static void msl_generate_entrypoint(struct msl_generator *gen)
Definition: msl.c:737
static void msl_generate_descriptor_struct_declarations(struct msl_generator *gen)
Definition: msl.c:438
static void msl_src_cleanup(struct msl_src *src, struct vkd3d_string_buffer_cache *cache)
Definition: msl.c:209
static void msl_print_indent(struct vkd3d_string_buffer *buffer, unsigned int indent)
Definition: msl.c:80
int msl_compile(struct vsir_program *program, uint64_t config_flags, const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context)
Definition: msl.c:879
static void msl_generate_output_struct_declarations(struct msl_generator *gen)
Definition: msl.c:591
static void msl_ret(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins)
Definition: msl.c:306
static void msl_generate_entrypoint_epilogue(struct msl_generator *gen)
Definition: msl.c:703
static void msl_generate_entrypoint_prologue(struct msl_generator *gen)
Definition: msl.c:671
static void msl_generate_input_struct_declarations(struct msl_generator *gen)
Definition: msl.c:473
static bool msl_get_cbv_binding(const struct msl_generator *gen, unsigned int register_space, unsigned int register_idx, unsigned int *binding_idx)
Definition: msl.c:362
static void msl_generate_pixel_output_element_attribute(struct msl_generator *gen, const struct signature_element *e)
Definition: msl.c:577
static bool msl_check_shader_visibility(const struct msl_generator *gen, enum vkd3d_shader_visibility visibility)
Definition: msl.c:335
static void msl_generate_vertex_output_element_attribute(struct msl_generator *gen, const struct signature_element *e)
Definition: msl.c:560
static int msl_generator_init(struct msl_generator *gen, struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info, struct vkd3d_shader_message_context *message_context)
Definition: msl.c:851
static void msl_print_register_datatype(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, enum vkd3d_data_type data_type)
Definition: msl.c:85
#define uint32_t
Definition: nsiface.idl:61
descriptor
Definition: scsi.h:3997
#define memset(x, y, z)
Definition: compat.h:39
#define args
Definition: format.c:66
Definition: match.c:390
Definition: cache.c:41
Definition: dsound.c:943
Definition: msl.c:27
const struct vkd3d_shader_dst_param * vsir
Definition: msl.c:28
struct vkd3d_string_buffer * register_name
Definition: msl.c:29
struct vkd3d_string_buffer * mask
Definition: msl.c:30
struct vkd3d_shader_location location
Definition: msl.c:38
const struct vkd3d_shader_scan_descriptor_info1 * descriptor_info
Definition: msl.c:45
unsigned int indent
Definition: msl.c:40
const char * prefix
Definition: msl.c:41
struct vkd3d_string_buffer * buffer
Definition: msl.c:37
struct vkd3d_string_buffer_cache string_buffers
Definition: msl.c:36
bool failed
Definition: msl.c:42
struct vkd3d_shader_message_context * message_context
Definition: msl.c:39
const struct vkd3d_shader_interface_info * interface_info
Definition: msl.c:44
struct vsir_program * program
Definition: msl.c:35
Definition: msl.c:22
struct vkd3d_string_buffer * str
Definition: msl.c:23
struct vkd3d_shader_register reg
struct vkd3d_shader_instruction * elements
struct vkd3d_shader_src_param * src
struct vkd3d_shader_location location
enum vkd3d_shader_opcode opcode
struct vkd3d_shader_dst_param * dst
struct vkd3d_shader_register reg
enum vkd3d_shader_src_modifier modifiers
#define VKD3D_PRINTF_FUNC(fmt, args)
Definition: vkd3d_common.h:114
#define VKD3D_ASSERT(cond)
Definition: vkd3d_common.h:49
VKD3D_SHADER_API const char * vkd3d_shader_get_version(unsigned int *major, unsigned int *minor)
@ VKD3D_SHADER_SV_TARGET
@ VKD3D_SHADER_SV_NONE
@ VKD3D_SHADER_SV_POSITION
vkd3d_shader_visibility
Definition: vkd3d_shader.h:383
@ VKD3D_SHADER_VISIBILITY_DOMAIN
Definition: vkd3d_shader.h:391
@ VKD3D_SHADER_VISIBILITY_COMPUTE
Definition: vkd3d_shader.h:398
@ VKD3D_SHADER_VISIBILITY_PIXEL
Definition: vkd3d_shader.h:395
@ VKD3D_SHADER_VISIBILITY_ALL
Definition: vkd3d_shader.h:385
@ VKD3D_SHADER_VISIBILITY_GEOMETRY
Definition: vkd3d_shader.h:393
@ VKD3D_SHADER_VISIBILITY_VERTEX
Definition: vkd3d_shader.h:387
@ VKD3D_SHADER_VISIBILITY_HULL
Definition: vkd3d_shader.h:389
@ VKD3D_SHADER_COMPONENT_INT
@ VKD3D_SHADER_COMPONENT_UINT
@ VKD3D_SHADER_COMPONENT_FLOAT
@ VKD3D_SHADER_DESCRIPTOR_TYPE_CBV
Definition: vkd3d_shader.h:435
@ VKD3D_SHADER_BINDING_FLAG_BUFFER
Definition: vkd3d_shader.h:468
@ VKD3D_SHADER_MINIMUM_PRECISION_NONE
int vkd3d_string_buffer_vprintf(struct vkd3d_string_buffer *buffer, const char *format, va_list args)
struct vkd3d_string_buffer * vkd3d_string_buffer_get(struct vkd3d_string_buffer_cache *cache)
void vkd3d_shader_code_from_string_buffer(struct vkd3d_shader_code *code, struct vkd3d_string_buffer *buffer)
void vkd3d_shader_verror(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, enum vkd3d_shader_error error, const char *format, va_list args)
void vkd3d_string_buffer_release(struct vkd3d_string_buffer_cache *cache, struct vkd3d_string_buffer *buffer)
void vkd3d_string_buffer_cache_init(struct vkd3d_string_buffer_cache *cache)
void vkd3d_string_buffer_cache_cleanup(struct vkd3d_string_buffer_cache *cache)
int vkd3d_string_buffer_printf(struct vkd3d_string_buffer *buffer, const char *format,...)
#define vkd3d_find_struct(c, t)
#define VKD3DSI_PRECISE_XYZW
vkd3d_shader_type
@ VKD3D_SHADER_TYPE_VERTEX
@ VKD3D_SHADER_TYPE_HULL
@ VKD3D_SHADER_TYPE_GEOMETRY
@ VKD3D_SHADER_TYPE_COMPUTE
@ VKD3D_SHADER_TYPE_PIXEL
@ VKD3D_SHADER_TYPE_DOMAIN
@ VKD3DSIM_NONE
#define VKD3DSP_WRITEMASK_3
@ VKD3DSPR_CONSTBUFFER
@ VKD3DSPR_TEMP
@ VKD3DSPR_OUTPUT
@ VKD3DSPR_INPUT
vkd3d_shader_error
@ VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND
@ VKD3D_SHADER_ERROR_MSL_INTERNAL
@ VSIR_DIMENSION_VEC4
@ VKD3D_DATA_INT
@ VKD3D_DATA_UINT
@ VKD3D_DATA_FLOAT
@ VSIR_FULLY_NORMALISED_IO
static unsigned int vsir_swizzle_get_component(uint32_t swizzle, unsigned int idx)
@ VKD3DSIH_NOP
@ VKD3DSIH_DCL_OUTPUT
@ VKD3DSIH_DCL_OUTPUT_SIV
@ VKD3DSIH_DCL_INPUT
@ VKD3DSIH_MOV
@ VKD3DSIH_RET
#define vkd3d_string_buffer_trace(buffer)
static enum vkd3d_data_type vkd3d_data_type_from_component_type(enum vkd3d_shader_component_type component_type)
#define VKD3DSP_WRITEMASK_0
#define VKD3DSP_WRITEMASK_1
#define SIGNATURE_TARGET_LOCATION_UNUSED
#define VKD3DSP_WRITEMASK_2
#define VKD3D_VEC4_SIZE
@ VKD3D_ERROR_INVALID_SHADER
Definition: vkd3d_types.h:53
@ VKD3D_OK
Definition: vkd3d_types.h:43
@ VKD3D_ERROR_OUT_OF_MEMORY
Definition: vkd3d_types.h:49
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
static size_t align(size_t addr, size_t alignment)
#define const
Definition: zconf.h:233