• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2010 Intel Corporation
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #include "brw_cfg.h"
7 #include "brw_eu.h"
8 #include "brw_fs.h"
9 #include "brw_generator.h"
10 #include "brw_nir.h"
11 #include "brw_private.h"
12 #include "dev/intel_debug.h"
13 #include "util/macros.h"
14 
15 static void
brw_assign_tes_urb_setup(fs_visitor & s)16 brw_assign_tes_urb_setup(fs_visitor &s)
17 {
18    assert(s.stage == MESA_SHADER_TESS_EVAL);
19 
20    struct brw_vue_prog_data *vue_prog_data = brw_vue_prog_data(s.prog_data);
21 
22    s.first_non_payload_grf += 8 * vue_prog_data->urb_read_length;
23 
24    /* Rewrite all ATTR file references to HW_REGs. */
25    foreach_block_and_inst(block, fs_inst, inst, s.cfg) {
26       s.convert_attr_sources_to_hw_regs(inst);
27    }
28 }
29 
30 static bool
run_tes(fs_visitor & s)31 run_tes(fs_visitor &s)
32 {
33    assert(s.stage == MESA_SHADER_TESS_EVAL);
34 
35    s.payload_ = new tes_thread_payload(s);
36 
37    nir_to_brw(&s);
38 
39    if (s.failed)
40       return false;
41 
42    s.emit_urb_writes();
43 
44    brw_calculate_cfg(s);
45 
46    brw_optimize(s);
47 
48    s.assign_curb_setup();
49    brw_assign_tes_urb_setup(s);
50 
51    brw_lower_3src_null_dest(s);
52    brw_workaround_memory_fence_before_eot(s);
53    brw_workaround_emit_dummy_mov_instruction(s);
54 
55    brw_allocate_registers(s, true /* allow_spilling */);
56 
57    brw_workaround_source_arf_before_eot(s);
58 
59    return !s.failed;
60 }
61 
62 const unsigned *
brw_compile_tes(const struct brw_compiler * compiler,brw_compile_tes_params * params)63 brw_compile_tes(const struct brw_compiler *compiler,
64                 brw_compile_tes_params *params)
65 {
66    const struct intel_device_info *devinfo = compiler->devinfo;
67    nir_shader *nir = params->base.nir;
68    const struct brw_tes_prog_key *key = params->key;
69    const struct intel_vue_map *input_vue_map = params->input_vue_map;
70    struct brw_tes_prog_data *prog_data = params->prog_data;
71 
72    const bool debug_enabled = brw_should_print_shader(nir, DEBUG_TES);
73 
74    prog_data->base.base.stage = MESA_SHADER_TESS_EVAL;
75    prog_data->base.base.ray_queries = nir->info.ray_queries;
76 
77    nir->info.inputs_read = key->inputs_read;
78    nir->info.patch_inputs_read = key->patch_inputs_read;
79 
80    brw_nir_apply_key(nir, compiler, &key->base,
81                      brw_geometry_stage_dispatch_width(compiler->devinfo));
82    brw_nir_lower_tes_inputs(nir, input_vue_map);
83    brw_nir_lower_vue_outputs(nir);
84    brw_postprocess_nir(nir, compiler, debug_enabled,
85                        key->base.robust_flags);
86 
87    brw_compute_vue_map(devinfo, &prog_data->base.vue_map,
88                        nir->info.outputs_written,
89                        nir->info.separate_shader, 1);
90 
91    unsigned output_size_bytes = prog_data->base.vue_map.num_slots * 4 * 4;
92 
93    assert(output_size_bytes >= 1);
94    if (output_size_bytes > GFX7_MAX_DS_URB_ENTRY_SIZE_BYTES) {
95       params->base.error_str = ralloc_strdup(params->base.mem_ctx,
96                                              "DS outputs exceed maximum size");
97       return NULL;
98    }
99 
100    prog_data->base.clip_distance_mask =
101       ((1 << nir->info.clip_distance_array_size) - 1);
102    prog_data->base.cull_distance_mask =
103       ((1 << nir->info.cull_distance_array_size) - 1) <<
104       nir->info.clip_distance_array_size;
105 
106    prog_data->include_primitive_id =
107       BITSET_TEST(nir->info.system_values_read, SYSTEM_VALUE_PRIMITIVE_ID);
108 
109    /* URB entry sizes are stored as a multiple of 64 bytes. */
110    prog_data->base.urb_entry_size = ALIGN(output_size_bytes, 64) / 64;
111 
112    prog_data->base.urb_read_length = 0;
113 
114    STATIC_ASSERT(INTEL_TESS_PARTITIONING_INTEGER == TESS_SPACING_EQUAL - 1);
115    STATIC_ASSERT(INTEL_TESS_PARTITIONING_ODD_FRACTIONAL ==
116                  TESS_SPACING_FRACTIONAL_ODD - 1);
117    STATIC_ASSERT(INTEL_TESS_PARTITIONING_EVEN_FRACTIONAL ==
118                  TESS_SPACING_FRACTIONAL_EVEN - 1);
119 
120    prog_data->partitioning =
121       (enum intel_tess_partitioning) (nir->info.tess.spacing - 1);
122 
123    switch (nir->info.tess._primitive_mode) {
124    case TESS_PRIMITIVE_QUADS:
125       prog_data->domain = INTEL_TESS_DOMAIN_QUAD;
126       break;
127    case TESS_PRIMITIVE_TRIANGLES:
128       prog_data->domain = INTEL_TESS_DOMAIN_TRI;
129       break;
130    case TESS_PRIMITIVE_ISOLINES:
131       prog_data->domain = INTEL_TESS_DOMAIN_ISOLINE;
132       break;
133    default:
134       unreachable("invalid domain shader primitive mode");
135    }
136 
137    if (nir->info.tess.point_mode) {
138       prog_data->output_topology = INTEL_TESS_OUTPUT_TOPOLOGY_POINT;
139    } else if (nir->info.tess._primitive_mode == TESS_PRIMITIVE_ISOLINES) {
140       prog_data->output_topology = INTEL_TESS_OUTPUT_TOPOLOGY_LINE;
141    } else {
142       /* Hardware winding order is backwards from OpenGL */
143       prog_data->output_topology =
144          nir->info.tess.ccw ? INTEL_TESS_OUTPUT_TOPOLOGY_TRI_CW
145                              : INTEL_TESS_OUTPUT_TOPOLOGY_TRI_CCW;
146    }
147 
148    if (unlikely(debug_enabled)) {
149       fprintf(stderr, "TES Input ");
150       brw_print_vue_map(stderr, input_vue_map, MESA_SHADER_TESS_EVAL);
151       fprintf(stderr, "TES Output ");
152       brw_print_vue_map(stderr, &prog_data->base.vue_map,
153                         MESA_SHADER_TESS_EVAL);
154    }
155 
156    const unsigned dispatch_width = devinfo->ver >= 20 ? 16 : 8;
157    fs_visitor v(compiler, &params->base, &key->base,
158                 &prog_data->base.base, nir, dispatch_width,
159                 params->base.stats != NULL, debug_enabled);
160    if (!run_tes(v)) {
161       params->base.error_str =
162          ralloc_strdup(params->base.mem_ctx, v.fail_msg);
163       return NULL;
164    }
165 
166    assert(v.payload().num_regs % reg_unit(devinfo) == 0);
167    prog_data->base.base.dispatch_grf_start_reg = v.payload().num_regs / reg_unit(devinfo);
168 
169    prog_data->base.dispatch_mode = INTEL_DISPATCH_MODE_SIMD8;
170 
171    brw_generator g(compiler, &params->base,
172                   &prog_data->base.base, MESA_SHADER_TESS_EVAL);
173    if (unlikely(debug_enabled)) {
174       g.enable_debug(ralloc_asprintf(params->base.mem_ctx,
175                                      "%s tessellation evaluation shader %s",
176                                      nir->info.label ? nir->info.label
177                                                      : "unnamed",
178                                      nir->info.name));
179    }
180 
181    g.generate_code(v.cfg, dispatch_width, v.shader_stats,
182                    v.performance_analysis.require(), params->base.stats);
183 
184    g.add_const_data(nir->constant_data, nir->constant_data_size);
185 
186    return g.get_assembly();
187 }
188 
189