1 #include "sfn_nir.h"
2
r600_lower_tess_io_filter(const nir_instr * instr,gl_shader_stage stage)3 bool r600_lower_tess_io_filter(const nir_instr *instr, gl_shader_stage stage)
4 {
5 if (instr->type != nir_instr_type_intrinsic)
6 return false;
7
8 nir_intrinsic_instr *op = nir_instr_as_intrinsic(instr);
9 switch (op->intrinsic) {
10 case nir_intrinsic_load_input:
11 return stage == MESA_SHADER_TESS_CTRL || stage == MESA_SHADER_TESS_EVAL;
12 case nir_intrinsic_load_output:
13 case nir_intrinsic_load_per_vertex_input:
14 case nir_intrinsic_load_per_vertex_output:
15 case nir_intrinsic_store_per_vertex_output:
16 case nir_intrinsic_load_patch_vertices_in:
17 case nir_intrinsic_load_tess_level_outer:
18 case nir_intrinsic_load_tess_level_inner:
19 return true;
20 case nir_intrinsic_store_output:
21 return stage == MESA_SHADER_TESS_CTRL || stage == MESA_SHADER_VERTEX;
22 default:
23 ;
24 }
25 return false;
26 }
27
28 static nir_ssa_def *
emit_load_param_base(nir_builder * b,nir_intrinsic_op op)29 emit_load_param_base(nir_builder *b, nir_intrinsic_op op)
30 {
31 nir_intrinsic_instr *result = nir_intrinsic_instr_create(b->shader, op);
32 nir_ssa_dest_init(&result->instr, &result->dest,
33 4, 32, NULL);
34 nir_builder_instr_insert(b, &result->instr);
35 return &result->dest.ssa;
36 }
37
get_tcs_varying_offset(nir_intrinsic_instr * op)38 static int get_tcs_varying_offset(nir_intrinsic_instr *op)
39 {
40 unsigned location = nir_intrinsic_io_semantics(op).location;
41
42 switch (location) {
43 case VARYING_SLOT_POS:
44 return 0;
45 case VARYING_SLOT_PSIZ:
46 return 0x10;
47 case VARYING_SLOT_CLIP_DIST0:
48 return 0x20;
49 case VARYING_SLOT_CLIP_DIST1:
50 return 0x30;
51 case VARYING_SLOT_TESS_LEVEL_OUTER:
52 return 0;
53 case VARYING_SLOT_TESS_LEVEL_INNER:
54 return 0x10;
55 default:
56 if (location >= VARYING_SLOT_VAR0 &&
57 location <= VARYING_SLOT_VAR31)
58 return 0x10 * (location - VARYING_SLOT_VAR0) + 0x40;
59
60 if (location >= VARYING_SLOT_PATCH0) {
61 return 0x10 * (location - VARYING_SLOT_PATCH0) + 0x20;
62 }
63 }
64 return 0;
65 }
66
67 static inline nir_ssa_def *
r600_umad_24(nir_builder * b,nir_ssa_def * op1,nir_ssa_def * op2,nir_ssa_def * op3)68 r600_umad_24(nir_builder *b, nir_ssa_def *op1, nir_ssa_def *op2, nir_ssa_def *op3)
69 {
70 return nir_build_alu(b, nir_op_umad24, op1, op2, op3, NULL);
71 }
72
73 static inline nir_ssa_def *
r600_tcs_base_address(nir_builder * b,nir_ssa_def * param_base,nir_ssa_def * rel_patch_id)74 r600_tcs_base_address(nir_builder *b, nir_ssa_def *param_base, nir_ssa_def *rel_patch_id)
75 {
76 return r600_umad_24(b, nir_channel(b, param_base, 0),
77 rel_patch_id,
78 nir_channel(b, param_base, 3));
79 }
80
81
82 static nir_ssa_def *
emil_lsd_in_addr(nir_builder * b,nir_ssa_def * base,nir_ssa_def * patch_id,nir_intrinsic_instr * op)83 emil_lsd_in_addr(nir_builder *b, nir_ssa_def *base, nir_ssa_def *patch_id, nir_intrinsic_instr *op)
84 {
85 nir_ssa_def *addr = nir_build_alu(b, nir_op_umul24,
86 nir_channel(b, base, 0),
87 patch_id, NULL, NULL);
88
89 auto idx1 = nir_src_as_const_value(op->src[0]);
90 if (!idx1 || idx1->u32 != 0)
91 addr = r600_umad_24(b, nir_channel(b, base, 1),
92 op->src[0].ssa, addr);
93
94 auto offset = nir_imm_int(b, get_tcs_varying_offset(op));
95
96 auto idx2 = nir_src_as_const_value(op->src[1]);
97 if (!idx2 || idx2->u32 != 0)
98 offset = nir_iadd(b, offset, nir_ishl(b, op->src[1].ssa, nir_imm_int(b, 4)));
99
100 return nir_iadd(b, addr, offset);
101 }
102
103 static nir_ssa_def *
emil_lsd_out_addr(nir_builder * b,nir_ssa_def * base,nir_ssa_def * patch_id,nir_intrinsic_instr * op,nir_variable_mode mode,int src_offset)104 emil_lsd_out_addr(nir_builder *b, nir_ssa_def *base, nir_ssa_def *patch_id, nir_intrinsic_instr *op, nir_variable_mode mode, int src_offset)
105 {
106
107 nir_ssa_def *addr1 = r600_umad_24(b, nir_channel(b, base, 0),
108 patch_id,
109 nir_channel(b, base, 2));
110 nir_ssa_def *addr2 = r600_umad_24(b, nir_channel(b, base, 1),
111 op->src[src_offset].ssa, addr1);
112 int offset = get_tcs_varying_offset(op);
113 return nir_iadd(b, nir_iadd(b, addr2,
114 nir_ishl(b, op->src[src_offset + 1].ssa, nir_imm_int(b,4))),
115 nir_imm_int(b, offset));
116 }
117
load_offset_group(nir_builder * b,int ncomponents)118 static nir_ssa_def *load_offset_group(nir_builder *b, int ncomponents)
119 {
120 switch (ncomponents) {
121 /* tess outer offsets */
122 case 1: return nir_imm_int(b, 0);
123 case 2: return nir_imm_ivec2(b, 0, 4);
124 case 3: return r600_imm_ivec3(b, 0, 4, 8);
125 case 4: return nir_imm_ivec4(b, 0, 4, 8, 12);
126 /* tess inner offsets */
127 case 5: return nir_imm_int(b, 16);
128 case 6: return nir_imm_ivec2(b, 16, 20);
129 default:
130 debug_printf("Got %d components\n", ncomponents);
131 unreachable("Unsupported component count");
132 }
133 }
134
load_offset_group_from_mask(nir_builder * b,uint32_t mask)135 static nir_ssa_def *load_offset_group_from_mask(nir_builder *b, uint32_t mask)
136 {
137 auto full_mask = nir_imm_ivec4(b, 0, 4, 8, 12);
138 return nir_channels(b, full_mask, mask);
139 }
140
141 struct MaskQuery {
142 uint32_t mask;
143 uint32_t ssa_index;
144 nir_alu_instr *alu;
145 int index;
146 uint32_t full_mask;
147 };
148
update_alu_mask(nir_src * src,void * data)149 static bool update_alu_mask(nir_src *src, void *data)
150 {
151 auto mq = reinterpret_cast<MaskQuery *>(data);
152
153 if (mq->ssa_index == src->ssa->index) {
154 mq->mask |= nir_alu_instr_src_read_mask(mq->alu, mq->index);
155 }
156 ++mq->index;
157
158 return mq->mask != mq->full_mask;
159 }
160
get_dest_usee_mask(nir_intrinsic_instr * op)161 static uint32_t get_dest_usee_mask(nir_intrinsic_instr *op)
162 {
163 assert(op->dest.is_ssa);
164
165 MaskQuery mq = {0};
166 mq.full_mask = (1 << nir_dest_num_components(op->dest)) - 1;
167
168 nir_foreach_use(use_src, &op->dest.ssa) {
169 auto use_instr = use_src->parent_instr;
170 mq.ssa_index = use_src->ssa->index;
171
172 switch (use_instr->type) {
173 case nir_instr_type_alu: {
174 mq.alu = nir_instr_as_alu(use_instr);
175 mq.index = 0;
176 if (!nir_foreach_src(use_instr, update_alu_mask, &mq))
177 return 0xf;
178 break;
179 }
180 case nir_instr_type_intrinsic: {
181 auto intr = nir_instr_as_intrinsic(use_instr);
182 switch (intr->intrinsic) {
183 case nir_intrinsic_store_output:
184 case nir_intrinsic_store_per_vertex_output:
185 mq.mask |= nir_intrinsic_write_mask(intr) << nir_intrinsic_component(intr);
186 break;
187 case nir_intrinsic_store_scratch:
188 case nir_intrinsic_store_local_shared_r600:
189 mq.mask |= nir_intrinsic_write_mask(intr);
190 break;
191 default:
192 return 0xf;
193 }
194 break;
195 }
196 default:
197 return 0xf;
198 }
199
200 }
201 return mq.mask;
202 }
203
replace_load_instr(nir_builder * b,nir_intrinsic_instr * op,nir_ssa_def * addr)204 static void replace_load_instr(nir_builder *b, nir_intrinsic_instr *op, nir_ssa_def *addr)
205 {
206 uint32_t mask = get_dest_usee_mask(op);
207 if (mask) {
208 nir_ssa_def *addr_outer = nir_iadd(b, addr, load_offset_group_from_mask(b, mask));
209 if (nir_intrinsic_component(op))
210 addr_outer = nir_iadd(b, addr_outer, nir_imm_int(b, 4 * nir_intrinsic_component(op)));
211
212 auto new_load = nir_load_local_shared_r600(b, 32, addr_outer);
213
214 auto undef = nir_ssa_undef(b, 1, 32);
215 int comps = nir_dest_num_components(op->dest);
216 nir_ssa_def *remix[4] = {undef, undef, undef, undef};
217
218 int chan = 0;
219 for (int i = 0; i < comps; ++i) {
220 if (mask & (1 << i)) {
221 remix[i] = nir_channel(b, new_load, chan++);
222 }
223 }
224 auto new_load_remixed = nir_vec(b, remix, comps);
225 nir_ssa_def_rewrite_uses(&op->dest.ssa, new_load_remixed);
226 }
227 nir_instr_remove(&op->instr);
228 }
229
230 static nir_ssa_def *
r600_load_rel_patch_id(nir_builder * b)231 r600_load_rel_patch_id(nir_builder *b)
232 {
233 auto patch_id = nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_tcs_rel_patch_id_r600);
234 nir_ssa_dest_init(&patch_id->instr, &patch_id->dest,
235 1, 32, NULL);
236 nir_builder_instr_insert(b, &patch_id->instr);
237 return &patch_id->dest.ssa;
238 }
239
240 static void
emit_store_lds(nir_builder * b,nir_intrinsic_instr * op,nir_ssa_def * addr)241 emit_store_lds(nir_builder *b, nir_intrinsic_instr *op, nir_ssa_def *addr)
242 {
243 uint32_t orig_writemask = nir_intrinsic_write_mask(op) << nir_intrinsic_component(op);
244
245 for (int i = 0; i < 2; ++i) {
246 unsigned test_mask = (0x3 << 2 * i);
247 if (!(orig_writemask & test_mask))
248 continue;
249
250 uint32_t writemask = test_mask >> nir_intrinsic_component(op);
251
252 auto store_tcs_out = nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_local_shared_r600);
253 nir_intrinsic_set_write_mask(store_tcs_out, writemask);
254 store_tcs_out->src[0] = nir_src_for_ssa(op->src[0].ssa);
255 store_tcs_out->num_components = store_tcs_out->src[0].ssa->num_components;
256 bool start_even = (orig_writemask & (1u << (2 * i)));
257
258 auto addr2 = nir_iadd(b, addr, nir_imm_int(b, 8 * i + (start_even ? 0 : 4)));
259 store_tcs_out->src[1] = nir_src_for_ssa(addr2);
260
261 nir_builder_instr_insert(b, &store_tcs_out->instr);
262 }
263 }
264
265 static nir_ssa_def *
emil_tcs_io_offset(nir_builder * b,nir_ssa_def * addr,nir_intrinsic_instr * op,int src_offset)266 emil_tcs_io_offset(nir_builder *b, nir_ssa_def *addr, nir_intrinsic_instr *op, int src_offset)
267 {
268 int offset = get_tcs_varying_offset(op);
269 return nir_iadd(b, nir_iadd(b, addr,
270 nir_ishl(b, op->src[src_offset].ssa, nir_imm_int(b,4))),
271 nir_imm_int(b, offset));
272 }
273
274
275 inline unsigned
outer_tf_components(pipe_prim_type prim_type)276 outer_tf_components(pipe_prim_type prim_type)
277 {
278 switch (prim_type) {
279 case PIPE_PRIM_LINES: return 2;
280 case PIPE_PRIM_TRIANGLES: return 3;
281 case PIPE_PRIM_QUADS: return 4;
282 default:
283 return 0;
284 }
285 }
286
287
288
289 static bool
r600_lower_tess_io_impl(nir_builder * b,nir_instr * instr,enum pipe_prim_type prim_type)290 r600_lower_tess_io_impl(nir_builder *b, nir_instr *instr, enum pipe_prim_type prim_type)
291 {
292 static nir_ssa_def *load_in_param_base = nullptr;
293 static nir_ssa_def *load_out_param_base = nullptr;
294
295 b->cursor = nir_before_instr(instr);
296 nir_intrinsic_instr *op = nir_instr_as_intrinsic(instr);
297
298 if (b->shader->info.stage == MESA_SHADER_TESS_CTRL) {
299 load_in_param_base = emit_load_param_base(b, nir_intrinsic_load_tcs_in_param_base_r600);
300 load_out_param_base = emit_load_param_base(b, nir_intrinsic_load_tcs_out_param_base_r600);
301 } else if (b->shader->info.stage == MESA_SHADER_TESS_EVAL) {
302 load_in_param_base = emit_load_param_base(b, nir_intrinsic_load_tcs_out_param_base_r600);
303 } else if (b->shader->info.stage == MESA_SHADER_VERTEX) {
304 load_out_param_base = emit_load_param_base(b, nir_intrinsic_load_tcs_in_param_base_r600);
305 }
306
307 auto rel_patch_id = r600_load_rel_patch_id(b);
308
309 unsigned tf_inner_address_offset = 0;
310 unsigned ncomps_correct = 0;
311
312 switch (op->intrinsic) {
313 case nir_intrinsic_load_patch_vertices_in: {
314 nir_ssa_def *vertices_in;
315 if (b->shader->info.stage == MESA_SHADER_TESS_CTRL)
316 vertices_in = nir_channel(b, load_in_param_base, 2);
317 else {
318 auto base = emit_load_param_base(b, nir_intrinsic_load_tcs_in_param_base_r600);
319 vertices_in = nir_channel(b, base, 2);
320 }
321 nir_ssa_def_rewrite_uses(&op->dest.ssa, vertices_in);
322 nir_instr_remove(&op->instr);
323 return true;
324 }
325 case nir_intrinsic_load_per_vertex_input: {
326 nir_ssa_def *addr =
327 b->shader->info.stage == MESA_SHADER_TESS_CTRL ?
328 emil_lsd_in_addr(b, load_in_param_base, rel_patch_id, op) :
329 emil_lsd_out_addr(b, load_in_param_base, rel_patch_id, op, nir_var_shader_in, 0);
330 replace_load_instr(b, op, addr);
331 return true;
332 }
333 case nir_intrinsic_store_per_vertex_output: {
334 nir_ssa_def *addr = emil_lsd_out_addr(b, load_out_param_base, rel_patch_id, op, nir_var_shader_out, 1);
335 emit_store_lds(b, op, addr);
336 nir_instr_remove(instr);
337 return true;
338 }
339 case nir_intrinsic_load_per_vertex_output: {
340 nir_ssa_def *addr = emil_lsd_out_addr(b, load_out_param_base, rel_patch_id, op, nir_var_shader_out, 0);
341 replace_load_instr(b, op, addr);
342 return true;
343 }
344 case nir_intrinsic_store_output: {
345 nir_ssa_def *addr = (b->shader->info.stage == MESA_SHADER_TESS_CTRL) ?
346 r600_tcs_base_address(b, load_out_param_base, rel_patch_id):
347 nir_build_alu(b, nir_op_umul24,
348 nir_channel(b, load_out_param_base, 1),
349 rel_patch_id, NULL, NULL);
350 addr = emil_tcs_io_offset(b, addr, op, 1);
351 emit_store_lds(b, op, addr);
352 nir_instr_remove(instr);
353 return true;
354 }
355 case nir_intrinsic_load_output: {
356 nir_ssa_def *addr = r600_tcs_base_address(b, load_out_param_base, rel_patch_id);
357 addr = emil_tcs_io_offset(b, addr, op, 0);
358 replace_load_instr(b, op, addr);
359 return true;
360 }
361 case nir_intrinsic_load_input: {
362 nir_ssa_def *addr = r600_tcs_base_address(b, load_in_param_base, rel_patch_id);
363 addr = emil_tcs_io_offset(b, addr, op, 0);
364 replace_load_instr(b, op, addr);
365 return true;
366 }
367 case nir_intrinsic_load_tess_level_inner:
368 tf_inner_address_offset = 4;
369 ncomps_correct = 2;
370 FALLTHROUGH;
371 case nir_intrinsic_load_tess_level_outer: {
372 auto ncomps = outer_tf_components(prim_type);
373 if (!ncomps)
374 return false;
375 ncomps -= ncomps_correct;
376 auto base = emit_load_param_base(b, nir_intrinsic_load_tcs_out_param_base_r600);
377 auto rel_patch_id = r600_load_rel_patch_id(b);
378 nir_ssa_def *addr0 = r600_tcs_base_address(b, base, rel_patch_id);
379 nir_ssa_def *addr_outer = nir_iadd(b, addr0, load_offset_group(b, tf_inner_address_offset + ncomps));
380
381 auto tf = nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_local_shared_r600);
382 tf->num_components = ncomps;
383 tf->src[0] = nir_src_for_ssa(addr_outer);
384 nir_ssa_dest_init(&tf->instr, &tf->dest,
385 tf->num_components, 32, NULL);
386 nir_builder_instr_insert(b, &tf->instr);
387
388 nir_ssa_def_rewrite_uses(&op->dest.ssa, &tf->dest.ssa);
389 nir_instr_remove(instr);
390 return true;
391 }
392 default:
393 ;
394 }
395
396 return false;
397 }
398
r600_lower_tess_io(nir_shader * shader,enum pipe_prim_type prim_type)399 bool r600_lower_tess_io(nir_shader *shader, enum pipe_prim_type prim_type)
400 {
401 bool progress = false;
402 nir_foreach_function(function, shader) {
403 if (function->impl) {
404 nir_builder b;
405 nir_builder_init(&b, function->impl);
406
407 nir_foreach_block(block, function->impl) {
408 nir_foreach_instr_safe(instr, block) {
409 if (instr->type != nir_instr_type_intrinsic)
410 continue;
411
412 if (r600_lower_tess_io_filter(instr, shader->info.stage))
413 progress |= r600_lower_tess_io_impl(&b, instr, prim_type);
414 }
415 }
416 }
417 }
418 return progress;
419 }
420
r600_emit_tf(nir_builder * b,nir_ssa_def * val)421 bool r600_emit_tf(nir_builder *b, nir_ssa_def *val)
422 {
423 nir_intrinsic_instr *store_tf = nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_tf_r600);
424 store_tf->num_components = val->num_components;
425 store_tf->src[0] = nir_src_for_ssa(val);
426 nir_builder_instr_insert(b, &store_tf->instr);
427 return true;
428 }
429
r600_append_tcs_TF_emission(nir_shader * shader,enum pipe_prim_type prim_type)430 bool r600_append_tcs_TF_emission(nir_shader *shader, enum pipe_prim_type prim_type) {
431 if (shader->info.stage != MESA_SHADER_TESS_CTRL)
432 return false;
433
434 nir_foreach_function(function, shader) {
435 nir_foreach_block(block, function->impl) {
436 nir_foreach_instr_safe(instr, block) {
437 if (instr->type != nir_instr_type_intrinsic)
438 continue;
439 nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
440 if (intr->intrinsic == nir_intrinsic_store_tf_r600) {
441 return false;
442 }
443 }
444 }
445 }
446 nir_builder builder;
447 nir_builder *b = &builder;
448
449 assert(exec_list_length(&shader->functions) == 1);
450 nir_function *f = (nir_function *)shader->functions.get_head();
451 nir_builder_init(b, f->impl);
452
453 auto outer_comps = outer_tf_components(prim_type);
454 if (!outer_comps)
455 return false;
456
457 unsigned inner_comps = outer_comps - 2;
458 unsigned stride = (inner_comps + outer_comps) * 4;
459
460 b->cursor = nir_after_cf_list(&f->impl->body);
461
462 auto invocation_id = nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_invocation_id);
463 nir_ssa_dest_init(&invocation_id->instr, &invocation_id->dest,
464 1, 32, NULL);
465 nir_builder_instr_insert(b, &invocation_id->instr);
466
467 nir_push_if(b, nir_ieq_imm(b, &invocation_id->dest.ssa, 0));
468 auto base = emit_load_param_base(b, nir_intrinsic_load_tcs_out_param_base_r600);
469 auto rel_patch_id = r600_load_rel_patch_id(b);
470
471 nir_ssa_def *addr0 = r600_tcs_base_address(b, base, rel_patch_id);
472
473 nir_ssa_def *addr_outer = nir_iadd(b, addr0, load_offset_group(b, outer_comps));
474 auto tf_outer = nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_local_shared_r600);
475 tf_outer->num_components = outer_comps;
476 tf_outer->src[0] = nir_src_for_ssa(addr_outer);
477 nir_ssa_dest_init(&tf_outer->instr, &tf_outer->dest,
478 tf_outer->num_components, 32, NULL);
479 nir_builder_instr_insert(b, &tf_outer->instr);
480
481 std::vector<nir_ssa_def *> tf_out;
482
483
484 auto tf_out_base = nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_tcs_tess_factor_base_r600);
485 nir_ssa_dest_init(&tf_out_base->instr, &tf_out_base->dest,
486 1, 32, NULL);
487 nir_builder_instr_insert(b, &tf_out_base->instr);
488
489 auto out_addr0 = nir_build_alu(b, nir_op_umad24,
490 rel_patch_id,
491 nir_imm_int(b, stride),
492 &tf_out_base->dest.ssa,
493 NULL);
494 int chanx = 0;
495 int chany = 1;
496
497 if (prim_type == PIPE_PRIM_LINES)
498 std::swap(chanx, chany);
499
500
501 auto v0 = nir_vec4(b, out_addr0, nir_channel(b, &tf_outer->dest.ssa, chanx),
502 nir_iadd(b, out_addr0, nir_imm_int(b, 4)),
503 nir_channel(b, &tf_outer->dest.ssa, chany));
504
505 tf_out.push_back(v0);
506 if (outer_comps > 2) {
507 auto v1 = (outer_comps > 3) ? nir_vec4(b, nir_iadd(b, out_addr0, nir_imm_int(b, 8)),
508 nir_channel(b, &tf_outer->dest.ssa, 2),
509 nir_iadd(b, out_addr0, nir_imm_int(b, 12)),
510 nir_channel(b, &tf_outer->dest.ssa, 3)) :
511 nir_vec2(b, nir_iadd(b, out_addr0, nir_imm_int(b, 8)),
512 nir_channel(b, &tf_outer->dest.ssa, 2));
513 tf_out.push_back(v1);
514 }
515
516 if (inner_comps) {
517 nir_ssa_def *addr1 = nir_iadd(b, addr0, load_offset_group(b, 4 + inner_comps));
518 auto tf_inner = nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_local_shared_r600);
519 tf_inner->num_components = inner_comps;
520 tf_inner->src[0] = nir_src_for_ssa(addr1);
521 nir_ssa_dest_init(&tf_inner->instr, &tf_inner->dest,
522 tf_inner->num_components, 32, NULL);
523 nir_builder_instr_insert(b, &tf_inner->instr);
524
525 auto v2 = (inner_comps > 1) ? nir_vec4(b, nir_iadd(b, out_addr0, nir_imm_int(b, 16)),
526 nir_channel(b, &tf_inner->dest.ssa, 0),
527 nir_iadd(b, out_addr0, nir_imm_int(b, 20)),
528 nir_channel(b, &tf_inner->dest.ssa, 1)):
529 nir_vec2(b, nir_iadd(b, out_addr0, nir_imm_int(b, 12)),
530 nir_channel(b, &tf_inner->dest.ssa, 0));
531 tf_out.push_back(v2);
532 }
533
534 for (auto tf: tf_out)
535 r600_emit_tf(b, tf);
536
537 nir_pop_if(b, nullptr);
538
539 nir_metadata_preserve(f->impl, nir_metadata_none);
540
541 return true;
542 }
543
544 static bool
r600_lower_tess_coord_filter(const nir_instr * instr,UNUSED const void * _options)545 r600_lower_tess_coord_filter(const nir_instr *instr, UNUSED const void *_options)
546 {
547 if (instr->type != nir_instr_type_intrinsic)
548 return false;
549 auto intr = nir_instr_as_intrinsic(instr);
550 return intr->intrinsic == nir_intrinsic_load_tess_coord;
551 }
552
553 static nir_ssa_def *
r600_lower_tess_coord_impl(nir_builder * b,nir_instr * instr,void * _options)554 r600_lower_tess_coord_impl(nir_builder *b, nir_instr *instr, void *_options)
555 {
556 pipe_prim_type prim_type = *(pipe_prim_type *)_options;
557
558 auto tc_xy = nir_load_tess_coord_r600(b);
559
560 auto tc_x = nir_channel(b, tc_xy, 0);
561 auto tc_y = nir_channel(b, tc_xy, 1);
562
563 if (prim_type == PIPE_PRIM_TRIANGLES)
564 return nir_vec3(b, tc_x, tc_y, nir_fsub(b, nir_imm_float(b, 1.0),
565 nir_fadd(b, tc_x, tc_y)));
566 else
567 return nir_vec3(b, tc_x, tc_y, nir_imm_float(b, 0.0));
568 }
569
570
r600_lower_tess_coord(nir_shader * sh,enum pipe_prim_type prim_type)571 bool r600_lower_tess_coord(nir_shader *sh, enum pipe_prim_type prim_type)
572 {
573 return nir_shader_lower_instructions(sh, r600_lower_tess_coord_filter,
574 r600_lower_tess_coord_impl, &prim_type);
575 }
576