xref: /aosp_15_r20/external/mesa3d/src/microsoft/compiler/dxil_module.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © Microsoft Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24  /*
25   * See the DirectX Shader Compiler for documentation for DXIL details:
26   * https://github.com/Microsoft/DirectXShaderCompiler/blob/master/docs/DXIL.rst
27   */
28 
29 #ifndef DXIL_MODULE_H
30 #define DXIL_MODULE_H
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
36 #include "dxil_buffer.h"
37 #include "dxil_signature.h"
38 
39 #include "util/list.h"
40 
41 
42 #define DXIL_SHADER_MAX_IO_ROWS 128
43 
44 enum dxil_shader_kind {
45    DXIL_PIXEL_SHADER = 0,
46    DXIL_VERTEX_SHADER = 1,
47    DXIL_GEOMETRY_SHADER = 2,
48    DXIL_HULL_SHADER = 3,
49    DXIL_DOMAIN_SHADER = 4,
50    DXIL_COMPUTE_SHADER = 5,
51 };
52 
53 extern int debug_dxil;
54 
55 enum dxil_debug_flags {
56    DXIL_DEBUG_VERBOSE    = 1 << 0,
57    DXIL_DEBUG_DUMP_BLOB  = 1 << 1,
58    DXIL_DEBUG_TRACE      = 1 << 2,
59    DXIL_DEBUG_DUMP_MODULE = 1 << 3,
60 };
61 
62 enum dxil_bin_opcode {
63    DXIL_BINOP_ADD = 0,
64    DXIL_BINOP_SUB = 1,
65    DXIL_BINOP_MUL = 2,
66    DXIL_BINOP_UDIV = 3,
67    DXIL_BINOP_SDIV = 4,
68    DXIL_BINOP_UREM = 5,
69    DXIL_BINOP_SREM = 6,
70    DXIL_BINOP_SHL = 7,
71    DXIL_BINOP_LSHR = 8,
72    DXIL_BINOP_ASHR = 9,
73    DXIL_BINOP_AND = 10,
74    DXIL_BINOP_OR = 11,
75    DXIL_BINOP_XOR = 12,
76    DXIL_BINOP_INSTR_COUNT
77 };
78 
79 enum dxil_cast_opcode {
80    DXIL_CAST_TRUNC = 0,
81    DXIL_CAST_ZEXT = 1,
82    DXIL_CAST_SEXT = 2,
83    DXIL_CAST_FPTOUI = 3,
84    DXIL_CAST_FPTOSI = 4,
85    DXIL_CAST_UITOFP = 5,
86    DXIL_CAST_SITOFP = 6,
87    DXIL_CAST_FPTRUNC = 7,
88    DXIL_CAST_FPEXT = 8,
89    DXIL_CAST_PTRTOINT = 9,
90    DXIL_CAST_INTTOPTR = 10,
91    DXIL_CAST_BITCAST = 11,
92    DXIL_CAST_ADDRSPACECAST = 12,
93    DXIL_CAST_INSTR_COUNT
94 };
95 
96 enum dxil_cmp_pred {
97    DXIL_FCMP_FALSE = 0,
98    DXIL_FCMP_OEQ = 1,
99    DXIL_FCMP_OGT = 2,
100    DXIL_FCMP_OGE = 3,
101    DXIL_FCMP_OLT = 4,
102    DXIL_FCMP_OLE = 5,
103    DXIL_FCMP_ONE = 6,
104    DXIL_FCMP_ORD = 7,
105    DXIL_FCMP_UNO = 8,
106    DXIL_FCMP_UEQ = 9,
107    DXIL_FCMP_UGT = 10,
108    DXIL_FCMP_UGE = 11,
109    DXIL_FCMP_ULT = 12,
110    DXIL_FCMP_ULE = 13,
111    DXIL_FCMP_UNE = 14,
112    DXIL_FCMP_TRUE = 15,
113    DXIL_ICMP_EQ = 32,
114    DXIL_ICMP_NE = 33,
115    DXIL_ICMP_UGT = 34,
116    DXIL_ICMP_UGE = 35,
117    DXIL_ICMP_ULT = 36,
118    DXIL_ICMP_ULE = 37,
119    DXIL_ICMP_SGT = 38,
120    DXIL_ICMP_SGE = 39,
121    DXIL_ICMP_SLT = 40,
122    DXIL_ICMP_SLE = 41,
123    DXIL_CMP_INSTR_COUNT
124 };
125 
126 enum dxil_opt_flags {
127   DXIL_UNSAFE_ALGEBRA = (1 << 0),
128   DXIL_NO_NANS = (1 << 1),
129   DXIL_NO_INFS = (1 << 2),
130   DXIL_NO_SIGNED_ZEROS = (1 << 3),
131   DXIL_ALLOW_RECIPROCAL = (1 << 4)
132 };
133 
134 struct dxil_features {
135    uint64_t doubles : 1,
136             cs_4x_raw_sb : 1,
137             uavs_at_every_stage : 1,
138             use_64uavs : 1,
139             min_precision : 1,
140             dx11_1_double_extensions : 1,
141             dx11_1_shader_extensions : 1,
142             dx9_comparison_filtering : 1,
143             tiled_resources : 1,
144             stencil_ref : 1,
145             inner_coverage : 1,
146             typed_uav_load_additional_formats : 1,
147             rovs : 1,
148             array_layer_from_vs_or_ds : 1,
149             wave_ops : 1,
150             int64_ops : 1,
151             view_id : 1,
152             barycentrics : 1,
153             native_low_precision : 1,
154             shading_rate : 1,
155             raytracing_tier_1_1 : 1,
156             sampler_feedback : 1,
157             atomic_int64_typed : 1,
158             atomic_int64_tgsm : 1,
159             derivatives_in_mesh_or_amp : 1,
160             resource_descriptor_heap_indexing : 1,
161             sampler_descriptor_heap_indexing : 1,
162             unnamed : 1,
163             atomic_int64_heap_resource : 1,
164             advanced_texture_ops : 1,
165             writable_msaa : 1,
166             sample_cmp_bias_gradient : 1,
167             extended_command_info : 1;
168 };
169 
170 struct dxil_shader_info {
171    unsigned has_out_position:1;
172    unsigned has_out_depth:1;
173    unsigned has_per_sample_input:1;
174 };
175 
176 struct dxil_func_def {
177    struct list_head head;
178    const struct dxil_func *func;
179 
180    struct list_head instr_list;
181    int *basic_block_ids; /* maps from "user" ids to LLVM ids */
182    size_t num_basic_block_ids;
183    unsigned curr_block;
184 };
185 
186 struct dxil_module {
187    void *ralloc_ctx;
188    enum dxil_shader_kind shader_kind;
189    unsigned major_version, minor_version;
190    unsigned major_validator, minor_validator;
191    struct dxil_features feats;
192    unsigned raw_and_structured_buffers : 1;
193    struct dxil_shader_info info;
194 
195    struct dxil_buffer buf;
196 
197    /* The number of entries in the arrays below */
198    unsigned num_sig_inputs;
199    unsigned num_sig_outputs;
200    unsigned num_sig_patch_consts;
201 
202    /* The number of "vectors" of elements. This is used to determine the sizes
203     * of the dependency tables.
204     */
205    unsigned num_psv_inputs;
206    unsigned num_psv_outputs[4];
207    unsigned num_psv_patch_consts;
208 
209    struct dxil_signature_record inputs[DXIL_SHADER_MAX_IO_ROWS];
210    struct dxil_signature_record outputs[DXIL_SHADER_MAX_IO_ROWS];
211    struct dxil_signature_record patch_consts[DXIL_SHADER_MAX_IO_ROWS];
212 
213    /* This array is indexed using var->data.driver_location, which
214     * is not a direct match to IO rows, since a row is a vec4, and
215     * variables can occupy less than that, and several vars can
216     * be packed in a row. Hence the x4, but I doubt we can end up
217     * with more than 80x4 variables in practice. Maybe this array
218     * should be allocated dynamically based on on the maximum
219     * driver_location across all input vars.
220     */
221    unsigned input_mappings[DXIL_SHADER_MAX_IO_ROWS * 4];
222 
223    struct dxil_psv_signature_element psv_inputs[DXIL_SHADER_MAX_IO_ROWS];
224    struct dxil_psv_signature_element psv_outputs[DXIL_SHADER_MAX_IO_ROWS];
225    struct dxil_psv_signature_element psv_patch_consts[DXIL_SHADER_MAX_IO_ROWS];
226 
227    struct _mesa_string_buffer *sem_string_table;
228    struct dxil_psv_sem_index_table sem_index_table;
229 
230    /* These tables are a bitmask per input, with one bit per output
231     * to indicate whether or not that input contributes to the output.
232     * Each input's bitmask size is rounded up to a uint32 (DWORD),
233     * so a bitbask for one output component is the same as for 8 output vec4s.
234     * Sizes are in number of uint32s.
235     * Meaning of each array entry depends on shader stage.
236     * GS: [i] = output stream index
237     * HS: [0] = control point outputs, [1] = patch constant outputs
238     * DS: [0] = control point inputs, [1] = patch constant inputs (only for io table)
239     * PS/VS: only 0 is used. */
240    uint32_t *serialized_dependency_table;
241    uint32_t *viewid_dependency_table[4];
242    uint32_t *io_dependency_table[4];
243    uint32_t dependency_table_dwords_per_input[4];
244    uint32_t io_dependency_table_size[4];
245    uint32_t serialized_dependency_table_size;
246 
247    struct {
248       unsigned abbrev_width;
249       intptr_t offset;
250    } blocks[16];
251    size_t num_blocks;
252 
253    struct list_head type_list;
254    struct list_head gvar_list;
255    struct list_head func_list;
256    struct list_head func_def_list;
257    struct list_head attr_set_list;
258    struct list_head const_list;
259    struct list_head mdnode_list;
260    struct list_head md_named_node_list;
261    const struct dxil_type *void_type;
262    const struct dxil_type *int1_type, *int8_type, *int16_type,
263                           *int32_type, *int64_type;
264    const struct dxil_type *float16_type, *float32_type, *float64_type;
265 
266    struct rb_tree *functions;
267 
268    struct dxil_func_def *cur_emitting_func;
269 };
270 
271 struct dxil_instr;
272 struct dxil_value;
273 
274 void
275 dxil_module_init(struct dxil_module *m, void *ralloc_ctx);
276 
277 void
278 dxil_module_release(struct dxil_module *m);
279 
280 const struct dxil_value *
281 dxil_add_global_var(struct dxil_module *m, const char *name,
282                     const struct dxil_type *type,
283                     enum dxil_address_space as, int align,
284                     const struct dxil_value *value);
285 
286 const struct dxil_value *
287 dxil_add_global_ptr_var(struct dxil_module *m, const char *name,
288                         const struct dxil_type *type,
289                         enum dxil_address_space as, int align,
290                         const struct dxil_value *value);
291 
292 struct dxil_func_def *
293 dxil_add_function_def(struct dxil_module *m, const char *name,
294                       const struct dxil_type *type, unsigned num_blocks,
295                       const char *const *attr_keys, const char *const *attr_values);
296 
297 const struct dxil_func *
298 dxil_add_function_decl(struct dxil_module *m, const char *name,
299                        const struct dxil_type *type,
300                        enum dxil_attr_kind attr);
301 
302 const struct dxil_type *
303 dxil_module_get_void_type(struct dxil_module *m);
304 
305 const struct dxil_type *
306 dxil_module_get_int_type(struct dxil_module *m, unsigned bit_size);
307 
308 const struct dxil_type *
309 dxil_module_get_float_type(struct dxil_module *m, unsigned bit_size);
310 
311 const struct dxil_type *
312 dxil_module_get_pointer_type(struct dxil_module *m,
313                              const struct dxil_type *target);
314 
315 const struct dxil_type *
316 dxil_get_overload_type(struct dxil_module *mod, enum overload_type overload);
317 
318 const struct dxil_type *
319 dxil_module_get_handle_type(struct dxil_module *m);
320 
321 const struct dxil_type *
322 dxil_module_get_cbuf_ret_type(struct dxil_module *mod, enum overload_type overload);
323 
324 const struct dxil_type *
325 dxil_module_get_split_double_ret_type(struct dxil_module *mod);
326 
327 const struct dxil_type *
328 dxil_module_get_res_type(struct dxil_module *m, enum dxil_resource_kind kind,
329                          enum dxil_component_type comp_type, unsigned num_comps,
330                          bool readwrite);
331 
332 const struct dxil_type *
333 dxil_module_get_resret_type(struct dxil_module *m, enum overload_type overload);
334 
335 const struct dxil_type *
336 dxil_module_get_dimret_type(struct dxil_module *m);
337 
338 const struct dxil_type *
339 dxil_module_get_samplepos_type(struct dxil_module *m);
340 
341 const struct dxil_type *
342 dxil_module_get_res_bind_type(struct dxil_module *m);
343 
344 const struct dxil_type *
345 dxil_module_get_res_props_type(struct dxil_module *m);
346 
347 const struct dxil_type *
348 dxil_module_get_fouri32_type(struct dxil_module *m);
349 
350 const struct dxil_type *
351 dxil_module_get_struct_type(struct dxil_module *m,
352                             const char *name,
353                             const struct dxil_type **elem_types,
354                             size_t num_elem_types);
355 
356 const struct dxil_type *
357 dxil_module_get_array_type(struct dxil_module *m,
358                            const struct dxil_type *elem_type,
359                            size_t num_elems);
360 
361 const struct dxil_type *
362 dxil_module_get_vector_type(struct dxil_module *m,
363                             const struct dxil_type *elem_type,
364                             size_t num_elems);
365 
366 const struct dxil_type *
367 dxil_module_add_function_type(struct dxil_module *m,
368                               const struct dxil_type *ret_type,
369                               const struct dxil_type **arg_types,
370                               size_t num_arg_types);
371 
372 nir_alu_type
373 dxil_type_to_nir_type(const struct dxil_type *type);
374 
375 bool
376 dxil_value_type_equal_to(const struct dxil_value *value,
377                          const struct dxil_type *lhs);
378 
379 bool
380 dxil_value_type_bitsize_equal_to(const struct dxil_value *value, unsigned bitsize);
381 
382 const struct dxil_type *
383 dxil_value_get_type(const struct dxil_value *value);
384 
385 const struct dxil_value *
386 dxil_module_get_int1_const(struct dxil_module *m, bool value);
387 
388 const struct dxil_value *
389 dxil_module_get_int8_const(struct dxil_module *m, int8_t value);
390 
391 const struct dxil_value *
392 dxil_module_get_int16_const(struct dxil_module *m, int16_t value);
393 
394 const struct dxil_value *
395 dxil_module_get_int32_const(struct dxil_module *m, int32_t value);
396 
397 const struct dxil_value *
398 dxil_module_get_int64_const(struct dxil_module *m, int64_t value);
399 
400 const struct dxil_value *
401 dxil_module_get_int_const(struct dxil_module *m, intmax_t value,
402                           unsigned bit_size);
403 
404 const struct dxil_value *
405 dxil_module_get_float16_const(struct dxil_module *m, uint16_t);
406 
407 const struct dxil_value *
408 dxil_module_get_float_const(struct dxil_module *m, float value);
409 
410 const struct dxil_value *
411 dxil_module_get_double_const(struct dxil_module *m, double value);
412 
413 const struct dxil_value *
414 dxil_module_get_array_const(struct dxil_module *m, const struct dxil_type *type,
415                             const struct dxil_value **values);
416 
417 const struct dxil_value *
418 dxil_module_get_vector_const(struct dxil_module *m, const struct dxil_type *type,
419                              const struct dxil_value **values);
420 
421 const struct dxil_value *
422 dxil_module_get_struct_const(struct dxil_module *m, const struct dxil_type *type,
423                              const struct dxil_value **values);
424 
425 const struct dxil_value *
426 dxil_module_get_undef(struct dxil_module *m, const struct dxil_type *type);
427 
428 const struct dxil_value *
429 dxil_module_get_res_bind_const(struct dxil_module *m,
430                                uint32_t lower_bound,
431                                uint32_t upper_bound,
432                                uint32_t space,
433                                uint8_t class);
434 
435 const struct dxil_value *
436 dxil_module_get_res_props_const(struct dxil_module *m,
437                                 enum dxil_resource_class class,
438                                 const struct dxil_mdnode *mdnode);
439 
440 const struct dxil_value *
441 dxil_module_get_srv_res_props_const(struct dxil_module *m,
442                                     const nir_tex_instr *tex);
443 
444 const struct dxil_value *
445 dxil_module_get_sampler_res_props_const(struct dxil_module *m,
446                                         bool is_shadow);
447 
448 const struct dxil_value *
449 dxil_module_get_uav_res_props_const(struct dxil_module *m,
450                                     nir_intrinsic_instr *intr);
451 
452 const struct dxil_value *
453 dxil_module_get_buffer_res_props_const(struct dxil_module *m,
454                                        enum dxil_resource_class class,
455                                        enum dxil_resource_kind kind);
456 
457 const struct dxil_mdnode *
458 dxil_get_metadata_string(struct dxil_module *m, const char *str);
459 
460 const struct dxil_mdnode *
461 dxil_get_metadata_value(struct dxil_module *m, const struct dxil_type *type,
462                         const struct dxil_value *value);
463 
464 const struct dxil_mdnode *
465 dxil_get_metadata_func(struct dxil_module *m, const struct dxil_func *func);
466 
467 const struct dxil_mdnode *
468 dxil_get_metadata_int1(struct dxil_module *m, bool value);
469 
470 const struct dxil_mdnode *
471 dxil_get_metadata_int8(struct dxil_module *m, int8_t value);
472 
473 const struct dxil_mdnode *
474 dxil_get_metadata_int32(struct dxil_module *m, int32_t value);
475 
476 const struct dxil_mdnode *
477 dxil_get_metadata_int64(struct dxil_module *m, int64_t value);
478 
479 const struct dxil_mdnode *
480 dxil_get_metadata_float32(struct dxil_module *m, float value);
481 
482 const struct dxil_mdnode *
483 dxil_get_metadata_node(struct dxil_module *m,
484                        const struct dxil_mdnode *subnodes[],
485                        size_t num_subnodes);
486 
487 bool
488 dxil_add_metadata_named_node(struct dxil_module *m, const char *name,
489                              const struct dxil_mdnode *subnodes[],
490                              size_t num_subnodes);
491 
492 const struct dxil_value *
493 dxil_emit_binop(struct dxil_module *m, enum dxil_bin_opcode opcode,
494                 const struct dxil_value *op0, const struct dxil_value *op1,
495                 enum dxil_opt_flags flags);
496 
497 const struct dxil_value *
498 dxil_emit_cmp(struct dxil_module *m, enum dxil_cmp_pred pred,
499               const struct dxil_value *op0, const struct dxil_value *op1);
500 
501 const struct dxil_value *
502 dxil_emit_select(struct dxil_module *m,
503                 const struct dxil_value *op0,
504                 const struct dxil_value *op1,
505                 const struct dxil_value *op2);
506 
507 const struct dxil_value *
508 dxil_emit_extractval(struct dxil_module *m, const struct dxil_value *src,
509                      const unsigned int index);
510 
511 const struct dxil_value *
512 dxil_emit_cast(struct dxil_module *m, enum dxil_cast_opcode opcode,
513                const struct dxil_type *type,
514                const struct dxil_value *value);
515 
516 bool
517 dxil_emit_branch(struct dxil_module *m, const struct dxil_value *cond,
518                  unsigned true_block, unsigned false_block);
519 
520 const struct dxil_value *
521 dxil_instr_get_return_value(struct dxil_instr *instr);
522 
523 struct dxil_instr *
524 dxil_emit_phi(struct dxil_module *m, const struct dxil_type *type);
525 
526 bool
527 dxil_phi_add_incoming(struct dxil_instr *instr,
528                       const struct dxil_value *incoming_values[],
529                       const unsigned incoming_blocks[],
530                       size_t num_incoming);
531 
532 const struct dxil_value *
533 dxil_emit_call(struct dxil_module *m,
534                const struct dxil_func *func,
535                const struct dxil_value **args, size_t num_args);
536 
537 bool
538 dxil_emit_call_void(struct dxil_module *m,
539                     const struct dxil_func *func,
540                     const struct dxil_value **args, size_t num_args);
541 
542 bool
543 dxil_emit_ret_void(struct dxil_module *m);
544 
545 const struct dxil_value *
546 dxil_emit_alloca(struct dxil_module *m, const struct dxil_type *alloc_type,
547                  const struct dxil_value *size,
548                  unsigned int align);
549 
550 const struct dxil_value *
551 dxil_emit_gep_inbounds(struct dxil_module *m,
552                        const struct dxil_value **operands,
553                        size_t num_operands);
554 
555 const struct dxil_value *
556 dxil_emit_load(struct dxil_module *m, const struct dxil_value *ptr,
557                unsigned align,
558                bool is_volatile);
559 
560 bool
561 dxil_emit_store(struct dxil_module *m, const struct dxil_value *value,
562                 const struct dxil_value *ptr, unsigned align,
563                 bool is_volatile);
564 
565 const struct dxil_value *
566 dxil_emit_cmpxchg(struct dxil_module *m, const struct dxil_value *cmpval,
567                   const struct dxil_value *newval,
568                   const struct dxil_value *ptr, bool is_volatile,
569                   enum dxil_atomic_ordering ordering,
570                   enum dxil_sync_scope syncscope);
571 
572 const struct dxil_value *
573 dxil_emit_atomicrmw(struct dxil_module *m, const struct dxil_value *value,
574                     const struct dxil_value *ptr, enum dxil_rmw_op op,
575                     bool is_volatile, enum dxil_atomic_ordering ordering,
576                     enum dxil_sync_scope syncscope);
577 
578 bool
579 dxil_emit_module(struct dxil_module *m);
580 
581 #ifdef __cplusplus
582 }
583 #endif
584 
585 #endif
586