1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © Microsoft Corporation
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker *
11*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker * Software.
14*61046927SAndroid Build Coastguard Worker *
15*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker */
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker #include "dzn_nir.h"
25*61046927SAndroid Build Coastguard Worker
26*61046927SAndroid Build Coastguard Worker #include "spirv_to_dxil.h"
27*61046927SAndroid Build Coastguard Worker #include "nir_to_dxil.h"
28*61046927SAndroid Build Coastguard Worker #include "nir_builder.h"
29*61046927SAndroid Build Coastguard Worker #include "nir_builtin_builder.h"
30*61046927SAndroid Build Coastguard Worker #include "dxil_nir.h"
31*61046927SAndroid Build Coastguard Worker #include "vk_nir_convert_ycbcr.h"
32*61046927SAndroid Build Coastguard Worker
33*61046927SAndroid Build Coastguard Worker static nir_def *
dzn_nir_create_bo_desc(nir_builder * b,nir_variable_mode mode,uint32_t desc_set,uint32_t binding,const char * name,unsigned access)34*61046927SAndroid Build Coastguard Worker dzn_nir_create_bo_desc(nir_builder *b,
35*61046927SAndroid Build Coastguard Worker nir_variable_mode mode,
36*61046927SAndroid Build Coastguard Worker uint32_t desc_set,
37*61046927SAndroid Build Coastguard Worker uint32_t binding,
38*61046927SAndroid Build Coastguard Worker const char *name,
39*61046927SAndroid Build Coastguard Worker unsigned access)
40*61046927SAndroid Build Coastguard Worker {
41*61046927SAndroid Build Coastguard Worker struct glsl_struct_field field = {
42*61046927SAndroid Build Coastguard Worker .type = mode == nir_var_mem_ubo ?
43*61046927SAndroid Build Coastguard Worker glsl_array_type(glsl_uint_type(), 4096, 4) :
44*61046927SAndroid Build Coastguard Worker glsl_uint_type(),
45*61046927SAndroid Build Coastguard Worker .name = "dummy_int",
46*61046927SAndroid Build Coastguard Worker };
47*61046927SAndroid Build Coastguard Worker const struct glsl_type *dummy_type =
48*61046927SAndroid Build Coastguard Worker glsl_struct_type(&field, 1, "dummy_type", false);
49*61046927SAndroid Build Coastguard Worker
50*61046927SAndroid Build Coastguard Worker nir_variable *var =
51*61046927SAndroid Build Coastguard Worker nir_variable_create(b->shader, mode, dummy_type, name);
52*61046927SAndroid Build Coastguard Worker var->data.descriptor_set = desc_set;
53*61046927SAndroid Build Coastguard Worker var->data.binding = binding;
54*61046927SAndroid Build Coastguard Worker var->data.access = access;
55*61046927SAndroid Build Coastguard Worker
56*61046927SAndroid Build Coastguard Worker assert(mode == nir_var_mem_ubo || mode == nir_var_mem_ssbo);
57*61046927SAndroid Build Coastguard Worker if (mode == nir_var_mem_ubo)
58*61046927SAndroid Build Coastguard Worker b->shader->info.num_ubos++;
59*61046927SAndroid Build Coastguard Worker else
60*61046927SAndroid Build Coastguard Worker b->shader->info.num_ssbos++;
61*61046927SAndroid Build Coastguard Worker
62*61046927SAndroid Build Coastguard Worker VkDescriptorType desc_type =
63*61046927SAndroid Build Coastguard Worker var->data.mode == nir_var_mem_ubo ?
64*61046927SAndroid Build Coastguard Worker VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER :
65*61046927SAndroid Build Coastguard Worker VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
66*61046927SAndroid Build Coastguard Worker nir_address_format addr_format = nir_address_format_32bit_index_offset;
67*61046927SAndroid Build Coastguard Worker nir_def *index =
68*61046927SAndroid Build Coastguard Worker nir_vulkan_resource_index(b,
69*61046927SAndroid Build Coastguard Worker nir_address_format_num_components(addr_format),
70*61046927SAndroid Build Coastguard Worker nir_address_format_bit_size(addr_format),
71*61046927SAndroid Build Coastguard Worker nir_imm_int(b, 0),
72*61046927SAndroid Build Coastguard Worker .desc_set = desc_set,
73*61046927SAndroid Build Coastguard Worker .binding = binding,
74*61046927SAndroid Build Coastguard Worker .desc_type = desc_type);
75*61046927SAndroid Build Coastguard Worker
76*61046927SAndroid Build Coastguard Worker nir_def *desc =
77*61046927SAndroid Build Coastguard Worker nir_load_vulkan_descriptor(b,
78*61046927SAndroid Build Coastguard Worker nir_address_format_num_components(addr_format),
79*61046927SAndroid Build Coastguard Worker nir_address_format_bit_size(addr_format),
80*61046927SAndroid Build Coastguard Worker index,
81*61046927SAndroid Build Coastguard Worker .desc_type = desc_type);
82*61046927SAndroid Build Coastguard Worker
83*61046927SAndroid Build Coastguard Worker return nir_channel(b, desc, 0);
84*61046927SAndroid Build Coastguard Worker }
85*61046927SAndroid Build Coastguard Worker
86*61046927SAndroid Build Coastguard Worker nir_shader *
dzn_nir_indirect_draw_shader(struct dzn_indirect_draw_type type)87*61046927SAndroid Build Coastguard Worker dzn_nir_indirect_draw_shader(struct dzn_indirect_draw_type type)
88*61046927SAndroid Build Coastguard Worker {
89*61046927SAndroid Build Coastguard Worker nir_builder b =
90*61046927SAndroid Build Coastguard Worker nir_builder_init_simple_shader(MESA_SHADER_COMPUTE,
91*61046927SAndroid Build Coastguard Worker dxil_get_base_nir_compiler_options(),
92*61046927SAndroid Build Coastguard Worker "dzn_meta_indirect_%sdraw%s%s%s()",
93*61046927SAndroid Build Coastguard Worker type.indexed ? "indexed_" : "",
94*61046927SAndroid Build Coastguard Worker type.indirect_count ? "_count" : "",
95*61046927SAndroid Build Coastguard Worker type.triangle_fan ? "_triangle_fan" : "",
96*61046927SAndroid Build Coastguard Worker type.triangle_fan_primitive_restart ? "_primitive_restart" : "");
97*61046927SAndroid Build Coastguard Worker b.shader->info.internal = true;
98*61046927SAndroid Build Coastguard Worker
99*61046927SAndroid Build Coastguard Worker nir_def *params_desc =
100*61046927SAndroid Build Coastguard Worker dzn_nir_create_bo_desc(&b, nir_var_mem_ubo, 0, 0, "params", 0);
101*61046927SAndroid Build Coastguard Worker nir_def *draw_buf_desc =
102*61046927SAndroid Build Coastguard Worker dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 1, "draw_buf", ACCESS_NON_WRITEABLE);
103*61046927SAndroid Build Coastguard Worker nir_def *exec_buf_desc =
104*61046927SAndroid Build Coastguard Worker dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 2, "exec_buf", ACCESS_NON_READABLE);
105*61046927SAndroid Build Coastguard Worker
106*61046927SAndroid Build Coastguard Worker unsigned params_size = 0;
107*61046927SAndroid Build Coastguard Worker if (type.triangle_fan)
108*61046927SAndroid Build Coastguard Worker params_size = sizeof(struct dzn_indirect_draw_triangle_fan_rewrite_params);
109*61046927SAndroid Build Coastguard Worker else
110*61046927SAndroid Build Coastguard Worker params_size = sizeof(struct dzn_indirect_draw_rewrite_params);
111*61046927SAndroid Build Coastguard Worker
112*61046927SAndroid Build Coastguard Worker nir_def *params =
113*61046927SAndroid Build Coastguard Worker nir_load_ubo(&b, params_size / 4, 32,
114*61046927SAndroid Build Coastguard Worker params_desc, nir_imm_int(&b, 0),
115*61046927SAndroid Build Coastguard Worker .align_mul = 4, .align_offset = 0, .range_base = 0, .range = ~0);
116*61046927SAndroid Build Coastguard Worker
117*61046927SAndroid Build Coastguard Worker uint32_t exec_stride_imm = 0;
118*61046927SAndroid Build Coastguard Worker uint32_t draw_args_offset = 0;
119*61046927SAndroid Build Coastguard Worker if (type.triangle_fan)
120*61046927SAndroid Build Coastguard Worker exec_stride_imm += sizeof(D3D12_INDEX_BUFFER_VIEW);
121*61046927SAndroid Build Coastguard Worker if (type.draw_params)
122*61046927SAndroid Build Coastguard Worker exec_stride_imm += sizeof(uint32_t) * 2;
123*61046927SAndroid Build Coastguard Worker if (type.draw_id)
124*61046927SAndroid Build Coastguard Worker exec_stride_imm += sizeof(uint32_t);
125*61046927SAndroid Build Coastguard Worker draw_args_offset = exec_stride_imm;
126*61046927SAndroid Build Coastguard Worker exec_stride_imm += (type.indexed || type.triangle_fan) ?
127*61046927SAndroid Build Coastguard Worker sizeof(D3D12_DRAW_INDEXED_ARGUMENTS) : sizeof(D3D12_DRAW_ARGUMENTS);
128*61046927SAndroid Build Coastguard Worker
129*61046927SAndroid Build Coastguard Worker nir_def *draw_stride = nir_channel(&b, params, 0);
130*61046927SAndroid Build Coastguard Worker nir_def *exec_stride = nir_imm_int(&b, exec_stride_imm);
131*61046927SAndroid Build Coastguard Worker nir_def *index =
132*61046927SAndroid Build Coastguard Worker nir_channel(&b, nir_load_global_invocation_id(&b, 32), 0);
133*61046927SAndroid Build Coastguard Worker
134*61046927SAndroid Build Coastguard Worker if (type.indirect_count) {
135*61046927SAndroid Build Coastguard Worker nir_def *count_buf_desc =
136*61046927SAndroid Build Coastguard Worker dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 3, "count_buf", ACCESS_NON_WRITEABLE);
137*61046927SAndroid Build Coastguard Worker
138*61046927SAndroid Build Coastguard Worker nir_def *draw_count =
139*61046927SAndroid Build Coastguard Worker nir_load_ssbo(&b, 1, 32, count_buf_desc, nir_imm_int(&b, 0), .align_mul = 4);
140*61046927SAndroid Build Coastguard Worker
141*61046927SAndroid Build Coastguard Worker nir_push_if(&b, nir_ieq_imm(&b, index, 0));
142*61046927SAndroid Build Coastguard Worker nir_store_ssbo(&b, draw_count, exec_buf_desc, nir_imm_int(&b, 0),
143*61046927SAndroid Build Coastguard Worker .write_mask = 0x1, .access = ACCESS_NON_READABLE,
144*61046927SAndroid Build Coastguard Worker .align_mul = 16);
145*61046927SAndroid Build Coastguard Worker nir_pop_if(&b, NULL);
146*61046927SAndroid Build Coastguard Worker
147*61046927SAndroid Build Coastguard Worker nir_push_if(&b, nir_ult(&b, index, draw_count));
148*61046927SAndroid Build Coastguard Worker }
149*61046927SAndroid Build Coastguard Worker
150*61046927SAndroid Build Coastguard Worker nir_def *draw_offset = nir_imul(&b, draw_stride, index);
151*61046927SAndroid Build Coastguard Worker
152*61046927SAndroid Build Coastguard Worker /* The first entry contains the indirect count */
153*61046927SAndroid Build Coastguard Worker nir_def *exec_offset =
154*61046927SAndroid Build Coastguard Worker type.indirect_count ?
155*61046927SAndroid Build Coastguard Worker nir_imul(&b, exec_stride, nir_iadd_imm(&b, index, 1)) :
156*61046927SAndroid Build Coastguard Worker nir_imul(&b, exec_stride, index);
157*61046927SAndroid Build Coastguard Worker
158*61046927SAndroid Build Coastguard Worker nir_def *draw_info1 =
159*61046927SAndroid Build Coastguard Worker nir_load_ssbo(&b, 4, 32, draw_buf_desc, draw_offset, .align_mul = 4);
160*61046927SAndroid Build Coastguard Worker nir_def *draw_info2 =
161*61046927SAndroid Build Coastguard Worker type.indexed ?
162*61046927SAndroid Build Coastguard Worker nir_load_ssbo(&b, 1, 32, draw_buf_desc,
163*61046927SAndroid Build Coastguard Worker nir_iadd_imm(&b, draw_offset, 16), .align_mul = 4) :
164*61046927SAndroid Build Coastguard Worker nir_imm_int(&b, 0);
165*61046927SAndroid Build Coastguard Worker
166*61046927SAndroid Build Coastguard Worker nir_def *first_vertex = nir_channel(&b, draw_info1, type.indexed ? 3 : 2);
167*61046927SAndroid Build Coastguard Worker nir_def *base_instance =
168*61046927SAndroid Build Coastguard Worker type.indexed ? draw_info2 : nir_channel(&b, draw_info1, 3);
169*61046927SAndroid Build Coastguard Worker
170*61046927SAndroid Build Coastguard Worker uint32_t exec_val_idx = 0;
171*61046927SAndroid Build Coastguard Worker nir_def *exec_vals[8] = { NULL };
172*61046927SAndroid Build Coastguard Worker if (type.draw_params) {
173*61046927SAndroid Build Coastguard Worker exec_vals[exec_val_idx++] = first_vertex;
174*61046927SAndroid Build Coastguard Worker exec_vals[exec_val_idx++] = base_instance;
175*61046927SAndroid Build Coastguard Worker }
176*61046927SAndroid Build Coastguard Worker if (type.draw_id)
177*61046927SAndroid Build Coastguard Worker exec_vals[exec_val_idx++] = index;
178*61046927SAndroid Build Coastguard Worker
179*61046927SAndroid Build Coastguard Worker if (type.triangle_fan) {
180*61046927SAndroid Build Coastguard Worker /* Patch {vertex,index}_count and first_index */
181*61046927SAndroid Build Coastguard Worker nir_def *triangle_count =
182*61046927SAndroid Build Coastguard Worker nir_usub_sat(&b, nir_channel(&b, draw_info1, 0), nir_imm_int(&b, 2));
183*61046927SAndroid Build Coastguard Worker exec_vals[exec_val_idx++] = nir_imul_imm(&b, triangle_count, 3);
184*61046927SAndroid Build Coastguard Worker exec_vals[exec_val_idx++] = nir_channel(&b, draw_info1, 1);
185*61046927SAndroid Build Coastguard Worker exec_vals[exec_val_idx++] = nir_imm_int(&b, 0);
186*61046927SAndroid Build Coastguard Worker exec_vals[exec_val_idx++] = first_vertex;
187*61046927SAndroid Build Coastguard Worker exec_vals[exec_val_idx++] = base_instance;
188*61046927SAndroid Build Coastguard Worker
189*61046927SAndroid Build Coastguard Worker nir_def *triangle_fan_exec_buf_desc =
190*61046927SAndroid Build Coastguard Worker dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 4,
191*61046927SAndroid Build Coastguard Worker "triangle_fan_exec_buf",
192*61046927SAndroid Build Coastguard Worker ACCESS_NON_READABLE);
193*61046927SAndroid Build Coastguard Worker nir_def *triangle_fan_index_buf_stride = nir_channel(&b, params, 1);
194*61046927SAndroid Build Coastguard Worker nir_def *triangle_fan_index_buf_addr_lo =
195*61046927SAndroid Build Coastguard Worker nir_iadd(&b, nir_channel(&b, params, 2),
196*61046927SAndroid Build Coastguard Worker nir_imul(&b, triangle_fan_index_buf_stride, index));
197*61046927SAndroid Build Coastguard Worker
198*61046927SAndroid Build Coastguard Worker nir_def *triangle_fan_exec_vals[9] = { 0 };
199*61046927SAndroid Build Coastguard Worker uint32_t triangle_fan_exec_param_count = 0;
200*61046927SAndroid Build Coastguard Worker nir_def *addr_lo_overflow =
201*61046927SAndroid Build Coastguard Worker nir_ult(&b, triangle_fan_index_buf_addr_lo, nir_channel(&b, params, 2));
202*61046927SAndroid Build Coastguard Worker nir_def *triangle_fan_index_buf_addr_hi =
203*61046927SAndroid Build Coastguard Worker nir_iadd(&b, nir_channel(&b, params, 3),
204*61046927SAndroid Build Coastguard Worker nir_bcsel(&b, addr_lo_overflow, nir_imm_int(&b, 1), nir_imm_int(&b, 0)));
205*61046927SAndroid Build Coastguard Worker
206*61046927SAndroid Build Coastguard Worker triangle_fan_exec_vals[triangle_fan_exec_param_count++] = triangle_fan_index_buf_addr_lo;
207*61046927SAndroid Build Coastguard Worker triangle_fan_exec_vals[triangle_fan_exec_param_count++] = triangle_fan_index_buf_addr_hi;
208*61046927SAndroid Build Coastguard Worker
209*61046927SAndroid Build Coastguard Worker if (type.triangle_fan_primitive_restart) {
210*61046927SAndroid Build Coastguard Worker triangle_fan_exec_vals[triangle_fan_exec_param_count++] = nir_channel(&b, draw_info1, 2);
211*61046927SAndroid Build Coastguard Worker triangle_fan_exec_vals[triangle_fan_exec_param_count++] = nir_channel(&b, draw_info1, 0);
212*61046927SAndroid Build Coastguard Worker uint32_t index_count_offset = draw_args_offset +
213*61046927SAndroid Build Coastguard Worker offsetof(D3D12_DRAW_INDEXED_ARGUMENTS, IndexCountPerInstance);
214*61046927SAndroid Build Coastguard Worker nir_def *exec_buf_start =
215*61046927SAndroid Build Coastguard Worker nir_load_ubo(&b, 2, 32,
216*61046927SAndroid Build Coastguard Worker params_desc, nir_imm_int(&b, 16),
217*61046927SAndroid Build Coastguard Worker .align_mul = 4, .align_offset = 0, .range_base = 0, .range = ~0);
218*61046927SAndroid Build Coastguard Worker nir_def *exec_buf_start_lo =
219*61046927SAndroid Build Coastguard Worker nir_iadd(&b, nir_imm_int(&b, index_count_offset),
220*61046927SAndroid Build Coastguard Worker nir_iadd(&b, nir_channel(&b, exec_buf_start, 0),
221*61046927SAndroid Build Coastguard Worker nir_imul(&b, exec_stride, index)));
222*61046927SAndroid Build Coastguard Worker addr_lo_overflow = nir_ult(&b, exec_buf_start_lo, nir_channel(&b, exec_buf_start, 0));
223*61046927SAndroid Build Coastguard Worker nir_def *exec_buf_start_hi =
224*61046927SAndroid Build Coastguard Worker nir_iadd(&b, nir_channel(&b, exec_buf_start, 0),
225*61046927SAndroid Build Coastguard Worker nir_bcsel(&b, addr_lo_overflow, nir_imm_int(&b, 1), nir_imm_int(&b, 0)));
226*61046927SAndroid Build Coastguard Worker triangle_fan_exec_vals[triangle_fan_exec_param_count++] = exec_buf_start_lo;
227*61046927SAndroid Build Coastguard Worker triangle_fan_exec_vals[triangle_fan_exec_param_count++] = exec_buf_start_hi;
228*61046927SAndroid Build Coastguard Worker triangle_fan_exec_vals[triangle_fan_exec_param_count++] = nir_imm_int(&b, 1);
229*61046927SAndroid Build Coastguard Worker } else {
230*61046927SAndroid Build Coastguard Worker triangle_fan_exec_vals[triangle_fan_exec_param_count++] =
231*61046927SAndroid Build Coastguard Worker type.indexed ? nir_channel(&b, draw_info1, 2) : nir_imm_int(&b, 0);
232*61046927SAndroid Build Coastguard Worker triangle_fan_exec_vals[triangle_fan_exec_param_count++] =
233*61046927SAndroid Build Coastguard Worker triangle_count;
234*61046927SAndroid Build Coastguard Worker }
235*61046927SAndroid Build Coastguard Worker triangle_fan_exec_vals[triangle_fan_exec_param_count++] = nir_imm_int(&b, 1);
236*61046927SAndroid Build Coastguard Worker triangle_fan_exec_vals[triangle_fan_exec_param_count++] = nir_imm_int(&b, 1);
237*61046927SAndroid Build Coastguard Worker
238*61046927SAndroid Build Coastguard Worker unsigned rewrite_index_exec_params =
239*61046927SAndroid Build Coastguard Worker type.triangle_fan_primitive_restart ?
240*61046927SAndroid Build Coastguard Worker sizeof(struct dzn_indirect_triangle_fan_prim_restart_rewrite_index_exec_params) :
241*61046927SAndroid Build Coastguard Worker sizeof(struct dzn_indirect_triangle_fan_rewrite_index_exec_params);
242*61046927SAndroid Build Coastguard Worker nir_def *triangle_fan_exec_stride =
243*61046927SAndroid Build Coastguard Worker nir_imm_int(&b, rewrite_index_exec_params);
244*61046927SAndroid Build Coastguard Worker nir_def *triangle_fan_exec_offset =
245*61046927SAndroid Build Coastguard Worker nir_imul(&b, triangle_fan_exec_stride, index);
246*61046927SAndroid Build Coastguard Worker
247*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < triangle_fan_exec_param_count; i += 4) {
248*61046927SAndroid Build Coastguard Worker unsigned comps = MIN2(triangle_fan_exec_param_count - i, 4);
249*61046927SAndroid Build Coastguard Worker uint32_t mask = (1 << comps) - 1;
250*61046927SAndroid Build Coastguard Worker
251*61046927SAndroid Build Coastguard Worker nir_store_ssbo(&b, nir_vec(&b, &triangle_fan_exec_vals[i], comps),
252*61046927SAndroid Build Coastguard Worker triangle_fan_exec_buf_desc,
253*61046927SAndroid Build Coastguard Worker nir_iadd_imm(&b, triangle_fan_exec_offset, i * 4),
254*61046927SAndroid Build Coastguard Worker .write_mask = mask, .access = ACCESS_NON_READABLE, .align_mul = 4);
255*61046927SAndroid Build Coastguard Worker }
256*61046927SAndroid Build Coastguard Worker
257*61046927SAndroid Build Coastguard Worker nir_def *ibview_vals[] = {
258*61046927SAndroid Build Coastguard Worker triangle_fan_index_buf_addr_lo,
259*61046927SAndroid Build Coastguard Worker triangle_fan_index_buf_addr_hi,
260*61046927SAndroid Build Coastguard Worker triangle_fan_index_buf_stride,
261*61046927SAndroid Build Coastguard Worker nir_imm_int(&b, DXGI_FORMAT_R32_UINT),
262*61046927SAndroid Build Coastguard Worker };
263*61046927SAndroid Build Coastguard Worker
264*61046927SAndroid Build Coastguard Worker nir_store_ssbo(&b, nir_vec(&b, ibview_vals, ARRAY_SIZE(ibview_vals)),
265*61046927SAndroid Build Coastguard Worker exec_buf_desc, exec_offset,
266*61046927SAndroid Build Coastguard Worker .write_mask = 0xf, .access = ACCESS_NON_READABLE, .align_mul = 16);
267*61046927SAndroid Build Coastguard Worker exec_offset = nir_iadd_imm(&b, exec_offset, ARRAY_SIZE(ibview_vals) * 4);
268*61046927SAndroid Build Coastguard Worker } else {
269*61046927SAndroid Build Coastguard Worker exec_vals[exec_val_idx++] = nir_channel(&b, draw_info1, 0);
270*61046927SAndroid Build Coastguard Worker exec_vals[exec_val_idx++] = nir_channel(&b, draw_info1, 1);
271*61046927SAndroid Build Coastguard Worker exec_vals[exec_val_idx++] = nir_channel(&b, draw_info1, 2);
272*61046927SAndroid Build Coastguard Worker exec_vals[exec_val_idx++] = nir_channel(&b, draw_info1, 3);
273*61046927SAndroid Build Coastguard Worker if (type.indexed)
274*61046927SAndroid Build Coastguard Worker exec_vals[exec_val_idx++] = draw_info2;
275*61046927SAndroid Build Coastguard Worker }
276*61046927SAndroid Build Coastguard Worker
277*61046927SAndroid Build Coastguard Worker nir_store_ssbo(&b, nir_vec(&b, exec_vals, MIN2(exec_val_idx, 4)),
278*61046927SAndroid Build Coastguard Worker exec_buf_desc, exec_offset,
279*61046927SAndroid Build Coastguard Worker .write_mask = ((1 << exec_val_idx) - 1) & 0xf, .access = ACCESS_NON_READABLE, .align_mul = 16);
280*61046927SAndroid Build Coastguard Worker if (exec_val_idx > 4) {
281*61046927SAndroid Build Coastguard Worker nir_store_ssbo(&b, nir_vec(&b, &exec_vals[4], exec_val_idx - 4),
282*61046927SAndroid Build Coastguard Worker exec_buf_desc, nir_iadd_imm(&b, exec_offset, 16),
283*61046927SAndroid Build Coastguard Worker .write_mask = ((1 << (exec_val_idx - 4)) - 1) & 0xf, .access = ACCESS_NON_READABLE, .align_mul = 16);
284*61046927SAndroid Build Coastguard Worker }
285*61046927SAndroid Build Coastguard Worker
286*61046927SAndroid Build Coastguard Worker if (type.indirect_count)
287*61046927SAndroid Build Coastguard Worker nir_pop_if(&b, NULL);
288*61046927SAndroid Build Coastguard Worker
289*61046927SAndroid Build Coastguard Worker return b.shader;
290*61046927SAndroid Build Coastguard Worker }
291*61046927SAndroid Build Coastguard Worker
292*61046927SAndroid Build Coastguard Worker nir_shader *
dzn_nir_triangle_fan_prim_restart_rewrite_index_shader(uint8_t old_index_size)293*61046927SAndroid Build Coastguard Worker dzn_nir_triangle_fan_prim_restart_rewrite_index_shader(uint8_t old_index_size)
294*61046927SAndroid Build Coastguard Worker {
295*61046927SAndroid Build Coastguard Worker assert(old_index_size == 2 || old_index_size == 4);
296*61046927SAndroid Build Coastguard Worker
297*61046927SAndroid Build Coastguard Worker nir_builder b =
298*61046927SAndroid Build Coastguard Worker nir_builder_init_simple_shader(MESA_SHADER_COMPUTE,
299*61046927SAndroid Build Coastguard Worker dxil_get_base_nir_compiler_options(),
300*61046927SAndroid Build Coastguard Worker "dzn_meta_triangle_prim_rewrite_index(old_index_size=%d)",
301*61046927SAndroid Build Coastguard Worker old_index_size);
302*61046927SAndroid Build Coastguard Worker b.shader->info.internal = true;
303*61046927SAndroid Build Coastguard Worker
304*61046927SAndroid Build Coastguard Worker nir_def *params_desc =
305*61046927SAndroid Build Coastguard Worker dzn_nir_create_bo_desc(&b, nir_var_mem_ubo, 0, 0, "params", 0);
306*61046927SAndroid Build Coastguard Worker nir_def *new_index_buf_desc =
307*61046927SAndroid Build Coastguard Worker dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 1,
308*61046927SAndroid Build Coastguard Worker "new_index_buf", ACCESS_NON_READABLE);
309*61046927SAndroid Build Coastguard Worker nir_def *old_index_buf_desc =
310*61046927SAndroid Build Coastguard Worker dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 2,
311*61046927SAndroid Build Coastguard Worker "old_index_buf", ACCESS_NON_WRITEABLE);
312*61046927SAndroid Build Coastguard Worker nir_def *new_index_count_ptr_desc =
313*61046927SAndroid Build Coastguard Worker dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 3,
314*61046927SAndroid Build Coastguard Worker "new_index_count_ptr", ACCESS_NON_READABLE);
315*61046927SAndroid Build Coastguard Worker
316*61046927SAndroid Build Coastguard Worker nir_def *params =
317*61046927SAndroid Build Coastguard Worker nir_load_ubo(&b, sizeof(struct dzn_triangle_fan_prim_restart_rewrite_index_params) / 4, 32,
318*61046927SAndroid Build Coastguard Worker params_desc, nir_imm_int(&b, 0),
319*61046927SAndroid Build Coastguard Worker .align_mul = 4, .align_offset = 0, .range_base = 0, .range = ~0);
320*61046927SAndroid Build Coastguard Worker
321*61046927SAndroid Build Coastguard Worker nir_def *prim_restart_val =
322*61046927SAndroid Build Coastguard Worker nir_imm_int(&b, old_index_size == 2 ? 0xffff : 0xffffffff);
323*61046927SAndroid Build Coastguard Worker nir_variable *old_index_ptr_var =
324*61046927SAndroid Build Coastguard Worker nir_local_variable_create(b.impl, glsl_uint_type(), "old_index_ptr_var");
325*61046927SAndroid Build Coastguard Worker nir_def *old_index_ptr = nir_channel(&b, params, 0);
326*61046927SAndroid Build Coastguard Worker nir_store_var(&b, old_index_ptr_var, old_index_ptr, 1);
327*61046927SAndroid Build Coastguard Worker nir_variable *new_index_ptr_var =
328*61046927SAndroid Build Coastguard Worker nir_local_variable_create(b.impl, glsl_uint_type(), "new_index_ptr_var");
329*61046927SAndroid Build Coastguard Worker nir_store_var(&b, new_index_ptr_var, nir_imm_int(&b, 0), 1);
330*61046927SAndroid Build Coastguard Worker nir_def *old_index_count = nir_channel(&b, params, 1);
331*61046927SAndroid Build Coastguard Worker nir_variable *index0_var =
332*61046927SAndroid Build Coastguard Worker nir_local_variable_create(b.impl, glsl_uint_type(), "index0_var");
333*61046927SAndroid Build Coastguard Worker nir_store_var(&b, index0_var, prim_restart_val, 1);
334*61046927SAndroid Build Coastguard Worker
335*61046927SAndroid Build Coastguard Worker /*
336*61046927SAndroid Build Coastguard Worker * Filter out all primitive-restart magic values, and generate a triangle list
337*61046927SAndroid Build Coastguard Worker * from the triangle fan definition.
338*61046927SAndroid Build Coastguard Worker *
339*61046927SAndroid Build Coastguard Worker * Basically:
340*61046927SAndroid Build Coastguard Worker *
341*61046927SAndroid Build Coastguard Worker * new_index_ptr = 0;
342*61046927SAndroid Build Coastguard Worker * index0 = restart_prim_value; // 0xffff or 0xffffffff
343*61046927SAndroid Build Coastguard Worker * for (old_index_ptr = firstIndex; old_index_ptr < indexCount;) {
344*61046927SAndroid Build Coastguard Worker * // If we have no starting-point we need at least 3 vertices,
345*61046927SAndroid Build Coastguard Worker * // otherwise we can do with two. If there's not enough vertices
346*61046927SAndroid Build Coastguard Worker * // to form a primitive, we just bail out.
347*61046927SAndroid Build Coastguard Worker * min_indices = index0 == restart_prim_value ? 3 : 2;
348*61046927SAndroid Build Coastguard Worker * if (old_index_ptr + min_indices > firstIndex + indexCount)
349*61046927SAndroid Build Coastguard Worker * break;
350*61046927SAndroid Build Coastguard Worker *
351*61046927SAndroid Build Coastguard Worker * if (index0 == restart_prim_value) {
352*61046927SAndroid Build Coastguard Worker * // No starting point, skip all entries until we have a
353*61046927SAndroid Build Coastguard Worker * // non-primitive-restart value
354*61046927SAndroid Build Coastguard Worker * index0 = old_index_buf[old_index_ptr++];
355*61046927SAndroid Build Coastguard Worker * continue;
356*61046927SAndroid Build Coastguard Worker * }
357*61046927SAndroid Build Coastguard Worker *
358*61046927SAndroid Build Coastguard Worker * // If at least one index contains the primitive-restart pattern,
359*61046927SAndroid Build Coastguard Worker // ignore this triangle, and skip the unused entries
360*61046927SAndroid Build Coastguard Worker * if (old_index_buf[old_index_ptr + 1] == restart_prim_value) {
361*61046927SAndroid Build Coastguard Worker * old_index_ptr += 2;
362*61046927SAndroid Build Coastguard Worker * continue;
363*61046927SAndroid Build Coastguard Worker * }
364*61046927SAndroid Build Coastguard Worker * if (old_index_buf[old_index_ptr] == restart_prim_value) {
365*61046927SAndroid Build Coastguard Worker * old_index_ptr++;
366*61046927SAndroid Build Coastguard Worker * continue;
367*61046927SAndroid Build Coastguard Worker * }
368*61046927SAndroid Build Coastguard Worker *
369*61046927SAndroid Build Coastguard Worker * // We have a valid primitive, queue it to the new index buffer
370*61046927SAndroid Build Coastguard Worker * new_index_buf[new_index_ptr++] = old_index_buf[old_index_ptr];
371*61046927SAndroid Build Coastguard Worker * new_index_buf[new_index_ptr++] = old_index_buf[old_index_ptr + 1];
372*61046927SAndroid Build Coastguard Worker * new_index_buf[new_index_ptr++] = index0;
373*61046927SAndroid Build Coastguard Worker * }
374*61046927SAndroid Build Coastguard Worker *
375*61046927SAndroid Build Coastguard Worker * expressed in NIR, which admitedly is not super easy to grasp with.
376*61046927SAndroid Build Coastguard Worker * TODO: Might be a good thing to use use the CL compiler we have and turn
377*61046927SAndroid Build Coastguard Worker * those shaders into CL kernels.
378*61046927SAndroid Build Coastguard Worker */
379*61046927SAndroid Build Coastguard Worker nir_push_loop(&b);
380*61046927SAndroid Build Coastguard Worker
381*61046927SAndroid Build Coastguard Worker old_index_ptr = nir_load_var(&b, old_index_ptr_var);
382*61046927SAndroid Build Coastguard Worker nir_def *index0 = nir_load_var(&b, index0_var);
383*61046927SAndroid Build Coastguard Worker
384*61046927SAndroid Build Coastguard Worker nir_def *read_index_count =
385*61046927SAndroid Build Coastguard Worker nir_bcsel(&b, nir_ieq(&b, index0, prim_restart_val),
386*61046927SAndroid Build Coastguard Worker nir_imm_int(&b, 3), nir_imm_int(&b, 2));
387*61046927SAndroid Build Coastguard Worker nir_push_if(&b, nir_ult(&b, old_index_count, nir_iadd(&b, old_index_ptr, read_index_count)));
388*61046927SAndroid Build Coastguard Worker nir_jump(&b, nir_jump_break);
389*61046927SAndroid Build Coastguard Worker nir_pop_if(&b, NULL);
390*61046927SAndroid Build Coastguard Worker
391*61046927SAndroid Build Coastguard Worker nir_def *old_index_offset =
392*61046927SAndroid Build Coastguard Worker nir_imul_imm(&b, old_index_ptr, old_index_size);
393*61046927SAndroid Build Coastguard Worker
394*61046927SAndroid Build Coastguard Worker nir_push_if(&b, nir_ieq(&b, index0, prim_restart_val));
395*61046927SAndroid Build Coastguard Worker nir_def *index_val =
396*61046927SAndroid Build Coastguard Worker nir_load_ssbo(&b, 1, 32, old_index_buf_desc,
397*61046927SAndroid Build Coastguard Worker old_index_size == 2 ? nir_iand_imm(&b, old_index_offset, ~3ULL) : old_index_offset,
398*61046927SAndroid Build Coastguard Worker .align_mul = 4);
399*61046927SAndroid Build Coastguard Worker if (old_index_size == 2) {
400*61046927SAndroid Build Coastguard Worker index_val = nir_bcsel(&b, nir_test_mask(&b, old_index_offset, 0x2),
401*61046927SAndroid Build Coastguard Worker nir_ushr_imm(&b, index_val, 16),
402*61046927SAndroid Build Coastguard Worker nir_iand_imm(&b, index_val, 0xffff));
403*61046927SAndroid Build Coastguard Worker }
404*61046927SAndroid Build Coastguard Worker
405*61046927SAndroid Build Coastguard Worker nir_store_var(&b, index0_var, index_val, 1);
406*61046927SAndroid Build Coastguard Worker nir_store_var(&b, old_index_ptr_var, nir_iadd_imm(&b, old_index_ptr, 1), 1);
407*61046927SAndroid Build Coastguard Worker nir_jump(&b, nir_jump_continue);
408*61046927SAndroid Build Coastguard Worker nir_pop_if(&b, NULL);
409*61046927SAndroid Build Coastguard Worker
410*61046927SAndroid Build Coastguard Worker nir_def *index12 =
411*61046927SAndroid Build Coastguard Worker nir_load_ssbo(&b, 2, 32, old_index_buf_desc,
412*61046927SAndroid Build Coastguard Worker old_index_size == 2 ? nir_iand_imm(&b, old_index_offset, ~3ULL) : old_index_offset,
413*61046927SAndroid Build Coastguard Worker .align_mul = 4);
414*61046927SAndroid Build Coastguard Worker if (old_index_size == 2) {
415*61046927SAndroid Build Coastguard Worker nir_def *indices[] = {
416*61046927SAndroid Build Coastguard Worker nir_iand_imm(&b, nir_channel(&b, index12, 0), 0xffff),
417*61046927SAndroid Build Coastguard Worker nir_ushr_imm(&b, nir_channel(&b, index12, 0), 16),
418*61046927SAndroid Build Coastguard Worker nir_iand_imm(&b, nir_channel(&b, index12, 1), 0xffff),
419*61046927SAndroid Build Coastguard Worker };
420*61046927SAndroid Build Coastguard Worker
421*61046927SAndroid Build Coastguard Worker index12 = nir_bcsel(&b, nir_test_mask(&b, old_index_offset, 0x2),
422*61046927SAndroid Build Coastguard Worker nir_vec2(&b, indices[1], indices[2]),
423*61046927SAndroid Build Coastguard Worker nir_vec2(&b, indices[0], indices[1]));
424*61046927SAndroid Build Coastguard Worker }
425*61046927SAndroid Build Coastguard Worker
426*61046927SAndroid Build Coastguard Worker nir_push_if(&b, nir_ieq(&b, nir_channel(&b, index12, 1), prim_restart_val));
427*61046927SAndroid Build Coastguard Worker nir_store_var(&b, old_index_ptr_var, nir_iadd_imm(&b, old_index_ptr, 2), 1);
428*61046927SAndroid Build Coastguard Worker nir_store_var(&b, index0_var, prim_restart_val, 1);
429*61046927SAndroid Build Coastguard Worker nir_jump(&b, nir_jump_continue);
430*61046927SAndroid Build Coastguard Worker nir_push_else(&b, NULL);
431*61046927SAndroid Build Coastguard Worker nir_store_var(&b, old_index_ptr_var, nir_iadd_imm(&b, old_index_ptr, 1), 1);
432*61046927SAndroid Build Coastguard Worker nir_push_if(&b, nir_ieq(&b, nir_channel(&b, index12, 0), prim_restart_val));
433*61046927SAndroid Build Coastguard Worker nir_store_var(&b, index0_var, prim_restart_val, 1);
434*61046927SAndroid Build Coastguard Worker nir_jump(&b, nir_jump_continue);
435*61046927SAndroid Build Coastguard Worker nir_push_else(&b, NULL);
436*61046927SAndroid Build Coastguard Worker nir_def *new_indices =
437*61046927SAndroid Build Coastguard Worker nir_vec3(&b, nir_channel(&b, index12, 0), nir_channel(&b, index12, 1), index0);
438*61046927SAndroid Build Coastguard Worker nir_def *new_index_ptr = nir_load_var(&b, new_index_ptr_var);
439*61046927SAndroid Build Coastguard Worker nir_def *new_index_offset = nir_imul_imm(&b, new_index_ptr, sizeof(uint32_t));
440*61046927SAndroid Build Coastguard Worker nir_store_ssbo(&b, new_indices, new_index_buf_desc,
441*61046927SAndroid Build Coastguard Worker new_index_offset,
442*61046927SAndroid Build Coastguard Worker .write_mask = 7, .access = ACCESS_NON_READABLE, .align_mul = 4);
443*61046927SAndroid Build Coastguard Worker nir_store_var(&b, new_index_ptr_var, nir_iadd_imm(&b, new_index_ptr, 3), 1);
444*61046927SAndroid Build Coastguard Worker nir_pop_if(&b, NULL);
445*61046927SAndroid Build Coastguard Worker nir_pop_if(&b, NULL);
446*61046927SAndroid Build Coastguard Worker nir_pop_loop(&b, NULL);
447*61046927SAndroid Build Coastguard Worker
448*61046927SAndroid Build Coastguard Worker nir_store_ssbo(&b, nir_load_var(&b, new_index_ptr_var),
449*61046927SAndroid Build Coastguard Worker new_index_count_ptr_desc, nir_imm_int(&b, 0),
450*61046927SAndroid Build Coastguard Worker .write_mask = 1, .access = ACCESS_NON_READABLE, .align_mul = 4);
451*61046927SAndroid Build Coastguard Worker
452*61046927SAndroid Build Coastguard Worker return b.shader;
453*61046927SAndroid Build Coastguard Worker }
454*61046927SAndroid Build Coastguard Worker
455*61046927SAndroid Build Coastguard Worker nir_shader *
dzn_nir_triangle_fan_rewrite_index_shader(uint8_t old_index_size)456*61046927SAndroid Build Coastguard Worker dzn_nir_triangle_fan_rewrite_index_shader(uint8_t old_index_size)
457*61046927SAndroid Build Coastguard Worker {
458*61046927SAndroid Build Coastguard Worker assert(old_index_size == 0 || old_index_size == 2 || old_index_size == 4);
459*61046927SAndroid Build Coastguard Worker
460*61046927SAndroid Build Coastguard Worker nir_builder b =
461*61046927SAndroid Build Coastguard Worker nir_builder_init_simple_shader(MESA_SHADER_COMPUTE,
462*61046927SAndroid Build Coastguard Worker dxil_get_base_nir_compiler_options(),
463*61046927SAndroid Build Coastguard Worker "dzn_meta_triangle_rewrite_index(old_index_size=%d)",
464*61046927SAndroid Build Coastguard Worker old_index_size);
465*61046927SAndroid Build Coastguard Worker b.shader->info.internal = true;
466*61046927SAndroid Build Coastguard Worker
467*61046927SAndroid Build Coastguard Worker nir_def *params_desc =
468*61046927SAndroid Build Coastguard Worker dzn_nir_create_bo_desc(&b, nir_var_mem_ubo, 0, 0, "params", 0);
469*61046927SAndroid Build Coastguard Worker nir_def *new_index_buf_desc =
470*61046927SAndroid Build Coastguard Worker dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 1,
471*61046927SAndroid Build Coastguard Worker "new_index_buf", ACCESS_NON_READABLE);
472*61046927SAndroid Build Coastguard Worker
473*61046927SAndroid Build Coastguard Worker nir_def *old_index_buf_desc = NULL;
474*61046927SAndroid Build Coastguard Worker if (old_index_size > 0) {
475*61046927SAndroid Build Coastguard Worker old_index_buf_desc =
476*61046927SAndroid Build Coastguard Worker dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 2,
477*61046927SAndroid Build Coastguard Worker "old_index_buf", ACCESS_NON_WRITEABLE);
478*61046927SAndroid Build Coastguard Worker }
479*61046927SAndroid Build Coastguard Worker
480*61046927SAndroid Build Coastguard Worker nir_def *params =
481*61046927SAndroid Build Coastguard Worker nir_load_ubo(&b, sizeof(struct dzn_triangle_fan_rewrite_index_params) / 4, 32,
482*61046927SAndroid Build Coastguard Worker params_desc, nir_imm_int(&b, 0),
483*61046927SAndroid Build Coastguard Worker .align_mul = 4, .align_offset = 0, .range_base = 0, .range = ~0);
484*61046927SAndroid Build Coastguard Worker
485*61046927SAndroid Build Coastguard Worker nir_def *triangle = nir_channel(&b, nir_load_global_invocation_id(&b, 32), 0);
486*61046927SAndroid Build Coastguard Worker nir_def *new_indices;
487*61046927SAndroid Build Coastguard Worker
488*61046927SAndroid Build Coastguard Worker if (old_index_size > 0) {
489*61046927SAndroid Build Coastguard Worker nir_def *old_first_index = nir_channel(&b, params, 0);
490*61046927SAndroid Build Coastguard Worker nir_def *old_index0_offset =
491*61046927SAndroid Build Coastguard Worker nir_imul_imm(&b, old_first_index, old_index_size);
492*61046927SAndroid Build Coastguard Worker nir_def *old_index1_offset =
493*61046927SAndroid Build Coastguard Worker nir_imul_imm(&b, nir_iadd(&b, nir_iadd_imm(&b, triangle, 1), old_first_index),
494*61046927SAndroid Build Coastguard Worker old_index_size);
495*61046927SAndroid Build Coastguard Worker
496*61046927SAndroid Build Coastguard Worker nir_def *old_index0 =
497*61046927SAndroid Build Coastguard Worker nir_load_ssbo(&b, 1, 32, old_index_buf_desc,
498*61046927SAndroid Build Coastguard Worker old_index_size == 2 ? nir_iand_imm(&b, old_index0_offset, ~3ULL) : old_index0_offset,
499*61046927SAndroid Build Coastguard Worker .align_mul = 4);
500*61046927SAndroid Build Coastguard Worker
501*61046927SAndroid Build Coastguard Worker if (old_index_size == 2) {
502*61046927SAndroid Build Coastguard Worker old_index0 = nir_bcsel(&b, nir_test_mask(&b, old_index0_offset, 0x2),
503*61046927SAndroid Build Coastguard Worker nir_ushr_imm(&b, old_index0, 16),
504*61046927SAndroid Build Coastguard Worker nir_iand_imm(&b, old_index0, 0xffff));
505*61046927SAndroid Build Coastguard Worker }
506*61046927SAndroid Build Coastguard Worker
507*61046927SAndroid Build Coastguard Worker nir_def *old_index12 =
508*61046927SAndroid Build Coastguard Worker nir_load_ssbo(&b, 2, 32, old_index_buf_desc,
509*61046927SAndroid Build Coastguard Worker old_index_size == 2 ? nir_iand_imm(&b, old_index1_offset, ~3ULL) : old_index1_offset,
510*61046927SAndroid Build Coastguard Worker .align_mul = 4);
511*61046927SAndroid Build Coastguard Worker if (old_index_size == 2) {
512*61046927SAndroid Build Coastguard Worker nir_def *indices[] = {
513*61046927SAndroid Build Coastguard Worker nir_iand_imm(&b, nir_channel(&b, old_index12, 0), 0xffff),
514*61046927SAndroid Build Coastguard Worker nir_ushr_imm(&b, nir_channel(&b, old_index12, 0), 16),
515*61046927SAndroid Build Coastguard Worker nir_iand_imm(&b, nir_channel(&b, old_index12, 1), 0xffff),
516*61046927SAndroid Build Coastguard Worker };
517*61046927SAndroid Build Coastguard Worker
518*61046927SAndroid Build Coastguard Worker old_index12 = nir_bcsel(&b, nir_test_mask(&b, old_index1_offset, 0x2),
519*61046927SAndroid Build Coastguard Worker nir_vec2(&b, indices[1], indices[2]),
520*61046927SAndroid Build Coastguard Worker nir_vec2(&b, indices[0], indices[1]));
521*61046927SAndroid Build Coastguard Worker }
522*61046927SAndroid Build Coastguard Worker
523*61046927SAndroid Build Coastguard Worker /* TODO: VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT */
524*61046927SAndroid Build Coastguard Worker new_indices =
525*61046927SAndroid Build Coastguard Worker nir_vec3(&b, nir_channel(&b, old_index12, 0),
526*61046927SAndroid Build Coastguard Worker nir_channel(&b, old_index12, 1), old_index0);
527*61046927SAndroid Build Coastguard Worker } else {
528*61046927SAndroid Build Coastguard Worker new_indices =
529*61046927SAndroid Build Coastguard Worker nir_vec3(&b,
530*61046927SAndroid Build Coastguard Worker nir_iadd_imm(&b, triangle, 1),
531*61046927SAndroid Build Coastguard Worker nir_iadd_imm(&b, triangle, 2),
532*61046927SAndroid Build Coastguard Worker nir_imm_int(&b, 0));
533*61046927SAndroid Build Coastguard Worker }
534*61046927SAndroid Build Coastguard Worker
535*61046927SAndroid Build Coastguard Worker nir_def *new_index_offset =
536*61046927SAndroid Build Coastguard Worker nir_imul_imm(&b, triangle, 4 * 3);
537*61046927SAndroid Build Coastguard Worker
538*61046927SAndroid Build Coastguard Worker nir_store_ssbo(&b, new_indices, new_index_buf_desc,
539*61046927SAndroid Build Coastguard Worker new_index_offset,
540*61046927SAndroid Build Coastguard Worker .write_mask = 7, .access = ACCESS_NON_READABLE, .align_mul = 4);
541*61046927SAndroid Build Coastguard Worker
542*61046927SAndroid Build Coastguard Worker return b.shader;
543*61046927SAndroid Build Coastguard Worker }
544*61046927SAndroid Build Coastguard Worker
545*61046927SAndroid Build Coastguard Worker nir_shader *
dzn_nir_blit_vs(void)546*61046927SAndroid Build Coastguard Worker dzn_nir_blit_vs(void)
547*61046927SAndroid Build Coastguard Worker {
548*61046927SAndroid Build Coastguard Worker nir_builder b =
549*61046927SAndroid Build Coastguard Worker nir_builder_init_simple_shader(MESA_SHADER_VERTEX,
550*61046927SAndroid Build Coastguard Worker dxil_get_base_nir_compiler_options(),
551*61046927SAndroid Build Coastguard Worker "dzn_meta_blit_vs()");
552*61046927SAndroid Build Coastguard Worker b.shader->info.internal = true;
553*61046927SAndroid Build Coastguard Worker
554*61046927SAndroid Build Coastguard Worker nir_def *params_desc =
555*61046927SAndroid Build Coastguard Worker dzn_nir_create_bo_desc(&b, nir_var_mem_ubo, 0, 0, "params", 0);
556*61046927SAndroid Build Coastguard Worker
557*61046927SAndroid Build Coastguard Worker nir_variable *out_pos =
558*61046927SAndroid Build Coastguard Worker nir_variable_create(b.shader, nir_var_shader_out, glsl_vec4_type(),
559*61046927SAndroid Build Coastguard Worker "gl_Position");
560*61046927SAndroid Build Coastguard Worker out_pos->data.location = VARYING_SLOT_POS;
561*61046927SAndroid Build Coastguard Worker out_pos->data.driver_location = 0;
562*61046927SAndroid Build Coastguard Worker
563*61046927SAndroid Build Coastguard Worker nir_variable *out_coords =
564*61046927SAndroid Build Coastguard Worker nir_variable_create(b.shader, nir_var_shader_out, glsl_vec_type(3),
565*61046927SAndroid Build Coastguard Worker "coords");
566*61046927SAndroid Build Coastguard Worker out_coords->data.location = VARYING_SLOT_TEX0;
567*61046927SAndroid Build Coastguard Worker out_coords->data.driver_location = 1;
568*61046927SAndroid Build Coastguard Worker
569*61046927SAndroid Build Coastguard Worker nir_def *vertex = nir_load_vertex_id(&b);
570*61046927SAndroid Build Coastguard Worker nir_def *coords_arr[4] = {
571*61046927SAndroid Build Coastguard Worker nir_load_ubo(&b, 4, 32, params_desc, nir_imm_int(&b, 0),
572*61046927SAndroid Build Coastguard Worker .align_mul = 16, .align_offset = 0, .range_base = 0, .range = ~0),
573*61046927SAndroid Build Coastguard Worker nir_load_ubo(&b, 4, 32, params_desc, nir_imm_int(&b, 16),
574*61046927SAndroid Build Coastguard Worker .align_mul = 16, .align_offset = 0, .range_base = 0, .range = ~0),
575*61046927SAndroid Build Coastguard Worker nir_load_ubo(&b, 4, 32, params_desc, nir_imm_int(&b, 32),
576*61046927SAndroid Build Coastguard Worker .align_mul = 16, .align_offset = 0, .range_base = 0, .range = ~0),
577*61046927SAndroid Build Coastguard Worker nir_load_ubo(&b, 4, 32, params_desc, nir_imm_int(&b, 48),
578*61046927SAndroid Build Coastguard Worker .align_mul = 16, .align_offset = 0, .range_base = 0, .range = ~0),
579*61046927SAndroid Build Coastguard Worker };
580*61046927SAndroid Build Coastguard Worker nir_def *coords =
581*61046927SAndroid Build Coastguard Worker nir_bcsel(&b, nir_ieq_imm(&b, vertex, 0), coords_arr[0],
582*61046927SAndroid Build Coastguard Worker nir_bcsel(&b, nir_ieq_imm(&b, vertex, 1), coords_arr[1],
583*61046927SAndroid Build Coastguard Worker nir_bcsel(&b, nir_ieq_imm(&b, vertex, 2), coords_arr[2], coords_arr[3])));
584*61046927SAndroid Build Coastguard Worker nir_def *pos =
585*61046927SAndroid Build Coastguard Worker nir_vec4(&b, nir_channel(&b, coords, 0), nir_channel(&b, coords, 1),
586*61046927SAndroid Build Coastguard Worker nir_imm_float(&b, 0.0), nir_imm_float(&b, 1.0));
587*61046927SAndroid Build Coastguard Worker nir_def *z_coord =
588*61046927SAndroid Build Coastguard Worker nir_load_ubo(&b, 1, 32, params_desc, nir_imm_int(&b, 4 * 4 * sizeof(float)),
589*61046927SAndroid Build Coastguard Worker .align_mul = 64, .align_offset = 0, .range_base = 0, .range = ~0);
590*61046927SAndroid Build Coastguard Worker coords = nir_vec3(&b, nir_channel(&b, coords, 2), nir_channel(&b, coords, 3), z_coord);
591*61046927SAndroid Build Coastguard Worker
592*61046927SAndroid Build Coastguard Worker nir_store_var(&b, out_pos, pos, 0xf);
593*61046927SAndroid Build Coastguard Worker nir_store_var(&b, out_coords, coords, 0x7);
594*61046927SAndroid Build Coastguard Worker return b.shader;
595*61046927SAndroid Build Coastguard Worker }
596*61046927SAndroid Build Coastguard Worker
597*61046927SAndroid Build Coastguard Worker nir_shader *
dzn_nir_blit_fs(const struct dzn_nir_blit_info * info)598*61046927SAndroid Build Coastguard Worker dzn_nir_blit_fs(const struct dzn_nir_blit_info *info)
599*61046927SAndroid Build Coastguard Worker {
600*61046927SAndroid Build Coastguard Worker bool ms = info->src_samples > 1;
601*61046927SAndroid Build Coastguard Worker nir_alu_type nir_out_type =
602*61046927SAndroid Build Coastguard Worker nir_get_nir_type_for_glsl_base_type(info->out_type);
603*61046927SAndroid Build Coastguard Worker uint32_t coord_comps =
604*61046927SAndroid Build Coastguard Worker glsl_get_sampler_dim_coordinate_components(info->sampler_dim) +
605*61046927SAndroid Build Coastguard Worker info->src_is_array;
606*61046927SAndroid Build Coastguard Worker
607*61046927SAndroid Build Coastguard Worker nir_builder b =
608*61046927SAndroid Build Coastguard Worker nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT,
609*61046927SAndroid Build Coastguard Worker dxil_get_base_nir_compiler_options(),
610*61046927SAndroid Build Coastguard Worker "dzn_meta_blit_fs()");
611*61046927SAndroid Build Coastguard Worker b.shader->info.internal = true;
612*61046927SAndroid Build Coastguard Worker
613*61046927SAndroid Build Coastguard Worker const struct glsl_type *tex_type =
614*61046927SAndroid Build Coastguard Worker glsl_texture_type(info->sampler_dim, info->src_is_array, info->out_type);
615*61046927SAndroid Build Coastguard Worker nir_variable *tex_var =
616*61046927SAndroid Build Coastguard Worker nir_variable_create(b.shader, nir_var_uniform, tex_type, "texture");
617*61046927SAndroid Build Coastguard Worker nir_deref_instr *tex_deref = nir_build_deref_var(&b, tex_var);
618*61046927SAndroid Build Coastguard Worker
619*61046927SAndroid Build Coastguard Worker nir_variable *pos_var =
620*61046927SAndroid Build Coastguard Worker nir_variable_create(b.shader, nir_var_shader_in,
621*61046927SAndroid Build Coastguard Worker glsl_vector_type(GLSL_TYPE_FLOAT, 4),
622*61046927SAndroid Build Coastguard Worker "gl_FragCoord");
623*61046927SAndroid Build Coastguard Worker pos_var->data.location = VARYING_SLOT_POS;
624*61046927SAndroid Build Coastguard Worker pos_var->data.driver_location = 0;
625*61046927SAndroid Build Coastguard Worker
626*61046927SAndroid Build Coastguard Worker nir_variable *coord_var =
627*61046927SAndroid Build Coastguard Worker nir_variable_create(b.shader, nir_var_shader_in,
628*61046927SAndroid Build Coastguard Worker glsl_vector_type(GLSL_TYPE_FLOAT, 3),
629*61046927SAndroid Build Coastguard Worker "coord");
630*61046927SAndroid Build Coastguard Worker coord_var->data.location = VARYING_SLOT_TEX0;
631*61046927SAndroid Build Coastguard Worker coord_var->data.driver_location = 1;
632*61046927SAndroid Build Coastguard Worker nir_def *coord =
633*61046927SAndroid Build Coastguard Worker nir_trim_vector(&b, nir_load_var(&b, coord_var), coord_comps);
634*61046927SAndroid Build Coastguard Worker
635*61046927SAndroid Build Coastguard Worker uint32_t out_comps =
636*61046927SAndroid Build Coastguard Worker (info->loc == FRAG_RESULT_DEPTH || info->loc == FRAG_RESULT_STENCIL) ? 1 : 4;
637*61046927SAndroid Build Coastguard Worker nir_variable *out = NULL;
638*61046927SAndroid Build Coastguard Worker if (!info->stencil_fallback) {
639*61046927SAndroid Build Coastguard Worker out = nir_variable_create(b.shader, nir_var_shader_out,
640*61046927SAndroid Build Coastguard Worker glsl_vector_type(info->out_type, out_comps),
641*61046927SAndroid Build Coastguard Worker "out");
642*61046927SAndroid Build Coastguard Worker out->data.location = info->loc;
643*61046927SAndroid Build Coastguard Worker }
644*61046927SAndroid Build Coastguard Worker
645*61046927SAndroid Build Coastguard Worker nir_def *res = NULL;
646*61046927SAndroid Build Coastguard Worker
647*61046927SAndroid Build Coastguard Worker if (info->resolve_mode != dzn_blit_resolve_none) {
648*61046927SAndroid Build Coastguard Worker enum dzn_blit_resolve_mode resolve_mode = info->resolve_mode;
649*61046927SAndroid Build Coastguard Worker
650*61046927SAndroid Build Coastguard Worker nir_op resolve_op = nir_op_mov;
651*61046927SAndroid Build Coastguard Worker switch (resolve_mode) {
652*61046927SAndroid Build Coastguard Worker case dzn_blit_resolve_average:
653*61046927SAndroid Build Coastguard Worker /* When resolving a float type, we need to calculate the average of all
654*61046927SAndroid Build Coastguard Worker * samples. For integer resolve, Vulkan says that one sample should be
655*61046927SAndroid Build Coastguard Worker * chosen without telling which. Let's just pick the first one in that
656*61046927SAndroid Build Coastguard Worker * case.
657*61046927SAndroid Build Coastguard Worker */
658*61046927SAndroid Build Coastguard Worker if (info->out_type == GLSL_TYPE_FLOAT)
659*61046927SAndroid Build Coastguard Worker resolve_op = nir_op_fadd;
660*61046927SAndroid Build Coastguard Worker else
661*61046927SAndroid Build Coastguard Worker resolve_mode = dzn_blit_resolve_sample_zero;
662*61046927SAndroid Build Coastguard Worker break;
663*61046927SAndroid Build Coastguard Worker case dzn_blit_resolve_min:
664*61046927SAndroid Build Coastguard Worker switch (info->out_type) {
665*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT: resolve_op = nir_op_fmin; break;
666*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT: resolve_op = nir_op_imin; break;
667*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT: resolve_op = nir_op_umin; break;
668*61046927SAndroid Build Coastguard Worker }
669*61046927SAndroid Build Coastguard Worker break;
670*61046927SAndroid Build Coastguard Worker case dzn_blit_resolve_max:
671*61046927SAndroid Build Coastguard Worker switch (info->out_type) {
672*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_FLOAT: resolve_op = nir_op_fmax; break;
673*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_INT: resolve_op = nir_op_imax; break;
674*61046927SAndroid Build Coastguard Worker case GLSL_TYPE_UINT: resolve_op = nir_op_umax; break;
675*61046927SAndroid Build Coastguard Worker }
676*61046927SAndroid Build Coastguard Worker break;
677*61046927SAndroid Build Coastguard Worker case dzn_blit_resolve_none:
678*61046927SAndroid Build Coastguard Worker case dzn_blit_resolve_sample_zero:
679*61046927SAndroid Build Coastguard Worker break;
680*61046927SAndroid Build Coastguard Worker }
681*61046927SAndroid Build Coastguard Worker
682*61046927SAndroid Build Coastguard Worker unsigned nsamples = resolve_mode == dzn_blit_resolve_sample_zero ?
683*61046927SAndroid Build Coastguard Worker 1 : info->src_samples;
684*61046927SAndroid Build Coastguard Worker for (unsigned s = 0; s < nsamples; s++) {
685*61046927SAndroid Build Coastguard Worker nir_tex_instr *tex = nir_tex_instr_create(b.shader, 4);
686*61046927SAndroid Build Coastguard Worker
687*61046927SAndroid Build Coastguard Worker tex->op = nir_texop_txf_ms;
688*61046927SAndroid Build Coastguard Worker tex->dest_type = nir_out_type;
689*61046927SAndroid Build Coastguard Worker tex->texture_index = 0;
690*61046927SAndroid Build Coastguard Worker tex->is_array = info->src_is_array;
691*61046927SAndroid Build Coastguard Worker tex->sampler_dim = info->sampler_dim;
692*61046927SAndroid Build Coastguard Worker
693*61046927SAndroid Build Coastguard Worker tex->src[0] = nir_tex_src_for_ssa(nir_tex_src_coord,
694*61046927SAndroid Build Coastguard Worker nir_f2i32(&b, coord));
695*61046927SAndroid Build Coastguard Worker tex->coord_components = coord_comps;
696*61046927SAndroid Build Coastguard Worker
697*61046927SAndroid Build Coastguard Worker tex->src[1] = nir_tex_src_for_ssa(nir_tex_src_ms_index,
698*61046927SAndroid Build Coastguard Worker nir_imm_int(&b, s));
699*61046927SAndroid Build Coastguard Worker
700*61046927SAndroid Build Coastguard Worker tex->src[2] = nir_tex_src_for_ssa(nir_tex_src_lod,
701*61046927SAndroid Build Coastguard Worker nir_imm_int(&b, 0));
702*61046927SAndroid Build Coastguard Worker
703*61046927SAndroid Build Coastguard Worker tex->src[3] = nir_tex_src_for_ssa(nir_tex_src_texture_deref,
704*61046927SAndroid Build Coastguard Worker &tex_deref->def);
705*61046927SAndroid Build Coastguard Worker
706*61046927SAndroid Build Coastguard Worker nir_def_init(&tex->instr, &tex->def, 4, 32);
707*61046927SAndroid Build Coastguard Worker
708*61046927SAndroid Build Coastguard Worker nir_builder_instr_insert(&b, &tex->instr);
709*61046927SAndroid Build Coastguard Worker res = res ? nir_build_alu2(&b, resolve_op, res, &tex->def) : &tex->def;
710*61046927SAndroid Build Coastguard Worker }
711*61046927SAndroid Build Coastguard Worker
712*61046927SAndroid Build Coastguard Worker if (resolve_mode == dzn_blit_resolve_average)
713*61046927SAndroid Build Coastguard Worker res = nir_fmul_imm(&b, res, 1.0f / nsamples);
714*61046927SAndroid Build Coastguard Worker } else {
715*61046927SAndroid Build Coastguard Worker nir_tex_instr *tex =
716*61046927SAndroid Build Coastguard Worker nir_tex_instr_create(b.shader, ms ? 4 : 3);
717*61046927SAndroid Build Coastguard Worker
718*61046927SAndroid Build Coastguard Worker tex->dest_type = nir_out_type;
719*61046927SAndroid Build Coastguard Worker tex->is_array = info->src_is_array;
720*61046927SAndroid Build Coastguard Worker tex->sampler_dim = info->sampler_dim;
721*61046927SAndroid Build Coastguard Worker
722*61046927SAndroid Build Coastguard Worker if (ms) {
723*61046927SAndroid Build Coastguard Worker tex->op = nir_texop_txf_ms;
724*61046927SAndroid Build Coastguard Worker
725*61046927SAndroid Build Coastguard Worker tex->src[0] = nir_tex_src_for_ssa(nir_tex_src_coord,
726*61046927SAndroid Build Coastguard Worker nir_f2i32(&b, coord));
727*61046927SAndroid Build Coastguard Worker tex->coord_components = coord_comps;
728*61046927SAndroid Build Coastguard Worker
729*61046927SAndroid Build Coastguard Worker tex->src[1] = nir_tex_src_for_ssa(nir_tex_src_ms_index,
730*61046927SAndroid Build Coastguard Worker nir_load_sample_id(&b));
731*61046927SAndroid Build Coastguard Worker
732*61046927SAndroid Build Coastguard Worker tex->src[2] = nir_tex_src_for_ssa(nir_tex_src_lod,
733*61046927SAndroid Build Coastguard Worker nir_imm_int(&b, 0));
734*61046927SAndroid Build Coastguard Worker
735*61046927SAndroid Build Coastguard Worker tex->src[3] = nir_tex_src_for_ssa(nir_tex_src_texture_deref,
736*61046927SAndroid Build Coastguard Worker &tex_deref->def);
737*61046927SAndroid Build Coastguard Worker } else {
738*61046927SAndroid Build Coastguard Worker nir_variable *sampler_var =
739*61046927SAndroid Build Coastguard Worker nir_variable_create(b.shader, nir_var_uniform, glsl_bare_sampler_type(), "sampler");
740*61046927SAndroid Build Coastguard Worker nir_deref_instr *sampler_deref = nir_build_deref_var(&b, sampler_var);
741*61046927SAndroid Build Coastguard Worker
742*61046927SAndroid Build Coastguard Worker tex->op = nir_texop_tex;
743*61046927SAndroid Build Coastguard Worker tex->sampler_index = 0;
744*61046927SAndroid Build Coastguard Worker
745*61046927SAndroid Build Coastguard Worker tex->src[0] = nir_tex_src_for_ssa(nir_tex_src_coord, coord);
746*61046927SAndroid Build Coastguard Worker tex->coord_components = coord_comps;
747*61046927SAndroid Build Coastguard Worker
748*61046927SAndroid Build Coastguard Worker tex->src[1] = nir_tex_src_for_ssa(nir_tex_src_texture_deref,
749*61046927SAndroid Build Coastguard Worker &tex_deref->def);
750*61046927SAndroid Build Coastguard Worker
751*61046927SAndroid Build Coastguard Worker tex->src[2] = nir_tex_src_for_ssa(nir_tex_src_sampler_deref,
752*61046927SAndroid Build Coastguard Worker &sampler_deref->def);
753*61046927SAndroid Build Coastguard Worker }
754*61046927SAndroid Build Coastguard Worker
755*61046927SAndroid Build Coastguard Worker nir_def_init(&tex->instr, &tex->def, 4, 32);
756*61046927SAndroid Build Coastguard Worker nir_builder_instr_insert(&b, &tex->instr);
757*61046927SAndroid Build Coastguard Worker res = &tex->def;
758*61046927SAndroid Build Coastguard Worker }
759*61046927SAndroid Build Coastguard Worker
760*61046927SAndroid Build Coastguard Worker if (info->stencil_fallback) {
761*61046927SAndroid Build Coastguard Worker nir_def *mask_desc =
762*61046927SAndroid Build Coastguard Worker dzn_nir_create_bo_desc(&b, nir_var_mem_ubo, 0, 0, "mask", 0);
763*61046927SAndroid Build Coastguard Worker nir_def *mask = nir_load_ubo(&b, 1, 32, mask_desc, nir_imm_int(&b, 0),
764*61046927SAndroid Build Coastguard Worker .align_mul = 16, .align_offset = 0, .range_base = 0, .range = ~0);
765*61046927SAndroid Build Coastguard Worker nir_def *fail = nir_ieq_imm(&b, nir_iand(&b, nir_channel(&b, res, 0), mask), 0);
766*61046927SAndroid Build Coastguard Worker nir_discard_if(&b, fail);
767*61046927SAndroid Build Coastguard Worker } else {
768*61046927SAndroid Build Coastguard Worker nir_store_var(&b, out, nir_trim_vector(&b, res, out_comps), 0xf);
769*61046927SAndroid Build Coastguard Worker }
770*61046927SAndroid Build Coastguard Worker
771*61046927SAndroid Build Coastguard Worker return b.shader;
772*61046927SAndroid Build Coastguard Worker }
773*61046927SAndroid Build Coastguard Worker
774*61046927SAndroid Build Coastguard Worker static nir_def *
cull_face(nir_builder * b,nir_variable * vertices,bool ccw)775*61046927SAndroid Build Coastguard Worker cull_face(nir_builder *b, nir_variable *vertices, bool ccw)
776*61046927SAndroid Build Coastguard Worker {
777*61046927SAndroid Build Coastguard Worker nir_def *v0 =
778*61046927SAndroid Build Coastguard Worker nir_load_deref(b, nir_build_deref_array(b, nir_build_deref_var(b, vertices), nir_imm_int(b, 0)));
779*61046927SAndroid Build Coastguard Worker nir_def *v1 =
780*61046927SAndroid Build Coastguard Worker nir_load_deref(b, nir_build_deref_array(b, nir_build_deref_var(b, vertices), nir_imm_int(b, 1)));
781*61046927SAndroid Build Coastguard Worker nir_def *v2 =
782*61046927SAndroid Build Coastguard Worker nir_load_deref(b, nir_build_deref_array(b, nir_build_deref_var(b, vertices), nir_imm_int(b, 2)));
783*61046927SAndroid Build Coastguard Worker
784*61046927SAndroid Build Coastguard Worker nir_def *dir = nir_fdot(b, nir_cross4(b, nir_fsub(b, v1, v0),
785*61046927SAndroid Build Coastguard Worker nir_fsub(b, v2, v0)),
786*61046927SAndroid Build Coastguard Worker nir_imm_vec4(b, 0.0, 0.0, -1.0, 0.0));
787*61046927SAndroid Build Coastguard Worker if (ccw)
788*61046927SAndroid Build Coastguard Worker return nir_fle_imm(b, dir, 0.0f);
789*61046927SAndroid Build Coastguard Worker else
790*61046927SAndroid Build Coastguard Worker return nir_fgt_imm(b, dir, 0.0f);
791*61046927SAndroid Build Coastguard Worker }
792*61046927SAndroid Build Coastguard Worker
793*61046927SAndroid Build Coastguard Worker static void
copy_vars(nir_builder * b,nir_deref_instr * dst,nir_deref_instr * src)794*61046927SAndroid Build Coastguard Worker copy_vars(nir_builder *b, nir_deref_instr *dst, nir_deref_instr *src)
795*61046927SAndroid Build Coastguard Worker {
796*61046927SAndroid Build Coastguard Worker assert(glsl_get_bare_type(dst->type) == glsl_get_bare_type(src->type));
797*61046927SAndroid Build Coastguard Worker if (glsl_type_is_struct(dst->type)) {
798*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < glsl_get_length(dst->type); ++i) {
799*61046927SAndroid Build Coastguard Worker copy_vars(b, nir_build_deref_struct(b, dst, i), nir_build_deref_struct(b, src, i));
800*61046927SAndroid Build Coastguard Worker }
801*61046927SAndroid Build Coastguard Worker } else if (glsl_type_is_array_or_matrix(dst->type)) {
802*61046927SAndroid Build Coastguard Worker copy_vars(b, nir_build_deref_array_wildcard(b, dst), nir_build_deref_array_wildcard(b, src));
803*61046927SAndroid Build Coastguard Worker } else {
804*61046927SAndroid Build Coastguard Worker nir_copy_deref(b, dst, src);
805*61046927SAndroid Build Coastguard Worker }
806*61046927SAndroid Build Coastguard Worker }
807*61046927SAndroid Build Coastguard Worker
808*61046927SAndroid Build Coastguard Worker static nir_def *
load_dynamic_depth_bias(nir_builder * b,struct dzn_nir_point_gs_info * info)809*61046927SAndroid Build Coastguard Worker load_dynamic_depth_bias(nir_builder *b, struct dzn_nir_point_gs_info *info)
810*61046927SAndroid Build Coastguard Worker {
811*61046927SAndroid Build Coastguard Worker nir_address_format ubo_format = nir_address_format_32bit_index_offset;
812*61046927SAndroid Build Coastguard Worker unsigned offset = offsetof(struct dxil_spirv_vertex_runtime_data, depth_bias);
813*61046927SAndroid Build Coastguard Worker
814*61046927SAndroid Build Coastguard Worker nir_def *index = nir_vulkan_resource_index(
815*61046927SAndroid Build Coastguard Worker b, nir_address_format_num_components(ubo_format),
816*61046927SAndroid Build Coastguard Worker nir_address_format_bit_size(ubo_format),
817*61046927SAndroid Build Coastguard Worker nir_imm_int(b, 0),
818*61046927SAndroid Build Coastguard Worker .desc_set = info->runtime_data_cbv.register_space,
819*61046927SAndroid Build Coastguard Worker .binding = info->runtime_data_cbv.base_shader_register,
820*61046927SAndroid Build Coastguard Worker .desc_type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
821*61046927SAndroid Build Coastguard Worker
822*61046927SAndroid Build Coastguard Worker nir_def *load_desc = nir_load_vulkan_descriptor(
823*61046927SAndroid Build Coastguard Worker b, nir_address_format_num_components(ubo_format),
824*61046927SAndroid Build Coastguard Worker nir_address_format_bit_size(ubo_format),
825*61046927SAndroid Build Coastguard Worker index, .desc_type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
826*61046927SAndroid Build Coastguard Worker
827*61046927SAndroid Build Coastguard Worker return nir_load_ubo(
828*61046927SAndroid Build Coastguard Worker b, 1, 32,
829*61046927SAndroid Build Coastguard Worker nir_channel(b, load_desc, 0),
830*61046927SAndroid Build Coastguard Worker nir_imm_int(b, offset),
831*61046927SAndroid Build Coastguard Worker .align_mul = 256,
832*61046927SAndroid Build Coastguard Worker .align_offset = offset);
833*61046927SAndroid Build Coastguard Worker }
834*61046927SAndroid Build Coastguard Worker
835*61046927SAndroid Build Coastguard Worker nir_shader *
dzn_nir_polygon_point_mode_gs(const nir_shader * previous_shader,struct dzn_nir_point_gs_info * info)836*61046927SAndroid Build Coastguard Worker dzn_nir_polygon_point_mode_gs(const nir_shader *previous_shader, struct dzn_nir_point_gs_info *info)
837*61046927SAndroid Build Coastguard Worker {
838*61046927SAndroid Build Coastguard Worker nir_builder builder;
839*61046927SAndroid Build Coastguard Worker nir_builder *b = &builder;
840*61046927SAndroid Build Coastguard Worker nir_variable *pos_var = NULL;
841*61046927SAndroid Build Coastguard Worker
842*61046927SAndroid Build Coastguard Worker unsigned num_vars = 0;
843*61046927SAndroid Build Coastguard Worker nir_variable *in[VARYING_SLOT_MAX];
844*61046927SAndroid Build Coastguard Worker nir_variable *out[VARYING_SLOT_MAX];
845*61046927SAndroid Build Coastguard Worker
846*61046927SAndroid Build Coastguard Worker
847*61046927SAndroid Build Coastguard Worker builder = nir_builder_init_simple_shader(MESA_SHADER_GEOMETRY,
848*61046927SAndroid Build Coastguard Worker dxil_get_base_nir_compiler_options(),
849*61046927SAndroid Build Coastguard Worker "implicit_gs");
850*61046927SAndroid Build Coastguard Worker
851*61046927SAndroid Build Coastguard Worker nir_shader *nir = b->shader;
852*61046927SAndroid Build Coastguard Worker nir->info.inputs_read = nir->info.outputs_written = previous_shader->info.outputs_written;
853*61046927SAndroid Build Coastguard Worker nir->info.outputs_written |= (1ull << VARYING_SLOT_VAR12);
854*61046927SAndroid Build Coastguard Worker nir->info.gs.input_primitive = MESA_PRIM_TRIANGLES;
855*61046927SAndroid Build Coastguard Worker nir->info.gs.output_primitive = MESA_PRIM_POINTS;
856*61046927SAndroid Build Coastguard Worker nir->info.gs.vertices_in = 3;
857*61046927SAndroid Build Coastguard Worker nir->info.gs.vertices_out = 3;
858*61046927SAndroid Build Coastguard Worker nir->info.gs.invocations = 1;
859*61046927SAndroid Build Coastguard Worker nir->info.gs.active_stream_mask = 1;
860*61046927SAndroid Build Coastguard Worker
861*61046927SAndroid Build Coastguard Worker nir_foreach_shader_out_variable(var, previous_shader) {
862*61046927SAndroid Build Coastguard Worker char tmp[100];
863*61046927SAndroid Build Coastguard Worker snprintf(tmp, ARRAY_SIZE(tmp), "in_%d", num_vars);
864*61046927SAndroid Build Coastguard Worker in[num_vars] = nir_variable_create(nir,
865*61046927SAndroid Build Coastguard Worker nir_var_shader_in,
866*61046927SAndroid Build Coastguard Worker glsl_array_type(var->type, 3, 0),
867*61046927SAndroid Build Coastguard Worker tmp);
868*61046927SAndroid Build Coastguard Worker in[num_vars]->data = var->data;
869*61046927SAndroid Build Coastguard Worker in[num_vars]->data.mode = nir_var_shader_in;
870*61046927SAndroid Build Coastguard Worker
871*61046927SAndroid Build Coastguard Worker if (var->data.location == VARYING_SLOT_POS)
872*61046927SAndroid Build Coastguard Worker pos_var = in[num_vars];
873*61046927SAndroid Build Coastguard Worker
874*61046927SAndroid Build Coastguard Worker snprintf(tmp, ARRAY_SIZE(tmp), "out_%d", num_vars);
875*61046927SAndroid Build Coastguard Worker out[num_vars] = nir_variable_create(nir, nir_var_shader_out, var->type, tmp);
876*61046927SAndroid Build Coastguard Worker out[num_vars]->data = var->data;
877*61046927SAndroid Build Coastguard Worker
878*61046927SAndroid Build Coastguard Worker num_vars++;
879*61046927SAndroid Build Coastguard Worker }
880*61046927SAndroid Build Coastguard Worker
881*61046927SAndroid Build Coastguard Worker nir_variable *front_facing_var = nir_variable_create(nir,
882*61046927SAndroid Build Coastguard Worker nir_var_shader_out,
883*61046927SAndroid Build Coastguard Worker glsl_uint_type(),
884*61046927SAndroid Build Coastguard Worker "gl_FrontFacing");
885*61046927SAndroid Build Coastguard Worker front_facing_var->data.location = VARYING_SLOT_VAR12;
886*61046927SAndroid Build Coastguard Worker front_facing_var->data.driver_location = num_vars;
887*61046927SAndroid Build Coastguard Worker front_facing_var->data.interpolation = INTERP_MODE_FLAT;
888*61046927SAndroid Build Coastguard Worker
889*61046927SAndroid Build Coastguard Worker nir_def *depth_bias_scale = NULL;
890*61046927SAndroid Build Coastguard Worker if (info->depth_bias) {
891*61046927SAndroid Build Coastguard Worker switch (info->ds_fmt) {
892*61046927SAndroid Build Coastguard Worker case DXGI_FORMAT_D16_UNORM:
893*61046927SAndroid Build Coastguard Worker depth_bias_scale = nir_imm_float(b, 1.0f / (1 << 16));
894*61046927SAndroid Build Coastguard Worker break;
895*61046927SAndroid Build Coastguard Worker case DXGI_FORMAT_D24_UNORM_S8_UINT:
896*61046927SAndroid Build Coastguard Worker depth_bias_scale = nir_imm_float(b, 1.0f / (1 << 24));
897*61046927SAndroid Build Coastguard Worker break;
898*61046927SAndroid Build Coastguard Worker case DXGI_FORMAT_D32_FLOAT:
899*61046927SAndroid Build Coastguard Worker case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: {
900*61046927SAndroid Build Coastguard Worker nir_deref_instr *deref_pos = nir_build_deref_var(b, pos_var);
901*61046927SAndroid Build Coastguard Worker nir_def *max_z = NULL;
902*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < 3; ++i) {
903*61046927SAndroid Build Coastguard Worker nir_def *pos = nir_load_deref(b, nir_build_deref_array_imm(b, deref_pos, i));
904*61046927SAndroid Build Coastguard Worker nir_def *z = nir_iand_imm(b, nir_channel(b, pos, 2), 0x7fffffff);
905*61046927SAndroid Build Coastguard Worker max_z = i == 0 ? z : nir_imax(b, z, max_z);
906*61046927SAndroid Build Coastguard Worker }
907*61046927SAndroid Build Coastguard Worker nir_def *exponent = nir_ishr_imm(b, nir_iand_imm(b, max_z, 0x7f800000), 23);
908*61046927SAndroid Build Coastguard Worker depth_bias_scale = nir_fexp2(b, nir_i2f32(b, nir_iadd_imm(b, exponent, -23)));
909*61046927SAndroid Build Coastguard Worker break;
910*61046927SAndroid Build Coastguard Worker }
911*61046927SAndroid Build Coastguard Worker default:
912*61046927SAndroid Build Coastguard Worker depth_bias_scale = nir_imm_float(b, 0.0f);
913*61046927SAndroid Build Coastguard Worker }
914*61046927SAndroid Build Coastguard Worker }
915*61046927SAndroid Build Coastguard Worker
916*61046927SAndroid Build Coastguard Worker /* Temporary variable "loop_index" to loop over input vertices */
917*61046927SAndroid Build Coastguard Worker nir_function_impl *impl = nir_shader_get_entrypoint(nir);
918*61046927SAndroid Build Coastguard Worker nir_variable *loop_index_var =
919*61046927SAndroid Build Coastguard Worker nir_local_variable_create(impl, glsl_uint_type(), "loop_index");
920*61046927SAndroid Build Coastguard Worker nir_deref_instr *loop_index_deref = nir_build_deref_var(b, loop_index_var);
921*61046927SAndroid Build Coastguard Worker nir_store_deref(b, loop_index_deref, nir_imm_int(b, 0), 1);
922*61046927SAndroid Build Coastguard Worker
923*61046927SAndroid Build Coastguard Worker nir_def *cull_pass = nir_imm_true(b);
924*61046927SAndroid Build Coastguard Worker nir_def *front_facing;
925*61046927SAndroid Build Coastguard Worker assert(info->cull_mode != VK_CULL_MODE_FRONT_AND_BACK);
926*61046927SAndroid Build Coastguard Worker if (info->cull_mode == VK_CULL_MODE_FRONT_BIT) {
927*61046927SAndroid Build Coastguard Worker cull_pass = cull_face(b, pos_var, info->front_ccw);
928*61046927SAndroid Build Coastguard Worker front_facing = nir_b2i32(b, cull_pass);
929*61046927SAndroid Build Coastguard Worker } else if (info->cull_mode == VK_CULL_MODE_BACK_BIT) {
930*61046927SAndroid Build Coastguard Worker cull_pass = cull_face(b, pos_var, !info->front_ccw);
931*61046927SAndroid Build Coastguard Worker front_facing = nir_inot(b, nir_b2i32(b, cull_pass));
932*61046927SAndroid Build Coastguard Worker } else
933*61046927SAndroid Build Coastguard Worker front_facing = nir_i2i32(b, cull_face(b, pos_var, info->front_ccw));
934*61046927SAndroid Build Coastguard Worker
935*61046927SAndroid Build Coastguard Worker /**
936*61046927SAndroid Build Coastguard Worker * if (cull_pass) {
937*61046927SAndroid Build Coastguard Worker * while {
938*61046927SAndroid Build Coastguard Worker * if (loop_index >= 3)
939*61046927SAndroid Build Coastguard Worker * break;
940*61046927SAndroid Build Coastguard Worker */
941*61046927SAndroid Build Coastguard Worker nir_if *cull_check = nir_push_if(b, cull_pass);
942*61046927SAndroid Build Coastguard Worker nir_loop *loop = nir_push_loop(b);
943*61046927SAndroid Build Coastguard Worker
944*61046927SAndroid Build Coastguard Worker nir_def *loop_index = nir_load_deref(b, loop_index_deref);
945*61046927SAndroid Build Coastguard Worker nir_def *cmp = nir_ige(b, loop_index,
946*61046927SAndroid Build Coastguard Worker nir_imm_int(b, 3));
947*61046927SAndroid Build Coastguard Worker nir_if *loop_check = nir_push_if(b, cmp);
948*61046927SAndroid Build Coastguard Worker nir_jump(b, nir_jump_break);
949*61046927SAndroid Build Coastguard Worker nir_pop_if(b, loop_check);
950*61046927SAndroid Build Coastguard Worker
951*61046927SAndroid Build Coastguard Worker /**
952*61046927SAndroid Build Coastguard Worker * [...] // Copy all variables
953*61046927SAndroid Build Coastguard Worker * EmitVertex();
954*61046927SAndroid Build Coastguard Worker */
955*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_vars; ++i) {
956*61046927SAndroid Build Coastguard Worker nir_def *index = loop_index;
957*61046927SAndroid Build Coastguard Worker nir_deref_instr *in_value = nir_build_deref_array(b, nir_build_deref_var(b, in[i]), index);
958*61046927SAndroid Build Coastguard Worker if (in[i] == pos_var && info->depth_bias) {
959*61046927SAndroid Build Coastguard Worker nir_def *bias_val;
960*61046927SAndroid Build Coastguard Worker if (info->depth_bias_dynamic) {
961*61046927SAndroid Build Coastguard Worker bias_val = load_dynamic_depth_bias(b, info);
962*61046927SAndroid Build Coastguard Worker } else {
963*61046927SAndroid Build Coastguard Worker assert(info->slope_scaled_depth_bias == 0.0f);
964*61046927SAndroid Build Coastguard Worker bias_val = nir_imm_float(b, info->constant_depth_bias);
965*61046927SAndroid Build Coastguard Worker }
966*61046927SAndroid Build Coastguard Worker bias_val = nir_fmul(b, bias_val, depth_bias_scale);
967*61046927SAndroid Build Coastguard Worker nir_def *old_val = nir_load_deref(b, in_value);
968*61046927SAndroid Build Coastguard Worker nir_def *new_val = nir_vector_insert_imm(b, old_val,
969*61046927SAndroid Build Coastguard Worker nir_fadd(b, nir_channel(b, old_val, 2), bias_val),
970*61046927SAndroid Build Coastguard Worker 2);
971*61046927SAndroid Build Coastguard Worker nir_store_var(b, out[i], new_val, 0xf);
972*61046927SAndroid Build Coastguard Worker } else {
973*61046927SAndroid Build Coastguard Worker copy_vars(b, nir_build_deref_var(b, out[i]), in_value);
974*61046927SAndroid Build Coastguard Worker }
975*61046927SAndroid Build Coastguard Worker }
976*61046927SAndroid Build Coastguard Worker nir_store_var(b, front_facing_var, front_facing, 0x1);
977*61046927SAndroid Build Coastguard Worker nir_emit_vertex(b, 0);
978*61046927SAndroid Build Coastguard Worker
979*61046927SAndroid Build Coastguard Worker /**
980*61046927SAndroid Build Coastguard Worker * loop_index++;
981*61046927SAndroid Build Coastguard Worker * }
982*61046927SAndroid Build Coastguard Worker * }
983*61046927SAndroid Build Coastguard Worker */
984*61046927SAndroid Build Coastguard Worker nir_store_deref(b, loop_index_deref, nir_iadd_imm(b, loop_index, 1), 1);
985*61046927SAndroid Build Coastguard Worker nir_pop_loop(b, loop);
986*61046927SAndroid Build Coastguard Worker nir_pop_if(b, cull_check);
987*61046927SAndroid Build Coastguard Worker
988*61046927SAndroid Build Coastguard Worker nir_validate_shader(nir, "in dzn_nir_polygon_point_mode_gs");
989*61046927SAndroid Build Coastguard Worker
990*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_var_copies);
991*61046927SAndroid Build Coastguard Worker return b->shader;
992*61046927SAndroid Build Coastguard Worker }
993