1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2016 Red Hat.
3*61046927SAndroid Build Coastguard Worker * Copyright © 2016 Bas Nieuwenhuizen
4*61046927SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT
5*61046927SAndroid Build Coastguard Worker *
6*61046927SAndroid Build Coastguard Worker * based in part on anv driver which is:
7*61046927SAndroid Build Coastguard Worker * Copyright © 2015 Intel Corporation
8*61046927SAndroid Build Coastguard Worker */
9*61046927SAndroid Build Coastguard Worker
10*61046927SAndroid Build Coastguard Worker #include "tu_pipeline.h"
11*61046927SAndroid Build Coastguard Worker
12*61046927SAndroid Build Coastguard Worker #include "common/freedreno_guardband.h"
13*61046927SAndroid Build Coastguard Worker
14*61046927SAndroid Build Coastguard Worker #include "ir3/ir3_nir.h"
15*61046927SAndroid Build Coastguard Worker #include "nir/nir.h"
16*61046927SAndroid Build Coastguard Worker #include "nir/nir_builder.h"
17*61046927SAndroid Build Coastguard Worker #include "nir/nir_serialize.h"
18*61046927SAndroid Build Coastguard Worker #include "spirv/nir_spirv.h"
19*61046927SAndroid Build Coastguard Worker #include "util/u_debug.h"
20*61046927SAndroid Build Coastguard Worker #include "util/mesa-sha1.h"
21*61046927SAndroid Build Coastguard Worker #include "vk_nir.h"
22*61046927SAndroid Build Coastguard Worker #include "vk_pipeline.h"
23*61046927SAndroid Build Coastguard Worker #include "vk_render_pass.h"
24*61046927SAndroid Build Coastguard Worker #include "vk_util.h"
25*61046927SAndroid Build Coastguard Worker
26*61046927SAndroid Build Coastguard Worker #include "tu_cmd_buffer.h"
27*61046927SAndroid Build Coastguard Worker #include "tu_cs.h"
28*61046927SAndroid Build Coastguard Worker #include "tu_device.h"
29*61046927SAndroid Build Coastguard Worker #include "tu_knl.h"
30*61046927SAndroid Build Coastguard Worker #include "tu_formats.h"
31*61046927SAndroid Build Coastguard Worker #include "tu_lrz.h"
32*61046927SAndroid Build Coastguard Worker #include "tu_pass.h"
33*61046927SAndroid Build Coastguard Worker #include "tu_rmv.h"
34*61046927SAndroid Build Coastguard Worker
35*61046927SAndroid Build Coastguard Worker /* Emit IB that preloads the descriptors that the shader uses */
36*61046927SAndroid Build Coastguard Worker
37*61046927SAndroid Build Coastguard Worker static void
emit_load_state(struct tu_cs * cs,unsigned opcode,enum a6xx_state_type st,enum a6xx_state_block sb,unsigned base,unsigned offset,unsigned count)38*61046927SAndroid Build Coastguard Worker emit_load_state(struct tu_cs *cs, unsigned opcode, enum a6xx_state_type st,
39*61046927SAndroid Build Coastguard Worker enum a6xx_state_block sb, unsigned base, unsigned offset,
40*61046927SAndroid Build Coastguard Worker unsigned count)
41*61046927SAndroid Build Coastguard Worker {
42*61046927SAndroid Build Coastguard Worker /* Note: just emit one packet, even if count overflows NUM_UNIT. It's not
43*61046927SAndroid Build Coastguard Worker * clear if emitting more packets will even help anything. Presumably the
44*61046927SAndroid Build Coastguard Worker * descriptor cache is relatively small, and these packets stop doing
45*61046927SAndroid Build Coastguard Worker * anything when there are too many descriptors.
46*61046927SAndroid Build Coastguard Worker */
47*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt7(cs, opcode, 3);
48*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs,
49*61046927SAndroid Build Coastguard Worker CP_LOAD_STATE6_0_STATE_TYPE(st) |
50*61046927SAndroid Build Coastguard Worker CP_LOAD_STATE6_0_STATE_SRC(SS6_BINDLESS) |
51*61046927SAndroid Build Coastguard Worker CP_LOAD_STATE6_0_STATE_BLOCK(sb) |
52*61046927SAndroid Build Coastguard Worker CP_LOAD_STATE6_0_NUM_UNIT(MIN2(count, 1024-1)));
53*61046927SAndroid Build Coastguard Worker tu_cs_emit_qw(cs, offset | (base << 28));
54*61046927SAndroid Build Coastguard Worker }
55*61046927SAndroid Build Coastguard Worker
56*61046927SAndroid Build Coastguard Worker static unsigned
tu6_load_state_size(struct tu_pipeline * pipeline,struct tu_pipeline_layout * layout)57*61046927SAndroid Build Coastguard Worker tu6_load_state_size(struct tu_pipeline *pipeline,
58*61046927SAndroid Build Coastguard Worker struct tu_pipeline_layout *layout)
59*61046927SAndroid Build Coastguard Worker {
60*61046927SAndroid Build Coastguard Worker const unsigned load_state_size = 4;
61*61046927SAndroid Build Coastguard Worker unsigned size = 0;
62*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < layout->num_sets; i++) {
63*61046927SAndroid Build Coastguard Worker if (!(pipeline->active_desc_sets & (1u << i)))
64*61046927SAndroid Build Coastguard Worker continue;
65*61046927SAndroid Build Coastguard Worker
66*61046927SAndroid Build Coastguard Worker struct tu_descriptor_set_layout *set_layout = layout->set[i].layout;
67*61046927SAndroid Build Coastguard Worker for (unsigned j = 0; j < set_layout->binding_count; j++) {
68*61046927SAndroid Build Coastguard Worker struct tu_descriptor_set_binding_layout *binding = &set_layout->binding[j];
69*61046927SAndroid Build Coastguard Worker unsigned count = 0;
70*61046927SAndroid Build Coastguard Worker /* See comment in tu6_emit_load_state(). */
71*61046927SAndroid Build Coastguard Worker VkShaderStageFlags stages = pipeline->active_stages & binding->shader_stages;
72*61046927SAndroid Build Coastguard Worker unsigned stage_count = util_bitcount(stages);
73*61046927SAndroid Build Coastguard Worker
74*61046927SAndroid Build Coastguard Worker if (!binding->array_size)
75*61046927SAndroid Build Coastguard Worker continue;
76*61046927SAndroid Build Coastguard Worker
77*61046927SAndroid Build Coastguard Worker switch (binding->type) {
78*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
79*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
80*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
81*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
82*61046927SAndroid Build Coastguard Worker /* IBO-backed resources only need one packet for all graphics stages */
83*61046927SAndroid Build Coastguard Worker if (stage_count)
84*61046927SAndroid Build Coastguard Worker count += 1;
85*61046927SAndroid Build Coastguard Worker break;
86*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_SAMPLER:
87*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
88*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
89*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
90*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
91*61046927SAndroid Build Coastguard Worker /* Textures and UBO's needs a packet for each stage */
92*61046927SAndroid Build Coastguard Worker count = stage_count;
93*61046927SAndroid Build Coastguard Worker break;
94*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
95*61046927SAndroid Build Coastguard Worker /* Because of how we pack combined images and samplers, we
96*61046927SAndroid Build Coastguard Worker * currently can't use one packet for the whole array.
97*61046927SAndroid Build Coastguard Worker */
98*61046927SAndroid Build Coastguard Worker count = stage_count * binding->array_size * 2;
99*61046927SAndroid Build Coastguard Worker break;
100*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
101*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK:
102*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_MUTABLE_EXT:
103*61046927SAndroid Build Coastguard Worker break;
104*61046927SAndroid Build Coastguard Worker default:
105*61046927SAndroid Build Coastguard Worker unreachable("bad descriptor type");
106*61046927SAndroid Build Coastguard Worker }
107*61046927SAndroid Build Coastguard Worker size += count * load_state_size;
108*61046927SAndroid Build Coastguard Worker }
109*61046927SAndroid Build Coastguard Worker }
110*61046927SAndroid Build Coastguard Worker return size;
111*61046927SAndroid Build Coastguard Worker }
112*61046927SAndroid Build Coastguard Worker
113*61046927SAndroid Build Coastguard Worker static void
tu6_emit_load_state(struct tu_device * device,struct tu_pipeline * pipeline,struct tu_pipeline_layout * layout)114*61046927SAndroid Build Coastguard Worker tu6_emit_load_state(struct tu_device *device,
115*61046927SAndroid Build Coastguard Worker struct tu_pipeline *pipeline,
116*61046927SAndroid Build Coastguard Worker struct tu_pipeline_layout *layout)
117*61046927SAndroid Build Coastguard Worker {
118*61046927SAndroid Build Coastguard Worker unsigned size = tu6_load_state_size(pipeline, layout);
119*61046927SAndroid Build Coastguard Worker if (size == 0)
120*61046927SAndroid Build Coastguard Worker return;
121*61046927SAndroid Build Coastguard Worker
122*61046927SAndroid Build Coastguard Worker struct tu_cs cs;
123*61046927SAndroid Build Coastguard Worker tu_cs_begin_sub_stream(&pipeline->cs, size, &cs);
124*61046927SAndroid Build Coastguard Worker
125*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < layout->num_sets; i++) {
126*61046927SAndroid Build Coastguard Worker /* From 13.2.7. Descriptor Set Binding:
127*61046927SAndroid Build Coastguard Worker *
128*61046927SAndroid Build Coastguard Worker * A compatible descriptor set must be bound for all set numbers that
129*61046927SAndroid Build Coastguard Worker * any shaders in a pipeline access, at the time that a draw or
130*61046927SAndroid Build Coastguard Worker * dispatch command is recorded to execute using that pipeline.
131*61046927SAndroid Build Coastguard Worker * However, if none of the shaders in a pipeline statically use any
132*61046927SAndroid Build Coastguard Worker * bindings with a particular set number, then no descriptor set need
133*61046927SAndroid Build Coastguard Worker * be bound for that set number, even if the pipeline layout includes
134*61046927SAndroid Build Coastguard Worker * a non-trivial descriptor set layout for that set number.
135*61046927SAndroid Build Coastguard Worker *
136*61046927SAndroid Build Coastguard Worker * This means that descriptor sets unused by the pipeline may have a
137*61046927SAndroid Build Coastguard Worker * garbage or 0 BINDLESS_BASE register, which will cause context faults
138*61046927SAndroid Build Coastguard Worker * when prefetching descriptors from these sets. Skip prefetching for
139*61046927SAndroid Build Coastguard Worker * descriptors from them to avoid this. This is also an optimization,
140*61046927SAndroid Build Coastguard Worker * since these prefetches would be useless.
141*61046927SAndroid Build Coastguard Worker */
142*61046927SAndroid Build Coastguard Worker if (!(pipeline->active_desc_sets & (1u << i)))
143*61046927SAndroid Build Coastguard Worker continue;
144*61046927SAndroid Build Coastguard Worker
145*61046927SAndroid Build Coastguard Worker struct tu_descriptor_set_layout *set_layout = layout->set[i].layout;
146*61046927SAndroid Build Coastguard Worker for (unsigned j = 0; j < set_layout->binding_count; j++) {
147*61046927SAndroid Build Coastguard Worker struct tu_descriptor_set_binding_layout *binding = &set_layout->binding[j];
148*61046927SAndroid Build Coastguard Worker unsigned base = i;
149*61046927SAndroid Build Coastguard Worker unsigned offset = binding->offset / 4;
150*61046927SAndroid Build Coastguard Worker /* Note: amber sets VK_SHADER_STAGE_ALL for its descriptor layout, and
151*61046927SAndroid Build Coastguard Worker * zink has descriptors for each stage in the push layout even if some
152*61046927SAndroid Build Coastguard Worker * stages aren't present in a used pipeline. We don't want to emit
153*61046927SAndroid Build Coastguard Worker * loads for unused descriptors.
154*61046927SAndroid Build Coastguard Worker */
155*61046927SAndroid Build Coastguard Worker VkShaderStageFlags stages = pipeline->active_stages & binding->shader_stages;
156*61046927SAndroid Build Coastguard Worker unsigned count = binding->array_size;
157*61046927SAndroid Build Coastguard Worker
158*61046927SAndroid Build Coastguard Worker /* If this is a variable-count descriptor, then the array_size is an
159*61046927SAndroid Build Coastguard Worker * upper bound on the size, but we don't know how many descriptors
160*61046927SAndroid Build Coastguard Worker * will actually be used. Therefore we can't pre-load them here.
161*61046927SAndroid Build Coastguard Worker */
162*61046927SAndroid Build Coastguard Worker if (j == set_layout->binding_count - 1 &&
163*61046927SAndroid Build Coastguard Worker set_layout->has_variable_descriptors)
164*61046927SAndroid Build Coastguard Worker continue;
165*61046927SAndroid Build Coastguard Worker
166*61046927SAndroid Build Coastguard Worker if (count == 0 || stages == 0)
167*61046927SAndroid Build Coastguard Worker continue;
168*61046927SAndroid Build Coastguard Worker switch (binding->type) {
169*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
170*61046927SAndroid Build Coastguard Worker assert(device->physical_device->reserved_set_idx >= 0);
171*61046927SAndroid Build Coastguard Worker base = device->physical_device->reserved_set_idx;
172*61046927SAndroid Build Coastguard Worker offset = (pipeline->program.dynamic_descriptor_offsets[i] +
173*61046927SAndroid Build Coastguard Worker binding->dynamic_offset_offset) / 4;
174*61046927SAndroid Build Coastguard Worker FALLTHROUGH;
175*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
176*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
177*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: {
178*61046927SAndroid Build Coastguard Worker unsigned mul = binding->size / (A6XX_TEX_CONST_DWORDS * 4);
179*61046927SAndroid Build Coastguard Worker /* IBO-backed resources only need one packet for all graphics stages */
180*61046927SAndroid Build Coastguard Worker if (stages & ~VK_SHADER_STAGE_COMPUTE_BIT) {
181*61046927SAndroid Build Coastguard Worker emit_load_state(&cs, CP_LOAD_STATE6, ST6_SHADER, SB6_IBO,
182*61046927SAndroid Build Coastguard Worker base, offset, count * mul);
183*61046927SAndroid Build Coastguard Worker }
184*61046927SAndroid Build Coastguard Worker if (stages & VK_SHADER_STAGE_COMPUTE_BIT) {
185*61046927SAndroid Build Coastguard Worker emit_load_state(&cs, CP_LOAD_STATE6_FRAG, ST6_IBO, SB6_CS_SHADER,
186*61046927SAndroid Build Coastguard Worker base, offset, count * mul);
187*61046927SAndroid Build Coastguard Worker }
188*61046927SAndroid Build Coastguard Worker break;
189*61046927SAndroid Build Coastguard Worker }
190*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
191*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK:
192*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_MUTABLE_EXT:
193*61046927SAndroid Build Coastguard Worker /* nothing - input attachments and inline uniforms don't use bindless */
194*61046927SAndroid Build Coastguard Worker break;
195*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_SAMPLER:
196*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
197*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: {
198*61046927SAndroid Build Coastguard Worker tu_foreach_stage(stage, stages) {
199*61046927SAndroid Build Coastguard Worker emit_load_state(&cs, tu6_stage2opcode(stage),
200*61046927SAndroid Build Coastguard Worker binding->type == VK_DESCRIPTOR_TYPE_SAMPLER ?
201*61046927SAndroid Build Coastguard Worker ST6_SHADER : ST6_CONSTANTS,
202*61046927SAndroid Build Coastguard Worker tu6_stage2texsb(stage), base, offset, count);
203*61046927SAndroid Build Coastguard Worker }
204*61046927SAndroid Build Coastguard Worker break;
205*61046927SAndroid Build Coastguard Worker }
206*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
207*61046927SAndroid Build Coastguard Worker assert(device->physical_device->reserved_set_idx >= 0);
208*61046927SAndroid Build Coastguard Worker base = device->physical_device->reserved_set_idx;
209*61046927SAndroid Build Coastguard Worker offset = (pipeline->program.dynamic_descriptor_offsets[i] +
210*61046927SAndroid Build Coastguard Worker binding->dynamic_offset_offset) / 4;
211*61046927SAndroid Build Coastguard Worker FALLTHROUGH;
212*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: {
213*61046927SAndroid Build Coastguard Worker tu_foreach_stage(stage, stages) {
214*61046927SAndroid Build Coastguard Worker emit_load_state(&cs, tu6_stage2opcode(stage), ST6_UBO,
215*61046927SAndroid Build Coastguard Worker tu6_stage2shadersb(stage), base, offset, count);
216*61046927SAndroid Build Coastguard Worker }
217*61046927SAndroid Build Coastguard Worker break;
218*61046927SAndroid Build Coastguard Worker }
219*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: {
220*61046927SAndroid Build Coastguard Worker tu_foreach_stage(stage, stages) {
221*61046927SAndroid Build Coastguard Worker /* TODO: We could emit less CP_LOAD_STATE6 if we used
222*61046927SAndroid Build Coastguard Worker * struct-of-arrays instead of array-of-structs.
223*61046927SAndroid Build Coastguard Worker */
224*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < count; i++) {
225*61046927SAndroid Build Coastguard Worker unsigned tex_offset = offset + 2 * i * A6XX_TEX_CONST_DWORDS;
226*61046927SAndroid Build Coastguard Worker unsigned sam_offset = offset + (2 * i + 1) * A6XX_TEX_CONST_DWORDS;
227*61046927SAndroid Build Coastguard Worker emit_load_state(&cs, tu6_stage2opcode(stage),
228*61046927SAndroid Build Coastguard Worker ST6_CONSTANTS, tu6_stage2texsb(stage),
229*61046927SAndroid Build Coastguard Worker base, tex_offset, 1);
230*61046927SAndroid Build Coastguard Worker emit_load_state(&cs, tu6_stage2opcode(stage),
231*61046927SAndroid Build Coastguard Worker ST6_SHADER, tu6_stage2texsb(stage),
232*61046927SAndroid Build Coastguard Worker base, sam_offset, 1);
233*61046927SAndroid Build Coastguard Worker }
234*61046927SAndroid Build Coastguard Worker }
235*61046927SAndroid Build Coastguard Worker break;
236*61046927SAndroid Build Coastguard Worker }
237*61046927SAndroid Build Coastguard Worker default:
238*61046927SAndroid Build Coastguard Worker unreachable("bad descriptor type");
239*61046927SAndroid Build Coastguard Worker }
240*61046927SAndroid Build Coastguard Worker }
241*61046927SAndroid Build Coastguard Worker }
242*61046927SAndroid Build Coastguard Worker
243*61046927SAndroid Build Coastguard Worker pipeline->load_state = tu_cs_end_draw_state(&pipeline->cs, &cs);
244*61046927SAndroid Build Coastguard Worker }
245*61046927SAndroid Build Coastguard Worker
246*61046927SAndroid Build Coastguard Worker struct tu_pipeline_builder
247*61046927SAndroid Build Coastguard Worker {
248*61046927SAndroid Build Coastguard Worker struct tu_device *device;
249*61046927SAndroid Build Coastguard Worker void *mem_ctx;
250*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache *cache;
251*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc;
252*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *create_info;
253*61046927SAndroid Build Coastguard Worker VkPipelineCreateFlags2KHR create_flags;
254*61046927SAndroid Build Coastguard Worker
255*61046927SAndroid Build Coastguard Worker struct tu_pipeline_layout layout;
256*61046927SAndroid Build Coastguard Worker
257*61046927SAndroid Build Coastguard Worker struct tu_pvtmem_config pvtmem;
258*61046927SAndroid Build Coastguard Worker
259*61046927SAndroid Build Coastguard Worker bool rasterizer_discard;
260*61046927SAndroid Build Coastguard Worker /* these states are affectd by rasterizer_discard */
261*61046927SAndroid Build Coastguard Worker uint8_t unscaled_input_fragcoord;
262*61046927SAndroid Build Coastguard Worker
263*61046927SAndroid Build Coastguard Worker /* Each library defines at least one piece of state in
264*61046927SAndroid Build Coastguard Worker * VkGraphicsPipelineLibraryFlagsEXT, and libraries cannot overlap, so
265*61046927SAndroid Build Coastguard Worker * there can be at most as many libraries as pieces of state, of which
266*61046927SAndroid Build Coastguard Worker * there are currently 4.
267*61046927SAndroid Build Coastguard Worker */
268*61046927SAndroid Build Coastguard Worker #define MAX_LIBRARIES 4
269*61046927SAndroid Build Coastguard Worker
270*61046927SAndroid Build Coastguard Worker unsigned num_libraries;
271*61046927SAndroid Build Coastguard Worker struct tu_graphics_lib_pipeline *libraries[MAX_LIBRARIES];
272*61046927SAndroid Build Coastguard Worker
273*61046927SAndroid Build Coastguard Worker /* This is just the state that we are compiling now, whereas the final
274*61046927SAndroid Build Coastguard Worker * pipeline will include the state from the libraries.
275*61046927SAndroid Build Coastguard Worker */
276*61046927SAndroid Build Coastguard Worker VkGraphicsPipelineLibraryFlagsEXT state;
277*61046927SAndroid Build Coastguard Worker
278*61046927SAndroid Build Coastguard Worker /* The stages we are compiling now. */
279*61046927SAndroid Build Coastguard Worker VkShaderStageFlags active_stages;
280*61046927SAndroid Build Coastguard Worker
281*61046927SAndroid Build Coastguard Worker bool fragment_density_map;
282*61046927SAndroid Build Coastguard Worker
283*61046927SAndroid Build Coastguard Worker struct vk_graphics_pipeline_all_state all_state;
284*61046927SAndroid Build Coastguard Worker struct vk_graphics_pipeline_state graphics_state;
285*61046927SAndroid Build Coastguard Worker };
286*61046927SAndroid Build Coastguard Worker
287*61046927SAndroid Build Coastguard Worker static bool
tu_logic_op_reads_dst(VkLogicOp op)288*61046927SAndroid Build Coastguard Worker tu_logic_op_reads_dst(VkLogicOp op)
289*61046927SAndroid Build Coastguard Worker {
290*61046927SAndroid Build Coastguard Worker switch (op) {
291*61046927SAndroid Build Coastguard Worker case VK_LOGIC_OP_CLEAR:
292*61046927SAndroid Build Coastguard Worker case VK_LOGIC_OP_COPY:
293*61046927SAndroid Build Coastguard Worker case VK_LOGIC_OP_COPY_INVERTED:
294*61046927SAndroid Build Coastguard Worker case VK_LOGIC_OP_SET:
295*61046927SAndroid Build Coastguard Worker return false;
296*61046927SAndroid Build Coastguard Worker default:
297*61046927SAndroid Build Coastguard Worker return true;
298*61046927SAndroid Build Coastguard Worker }
299*61046927SAndroid Build Coastguard Worker }
300*61046927SAndroid Build Coastguard Worker
301*61046927SAndroid Build Coastguard Worker static bool
tu_blend_state_is_dual_src(const struct vk_color_blend_state * cb)302*61046927SAndroid Build Coastguard Worker tu_blend_state_is_dual_src(const struct vk_color_blend_state *cb)
303*61046927SAndroid Build Coastguard Worker {
304*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < cb->attachment_count; i++) {
305*61046927SAndroid Build Coastguard Worker if (tu_blend_factor_is_dual_src((VkBlendFactor)cb->attachments[i].src_color_blend_factor) ||
306*61046927SAndroid Build Coastguard Worker tu_blend_factor_is_dual_src((VkBlendFactor)cb->attachments[i].dst_color_blend_factor) ||
307*61046927SAndroid Build Coastguard Worker tu_blend_factor_is_dual_src((VkBlendFactor)cb->attachments[i].src_alpha_blend_factor) ||
308*61046927SAndroid Build Coastguard Worker tu_blend_factor_is_dual_src((VkBlendFactor)cb->attachments[i].dst_alpha_blend_factor))
309*61046927SAndroid Build Coastguard Worker return true;
310*61046927SAndroid Build Coastguard Worker }
311*61046927SAndroid Build Coastguard Worker
312*61046927SAndroid Build Coastguard Worker return false;
313*61046927SAndroid Build Coastguard Worker }
314*61046927SAndroid Build Coastguard Worker
315*61046927SAndroid Build Coastguard Worker enum ir3_push_consts_type
tu_push_consts_type(const struct tu_pipeline_layout * layout,const struct ir3_compiler * compiler)316*61046927SAndroid Build Coastguard Worker tu_push_consts_type(const struct tu_pipeline_layout *layout,
317*61046927SAndroid Build Coastguard Worker const struct ir3_compiler *compiler)
318*61046927SAndroid Build Coastguard Worker {
319*61046927SAndroid Build Coastguard Worker if (!layout->push_constant_size)
320*61046927SAndroid Build Coastguard Worker return IR3_PUSH_CONSTS_NONE;
321*61046927SAndroid Build Coastguard Worker
322*61046927SAndroid Build Coastguard Worker if (TU_DEBUG(PUSH_CONSTS_PER_STAGE))
323*61046927SAndroid Build Coastguard Worker return IR3_PUSH_CONSTS_PER_STAGE;
324*61046927SAndroid Build Coastguard Worker
325*61046927SAndroid Build Coastguard Worker if (tu6_shared_constants_enable(layout, compiler)) {
326*61046927SAndroid Build Coastguard Worker return IR3_PUSH_CONSTS_SHARED;
327*61046927SAndroid Build Coastguard Worker } else {
328*61046927SAndroid Build Coastguard Worker if (compiler->gen >= 7) {
329*61046927SAndroid Build Coastguard Worker return IR3_PUSH_CONSTS_SHARED_PREAMBLE;
330*61046927SAndroid Build Coastguard Worker } else {
331*61046927SAndroid Build Coastguard Worker return IR3_PUSH_CONSTS_PER_STAGE;
332*61046927SAndroid Build Coastguard Worker }
333*61046927SAndroid Build Coastguard Worker }
334*61046927SAndroid Build Coastguard Worker }
335*61046927SAndroid Build Coastguard Worker
336*61046927SAndroid Build Coastguard Worker template <chip CHIP>
337*61046927SAndroid Build Coastguard Worker struct xs_config {
338*61046927SAndroid Build Coastguard Worker uint16_t reg_sp_xs_config;
339*61046927SAndroid Build Coastguard Worker uint16_t reg_hlsq_xs_ctrl;
340*61046927SAndroid Build Coastguard Worker };
341*61046927SAndroid Build Coastguard Worker
342*61046927SAndroid Build Coastguard Worker template <chip CHIP>
343*61046927SAndroid Build Coastguard Worker static const xs_config<CHIP> xs_configs[] = {
344*61046927SAndroid Build Coastguard Worker [MESA_SHADER_VERTEX] = {
345*61046927SAndroid Build Coastguard Worker REG_A6XX_SP_VS_CONFIG,
346*61046927SAndroid Build Coastguard Worker CHIP == A6XX ? REG_A6XX_HLSQ_VS_CNTL : REG_A7XX_HLSQ_VS_CNTL,
347*61046927SAndroid Build Coastguard Worker },
348*61046927SAndroid Build Coastguard Worker [MESA_SHADER_TESS_CTRL] = {
349*61046927SAndroid Build Coastguard Worker REG_A6XX_SP_HS_CONFIG,
350*61046927SAndroid Build Coastguard Worker CHIP == A6XX ? REG_A6XX_HLSQ_HS_CNTL : REG_A7XX_HLSQ_HS_CNTL,
351*61046927SAndroid Build Coastguard Worker },
352*61046927SAndroid Build Coastguard Worker [MESA_SHADER_TESS_EVAL] = {
353*61046927SAndroid Build Coastguard Worker REG_A6XX_SP_DS_CONFIG,
354*61046927SAndroid Build Coastguard Worker CHIP == A6XX ? REG_A6XX_HLSQ_DS_CNTL : REG_A7XX_HLSQ_DS_CNTL,
355*61046927SAndroid Build Coastguard Worker },
356*61046927SAndroid Build Coastguard Worker [MESA_SHADER_GEOMETRY] = {
357*61046927SAndroid Build Coastguard Worker REG_A6XX_SP_GS_CONFIG,
358*61046927SAndroid Build Coastguard Worker CHIP == A6XX ? REG_A6XX_HLSQ_GS_CNTL : REG_A7XX_HLSQ_GS_CNTL,
359*61046927SAndroid Build Coastguard Worker },
360*61046927SAndroid Build Coastguard Worker [MESA_SHADER_FRAGMENT] = {
361*61046927SAndroid Build Coastguard Worker REG_A6XX_SP_FS_CONFIG,
362*61046927SAndroid Build Coastguard Worker CHIP == A6XX ? REG_A6XX_HLSQ_FS_CNTL : REG_A7XX_HLSQ_FS_CNTL,
363*61046927SAndroid Build Coastguard Worker },
364*61046927SAndroid Build Coastguard Worker [MESA_SHADER_COMPUTE] = {
365*61046927SAndroid Build Coastguard Worker REG_A6XX_SP_CS_CONFIG,
366*61046927SAndroid Build Coastguard Worker CHIP == A6XX ? REG_A6XX_HLSQ_CS_CNTL : REG_A7XX_HLSQ_CS_CNTL,
367*61046927SAndroid Build Coastguard Worker },
368*61046927SAndroid Build Coastguard Worker };
369*61046927SAndroid Build Coastguard Worker
370*61046927SAndroid Build Coastguard Worker template <chip CHIP>
371*61046927SAndroid Build Coastguard Worker void
tu6_emit_xs_config(struct tu_cs * cs,gl_shader_stage stage,const struct ir3_shader_variant * xs)372*61046927SAndroid Build Coastguard Worker tu6_emit_xs_config(struct tu_cs *cs,
373*61046927SAndroid Build Coastguard Worker gl_shader_stage stage, /* xs->type, but xs may be NULL */
374*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *xs)
375*61046927SAndroid Build Coastguard Worker {
376*61046927SAndroid Build Coastguard Worker const struct xs_config<CHIP> *cfg = &xs_configs<CHIP>[stage];
377*61046927SAndroid Build Coastguard Worker
378*61046927SAndroid Build Coastguard Worker if (!xs) {
379*61046927SAndroid Build Coastguard Worker /* shader stage disabled */
380*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, cfg->reg_sp_xs_config, 1);
381*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, 0);
382*61046927SAndroid Build Coastguard Worker
383*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, cfg->reg_hlsq_xs_ctrl, 1);
384*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, 0);
385*61046927SAndroid Build Coastguard Worker return;
386*61046927SAndroid Build Coastguard Worker }
387*61046927SAndroid Build Coastguard Worker
388*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, cfg->reg_sp_xs_config, 1);
389*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, A6XX_SP_VS_CONFIG_ENABLED |
390*61046927SAndroid Build Coastguard Worker COND(xs->bindless_tex, A6XX_SP_VS_CONFIG_BINDLESS_TEX) |
391*61046927SAndroid Build Coastguard Worker COND(xs->bindless_samp, A6XX_SP_VS_CONFIG_BINDLESS_SAMP) |
392*61046927SAndroid Build Coastguard Worker COND(xs->bindless_ibo, A6XX_SP_VS_CONFIG_BINDLESS_IBO) |
393*61046927SAndroid Build Coastguard Worker COND(xs->bindless_ubo, A6XX_SP_VS_CONFIG_BINDLESS_UBO) |
394*61046927SAndroid Build Coastguard Worker A6XX_SP_VS_CONFIG_NTEX(xs->num_samp) |
395*61046927SAndroid Build Coastguard Worker A6XX_SP_VS_CONFIG_NSAMP(xs->num_samp));
396*61046927SAndroid Build Coastguard Worker
397*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, cfg->reg_hlsq_xs_ctrl, 1);
398*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, A6XX_HLSQ_VS_CNTL_CONSTLEN(xs->constlen) |
399*61046927SAndroid Build Coastguard Worker A6XX_HLSQ_VS_CNTL_ENABLED |
400*61046927SAndroid Build Coastguard Worker COND(xs->shader_options.push_consts_type == IR3_PUSH_CONSTS_SHARED_PREAMBLE,
401*61046927SAndroid Build Coastguard Worker A7XX_HLSQ_VS_CNTL_READ_IMM_SHARED_CONSTS));
402*61046927SAndroid Build Coastguard Worker }
403*61046927SAndroid Build Coastguard Worker TU_GENX(tu6_emit_xs_config);
404*61046927SAndroid Build Coastguard Worker
405*61046927SAndroid Build Coastguard Worker static void
tu6_emit_dynamic_offset(struct tu_cs * cs,const struct ir3_shader_variant * xs,const struct tu_shader * shader,const struct tu_program_state * program)406*61046927SAndroid Build Coastguard Worker tu6_emit_dynamic_offset(struct tu_cs *cs,
407*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *xs,
408*61046927SAndroid Build Coastguard Worker const struct tu_shader *shader,
409*61046927SAndroid Build Coastguard Worker const struct tu_program_state *program)
410*61046927SAndroid Build Coastguard Worker {
411*61046927SAndroid Build Coastguard Worker const struct tu_physical_device *phys_dev = cs->device->physical_device;
412*61046927SAndroid Build Coastguard Worker
413*61046927SAndroid Build Coastguard Worker if (!xs)
414*61046927SAndroid Build Coastguard Worker return;
415*61046927SAndroid Build Coastguard Worker
416*61046927SAndroid Build Coastguard Worker if (cs->device->physical_device->info->a7xx.load_shader_consts_via_preamble) {
417*61046927SAndroid Build Coastguard Worker if (shader->const_state.dynamic_offsets_ubo.size == 0)
418*61046927SAndroid Build Coastguard Worker return;
419*61046927SAndroid Build Coastguard Worker
420*61046927SAndroid Build Coastguard Worker uint32_t offsets[MAX_SETS];
421*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < phys_dev->usable_sets; i++) {
422*61046927SAndroid Build Coastguard Worker unsigned dynamic_offset_start =
423*61046927SAndroid Build Coastguard Worker program->dynamic_descriptor_offsets[i] / (A6XX_TEX_CONST_DWORDS * 4);
424*61046927SAndroid Build Coastguard Worker offsets[i] = dynamic_offset_start;
425*61046927SAndroid Build Coastguard Worker }
426*61046927SAndroid Build Coastguard Worker
427*61046927SAndroid Build Coastguard Worker /* A7XX TODO: Emit data via sub_cs instead of NOP */
428*61046927SAndroid Build Coastguard Worker uint64_t iova = tu_cs_emit_data_nop(cs, offsets, phys_dev->usable_sets, 4);
429*61046927SAndroid Build Coastguard Worker uint32_t offset = shader->const_state.dynamic_offsets_ubo.idx;
430*61046927SAndroid Build Coastguard Worker
431*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt7(cs, tu6_stage2opcode(xs->type), 5);
432*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, CP_LOAD_STATE6_0_DST_OFF(offset) |
433*61046927SAndroid Build Coastguard Worker CP_LOAD_STATE6_0_STATE_TYPE(ST6_UBO) |
434*61046927SAndroid Build Coastguard Worker CP_LOAD_STATE6_0_STATE_SRC(SS6_DIRECT) |
435*61046927SAndroid Build Coastguard Worker CP_LOAD_STATE6_0_STATE_BLOCK(tu6_stage2shadersb(xs->type)) |
436*61046927SAndroid Build Coastguard Worker CP_LOAD_STATE6_0_NUM_UNIT(1));
437*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, CP_LOAD_STATE6_1_EXT_SRC_ADDR(0));
438*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, CP_LOAD_STATE6_2_EXT_SRC_ADDR_HI(0));
439*61046927SAndroid Build Coastguard Worker int size_vec4s = DIV_ROUND_UP(phys_dev->usable_sets, 4);
440*61046927SAndroid Build Coastguard Worker tu_cs_emit_qw(cs, iova | ((uint64_t)A6XX_UBO_1_SIZE(size_vec4s) << 32));
441*61046927SAndroid Build Coastguard Worker } else {
442*61046927SAndroid Build Coastguard Worker if (shader->const_state.dynamic_offset_loc == UINT32_MAX)
443*61046927SAndroid Build Coastguard Worker return;
444*61046927SAndroid Build Coastguard Worker
445*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt7(cs, tu6_stage2opcode(xs->type), 3 + phys_dev->usable_sets);
446*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, CP_LOAD_STATE6_0_DST_OFF(shader->const_state.dynamic_offset_loc / 4) |
447*61046927SAndroid Build Coastguard Worker CP_LOAD_STATE6_0_STATE_TYPE(ST6_CONSTANTS) |
448*61046927SAndroid Build Coastguard Worker CP_LOAD_STATE6_0_STATE_SRC(SS6_DIRECT) |
449*61046927SAndroid Build Coastguard Worker CP_LOAD_STATE6_0_STATE_BLOCK(tu6_stage2shadersb(xs->type)) |
450*61046927SAndroid Build Coastguard Worker CP_LOAD_STATE6_0_NUM_UNIT(DIV_ROUND_UP(phys_dev->usable_sets, 4)));
451*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, CP_LOAD_STATE6_1_EXT_SRC_ADDR(0));
452*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, CP_LOAD_STATE6_2_EXT_SRC_ADDR_HI(0));
453*61046927SAndroid Build Coastguard Worker
454*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < phys_dev->usable_sets; i++) {
455*61046927SAndroid Build Coastguard Worker unsigned dynamic_offset_start =
456*61046927SAndroid Build Coastguard Worker program->dynamic_descriptor_offsets[i] / (A6XX_TEX_CONST_DWORDS * 4);
457*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, dynamic_offset_start);
458*61046927SAndroid Build Coastguard Worker }
459*61046927SAndroid Build Coastguard Worker }
460*61046927SAndroid Build Coastguard Worker }
461*61046927SAndroid Build Coastguard Worker
462*61046927SAndroid Build Coastguard Worker template <chip CHIP>
463*61046927SAndroid Build Coastguard Worker void
tu6_emit_shared_consts_enable(struct tu_cs * cs,bool enable)464*61046927SAndroid Build Coastguard Worker tu6_emit_shared_consts_enable(struct tu_cs *cs, bool enable)
465*61046927SAndroid Build Coastguard Worker {
466*61046927SAndroid Build Coastguard Worker if (CHIP == A6XX) {
467*61046927SAndroid Build Coastguard Worker /* Enable/disable shared constants */
468*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs, A6XX_HLSQ_SHARED_CONSTS(.enable = enable));
469*61046927SAndroid Build Coastguard Worker } else {
470*61046927SAndroid Build Coastguard Worker assert(!enable);
471*61046927SAndroid Build Coastguard Worker }
472*61046927SAndroid Build Coastguard Worker
473*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs, A6XX_SP_MODE_CONTROL(.constant_demotion_enable = true,
474*61046927SAndroid Build Coastguard Worker .isammode = ISAMMODE_GL,
475*61046927SAndroid Build Coastguard Worker .shared_consts_enable = enable));
476*61046927SAndroid Build Coastguard Worker }
477*61046927SAndroid Build Coastguard Worker TU_GENX(tu6_emit_shared_consts_enable);
478*61046927SAndroid Build Coastguard Worker
479*61046927SAndroid Build Coastguard Worker template <chip CHIP>
480*61046927SAndroid Build Coastguard Worker static void
tu6_setup_streamout(struct tu_cs * cs,const struct ir3_shader_variant * v,const struct ir3_shader_linkage * l)481*61046927SAndroid Build Coastguard Worker tu6_setup_streamout(struct tu_cs *cs,
482*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *v,
483*61046927SAndroid Build Coastguard Worker const struct ir3_shader_linkage *l)
484*61046927SAndroid Build Coastguard Worker {
485*61046927SAndroid Build Coastguard Worker const struct ir3_stream_output_info *info = &v->stream_output;
486*61046927SAndroid Build Coastguard Worker /* Note: 64 here comes from the HW layout of the program RAM. The program
487*61046927SAndroid Build Coastguard Worker * for stream N is at DWORD 64 * N.
488*61046927SAndroid Build Coastguard Worker */
489*61046927SAndroid Build Coastguard Worker #define A6XX_SO_PROG_DWORDS 64
490*61046927SAndroid Build Coastguard Worker uint32_t prog[A6XX_SO_PROG_DWORDS * IR3_MAX_SO_STREAMS] = {};
491*61046927SAndroid Build Coastguard Worker BITSET_DECLARE(valid_dwords, A6XX_SO_PROG_DWORDS * IR3_MAX_SO_STREAMS) = {0};
492*61046927SAndroid Build Coastguard Worker
493*61046927SAndroid Build Coastguard Worker /* TODO: streamout state should be in a non-GMEM draw state */
494*61046927SAndroid Build Coastguard Worker
495*61046927SAndroid Build Coastguard Worker /* no streamout: */
496*61046927SAndroid Build Coastguard Worker if (info->num_outputs == 0) {
497*61046927SAndroid Build Coastguard Worker unsigned sizedw = 4;
498*61046927SAndroid Build Coastguard Worker if (cs->device->physical_device->info->a6xx.tess_use_shared)
499*61046927SAndroid Build Coastguard Worker sizedw += 2;
500*61046927SAndroid Build Coastguard Worker
501*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt7(cs, CP_CONTEXT_REG_BUNCH, sizedw);
502*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, REG_A6XX_VPC_SO_CNTL);
503*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, 0);
504*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, REG_A6XX_VPC_SO_STREAM_CNTL);
505*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, 0);
506*61046927SAndroid Build Coastguard Worker
507*61046927SAndroid Build Coastguard Worker if (cs->device->physical_device->info->a6xx.tess_use_shared) {
508*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, REG_A6XX_PC_SO_STREAM_CNTL);
509*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, 0);
510*61046927SAndroid Build Coastguard Worker }
511*61046927SAndroid Build Coastguard Worker
512*61046927SAndroid Build Coastguard Worker return;
513*61046927SAndroid Build Coastguard Worker }
514*61046927SAndroid Build Coastguard Worker
515*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < info->num_outputs; i++) {
516*61046927SAndroid Build Coastguard Worker const struct ir3_stream_output *out = &info->output[i];
517*61046927SAndroid Build Coastguard Worker unsigned k = out->register_index;
518*61046927SAndroid Build Coastguard Worker unsigned idx;
519*61046927SAndroid Build Coastguard Worker
520*61046927SAndroid Build Coastguard Worker /* Skip it, if it's an output that was never assigned a register. */
521*61046927SAndroid Build Coastguard Worker if (k >= v->outputs_count || v->outputs[k].regid == INVALID_REG)
522*61046927SAndroid Build Coastguard Worker continue;
523*61046927SAndroid Build Coastguard Worker
524*61046927SAndroid Build Coastguard Worker /* linkage map sorted by order frag shader wants things, so
525*61046927SAndroid Build Coastguard Worker * a bit less ideal here..
526*61046927SAndroid Build Coastguard Worker */
527*61046927SAndroid Build Coastguard Worker for (idx = 0; idx < l->cnt; idx++)
528*61046927SAndroid Build Coastguard Worker if (l->var[idx].slot == v->outputs[k].slot)
529*61046927SAndroid Build Coastguard Worker break;
530*61046927SAndroid Build Coastguard Worker
531*61046927SAndroid Build Coastguard Worker assert(idx < l->cnt);
532*61046927SAndroid Build Coastguard Worker
533*61046927SAndroid Build Coastguard Worker for (unsigned j = 0; j < out->num_components; j++) {
534*61046927SAndroid Build Coastguard Worker unsigned c = j + out->start_component;
535*61046927SAndroid Build Coastguard Worker unsigned loc = l->var[idx].loc + c;
536*61046927SAndroid Build Coastguard Worker unsigned off = j + out->dst_offset; /* in dwords */
537*61046927SAndroid Build Coastguard Worker
538*61046927SAndroid Build Coastguard Worker assert(loc < A6XX_SO_PROG_DWORDS * 2);
539*61046927SAndroid Build Coastguard Worker unsigned dword = out->stream * A6XX_SO_PROG_DWORDS + loc/2;
540*61046927SAndroid Build Coastguard Worker if (loc & 1) {
541*61046927SAndroid Build Coastguard Worker prog[dword] |= A6XX_VPC_SO_PROG_B_EN |
542*61046927SAndroid Build Coastguard Worker A6XX_VPC_SO_PROG_B_BUF(out->output_buffer) |
543*61046927SAndroid Build Coastguard Worker A6XX_VPC_SO_PROG_B_OFF(off * 4);
544*61046927SAndroid Build Coastguard Worker } else {
545*61046927SAndroid Build Coastguard Worker prog[dword] |= A6XX_VPC_SO_PROG_A_EN |
546*61046927SAndroid Build Coastguard Worker A6XX_VPC_SO_PROG_A_BUF(out->output_buffer) |
547*61046927SAndroid Build Coastguard Worker A6XX_VPC_SO_PROG_A_OFF(off * 4);
548*61046927SAndroid Build Coastguard Worker }
549*61046927SAndroid Build Coastguard Worker BITSET_SET(valid_dwords, dword);
550*61046927SAndroid Build Coastguard Worker }
551*61046927SAndroid Build Coastguard Worker }
552*61046927SAndroid Build Coastguard Worker
553*61046927SAndroid Build Coastguard Worker unsigned prog_count = 0;
554*61046927SAndroid Build Coastguard Worker unsigned start, end;
555*61046927SAndroid Build Coastguard Worker BITSET_FOREACH_RANGE(start, end, valid_dwords,
556*61046927SAndroid Build Coastguard Worker A6XX_SO_PROG_DWORDS * IR3_MAX_SO_STREAMS) {
557*61046927SAndroid Build Coastguard Worker prog_count += end - start + 1;
558*61046927SAndroid Build Coastguard Worker }
559*61046927SAndroid Build Coastguard Worker
560*61046927SAndroid Build Coastguard Worker const bool emit_pc_so_stream_cntl =
561*61046927SAndroid Build Coastguard Worker cs->device->physical_device->info->a6xx.tess_use_shared &&
562*61046927SAndroid Build Coastguard Worker v->type == MESA_SHADER_TESS_EVAL;
563*61046927SAndroid Build Coastguard Worker
564*61046927SAndroid Build Coastguard Worker if (emit_pc_so_stream_cntl)
565*61046927SAndroid Build Coastguard Worker prog_count += 1;
566*61046927SAndroid Build Coastguard Worker
567*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt7(cs, CP_CONTEXT_REG_BUNCH, 10 + 2 * prog_count);
568*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, REG_A6XX_VPC_SO_STREAM_CNTL);
569*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, A6XX_VPC_SO_STREAM_CNTL_STREAM_ENABLE(info->streams_written) |
570*61046927SAndroid Build Coastguard Worker COND(info->stride[0] > 0,
571*61046927SAndroid Build Coastguard Worker A6XX_VPC_SO_STREAM_CNTL_BUF0_STREAM(1 + info->buffer_to_stream[0])) |
572*61046927SAndroid Build Coastguard Worker COND(info->stride[1] > 0,
573*61046927SAndroid Build Coastguard Worker A6XX_VPC_SO_STREAM_CNTL_BUF1_STREAM(1 + info->buffer_to_stream[1])) |
574*61046927SAndroid Build Coastguard Worker COND(info->stride[2] > 0,
575*61046927SAndroid Build Coastguard Worker A6XX_VPC_SO_STREAM_CNTL_BUF2_STREAM(1 + info->buffer_to_stream[2])) |
576*61046927SAndroid Build Coastguard Worker COND(info->stride[3] > 0,
577*61046927SAndroid Build Coastguard Worker A6XX_VPC_SO_STREAM_CNTL_BUF3_STREAM(1 + info->buffer_to_stream[3])));
578*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < 4; i++) {
579*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, REG_A6XX_VPC_SO_BUFFER_STRIDE(i));
580*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, info->stride[i]);
581*61046927SAndroid Build Coastguard Worker }
582*61046927SAndroid Build Coastguard Worker bool first = true;
583*61046927SAndroid Build Coastguard Worker BITSET_FOREACH_RANGE(start, end, valid_dwords,
584*61046927SAndroid Build Coastguard Worker A6XX_SO_PROG_DWORDS * IR3_MAX_SO_STREAMS) {
585*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, REG_A6XX_VPC_SO_CNTL);
586*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, COND(first, A6XX_VPC_SO_CNTL_RESET) |
587*61046927SAndroid Build Coastguard Worker A6XX_VPC_SO_CNTL_ADDR(start));
588*61046927SAndroid Build Coastguard Worker for (unsigned i = start; i < end; i++) {
589*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, REG_A6XX_VPC_SO_PROG);
590*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, prog[i]);
591*61046927SAndroid Build Coastguard Worker }
592*61046927SAndroid Build Coastguard Worker first = false;
593*61046927SAndroid Build Coastguard Worker }
594*61046927SAndroid Build Coastguard Worker
595*61046927SAndroid Build Coastguard Worker if (emit_pc_so_stream_cntl) {
596*61046927SAndroid Build Coastguard Worker /* Possibly not tess_use_shared related, but the combination of
597*61046927SAndroid Build Coastguard Worker * tess + xfb fails some tests if we don't emit this.
598*61046927SAndroid Build Coastguard Worker */
599*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, REG_A6XX_PC_SO_STREAM_CNTL);
600*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, A6XX_PC_SO_STREAM_CNTL_STREAM_ENABLE(info->streams_written));
601*61046927SAndroid Build Coastguard Worker }
602*61046927SAndroid Build Coastguard Worker }
603*61046927SAndroid Build Coastguard Worker
604*61046927SAndroid Build Coastguard Worker enum tu_geom_consts_type
605*61046927SAndroid Build Coastguard Worker {
606*61046927SAndroid Build Coastguard Worker TU_CONSTS_PRIMITIVE_MAP,
607*61046927SAndroid Build Coastguard Worker TU_CONSTS_PRIMITIVE_PARAM,
608*61046927SAndroid Build Coastguard Worker };
609*61046927SAndroid Build Coastguard Worker
610*61046927SAndroid Build Coastguard Worker static void
tu6_emit_const(struct tu_cs * cs,uint32_t opcode,enum tu_geom_consts_type type,const struct ir3_const_state * const_state,unsigned constlen,enum a6xx_state_block block,uint32_t offset,uint32_t size,const uint32_t * dwords)611*61046927SAndroid Build Coastguard Worker tu6_emit_const(struct tu_cs *cs, uint32_t opcode, enum tu_geom_consts_type type,
612*61046927SAndroid Build Coastguard Worker const struct ir3_const_state *const_state,
613*61046927SAndroid Build Coastguard Worker unsigned constlen, enum a6xx_state_block block,
614*61046927SAndroid Build Coastguard Worker uint32_t offset, uint32_t size, const uint32_t *dwords) {
615*61046927SAndroid Build Coastguard Worker assert(size % 4 == 0);
616*61046927SAndroid Build Coastguard Worker dwords = (uint32_t *)&((uint8_t *)dwords)[offset];
617*61046927SAndroid Build Coastguard Worker
618*61046927SAndroid Build Coastguard Worker if (!cs->device->physical_device->info->a7xx.load_shader_consts_via_preamble) {
619*61046927SAndroid Build Coastguard Worker uint32_t base;
620*61046927SAndroid Build Coastguard Worker switch (type) {
621*61046927SAndroid Build Coastguard Worker case TU_CONSTS_PRIMITIVE_MAP:
622*61046927SAndroid Build Coastguard Worker base = const_state->offsets.primitive_map;
623*61046927SAndroid Build Coastguard Worker break;
624*61046927SAndroid Build Coastguard Worker case TU_CONSTS_PRIMITIVE_PARAM:
625*61046927SAndroid Build Coastguard Worker base = const_state->offsets.primitive_param;
626*61046927SAndroid Build Coastguard Worker break;
627*61046927SAndroid Build Coastguard Worker default:
628*61046927SAndroid Build Coastguard Worker unreachable("bad consts type");
629*61046927SAndroid Build Coastguard Worker }
630*61046927SAndroid Build Coastguard Worker
631*61046927SAndroid Build Coastguard Worker int32_t adjusted_size = MIN2(base * 4 + size, constlen * 4) - base * 4;
632*61046927SAndroid Build Coastguard Worker if (adjusted_size <= 0)
633*61046927SAndroid Build Coastguard Worker return;
634*61046927SAndroid Build Coastguard Worker
635*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt7(cs, opcode, 3 + adjusted_size);
636*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, CP_LOAD_STATE6_0_DST_OFF(base) |
637*61046927SAndroid Build Coastguard Worker CP_LOAD_STATE6_0_STATE_TYPE(ST6_CONSTANTS) |
638*61046927SAndroid Build Coastguard Worker CP_LOAD_STATE6_0_STATE_SRC(SS6_DIRECT) |
639*61046927SAndroid Build Coastguard Worker CP_LOAD_STATE6_0_STATE_BLOCK(block) |
640*61046927SAndroid Build Coastguard Worker CP_LOAD_STATE6_0_NUM_UNIT(adjusted_size / 4));
641*61046927SAndroid Build Coastguard Worker
642*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, CP_LOAD_STATE6_1_EXT_SRC_ADDR(0));
643*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, CP_LOAD_STATE6_2_EXT_SRC_ADDR_HI(0));
644*61046927SAndroid Build Coastguard Worker
645*61046927SAndroid Build Coastguard Worker tu_cs_emit_array(cs, dwords, adjusted_size);
646*61046927SAndroid Build Coastguard Worker } else {
647*61046927SAndroid Build Coastguard Worker uint32_t base;
648*61046927SAndroid Build Coastguard Worker switch (type) {
649*61046927SAndroid Build Coastguard Worker case TU_CONSTS_PRIMITIVE_MAP:
650*61046927SAndroid Build Coastguard Worker base = const_state->primitive_map_ubo.idx;
651*61046927SAndroid Build Coastguard Worker break;
652*61046927SAndroid Build Coastguard Worker case TU_CONSTS_PRIMITIVE_PARAM:
653*61046927SAndroid Build Coastguard Worker base = const_state->primitive_param_ubo.idx;
654*61046927SAndroid Build Coastguard Worker break;
655*61046927SAndroid Build Coastguard Worker default:
656*61046927SAndroid Build Coastguard Worker unreachable("bad consts type");
657*61046927SAndroid Build Coastguard Worker }
658*61046927SAndroid Build Coastguard Worker if (base == -1)
659*61046927SAndroid Build Coastguard Worker return;
660*61046927SAndroid Build Coastguard Worker
661*61046927SAndroid Build Coastguard Worker /* A7XX TODO: Emit data via sub_cs instead of NOP */
662*61046927SAndroid Build Coastguard Worker uint64_t iova = tu_cs_emit_data_nop(cs, dwords, size, 4);
663*61046927SAndroid Build Coastguard Worker
664*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt7(cs, opcode, 5);
665*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, CP_LOAD_STATE6_0_DST_OFF(base) |
666*61046927SAndroid Build Coastguard Worker CP_LOAD_STATE6_0_STATE_TYPE(ST6_UBO) |
667*61046927SAndroid Build Coastguard Worker CP_LOAD_STATE6_0_STATE_SRC(SS6_DIRECT) |
668*61046927SAndroid Build Coastguard Worker CP_LOAD_STATE6_0_STATE_BLOCK(block) |
669*61046927SAndroid Build Coastguard Worker CP_LOAD_STATE6_0_NUM_UNIT(1));
670*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, CP_LOAD_STATE6_1_EXT_SRC_ADDR(0));
671*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, CP_LOAD_STATE6_2_EXT_SRC_ADDR_HI(0));
672*61046927SAndroid Build Coastguard Worker int size_vec4s = DIV_ROUND_UP(size, 4);
673*61046927SAndroid Build Coastguard Worker tu_cs_emit_qw(cs, iova | ((uint64_t)A6XX_UBO_1_SIZE(size_vec4s) << 32));
674*61046927SAndroid Build Coastguard Worker }
675*61046927SAndroid Build Coastguard Worker }
676*61046927SAndroid Build Coastguard Worker
677*61046927SAndroid Build Coastguard Worker static void
tu6_emit_link_map(struct tu_cs * cs,const struct ir3_shader_variant * producer,const struct ir3_shader_variant * consumer,enum a6xx_state_block sb)678*61046927SAndroid Build Coastguard Worker tu6_emit_link_map(struct tu_cs *cs,
679*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *producer,
680*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *consumer,
681*61046927SAndroid Build Coastguard Worker enum a6xx_state_block sb)
682*61046927SAndroid Build Coastguard Worker {
683*61046927SAndroid Build Coastguard Worker const struct ir3_const_state *const_state = ir3_const_state(consumer);
684*61046927SAndroid Build Coastguard Worker uint32_t size = ALIGN(consumer->input_size, 4);
685*61046927SAndroid Build Coastguard Worker
686*61046927SAndroid Build Coastguard Worker if (size == 0)
687*61046927SAndroid Build Coastguard Worker return;
688*61046927SAndroid Build Coastguard Worker
689*61046927SAndroid Build Coastguard Worker tu6_emit_const(cs, CP_LOAD_STATE6_GEOM, TU_CONSTS_PRIMITIVE_MAP,
690*61046927SAndroid Build Coastguard Worker const_state, consumer->constlen, sb, 0, size, producer->output_loc);
691*61046927SAndroid Build Coastguard Worker }
692*61046927SAndroid Build Coastguard Worker
693*61046927SAndroid Build Coastguard Worker static int
tu6_vpc_varying_mode(const struct ir3_shader_variant * fs,const struct ir3_shader_variant * last_shader,uint32_t index,uint8_t * interp_mode,uint8_t * ps_repl_mode)694*61046927SAndroid Build Coastguard Worker tu6_vpc_varying_mode(const struct ir3_shader_variant *fs,
695*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *last_shader,
696*61046927SAndroid Build Coastguard Worker uint32_t index,
697*61046927SAndroid Build Coastguard Worker uint8_t *interp_mode,
698*61046927SAndroid Build Coastguard Worker uint8_t *ps_repl_mode)
699*61046927SAndroid Build Coastguard Worker {
700*61046927SAndroid Build Coastguard Worker const uint32_t compmask = fs->inputs[index].compmask;
701*61046927SAndroid Build Coastguard Worker
702*61046927SAndroid Build Coastguard Worker /* NOTE: varyings are packed, so if compmask is 0xb then first, second, and
703*61046927SAndroid Build Coastguard Worker * fourth component occupy three consecutive varying slots
704*61046927SAndroid Build Coastguard Worker */
705*61046927SAndroid Build Coastguard Worker int shift = 0;
706*61046927SAndroid Build Coastguard Worker *interp_mode = 0;
707*61046927SAndroid Build Coastguard Worker *ps_repl_mode = 0;
708*61046927SAndroid Build Coastguard Worker if (fs->inputs[index].slot == VARYING_SLOT_PNTC) {
709*61046927SAndroid Build Coastguard Worker if (compmask & 0x1) {
710*61046927SAndroid Build Coastguard Worker *ps_repl_mode |= PS_REPL_S << shift;
711*61046927SAndroid Build Coastguard Worker shift += 2;
712*61046927SAndroid Build Coastguard Worker }
713*61046927SAndroid Build Coastguard Worker if (compmask & 0x2) {
714*61046927SAndroid Build Coastguard Worker *ps_repl_mode |= PS_REPL_T << shift;
715*61046927SAndroid Build Coastguard Worker shift += 2;
716*61046927SAndroid Build Coastguard Worker }
717*61046927SAndroid Build Coastguard Worker if (compmask & 0x4) {
718*61046927SAndroid Build Coastguard Worker *interp_mode |= INTERP_ZERO << shift;
719*61046927SAndroid Build Coastguard Worker shift += 2;
720*61046927SAndroid Build Coastguard Worker }
721*61046927SAndroid Build Coastguard Worker if (compmask & 0x8) {
722*61046927SAndroid Build Coastguard Worker *interp_mode |= INTERP_ONE << 6;
723*61046927SAndroid Build Coastguard Worker shift += 2;
724*61046927SAndroid Build Coastguard Worker }
725*61046927SAndroid Build Coastguard Worker } else if (fs->inputs[index].slot == VARYING_SLOT_LAYER ||
726*61046927SAndroid Build Coastguard Worker fs->inputs[index].slot == VARYING_SLOT_VIEWPORT) {
727*61046927SAndroid Build Coastguard Worker /* If the last geometry shader doesn't statically write these, they're
728*61046927SAndroid Build Coastguard Worker * implicitly zero and the FS is supposed to read zero.
729*61046927SAndroid Build Coastguard Worker */
730*61046927SAndroid Build Coastguard Worker const gl_varying_slot slot = (gl_varying_slot) fs->inputs[index].slot;
731*61046927SAndroid Build Coastguard Worker if (ir3_find_output(last_shader, slot) < 0 &&
732*61046927SAndroid Build Coastguard Worker (compmask & 0x1)) {
733*61046927SAndroid Build Coastguard Worker *interp_mode |= INTERP_ZERO;
734*61046927SAndroid Build Coastguard Worker } else {
735*61046927SAndroid Build Coastguard Worker *interp_mode |= INTERP_FLAT;
736*61046927SAndroid Build Coastguard Worker }
737*61046927SAndroid Build Coastguard Worker } else if (fs->inputs[index].flat) {
738*61046927SAndroid Build Coastguard Worker for (int i = 0; i < 4; i++) {
739*61046927SAndroid Build Coastguard Worker if (compmask & (1 << i)) {
740*61046927SAndroid Build Coastguard Worker *interp_mode |= INTERP_FLAT << shift;
741*61046927SAndroid Build Coastguard Worker shift += 2;
742*61046927SAndroid Build Coastguard Worker }
743*61046927SAndroid Build Coastguard Worker }
744*61046927SAndroid Build Coastguard Worker }
745*61046927SAndroid Build Coastguard Worker
746*61046927SAndroid Build Coastguard Worker return util_bitcount(compmask) * 2;
747*61046927SAndroid Build Coastguard Worker }
748*61046927SAndroid Build Coastguard Worker
749*61046927SAndroid Build Coastguard Worker static void
tu6_emit_vpc_varying_modes(struct tu_cs * cs,const struct ir3_shader_variant * fs,const struct ir3_shader_variant * last_shader)750*61046927SAndroid Build Coastguard Worker tu6_emit_vpc_varying_modes(struct tu_cs *cs,
751*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *fs,
752*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *last_shader)
753*61046927SAndroid Build Coastguard Worker {
754*61046927SAndroid Build Coastguard Worker uint32_t interp_modes[8] = { 0 };
755*61046927SAndroid Build Coastguard Worker uint32_t ps_repl_modes[8] = { 0 };
756*61046927SAndroid Build Coastguard Worker uint32_t interp_regs = 0;
757*61046927SAndroid Build Coastguard Worker
758*61046927SAndroid Build Coastguard Worker if (fs) {
759*61046927SAndroid Build Coastguard Worker for (int i = -1;
760*61046927SAndroid Build Coastguard Worker (i = ir3_next_varying(fs, i)) < (int) fs->inputs_count;) {
761*61046927SAndroid Build Coastguard Worker
762*61046927SAndroid Build Coastguard Worker /* get the mode for input i */
763*61046927SAndroid Build Coastguard Worker uint8_t interp_mode;
764*61046927SAndroid Build Coastguard Worker uint8_t ps_repl_mode;
765*61046927SAndroid Build Coastguard Worker const int bits =
766*61046927SAndroid Build Coastguard Worker tu6_vpc_varying_mode(fs, last_shader, i, &interp_mode, &ps_repl_mode);
767*61046927SAndroid Build Coastguard Worker
768*61046927SAndroid Build Coastguard Worker /* OR the mode into the array */
769*61046927SAndroid Build Coastguard Worker const uint32_t inloc = fs->inputs[i].inloc * 2;
770*61046927SAndroid Build Coastguard Worker uint32_t n = inloc / 32;
771*61046927SAndroid Build Coastguard Worker uint32_t shift = inloc % 32;
772*61046927SAndroid Build Coastguard Worker interp_modes[n] |= interp_mode << shift;
773*61046927SAndroid Build Coastguard Worker ps_repl_modes[n] |= ps_repl_mode << shift;
774*61046927SAndroid Build Coastguard Worker if (shift + bits > 32) {
775*61046927SAndroid Build Coastguard Worker n++;
776*61046927SAndroid Build Coastguard Worker shift = 32 - shift;
777*61046927SAndroid Build Coastguard Worker
778*61046927SAndroid Build Coastguard Worker interp_modes[n] |= interp_mode >> shift;
779*61046927SAndroid Build Coastguard Worker ps_repl_modes[n] |= ps_repl_mode >> shift;
780*61046927SAndroid Build Coastguard Worker }
781*61046927SAndroid Build Coastguard Worker interp_regs = MAX2(interp_regs, n + 1);
782*61046927SAndroid Build Coastguard Worker }
783*61046927SAndroid Build Coastguard Worker }
784*61046927SAndroid Build Coastguard Worker
785*61046927SAndroid Build Coastguard Worker if (interp_regs) {
786*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, REG_A6XX_VPC_VARYING_INTERP_MODE(0), interp_regs);
787*61046927SAndroid Build Coastguard Worker tu_cs_emit_array(cs, interp_modes, interp_regs);
788*61046927SAndroid Build Coastguard Worker
789*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, REG_A6XX_VPC_VARYING_PS_REPL_MODE(0), interp_regs);
790*61046927SAndroid Build Coastguard Worker tu_cs_emit_array(cs, ps_repl_modes, interp_regs);
791*61046927SAndroid Build Coastguard Worker }
792*61046927SAndroid Build Coastguard Worker }
793*61046927SAndroid Build Coastguard Worker
794*61046927SAndroid Build Coastguard Worker template <chip CHIP>
795*61046927SAndroid Build Coastguard Worker void
tu6_emit_vpc(struct tu_cs * cs,const struct ir3_shader_variant * vs,const struct ir3_shader_variant * hs,const struct ir3_shader_variant * ds,const struct ir3_shader_variant * gs,const struct ir3_shader_variant * fs)796*61046927SAndroid Build Coastguard Worker tu6_emit_vpc(struct tu_cs *cs,
797*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *vs,
798*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *hs,
799*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *ds,
800*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *gs,
801*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *fs)
802*61046927SAndroid Build Coastguard Worker {
803*61046927SAndroid Build Coastguard Worker /* note: doesn't compile as static because of the array regs.. */
804*61046927SAndroid Build Coastguard Worker const struct reg_config {
805*61046927SAndroid Build Coastguard Worker uint16_t reg_sp_xs_out_reg;
806*61046927SAndroid Build Coastguard Worker uint16_t reg_sp_xs_vpc_dst_reg;
807*61046927SAndroid Build Coastguard Worker uint16_t reg_vpc_xs_pack;
808*61046927SAndroid Build Coastguard Worker uint16_t reg_vpc_xs_clip_cntl;
809*61046927SAndroid Build Coastguard Worker uint16_t reg_vpc_xs_clip_cntl_v2;
810*61046927SAndroid Build Coastguard Worker uint16_t reg_gras_xs_cl_cntl;
811*61046927SAndroid Build Coastguard Worker uint16_t reg_pc_xs_out_cntl;
812*61046927SAndroid Build Coastguard Worker uint16_t reg_sp_xs_primitive_cntl;
813*61046927SAndroid Build Coastguard Worker uint16_t reg_vpc_xs_layer_cntl;
814*61046927SAndroid Build Coastguard Worker uint16_t reg_vpc_xs_layer_cntl_v2;
815*61046927SAndroid Build Coastguard Worker uint16_t reg_gras_xs_layer_cntl;
816*61046927SAndroid Build Coastguard Worker } reg_config[] = {
817*61046927SAndroid Build Coastguard Worker [MESA_SHADER_VERTEX] = {
818*61046927SAndroid Build Coastguard Worker REG_A6XX_SP_VS_OUT_REG(0),
819*61046927SAndroid Build Coastguard Worker REG_A6XX_SP_VS_VPC_DST_REG(0),
820*61046927SAndroid Build Coastguard Worker REG_A6XX_VPC_VS_PACK,
821*61046927SAndroid Build Coastguard Worker REG_A6XX_VPC_VS_CLIP_CNTL,
822*61046927SAndroid Build Coastguard Worker REG_A6XX_VPC_VS_CLIP_CNTL_V2,
823*61046927SAndroid Build Coastguard Worker REG_A6XX_GRAS_VS_CL_CNTL,
824*61046927SAndroid Build Coastguard Worker REG_A6XX_PC_VS_OUT_CNTL,
825*61046927SAndroid Build Coastguard Worker REG_A6XX_SP_VS_PRIMITIVE_CNTL,
826*61046927SAndroid Build Coastguard Worker REG_A6XX_VPC_VS_LAYER_CNTL,
827*61046927SAndroid Build Coastguard Worker REG_A6XX_VPC_VS_LAYER_CNTL_V2,
828*61046927SAndroid Build Coastguard Worker REG_A6XX_GRAS_VS_LAYER_CNTL
829*61046927SAndroid Build Coastguard Worker },
830*61046927SAndroid Build Coastguard Worker [MESA_SHADER_TESS_CTRL] = {
831*61046927SAndroid Build Coastguard Worker 0,
832*61046927SAndroid Build Coastguard Worker 0,
833*61046927SAndroid Build Coastguard Worker 0,
834*61046927SAndroid Build Coastguard Worker 0,
835*61046927SAndroid Build Coastguard Worker 0,
836*61046927SAndroid Build Coastguard Worker 0,
837*61046927SAndroid Build Coastguard Worker REG_A6XX_PC_HS_OUT_CNTL,
838*61046927SAndroid Build Coastguard Worker 0,
839*61046927SAndroid Build Coastguard Worker 0,
840*61046927SAndroid Build Coastguard Worker 0
841*61046927SAndroid Build Coastguard Worker },
842*61046927SAndroid Build Coastguard Worker [MESA_SHADER_TESS_EVAL] = {
843*61046927SAndroid Build Coastguard Worker REG_A6XX_SP_DS_OUT_REG(0),
844*61046927SAndroid Build Coastguard Worker REG_A6XX_SP_DS_VPC_DST_REG(0),
845*61046927SAndroid Build Coastguard Worker REG_A6XX_VPC_DS_PACK,
846*61046927SAndroid Build Coastguard Worker REG_A6XX_VPC_DS_CLIP_CNTL,
847*61046927SAndroid Build Coastguard Worker REG_A6XX_VPC_DS_CLIP_CNTL_V2,
848*61046927SAndroid Build Coastguard Worker REG_A6XX_GRAS_DS_CL_CNTL,
849*61046927SAndroid Build Coastguard Worker REG_A6XX_PC_DS_OUT_CNTL,
850*61046927SAndroid Build Coastguard Worker REG_A6XX_SP_DS_PRIMITIVE_CNTL,
851*61046927SAndroid Build Coastguard Worker REG_A6XX_VPC_DS_LAYER_CNTL,
852*61046927SAndroid Build Coastguard Worker REG_A6XX_VPC_DS_LAYER_CNTL_V2,
853*61046927SAndroid Build Coastguard Worker REG_A6XX_GRAS_DS_LAYER_CNTL
854*61046927SAndroid Build Coastguard Worker },
855*61046927SAndroid Build Coastguard Worker [MESA_SHADER_GEOMETRY] = {
856*61046927SAndroid Build Coastguard Worker REG_A6XX_SP_GS_OUT_REG(0),
857*61046927SAndroid Build Coastguard Worker REG_A6XX_SP_GS_VPC_DST_REG(0),
858*61046927SAndroid Build Coastguard Worker REG_A6XX_VPC_GS_PACK,
859*61046927SAndroid Build Coastguard Worker REG_A6XX_VPC_GS_CLIP_CNTL,
860*61046927SAndroid Build Coastguard Worker REG_A6XX_VPC_GS_CLIP_CNTL_V2,
861*61046927SAndroid Build Coastguard Worker REG_A6XX_GRAS_GS_CL_CNTL,
862*61046927SAndroid Build Coastguard Worker REG_A6XX_PC_GS_OUT_CNTL,
863*61046927SAndroid Build Coastguard Worker REG_A6XX_SP_GS_PRIMITIVE_CNTL,
864*61046927SAndroid Build Coastguard Worker REG_A6XX_VPC_GS_LAYER_CNTL,
865*61046927SAndroid Build Coastguard Worker REG_A6XX_VPC_GS_LAYER_CNTL_V2,
866*61046927SAndroid Build Coastguard Worker REG_A6XX_GRAS_GS_LAYER_CNTL
867*61046927SAndroid Build Coastguard Worker },
868*61046927SAndroid Build Coastguard Worker };
869*61046927SAndroid Build Coastguard Worker
870*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *last_shader;
871*61046927SAndroid Build Coastguard Worker if (gs) {
872*61046927SAndroid Build Coastguard Worker last_shader = gs;
873*61046927SAndroid Build Coastguard Worker } else if (hs) {
874*61046927SAndroid Build Coastguard Worker last_shader = ds;
875*61046927SAndroid Build Coastguard Worker } else {
876*61046927SAndroid Build Coastguard Worker last_shader = vs;
877*61046927SAndroid Build Coastguard Worker }
878*61046927SAndroid Build Coastguard Worker
879*61046927SAndroid Build Coastguard Worker const struct reg_config *cfg = ®_config[last_shader->type];
880*61046927SAndroid Build Coastguard Worker
881*61046927SAndroid Build Coastguard Worker struct ir3_shader_linkage linkage = {
882*61046927SAndroid Build Coastguard Worker .primid_loc = 0xff,
883*61046927SAndroid Build Coastguard Worker .clip0_loc = 0xff,
884*61046927SAndroid Build Coastguard Worker .clip1_loc = 0xff,
885*61046927SAndroid Build Coastguard Worker };
886*61046927SAndroid Build Coastguard Worker if (fs)
887*61046927SAndroid Build Coastguard Worker ir3_link_shaders(&linkage, last_shader, fs, true);
888*61046927SAndroid Build Coastguard Worker
889*61046927SAndroid Build Coastguard Worker if (last_shader->stream_output.num_outputs)
890*61046927SAndroid Build Coastguard Worker ir3_link_stream_out(&linkage, last_shader);
891*61046927SAndroid Build Coastguard Worker
892*61046927SAndroid Build Coastguard Worker /* a6xx finds position/pointsize at the end */
893*61046927SAndroid Build Coastguard Worker const uint32_t pointsize_regid =
894*61046927SAndroid Build Coastguard Worker ir3_find_output_regid(last_shader, VARYING_SLOT_PSIZ);
895*61046927SAndroid Build Coastguard Worker const uint32_t layer_regid =
896*61046927SAndroid Build Coastguard Worker ir3_find_output_regid(last_shader, VARYING_SLOT_LAYER);
897*61046927SAndroid Build Coastguard Worker const uint32_t view_regid =
898*61046927SAndroid Build Coastguard Worker ir3_find_output_regid(last_shader, VARYING_SLOT_VIEWPORT);
899*61046927SAndroid Build Coastguard Worker const uint32_t clip0_regid =
900*61046927SAndroid Build Coastguard Worker ir3_find_output_regid(last_shader, VARYING_SLOT_CLIP_DIST0);
901*61046927SAndroid Build Coastguard Worker const uint32_t clip1_regid =
902*61046927SAndroid Build Coastguard Worker ir3_find_output_regid(last_shader, VARYING_SLOT_CLIP_DIST1);
903*61046927SAndroid Build Coastguard Worker uint32_t flags_regid = gs ?
904*61046927SAndroid Build Coastguard Worker ir3_find_output_regid(gs, VARYING_SLOT_GS_VERTEX_FLAGS_IR3) : 0;
905*61046927SAndroid Build Coastguard Worker
906*61046927SAndroid Build Coastguard Worker uint32_t pointsize_loc = 0xff, position_loc = 0xff, layer_loc = 0xff, view_loc = 0xff;
907*61046927SAndroid Build Coastguard Worker
908*61046927SAndroid Build Coastguard Worker if (layer_regid != regid(63, 0)) {
909*61046927SAndroid Build Coastguard Worker layer_loc = linkage.max_loc;
910*61046927SAndroid Build Coastguard Worker ir3_link_add(&linkage, VARYING_SLOT_LAYER, layer_regid, 0x1, linkage.max_loc);
911*61046927SAndroid Build Coastguard Worker }
912*61046927SAndroid Build Coastguard Worker
913*61046927SAndroid Build Coastguard Worker if (view_regid != regid(63, 0)) {
914*61046927SAndroid Build Coastguard Worker view_loc = linkage.max_loc;
915*61046927SAndroid Build Coastguard Worker ir3_link_add(&linkage, VARYING_SLOT_VIEWPORT, view_regid, 0x1, linkage.max_loc);
916*61046927SAndroid Build Coastguard Worker }
917*61046927SAndroid Build Coastguard Worker
918*61046927SAndroid Build Coastguard Worker unsigned extra_pos = 0;
919*61046927SAndroid Build Coastguard Worker
920*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < last_shader->outputs_count; i++) {
921*61046927SAndroid Build Coastguard Worker if (last_shader->outputs[i].slot != VARYING_SLOT_POS)
922*61046927SAndroid Build Coastguard Worker continue;
923*61046927SAndroid Build Coastguard Worker
924*61046927SAndroid Build Coastguard Worker if (position_loc == 0xff)
925*61046927SAndroid Build Coastguard Worker position_loc = linkage.max_loc;
926*61046927SAndroid Build Coastguard Worker
927*61046927SAndroid Build Coastguard Worker ir3_link_add(&linkage, last_shader->outputs[i].slot,
928*61046927SAndroid Build Coastguard Worker last_shader->outputs[i].regid,
929*61046927SAndroid Build Coastguard Worker 0xf, position_loc + 4 * last_shader->outputs[i].view);
930*61046927SAndroid Build Coastguard Worker extra_pos = MAX2(extra_pos, last_shader->outputs[i].view);
931*61046927SAndroid Build Coastguard Worker }
932*61046927SAndroid Build Coastguard Worker
933*61046927SAndroid Build Coastguard Worker if (pointsize_regid != regid(63, 0)) {
934*61046927SAndroid Build Coastguard Worker pointsize_loc = linkage.max_loc;
935*61046927SAndroid Build Coastguard Worker ir3_link_add(&linkage, VARYING_SLOT_PSIZ, pointsize_regid, 0x1, linkage.max_loc);
936*61046927SAndroid Build Coastguard Worker }
937*61046927SAndroid Build Coastguard Worker
938*61046927SAndroid Build Coastguard Worker uint8_t clip_cull_mask = last_shader->clip_mask | last_shader->cull_mask;
939*61046927SAndroid Build Coastguard Worker
940*61046927SAndroid Build Coastguard Worker /* Handle the case where clip/cull distances aren't read by the FS */
941*61046927SAndroid Build Coastguard Worker uint32_t clip0_loc = linkage.clip0_loc, clip1_loc = linkage.clip1_loc;
942*61046927SAndroid Build Coastguard Worker if (clip0_loc == 0xff && clip0_regid != regid(63, 0)) {
943*61046927SAndroid Build Coastguard Worker clip0_loc = linkage.max_loc;
944*61046927SAndroid Build Coastguard Worker ir3_link_add(&linkage, VARYING_SLOT_CLIP_DIST0, clip0_regid,
945*61046927SAndroid Build Coastguard Worker clip_cull_mask & 0xf, linkage.max_loc);
946*61046927SAndroid Build Coastguard Worker }
947*61046927SAndroid Build Coastguard Worker if (clip1_loc == 0xff && clip1_regid != regid(63, 0)) {
948*61046927SAndroid Build Coastguard Worker clip1_loc = linkage.max_loc;
949*61046927SAndroid Build Coastguard Worker ir3_link_add(&linkage, VARYING_SLOT_CLIP_DIST1, clip1_regid,
950*61046927SAndroid Build Coastguard Worker clip_cull_mask >> 4, linkage.max_loc);
951*61046927SAndroid Build Coastguard Worker }
952*61046927SAndroid Build Coastguard Worker
953*61046927SAndroid Build Coastguard Worker tu6_setup_streamout<CHIP>(cs, last_shader, &linkage);
954*61046927SAndroid Build Coastguard Worker
955*61046927SAndroid Build Coastguard Worker /* There is a hardware bug on a750 where STRIDE_IN_VPC of 5 to 8 in GS with
956*61046927SAndroid Build Coastguard Worker * an input primitive type with adjacency, an output primitive type of
957*61046927SAndroid Build Coastguard Worker * points, and a high enough vertex count causes a hang.
958*61046927SAndroid Build Coastguard Worker */
959*61046927SAndroid Build Coastguard Worker if (cs->device->physical_device->info->a7xx.gs_vpc_adjacency_quirk &&
960*61046927SAndroid Build Coastguard Worker gs && gs->gs.output_primitive == MESA_PRIM_POINTS &&
961*61046927SAndroid Build Coastguard Worker linkage.max_loc > 4) {
962*61046927SAndroid Build Coastguard Worker linkage.max_loc = MAX2(linkage.max_loc, 9);
963*61046927SAndroid Build Coastguard Worker }
964*61046927SAndroid Build Coastguard Worker
965*61046927SAndroid Build Coastguard Worker /* The GPU hangs on some models when there are no outputs (xs_pack::CNT),
966*61046927SAndroid Build Coastguard Worker * at least when a DS is the last stage, so add a dummy output to keep it
967*61046927SAndroid Build Coastguard Worker * happy if there aren't any. We do this late in order to avoid emitting
968*61046927SAndroid Build Coastguard Worker * any unused code and make sure that optimizations don't remove it.
969*61046927SAndroid Build Coastguard Worker */
970*61046927SAndroid Build Coastguard Worker if (linkage.cnt == 0)
971*61046927SAndroid Build Coastguard Worker ir3_link_add(&linkage, 0, 0, 0x1, linkage.max_loc);
972*61046927SAndroid Build Coastguard Worker
973*61046927SAndroid Build Coastguard Worker /* map outputs of the last shader to VPC */
974*61046927SAndroid Build Coastguard Worker assert(linkage.cnt <= 32);
975*61046927SAndroid Build Coastguard Worker const uint32_t sp_out_count = DIV_ROUND_UP(linkage.cnt, 2);
976*61046927SAndroid Build Coastguard Worker const uint32_t sp_vpc_dst_count = DIV_ROUND_UP(linkage.cnt, 4);
977*61046927SAndroid Build Coastguard Worker uint32_t sp_out[16] = {0};
978*61046927SAndroid Build Coastguard Worker uint32_t sp_vpc_dst[8] = {0};
979*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < linkage.cnt; i++) {
980*61046927SAndroid Build Coastguard Worker ((uint16_t *) sp_out)[i] =
981*61046927SAndroid Build Coastguard Worker A6XX_SP_VS_OUT_REG_A_REGID(linkage.var[i].regid) |
982*61046927SAndroid Build Coastguard Worker A6XX_SP_VS_OUT_REG_A_COMPMASK(linkage.var[i].compmask);
983*61046927SAndroid Build Coastguard Worker ((uint8_t *) sp_vpc_dst)[i] =
984*61046927SAndroid Build Coastguard Worker A6XX_SP_VS_VPC_DST_REG_OUTLOC0(linkage.var[i].loc);
985*61046927SAndroid Build Coastguard Worker }
986*61046927SAndroid Build Coastguard Worker
987*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, cfg->reg_sp_xs_out_reg, sp_out_count);
988*61046927SAndroid Build Coastguard Worker tu_cs_emit_array(cs, sp_out, sp_out_count);
989*61046927SAndroid Build Coastguard Worker
990*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, cfg->reg_sp_xs_vpc_dst_reg, sp_vpc_dst_count);
991*61046927SAndroid Build Coastguard Worker tu_cs_emit_array(cs, sp_vpc_dst, sp_vpc_dst_count);
992*61046927SAndroid Build Coastguard Worker
993*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, cfg->reg_vpc_xs_pack, 1);
994*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, A6XX_VPC_VS_PACK_POSITIONLOC(position_loc) |
995*61046927SAndroid Build Coastguard Worker A6XX_VPC_VS_PACK_PSIZELOC(pointsize_loc) |
996*61046927SAndroid Build Coastguard Worker A6XX_VPC_VS_PACK_STRIDE_IN_VPC(linkage.max_loc) |
997*61046927SAndroid Build Coastguard Worker A6XX_VPC_VS_PACK_EXTRAPOS(extra_pos));
998*61046927SAndroid Build Coastguard Worker
999*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, cfg->reg_vpc_xs_clip_cntl, 1);
1000*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, A6XX_VPC_VS_CLIP_CNTL_CLIP_MASK(clip_cull_mask) |
1001*61046927SAndroid Build Coastguard Worker A6XX_VPC_VS_CLIP_CNTL_CLIP_DIST_03_LOC(clip0_loc) |
1002*61046927SAndroid Build Coastguard Worker A6XX_VPC_VS_CLIP_CNTL_CLIP_DIST_47_LOC(clip1_loc));
1003*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, cfg->reg_vpc_xs_clip_cntl_v2, 1);
1004*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, A6XX_VPC_VS_CLIP_CNTL_CLIP_MASK(clip_cull_mask) |
1005*61046927SAndroid Build Coastguard Worker A6XX_VPC_VS_CLIP_CNTL_CLIP_DIST_03_LOC(clip0_loc) |
1006*61046927SAndroid Build Coastguard Worker A6XX_VPC_VS_CLIP_CNTL_CLIP_DIST_47_LOC(clip1_loc));
1007*61046927SAndroid Build Coastguard Worker
1008*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, cfg->reg_gras_xs_cl_cntl, 1);
1009*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, A6XX_GRAS_VS_CL_CNTL_CLIP_MASK(last_shader->clip_mask) |
1010*61046927SAndroid Build Coastguard Worker A6XX_GRAS_VS_CL_CNTL_CULL_MASK(last_shader->cull_mask));
1011*61046927SAndroid Build Coastguard Worker
1012*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *geom_shaders[] = { vs, hs, ds, gs };
1013*61046927SAndroid Build Coastguard Worker
1014*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < ARRAY_SIZE(geom_shaders); i++) {
1015*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *shader = geom_shaders[i];
1016*61046927SAndroid Build Coastguard Worker if (!shader)
1017*61046927SAndroid Build Coastguard Worker continue;
1018*61046927SAndroid Build Coastguard Worker
1019*61046927SAndroid Build Coastguard Worker bool primid = shader->type != MESA_SHADER_VERTEX &&
1020*61046927SAndroid Build Coastguard Worker VALIDREG(ir3_find_sysval_regid(shader, SYSTEM_VALUE_PRIMITIVE_ID));
1021*61046927SAndroid Build Coastguard Worker
1022*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, reg_config[shader->type].reg_pc_xs_out_cntl, 1);
1023*61046927SAndroid Build Coastguard Worker if (shader == last_shader) {
1024*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, A6XX_PC_VS_OUT_CNTL_STRIDE_IN_VPC(linkage.max_loc) |
1025*61046927SAndroid Build Coastguard Worker CONDREG(pointsize_regid, A6XX_PC_VS_OUT_CNTL_PSIZE) |
1026*61046927SAndroid Build Coastguard Worker CONDREG(layer_regid, A6XX_PC_VS_OUT_CNTL_LAYER) |
1027*61046927SAndroid Build Coastguard Worker CONDREG(view_regid, A6XX_PC_VS_OUT_CNTL_VIEW) |
1028*61046927SAndroid Build Coastguard Worker COND(primid, A6XX_PC_VS_OUT_CNTL_PRIMITIVE_ID) |
1029*61046927SAndroid Build Coastguard Worker A6XX_PC_VS_OUT_CNTL_CLIP_MASK(clip_cull_mask));
1030*61046927SAndroid Build Coastguard Worker } else {
1031*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, COND(primid, A6XX_PC_VS_OUT_CNTL_PRIMITIVE_ID));
1032*61046927SAndroid Build Coastguard Worker }
1033*61046927SAndroid Build Coastguard Worker }
1034*61046927SAndroid Build Coastguard Worker
1035*61046927SAndroid Build Coastguard Worker /* if vertex_flags somehow gets optimized out, your gonna have a bad time: */
1036*61046927SAndroid Build Coastguard Worker if (gs)
1037*61046927SAndroid Build Coastguard Worker assert(flags_regid != INVALID_REG);
1038*61046927SAndroid Build Coastguard Worker
1039*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, cfg->reg_sp_xs_primitive_cntl, 1);
1040*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, A6XX_SP_VS_PRIMITIVE_CNTL_OUT(linkage.cnt) |
1041*61046927SAndroid Build Coastguard Worker A6XX_SP_GS_PRIMITIVE_CNTL_FLAGS_REGID(flags_regid));
1042*61046927SAndroid Build Coastguard Worker
1043*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, cfg->reg_vpc_xs_layer_cntl, 1);
1044*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, A6XX_VPC_VS_LAYER_CNTL_LAYERLOC(layer_loc) |
1045*61046927SAndroid Build Coastguard Worker A6XX_VPC_VS_LAYER_CNTL_VIEWLOC(view_loc) |
1046*61046927SAndroid Build Coastguard Worker 0xff0000);
1047*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, cfg->reg_vpc_xs_layer_cntl_v2, 1);
1048*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, A6XX_VPC_VS_LAYER_CNTL_LAYERLOC(layer_loc) |
1049*61046927SAndroid Build Coastguard Worker A6XX_VPC_VS_LAYER_CNTL_VIEWLOC(view_loc) |
1050*61046927SAndroid Build Coastguard Worker 0xff0000);
1051*61046927SAndroid Build Coastguard Worker
1052*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, cfg->reg_gras_xs_layer_cntl, 1);
1053*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, CONDREG(layer_regid, A6XX_GRAS_GS_LAYER_CNTL_WRITES_LAYER) |
1054*61046927SAndroid Build Coastguard Worker CONDREG(view_regid, A6XX_GRAS_GS_LAYER_CNTL_WRITES_VIEW));
1055*61046927SAndroid Build Coastguard Worker
1056*61046927SAndroid Build Coastguard Worker tu6_emit_vpc_varying_modes(cs, fs, last_shader);
1057*61046927SAndroid Build Coastguard Worker }
1058*61046927SAndroid Build Coastguard Worker TU_GENX(tu6_emit_vpc);
1059*61046927SAndroid Build Coastguard Worker
1060*61046927SAndroid Build Coastguard Worker static void
tu6_emit_vs_params(struct tu_cs * cs,const struct ir3_const_state * const_state,unsigned constlen,unsigned param_stride,unsigned num_vertices)1061*61046927SAndroid Build Coastguard Worker tu6_emit_vs_params(struct tu_cs *cs,
1062*61046927SAndroid Build Coastguard Worker const struct ir3_const_state *const_state,
1063*61046927SAndroid Build Coastguard Worker unsigned constlen,
1064*61046927SAndroid Build Coastguard Worker unsigned param_stride,
1065*61046927SAndroid Build Coastguard Worker unsigned num_vertices)
1066*61046927SAndroid Build Coastguard Worker {
1067*61046927SAndroid Build Coastguard Worker uint32_t vs_params[4] = {
1068*61046927SAndroid Build Coastguard Worker param_stride * num_vertices * 4, /* vs primitive stride */
1069*61046927SAndroid Build Coastguard Worker param_stride * 4, /* vs vertex stride */
1070*61046927SAndroid Build Coastguard Worker 0,
1071*61046927SAndroid Build Coastguard Worker 0,
1072*61046927SAndroid Build Coastguard Worker };
1073*61046927SAndroid Build Coastguard Worker tu6_emit_const(cs, CP_LOAD_STATE6_GEOM, TU_CONSTS_PRIMITIVE_PARAM,
1074*61046927SAndroid Build Coastguard Worker const_state, constlen, SB6_VS_SHADER, 0,
1075*61046927SAndroid Build Coastguard Worker ARRAY_SIZE(vs_params), vs_params);
1076*61046927SAndroid Build Coastguard Worker }
1077*61046927SAndroid Build Coastguard Worker
1078*61046927SAndroid Build Coastguard Worker static void
tu_get_tess_iova(struct tu_device * dev,uint64_t * tess_factor_iova,uint64_t * tess_param_iova)1079*61046927SAndroid Build Coastguard Worker tu_get_tess_iova(struct tu_device *dev,
1080*61046927SAndroid Build Coastguard Worker uint64_t *tess_factor_iova,
1081*61046927SAndroid Build Coastguard Worker uint64_t *tess_param_iova)
1082*61046927SAndroid Build Coastguard Worker {
1083*61046927SAndroid Build Coastguard Worker /* Create the shared tess factor BO the first time tess is used on the device. */
1084*61046927SAndroid Build Coastguard Worker if (!dev->tess_bo) {
1085*61046927SAndroid Build Coastguard Worker mtx_lock(&dev->mutex);
1086*61046927SAndroid Build Coastguard Worker if (!dev->tess_bo) {
1087*61046927SAndroid Build Coastguard Worker tu_bo_init_new(dev, NULL, &dev->tess_bo, TU_TESS_BO_SIZE,
1088*61046927SAndroid Build Coastguard Worker TU_BO_ALLOC_INTERNAL_RESOURCE, "tess");
1089*61046927SAndroid Build Coastguard Worker }
1090*61046927SAndroid Build Coastguard Worker mtx_unlock(&dev->mutex);
1091*61046927SAndroid Build Coastguard Worker }
1092*61046927SAndroid Build Coastguard Worker
1093*61046927SAndroid Build Coastguard Worker *tess_factor_iova = dev->tess_bo->iova;
1094*61046927SAndroid Build Coastguard Worker *tess_param_iova = dev->tess_bo->iova + TU_TESS_FACTOR_SIZE;
1095*61046927SAndroid Build Coastguard Worker }
1096*61046927SAndroid Build Coastguard Worker
1097*61046927SAndroid Build Coastguard Worker static const enum mesa_vk_dynamic_graphics_state tu_patch_control_points_state[] = {
1098*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_TS_PATCH_CONTROL_POINTS,
1099*61046927SAndroid Build Coastguard Worker };
1100*61046927SAndroid Build Coastguard Worker
1101*61046927SAndroid Build Coastguard Worker #define HS_PARAMS_SIZE 8
1102*61046927SAndroid Build Coastguard Worker
1103*61046927SAndroid Build Coastguard Worker template <chip CHIP>
1104*61046927SAndroid Build Coastguard Worker static unsigned
tu6_patch_control_points_size(struct tu_device * dev,const struct tu_shader * vs,const struct tu_shader * tcs,const struct tu_shader * tes,const struct tu_program_state * program,uint32_t patch_control_points)1105*61046927SAndroid Build Coastguard Worker tu6_patch_control_points_size(struct tu_device *dev,
1106*61046927SAndroid Build Coastguard Worker const struct tu_shader *vs,
1107*61046927SAndroid Build Coastguard Worker const struct tu_shader *tcs,
1108*61046927SAndroid Build Coastguard Worker const struct tu_shader *tes,
1109*61046927SAndroid Build Coastguard Worker const struct tu_program_state *program,
1110*61046927SAndroid Build Coastguard Worker uint32_t patch_control_points)
1111*61046927SAndroid Build Coastguard Worker {
1112*61046927SAndroid Build Coastguard Worker if (dev->physical_device->info->a7xx.load_shader_consts_via_preamble) {
1113*61046927SAndroid Build Coastguard Worker #define EMIT_CONST_DWORDS(const_dwords) (6 + const_dwords + 4)
1114*61046927SAndroid Build Coastguard Worker return EMIT_CONST_DWORDS(4) +
1115*61046927SAndroid Build Coastguard Worker EMIT_CONST_DWORDS(HS_PARAMS_SIZE) + 2 + 2 + 2;
1116*61046927SAndroid Build Coastguard Worker #undef EMIT_CONST_DWORDS
1117*61046927SAndroid Build Coastguard Worker } else {
1118*61046927SAndroid Build Coastguard Worker #define EMIT_CONST_DWORDS(const_dwords) (4 + const_dwords)
1119*61046927SAndroid Build Coastguard Worker return EMIT_CONST_DWORDS(4) +
1120*61046927SAndroid Build Coastguard Worker EMIT_CONST_DWORDS(HS_PARAMS_SIZE) + 2 + 2 + 2;
1121*61046927SAndroid Build Coastguard Worker #undef EMIT_CONST_DWORDS
1122*61046927SAndroid Build Coastguard Worker }
1123*61046927SAndroid Build Coastguard Worker }
1124*61046927SAndroid Build Coastguard Worker
1125*61046927SAndroid Build Coastguard Worker template <chip CHIP>
1126*61046927SAndroid Build Coastguard Worker void
tu6_emit_patch_control_points(struct tu_cs * cs,const struct tu_shader * vs,const struct tu_shader * tcs,const struct tu_shader * tes,const struct tu_program_state * program,uint32_t patch_control_points)1127*61046927SAndroid Build Coastguard Worker tu6_emit_patch_control_points(struct tu_cs *cs,
1128*61046927SAndroid Build Coastguard Worker const struct tu_shader *vs,
1129*61046927SAndroid Build Coastguard Worker const struct tu_shader *tcs,
1130*61046927SAndroid Build Coastguard Worker const struct tu_shader *tes,
1131*61046927SAndroid Build Coastguard Worker const struct tu_program_state *program,
1132*61046927SAndroid Build Coastguard Worker uint32_t patch_control_points)
1133*61046927SAndroid Build Coastguard Worker {
1134*61046927SAndroid Build Coastguard Worker if (!tcs->variant)
1135*61046927SAndroid Build Coastguard Worker return;
1136*61046927SAndroid Build Coastguard Worker
1137*61046927SAndroid Build Coastguard Worker struct tu_device *dev = cs->device;
1138*61046927SAndroid Build Coastguard Worker
1139*61046927SAndroid Build Coastguard Worker tu6_emit_vs_params(cs,
1140*61046927SAndroid Build Coastguard Worker &program->link[MESA_SHADER_VERTEX].const_state,
1141*61046927SAndroid Build Coastguard Worker program->link[MESA_SHADER_VERTEX].constlen,
1142*61046927SAndroid Build Coastguard Worker vs->variant->output_size,
1143*61046927SAndroid Build Coastguard Worker patch_control_points);
1144*61046927SAndroid Build Coastguard Worker
1145*61046927SAndroid Build Coastguard Worker uint64_t tess_factor_iova, tess_param_iova;
1146*61046927SAndroid Build Coastguard Worker tu_get_tess_iova(dev, &tess_factor_iova, &tess_param_iova);
1147*61046927SAndroid Build Coastguard Worker
1148*61046927SAndroid Build Coastguard Worker uint32_t hs_params[HS_PARAMS_SIZE] = {
1149*61046927SAndroid Build Coastguard Worker vs->variant->output_size * patch_control_points * 4, /* hs primitive stride */
1150*61046927SAndroid Build Coastguard Worker vs->variant->output_size * 4, /* hs vertex stride */
1151*61046927SAndroid Build Coastguard Worker tcs->variant->output_size,
1152*61046927SAndroid Build Coastguard Worker patch_control_points,
1153*61046927SAndroid Build Coastguard Worker tess_param_iova,
1154*61046927SAndroid Build Coastguard Worker tess_param_iova >> 32,
1155*61046927SAndroid Build Coastguard Worker tess_factor_iova,
1156*61046927SAndroid Build Coastguard Worker tess_factor_iova >> 32,
1157*61046927SAndroid Build Coastguard Worker };
1158*61046927SAndroid Build Coastguard Worker
1159*61046927SAndroid Build Coastguard Worker const struct ir3_const_state *hs_const =
1160*61046927SAndroid Build Coastguard Worker &program->link[MESA_SHADER_TESS_CTRL].const_state;
1161*61046927SAndroid Build Coastguard Worker unsigned hs_constlen = program->link[MESA_SHADER_TESS_CTRL].constlen;
1162*61046927SAndroid Build Coastguard Worker tu6_emit_const(cs, CP_LOAD_STATE6_GEOM, TU_CONSTS_PRIMITIVE_PARAM,
1163*61046927SAndroid Build Coastguard Worker hs_const, hs_constlen, SB6_HS_SHADER, 0,
1164*61046927SAndroid Build Coastguard Worker ARRAY_SIZE(hs_params), hs_params);
1165*61046927SAndroid Build Coastguard Worker
1166*61046927SAndroid Build Coastguard Worker uint32_t patch_local_mem_size_16b =
1167*61046927SAndroid Build Coastguard Worker patch_control_points * vs->variant->output_size / 4;
1168*61046927SAndroid Build Coastguard Worker
1169*61046927SAndroid Build Coastguard Worker /* Total attribute slots in HS incoming patch. */
1170*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, REG_A6XX_PC_HS_INPUT_SIZE, 1);
1171*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, patch_local_mem_size_16b);
1172*61046927SAndroid Build Coastguard Worker
1173*61046927SAndroid Build Coastguard Worker const uint32_t wavesize = 64;
1174*61046927SAndroid Build Coastguard Worker const uint32_t vs_hs_local_mem_size = 16384;
1175*61046927SAndroid Build Coastguard Worker
1176*61046927SAndroid Build Coastguard Worker uint32_t max_patches_per_wave;
1177*61046927SAndroid Build Coastguard Worker if (dev->physical_device->info->a6xx.tess_use_shared) {
1178*61046927SAndroid Build Coastguard Worker /* HS invocations for a patch are always within the same wave,
1179*61046927SAndroid Build Coastguard Worker * making barriers less expensive. VS can't have barriers so we
1180*61046927SAndroid Build Coastguard Worker * don't care about VS invocations being in the same wave.
1181*61046927SAndroid Build Coastguard Worker */
1182*61046927SAndroid Build Coastguard Worker max_patches_per_wave = wavesize / tcs->variant->tess.tcs_vertices_out;
1183*61046927SAndroid Build Coastguard Worker } else {
1184*61046927SAndroid Build Coastguard Worker /* VS is also in the same wave */
1185*61046927SAndroid Build Coastguard Worker max_patches_per_wave =
1186*61046927SAndroid Build Coastguard Worker wavesize / MAX2(patch_control_points,
1187*61046927SAndroid Build Coastguard Worker tcs->variant->tess.tcs_vertices_out);
1188*61046927SAndroid Build Coastguard Worker }
1189*61046927SAndroid Build Coastguard Worker
1190*61046927SAndroid Build Coastguard Worker uint32_t patches_per_wave =
1191*61046927SAndroid Build Coastguard Worker MIN2(vs_hs_local_mem_size / (patch_local_mem_size_16b * 16),
1192*61046927SAndroid Build Coastguard Worker max_patches_per_wave);
1193*61046927SAndroid Build Coastguard Worker
1194*61046927SAndroid Build Coastguard Worker uint32_t wave_input_size = DIV_ROUND_UP(
1195*61046927SAndroid Build Coastguard Worker patches_per_wave * patch_local_mem_size_16b * 16, 256);
1196*61046927SAndroid Build Coastguard Worker
1197*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, REG_A6XX_SP_HS_WAVE_INPUT_SIZE, 1);
1198*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, wave_input_size);
1199*61046927SAndroid Build Coastguard Worker
1200*61046927SAndroid Build Coastguard Worker /* maximum number of patches that can fit in tess factor/param buffers */
1201*61046927SAndroid Build Coastguard Worker uint32_t subdraw_size = MIN2(TU_TESS_FACTOR_SIZE / ir3_tess_factor_stride(tes->variant->key.tessellation),
1202*61046927SAndroid Build Coastguard Worker TU_TESS_PARAM_SIZE / (tcs->variant->output_size * 4));
1203*61046927SAndroid Build Coastguard Worker /* convert from # of patches to draw count */
1204*61046927SAndroid Build Coastguard Worker subdraw_size *= patch_control_points;
1205*61046927SAndroid Build Coastguard Worker
1206*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt7(cs, CP_SET_SUBDRAW_SIZE, 1);
1207*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, subdraw_size);
1208*61046927SAndroid Build Coastguard Worker }
1209*61046927SAndroid Build Coastguard Worker
1210*61046927SAndroid Build Coastguard Worker static void
tu6_emit_geom_tess_consts(struct tu_cs * cs,const struct ir3_shader_variant * vs,const struct ir3_shader_variant * hs,const struct ir3_shader_variant * ds,const struct ir3_shader_variant * gs)1211*61046927SAndroid Build Coastguard Worker tu6_emit_geom_tess_consts(struct tu_cs *cs,
1212*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *vs,
1213*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *hs,
1214*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *ds,
1215*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *gs)
1216*61046927SAndroid Build Coastguard Worker {
1217*61046927SAndroid Build Coastguard Worker struct tu_device *dev = cs->device;
1218*61046927SAndroid Build Coastguard Worker
1219*61046927SAndroid Build Coastguard Worker if (gs && !hs) {
1220*61046927SAndroid Build Coastguard Worker tu6_emit_vs_params(cs, ir3_const_state(vs), vs->constlen,
1221*61046927SAndroid Build Coastguard Worker vs->output_size, gs->gs.vertices_in);
1222*61046927SAndroid Build Coastguard Worker }
1223*61046927SAndroid Build Coastguard Worker
1224*61046927SAndroid Build Coastguard Worker if (hs) {
1225*61046927SAndroid Build Coastguard Worker uint64_t tess_factor_iova, tess_param_iova;
1226*61046927SAndroid Build Coastguard Worker tu_get_tess_iova(dev, &tess_factor_iova, &tess_param_iova);
1227*61046927SAndroid Build Coastguard Worker
1228*61046927SAndroid Build Coastguard Worker uint32_t ds_params[8] = {
1229*61046927SAndroid Build Coastguard Worker gs ? ds->output_size * gs->gs.vertices_in * 4 : 0, /* ds primitive stride */
1230*61046927SAndroid Build Coastguard Worker ds->output_size * 4, /* ds vertex stride */
1231*61046927SAndroid Build Coastguard Worker hs->output_size, /* hs vertex stride (dwords) */
1232*61046927SAndroid Build Coastguard Worker hs->tess.tcs_vertices_out,
1233*61046927SAndroid Build Coastguard Worker tess_param_iova,
1234*61046927SAndroid Build Coastguard Worker tess_param_iova >> 32,
1235*61046927SAndroid Build Coastguard Worker tess_factor_iova,
1236*61046927SAndroid Build Coastguard Worker tess_factor_iova >> 32,
1237*61046927SAndroid Build Coastguard Worker };
1238*61046927SAndroid Build Coastguard Worker
1239*61046927SAndroid Build Coastguard Worker tu6_emit_const(cs, CP_LOAD_STATE6_GEOM, TU_CONSTS_PRIMITIVE_PARAM,
1240*61046927SAndroid Build Coastguard Worker ds->const_state, ds->constlen, SB6_DS_SHADER, 0,
1241*61046927SAndroid Build Coastguard Worker ARRAY_SIZE(ds_params), ds_params);
1242*61046927SAndroid Build Coastguard Worker }
1243*61046927SAndroid Build Coastguard Worker
1244*61046927SAndroid Build Coastguard Worker if (gs) {
1245*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *prev = ds ? ds : vs;
1246*61046927SAndroid Build Coastguard Worker uint32_t gs_params[4] = {
1247*61046927SAndroid Build Coastguard Worker prev->output_size * gs->gs.vertices_in * 4, /* gs primitive stride */
1248*61046927SAndroid Build Coastguard Worker prev->output_size * 4, /* gs vertex stride */
1249*61046927SAndroid Build Coastguard Worker 0,
1250*61046927SAndroid Build Coastguard Worker 0,
1251*61046927SAndroid Build Coastguard Worker };
1252*61046927SAndroid Build Coastguard Worker tu6_emit_const(cs, CP_LOAD_STATE6_GEOM, TU_CONSTS_PRIMITIVE_PARAM,
1253*61046927SAndroid Build Coastguard Worker gs->const_state, gs->constlen, SB6_GS_SHADER, 0,
1254*61046927SAndroid Build Coastguard Worker ARRAY_SIZE(gs_params), gs_params);
1255*61046927SAndroid Build Coastguard Worker }
1256*61046927SAndroid Build Coastguard Worker }
1257*61046927SAndroid Build Coastguard Worker
1258*61046927SAndroid Build Coastguard Worker template <chip CHIP>
1259*61046927SAndroid Build Coastguard Worker static void
tu6_emit_program_config(struct tu_cs * cs,const struct tu_program_state * prog,struct tu_shader ** shaders,const struct ir3_shader_variant ** variants)1260*61046927SAndroid Build Coastguard Worker tu6_emit_program_config(struct tu_cs *cs,
1261*61046927SAndroid Build Coastguard Worker const struct tu_program_state *prog,
1262*61046927SAndroid Build Coastguard Worker struct tu_shader **shaders,
1263*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant **variants)
1264*61046927SAndroid Build Coastguard Worker {
1265*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(MESA_SHADER_VERTEX == 0);
1266*61046927SAndroid Build Coastguard Worker
1267*61046927SAndroid Build Coastguard Worker bool shared_consts_enable =
1268*61046927SAndroid Build Coastguard Worker prog->shared_consts.type == IR3_PUSH_CONSTS_SHARED;
1269*61046927SAndroid Build Coastguard Worker tu6_emit_shared_consts_enable<CHIP>(cs, shared_consts_enable);
1270*61046927SAndroid Build Coastguard Worker
1271*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs, HLSQ_INVALIDATE_CMD(CHIP,
1272*61046927SAndroid Build Coastguard Worker .vs_state = true,
1273*61046927SAndroid Build Coastguard Worker .hs_state = true,
1274*61046927SAndroid Build Coastguard Worker .ds_state = true,
1275*61046927SAndroid Build Coastguard Worker .gs_state = true,
1276*61046927SAndroid Build Coastguard Worker .fs_state = true,
1277*61046927SAndroid Build Coastguard Worker .gfx_ibo = true,
1278*61046927SAndroid Build Coastguard Worker .gfx_shared_const = shared_consts_enable));
1279*61046927SAndroid Build Coastguard Worker for (size_t stage_idx = MESA_SHADER_VERTEX;
1280*61046927SAndroid Build Coastguard Worker stage_idx <= MESA_SHADER_FRAGMENT; stage_idx++) {
1281*61046927SAndroid Build Coastguard Worker gl_shader_stage stage = (gl_shader_stage) stage_idx;
1282*61046927SAndroid Build Coastguard Worker tu6_emit_xs_config<CHIP>(cs, stage, variants[stage]);
1283*61046927SAndroid Build Coastguard Worker }
1284*61046927SAndroid Build Coastguard Worker
1285*61046927SAndroid Build Coastguard Worker for (size_t stage_idx = MESA_SHADER_VERTEX;
1286*61046927SAndroid Build Coastguard Worker stage_idx <= MESA_SHADER_FRAGMENT; stage_idx++) {
1287*61046927SAndroid Build Coastguard Worker gl_shader_stage stage = (gl_shader_stage) stage_idx;
1288*61046927SAndroid Build Coastguard Worker tu6_emit_dynamic_offset(cs, variants[stage], shaders[stage], prog);
1289*61046927SAndroid Build Coastguard Worker }
1290*61046927SAndroid Build Coastguard Worker
1291*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *vs = variants[MESA_SHADER_VERTEX];
1292*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *hs = variants[MESA_SHADER_TESS_CTRL];
1293*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *ds = variants[MESA_SHADER_TESS_EVAL];
1294*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *gs = variants[MESA_SHADER_GEOMETRY];
1295*61046927SAndroid Build Coastguard Worker
1296*61046927SAndroid Build Coastguard Worker if (hs) {
1297*61046927SAndroid Build Coastguard Worker tu6_emit_link_map(cs, vs, hs, SB6_HS_SHADER);
1298*61046927SAndroid Build Coastguard Worker tu6_emit_link_map(cs, hs, ds, SB6_DS_SHADER);
1299*61046927SAndroid Build Coastguard Worker }
1300*61046927SAndroid Build Coastguard Worker
1301*61046927SAndroid Build Coastguard Worker if (gs) {
1302*61046927SAndroid Build Coastguard Worker if (hs) {
1303*61046927SAndroid Build Coastguard Worker tu6_emit_link_map(cs, ds, gs, SB6_GS_SHADER);
1304*61046927SAndroid Build Coastguard Worker } else {
1305*61046927SAndroid Build Coastguard Worker tu6_emit_link_map(cs, vs, gs, SB6_GS_SHADER);
1306*61046927SAndroid Build Coastguard Worker }
1307*61046927SAndroid Build Coastguard Worker
1308*61046927SAndroid Build Coastguard Worker uint32_t prev_stage_output_size = ds ? ds->output_size : vs->output_size;
1309*61046927SAndroid Build Coastguard Worker
1310*61046927SAndroid Build Coastguard Worker if (CHIP == A6XX) {
1311*61046927SAndroid Build Coastguard Worker /* Size of per-primitive alloction in ldlw memory in vec4s. */
1312*61046927SAndroid Build Coastguard Worker uint32_t vec4_size = gs->gs.vertices_in *
1313*61046927SAndroid Build Coastguard Worker DIV_ROUND_UP(prev_stage_output_size, 4);
1314*61046927SAndroid Build Coastguard Worker
1315*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, REG_A6XX_PC_PRIMITIVE_CNTL_6, 1);
1316*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, A6XX_PC_PRIMITIVE_CNTL_6_STRIDE_IN_VPC(vec4_size));
1317*61046927SAndroid Build Coastguard Worker }
1318*61046927SAndroid Build Coastguard Worker
1319*61046927SAndroid Build Coastguard Worker uint32_t prim_size = prev_stage_output_size;
1320*61046927SAndroid Build Coastguard Worker if (prim_size > 64)
1321*61046927SAndroid Build Coastguard Worker prim_size = 64;
1322*61046927SAndroid Build Coastguard Worker else if (prim_size == 64)
1323*61046927SAndroid Build Coastguard Worker prim_size = 63;
1324*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, REG_A6XX_SP_GS_PRIM_SIZE, 1);
1325*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, prim_size);
1326*61046927SAndroid Build Coastguard Worker }
1327*61046927SAndroid Build Coastguard Worker
1328*61046927SAndroid Build Coastguard Worker if (gs || hs) {
1329*61046927SAndroid Build Coastguard Worker tu6_emit_geom_tess_consts(cs, vs, hs, ds, gs);
1330*61046927SAndroid Build Coastguard Worker }
1331*61046927SAndroid Build Coastguard Worker }
1332*61046927SAndroid Build Coastguard Worker
1333*61046927SAndroid Build Coastguard Worker static bool
contains_all_shader_state(VkGraphicsPipelineLibraryFlagsEXT state)1334*61046927SAndroid Build Coastguard Worker contains_all_shader_state(VkGraphicsPipelineLibraryFlagsEXT state)
1335*61046927SAndroid Build Coastguard Worker {
1336*61046927SAndroid Build Coastguard Worker return (state &
1337*61046927SAndroid Build Coastguard Worker (VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT |
1338*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT)) ==
1339*61046927SAndroid Build Coastguard Worker (VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT |
1340*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT);
1341*61046927SAndroid Build Coastguard Worker }
1342*61046927SAndroid Build Coastguard Worker
1343*61046927SAndroid Build Coastguard Worker static bool
pipeline_contains_all_shader_state(struct tu_pipeline * pipeline)1344*61046927SAndroid Build Coastguard Worker pipeline_contains_all_shader_state(struct tu_pipeline *pipeline)
1345*61046927SAndroid Build Coastguard Worker {
1346*61046927SAndroid Build Coastguard Worker return pipeline->type == TU_PIPELINE_GRAPHICS ||
1347*61046927SAndroid Build Coastguard Worker pipeline->type == TU_PIPELINE_COMPUTE ||
1348*61046927SAndroid Build Coastguard Worker contains_all_shader_state(tu_pipeline_to_graphics_lib(pipeline)->state);
1349*61046927SAndroid Build Coastguard Worker }
1350*61046927SAndroid Build Coastguard Worker
1351*61046927SAndroid Build Coastguard Worker /* Return true if this pipeline contains all of the GPL stages listed but none
1352*61046927SAndroid Build Coastguard Worker * of the libraries it uses do, so this is "the first time" that all of them
1353*61046927SAndroid Build Coastguard Worker * are defined together. This is useful for state that needs to be combined
1354*61046927SAndroid Build Coastguard Worker * from multiple GPL stages.
1355*61046927SAndroid Build Coastguard Worker */
1356*61046927SAndroid Build Coastguard Worker
1357*61046927SAndroid Build Coastguard Worker static bool
set_combined_state(struct tu_pipeline_builder * builder,struct tu_pipeline * pipeline,VkGraphicsPipelineLibraryFlagsEXT state)1358*61046927SAndroid Build Coastguard Worker set_combined_state(struct tu_pipeline_builder *builder,
1359*61046927SAndroid Build Coastguard Worker struct tu_pipeline *pipeline,
1360*61046927SAndroid Build Coastguard Worker VkGraphicsPipelineLibraryFlagsEXT state)
1361*61046927SAndroid Build Coastguard Worker {
1362*61046927SAndroid Build Coastguard Worker if (pipeline->type == TU_PIPELINE_GRAPHICS_LIB &&
1363*61046927SAndroid Build Coastguard Worker (tu_pipeline_to_graphics_lib(pipeline)->state & state) != state)
1364*61046927SAndroid Build Coastguard Worker return false;
1365*61046927SAndroid Build Coastguard Worker
1366*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < builder->num_libraries; i++) {
1367*61046927SAndroid Build Coastguard Worker if ((builder->libraries[i]->state & state) == state)
1368*61046927SAndroid Build Coastguard Worker return false;
1369*61046927SAndroid Build Coastguard Worker }
1370*61046927SAndroid Build Coastguard Worker
1371*61046927SAndroid Build Coastguard Worker return true;
1372*61046927SAndroid Build Coastguard Worker }
1373*61046927SAndroid Build Coastguard Worker
1374*61046927SAndroid Build Coastguard Worker #define TU6_EMIT_VERTEX_INPUT_MAX_DWORDS (MAX_VERTEX_ATTRIBS * 2 + 1)
1375*61046927SAndroid Build Coastguard Worker
1376*61046927SAndroid Build Coastguard Worker static VkResult
tu_pipeline_allocate_cs(struct tu_device * dev,struct tu_pipeline * pipeline,struct tu_pipeline_layout * layout,struct tu_pipeline_builder * builder,const struct ir3_shader_variant * compute)1377*61046927SAndroid Build Coastguard Worker tu_pipeline_allocate_cs(struct tu_device *dev,
1378*61046927SAndroid Build Coastguard Worker struct tu_pipeline *pipeline,
1379*61046927SAndroid Build Coastguard Worker struct tu_pipeline_layout *layout,
1380*61046927SAndroid Build Coastguard Worker struct tu_pipeline_builder *builder,
1381*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *compute)
1382*61046927SAndroid Build Coastguard Worker {
1383*61046927SAndroid Build Coastguard Worker uint32_t size = 1024;
1384*61046927SAndroid Build Coastguard Worker
1385*61046927SAndroid Build Coastguard Worker /* graphics case: */
1386*61046927SAndroid Build Coastguard Worker if (builder) {
1387*61046927SAndroid Build Coastguard Worker if (builder->state &
1388*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT) {
1389*61046927SAndroid Build Coastguard Worker size += TU6_EMIT_VERTEX_INPUT_MAX_DWORDS;
1390*61046927SAndroid Build Coastguard Worker }
1391*61046927SAndroid Build Coastguard Worker
1392*61046927SAndroid Build Coastguard Worker if (set_combined_state(builder, pipeline,
1393*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT |
1394*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT)) {
1395*61046927SAndroid Build Coastguard Worker size += tu6_load_state_size(pipeline, layout);
1396*61046927SAndroid Build Coastguard Worker }
1397*61046927SAndroid Build Coastguard Worker } else {
1398*61046927SAndroid Build Coastguard Worker size += tu6_load_state_size(pipeline, layout);
1399*61046927SAndroid Build Coastguard Worker }
1400*61046927SAndroid Build Coastguard Worker
1401*61046927SAndroid Build Coastguard Worker /* Allocate the space for the pipeline out of the device's RO suballocator.
1402*61046927SAndroid Build Coastguard Worker *
1403*61046927SAndroid Build Coastguard Worker * Sub-allocating BOs saves memory and also kernel overhead in refcounting of
1404*61046927SAndroid Build Coastguard Worker * BOs at exec time.
1405*61046927SAndroid Build Coastguard Worker *
1406*61046927SAndroid Build Coastguard Worker * The pipeline cache would seem like a natural place to stick the
1407*61046927SAndroid Build Coastguard Worker * suballocator, except that it is not guaranteed to outlive the pipelines
1408*61046927SAndroid Build Coastguard Worker * created from it, so you can't store any long-lived state there, and you
1409*61046927SAndroid Build Coastguard Worker * can't use its EXTERNALLY_SYNCHRONIZED flag to avoid atomics because
1410*61046927SAndroid Build Coastguard Worker * pipeline destroy isn't synchronized by the cache.
1411*61046927SAndroid Build Coastguard Worker */
1412*61046927SAndroid Build Coastguard Worker mtx_lock(&dev->pipeline_mutex);
1413*61046927SAndroid Build Coastguard Worker VkResult result = tu_suballoc_bo_alloc(&pipeline->bo, &dev->pipeline_suballoc,
1414*61046927SAndroid Build Coastguard Worker size * 4, 128);
1415*61046927SAndroid Build Coastguard Worker mtx_unlock(&dev->pipeline_mutex);
1416*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
1417*61046927SAndroid Build Coastguard Worker return result;
1418*61046927SAndroid Build Coastguard Worker
1419*61046927SAndroid Build Coastguard Worker TU_RMV(cmd_buffer_suballoc_bo_create, dev, &pipeline->bo);
1420*61046927SAndroid Build Coastguard Worker tu_cs_init_suballoc(&pipeline->cs, dev, &pipeline->bo);
1421*61046927SAndroid Build Coastguard Worker
1422*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
1423*61046927SAndroid Build Coastguard Worker }
1424*61046927SAndroid Build Coastguard Worker
1425*61046927SAndroid Build Coastguard Worker static void
tu_append_executable(struct tu_pipeline * pipeline,const struct ir3_shader_variant * variant,char * nir_from_spirv)1426*61046927SAndroid Build Coastguard Worker tu_append_executable(struct tu_pipeline *pipeline,
1427*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *variant,
1428*61046927SAndroid Build Coastguard Worker char *nir_from_spirv)
1429*61046927SAndroid Build Coastguard Worker {
1430*61046927SAndroid Build Coastguard Worker struct tu_pipeline_executable exe = {
1431*61046927SAndroid Build Coastguard Worker .stage = variant->type,
1432*61046927SAndroid Build Coastguard Worker .stats = variant->info,
1433*61046927SAndroid Build Coastguard Worker .is_binning = variant->binning_pass,
1434*61046927SAndroid Build Coastguard Worker .nir_from_spirv = nir_from_spirv,
1435*61046927SAndroid Build Coastguard Worker .nir_final = ralloc_strdup(pipeline->executables_mem_ctx, variant->disasm_info.nir),
1436*61046927SAndroid Build Coastguard Worker .disasm = ralloc_strdup(pipeline->executables_mem_ctx, variant->disasm_info.disasm),
1437*61046927SAndroid Build Coastguard Worker };
1438*61046927SAndroid Build Coastguard Worker
1439*61046927SAndroid Build Coastguard Worker util_dynarray_append(&pipeline->executables, struct tu_pipeline_executable, exe);
1440*61046927SAndroid Build Coastguard Worker }
1441*61046927SAndroid Build Coastguard Worker
1442*61046927SAndroid Build Coastguard Worker static void
tu_hash_stage(struct mesa_sha1 * ctx,VkPipelineCreateFlags2KHR pipeline_flags,const VkPipelineShaderStageCreateInfo * stage,const nir_shader * nir,const struct tu_shader_key * key)1443*61046927SAndroid Build Coastguard Worker tu_hash_stage(struct mesa_sha1 *ctx,
1444*61046927SAndroid Build Coastguard Worker VkPipelineCreateFlags2KHR pipeline_flags,
1445*61046927SAndroid Build Coastguard Worker const VkPipelineShaderStageCreateInfo *stage,
1446*61046927SAndroid Build Coastguard Worker const nir_shader *nir,
1447*61046927SAndroid Build Coastguard Worker const struct tu_shader_key *key)
1448*61046927SAndroid Build Coastguard Worker {
1449*61046927SAndroid Build Coastguard Worker
1450*61046927SAndroid Build Coastguard Worker if (nir) {
1451*61046927SAndroid Build Coastguard Worker struct blob blob;
1452*61046927SAndroid Build Coastguard Worker blob_init(&blob);
1453*61046927SAndroid Build Coastguard Worker nir_serialize(&blob, nir, true);
1454*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(ctx, blob.data, blob.size);
1455*61046927SAndroid Build Coastguard Worker blob_finish(&blob);
1456*61046927SAndroid Build Coastguard Worker } else {
1457*61046927SAndroid Build Coastguard Worker unsigned char stage_hash[SHA1_DIGEST_LENGTH];
1458*61046927SAndroid Build Coastguard Worker vk_pipeline_hash_shader_stage(pipeline_flags, stage, NULL, stage_hash);
1459*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(ctx, stage_hash, sizeof(stage_hash));
1460*61046927SAndroid Build Coastguard Worker }
1461*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(ctx, key, sizeof(*key));
1462*61046927SAndroid Build Coastguard Worker }
1463*61046927SAndroid Build Coastguard Worker
1464*61046927SAndroid Build Coastguard Worker /* Hash flags which can affect ir3 shader compilation which aren't known until
1465*61046927SAndroid Build Coastguard Worker * logical device creation.
1466*61046927SAndroid Build Coastguard Worker */
1467*61046927SAndroid Build Coastguard Worker static void
tu_hash_compiler(struct mesa_sha1 * ctx,const struct ir3_compiler * compiler)1468*61046927SAndroid Build Coastguard Worker tu_hash_compiler(struct mesa_sha1 *ctx, const struct ir3_compiler *compiler)
1469*61046927SAndroid Build Coastguard Worker {
1470*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(ctx, &compiler->options.robust_buffer_access2,
1471*61046927SAndroid Build Coastguard Worker sizeof(compiler->options.robust_buffer_access2));
1472*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(ctx, &ir3_shader_debug, sizeof(ir3_shader_debug));
1473*61046927SAndroid Build Coastguard Worker }
1474*61046927SAndroid Build Coastguard Worker
1475*61046927SAndroid Build Coastguard Worker static void
tu_hash_shaders(unsigned char * hash,VkPipelineCreateFlags2KHR pipeline_flags,const VkPipelineShaderStageCreateInfo ** stages,nir_shader * const * nir,const struct tu_pipeline_layout * layout,const struct tu_shader_key * keys,VkGraphicsPipelineLibraryFlagsEXT state,const struct ir3_compiler * compiler)1476*61046927SAndroid Build Coastguard Worker tu_hash_shaders(unsigned char *hash,
1477*61046927SAndroid Build Coastguard Worker VkPipelineCreateFlags2KHR pipeline_flags,
1478*61046927SAndroid Build Coastguard Worker const VkPipelineShaderStageCreateInfo **stages,
1479*61046927SAndroid Build Coastguard Worker nir_shader *const *nir,
1480*61046927SAndroid Build Coastguard Worker const struct tu_pipeline_layout *layout,
1481*61046927SAndroid Build Coastguard Worker const struct tu_shader_key *keys,
1482*61046927SAndroid Build Coastguard Worker VkGraphicsPipelineLibraryFlagsEXT state,
1483*61046927SAndroid Build Coastguard Worker const struct ir3_compiler *compiler)
1484*61046927SAndroid Build Coastguard Worker {
1485*61046927SAndroid Build Coastguard Worker struct mesa_sha1 ctx;
1486*61046927SAndroid Build Coastguard Worker
1487*61046927SAndroid Build Coastguard Worker _mesa_sha1_init(&ctx);
1488*61046927SAndroid Build Coastguard Worker
1489*61046927SAndroid Build Coastguard Worker if (layout)
1490*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, layout->sha1, sizeof(layout->sha1));
1491*61046927SAndroid Build Coastguard Worker
1492*61046927SAndroid Build Coastguard Worker for (int i = 0; i < MESA_SHADER_STAGES; ++i) {
1493*61046927SAndroid Build Coastguard Worker if (stages[i] || nir[i]) {
1494*61046927SAndroid Build Coastguard Worker tu_hash_stage(&ctx, pipeline_flags, stages[i], nir[i], &keys[i]);
1495*61046927SAndroid Build Coastguard Worker }
1496*61046927SAndroid Build Coastguard Worker }
1497*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, &state, sizeof(state));
1498*61046927SAndroid Build Coastguard Worker tu_hash_compiler(&ctx, compiler);
1499*61046927SAndroid Build Coastguard Worker _mesa_sha1_final(&ctx, hash);
1500*61046927SAndroid Build Coastguard Worker }
1501*61046927SAndroid Build Coastguard Worker
1502*61046927SAndroid Build Coastguard Worker static void
tu_hash_compute(unsigned char * hash,VkPipelineCreateFlags2KHR pipeline_flags,const VkPipelineShaderStageCreateInfo * stage,const struct tu_pipeline_layout * layout,const struct tu_shader_key * key,const struct ir3_compiler * compiler)1503*61046927SAndroid Build Coastguard Worker tu_hash_compute(unsigned char *hash,
1504*61046927SAndroid Build Coastguard Worker VkPipelineCreateFlags2KHR pipeline_flags,
1505*61046927SAndroid Build Coastguard Worker const VkPipelineShaderStageCreateInfo *stage,
1506*61046927SAndroid Build Coastguard Worker const struct tu_pipeline_layout *layout,
1507*61046927SAndroid Build Coastguard Worker const struct tu_shader_key *key,
1508*61046927SAndroid Build Coastguard Worker const struct ir3_compiler *compiler)
1509*61046927SAndroid Build Coastguard Worker {
1510*61046927SAndroid Build Coastguard Worker struct mesa_sha1 ctx;
1511*61046927SAndroid Build Coastguard Worker
1512*61046927SAndroid Build Coastguard Worker _mesa_sha1_init(&ctx);
1513*61046927SAndroid Build Coastguard Worker
1514*61046927SAndroid Build Coastguard Worker if (layout)
1515*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, layout->sha1, sizeof(layout->sha1));
1516*61046927SAndroid Build Coastguard Worker
1517*61046927SAndroid Build Coastguard Worker tu_hash_stage(&ctx, pipeline_flags, stage, NULL, key);
1518*61046927SAndroid Build Coastguard Worker
1519*61046927SAndroid Build Coastguard Worker tu_hash_compiler(&ctx, compiler);
1520*61046927SAndroid Build Coastguard Worker _mesa_sha1_final(&ctx, hash);
1521*61046927SAndroid Build Coastguard Worker }
1522*61046927SAndroid Build Coastguard Worker
1523*61046927SAndroid Build Coastguard Worker static struct tu_shader *
tu_pipeline_cache_lookup(struct vk_pipeline_cache * cache,const void * key_data,size_t key_size,bool * application_cache_hit)1524*61046927SAndroid Build Coastguard Worker tu_pipeline_cache_lookup(struct vk_pipeline_cache *cache,
1525*61046927SAndroid Build Coastguard Worker const void *key_data, size_t key_size,
1526*61046927SAndroid Build Coastguard Worker bool *application_cache_hit)
1527*61046927SAndroid Build Coastguard Worker {
1528*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache_object *object =
1529*61046927SAndroid Build Coastguard Worker vk_pipeline_cache_lookup_object(cache, key_data, key_size,
1530*61046927SAndroid Build Coastguard Worker &tu_shader_ops, application_cache_hit);
1531*61046927SAndroid Build Coastguard Worker if (object)
1532*61046927SAndroid Build Coastguard Worker return container_of(object, struct tu_shader, base);
1533*61046927SAndroid Build Coastguard Worker else
1534*61046927SAndroid Build Coastguard Worker return NULL;
1535*61046927SAndroid Build Coastguard Worker }
1536*61046927SAndroid Build Coastguard Worker
1537*61046927SAndroid Build Coastguard Worker static struct tu_shader *
tu_pipeline_cache_insert(struct vk_pipeline_cache * cache,struct tu_shader * shader)1538*61046927SAndroid Build Coastguard Worker tu_pipeline_cache_insert(struct vk_pipeline_cache *cache,
1539*61046927SAndroid Build Coastguard Worker struct tu_shader *shader)
1540*61046927SAndroid Build Coastguard Worker {
1541*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache_object *object =
1542*61046927SAndroid Build Coastguard Worker vk_pipeline_cache_add_object(cache, &shader->base);
1543*61046927SAndroid Build Coastguard Worker return container_of(object, struct tu_shader, base);
1544*61046927SAndroid Build Coastguard Worker }
1545*61046927SAndroid Build Coastguard Worker
1546*61046927SAndroid Build Coastguard Worker static bool
1547*61046927SAndroid Build Coastguard Worker tu_nir_shaders_serialize(struct vk_pipeline_cache_object *object,
1548*61046927SAndroid Build Coastguard Worker struct blob *blob);
1549*61046927SAndroid Build Coastguard Worker
1550*61046927SAndroid Build Coastguard Worker static struct vk_pipeline_cache_object *
1551*61046927SAndroid Build Coastguard Worker tu_nir_shaders_deserialize(struct vk_pipeline_cache *cache,
1552*61046927SAndroid Build Coastguard Worker const void *key_data,
1553*61046927SAndroid Build Coastguard Worker size_t key_size,
1554*61046927SAndroid Build Coastguard Worker struct blob_reader *blob);
1555*61046927SAndroid Build Coastguard Worker
1556*61046927SAndroid Build Coastguard Worker static void
tu_nir_shaders_destroy(struct vk_device * device,struct vk_pipeline_cache_object * object)1557*61046927SAndroid Build Coastguard Worker tu_nir_shaders_destroy(struct vk_device *device,
1558*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache_object *object)
1559*61046927SAndroid Build Coastguard Worker {
1560*61046927SAndroid Build Coastguard Worker struct tu_nir_shaders *shaders =
1561*61046927SAndroid Build Coastguard Worker container_of(object, struct tu_nir_shaders, base);
1562*61046927SAndroid Build Coastguard Worker
1563*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < ARRAY_SIZE(shaders->nir); i++)
1564*61046927SAndroid Build Coastguard Worker ralloc_free(shaders->nir[i]);
1565*61046927SAndroid Build Coastguard Worker
1566*61046927SAndroid Build Coastguard Worker vk_pipeline_cache_object_finish(&shaders->base);
1567*61046927SAndroid Build Coastguard Worker vk_free(&device->alloc, shaders);
1568*61046927SAndroid Build Coastguard Worker }
1569*61046927SAndroid Build Coastguard Worker
1570*61046927SAndroid Build Coastguard Worker const struct vk_pipeline_cache_object_ops tu_nir_shaders_ops = {
1571*61046927SAndroid Build Coastguard Worker .serialize = tu_nir_shaders_serialize,
1572*61046927SAndroid Build Coastguard Worker .deserialize = tu_nir_shaders_deserialize,
1573*61046927SAndroid Build Coastguard Worker .destroy = tu_nir_shaders_destroy,
1574*61046927SAndroid Build Coastguard Worker };
1575*61046927SAndroid Build Coastguard Worker
1576*61046927SAndroid Build Coastguard Worker static struct tu_nir_shaders *
tu_nir_shaders_init(struct tu_device * dev,const void * key_data,size_t key_size)1577*61046927SAndroid Build Coastguard Worker tu_nir_shaders_init(struct tu_device *dev, const void *key_data, size_t key_size)
1578*61046927SAndroid Build Coastguard Worker {
1579*61046927SAndroid Build Coastguard Worker VK_MULTIALLOC(ma);
1580*61046927SAndroid Build Coastguard Worker VK_MULTIALLOC_DECL(&ma, struct tu_nir_shaders, shaders, 1);
1581*61046927SAndroid Build Coastguard Worker VK_MULTIALLOC_DECL_SIZE(&ma, char, obj_key_data, key_size);
1582*61046927SAndroid Build Coastguard Worker
1583*61046927SAndroid Build Coastguard Worker if (!vk_multialloc_zalloc(&ma, &dev->vk.alloc,
1584*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_DEVICE))
1585*61046927SAndroid Build Coastguard Worker return NULL;
1586*61046927SAndroid Build Coastguard Worker
1587*61046927SAndroid Build Coastguard Worker memcpy(obj_key_data, key_data, key_size);
1588*61046927SAndroid Build Coastguard Worker vk_pipeline_cache_object_init(&dev->vk, &shaders->base,
1589*61046927SAndroid Build Coastguard Worker &tu_nir_shaders_ops, obj_key_data, key_size);
1590*61046927SAndroid Build Coastguard Worker
1591*61046927SAndroid Build Coastguard Worker return shaders;
1592*61046927SAndroid Build Coastguard Worker }
1593*61046927SAndroid Build Coastguard Worker
1594*61046927SAndroid Build Coastguard Worker static bool
tu_nir_shaders_serialize(struct vk_pipeline_cache_object * object,struct blob * blob)1595*61046927SAndroid Build Coastguard Worker tu_nir_shaders_serialize(struct vk_pipeline_cache_object *object,
1596*61046927SAndroid Build Coastguard Worker struct blob *blob)
1597*61046927SAndroid Build Coastguard Worker {
1598*61046927SAndroid Build Coastguard Worker struct tu_nir_shaders *shaders =
1599*61046927SAndroid Build Coastguard Worker container_of(object, struct tu_nir_shaders, base);
1600*61046927SAndroid Build Coastguard Worker
1601*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < ARRAY_SIZE(shaders->nir); i++) {
1602*61046927SAndroid Build Coastguard Worker if (shaders->nir[i]) {
1603*61046927SAndroid Build Coastguard Worker blob_write_uint8(blob, 1);
1604*61046927SAndroid Build Coastguard Worker nir_serialize(blob, shaders->nir[i], true);
1605*61046927SAndroid Build Coastguard Worker } else {
1606*61046927SAndroid Build Coastguard Worker blob_write_uint8(blob, 0);
1607*61046927SAndroid Build Coastguard Worker }
1608*61046927SAndroid Build Coastguard Worker }
1609*61046927SAndroid Build Coastguard Worker
1610*61046927SAndroid Build Coastguard Worker return true;
1611*61046927SAndroid Build Coastguard Worker }
1612*61046927SAndroid Build Coastguard Worker
1613*61046927SAndroid Build Coastguard Worker static struct vk_pipeline_cache_object *
tu_nir_shaders_deserialize(struct vk_pipeline_cache * cache,const void * key_data,size_t key_size,struct blob_reader * blob)1614*61046927SAndroid Build Coastguard Worker tu_nir_shaders_deserialize(struct vk_pipeline_cache *cache,
1615*61046927SAndroid Build Coastguard Worker const void *key_data,
1616*61046927SAndroid Build Coastguard Worker size_t key_size,
1617*61046927SAndroid Build Coastguard Worker struct blob_reader *blob)
1618*61046927SAndroid Build Coastguard Worker {
1619*61046927SAndroid Build Coastguard Worker struct tu_device *dev =
1620*61046927SAndroid Build Coastguard Worker container_of(cache->base.device, struct tu_device, vk);
1621*61046927SAndroid Build Coastguard Worker struct tu_nir_shaders *shaders =
1622*61046927SAndroid Build Coastguard Worker tu_nir_shaders_init(dev, key_data, key_size);
1623*61046927SAndroid Build Coastguard Worker
1624*61046927SAndroid Build Coastguard Worker if (!shaders)
1625*61046927SAndroid Build Coastguard Worker return NULL;
1626*61046927SAndroid Build Coastguard Worker
1627*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < ARRAY_SIZE(shaders->nir); i++) {
1628*61046927SAndroid Build Coastguard Worker if (blob_read_uint8(blob)) {
1629*61046927SAndroid Build Coastguard Worker shaders->nir[i] =
1630*61046927SAndroid Build Coastguard Worker nir_deserialize(NULL, ir3_get_compiler_options(dev->compiler), blob);
1631*61046927SAndroid Build Coastguard Worker }
1632*61046927SAndroid Build Coastguard Worker }
1633*61046927SAndroid Build Coastguard Worker
1634*61046927SAndroid Build Coastguard Worker return &shaders->base;
1635*61046927SAndroid Build Coastguard Worker }
1636*61046927SAndroid Build Coastguard Worker
1637*61046927SAndroid Build Coastguard Worker static struct tu_nir_shaders *
tu_nir_cache_lookup(struct vk_pipeline_cache * cache,const void * key_data,size_t key_size,bool * application_cache_hit)1638*61046927SAndroid Build Coastguard Worker tu_nir_cache_lookup(struct vk_pipeline_cache *cache,
1639*61046927SAndroid Build Coastguard Worker const void *key_data, size_t key_size,
1640*61046927SAndroid Build Coastguard Worker bool *application_cache_hit)
1641*61046927SAndroid Build Coastguard Worker {
1642*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache_object *object =
1643*61046927SAndroid Build Coastguard Worker vk_pipeline_cache_lookup_object(cache, key_data, key_size,
1644*61046927SAndroid Build Coastguard Worker &tu_nir_shaders_ops, application_cache_hit);
1645*61046927SAndroid Build Coastguard Worker if (object)
1646*61046927SAndroid Build Coastguard Worker return container_of(object, struct tu_nir_shaders, base);
1647*61046927SAndroid Build Coastguard Worker else
1648*61046927SAndroid Build Coastguard Worker return NULL;
1649*61046927SAndroid Build Coastguard Worker }
1650*61046927SAndroid Build Coastguard Worker
1651*61046927SAndroid Build Coastguard Worker static struct tu_nir_shaders *
tu_nir_cache_insert(struct vk_pipeline_cache * cache,struct tu_nir_shaders * shaders)1652*61046927SAndroid Build Coastguard Worker tu_nir_cache_insert(struct vk_pipeline_cache *cache,
1653*61046927SAndroid Build Coastguard Worker struct tu_nir_shaders *shaders)
1654*61046927SAndroid Build Coastguard Worker {
1655*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache_object *object =
1656*61046927SAndroid Build Coastguard Worker vk_pipeline_cache_add_object(cache, &shaders->base);
1657*61046927SAndroid Build Coastguard Worker return container_of(object, struct tu_nir_shaders, base);
1658*61046927SAndroid Build Coastguard Worker }
1659*61046927SAndroid Build Coastguard Worker
1660*61046927SAndroid Build Coastguard Worker static VkResult
tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder * builder,struct tu_pipeline * pipeline)1661*61046927SAndroid Build Coastguard Worker tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder,
1662*61046927SAndroid Build Coastguard Worker struct tu_pipeline *pipeline)
1663*61046927SAndroid Build Coastguard Worker {
1664*61046927SAndroid Build Coastguard Worker VkResult result = VK_SUCCESS;
1665*61046927SAndroid Build Coastguard Worker const struct ir3_compiler *compiler = builder->device->compiler;
1666*61046927SAndroid Build Coastguard Worker const VkPipelineShaderStageCreateInfo *stage_infos[MESA_SHADER_STAGES] = {
1667*61046927SAndroid Build Coastguard Worker NULL
1668*61046927SAndroid Build Coastguard Worker };
1669*61046927SAndroid Build Coastguard Worker VkPipelineCreationFeedback pipeline_feedback = {
1670*61046927SAndroid Build Coastguard Worker .flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT,
1671*61046927SAndroid Build Coastguard Worker };
1672*61046927SAndroid Build Coastguard Worker VkPipelineCreationFeedback stage_feedbacks[MESA_SHADER_STAGES] = { 0 };
1673*61046927SAndroid Build Coastguard Worker
1674*61046927SAndroid Build Coastguard Worker const bool executable_info =
1675*61046927SAndroid Build Coastguard Worker builder->create_flags &
1676*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATE_2_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR;
1677*61046927SAndroid Build Coastguard Worker
1678*61046927SAndroid Build Coastguard Worker bool retain_nir =
1679*61046927SAndroid Build Coastguard Worker builder->create_flags &
1680*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATE_2_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
1681*61046927SAndroid Build Coastguard Worker
1682*61046927SAndroid Build Coastguard Worker int64_t pipeline_start = os_time_get_nano();
1683*61046927SAndroid Build Coastguard Worker
1684*61046927SAndroid Build Coastguard Worker const VkPipelineCreationFeedbackCreateInfo *creation_feedback =
1685*61046927SAndroid Build Coastguard Worker vk_find_struct_const(builder->create_info->pNext, PIPELINE_CREATION_FEEDBACK_CREATE_INFO);
1686*61046927SAndroid Build Coastguard Worker
1687*61046927SAndroid Build Coastguard Worker bool must_compile = false;
1688*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < builder->create_info->stageCount; i++) {
1689*61046927SAndroid Build Coastguard Worker if (!(builder->active_stages & builder->create_info->pStages[i].stage))
1690*61046927SAndroid Build Coastguard Worker continue;
1691*61046927SAndroid Build Coastguard Worker
1692*61046927SAndroid Build Coastguard Worker gl_shader_stage stage =
1693*61046927SAndroid Build Coastguard Worker vk_to_mesa_shader_stage(builder->create_info->pStages[i].stage);
1694*61046927SAndroid Build Coastguard Worker stage_infos[stage] = &builder->create_info->pStages[i];
1695*61046927SAndroid Build Coastguard Worker must_compile = true;
1696*61046927SAndroid Build Coastguard Worker }
1697*61046927SAndroid Build Coastguard Worker
1698*61046927SAndroid Build Coastguard Worker /* Forward declare everything due to the goto usage */
1699*61046927SAndroid Build Coastguard Worker nir_shader *nir[ARRAY_SIZE(stage_infos)] = { NULL };
1700*61046927SAndroid Build Coastguard Worker struct tu_shader *shaders[ARRAY_SIZE(stage_infos)] = { NULL };
1701*61046927SAndroid Build Coastguard Worker nir_shader *post_link_nir[ARRAY_SIZE(nir)] = { NULL };
1702*61046927SAndroid Build Coastguard Worker char *nir_initial_disasm[ARRAY_SIZE(stage_infos)] = { NULL };
1703*61046927SAndroid Build Coastguard Worker bool cache_hit = false;
1704*61046927SAndroid Build Coastguard Worker
1705*61046927SAndroid Build Coastguard Worker struct tu_shader_key keys[ARRAY_SIZE(stage_infos)] = { };
1706*61046927SAndroid Build Coastguard Worker for (gl_shader_stage stage = MESA_SHADER_VERTEX;
1707*61046927SAndroid Build Coastguard Worker stage < ARRAY_SIZE(keys); stage = (gl_shader_stage) (stage+1)) {
1708*61046927SAndroid Build Coastguard Worker const VkPipelineShaderStageRequiredSubgroupSizeCreateInfo *subgroup_info = NULL;
1709*61046927SAndroid Build Coastguard Worker if (stage_infos[stage])
1710*61046927SAndroid Build Coastguard Worker subgroup_info = vk_find_struct_const(stage_infos[stage],
1711*61046927SAndroid Build Coastguard Worker PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO);
1712*61046927SAndroid Build Coastguard Worker bool allow_varying_subgroup_size =
1713*61046927SAndroid Build Coastguard Worker !stage_infos[stage] ||
1714*61046927SAndroid Build Coastguard Worker (stage_infos[stage]->flags &
1715*61046927SAndroid Build Coastguard Worker VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT);
1716*61046927SAndroid Build Coastguard Worker bool require_full_subgroups =
1717*61046927SAndroid Build Coastguard Worker stage_infos[stage] &&
1718*61046927SAndroid Build Coastguard Worker (stage_infos[stage]->flags &
1719*61046927SAndroid Build Coastguard Worker VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT);
1720*61046927SAndroid Build Coastguard Worker tu_shader_key_subgroup_size(&keys[stage], allow_varying_subgroup_size,
1721*61046927SAndroid Build Coastguard Worker require_full_subgroups, subgroup_info,
1722*61046927SAndroid Build Coastguard Worker builder->device);
1723*61046927SAndroid Build Coastguard Worker }
1724*61046927SAndroid Build Coastguard Worker
1725*61046927SAndroid Build Coastguard Worker if (builder->create_flags &
1726*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATE_2_LINK_TIME_OPTIMIZATION_BIT_EXT) {
1727*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < builder->num_libraries; i++) {
1728*61046927SAndroid Build Coastguard Worker struct tu_graphics_lib_pipeline *library = builder->libraries[i];
1729*61046927SAndroid Build Coastguard Worker
1730*61046927SAndroid Build Coastguard Worker for (unsigned j = 0; j < ARRAY_SIZE(library->shaders); j++) {
1731*61046927SAndroid Build Coastguard Worker if (library->shaders[j].nir) {
1732*61046927SAndroid Build Coastguard Worker assert(!nir[j]);
1733*61046927SAndroid Build Coastguard Worker nir[j] = nir_shader_clone(builder->mem_ctx,
1734*61046927SAndroid Build Coastguard Worker library->shaders[j].nir);
1735*61046927SAndroid Build Coastguard Worker keys[j] = library->shaders[j].key;
1736*61046927SAndroid Build Coastguard Worker must_compile = true;
1737*61046927SAndroid Build Coastguard Worker }
1738*61046927SAndroid Build Coastguard Worker }
1739*61046927SAndroid Build Coastguard Worker }
1740*61046927SAndroid Build Coastguard Worker }
1741*61046927SAndroid Build Coastguard Worker
1742*61046927SAndroid Build Coastguard Worker struct tu_nir_shaders *nir_shaders = NULL;
1743*61046927SAndroid Build Coastguard Worker if (!must_compile)
1744*61046927SAndroid Build Coastguard Worker goto done;
1745*61046927SAndroid Build Coastguard Worker
1746*61046927SAndroid Build Coastguard Worker if (builder->state &
1747*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT) {
1748*61046927SAndroid Build Coastguard Worker keys[MESA_SHADER_VERTEX].multiview_mask =
1749*61046927SAndroid Build Coastguard Worker builder->graphics_state.rp->view_mask;
1750*61046927SAndroid Build Coastguard Worker }
1751*61046927SAndroid Build Coastguard Worker
1752*61046927SAndroid Build Coastguard Worker if (builder->state & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT) {
1753*61046927SAndroid Build Coastguard Worker keys[MESA_SHADER_FRAGMENT].multiview_mask =
1754*61046927SAndroid Build Coastguard Worker builder->graphics_state.rp->view_mask;
1755*61046927SAndroid Build Coastguard Worker keys[MESA_SHADER_FRAGMENT].fragment_density_map =
1756*61046927SAndroid Build Coastguard Worker builder->fragment_density_map;
1757*61046927SAndroid Build Coastguard Worker keys[MESA_SHADER_FRAGMENT].unscaled_input_fragcoord =
1758*61046927SAndroid Build Coastguard Worker builder->unscaled_input_fragcoord;
1759*61046927SAndroid Build Coastguard Worker
1760*61046927SAndroid Build Coastguard Worker const VkPipelineMultisampleStateCreateInfo *msaa_info =
1761*61046927SAndroid Build Coastguard Worker builder->create_info->pMultisampleState;
1762*61046927SAndroid Build Coastguard Worker
1763*61046927SAndroid Build Coastguard Worker /* The 1.3.215 spec says:
1764*61046927SAndroid Build Coastguard Worker *
1765*61046927SAndroid Build Coastguard Worker * Sample shading can be used to specify a minimum number of unique
1766*61046927SAndroid Build Coastguard Worker * samples to process for each fragment. If sample shading is enabled,
1767*61046927SAndroid Build Coastguard Worker * an implementation must provide a minimum of
1768*61046927SAndroid Build Coastguard Worker *
1769*61046927SAndroid Build Coastguard Worker * max(ceil(minSampleShadingFactor * totalSamples), 1)
1770*61046927SAndroid Build Coastguard Worker *
1771*61046927SAndroid Build Coastguard Worker * unique associated data for each fragment, where
1772*61046927SAndroid Build Coastguard Worker * minSampleShadingFactor is the minimum fraction of sample shading.
1773*61046927SAndroid Build Coastguard Worker *
1774*61046927SAndroid Build Coastguard Worker * The definition is pretty much the same as OpenGL's GL_SAMPLE_SHADING.
1775*61046927SAndroid Build Coastguard Worker * They both require unique associated data.
1776*61046927SAndroid Build Coastguard Worker *
1777*61046927SAndroid Build Coastguard Worker * There are discussions to change the definition, such that
1778*61046927SAndroid Build Coastguard Worker * sampleShadingEnable does not imply unique associated data. Before the
1779*61046927SAndroid Build Coastguard Worker * discussions are settled and before apps (i.e., ANGLE) are fixed to
1780*61046927SAndroid Build Coastguard Worker * follow the new and incompatible definition, we should stick to the
1781*61046927SAndroid Build Coastguard Worker * current definition.
1782*61046927SAndroid Build Coastguard Worker *
1783*61046927SAndroid Build Coastguard Worker * Note that ir3_shader_key::sample_shading is not actually used by ir3,
1784*61046927SAndroid Build Coastguard Worker * just checked in tu6_emit_fs_inputs. We will also copy the value to
1785*61046927SAndroid Build Coastguard Worker * tu_shader_key::force_sample_interp in a bit.
1786*61046927SAndroid Build Coastguard Worker */
1787*61046927SAndroid Build Coastguard Worker keys[MESA_SHADER_FRAGMENT].force_sample_interp =
1788*61046927SAndroid Build Coastguard Worker !builder->rasterizer_discard && msaa_info && msaa_info->sampleShadingEnable;
1789*61046927SAndroid Build Coastguard Worker }
1790*61046927SAndroid Build Coastguard Worker
1791*61046927SAndroid Build Coastguard Worker unsigned char pipeline_sha1[20];
1792*61046927SAndroid Build Coastguard Worker tu_hash_shaders(pipeline_sha1, builder->create_flags, stage_infos, nir,
1793*61046927SAndroid Build Coastguard Worker &builder->layout, keys, builder->state, compiler);
1794*61046927SAndroid Build Coastguard Worker
1795*61046927SAndroid Build Coastguard Worker unsigned char nir_sha1[21];
1796*61046927SAndroid Build Coastguard Worker memcpy(nir_sha1, pipeline_sha1, sizeof(pipeline_sha1));
1797*61046927SAndroid Build Coastguard Worker nir_sha1[20] = 'N';
1798*61046927SAndroid Build Coastguard Worker
1799*61046927SAndroid Build Coastguard Worker if (!executable_info) {
1800*61046927SAndroid Build Coastguard Worker cache_hit = true;
1801*61046927SAndroid Build Coastguard Worker bool application_cache_hit = false;
1802*61046927SAndroid Build Coastguard Worker
1803*61046927SAndroid Build Coastguard Worker unsigned char shader_sha1[21];
1804*61046927SAndroid Build Coastguard Worker memcpy(shader_sha1, pipeline_sha1, sizeof(pipeline_sha1));
1805*61046927SAndroid Build Coastguard Worker
1806*61046927SAndroid Build Coastguard Worker for (gl_shader_stage stage = MESA_SHADER_VERTEX; stage < ARRAY_SIZE(nir);
1807*61046927SAndroid Build Coastguard Worker stage = (gl_shader_stage) (stage + 1)) {
1808*61046927SAndroid Build Coastguard Worker if (stage_infos[stage] || nir[stage]) {
1809*61046927SAndroid Build Coastguard Worker bool shader_application_cache_hit;
1810*61046927SAndroid Build Coastguard Worker shader_sha1[20] = (unsigned char) stage;
1811*61046927SAndroid Build Coastguard Worker shaders[stage] =
1812*61046927SAndroid Build Coastguard Worker tu_pipeline_cache_lookup(builder->cache, &shader_sha1,
1813*61046927SAndroid Build Coastguard Worker sizeof(shader_sha1),
1814*61046927SAndroid Build Coastguard Worker &shader_application_cache_hit);
1815*61046927SAndroid Build Coastguard Worker if (!shaders[stage]) {
1816*61046927SAndroid Build Coastguard Worker cache_hit = false;
1817*61046927SAndroid Build Coastguard Worker break;
1818*61046927SAndroid Build Coastguard Worker }
1819*61046927SAndroid Build Coastguard Worker application_cache_hit &= shader_application_cache_hit;
1820*61046927SAndroid Build Coastguard Worker }
1821*61046927SAndroid Build Coastguard Worker }
1822*61046927SAndroid Build Coastguard Worker
1823*61046927SAndroid Build Coastguard Worker /* If the user asks us to keep the NIR around, we need to have it for a
1824*61046927SAndroid Build Coastguard Worker * successful cache hit. If we only have a "partial" cache hit, then we
1825*61046927SAndroid Build Coastguard Worker * still need to recompile in order to get the NIR.
1826*61046927SAndroid Build Coastguard Worker */
1827*61046927SAndroid Build Coastguard Worker if (cache_hit &&
1828*61046927SAndroid Build Coastguard Worker (builder->create_flags &
1829*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATE_2_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT)) {
1830*61046927SAndroid Build Coastguard Worker bool nir_application_cache_hit = false;
1831*61046927SAndroid Build Coastguard Worker nir_shaders =
1832*61046927SAndroid Build Coastguard Worker tu_nir_cache_lookup(builder->cache, &nir_sha1,
1833*61046927SAndroid Build Coastguard Worker sizeof(nir_sha1),
1834*61046927SAndroid Build Coastguard Worker &nir_application_cache_hit);
1835*61046927SAndroid Build Coastguard Worker
1836*61046927SAndroid Build Coastguard Worker application_cache_hit &= nir_application_cache_hit;
1837*61046927SAndroid Build Coastguard Worker cache_hit &= !!nir_shaders;
1838*61046927SAndroid Build Coastguard Worker }
1839*61046927SAndroid Build Coastguard Worker
1840*61046927SAndroid Build Coastguard Worker if (application_cache_hit && builder->cache != builder->device->mem_cache) {
1841*61046927SAndroid Build Coastguard Worker pipeline_feedback.flags |=
1842*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT;
1843*61046927SAndroid Build Coastguard Worker }
1844*61046927SAndroid Build Coastguard Worker }
1845*61046927SAndroid Build Coastguard Worker
1846*61046927SAndroid Build Coastguard Worker if (!cache_hit) {
1847*61046927SAndroid Build Coastguard Worker if (builder->create_flags &
1848*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_KHR) {
1849*61046927SAndroid Build Coastguard Worker return VK_PIPELINE_COMPILE_REQUIRED;
1850*61046927SAndroid Build Coastguard Worker }
1851*61046927SAndroid Build Coastguard Worker
1852*61046927SAndroid Build Coastguard Worker result = tu_compile_shaders(builder->device,
1853*61046927SAndroid Build Coastguard Worker builder->create_flags,
1854*61046927SAndroid Build Coastguard Worker stage_infos,
1855*61046927SAndroid Build Coastguard Worker nir,
1856*61046927SAndroid Build Coastguard Worker keys,
1857*61046927SAndroid Build Coastguard Worker &builder->layout,
1858*61046927SAndroid Build Coastguard Worker pipeline_sha1,
1859*61046927SAndroid Build Coastguard Worker shaders,
1860*61046927SAndroid Build Coastguard Worker executable_info ? nir_initial_disasm : NULL,
1861*61046927SAndroid Build Coastguard Worker pipeline->executables_mem_ctx,
1862*61046927SAndroid Build Coastguard Worker retain_nir ? post_link_nir : NULL,
1863*61046927SAndroid Build Coastguard Worker stage_feedbacks);
1864*61046927SAndroid Build Coastguard Worker
1865*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
1866*61046927SAndroid Build Coastguard Worker goto fail;
1867*61046927SAndroid Build Coastguard Worker
1868*61046927SAndroid Build Coastguard Worker if (retain_nir) {
1869*61046927SAndroid Build Coastguard Worker nir_shaders =
1870*61046927SAndroid Build Coastguard Worker tu_nir_shaders_init(builder->device, &nir_sha1, sizeof(nir_sha1));
1871*61046927SAndroid Build Coastguard Worker for (gl_shader_stage stage = MESA_SHADER_VERTEX;
1872*61046927SAndroid Build Coastguard Worker stage < ARRAY_SIZE(nir); stage = (gl_shader_stage) (stage + 1)) {
1873*61046927SAndroid Build Coastguard Worker if (!post_link_nir[stage])
1874*61046927SAndroid Build Coastguard Worker continue;
1875*61046927SAndroid Build Coastguard Worker
1876*61046927SAndroid Build Coastguard Worker nir_shaders->nir[stage] = post_link_nir[stage];
1877*61046927SAndroid Build Coastguard Worker }
1878*61046927SAndroid Build Coastguard Worker
1879*61046927SAndroid Build Coastguard Worker nir_shaders = tu_nir_cache_insert(builder->cache, nir_shaders);
1880*61046927SAndroid Build Coastguard Worker }
1881*61046927SAndroid Build Coastguard Worker
1882*61046927SAndroid Build Coastguard Worker for (gl_shader_stage stage = MESA_SHADER_VERTEX; stage < ARRAY_SIZE(nir);
1883*61046927SAndroid Build Coastguard Worker stage = (gl_shader_stage) (stage + 1)) {
1884*61046927SAndroid Build Coastguard Worker if (!nir[stage])
1885*61046927SAndroid Build Coastguard Worker continue;
1886*61046927SAndroid Build Coastguard Worker
1887*61046927SAndroid Build Coastguard Worker shaders[stage] = tu_pipeline_cache_insert(builder->cache, shaders[stage]);
1888*61046927SAndroid Build Coastguard Worker }
1889*61046927SAndroid Build Coastguard Worker }
1890*61046927SAndroid Build Coastguard Worker
1891*61046927SAndroid Build Coastguard Worker done:
1892*61046927SAndroid Build Coastguard Worker
1893*61046927SAndroid Build Coastguard Worker /* Create empty shaders which contain the draw states to initialize
1894*61046927SAndroid Build Coastguard Worker * registers for unused shader stages.
1895*61046927SAndroid Build Coastguard Worker */
1896*61046927SAndroid Build Coastguard Worker if (builder->state &
1897*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT) {
1898*61046927SAndroid Build Coastguard Worker if (!shaders[MESA_SHADER_TESS_CTRL]) {
1899*61046927SAndroid Build Coastguard Worker shaders[MESA_SHADER_TESS_CTRL] = builder->device->empty_tcs;
1900*61046927SAndroid Build Coastguard Worker vk_pipeline_cache_object_ref(&shaders[MESA_SHADER_TESS_CTRL]->base);
1901*61046927SAndroid Build Coastguard Worker }
1902*61046927SAndroid Build Coastguard Worker if (!shaders[MESA_SHADER_TESS_EVAL]) {
1903*61046927SAndroid Build Coastguard Worker shaders[MESA_SHADER_TESS_EVAL] = builder->device->empty_tes;
1904*61046927SAndroid Build Coastguard Worker vk_pipeline_cache_object_ref(&shaders[MESA_SHADER_TESS_EVAL]->base);
1905*61046927SAndroid Build Coastguard Worker }
1906*61046927SAndroid Build Coastguard Worker if (!shaders[MESA_SHADER_GEOMETRY]) {
1907*61046927SAndroid Build Coastguard Worker shaders[MESA_SHADER_GEOMETRY] = builder->device->empty_gs;
1908*61046927SAndroid Build Coastguard Worker vk_pipeline_cache_object_ref(&shaders[MESA_SHADER_GEOMETRY]->base);
1909*61046927SAndroid Build Coastguard Worker }
1910*61046927SAndroid Build Coastguard Worker }
1911*61046927SAndroid Build Coastguard Worker
1912*61046927SAndroid Build Coastguard Worker if (builder->state &
1913*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT) {
1914*61046927SAndroid Build Coastguard Worker if (!shaders[MESA_SHADER_FRAGMENT]) {
1915*61046927SAndroid Build Coastguard Worker shaders[MESA_SHADER_FRAGMENT] =
1916*61046927SAndroid Build Coastguard Worker builder->fragment_density_map ?
1917*61046927SAndroid Build Coastguard Worker builder->device->empty_fs_fdm : builder->device->empty_fs;
1918*61046927SAndroid Build Coastguard Worker vk_pipeline_cache_object_ref(&shaders[MESA_SHADER_FRAGMENT]->base);
1919*61046927SAndroid Build Coastguard Worker }
1920*61046927SAndroid Build Coastguard Worker }
1921*61046927SAndroid Build Coastguard Worker
1922*61046927SAndroid Build Coastguard Worker for (gl_shader_stage stage = MESA_SHADER_VERTEX;
1923*61046927SAndroid Build Coastguard Worker stage < ARRAY_SIZE(nir); stage = (gl_shader_stage) (stage + 1)) {
1924*61046927SAndroid Build Coastguard Worker if (shaders[stage] && shaders[stage]->variant) {
1925*61046927SAndroid Build Coastguard Worker tu_append_executable(pipeline, shaders[stage]->variant,
1926*61046927SAndroid Build Coastguard Worker nir_initial_disasm[stage]);
1927*61046927SAndroid Build Coastguard Worker }
1928*61046927SAndroid Build Coastguard Worker }
1929*61046927SAndroid Build Coastguard Worker
1930*61046927SAndroid Build Coastguard Worker /* We may have deduplicated a cache entry, in which case our original
1931*61046927SAndroid Build Coastguard Worker * post_link_nir may be gone.
1932*61046927SAndroid Build Coastguard Worker */
1933*61046927SAndroid Build Coastguard Worker if (nir_shaders) {
1934*61046927SAndroid Build Coastguard Worker for (gl_shader_stage stage = MESA_SHADER_VERTEX;
1935*61046927SAndroid Build Coastguard Worker stage < ARRAY_SIZE(nir); stage = (gl_shader_stage) (stage + 1)) {
1936*61046927SAndroid Build Coastguard Worker if (nir_shaders->nir[stage]) {
1937*61046927SAndroid Build Coastguard Worker post_link_nir[stage] = nir_shaders->nir[stage];
1938*61046927SAndroid Build Coastguard Worker }
1939*61046927SAndroid Build Coastguard Worker }
1940*61046927SAndroid Build Coastguard Worker }
1941*61046927SAndroid Build Coastguard Worker
1942*61046927SAndroid Build Coastguard Worker /* In the case where we're building a library without link-time
1943*61046927SAndroid Build Coastguard Worker * optimization but with sub-libraries that retain LTO info, we should
1944*61046927SAndroid Build Coastguard Worker * retain it ourselves in case another pipeline includes us with LTO.
1945*61046927SAndroid Build Coastguard Worker */
1946*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < builder->num_libraries; i++) {
1947*61046927SAndroid Build Coastguard Worker struct tu_graphics_lib_pipeline *library = builder->libraries[i];
1948*61046927SAndroid Build Coastguard Worker for (gl_shader_stage stage = MESA_SHADER_VERTEX;
1949*61046927SAndroid Build Coastguard Worker stage < ARRAY_SIZE(library->shaders);
1950*61046927SAndroid Build Coastguard Worker stage = (gl_shader_stage) (stage + 1)) {
1951*61046927SAndroid Build Coastguard Worker if (!post_link_nir[stage] && library->shaders[stage].nir) {
1952*61046927SAndroid Build Coastguard Worker post_link_nir[stage] = library->shaders[stage].nir;
1953*61046927SAndroid Build Coastguard Worker keys[stage] = library->shaders[stage].key;
1954*61046927SAndroid Build Coastguard Worker }
1955*61046927SAndroid Build Coastguard Worker
1956*61046927SAndroid Build Coastguard Worker if (!shaders[stage] && library->base.shaders[stage]) {
1957*61046927SAndroid Build Coastguard Worker shaders[stage] = library->base.shaders[stage];
1958*61046927SAndroid Build Coastguard Worker vk_pipeline_cache_object_ref(&shaders[stage]->base);
1959*61046927SAndroid Build Coastguard Worker }
1960*61046927SAndroid Build Coastguard Worker }
1961*61046927SAndroid Build Coastguard Worker }
1962*61046927SAndroid Build Coastguard Worker
1963*61046927SAndroid Build Coastguard Worker if (shaders[MESA_SHADER_VERTEX]) {
1964*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *vs =
1965*61046927SAndroid Build Coastguard Worker shaders[MESA_SHADER_VERTEX]->variant;
1966*61046927SAndroid Build Coastguard Worker
1967*61046927SAndroid Build Coastguard Worker if (!vs->stream_output.num_outputs && ir3_has_binning_vs(&vs->key)) {
1968*61046927SAndroid Build Coastguard Worker tu_append_executable(pipeline, vs->binning, NULL);
1969*61046927SAndroid Build Coastguard Worker }
1970*61046927SAndroid Build Coastguard Worker }
1971*61046927SAndroid Build Coastguard Worker
1972*61046927SAndroid Build Coastguard Worker if (pipeline_contains_all_shader_state(pipeline)) {
1973*61046927SAndroid Build Coastguard Worker /* It doesn't make much sense to use RETAIN_LINK_TIME_OPTIMIZATION_INFO
1974*61046927SAndroid Build Coastguard Worker * when compiling all stages, but make sure we don't leak.
1975*61046927SAndroid Build Coastguard Worker */
1976*61046927SAndroid Build Coastguard Worker if (nir_shaders)
1977*61046927SAndroid Build Coastguard Worker vk_pipeline_cache_object_unref(&builder->device->vk,
1978*61046927SAndroid Build Coastguard Worker &nir_shaders->base);
1979*61046927SAndroid Build Coastguard Worker } else {
1980*61046927SAndroid Build Coastguard Worker struct tu_graphics_lib_pipeline *library =
1981*61046927SAndroid Build Coastguard Worker tu_pipeline_to_graphics_lib(pipeline);
1982*61046927SAndroid Build Coastguard Worker library->nir_shaders = nir_shaders;
1983*61046927SAndroid Build Coastguard Worker for (gl_shader_stage stage = MESA_SHADER_VERTEX;
1984*61046927SAndroid Build Coastguard Worker stage < ARRAY_SIZE(library->shaders);
1985*61046927SAndroid Build Coastguard Worker stage = (gl_shader_stage) (stage + 1)) {
1986*61046927SAndroid Build Coastguard Worker library->shaders[stage].nir = post_link_nir[stage];
1987*61046927SAndroid Build Coastguard Worker library->shaders[stage].key = keys[stage];
1988*61046927SAndroid Build Coastguard Worker }
1989*61046927SAndroid Build Coastguard Worker }
1990*61046927SAndroid Build Coastguard Worker
1991*61046927SAndroid Build Coastguard Worker for (gl_shader_stage stage = MESA_SHADER_VERTEX;
1992*61046927SAndroid Build Coastguard Worker stage < ARRAY_SIZE(shaders); stage = (gl_shader_stage) (stage + 1)) {
1993*61046927SAndroid Build Coastguard Worker pipeline->shaders[stage] = shaders[stage];
1994*61046927SAndroid Build Coastguard Worker if (shaders[stage])
1995*61046927SAndroid Build Coastguard Worker pipeline->active_desc_sets |= shaders[stage]->active_desc_sets;
1996*61046927SAndroid Build Coastguard Worker }
1997*61046927SAndroid Build Coastguard Worker
1998*61046927SAndroid Build Coastguard Worker pipeline_feedback.duration = os_time_get_nano() - pipeline_start;
1999*61046927SAndroid Build Coastguard Worker if (creation_feedback) {
2000*61046927SAndroid Build Coastguard Worker *creation_feedback->pPipelineCreationFeedback = pipeline_feedback;
2001*61046927SAndroid Build Coastguard Worker
2002*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < builder->create_info->stageCount; i++) {
2003*61046927SAndroid Build Coastguard Worker gl_shader_stage s =
2004*61046927SAndroid Build Coastguard Worker vk_to_mesa_shader_stage(builder->create_info->pStages[i].stage);
2005*61046927SAndroid Build Coastguard Worker creation_feedback->pPipelineStageCreationFeedbacks[i] = stage_feedbacks[s];
2006*61046927SAndroid Build Coastguard Worker }
2007*61046927SAndroid Build Coastguard Worker }
2008*61046927SAndroid Build Coastguard Worker
2009*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
2010*61046927SAndroid Build Coastguard Worker
2011*61046927SAndroid Build Coastguard Worker fail:
2012*61046927SAndroid Build Coastguard Worker if (nir_shaders)
2013*61046927SAndroid Build Coastguard Worker vk_pipeline_cache_object_unref(&builder->device->vk,
2014*61046927SAndroid Build Coastguard Worker &nir_shaders->base);
2015*61046927SAndroid Build Coastguard Worker
2016*61046927SAndroid Build Coastguard Worker return result;
2017*61046927SAndroid Build Coastguard Worker }
2018*61046927SAndroid Build Coastguard Worker
2019*61046927SAndroid Build Coastguard Worker static void
tu_pipeline_builder_parse_libraries(struct tu_pipeline_builder * builder,struct tu_pipeline * pipeline)2020*61046927SAndroid Build Coastguard Worker tu_pipeline_builder_parse_libraries(struct tu_pipeline_builder *builder,
2021*61046927SAndroid Build Coastguard Worker struct tu_pipeline *pipeline)
2022*61046927SAndroid Build Coastguard Worker {
2023*61046927SAndroid Build Coastguard Worker const VkPipelineLibraryCreateInfoKHR *library_info =
2024*61046927SAndroid Build Coastguard Worker vk_find_struct_const(builder->create_info->pNext,
2025*61046927SAndroid Build Coastguard Worker PIPELINE_LIBRARY_CREATE_INFO_KHR);
2026*61046927SAndroid Build Coastguard Worker
2027*61046927SAndroid Build Coastguard Worker if (library_info) {
2028*61046927SAndroid Build Coastguard Worker assert(library_info->libraryCount <= MAX_LIBRARIES);
2029*61046927SAndroid Build Coastguard Worker builder->num_libraries = library_info->libraryCount;
2030*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < library_info->libraryCount; i++) {
2031*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(tu_pipeline, library, library_info->pLibraries[i]);
2032*61046927SAndroid Build Coastguard Worker builder->libraries[i] = tu_pipeline_to_graphics_lib(library);
2033*61046927SAndroid Build Coastguard Worker }
2034*61046927SAndroid Build Coastguard Worker }
2035*61046927SAndroid Build Coastguard Worker
2036*61046927SAndroid Build Coastguard Worker /* Merge in the state from libraries. The program state is a bit special
2037*61046927SAndroid Build Coastguard Worker * and is handled separately.
2038*61046927SAndroid Build Coastguard Worker */
2039*61046927SAndroid Build Coastguard Worker if (pipeline->type == TU_PIPELINE_GRAPHICS_LIB)
2040*61046927SAndroid Build Coastguard Worker tu_pipeline_to_graphics_lib(pipeline)->state = builder->state;
2041*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < builder->num_libraries; i++) {
2042*61046927SAndroid Build Coastguard Worker struct tu_graphics_lib_pipeline *library = builder->libraries[i];
2043*61046927SAndroid Build Coastguard Worker if (pipeline->type == TU_PIPELINE_GRAPHICS_LIB)
2044*61046927SAndroid Build Coastguard Worker tu_pipeline_to_graphics_lib(pipeline)->state |= library->state;
2045*61046927SAndroid Build Coastguard Worker
2046*61046927SAndroid Build Coastguard Worker if (library->state &
2047*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT) {
2048*61046927SAndroid Build Coastguard Worker pipeline->output = library->base.output;
2049*61046927SAndroid Build Coastguard Worker pipeline->lrz_blend.reads_dest |= library->base.lrz_blend.reads_dest;
2050*61046927SAndroid Build Coastguard Worker pipeline->lrz_blend.valid |= library->base.lrz_blend.valid;
2051*61046927SAndroid Build Coastguard Worker pipeline->prim_order = library->base.prim_order;
2052*61046927SAndroid Build Coastguard Worker }
2053*61046927SAndroid Build Coastguard Worker
2054*61046927SAndroid Build Coastguard Worker if ((library->state &
2055*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT) &&
2056*61046927SAndroid Build Coastguard Worker (library->state &
2057*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT)) {
2058*61046927SAndroid Build Coastguard Worker pipeline->prim_order = library->base.prim_order;
2059*61046927SAndroid Build Coastguard Worker }
2060*61046927SAndroid Build Coastguard Worker
2061*61046927SAndroid Build Coastguard Worker pipeline->set_state_mask |= library->base.set_state_mask;
2062*61046927SAndroid Build Coastguard Worker
2063*61046927SAndroid Build Coastguard Worker u_foreach_bit (i, library->base.set_state_mask) {
2064*61046927SAndroid Build Coastguard Worker pipeline->dynamic_state[i] = library->base.dynamic_state[i];
2065*61046927SAndroid Build Coastguard Worker }
2066*61046927SAndroid Build Coastguard Worker
2067*61046927SAndroid Build Coastguard Worker if (contains_all_shader_state(library->state)) {
2068*61046927SAndroid Build Coastguard Worker pipeline->program = library->base.program;
2069*61046927SAndroid Build Coastguard Worker pipeline->load_state = library->base.load_state;
2070*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < ARRAY_SIZE(pipeline->shaders); i++) {
2071*61046927SAndroid Build Coastguard Worker if (library->base.shaders[i]) {
2072*61046927SAndroid Build Coastguard Worker pipeline->shaders[i] = library->base.shaders[i];
2073*61046927SAndroid Build Coastguard Worker vk_pipeline_cache_object_ref(&pipeline->shaders[i]->base);
2074*61046927SAndroid Build Coastguard Worker }
2075*61046927SAndroid Build Coastguard Worker }
2076*61046927SAndroid Build Coastguard Worker }
2077*61046927SAndroid Build Coastguard Worker
2078*61046927SAndroid Build Coastguard Worker BITSET_OR(pipeline->static_state_mask, pipeline->static_state_mask,
2079*61046927SAndroid Build Coastguard Worker library->base.static_state_mask);
2080*61046927SAndroid Build Coastguard Worker
2081*61046927SAndroid Build Coastguard Worker vk_graphics_pipeline_state_merge(&builder->graphics_state,
2082*61046927SAndroid Build Coastguard Worker &library->graphics_state);
2083*61046927SAndroid Build Coastguard Worker }
2084*61046927SAndroid Build Coastguard Worker }
2085*61046927SAndroid Build Coastguard Worker
2086*61046927SAndroid Build Coastguard Worker static void
tu_pipeline_builder_parse_layout(struct tu_pipeline_builder * builder,struct tu_pipeline * pipeline)2087*61046927SAndroid Build Coastguard Worker tu_pipeline_builder_parse_layout(struct tu_pipeline_builder *builder,
2088*61046927SAndroid Build Coastguard Worker struct tu_pipeline *pipeline)
2089*61046927SAndroid Build Coastguard Worker {
2090*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(tu_pipeline_layout, layout, builder->create_info->layout);
2091*61046927SAndroid Build Coastguard Worker
2092*61046927SAndroid Build Coastguard Worker if (layout) {
2093*61046927SAndroid Build Coastguard Worker /* Note: it's still valid to have a layout even if there are libraries.
2094*61046927SAndroid Build Coastguard Worker * This allows the app to e.g. overwrite an INDEPENDENT_SET layout with
2095*61046927SAndroid Build Coastguard Worker * a non-INDEPENDENT_SET layout which may make us use a faster path,
2096*61046927SAndroid Build Coastguard Worker * currently this just affects dynamic offset descriptors.
2097*61046927SAndroid Build Coastguard Worker */
2098*61046927SAndroid Build Coastguard Worker builder->layout = *layout;
2099*61046927SAndroid Build Coastguard Worker } else {
2100*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < builder->num_libraries; i++) {
2101*61046927SAndroid Build Coastguard Worker struct tu_graphics_lib_pipeline *library = builder->libraries[i];
2102*61046927SAndroid Build Coastguard Worker builder->layout.num_sets = MAX2(builder->layout.num_sets,
2103*61046927SAndroid Build Coastguard Worker library->num_sets);
2104*61046927SAndroid Build Coastguard Worker assert(builder->layout.num_sets <= builder->device->physical_device->usable_sets);
2105*61046927SAndroid Build Coastguard Worker for (unsigned j = 0; j < library->num_sets; j++) {
2106*61046927SAndroid Build Coastguard Worker builder->layout.set[i].layout = library->layouts[i];
2107*61046927SAndroid Build Coastguard Worker }
2108*61046927SAndroid Build Coastguard Worker
2109*61046927SAndroid Build Coastguard Worker builder->layout.push_constant_size = library->push_constant_size;
2110*61046927SAndroid Build Coastguard Worker }
2111*61046927SAndroid Build Coastguard Worker
2112*61046927SAndroid Build Coastguard Worker tu_pipeline_layout_init(&builder->layout);
2113*61046927SAndroid Build Coastguard Worker }
2114*61046927SAndroid Build Coastguard Worker
2115*61046927SAndroid Build Coastguard Worker if (pipeline->type == TU_PIPELINE_GRAPHICS_LIB) {
2116*61046927SAndroid Build Coastguard Worker struct tu_graphics_lib_pipeline *library =
2117*61046927SAndroid Build Coastguard Worker tu_pipeline_to_graphics_lib(pipeline);
2118*61046927SAndroid Build Coastguard Worker library->num_sets = builder->layout.num_sets;
2119*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < library->num_sets; i++) {
2120*61046927SAndroid Build Coastguard Worker library->layouts[i] = builder->layout.set[i].layout;
2121*61046927SAndroid Build Coastguard Worker if (library->layouts[i])
2122*61046927SAndroid Build Coastguard Worker vk_descriptor_set_layout_ref(&library->layouts[i]->vk);
2123*61046927SAndroid Build Coastguard Worker }
2124*61046927SAndroid Build Coastguard Worker library->push_constant_size = builder->layout.push_constant_size;
2125*61046927SAndroid Build Coastguard Worker }
2126*61046927SAndroid Build Coastguard Worker }
2127*61046927SAndroid Build Coastguard Worker
2128*61046927SAndroid Build Coastguard Worker static void
tu_pipeline_set_linkage(struct tu_program_descriptor_linkage * link,struct tu_const_state * const_state,const struct ir3_shader_variant * v)2129*61046927SAndroid Build Coastguard Worker tu_pipeline_set_linkage(struct tu_program_descriptor_linkage *link,
2130*61046927SAndroid Build Coastguard Worker struct tu_const_state *const_state,
2131*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *v)
2132*61046927SAndroid Build Coastguard Worker {
2133*61046927SAndroid Build Coastguard Worker link->const_state = *ir3_const_state(v);
2134*61046927SAndroid Build Coastguard Worker link->tu_const_state = *const_state;
2135*61046927SAndroid Build Coastguard Worker link->constlen = v->constlen;
2136*61046927SAndroid Build Coastguard Worker }
2137*61046927SAndroid Build Coastguard Worker
2138*61046927SAndroid Build Coastguard Worker template <chip CHIP>
2139*61046927SAndroid Build Coastguard Worker static void
tu_emit_program_state(struct tu_cs * sub_cs,struct tu_program_state * prog,struct tu_shader ** shaders)2140*61046927SAndroid Build Coastguard Worker tu_emit_program_state(struct tu_cs *sub_cs,
2141*61046927SAndroid Build Coastguard Worker struct tu_program_state *prog,
2142*61046927SAndroid Build Coastguard Worker struct tu_shader **shaders)
2143*61046927SAndroid Build Coastguard Worker {
2144*61046927SAndroid Build Coastguard Worker struct tu_device *dev = sub_cs->device;
2145*61046927SAndroid Build Coastguard Worker struct tu_cs prog_cs;
2146*61046927SAndroid Build Coastguard Worker
2147*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *variants[MESA_SHADER_STAGES];
2148*61046927SAndroid Build Coastguard Worker struct tu_draw_state draw_states[MESA_SHADER_STAGES];
2149*61046927SAndroid Build Coastguard Worker
2150*61046927SAndroid Build Coastguard Worker for (gl_shader_stage stage = MESA_SHADER_VERTEX;
2151*61046927SAndroid Build Coastguard Worker stage < ARRAY_SIZE(variants); stage = (gl_shader_stage) (stage+1)) {
2152*61046927SAndroid Build Coastguard Worker variants[stage] = shaders[stage] ? shaders[stage]->variant : NULL;
2153*61046927SAndroid Build Coastguard Worker }
2154*61046927SAndroid Build Coastguard Worker
2155*61046927SAndroid Build Coastguard Worker uint32_t safe_variants =
2156*61046927SAndroid Build Coastguard Worker ir3_trim_constlen(variants, dev->compiler);
2157*61046927SAndroid Build Coastguard Worker
2158*61046927SAndroid Build Coastguard Worker unsigned dynamic_descriptor_sizes[MAX_SETS] = { };
2159*61046927SAndroid Build Coastguard Worker
2160*61046927SAndroid Build Coastguard Worker for (gl_shader_stage stage = MESA_SHADER_VERTEX;
2161*61046927SAndroid Build Coastguard Worker stage < ARRAY_SIZE(variants); stage = (gl_shader_stage) (stage+1)) {
2162*61046927SAndroid Build Coastguard Worker if (shaders[stage]) {
2163*61046927SAndroid Build Coastguard Worker if (safe_variants & (1u << stage)) {
2164*61046927SAndroid Build Coastguard Worker variants[stage] = shaders[stage]->safe_const_variant;
2165*61046927SAndroid Build Coastguard Worker draw_states[stage] = shaders[stage]->safe_const_state;
2166*61046927SAndroid Build Coastguard Worker } else {
2167*61046927SAndroid Build Coastguard Worker draw_states[stage] = shaders[stage]->state;
2168*61046927SAndroid Build Coastguard Worker }
2169*61046927SAndroid Build Coastguard Worker
2170*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < MAX_SETS; i++) {
2171*61046927SAndroid Build Coastguard Worker if (shaders[stage]->dynamic_descriptor_sizes[i] >= 0) {
2172*61046927SAndroid Build Coastguard Worker dynamic_descriptor_sizes[i] =
2173*61046927SAndroid Build Coastguard Worker shaders[stage]->dynamic_descriptor_sizes[i];
2174*61046927SAndroid Build Coastguard Worker }
2175*61046927SAndroid Build Coastguard Worker }
2176*61046927SAndroid Build Coastguard Worker }
2177*61046927SAndroid Build Coastguard Worker }
2178*61046927SAndroid Build Coastguard Worker
2179*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < ARRAY_SIZE(variants); i++) {
2180*61046927SAndroid Build Coastguard Worker if (!variants[i])
2181*61046927SAndroid Build Coastguard Worker continue;
2182*61046927SAndroid Build Coastguard Worker
2183*61046927SAndroid Build Coastguard Worker tu_pipeline_set_linkage(&prog->link[i],
2184*61046927SAndroid Build Coastguard Worker &shaders[i]->const_state,
2185*61046927SAndroid Build Coastguard Worker variants[i]);
2186*61046927SAndroid Build Coastguard Worker
2187*61046927SAndroid Build Coastguard Worker struct tu_push_constant_range *push_consts =
2188*61046927SAndroid Build Coastguard Worker &shaders[i]->const_state.push_consts;
2189*61046927SAndroid Build Coastguard Worker if (push_consts->type == IR3_PUSH_CONSTS_SHARED ||
2190*61046927SAndroid Build Coastguard Worker push_consts->type == IR3_PUSH_CONSTS_SHARED_PREAMBLE) {
2191*61046927SAndroid Build Coastguard Worker prog->shared_consts = *push_consts;
2192*61046927SAndroid Build Coastguard Worker }
2193*61046927SAndroid Build Coastguard Worker }
2194*61046927SAndroid Build Coastguard Worker
2195*61046927SAndroid Build Coastguard Worker unsigned dynamic_descriptor_offset = 0;
2196*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < MAX_SETS; i++) {
2197*61046927SAndroid Build Coastguard Worker prog->dynamic_descriptor_offsets[i] = dynamic_descriptor_offset;
2198*61046927SAndroid Build Coastguard Worker dynamic_descriptor_offset += dynamic_descriptor_sizes[i];
2199*61046927SAndroid Build Coastguard Worker }
2200*61046927SAndroid Build Coastguard Worker
2201*61046927SAndroid Build Coastguard Worker /* Emit HLSQ_xS_CNTL/HLSQ_SP_xS_CONFIG *first*, before emitting anything
2202*61046927SAndroid Build Coastguard Worker * else that could depend on that state (like push constants)
2203*61046927SAndroid Build Coastguard Worker *
2204*61046927SAndroid Build Coastguard Worker * Note also that this always uses the full VS even in binning pass. The
2205*61046927SAndroid Build Coastguard Worker * binning pass variant has the same const layout as the full VS, and
2206*61046927SAndroid Build Coastguard Worker * the constlen for the VS will be the same or greater than the constlen
2207*61046927SAndroid Build Coastguard Worker * for the binning pass variant. It is required that the constlen state
2208*61046927SAndroid Build Coastguard Worker * matches between binning and draw passes, as some parts of the push
2209*61046927SAndroid Build Coastguard Worker * consts are emitted in state groups that are shared between the binning
2210*61046927SAndroid Build Coastguard Worker * and draw passes.
2211*61046927SAndroid Build Coastguard Worker */
2212*61046927SAndroid Build Coastguard Worker tu_cs_begin_sub_stream(sub_cs, 512, &prog_cs);
2213*61046927SAndroid Build Coastguard Worker tu6_emit_program_config<CHIP>(&prog_cs, prog, shaders, variants);
2214*61046927SAndroid Build Coastguard Worker prog->config_state = tu_cs_end_draw_state(sub_cs, &prog_cs);
2215*61046927SAndroid Build Coastguard Worker
2216*61046927SAndroid Build Coastguard Worker prog->vs_state = draw_states[MESA_SHADER_VERTEX];
2217*61046927SAndroid Build Coastguard Worker
2218*61046927SAndroid Build Coastguard Worker /* Don't use the binning pass variant when GS is present because we don't
2219*61046927SAndroid Build Coastguard Worker * support compiling correct binning pass variants with GS.
2220*61046927SAndroid Build Coastguard Worker */
2221*61046927SAndroid Build Coastguard Worker if (variants[MESA_SHADER_GEOMETRY]) {
2222*61046927SAndroid Build Coastguard Worker prog->vs_binning_state = prog->vs_state;
2223*61046927SAndroid Build Coastguard Worker } else {
2224*61046927SAndroid Build Coastguard Worker prog->vs_binning_state =
2225*61046927SAndroid Build Coastguard Worker shaders[MESA_SHADER_VERTEX]->binning_state;
2226*61046927SAndroid Build Coastguard Worker }
2227*61046927SAndroid Build Coastguard Worker
2228*61046927SAndroid Build Coastguard Worker prog->hs_state = draw_states[MESA_SHADER_TESS_CTRL];
2229*61046927SAndroid Build Coastguard Worker prog->ds_state = draw_states[MESA_SHADER_TESS_EVAL];
2230*61046927SAndroid Build Coastguard Worker prog->gs_state = draw_states[MESA_SHADER_GEOMETRY];
2231*61046927SAndroid Build Coastguard Worker prog->gs_binning_state =
2232*61046927SAndroid Build Coastguard Worker shaders[MESA_SHADER_GEOMETRY]->binning_state;
2233*61046927SAndroid Build Coastguard Worker prog->fs_state = draw_states[MESA_SHADER_FRAGMENT];
2234*61046927SAndroid Build Coastguard Worker
2235*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *vs = variants[MESA_SHADER_VERTEX];
2236*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *hs = variants[MESA_SHADER_TESS_CTRL];
2237*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *ds = variants[MESA_SHADER_TESS_EVAL];
2238*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *gs = variants[MESA_SHADER_GEOMETRY];
2239*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *fs = variants[MESA_SHADER_FRAGMENT];
2240*61046927SAndroid Build Coastguard Worker
2241*61046927SAndroid Build Coastguard Worker tu_cs_begin_sub_stream(sub_cs, 512, &prog_cs);
2242*61046927SAndroid Build Coastguard Worker tu6_emit_vpc<CHIP>(&prog_cs, vs, hs, ds, gs, fs);
2243*61046927SAndroid Build Coastguard Worker prog->vpc_state = tu_cs_end_draw_state(sub_cs, &prog_cs);
2244*61046927SAndroid Build Coastguard Worker
2245*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *last_shader;
2246*61046927SAndroid Build Coastguard Worker if (gs)
2247*61046927SAndroid Build Coastguard Worker last_shader = gs;
2248*61046927SAndroid Build Coastguard Worker else if (ds)
2249*61046927SAndroid Build Coastguard Worker last_shader = ds;
2250*61046927SAndroid Build Coastguard Worker else
2251*61046927SAndroid Build Coastguard Worker last_shader = vs;
2252*61046927SAndroid Build Coastguard Worker
2253*61046927SAndroid Build Coastguard Worker prog->per_view_viewport =
2254*61046927SAndroid Build Coastguard Worker !last_shader->writes_viewport &&
2255*61046927SAndroid Build Coastguard Worker shaders[MESA_SHADER_FRAGMENT]->fs.has_fdm &&
2256*61046927SAndroid Build Coastguard Worker dev->physical_device->info->a6xx.has_per_view_viewport;
2257*61046927SAndroid Build Coastguard Worker }
2258*61046927SAndroid Build Coastguard Worker
2259*61046927SAndroid Build Coastguard Worker static const enum mesa_vk_dynamic_graphics_state tu_vertex_input_state[] = {
2260*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_VI,
2261*61046927SAndroid Build Coastguard Worker };
2262*61046927SAndroid Build Coastguard Worker
2263*61046927SAndroid Build Coastguard Worker template <chip CHIP>
2264*61046927SAndroid Build Coastguard Worker static unsigned
tu6_vertex_input_size(struct tu_device * dev,const struct vk_vertex_input_state * vi)2265*61046927SAndroid Build Coastguard Worker tu6_vertex_input_size(struct tu_device *dev,
2266*61046927SAndroid Build Coastguard Worker const struct vk_vertex_input_state *vi)
2267*61046927SAndroid Build Coastguard Worker {
2268*61046927SAndroid Build Coastguard Worker return 1 + 2 * util_last_bit(vi->attributes_valid);
2269*61046927SAndroid Build Coastguard Worker }
2270*61046927SAndroid Build Coastguard Worker
2271*61046927SAndroid Build Coastguard Worker template <chip CHIP>
2272*61046927SAndroid Build Coastguard Worker static void
tu6_emit_vertex_input(struct tu_cs * cs,const struct vk_vertex_input_state * vi)2273*61046927SAndroid Build Coastguard Worker tu6_emit_vertex_input(struct tu_cs *cs,
2274*61046927SAndroid Build Coastguard Worker const struct vk_vertex_input_state *vi)
2275*61046927SAndroid Build Coastguard Worker {
2276*61046927SAndroid Build Coastguard Worker unsigned attr_count = util_last_bit(vi->attributes_valid);
2277*61046927SAndroid Build Coastguard Worker if (attr_count != 0)
2278*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, REG_A6XX_VFD_DECODE_INSTR(0), attr_count * 2);
2279*61046927SAndroid Build Coastguard Worker
2280*61046927SAndroid Build Coastguard Worker for (uint32_t loc = 0; loc < attr_count; loc++) {
2281*61046927SAndroid Build Coastguard Worker const struct vk_vertex_attribute_state *attr = &vi->attributes[loc];
2282*61046927SAndroid Build Coastguard Worker
2283*61046927SAndroid Build Coastguard Worker if (vi->attributes_valid & (1u << loc)) {
2284*61046927SAndroid Build Coastguard Worker const struct vk_vertex_binding_state *binding =
2285*61046927SAndroid Build Coastguard Worker &vi->bindings[attr->binding];
2286*61046927SAndroid Build Coastguard Worker
2287*61046927SAndroid Build Coastguard Worker enum pipe_format pipe_format = vk_format_to_pipe_format(attr->format);
2288*61046927SAndroid Build Coastguard Worker const struct tu_native_format format = tu6_format_vtx(pipe_format);
2289*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, A6XX_VFD_DECODE_INSTR(0,
2290*61046927SAndroid Build Coastguard Worker .idx = attr->binding,
2291*61046927SAndroid Build Coastguard Worker .offset = attr->offset,
2292*61046927SAndroid Build Coastguard Worker .instanced = binding->input_rate == VK_VERTEX_INPUT_RATE_INSTANCE,
2293*61046927SAndroid Build Coastguard Worker .format = format.fmt,
2294*61046927SAndroid Build Coastguard Worker .swap = format.swap,
2295*61046927SAndroid Build Coastguard Worker .unk30 = 1,
2296*61046927SAndroid Build Coastguard Worker ._float = !util_format_is_pure_integer(pipe_format)).value);
2297*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, A6XX_VFD_DECODE_STEP_RATE(0, binding->divisor).value);
2298*61046927SAndroid Build Coastguard Worker } else {
2299*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, 0);
2300*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, 0);
2301*61046927SAndroid Build Coastguard Worker }
2302*61046927SAndroid Build Coastguard Worker }
2303*61046927SAndroid Build Coastguard Worker }
2304*61046927SAndroid Build Coastguard Worker
2305*61046927SAndroid Build Coastguard Worker static const enum mesa_vk_dynamic_graphics_state tu_vertex_stride_state[] = {
2306*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_VI_BINDINGS_VALID,
2307*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_VI_BINDING_STRIDES,
2308*61046927SAndroid Build Coastguard Worker };
2309*61046927SAndroid Build Coastguard Worker
2310*61046927SAndroid Build Coastguard Worker template <chip CHIP>
2311*61046927SAndroid Build Coastguard Worker static unsigned
tu6_vertex_stride_size(struct tu_device * dev,const struct vk_vertex_input_state * vi)2312*61046927SAndroid Build Coastguard Worker tu6_vertex_stride_size(struct tu_device *dev,
2313*61046927SAndroid Build Coastguard Worker const struct vk_vertex_input_state *vi)
2314*61046927SAndroid Build Coastguard Worker {
2315*61046927SAndroid Build Coastguard Worker return 1 + 2 * util_last_bit(vi->bindings_valid);
2316*61046927SAndroid Build Coastguard Worker }
2317*61046927SAndroid Build Coastguard Worker
2318*61046927SAndroid Build Coastguard Worker template <chip CHIP>
2319*61046927SAndroid Build Coastguard Worker static void
tu6_emit_vertex_stride(struct tu_cs * cs,const struct vk_vertex_input_state * vi)2320*61046927SAndroid Build Coastguard Worker tu6_emit_vertex_stride(struct tu_cs *cs, const struct vk_vertex_input_state *vi)
2321*61046927SAndroid Build Coastguard Worker {
2322*61046927SAndroid Build Coastguard Worker if (vi->bindings_valid) {
2323*61046927SAndroid Build Coastguard Worker unsigned bindings_count = util_last_bit(vi->bindings_valid);
2324*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt7(cs, CP_CONTEXT_REG_BUNCH, 2 * bindings_count);
2325*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < bindings_count; i++) {
2326*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, REG_A6XX_VFD_FETCH_STRIDE(i));
2327*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, vi->bindings[i].stride);
2328*61046927SAndroid Build Coastguard Worker }
2329*61046927SAndroid Build Coastguard Worker }
2330*61046927SAndroid Build Coastguard Worker }
2331*61046927SAndroid Build Coastguard Worker
2332*61046927SAndroid Build Coastguard Worker template <chip CHIP>
2333*61046927SAndroid Build Coastguard Worker static unsigned
tu6_vertex_stride_size_dyn(struct tu_device * dev,const uint16_t * vi_binding_stride,uint32_t bindings_valid)2334*61046927SAndroid Build Coastguard Worker tu6_vertex_stride_size_dyn(struct tu_device *dev,
2335*61046927SAndroid Build Coastguard Worker const uint16_t *vi_binding_stride,
2336*61046927SAndroid Build Coastguard Worker uint32_t bindings_valid)
2337*61046927SAndroid Build Coastguard Worker {
2338*61046927SAndroid Build Coastguard Worker return 1 + 2 * util_last_bit(bindings_valid);
2339*61046927SAndroid Build Coastguard Worker }
2340*61046927SAndroid Build Coastguard Worker
2341*61046927SAndroid Build Coastguard Worker template <chip CHIP>
2342*61046927SAndroid Build Coastguard Worker static void
tu6_emit_vertex_stride_dyn(struct tu_cs * cs,const uint16_t * vi_binding_stride,uint32_t bindings_valid)2343*61046927SAndroid Build Coastguard Worker tu6_emit_vertex_stride_dyn(struct tu_cs *cs, const uint16_t *vi_binding_stride,
2344*61046927SAndroid Build Coastguard Worker uint32_t bindings_valid)
2345*61046927SAndroid Build Coastguard Worker {
2346*61046927SAndroid Build Coastguard Worker if (bindings_valid) {
2347*61046927SAndroid Build Coastguard Worker unsigned bindings_count = util_last_bit(bindings_valid);
2348*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt7(cs, CP_CONTEXT_REG_BUNCH, 2 * bindings_count);
2349*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < bindings_count; i++) {
2350*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, REG_A6XX_VFD_FETCH_STRIDE(i));
2351*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, vi_binding_stride[i]);
2352*61046927SAndroid Build Coastguard Worker }
2353*61046927SAndroid Build Coastguard Worker }
2354*61046927SAndroid Build Coastguard Worker }
2355*61046927SAndroid Build Coastguard Worker
2356*61046927SAndroid Build Coastguard Worker static const enum mesa_vk_dynamic_graphics_state tu_viewport_state[] = {
2357*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_VP_VIEWPORTS,
2358*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_VP_VIEWPORT_COUNT,
2359*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_VP_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE,
2360*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_RS_DEPTH_CLAMP_ENABLE,
2361*61046927SAndroid Build Coastguard Worker };
2362*61046927SAndroid Build Coastguard Worker
2363*61046927SAndroid Build Coastguard Worker template <chip CHIP>
2364*61046927SAndroid Build Coastguard Worker static unsigned
tu6_viewport_size(struct tu_device * dev,const struct vk_viewport_state * vp,const struct vk_rasterization_state * rs)2365*61046927SAndroid Build Coastguard Worker tu6_viewport_size(struct tu_device *dev,
2366*61046927SAndroid Build Coastguard Worker const struct vk_viewport_state *vp,
2367*61046927SAndroid Build Coastguard Worker const struct vk_rasterization_state *rs)
2368*61046927SAndroid Build Coastguard Worker {
2369*61046927SAndroid Build Coastguard Worker return 1 + vp->viewport_count * 6 + 1 + vp->viewport_count * 2 +
2370*61046927SAndroid Build Coastguard Worker 1 + vp->viewport_count * 2 + 5;
2371*61046927SAndroid Build Coastguard Worker }
2372*61046927SAndroid Build Coastguard Worker
2373*61046927SAndroid Build Coastguard Worker template <chip CHIP>
2374*61046927SAndroid Build Coastguard Worker static void
tu6_emit_viewport(struct tu_cs * cs,const struct vk_viewport_state * vp,const struct vk_rasterization_state * rs)2375*61046927SAndroid Build Coastguard Worker tu6_emit_viewport(struct tu_cs *cs,
2376*61046927SAndroid Build Coastguard Worker const struct vk_viewport_state *vp,
2377*61046927SAndroid Build Coastguard Worker const struct vk_rasterization_state *rs)
2378*61046927SAndroid Build Coastguard Worker {
2379*61046927SAndroid Build Coastguard Worker VkExtent2D guardband = {511, 511};
2380*61046927SAndroid Build Coastguard Worker
2381*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_CL_VPORT_XOFFSET(0), vp->viewport_count * 6);
2382*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < vp->viewport_count; i++) {
2383*61046927SAndroid Build Coastguard Worker const VkViewport *viewport = &vp->viewports[i];
2384*61046927SAndroid Build Coastguard Worker float offsets[3];
2385*61046927SAndroid Build Coastguard Worker float scales[3];
2386*61046927SAndroid Build Coastguard Worker scales[0] = viewport->width / 2.0f;
2387*61046927SAndroid Build Coastguard Worker scales[1] = viewport->height / 2.0f;
2388*61046927SAndroid Build Coastguard Worker if (vp->depth_clip_negative_one_to_one) {
2389*61046927SAndroid Build Coastguard Worker scales[2] = 0.5 * (viewport->maxDepth - viewport->minDepth);
2390*61046927SAndroid Build Coastguard Worker } else {
2391*61046927SAndroid Build Coastguard Worker scales[2] = viewport->maxDepth - viewport->minDepth;
2392*61046927SAndroid Build Coastguard Worker }
2393*61046927SAndroid Build Coastguard Worker
2394*61046927SAndroid Build Coastguard Worker offsets[0] = viewport->x + scales[0];
2395*61046927SAndroid Build Coastguard Worker offsets[1] = viewport->y + scales[1];
2396*61046927SAndroid Build Coastguard Worker if (vp->depth_clip_negative_one_to_one) {
2397*61046927SAndroid Build Coastguard Worker offsets[2] = 0.5 * (viewport->minDepth + viewport->maxDepth);
2398*61046927SAndroid Build Coastguard Worker } else {
2399*61046927SAndroid Build Coastguard Worker offsets[2] = viewport->minDepth;
2400*61046927SAndroid Build Coastguard Worker }
2401*61046927SAndroid Build Coastguard Worker
2402*61046927SAndroid Build Coastguard Worker for (uint32_t j = 0; j < 3; j++) {
2403*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, fui(offsets[j]));
2404*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, fui(scales[j]));
2405*61046927SAndroid Build Coastguard Worker }
2406*61046927SAndroid Build Coastguard Worker
2407*61046927SAndroid Build Coastguard Worker guardband.width =
2408*61046927SAndroid Build Coastguard Worker MIN2(guardband.width, fd_calc_guardband(offsets[0], scales[0], false));
2409*61046927SAndroid Build Coastguard Worker guardband.height =
2410*61046927SAndroid Build Coastguard Worker MIN2(guardband.height, fd_calc_guardband(offsets[1], scales[1], false));
2411*61046927SAndroid Build Coastguard Worker }
2412*61046927SAndroid Build Coastguard Worker
2413*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL(0), vp->viewport_count * 2);
2414*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < vp->viewport_count; i++) {
2415*61046927SAndroid Build Coastguard Worker const VkViewport *viewport = &vp->viewports[i];
2416*61046927SAndroid Build Coastguard Worker VkOffset2D min;
2417*61046927SAndroid Build Coastguard Worker VkOffset2D max;
2418*61046927SAndroid Build Coastguard Worker min.x = (int32_t) viewport->x;
2419*61046927SAndroid Build Coastguard Worker max.x = (int32_t) ceilf(viewport->x + viewport->width);
2420*61046927SAndroid Build Coastguard Worker if (viewport->height >= 0.0f) {
2421*61046927SAndroid Build Coastguard Worker min.y = (int32_t) viewport->y;
2422*61046927SAndroid Build Coastguard Worker max.y = (int32_t) ceilf(viewport->y + viewport->height);
2423*61046927SAndroid Build Coastguard Worker } else {
2424*61046927SAndroid Build Coastguard Worker min.y = (int32_t)(viewport->y + viewport->height);
2425*61046927SAndroid Build Coastguard Worker max.y = (int32_t) ceilf(viewport->y);
2426*61046927SAndroid Build Coastguard Worker }
2427*61046927SAndroid Build Coastguard Worker /* the spec allows viewport->height to be 0.0f */
2428*61046927SAndroid Build Coastguard Worker if (min.y == max.y)
2429*61046927SAndroid Build Coastguard Worker max.y++;
2430*61046927SAndroid Build Coastguard Worker /* allow viewport->width = 0.0f for un-initialized viewports: */
2431*61046927SAndroid Build Coastguard Worker if (min.x == max.x)
2432*61046927SAndroid Build Coastguard Worker max.x++;
2433*61046927SAndroid Build Coastguard Worker
2434*61046927SAndroid Build Coastguard Worker min.x = MAX2(min.x, 0);
2435*61046927SAndroid Build Coastguard Worker min.y = MAX2(min.y, 0);
2436*61046927SAndroid Build Coastguard Worker max.x = MAX2(max.x, 1);
2437*61046927SAndroid Build Coastguard Worker max.y = MAX2(max.y, 1);
2438*61046927SAndroid Build Coastguard Worker
2439*61046927SAndroid Build Coastguard Worker assert(min.x < max.x);
2440*61046927SAndroid Build Coastguard Worker assert(min.y < max.y);
2441*61046927SAndroid Build Coastguard Worker
2442*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_X(min.x) |
2443*61046927SAndroid Build Coastguard Worker A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_Y(min.y));
2444*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, A6XX_GRAS_SC_VIEWPORT_SCISSOR_BR_X(max.x - 1) |
2445*61046927SAndroid Build Coastguard Worker A6XX_GRAS_SC_VIEWPORT_SCISSOR_BR_Y(max.y - 1));
2446*61046927SAndroid Build Coastguard Worker }
2447*61046927SAndroid Build Coastguard Worker
2448*61046927SAndroid Build Coastguard Worker /* A7XX+ doesn't clamp to [0,1] with disabled depth clamp, to support
2449*61046927SAndroid Build Coastguard Worker * VK_EXT_depth_clamp_zero_one we have to always enable clamp and manually
2450*61046927SAndroid Build Coastguard Worker * set range to [0,1] when rs->depth_clamp_enable is false.
2451*61046927SAndroid Build Coastguard Worker */
2452*61046927SAndroid Build Coastguard Worker bool zero_one_depth_clamp = CHIP >= A7XX && !rs->depth_clamp_enable;
2453*61046927SAndroid Build Coastguard Worker
2454*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_CL_Z_CLAMP(0), vp->viewport_count * 2);
2455*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < vp->viewport_count; i++) {
2456*61046927SAndroid Build Coastguard Worker const VkViewport *viewport = &vp->viewports[i];
2457*61046927SAndroid Build Coastguard Worker if (zero_one_depth_clamp) {
2458*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, fui(0.0f));
2459*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, fui(1.0f));
2460*61046927SAndroid Build Coastguard Worker } else {
2461*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, fui(MIN2(viewport->minDepth, viewport->maxDepth)));
2462*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, fui(MAX2(viewport->minDepth, viewport->maxDepth)));
2463*61046927SAndroid Build Coastguard Worker }
2464*61046927SAndroid Build Coastguard Worker }
2465*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_CL_GUARDBAND_CLIP_ADJ, 1);
2466*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, A6XX_GRAS_CL_GUARDBAND_CLIP_ADJ_HORZ(guardband.width) |
2467*61046927SAndroid Build Coastguard Worker A6XX_GRAS_CL_GUARDBAND_CLIP_ADJ_VERT(guardband.height));
2468*61046927SAndroid Build Coastguard Worker
2469*61046927SAndroid Build Coastguard Worker /* TODO: what to do about this and multi viewport ? */
2470*61046927SAndroid Build Coastguard Worker float z_clamp_min = vp->viewport_count ? MIN2(vp->viewports[0].minDepth, vp->viewports[0].maxDepth) : 0;
2471*61046927SAndroid Build Coastguard Worker float z_clamp_max = vp->viewport_count ? MAX2(vp->viewports[0].minDepth, vp->viewports[0].maxDepth) : 0;
2472*61046927SAndroid Build Coastguard Worker if (zero_one_depth_clamp) {
2473*61046927SAndroid Build Coastguard Worker z_clamp_min = 0.0f;
2474*61046927SAndroid Build Coastguard Worker z_clamp_max = 1.0f;
2475*61046927SAndroid Build Coastguard Worker }
2476*61046927SAndroid Build Coastguard Worker
2477*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs,
2478*61046927SAndroid Build Coastguard Worker A6XX_RB_Z_CLAMP_MIN(z_clamp_min),
2479*61046927SAndroid Build Coastguard Worker A6XX_RB_Z_CLAMP_MAX(z_clamp_max));
2480*61046927SAndroid Build Coastguard Worker }
2481*61046927SAndroid Build Coastguard Worker
2482*61046927SAndroid Build Coastguard Worker struct apply_viewport_state {
2483*61046927SAndroid Build Coastguard Worker struct vk_viewport_state vp;
2484*61046927SAndroid Build Coastguard Worker struct vk_rasterization_state rs;
2485*61046927SAndroid Build Coastguard Worker bool share_scale;
2486*61046927SAndroid Build Coastguard Worker };
2487*61046927SAndroid Build Coastguard Worker
2488*61046927SAndroid Build Coastguard Worker /* It's a hardware restriction that the window offset (i.e. bin.offset) must
2489*61046927SAndroid Build Coastguard Worker * be the same for all views. This means that GMEM coordinates cannot be a
2490*61046927SAndroid Build Coastguard Worker * simple scaling of framebuffer coordinates, because this would require us to
2491*61046927SAndroid Build Coastguard Worker * scale the window offset and the scale may be different per view. Instead we
2492*61046927SAndroid Build Coastguard Worker * have to apply a per-bin offset to the GMEM coordinate transform to make
2493*61046927SAndroid Build Coastguard Worker * sure that the window offset maps to itself. Specifically we need an offset
2494*61046927SAndroid Build Coastguard Worker * o to the transform:
2495*61046927SAndroid Build Coastguard Worker *
2496*61046927SAndroid Build Coastguard Worker * x' = s * x + o
2497*61046927SAndroid Build Coastguard Worker *
2498*61046927SAndroid Build Coastguard Worker * so that when we plug in the bin start b_s:
2499*61046927SAndroid Build Coastguard Worker *
2500*61046927SAndroid Build Coastguard Worker * b_s = s * b_s + o
2501*61046927SAndroid Build Coastguard Worker *
2502*61046927SAndroid Build Coastguard Worker * and we get:
2503*61046927SAndroid Build Coastguard Worker *
2504*61046927SAndroid Build Coastguard Worker * o = b_s - s * b_s
2505*61046927SAndroid Build Coastguard Worker *
2506*61046927SAndroid Build Coastguard Worker * We use this form exactly, because we know the bin offset is a multiple of
2507*61046927SAndroid Build Coastguard Worker * the frag area so s * b_s is an integer and we can compute an exact result
2508*61046927SAndroid Build Coastguard Worker * easily.
2509*61046927SAndroid Build Coastguard Worker */
2510*61046927SAndroid Build Coastguard Worker
2511*61046927SAndroid Build Coastguard Worker VkOffset2D
tu_fdm_per_bin_offset(VkExtent2D frag_area,VkRect2D bin)2512*61046927SAndroid Build Coastguard Worker tu_fdm_per_bin_offset(VkExtent2D frag_area, VkRect2D bin)
2513*61046927SAndroid Build Coastguard Worker {
2514*61046927SAndroid Build Coastguard Worker assert(bin.offset.x % frag_area.width == 0);
2515*61046927SAndroid Build Coastguard Worker assert(bin.offset.y % frag_area.height == 0);
2516*61046927SAndroid Build Coastguard Worker
2517*61046927SAndroid Build Coastguard Worker return (VkOffset2D) {
2518*61046927SAndroid Build Coastguard Worker bin.offset.x - bin.offset.x / frag_area.width,
2519*61046927SAndroid Build Coastguard Worker bin.offset.y - bin.offset.y / frag_area.height
2520*61046927SAndroid Build Coastguard Worker };
2521*61046927SAndroid Build Coastguard Worker }
2522*61046927SAndroid Build Coastguard Worker
2523*61046927SAndroid Build Coastguard Worker static void
fdm_apply_viewports(struct tu_cmd_buffer * cmd,struct tu_cs * cs,void * data,VkRect2D bin,unsigned views,VkExtent2D * frag_areas)2524*61046927SAndroid Build Coastguard Worker fdm_apply_viewports(struct tu_cmd_buffer *cmd, struct tu_cs *cs, void *data,
2525*61046927SAndroid Build Coastguard Worker VkRect2D bin, unsigned views, VkExtent2D *frag_areas)
2526*61046927SAndroid Build Coastguard Worker {
2527*61046927SAndroid Build Coastguard Worker const struct apply_viewport_state *state =
2528*61046927SAndroid Build Coastguard Worker (const struct apply_viewport_state *)data;
2529*61046927SAndroid Build Coastguard Worker
2530*61046927SAndroid Build Coastguard Worker struct vk_viewport_state vp = state->vp;
2531*61046927SAndroid Build Coastguard Worker
2532*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < state->vp.viewport_count; i++) {
2533*61046927SAndroid Build Coastguard Worker /* Note: If we're using shared scaling, the scale should already be the
2534*61046927SAndroid Build Coastguard Worker * same across all views, we can pick any view. However the number
2535*61046927SAndroid Build Coastguard Worker * of viewports and number of views is not guaranteed the same, so we
2536*61046927SAndroid Build Coastguard Worker * need to pick the 0'th view which always exists to be safe.
2537*61046927SAndroid Build Coastguard Worker *
2538*61046927SAndroid Build Coastguard Worker * Conversly, if we're not using shared scaling then the rasterizer in
2539*61046927SAndroid Build Coastguard Worker * the original pipeline is using only the first viewport, so we need to
2540*61046927SAndroid Build Coastguard Worker * replicate it across all viewports.
2541*61046927SAndroid Build Coastguard Worker */
2542*61046927SAndroid Build Coastguard Worker VkExtent2D frag_area = state->share_scale ? frag_areas[0] : frag_areas[i];
2543*61046927SAndroid Build Coastguard Worker VkViewport viewport =
2544*61046927SAndroid Build Coastguard Worker state->share_scale ? state->vp.viewports[i] : state->vp.viewports[0];
2545*61046927SAndroid Build Coastguard Worker if (frag_area.width == 1 && frag_area.height == 1) {
2546*61046927SAndroid Build Coastguard Worker vp.viewports[i] = viewport;
2547*61046927SAndroid Build Coastguard Worker continue;
2548*61046927SAndroid Build Coastguard Worker }
2549*61046927SAndroid Build Coastguard Worker
2550*61046927SAndroid Build Coastguard Worker float scale_x = (float) 1.0f / frag_area.width;
2551*61046927SAndroid Build Coastguard Worker float scale_y = (float) 1.0f / frag_area.height;
2552*61046927SAndroid Build Coastguard Worker
2553*61046927SAndroid Build Coastguard Worker vp.viewports[i].minDepth = viewport.minDepth;
2554*61046927SAndroid Build Coastguard Worker vp.viewports[i].maxDepth = viewport.maxDepth;
2555*61046927SAndroid Build Coastguard Worker vp.viewports[i].width = viewport.width * scale_x;
2556*61046927SAndroid Build Coastguard Worker vp.viewports[i].height = viewport.height * scale_y;
2557*61046927SAndroid Build Coastguard Worker
2558*61046927SAndroid Build Coastguard Worker VkOffset2D offset = tu_fdm_per_bin_offset(frag_area, bin);
2559*61046927SAndroid Build Coastguard Worker
2560*61046927SAndroid Build Coastguard Worker vp.viewports[i].x = scale_x * viewport.x + offset.x;
2561*61046927SAndroid Build Coastguard Worker vp.viewports[i].y = scale_y * viewport.y + offset.y;
2562*61046927SAndroid Build Coastguard Worker }
2563*61046927SAndroid Build Coastguard Worker
2564*61046927SAndroid Build Coastguard Worker TU_CALLX(cs->device, tu6_emit_viewport)(cs, &vp, &state->rs);
2565*61046927SAndroid Build Coastguard Worker }
2566*61046927SAndroid Build Coastguard Worker
2567*61046927SAndroid Build Coastguard Worker static void
tu6_emit_viewport_fdm(struct tu_cs * cs,struct tu_cmd_buffer * cmd,const struct vk_viewport_state * vp,const struct vk_rasterization_state * rs)2568*61046927SAndroid Build Coastguard Worker tu6_emit_viewport_fdm(struct tu_cs *cs, struct tu_cmd_buffer *cmd,
2569*61046927SAndroid Build Coastguard Worker const struct vk_viewport_state *vp,
2570*61046927SAndroid Build Coastguard Worker const struct vk_rasterization_state *rs)
2571*61046927SAndroid Build Coastguard Worker {
2572*61046927SAndroid Build Coastguard Worker unsigned num_views = MAX2(cmd->state.pass->num_views, 1);
2573*61046927SAndroid Build Coastguard Worker struct apply_viewport_state state = {
2574*61046927SAndroid Build Coastguard Worker .vp = *vp,
2575*61046927SAndroid Build Coastguard Worker .rs = *rs,
2576*61046927SAndroid Build Coastguard Worker .share_scale = !cmd->state.per_view_viewport,
2577*61046927SAndroid Build Coastguard Worker };
2578*61046927SAndroid Build Coastguard Worker if (!state.share_scale)
2579*61046927SAndroid Build Coastguard Worker state.vp.viewport_count = num_views;
2580*61046927SAndroid Build Coastguard Worker unsigned size = TU_CALLX(cmd->device, tu6_viewport_size)(cmd->device, &state.vp, &state.rs);
2581*61046927SAndroid Build Coastguard Worker tu_cs_begin_sub_stream(&cmd->sub_cs, size, cs);
2582*61046927SAndroid Build Coastguard Worker tu_create_fdm_bin_patchpoint(cmd, cs, size, fdm_apply_viewports, state);
2583*61046927SAndroid Build Coastguard Worker }
2584*61046927SAndroid Build Coastguard Worker
2585*61046927SAndroid Build Coastguard Worker static const enum mesa_vk_dynamic_graphics_state tu_scissor_state[] = {
2586*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_VP_SCISSORS,
2587*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_VP_SCISSOR_COUNT,
2588*61046927SAndroid Build Coastguard Worker };
2589*61046927SAndroid Build Coastguard Worker
2590*61046927SAndroid Build Coastguard Worker template <chip CHIP>
2591*61046927SAndroid Build Coastguard Worker static unsigned
tu6_scissor_size(struct tu_device * dev,const struct vk_viewport_state * vp)2592*61046927SAndroid Build Coastguard Worker tu6_scissor_size(struct tu_device *dev, const struct vk_viewport_state *vp)
2593*61046927SAndroid Build Coastguard Worker {
2594*61046927SAndroid Build Coastguard Worker return 1 + vp->scissor_count * 2;
2595*61046927SAndroid Build Coastguard Worker }
2596*61046927SAndroid Build Coastguard Worker
2597*61046927SAndroid Build Coastguard Worker template <chip CHIP>
2598*61046927SAndroid Build Coastguard Worker void
tu6_emit_scissor(struct tu_cs * cs,const struct vk_viewport_state * vp)2599*61046927SAndroid Build Coastguard Worker tu6_emit_scissor(struct tu_cs *cs, const struct vk_viewport_state *vp)
2600*61046927SAndroid Build Coastguard Worker {
2601*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_SC_SCREEN_SCISSOR_TL(0), vp->scissor_count * 2);
2602*61046927SAndroid Build Coastguard Worker
2603*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < vp->scissor_count; i++) {
2604*61046927SAndroid Build Coastguard Worker const VkRect2D *scissor = &vp->scissors[i];
2605*61046927SAndroid Build Coastguard Worker
2606*61046927SAndroid Build Coastguard Worker uint32_t min_x = scissor->offset.x;
2607*61046927SAndroid Build Coastguard Worker uint32_t min_y = scissor->offset.y;
2608*61046927SAndroid Build Coastguard Worker uint32_t max_x = min_x + scissor->extent.width - 1;
2609*61046927SAndroid Build Coastguard Worker uint32_t max_y = min_y + scissor->extent.height - 1;
2610*61046927SAndroid Build Coastguard Worker
2611*61046927SAndroid Build Coastguard Worker if (!scissor->extent.width || !scissor->extent.height) {
2612*61046927SAndroid Build Coastguard Worker min_x = min_y = 1;
2613*61046927SAndroid Build Coastguard Worker max_x = max_y = 0;
2614*61046927SAndroid Build Coastguard Worker } else {
2615*61046927SAndroid Build Coastguard Worker /* avoid overflow */
2616*61046927SAndroid Build Coastguard Worker uint32_t scissor_max = BITFIELD_MASK(15);
2617*61046927SAndroid Build Coastguard Worker min_x = MIN2(scissor_max, min_x);
2618*61046927SAndroid Build Coastguard Worker min_y = MIN2(scissor_max, min_y);
2619*61046927SAndroid Build Coastguard Worker max_x = MIN2(scissor_max, max_x);
2620*61046927SAndroid Build Coastguard Worker max_y = MIN2(scissor_max, max_y);
2621*61046927SAndroid Build Coastguard Worker }
2622*61046927SAndroid Build Coastguard Worker
2623*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, A6XX_GRAS_SC_SCREEN_SCISSOR_TL_X(min_x) |
2624*61046927SAndroid Build Coastguard Worker A6XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(min_y));
2625*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, A6XX_GRAS_SC_SCREEN_SCISSOR_BR_X(max_x) |
2626*61046927SAndroid Build Coastguard Worker A6XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(max_y));
2627*61046927SAndroid Build Coastguard Worker }
2628*61046927SAndroid Build Coastguard Worker }
2629*61046927SAndroid Build Coastguard Worker
2630*61046927SAndroid Build Coastguard Worker static void
fdm_apply_scissors(struct tu_cmd_buffer * cmd,struct tu_cs * cs,void * data,VkRect2D bin,unsigned views,VkExtent2D * frag_areas)2631*61046927SAndroid Build Coastguard Worker fdm_apply_scissors(struct tu_cmd_buffer *cmd, struct tu_cs *cs, void *data,
2632*61046927SAndroid Build Coastguard Worker VkRect2D bin, unsigned views, VkExtent2D *frag_areas)
2633*61046927SAndroid Build Coastguard Worker {
2634*61046927SAndroid Build Coastguard Worker const struct apply_viewport_state *state =
2635*61046927SAndroid Build Coastguard Worker (const struct apply_viewport_state *)data;
2636*61046927SAndroid Build Coastguard Worker
2637*61046927SAndroid Build Coastguard Worker struct vk_viewport_state vp = state->vp;
2638*61046927SAndroid Build Coastguard Worker
2639*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < vp.scissor_count; i++) {
2640*61046927SAndroid Build Coastguard Worker VkExtent2D frag_area = state->share_scale ? frag_areas[0] : frag_areas[i];
2641*61046927SAndroid Build Coastguard Worker VkRect2D scissor =
2642*61046927SAndroid Build Coastguard Worker state->share_scale ? state->vp.scissors[i] : state->vp.scissors[0];
2643*61046927SAndroid Build Coastguard Worker if (frag_area.width == 1 && frag_area.height == 1) {
2644*61046927SAndroid Build Coastguard Worker vp.scissors[i] = scissor;
2645*61046927SAndroid Build Coastguard Worker continue;
2646*61046927SAndroid Build Coastguard Worker }
2647*61046927SAndroid Build Coastguard Worker
2648*61046927SAndroid Build Coastguard Worker /* Transform the scissor following the viewport. It's unclear how this
2649*61046927SAndroid Build Coastguard Worker * is supposed to handle cases where the scissor isn't aligned to the
2650*61046927SAndroid Build Coastguard Worker * fragment area, but we round outwards to always render partial
2651*61046927SAndroid Build Coastguard Worker * fragments if the scissor size equals the framebuffer size and it
2652*61046927SAndroid Build Coastguard Worker * isn't aligned to the fragment area.
2653*61046927SAndroid Build Coastguard Worker */
2654*61046927SAndroid Build Coastguard Worker VkOffset2D offset = tu_fdm_per_bin_offset(frag_area, bin);
2655*61046927SAndroid Build Coastguard Worker VkOffset2D min = {
2656*61046927SAndroid Build Coastguard Worker scissor.offset.x / frag_area.width + offset.x,
2657*61046927SAndroid Build Coastguard Worker scissor.offset.y / frag_area.width + offset.y,
2658*61046927SAndroid Build Coastguard Worker };
2659*61046927SAndroid Build Coastguard Worker VkOffset2D max = {
2660*61046927SAndroid Build Coastguard Worker DIV_ROUND_UP(scissor.offset.x + scissor.extent.width, frag_area.width) + offset.x,
2661*61046927SAndroid Build Coastguard Worker DIV_ROUND_UP(scissor.offset.y + scissor.extent.height, frag_area.height) + offset.y,
2662*61046927SAndroid Build Coastguard Worker };
2663*61046927SAndroid Build Coastguard Worker
2664*61046927SAndroid Build Coastguard Worker /* Intersect scissor with the scaled bin, this essentially replaces the
2665*61046927SAndroid Build Coastguard Worker * window scissor.
2666*61046927SAndroid Build Coastguard Worker */
2667*61046927SAndroid Build Coastguard Worker uint32_t scaled_width = bin.extent.width / frag_area.width;
2668*61046927SAndroid Build Coastguard Worker uint32_t scaled_height = bin.extent.height / frag_area.height;
2669*61046927SAndroid Build Coastguard Worker vp.scissors[i].offset.x = MAX2(min.x, bin.offset.x);
2670*61046927SAndroid Build Coastguard Worker vp.scissors[i].offset.y = MAX2(min.y, bin.offset.y);
2671*61046927SAndroid Build Coastguard Worker vp.scissors[i].extent.width =
2672*61046927SAndroid Build Coastguard Worker MIN2(max.x, bin.offset.x + scaled_width) - vp.scissors[i].offset.x;
2673*61046927SAndroid Build Coastguard Worker vp.scissors[i].extent.height =
2674*61046927SAndroid Build Coastguard Worker MIN2(max.y, bin.offset.y + scaled_height) - vp.scissors[i].offset.y;
2675*61046927SAndroid Build Coastguard Worker }
2676*61046927SAndroid Build Coastguard Worker
2677*61046927SAndroid Build Coastguard Worker TU_CALLX(cs->device, tu6_emit_scissor)(cs, &vp);
2678*61046927SAndroid Build Coastguard Worker }
2679*61046927SAndroid Build Coastguard Worker
2680*61046927SAndroid Build Coastguard Worker static void
tu6_emit_scissor_fdm(struct tu_cs * cs,struct tu_cmd_buffer * cmd,const struct vk_viewport_state * vp)2681*61046927SAndroid Build Coastguard Worker tu6_emit_scissor_fdm(struct tu_cs *cs, struct tu_cmd_buffer *cmd,
2682*61046927SAndroid Build Coastguard Worker const struct vk_viewport_state *vp)
2683*61046927SAndroid Build Coastguard Worker {
2684*61046927SAndroid Build Coastguard Worker unsigned num_views = MAX2(cmd->state.pass->num_views, 1);
2685*61046927SAndroid Build Coastguard Worker struct apply_viewport_state state = {
2686*61046927SAndroid Build Coastguard Worker .vp = *vp,
2687*61046927SAndroid Build Coastguard Worker .share_scale = !cmd->state.per_view_viewport,
2688*61046927SAndroid Build Coastguard Worker };
2689*61046927SAndroid Build Coastguard Worker if (!state.share_scale)
2690*61046927SAndroid Build Coastguard Worker state.vp.scissor_count = num_views;
2691*61046927SAndroid Build Coastguard Worker unsigned size = TU_CALLX(cmd->device, tu6_scissor_size)(cmd->device, &state.vp);
2692*61046927SAndroid Build Coastguard Worker tu_cs_begin_sub_stream(&cmd->sub_cs, size, cs);
2693*61046927SAndroid Build Coastguard Worker tu_create_fdm_bin_patchpoint(cmd, cs, size, fdm_apply_scissors, state);
2694*61046927SAndroid Build Coastguard Worker }
2695*61046927SAndroid Build Coastguard Worker
2696*61046927SAndroid Build Coastguard Worker static const enum mesa_vk_dynamic_graphics_state tu_sample_locations_state[] = {
2697*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS_ENABLE,
2698*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS,
2699*61046927SAndroid Build Coastguard Worker };
2700*61046927SAndroid Build Coastguard Worker
2701*61046927SAndroid Build Coastguard Worker template <chip CHIP>
2702*61046927SAndroid Build Coastguard Worker static unsigned
tu6_sample_locations_size(struct tu_device * dev,bool enable,const struct vk_sample_locations_state * samp_loc)2703*61046927SAndroid Build Coastguard Worker tu6_sample_locations_size(struct tu_device *dev, bool enable,
2704*61046927SAndroid Build Coastguard Worker const struct vk_sample_locations_state *samp_loc)
2705*61046927SAndroid Build Coastguard Worker {
2706*61046927SAndroid Build Coastguard Worker return 6 + (enable ? 6 : 0);
2707*61046927SAndroid Build Coastguard Worker }
2708*61046927SAndroid Build Coastguard Worker
2709*61046927SAndroid Build Coastguard Worker template <chip CHIP>
2710*61046927SAndroid Build Coastguard Worker void
tu6_emit_sample_locations(struct tu_cs * cs,bool enable,const struct vk_sample_locations_state * samp_loc)2711*61046927SAndroid Build Coastguard Worker tu6_emit_sample_locations(struct tu_cs *cs, bool enable,
2712*61046927SAndroid Build Coastguard Worker const struct vk_sample_locations_state *samp_loc)
2713*61046927SAndroid Build Coastguard Worker {
2714*61046927SAndroid Build Coastguard Worker uint32_t sample_config =
2715*61046927SAndroid Build Coastguard Worker COND(enable, A6XX_RB_SAMPLE_CONFIG_LOCATION_ENABLE);
2716*61046927SAndroid Build Coastguard Worker
2717*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_SAMPLE_CONFIG, 1);
2718*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, sample_config);
2719*61046927SAndroid Build Coastguard Worker
2720*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, REG_A6XX_RB_SAMPLE_CONFIG, 1);
2721*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, sample_config);
2722*61046927SAndroid Build Coastguard Worker
2723*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, REG_A6XX_SP_TP_SAMPLE_CONFIG, 1);
2724*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, sample_config);
2725*61046927SAndroid Build Coastguard Worker
2726*61046927SAndroid Build Coastguard Worker if (!enable)
2727*61046927SAndroid Build Coastguard Worker return;
2728*61046927SAndroid Build Coastguard Worker
2729*61046927SAndroid Build Coastguard Worker assert(samp_loc->grid_size.width == 1);
2730*61046927SAndroid Build Coastguard Worker assert(samp_loc->grid_size.height == 1);
2731*61046927SAndroid Build Coastguard Worker
2732*61046927SAndroid Build Coastguard Worker uint32_t sample_locations = 0;
2733*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < samp_loc->per_pixel; i++) {
2734*61046927SAndroid Build Coastguard Worker /* From VkSampleLocationEXT:
2735*61046927SAndroid Build Coastguard Worker *
2736*61046927SAndroid Build Coastguard Worker * The values specified in a VkSampleLocationEXT structure are always
2737*61046927SAndroid Build Coastguard Worker * clamped to the implementation-dependent sample location coordinate
2738*61046927SAndroid Build Coastguard Worker * range
2739*61046927SAndroid Build Coastguard Worker * [sampleLocationCoordinateRange[0],sampleLocationCoordinateRange[1]]
2740*61046927SAndroid Build Coastguard Worker */
2741*61046927SAndroid Build Coastguard Worker float x = CLAMP(samp_loc->locations[i].x, SAMPLE_LOCATION_MIN,
2742*61046927SAndroid Build Coastguard Worker SAMPLE_LOCATION_MAX);
2743*61046927SAndroid Build Coastguard Worker float y = CLAMP(samp_loc->locations[i].y, SAMPLE_LOCATION_MIN,
2744*61046927SAndroid Build Coastguard Worker SAMPLE_LOCATION_MAX);
2745*61046927SAndroid Build Coastguard Worker
2746*61046927SAndroid Build Coastguard Worker sample_locations |=
2747*61046927SAndroid Build Coastguard Worker (A6XX_RB_SAMPLE_LOCATION_0_SAMPLE_0_X(x) |
2748*61046927SAndroid Build Coastguard Worker A6XX_RB_SAMPLE_LOCATION_0_SAMPLE_0_Y(y)) << i*8;
2749*61046927SAndroid Build Coastguard Worker }
2750*61046927SAndroid Build Coastguard Worker
2751*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_SAMPLE_LOCATION_0, 1);
2752*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, sample_locations);
2753*61046927SAndroid Build Coastguard Worker
2754*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, REG_A6XX_RB_SAMPLE_LOCATION_0, 1);
2755*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, sample_locations);
2756*61046927SAndroid Build Coastguard Worker
2757*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, REG_A6XX_SP_TP_SAMPLE_LOCATION_0, 1);
2758*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, sample_locations);
2759*61046927SAndroid Build Coastguard Worker }
2760*61046927SAndroid Build Coastguard Worker
2761*61046927SAndroid Build Coastguard Worker static const enum mesa_vk_dynamic_graphics_state tu_depth_bias_state[] = {
2762*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS,
2763*61046927SAndroid Build Coastguard Worker };
2764*61046927SAndroid Build Coastguard Worker
2765*61046927SAndroid Build Coastguard Worker template <chip CHIP>
2766*61046927SAndroid Build Coastguard Worker static unsigned
tu6_depth_bias_size(struct tu_device * dev,const struct vk_rasterization_state * rs)2767*61046927SAndroid Build Coastguard Worker tu6_depth_bias_size(struct tu_device *dev,
2768*61046927SAndroid Build Coastguard Worker const struct vk_rasterization_state *rs)
2769*61046927SAndroid Build Coastguard Worker {
2770*61046927SAndroid Build Coastguard Worker return 4;
2771*61046927SAndroid Build Coastguard Worker }
2772*61046927SAndroid Build Coastguard Worker
2773*61046927SAndroid Build Coastguard Worker template <chip CHIP>
2774*61046927SAndroid Build Coastguard Worker void
tu6_emit_depth_bias(struct tu_cs * cs,const struct vk_rasterization_state * rs)2775*61046927SAndroid Build Coastguard Worker tu6_emit_depth_bias(struct tu_cs *cs, const struct vk_rasterization_state *rs)
2776*61046927SAndroid Build Coastguard Worker {
2777*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_SU_POLY_OFFSET_SCALE, 3);
2778*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, A6XX_GRAS_SU_POLY_OFFSET_SCALE(rs->depth_bias.slope).value);
2779*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, A6XX_GRAS_SU_POLY_OFFSET_OFFSET(rs->depth_bias.constant).value);
2780*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, A6XX_GRAS_SU_POLY_OFFSET_OFFSET_CLAMP(rs->depth_bias.clamp).value);
2781*61046927SAndroid Build Coastguard Worker }
2782*61046927SAndroid Build Coastguard Worker
2783*61046927SAndroid Build Coastguard Worker static const enum mesa_vk_dynamic_graphics_state tu_bandwidth_state[] = {
2784*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_CB_LOGIC_OP_ENABLE,
2785*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_CB_LOGIC_OP,
2786*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_CB_ATTACHMENT_COUNT,
2787*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES,
2788*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_CB_BLEND_ENABLES,
2789*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_CB_WRITE_MASKS,
2790*61046927SAndroid Build Coastguard Worker };
2791*61046927SAndroid Build Coastguard Worker
2792*61046927SAndroid Build Coastguard Worker static void
tu_calc_bandwidth(struct tu_bandwidth * bandwidth,const struct vk_color_blend_state * cb,const struct vk_render_pass_state * rp)2793*61046927SAndroid Build Coastguard Worker tu_calc_bandwidth(struct tu_bandwidth *bandwidth,
2794*61046927SAndroid Build Coastguard Worker const struct vk_color_blend_state *cb,
2795*61046927SAndroid Build Coastguard Worker const struct vk_render_pass_state *rp)
2796*61046927SAndroid Build Coastguard Worker {
2797*61046927SAndroid Build Coastguard Worker bool rop_reads_dst = cb->logic_op_enable && tu_logic_op_reads_dst((VkLogicOp)cb->logic_op);
2798*61046927SAndroid Build Coastguard Worker
2799*61046927SAndroid Build Coastguard Worker uint32_t total_bpp = 0;
2800*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < cb->attachment_count; i++) {
2801*61046927SAndroid Build Coastguard Worker const struct vk_color_blend_attachment_state *att = &cb->attachments[i];
2802*61046927SAndroid Build Coastguard Worker if (!(cb->color_write_enables & (1u << i)))
2803*61046927SAndroid Build Coastguard Worker continue;
2804*61046927SAndroid Build Coastguard Worker
2805*61046927SAndroid Build Coastguard Worker const VkFormat format = rp->color_attachment_formats[i];
2806*61046927SAndroid Build Coastguard Worker
2807*61046927SAndroid Build Coastguard Worker uint32_t write_bpp = 0;
2808*61046927SAndroid Build Coastguard Worker if (format == VK_FORMAT_UNDEFINED) {
2809*61046927SAndroid Build Coastguard Worker /* do nothing */
2810*61046927SAndroid Build Coastguard Worker } else if (att->write_mask == 0xf) {
2811*61046927SAndroid Build Coastguard Worker write_bpp = vk_format_get_blocksizebits(format);
2812*61046927SAndroid Build Coastguard Worker } else {
2813*61046927SAndroid Build Coastguard Worker const enum pipe_format pipe_format = vk_format_to_pipe_format(format);
2814*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < 4; i++) {
2815*61046927SAndroid Build Coastguard Worker if (att->write_mask & (1 << i)) {
2816*61046927SAndroid Build Coastguard Worker write_bpp += util_format_get_component_bits(pipe_format,
2817*61046927SAndroid Build Coastguard Worker UTIL_FORMAT_COLORSPACE_RGB, i);
2818*61046927SAndroid Build Coastguard Worker }
2819*61046927SAndroid Build Coastguard Worker }
2820*61046927SAndroid Build Coastguard Worker }
2821*61046927SAndroid Build Coastguard Worker total_bpp += write_bpp;
2822*61046927SAndroid Build Coastguard Worker
2823*61046927SAndroid Build Coastguard Worker if (rop_reads_dst || att->blend_enable) {
2824*61046927SAndroid Build Coastguard Worker total_bpp += write_bpp;
2825*61046927SAndroid Build Coastguard Worker }
2826*61046927SAndroid Build Coastguard Worker }
2827*61046927SAndroid Build Coastguard Worker
2828*61046927SAndroid Build Coastguard Worker bandwidth->color_bandwidth_per_sample = total_bpp / 8;
2829*61046927SAndroid Build Coastguard Worker
2830*61046927SAndroid Build Coastguard Worker if (rp->attachments & MESA_VK_RP_ATTACHMENT_DEPTH_BIT) {
2831*61046927SAndroid Build Coastguard Worker bandwidth->depth_cpp_per_sample = util_format_get_component_bits(
2832*61046927SAndroid Build Coastguard Worker vk_format_to_pipe_format(rp->depth_attachment_format),
2833*61046927SAndroid Build Coastguard Worker UTIL_FORMAT_COLORSPACE_ZS, 0) / 8;
2834*61046927SAndroid Build Coastguard Worker }
2835*61046927SAndroid Build Coastguard Worker
2836*61046927SAndroid Build Coastguard Worker if (rp->attachments & MESA_VK_RP_ATTACHMENT_STENCIL_BIT) {
2837*61046927SAndroid Build Coastguard Worker bandwidth->stencil_cpp_per_sample = util_format_get_component_bits(
2838*61046927SAndroid Build Coastguard Worker vk_format_to_pipe_format(rp->stencil_attachment_format),
2839*61046927SAndroid Build Coastguard Worker UTIL_FORMAT_COLORSPACE_ZS, 1) / 8;
2840*61046927SAndroid Build Coastguard Worker }
2841*61046927SAndroid Build Coastguard Worker }
2842*61046927SAndroid Build Coastguard Worker
2843*61046927SAndroid Build Coastguard Worker /* Return true if the blend state reads the color attachments. */
2844*61046927SAndroid Build Coastguard Worker static bool
tu6_calc_blend_lrz(const struct vk_color_blend_state * cb,const struct vk_render_pass_state * rp)2845*61046927SAndroid Build Coastguard Worker tu6_calc_blend_lrz(const struct vk_color_blend_state *cb,
2846*61046927SAndroid Build Coastguard Worker const struct vk_render_pass_state *rp)
2847*61046927SAndroid Build Coastguard Worker {
2848*61046927SAndroid Build Coastguard Worker if (cb->logic_op_enable && tu_logic_op_reads_dst((VkLogicOp)cb->logic_op))
2849*61046927SAndroid Build Coastguard Worker return true;
2850*61046927SAndroid Build Coastguard Worker
2851*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < cb->attachment_count; i++) {
2852*61046927SAndroid Build Coastguard Worker if (rp->color_attachment_formats[i] == VK_FORMAT_UNDEFINED)
2853*61046927SAndroid Build Coastguard Worker continue;
2854*61046927SAndroid Build Coastguard Worker
2855*61046927SAndroid Build Coastguard Worker const struct vk_color_blend_attachment_state *att = &cb->attachments[i];
2856*61046927SAndroid Build Coastguard Worker if (att->blend_enable)
2857*61046927SAndroid Build Coastguard Worker return true;
2858*61046927SAndroid Build Coastguard Worker if (!(cb->color_write_enables & (1u << i)))
2859*61046927SAndroid Build Coastguard Worker return true;
2860*61046927SAndroid Build Coastguard Worker unsigned mask =
2861*61046927SAndroid Build Coastguard Worker MASK(vk_format_get_nr_components(rp->color_attachment_formats[i]));
2862*61046927SAndroid Build Coastguard Worker if ((att->write_mask & mask) != mask)
2863*61046927SAndroid Build Coastguard Worker return true;
2864*61046927SAndroid Build Coastguard Worker }
2865*61046927SAndroid Build Coastguard Worker
2866*61046927SAndroid Build Coastguard Worker return false;
2867*61046927SAndroid Build Coastguard Worker }
2868*61046927SAndroid Build Coastguard Worker
2869*61046927SAndroid Build Coastguard Worker static const enum mesa_vk_dynamic_graphics_state tu_blend_lrz_state[] = {
2870*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_CB_LOGIC_OP_ENABLE,
2871*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_CB_LOGIC_OP,
2872*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_CB_ATTACHMENT_COUNT,
2873*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES,
2874*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_CB_BLEND_ENABLES,
2875*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_CB_WRITE_MASKS,
2876*61046927SAndroid Build Coastguard Worker };
2877*61046927SAndroid Build Coastguard Worker
2878*61046927SAndroid Build Coastguard Worker static void
tu_emit_blend_lrz(struct tu_lrz_blend * lrz,const struct vk_color_blend_state * cb,const struct vk_render_pass_state * rp)2879*61046927SAndroid Build Coastguard Worker tu_emit_blend_lrz(struct tu_lrz_blend *lrz,
2880*61046927SAndroid Build Coastguard Worker const struct vk_color_blend_state *cb,
2881*61046927SAndroid Build Coastguard Worker const struct vk_render_pass_state *rp)
2882*61046927SAndroid Build Coastguard Worker {
2883*61046927SAndroid Build Coastguard Worker lrz->reads_dest = tu6_calc_blend_lrz(cb, rp);
2884*61046927SAndroid Build Coastguard Worker lrz->valid = true;
2885*61046927SAndroid Build Coastguard Worker }
2886*61046927SAndroid Build Coastguard Worker
2887*61046927SAndroid Build Coastguard Worker static const enum mesa_vk_dynamic_graphics_state tu_blend_state[] = {
2888*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_CB_LOGIC_OP_ENABLE,
2889*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_CB_LOGIC_OP,
2890*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_CB_ATTACHMENT_COUNT,
2891*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES,
2892*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_CB_BLEND_ENABLES,
2893*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_CB_BLEND_EQUATIONS,
2894*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_CB_WRITE_MASKS,
2895*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_MS_ALPHA_TO_COVERAGE_ENABLE,
2896*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_MS_ALPHA_TO_ONE_ENABLE,
2897*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_MS_SAMPLE_MASK,
2898*61046927SAndroid Build Coastguard Worker };
2899*61046927SAndroid Build Coastguard Worker
2900*61046927SAndroid Build Coastguard Worker template <chip CHIP>
2901*61046927SAndroid Build Coastguard Worker static unsigned
tu6_blend_size(struct tu_device * dev,const struct vk_color_blend_state * cb,bool alpha_to_coverage_enable,bool alpha_to_one_enable,uint32_t sample_mask)2902*61046927SAndroid Build Coastguard Worker tu6_blend_size(struct tu_device *dev,
2903*61046927SAndroid Build Coastguard Worker const struct vk_color_blend_state *cb,
2904*61046927SAndroid Build Coastguard Worker bool alpha_to_coverage_enable,
2905*61046927SAndroid Build Coastguard Worker bool alpha_to_one_enable,
2906*61046927SAndroid Build Coastguard Worker uint32_t sample_mask)
2907*61046927SAndroid Build Coastguard Worker {
2908*61046927SAndroid Build Coastguard Worker unsigned num_rts = alpha_to_coverage_enable ?
2909*61046927SAndroid Build Coastguard Worker MAX2(cb->attachment_count, 1) : cb->attachment_count;
2910*61046927SAndroid Build Coastguard Worker return 8 + 3 * num_rts;
2911*61046927SAndroid Build Coastguard Worker }
2912*61046927SAndroid Build Coastguard Worker
2913*61046927SAndroid Build Coastguard Worker template <chip CHIP>
2914*61046927SAndroid Build Coastguard Worker static void
tu6_emit_blend(struct tu_cs * cs,const struct vk_color_blend_state * cb,bool alpha_to_coverage_enable,bool alpha_to_one_enable,uint32_t sample_mask)2915*61046927SAndroid Build Coastguard Worker tu6_emit_blend(struct tu_cs *cs,
2916*61046927SAndroid Build Coastguard Worker const struct vk_color_blend_state *cb,
2917*61046927SAndroid Build Coastguard Worker bool alpha_to_coverage_enable,
2918*61046927SAndroid Build Coastguard Worker bool alpha_to_one_enable,
2919*61046927SAndroid Build Coastguard Worker uint32_t sample_mask)
2920*61046927SAndroid Build Coastguard Worker {
2921*61046927SAndroid Build Coastguard Worker bool rop_reads_dst = cb->logic_op_enable && tu_logic_op_reads_dst((VkLogicOp)cb->logic_op);
2922*61046927SAndroid Build Coastguard Worker enum a3xx_rop_code rop = tu6_rop((VkLogicOp)cb->logic_op);
2923*61046927SAndroid Build Coastguard Worker
2924*61046927SAndroid Build Coastguard Worker uint32_t blend_enable_mask = 0;
2925*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < cb->attachment_count; i++) {
2926*61046927SAndroid Build Coastguard Worker const struct vk_color_blend_attachment_state *att = &cb->attachments[i];
2927*61046927SAndroid Build Coastguard Worker if (!(cb->color_write_enables & (1u << i)))
2928*61046927SAndroid Build Coastguard Worker continue;
2929*61046927SAndroid Build Coastguard Worker
2930*61046927SAndroid Build Coastguard Worker if (rop_reads_dst || att->blend_enable) {
2931*61046927SAndroid Build Coastguard Worker blend_enable_mask |= 1u << i;
2932*61046927SAndroid Build Coastguard Worker }
2933*61046927SAndroid Build Coastguard Worker }
2934*61046927SAndroid Build Coastguard Worker
2935*61046927SAndroid Build Coastguard Worker /* This will emit a dummy RB_MRT_*_CONTROL below if alpha-to-coverage is
2936*61046927SAndroid Build Coastguard Worker * enabled but there are no color attachments, in addition to changing
2937*61046927SAndroid Build Coastguard Worker * *_FS_OUTPUT_CNTL1.
2938*61046927SAndroid Build Coastguard Worker */
2939*61046927SAndroid Build Coastguard Worker unsigned num_rts = alpha_to_coverage_enable ?
2940*61046927SAndroid Build Coastguard Worker MAX2(cb->attachment_count, 1) : cb->attachment_count;
2941*61046927SAndroid Build Coastguard Worker
2942*61046927SAndroid Build Coastguard Worker bool dual_src_blend = tu_blend_state_is_dual_src(cb);
2943*61046927SAndroid Build Coastguard Worker
2944*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs, A6XX_SP_FS_OUTPUT_CNTL1(.mrt = num_rts));
2945*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs, A6XX_RB_FS_OUTPUT_CNTL1(.mrt = num_rts));
2946*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs, A6XX_SP_BLEND_CNTL(.enable_blend = blend_enable_mask,
2947*61046927SAndroid Build Coastguard Worker .unk8 = true,
2948*61046927SAndroid Build Coastguard Worker .dual_color_in_enable =
2949*61046927SAndroid Build Coastguard Worker dual_src_blend,
2950*61046927SAndroid Build Coastguard Worker .alpha_to_coverage =
2951*61046927SAndroid Build Coastguard Worker alpha_to_coverage_enable));
2952*61046927SAndroid Build Coastguard Worker /* set A6XX_RB_BLEND_CNTL_INDEPENDENT_BLEND only when enabled? */
2953*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs, A6XX_RB_BLEND_CNTL(.enable_blend = blend_enable_mask,
2954*61046927SAndroid Build Coastguard Worker .independent_blend = true,
2955*61046927SAndroid Build Coastguard Worker .dual_color_in_enable =
2956*61046927SAndroid Build Coastguard Worker dual_src_blend,
2957*61046927SAndroid Build Coastguard Worker .alpha_to_coverage =
2958*61046927SAndroid Build Coastguard Worker alpha_to_coverage_enable,
2959*61046927SAndroid Build Coastguard Worker .alpha_to_one = alpha_to_one_enable,
2960*61046927SAndroid Build Coastguard Worker .sample_mask = sample_mask));
2961*61046927SAndroid Build Coastguard Worker
2962*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_rts; i++) {
2963*61046927SAndroid Build Coastguard Worker const struct vk_color_blend_attachment_state *att = &cb->attachments[i];
2964*61046927SAndroid Build Coastguard Worker if ((cb->color_write_enables & (1u << i)) && i < cb->attachment_count) {
2965*61046927SAndroid Build Coastguard Worker const enum a3xx_rb_blend_opcode color_op = tu6_blend_op(att->color_blend_op);
2966*61046927SAndroid Build Coastguard Worker const enum adreno_rb_blend_factor src_color_factor =
2967*61046927SAndroid Build Coastguard Worker tu6_blend_factor((VkBlendFactor)att->src_color_blend_factor);
2968*61046927SAndroid Build Coastguard Worker const enum adreno_rb_blend_factor dst_color_factor =
2969*61046927SAndroid Build Coastguard Worker tu6_blend_factor((VkBlendFactor)att->dst_color_blend_factor);
2970*61046927SAndroid Build Coastguard Worker const enum a3xx_rb_blend_opcode alpha_op =
2971*61046927SAndroid Build Coastguard Worker tu6_blend_op(att->alpha_blend_op);
2972*61046927SAndroid Build Coastguard Worker const enum adreno_rb_blend_factor src_alpha_factor =
2973*61046927SAndroid Build Coastguard Worker tu6_blend_factor((VkBlendFactor)att->src_alpha_blend_factor);
2974*61046927SAndroid Build Coastguard Worker const enum adreno_rb_blend_factor dst_alpha_factor =
2975*61046927SAndroid Build Coastguard Worker tu6_blend_factor((VkBlendFactor)att->dst_alpha_blend_factor);
2976*61046927SAndroid Build Coastguard Worker
2977*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs,
2978*61046927SAndroid Build Coastguard Worker A6XX_RB_MRT_CONTROL(i,
2979*61046927SAndroid Build Coastguard Worker .blend = att->blend_enable,
2980*61046927SAndroid Build Coastguard Worker .blend2 = att->blend_enable,
2981*61046927SAndroid Build Coastguard Worker .rop_enable = cb->logic_op_enable,
2982*61046927SAndroid Build Coastguard Worker .rop_code = rop,
2983*61046927SAndroid Build Coastguard Worker .component_enable = att->write_mask),
2984*61046927SAndroid Build Coastguard Worker A6XX_RB_MRT_BLEND_CONTROL(i,
2985*61046927SAndroid Build Coastguard Worker .rgb_src_factor = src_color_factor,
2986*61046927SAndroid Build Coastguard Worker .rgb_blend_opcode = color_op,
2987*61046927SAndroid Build Coastguard Worker .rgb_dest_factor = dst_color_factor,
2988*61046927SAndroid Build Coastguard Worker .alpha_src_factor = src_alpha_factor,
2989*61046927SAndroid Build Coastguard Worker .alpha_blend_opcode = alpha_op,
2990*61046927SAndroid Build Coastguard Worker .alpha_dest_factor = dst_alpha_factor));
2991*61046927SAndroid Build Coastguard Worker } else {
2992*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs,
2993*61046927SAndroid Build Coastguard Worker A6XX_RB_MRT_CONTROL(i,),
2994*61046927SAndroid Build Coastguard Worker A6XX_RB_MRT_BLEND_CONTROL(i,));
2995*61046927SAndroid Build Coastguard Worker }
2996*61046927SAndroid Build Coastguard Worker }
2997*61046927SAndroid Build Coastguard Worker }
2998*61046927SAndroid Build Coastguard Worker
2999*61046927SAndroid Build Coastguard Worker static const enum mesa_vk_dynamic_graphics_state tu_blend_constants_state[] = {
3000*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS,
3001*61046927SAndroid Build Coastguard Worker };
3002*61046927SAndroid Build Coastguard Worker
3003*61046927SAndroid Build Coastguard Worker template <chip CHIP>
3004*61046927SAndroid Build Coastguard Worker static unsigned
tu6_blend_constants_size(struct tu_device * dev,const struct vk_color_blend_state * cb)3005*61046927SAndroid Build Coastguard Worker tu6_blend_constants_size(struct tu_device *dev,
3006*61046927SAndroid Build Coastguard Worker const struct vk_color_blend_state *cb)
3007*61046927SAndroid Build Coastguard Worker {
3008*61046927SAndroid Build Coastguard Worker return 5;
3009*61046927SAndroid Build Coastguard Worker }
3010*61046927SAndroid Build Coastguard Worker
3011*61046927SAndroid Build Coastguard Worker template <chip CHIP>
3012*61046927SAndroid Build Coastguard Worker static void
tu6_emit_blend_constants(struct tu_cs * cs,const struct vk_color_blend_state * cb)3013*61046927SAndroid Build Coastguard Worker tu6_emit_blend_constants(struct tu_cs *cs, const struct vk_color_blend_state *cb)
3014*61046927SAndroid Build Coastguard Worker {
3015*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLEND_RED_F32, 4);
3016*61046927SAndroid Build Coastguard Worker tu_cs_emit_array(cs, (const uint32_t *) cb->blend_constants, 4);
3017*61046927SAndroid Build Coastguard Worker }
3018*61046927SAndroid Build Coastguard Worker
3019*61046927SAndroid Build Coastguard Worker static const enum mesa_vk_dynamic_graphics_state tu_rast_state[] = {
3020*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_RS_DEPTH_CLAMP_ENABLE,
3021*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_RS_DEPTH_CLIP_ENABLE,
3022*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_RS_POLYGON_MODE,
3023*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_RS_CULL_MODE,
3024*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_RS_FRONT_FACE,
3025*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_RS_DEPTH_BIAS_ENABLE,
3026*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_RS_LINE_MODE,
3027*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_RS_RASTERIZER_DISCARD_ENABLE,
3028*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_RS_RASTERIZATION_STREAM,
3029*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_VP_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE,
3030*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_RS_LINE_WIDTH,
3031*61046927SAndroid Build Coastguard Worker };
3032*61046927SAndroid Build Coastguard Worker
3033*61046927SAndroid Build Coastguard Worker template <chip CHIP>
3034*61046927SAndroid Build Coastguard Worker uint32_t
tu6_rast_size(struct tu_device * dev,const struct vk_rasterization_state * rs,const struct vk_viewport_state * vp,bool multiview,bool per_view_viewport)3035*61046927SAndroid Build Coastguard Worker tu6_rast_size(struct tu_device *dev,
3036*61046927SAndroid Build Coastguard Worker const struct vk_rasterization_state *rs,
3037*61046927SAndroid Build Coastguard Worker const struct vk_viewport_state *vp,
3038*61046927SAndroid Build Coastguard Worker bool multiview,
3039*61046927SAndroid Build Coastguard Worker bool per_view_viewport)
3040*61046927SAndroid Build Coastguard Worker {
3041*61046927SAndroid Build Coastguard Worker if (CHIP == A6XX) {
3042*61046927SAndroid Build Coastguard Worker return 15 + (dev->physical_device->info->a6xx.has_shading_rate ? 8 : 0);
3043*61046927SAndroid Build Coastguard Worker } else {
3044*61046927SAndroid Build Coastguard Worker return 17;
3045*61046927SAndroid Build Coastguard Worker }
3046*61046927SAndroid Build Coastguard Worker }
3047*61046927SAndroid Build Coastguard Worker
3048*61046927SAndroid Build Coastguard Worker template <chip CHIP>
3049*61046927SAndroid Build Coastguard Worker void
tu6_emit_rast(struct tu_cs * cs,const struct vk_rasterization_state * rs,const struct vk_viewport_state * vp,bool multiview,bool per_view_viewport)3050*61046927SAndroid Build Coastguard Worker tu6_emit_rast(struct tu_cs *cs,
3051*61046927SAndroid Build Coastguard Worker const struct vk_rasterization_state *rs,
3052*61046927SAndroid Build Coastguard Worker const struct vk_viewport_state *vp,
3053*61046927SAndroid Build Coastguard Worker bool multiview,
3054*61046927SAndroid Build Coastguard Worker bool per_view_viewport)
3055*61046927SAndroid Build Coastguard Worker {
3056*61046927SAndroid Build Coastguard Worker enum a5xx_line_mode line_mode =
3057*61046927SAndroid Build Coastguard Worker rs->line.mode == VK_LINE_RASTERIZATION_MODE_BRESENHAM_KHR ?
3058*61046927SAndroid Build Coastguard Worker BRESENHAM : RECTANGULAR;
3059*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs,
3060*61046927SAndroid Build Coastguard Worker A6XX_GRAS_SU_CNTL(
3061*61046927SAndroid Build Coastguard Worker .cull_front = rs->cull_mode & VK_CULL_MODE_FRONT_BIT,
3062*61046927SAndroid Build Coastguard Worker .cull_back = rs->cull_mode & VK_CULL_MODE_BACK_BIT,
3063*61046927SAndroid Build Coastguard Worker .front_cw = rs->front_face == VK_FRONT_FACE_CLOCKWISE,
3064*61046927SAndroid Build Coastguard Worker .linehalfwidth = rs->line.width / 2.0f,
3065*61046927SAndroid Build Coastguard Worker .poly_offset = rs->depth_bias.enable,
3066*61046927SAndroid Build Coastguard Worker .line_mode = line_mode,
3067*61046927SAndroid Build Coastguard Worker .multiview_enable = multiview,
3068*61046927SAndroid Build Coastguard Worker .rendertargetindexincr = multiview,
3069*61046927SAndroid Build Coastguard Worker .viewportindexincr = multiview && per_view_viewport));
3070*61046927SAndroid Build Coastguard Worker
3071*61046927SAndroid Build Coastguard Worker bool depth_clip_enable = vk_rasterization_state_depth_clip_enable(rs);
3072*61046927SAndroid Build Coastguard Worker
3073*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs,
3074*61046927SAndroid Build Coastguard Worker A6XX_GRAS_CL_CNTL(
3075*61046927SAndroid Build Coastguard Worker .znear_clip_disable = !depth_clip_enable,
3076*61046927SAndroid Build Coastguard Worker .zfar_clip_disable = !depth_clip_enable,
3077*61046927SAndroid Build Coastguard Worker /* To support VK_EXT_depth_clamp_zero_one on a7xx+ */
3078*61046927SAndroid Build Coastguard Worker .z_clamp_enable = rs->depth_clamp_enable || CHIP >= A7XX,
3079*61046927SAndroid Build Coastguard Worker .zero_gb_scale_z = vp->depth_clip_negative_one_to_one ? 0 : 1,
3080*61046927SAndroid Build Coastguard Worker .vp_clip_code_ignore = 1));;
3081*61046927SAndroid Build Coastguard Worker
3082*61046927SAndroid Build Coastguard Worker enum a6xx_polygon_mode polygon_mode = tu6_polygon_mode(rs->polygon_mode);
3083*61046927SAndroid Build Coastguard Worker
3084*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs,
3085*61046927SAndroid Build Coastguard Worker A6XX_VPC_POLYGON_MODE(polygon_mode));
3086*61046927SAndroid Build Coastguard Worker
3087*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs,
3088*61046927SAndroid Build Coastguard Worker PC_POLYGON_MODE(CHIP, polygon_mode));
3089*61046927SAndroid Build Coastguard Worker
3090*61046927SAndroid Build Coastguard Worker if (CHIP == A7XX) {
3091*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs,
3092*61046927SAndroid Build Coastguard Worker A7XX_VPC_POLYGON_MODE2(polygon_mode));
3093*61046927SAndroid Build Coastguard Worker }
3094*61046927SAndroid Build Coastguard Worker
3095*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs, PC_RASTER_CNTL(CHIP,
3096*61046927SAndroid Build Coastguard Worker .stream = rs->rasterization_stream,
3097*61046927SAndroid Build Coastguard Worker .discard = rs->rasterizer_discard_enable));
3098*61046927SAndroid Build Coastguard Worker if (CHIP == A6XX) {
3099*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs, A6XX_VPC_UNKNOWN_9107(
3100*61046927SAndroid Build Coastguard Worker .raster_discard = rs->rasterizer_discard_enable));
3101*61046927SAndroid Build Coastguard Worker } else {
3102*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs, A7XX_PC_RASTER_CNTL_V2(
3103*61046927SAndroid Build Coastguard Worker .stream = rs->rasterization_stream,
3104*61046927SAndroid Build Coastguard Worker .discard = rs->rasterizer_discard_enable));
3105*61046927SAndroid Build Coastguard Worker }
3106*61046927SAndroid Build Coastguard Worker
3107*61046927SAndroid Build Coastguard Worker /* move to hw ctx init? */
3108*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs,
3109*61046927SAndroid Build Coastguard Worker A6XX_GRAS_SU_POINT_MINMAX(.min = 1.0f / 16.0f, .max = 4092.0f),
3110*61046927SAndroid Build Coastguard Worker A6XX_GRAS_SU_POINT_SIZE(1.0f));
3111*61046927SAndroid Build Coastguard Worker
3112*61046927SAndroid Build Coastguard Worker if (CHIP == A6XX && cs->device->physical_device->info->a6xx.has_shading_rate) {
3113*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs, A6XX_RB_UNKNOWN_8A00());
3114*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs, A6XX_RB_UNKNOWN_8A10());
3115*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs, A6XX_RB_UNKNOWN_8A20());
3116*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs, A6XX_RB_UNKNOWN_8A30());
3117*61046927SAndroid Build Coastguard Worker }
3118*61046927SAndroid Build Coastguard Worker }
3119*61046927SAndroid Build Coastguard Worker
3120*61046927SAndroid Build Coastguard Worker static const enum mesa_vk_dynamic_graphics_state tu_ds_state[] = {
3121*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE,
3122*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_DS_STENCIL_OP,
3123*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK,
3124*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK,
3125*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE,
3126*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_BOUNDS,
3127*61046927SAndroid Build Coastguard Worker };
3128*61046927SAndroid Build Coastguard Worker
3129*61046927SAndroid Build Coastguard Worker template <chip CHIP>
3130*61046927SAndroid Build Coastguard Worker static unsigned
tu6_ds_size(struct tu_device * dev,const struct vk_depth_stencil_state * ds,const struct vk_render_pass_state * rp)3131*61046927SAndroid Build Coastguard Worker tu6_ds_size(struct tu_device *dev,
3132*61046927SAndroid Build Coastguard Worker const struct vk_depth_stencil_state *ds,
3133*61046927SAndroid Build Coastguard Worker const struct vk_render_pass_state *rp)
3134*61046927SAndroid Build Coastguard Worker {
3135*61046927SAndroid Build Coastguard Worker return 13;
3136*61046927SAndroid Build Coastguard Worker }
3137*61046927SAndroid Build Coastguard Worker
3138*61046927SAndroid Build Coastguard Worker template <chip CHIP>
3139*61046927SAndroid Build Coastguard Worker static void
tu6_emit_ds(struct tu_cs * cs,const struct vk_depth_stencil_state * ds,const struct vk_render_pass_state * rp)3140*61046927SAndroid Build Coastguard Worker tu6_emit_ds(struct tu_cs *cs,
3141*61046927SAndroid Build Coastguard Worker const struct vk_depth_stencil_state *ds,
3142*61046927SAndroid Build Coastguard Worker const struct vk_render_pass_state *rp)
3143*61046927SAndroid Build Coastguard Worker {
3144*61046927SAndroid Build Coastguard Worker bool stencil_test_enable =
3145*61046927SAndroid Build Coastguard Worker ds->stencil.test_enable && rp->attachments & MESA_VK_RP_ATTACHMENT_STENCIL_BIT;
3146*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs, A6XX_RB_STENCIL_CONTROL(
3147*61046927SAndroid Build Coastguard Worker .stencil_enable = stencil_test_enable,
3148*61046927SAndroid Build Coastguard Worker .stencil_enable_bf = stencil_test_enable,
3149*61046927SAndroid Build Coastguard Worker .stencil_read = stencil_test_enable,
3150*61046927SAndroid Build Coastguard Worker .func = tu6_compare_func((VkCompareOp)ds->stencil.front.op.compare),
3151*61046927SAndroid Build Coastguard Worker .fail = tu6_stencil_op((VkStencilOp)ds->stencil.front.op.fail),
3152*61046927SAndroid Build Coastguard Worker .zpass = tu6_stencil_op((VkStencilOp)ds->stencil.front.op.pass),
3153*61046927SAndroid Build Coastguard Worker .zfail = tu6_stencil_op((VkStencilOp)ds->stencil.front.op.depth_fail),
3154*61046927SAndroid Build Coastguard Worker .func_bf = tu6_compare_func((VkCompareOp)ds->stencil.back.op.compare),
3155*61046927SAndroid Build Coastguard Worker .fail_bf = tu6_stencil_op((VkStencilOp)ds->stencil.back.op.fail),
3156*61046927SAndroid Build Coastguard Worker .zpass_bf = tu6_stencil_op((VkStencilOp)ds->stencil.back.op.pass),
3157*61046927SAndroid Build Coastguard Worker .zfail_bf = tu6_stencil_op((VkStencilOp)ds->stencil.back.op.depth_fail)));
3158*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs, A6XX_GRAS_SU_STENCIL_CNTL(stencil_test_enable));
3159*61046927SAndroid Build Coastguard Worker
3160*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs, A6XX_RB_STENCILMASK(
3161*61046927SAndroid Build Coastguard Worker .mask = ds->stencil.front.compare_mask,
3162*61046927SAndroid Build Coastguard Worker .bfmask = ds->stencil.back.compare_mask));
3163*61046927SAndroid Build Coastguard Worker
3164*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs, A6XX_RB_STENCILWRMASK(
3165*61046927SAndroid Build Coastguard Worker .wrmask = ds->stencil.front.write_mask,
3166*61046927SAndroid Build Coastguard Worker .bfwrmask = ds->stencil.back.write_mask));
3167*61046927SAndroid Build Coastguard Worker
3168*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs, A6XX_RB_STENCILREF(
3169*61046927SAndroid Build Coastguard Worker .ref = ds->stencil.front.reference,
3170*61046927SAndroid Build Coastguard Worker .bfref = ds->stencil.back.reference));
3171*61046927SAndroid Build Coastguard Worker
3172*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs,
3173*61046927SAndroid Build Coastguard Worker A6XX_RB_Z_BOUNDS_MIN(ds->depth.bounds_test.min),
3174*61046927SAndroid Build Coastguard Worker A6XX_RB_Z_BOUNDS_MAX(ds->depth.bounds_test.max));
3175*61046927SAndroid Build Coastguard Worker }
3176*61046927SAndroid Build Coastguard Worker
3177*61046927SAndroid Build Coastguard Worker static const enum mesa_vk_dynamic_graphics_state tu_rb_depth_cntl_state[] = {
3178*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_DS_DEPTH_TEST_ENABLE,
3179*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_DS_DEPTH_WRITE_ENABLE,
3180*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_DS_DEPTH_COMPARE_OP,
3181*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_ENABLE,
3182*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_RS_DEPTH_CLAMP_ENABLE,
3183*61046927SAndroid Build Coastguard Worker };
3184*61046927SAndroid Build Coastguard Worker
3185*61046927SAndroid Build Coastguard Worker template <chip CHIP>
3186*61046927SAndroid Build Coastguard Worker static unsigned
tu6_rb_depth_cntl_size(struct tu_device * dev,const struct vk_depth_stencil_state * ds,const struct vk_render_pass_state * rp,const struct vk_rasterization_state * rs)3187*61046927SAndroid Build Coastguard Worker tu6_rb_depth_cntl_size(struct tu_device *dev,
3188*61046927SAndroid Build Coastguard Worker const struct vk_depth_stencil_state *ds,
3189*61046927SAndroid Build Coastguard Worker const struct vk_render_pass_state *rp,
3190*61046927SAndroid Build Coastguard Worker const struct vk_rasterization_state *rs)
3191*61046927SAndroid Build Coastguard Worker {
3192*61046927SAndroid Build Coastguard Worker return 4;
3193*61046927SAndroid Build Coastguard Worker }
3194*61046927SAndroid Build Coastguard Worker
3195*61046927SAndroid Build Coastguard Worker template <chip CHIP>
3196*61046927SAndroid Build Coastguard Worker static void
tu6_emit_rb_depth_cntl(struct tu_cs * cs,const struct vk_depth_stencil_state * ds,const struct vk_render_pass_state * rp,const struct vk_rasterization_state * rs)3197*61046927SAndroid Build Coastguard Worker tu6_emit_rb_depth_cntl(struct tu_cs *cs,
3198*61046927SAndroid Build Coastguard Worker const struct vk_depth_stencil_state *ds,
3199*61046927SAndroid Build Coastguard Worker const struct vk_render_pass_state *rp,
3200*61046927SAndroid Build Coastguard Worker const struct vk_rasterization_state *rs)
3201*61046927SAndroid Build Coastguard Worker {
3202*61046927SAndroid Build Coastguard Worker if (rp->attachments & MESA_VK_RP_ATTACHMENT_DEPTH_BIT) {
3203*61046927SAndroid Build Coastguard Worker bool depth_test = ds->depth.test_enable;
3204*61046927SAndroid Build Coastguard Worker enum adreno_compare_func zfunc = tu6_compare_func(ds->depth.compare_op);
3205*61046927SAndroid Build Coastguard Worker
3206*61046927SAndroid Build Coastguard Worker /* On some GPUs it is necessary to enable z test for depth bounds test
3207*61046927SAndroid Build Coastguard Worker * when UBWC is enabled. Otherwise, the GPU would hang. FUNC_ALWAYS is
3208*61046927SAndroid Build Coastguard Worker * required to pass z test. Relevant tests:
3209*61046927SAndroid Build Coastguard Worker * dEQP-VK.pipeline.extended_dynamic_state.two_draws_dynamic.depth_bounds_test_disable
3210*61046927SAndroid Build Coastguard Worker * dEQP-VK.dynamic_state.ds_state.depth_bounds_1
3211*61046927SAndroid Build Coastguard Worker */
3212*61046927SAndroid Build Coastguard Worker if (ds->depth.bounds_test.enable &&
3213*61046927SAndroid Build Coastguard Worker !ds->depth.test_enable &&
3214*61046927SAndroid Build Coastguard Worker cs->device->physical_device->info->a6xx.depth_bounds_require_depth_test_quirk) {
3215*61046927SAndroid Build Coastguard Worker depth_test = true;
3216*61046927SAndroid Build Coastguard Worker zfunc = FUNC_ALWAYS;
3217*61046927SAndroid Build Coastguard Worker }
3218*61046927SAndroid Build Coastguard Worker
3219*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs, A6XX_RB_DEPTH_CNTL(
3220*61046927SAndroid Build Coastguard Worker .z_test_enable = depth_test,
3221*61046927SAndroid Build Coastguard Worker .z_write_enable = ds->depth.test_enable && ds->depth.write_enable,
3222*61046927SAndroid Build Coastguard Worker .zfunc = zfunc,
3223*61046927SAndroid Build Coastguard Worker /* To support VK_EXT_depth_clamp_zero_one on a7xx+ */
3224*61046927SAndroid Build Coastguard Worker .z_clamp_enable = rs->depth_clamp_enable || CHIP >= A7XX,
3225*61046927SAndroid Build Coastguard Worker /* TODO don't set for ALWAYS/NEVER */
3226*61046927SAndroid Build Coastguard Worker .z_read_enable = ds->depth.test_enable || ds->depth.bounds_test.enable,
3227*61046927SAndroid Build Coastguard Worker .z_bounds_enable = ds->depth.bounds_test.enable));
3228*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs, A6XX_GRAS_SU_DEPTH_CNTL(depth_test));
3229*61046927SAndroid Build Coastguard Worker } else {
3230*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs, A6XX_RB_DEPTH_CNTL());
3231*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs, A6XX_GRAS_SU_DEPTH_CNTL());
3232*61046927SAndroid Build Coastguard Worker }
3233*61046927SAndroid Build Coastguard Worker }
3234*61046927SAndroid Build Coastguard Worker
3235*61046927SAndroid Build Coastguard Worker static const enum mesa_vk_dynamic_graphics_state tu_prim_mode_sysmem_state[] = {
3236*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_ATTACHMENT_FEEDBACK_LOOP_ENABLE,
3237*61046927SAndroid Build Coastguard Worker };
3238*61046927SAndroid Build Coastguard Worker
3239*61046927SAndroid Build Coastguard Worker template <chip CHIP>
3240*61046927SAndroid Build Coastguard Worker static unsigned
tu6_prim_mode_sysmem_size(struct tu_device * dev,bool raster_order_attachment_access,VkImageAspectFlags feedback_loops,bool * sysmem_single_prim_mode)3241*61046927SAndroid Build Coastguard Worker tu6_prim_mode_sysmem_size(struct tu_device *dev,
3242*61046927SAndroid Build Coastguard Worker bool raster_order_attachment_access,
3243*61046927SAndroid Build Coastguard Worker VkImageAspectFlags feedback_loops,
3244*61046927SAndroid Build Coastguard Worker bool *sysmem_single_prim_mode)
3245*61046927SAndroid Build Coastguard Worker {
3246*61046927SAndroid Build Coastguard Worker return 2;
3247*61046927SAndroid Build Coastguard Worker }
3248*61046927SAndroid Build Coastguard Worker
3249*61046927SAndroid Build Coastguard Worker template <chip CHIP>
3250*61046927SAndroid Build Coastguard Worker static void
tu6_emit_prim_mode_sysmem(struct tu_cs * cs,bool raster_order_attachment_access,VkImageAspectFlags feedback_loops,bool * sysmem_single_prim_mode)3251*61046927SAndroid Build Coastguard Worker tu6_emit_prim_mode_sysmem(struct tu_cs *cs,
3252*61046927SAndroid Build Coastguard Worker bool raster_order_attachment_access,
3253*61046927SAndroid Build Coastguard Worker VkImageAspectFlags feedback_loops,
3254*61046927SAndroid Build Coastguard Worker bool *sysmem_single_prim_mode)
3255*61046927SAndroid Build Coastguard Worker {
3256*61046927SAndroid Build Coastguard Worker /* VK_EXT_rasterization_order_attachment_access:
3257*61046927SAndroid Build Coastguard Worker *
3258*61046927SAndroid Build Coastguard Worker * This extension allow access to framebuffer attachments when used as both
3259*61046927SAndroid Build Coastguard Worker * input and color attachments from one fragment to the next, in
3260*61046927SAndroid Build Coastguard Worker * rasterization order, without explicit synchronization.
3261*61046927SAndroid Build Coastguard Worker */
3262*61046927SAndroid Build Coastguard Worker raster_order_attachment_access |= TU_DEBUG(RAST_ORDER);
3263*61046927SAndroid Build Coastguard Worker
3264*61046927SAndroid Build Coastguard Worker /* If there is a feedback loop, then the shader can read the previous value
3265*61046927SAndroid Build Coastguard Worker * of a pixel being written out. It can also write some components and then
3266*61046927SAndroid Build Coastguard Worker * read different components without a barrier in between. This is a
3267*61046927SAndroid Build Coastguard Worker * problem in sysmem mode with UBWC, because the main buffer and flags
3268*61046927SAndroid Build Coastguard Worker * buffer can get out-of-sync if only one is flushed. We fix this by
3269*61046927SAndroid Build Coastguard Worker * setting the SINGLE_PRIM_MODE field to the same value that the blob does
3270*61046927SAndroid Build Coastguard Worker * for advanced_blend in sysmem mode if a feedback loop is detected.
3271*61046927SAndroid Build Coastguard Worker */
3272*61046927SAndroid Build Coastguard Worker enum a6xx_single_prim_mode sysmem_prim_mode =
3273*61046927SAndroid Build Coastguard Worker (raster_order_attachment_access || feedback_loops) ?
3274*61046927SAndroid Build Coastguard Worker FLUSH_PER_OVERLAP_AND_OVERWRITE : NO_FLUSH;
3275*61046927SAndroid Build Coastguard Worker
3276*61046927SAndroid Build Coastguard Worker if (sysmem_prim_mode == FLUSH_PER_OVERLAP_AND_OVERWRITE)
3277*61046927SAndroid Build Coastguard Worker *sysmem_single_prim_mode = true;
3278*61046927SAndroid Build Coastguard Worker
3279*61046927SAndroid Build Coastguard Worker tu_cs_emit_regs(cs, A6XX_GRAS_SC_CNTL(.ccusinglecachelinesize = 2,
3280*61046927SAndroid Build Coastguard Worker .single_prim_mode = sysmem_prim_mode));
3281*61046927SAndroid Build Coastguard Worker }
3282*61046927SAndroid Build Coastguard Worker
3283*61046927SAndroid Build Coastguard Worker static inline bool
emit_pipeline_state(BITSET_WORD * keep,BITSET_WORD * remove,BITSET_WORD * pipeline_set,const enum mesa_vk_dynamic_graphics_state * state_array,unsigned num_states,bool extra_cond,struct tu_pipeline_builder * builder)3284*61046927SAndroid Build Coastguard Worker emit_pipeline_state(BITSET_WORD *keep, BITSET_WORD *remove,
3285*61046927SAndroid Build Coastguard Worker BITSET_WORD *pipeline_set,
3286*61046927SAndroid Build Coastguard Worker const enum mesa_vk_dynamic_graphics_state *state_array,
3287*61046927SAndroid Build Coastguard Worker unsigned num_states, bool extra_cond,
3288*61046927SAndroid Build Coastguard Worker struct tu_pipeline_builder *builder)
3289*61046927SAndroid Build Coastguard Worker {
3290*61046927SAndroid Build Coastguard Worker BITSET_DECLARE(state, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX) = {};
3291*61046927SAndroid Build Coastguard Worker
3292*61046927SAndroid Build Coastguard Worker /* Unrolling this loop should produce a constant value once the function is
3293*61046927SAndroid Build Coastguard Worker * inlined, because state_array and num_states are a per-draw-state
3294*61046927SAndroid Build Coastguard Worker * constant, but GCC seems to need a little encouragement. clang does a
3295*61046927SAndroid Build Coastguard Worker * little better but still needs a pragma when there are a large number of
3296*61046927SAndroid Build Coastguard Worker * states.
3297*61046927SAndroid Build Coastguard Worker */
3298*61046927SAndroid Build Coastguard Worker #if defined(__clang__)
3299*61046927SAndroid Build Coastguard Worker #pragma clang loop unroll(full)
3300*61046927SAndroid Build Coastguard Worker #elif defined(__GNUC__) && __GNUC__ >= 8
3301*61046927SAndroid Build Coastguard Worker #pragma GCC unroll MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX
3302*61046927SAndroid Build Coastguard Worker #endif
3303*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_states; i++) {
3304*61046927SAndroid Build Coastguard Worker BITSET_SET(state, state_array[i]);
3305*61046927SAndroid Build Coastguard Worker }
3306*61046927SAndroid Build Coastguard Worker
3307*61046927SAndroid Build Coastguard Worker /* If all of the state is set, then after we emit it we can tentatively
3308*61046927SAndroid Build Coastguard Worker * remove it from the states to set for the pipeline by making it dynamic.
3309*61046927SAndroid Build Coastguard Worker * If we can't emit it, though, we need to keep around the partial state so
3310*61046927SAndroid Build Coastguard Worker * that we can emit it later, even if another draw state consumes it. That
3311*61046927SAndroid Build Coastguard Worker * is, we have to cancel any tentative removal.
3312*61046927SAndroid Build Coastguard Worker */
3313*61046927SAndroid Build Coastguard Worker BITSET_DECLARE(temp, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX);
3314*61046927SAndroid Build Coastguard Worker memcpy(temp, pipeline_set, sizeof(temp));
3315*61046927SAndroid Build Coastguard Worker BITSET_AND(temp, temp, state);
3316*61046927SAndroid Build Coastguard Worker if (!BITSET_EQUAL(temp, state) || !extra_cond) {
3317*61046927SAndroid Build Coastguard Worker __bitset_or(keep, keep, temp, ARRAY_SIZE(temp));
3318*61046927SAndroid Build Coastguard Worker return false;
3319*61046927SAndroid Build Coastguard Worker }
3320*61046927SAndroid Build Coastguard Worker __bitset_or(remove, remove, state, ARRAY_SIZE(state));
3321*61046927SAndroid Build Coastguard Worker return true;
3322*61046927SAndroid Build Coastguard Worker }
3323*61046927SAndroid Build Coastguard Worker
3324*61046927SAndroid Build Coastguard Worker template <chip CHIP>
3325*61046927SAndroid Build Coastguard Worker static void
tu_pipeline_builder_emit_state(struct tu_pipeline_builder * builder,struct tu_pipeline * pipeline)3326*61046927SAndroid Build Coastguard Worker tu_pipeline_builder_emit_state(struct tu_pipeline_builder *builder,
3327*61046927SAndroid Build Coastguard Worker struct tu_pipeline *pipeline)
3328*61046927SAndroid Build Coastguard Worker {
3329*61046927SAndroid Build Coastguard Worker struct tu_cs cs;
3330*61046927SAndroid Build Coastguard Worker BITSET_DECLARE(keep, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX) = {};
3331*61046927SAndroid Build Coastguard Worker BITSET_DECLARE(remove, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX) = {};
3332*61046927SAndroid Build Coastguard Worker BITSET_DECLARE(pipeline_set, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX) = {};
3333*61046927SAndroid Build Coastguard Worker
3334*61046927SAndroid Build Coastguard Worker vk_graphics_pipeline_get_state(&builder->graphics_state, pipeline_set);
3335*61046927SAndroid Build Coastguard Worker
3336*61046927SAndroid Build Coastguard Worker #define EMIT_STATE(name, extra_cond) \
3337*61046927SAndroid Build Coastguard Worker emit_pipeline_state(keep, remove, pipeline_set, tu_##name##_state, \
3338*61046927SAndroid Build Coastguard Worker ARRAY_SIZE(tu_##name##_state), extra_cond, builder)
3339*61046927SAndroid Build Coastguard Worker
3340*61046927SAndroid Build Coastguard Worker #define DRAW_STATE_COND(name, id, extra_cond, ...) \
3341*61046927SAndroid Build Coastguard Worker if (EMIT_STATE(name, extra_cond)) { \
3342*61046927SAndroid Build Coastguard Worker unsigned size = tu6_##name##_size<CHIP>(builder->device, __VA_ARGS__); \
3343*61046927SAndroid Build Coastguard Worker if (size > 0) { \
3344*61046927SAndroid Build Coastguard Worker tu_cs_begin_sub_stream(&pipeline->cs, size, &cs); \
3345*61046927SAndroid Build Coastguard Worker tu6_emit_##name<CHIP>(&cs, __VA_ARGS__); \
3346*61046927SAndroid Build Coastguard Worker pipeline->dynamic_state[id] = \
3347*61046927SAndroid Build Coastguard Worker tu_cs_end_draw_state(&pipeline->cs, &cs); \
3348*61046927SAndroid Build Coastguard Worker } \
3349*61046927SAndroid Build Coastguard Worker pipeline->set_state_mask |= (1u << id); \
3350*61046927SAndroid Build Coastguard Worker }
3351*61046927SAndroid Build Coastguard Worker #define DRAW_STATE(name, id, ...) DRAW_STATE_COND(name, id, true, __VA_ARGS__)
3352*61046927SAndroid Build Coastguard Worker
3353*61046927SAndroid Build Coastguard Worker DRAW_STATE(vertex_input, TU_DYNAMIC_STATE_VERTEX_INPUT,
3354*61046927SAndroid Build Coastguard Worker builder->graphics_state.vi);
3355*61046927SAndroid Build Coastguard Worker DRAW_STATE(vertex_stride, TU_DYNAMIC_STATE_VB_STRIDE,
3356*61046927SAndroid Build Coastguard Worker builder->graphics_state.vi);
3357*61046927SAndroid Build Coastguard Worker /* If (a) per-view viewport is used or (b) we don't know yet, then we need
3358*61046927SAndroid Build Coastguard Worker * to set viewport and stencil state dynamically.
3359*61046927SAndroid Build Coastguard Worker */
3360*61046927SAndroid Build Coastguard Worker bool no_per_view_viewport = pipeline_contains_all_shader_state(pipeline) &&
3361*61046927SAndroid Build Coastguard Worker !pipeline->program.per_view_viewport;
3362*61046927SAndroid Build Coastguard Worker DRAW_STATE_COND(viewport, TU_DYNAMIC_STATE_VIEWPORT, no_per_view_viewport,
3363*61046927SAndroid Build Coastguard Worker builder->graphics_state.vp,
3364*61046927SAndroid Build Coastguard Worker builder->graphics_state.rs);
3365*61046927SAndroid Build Coastguard Worker DRAW_STATE_COND(scissor, TU_DYNAMIC_STATE_SCISSOR, no_per_view_viewport,
3366*61046927SAndroid Build Coastguard Worker builder->graphics_state.vp);
3367*61046927SAndroid Build Coastguard Worker DRAW_STATE(sample_locations,
3368*61046927SAndroid Build Coastguard Worker TU_DYNAMIC_STATE_SAMPLE_LOCATIONS,
3369*61046927SAndroid Build Coastguard Worker builder->graphics_state.ms->sample_locations_enable,
3370*61046927SAndroid Build Coastguard Worker builder->graphics_state.ms->sample_locations);
3371*61046927SAndroid Build Coastguard Worker DRAW_STATE(depth_bias, TU_DYNAMIC_STATE_DEPTH_BIAS,
3372*61046927SAndroid Build Coastguard Worker builder->graphics_state.rs);
3373*61046927SAndroid Build Coastguard Worker bool attachments_valid =
3374*61046927SAndroid Build Coastguard Worker builder->graphics_state.rp &&
3375*61046927SAndroid Build Coastguard Worker vk_render_pass_state_has_attachment_info(builder->graphics_state.rp);
3376*61046927SAndroid Build Coastguard Worker struct vk_color_blend_state dummy_cb = {};
3377*61046927SAndroid Build Coastguard Worker const struct vk_color_blend_state *cb = builder->graphics_state.cb;
3378*61046927SAndroid Build Coastguard Worker if (attachments_valid &&
3379*61046927SAndroid Build Coastguard Worker !(builder->graphics_state.rp->attachments &
3380*61046927SAndroid Build Coastguard Worker MESA_VK_RP_ATTACHMENT_ANY_COLOR_BITS)) {
3381*61046927SAndroid Build Coastguard Worker /* If there are no color attachments, then the original blend state may
3382*61046927SAndroid Build Coastguard Worker * be NULL and the common code sanitizes it to always be NULL. In this
3383*61046927SAndroid Build Coastguard Worker * case we want to emit an empty blend/bandwidth/etc. rather than
3384*61046927SAndroid Build Coastguard Worker * letting it be dynamic (and potentially garbage).
3385*61046927SAndroid Build Coastguard Worker */
3386*61046927SAndroid Build Coastguard Worker cb = &dummy_cb;
3387*61046927SAndroid Build Coastguard Worker BITSET_SET(pipeline_set, MESA_VK_DYNAMIC_CB_LOGIC_OP_ENABLE);
3388*61046927SAndroid Build Coastguard Worker BITSET_SET(pipeline_set, MESA_VK_DYNAMIC_CB_LOGIC_OP);
3389*61046927SAndroid Build Coastguard Worker BITSET_SET(pipeline_set, MESA_VK_DYNAMIC_CB_ATTACHMENT_COUNT);
3390*61046927SAndroid Build Coastguard Worker BITSET_SET(pipeline_set, MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES);
3391*61046927SAndroid Build Coastguard Worker BITSET_SET(pipeline_set, MESA_VK_DYNAMIC_CB_BLEND_ENABLES);
3392*61046927SAndroid Build Coastguard Worker BITSET_SET(pipeline_set, MESA_VK_DYNAMIC_CB_BLEND_EQUATIONS);
3393*61046927SAndroid Build Coastguard Worker BITSET_SET(pipeline_set, MESA_VK_DYNAMIC_CB_WRITE_MASKS);
3394*61046927SAndroid Build Coastguard Worker BITSET_SET(pipeline_set, MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS);
3395*61046927SAndroid Build Coastguard Worker }
3396*61046927SAndroid Build Coastguard Worker DRAW_STATE(blend, TU_DYNAMIC_STATE_BLEND, cb,
3397*61046927SAndroid Build Coastguard Worker builder->graphics_state.ms->alpha_to_coverage_enable,
3398*61046927SAndroid Build Coastguard Worker builder->graphics_state.ms->alpha_to_one_enable,
3399*61046927SAndroid Build Coastguard Worker builder->graphics_state.ms->sample_mask);
3400*61046927SAndroid Build Coastguard Worker if (EMIT_STATE(blend_lrz, attachments_valid))
3401*61046927SAndroid Build Coastguard Worker tu_emit_blend_lrz(&pipeline->lrz_blend, cb,
3402*61046927SAndroid Build Coastguard Worker builder->graphics_state.rp);
3403*61046927SAndroid Build Coastguard Worker if (EMIT_STATE(bandwidth, attachments_valid))
3404*61046927SAndroid Build Coastguard Worker tu_calc_bandwidth(&pipeline->bandwidth, cb,
3405*61046927SAndroid Build Coastguard Worker builder->graphics_state.rp);
3406*61046927SAndroid Build Coastguard Worker DRAW_STATE(blend_constants, TU_DYNAMIC_STATE_BLEND_CONSTANTS, cb);
3407*61046927SAndroid Build Coastguard Worker if (attachments_valid &&
3408*61046927SAndroid Build Coastguard Worker !(builder->graphics_state.rp->attachments &
3409*61046927SAndroid Build Coastguard Worker MESA_VK_RP_ATTACHMENT_ANY_COLOR_BITS)) {
3410*61046927SAndroid Build Coastguard Worker /* Don't actually make anything dynamic as that may mean a partially-set
3411*61046927SAndroid Build Coastguard Worker * state group where the group is NULL which angers common code.
3412*61046927SAndroid Build Coastguard Worker */
3413*61046927SAndroid Build Coastguard Worker BITSET_CLEAR(remove, MESA_VK_DYNAMIC_CB_LOGIC_OP_ENABLE);
3414*61046927SAndroid Build Coastguard Worker BITSET_CLEAR(remove, MESA_VK_DYNAMIC_CB_LOGIC_OP);
3415*61046927SAndroid Build Coastguard Worker BITSET_CLEAR(remove, MESA_VK_DYNAMIC_CB_ATTACHMENT_COUNT);
3416*61046927SAndroid Build Coastguard Worker BITSET_CLEAR(remove, MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES);
3417*61046927SAndroid Build Coastguard Worker BITSET_CLEAR(remove, MESA_VK_DYNAMIC_CB_BLEND_ENABLES);
3418*61046927SAndroid Build Coastguard Worker BITSET_CLEAR(remove, MESA_VK_DYNAMIC_CB_BLEND_EQUATIONS);
3419*61046927SAndroid Build Coastguard Worker BITSET_CLEAR(remove, MESA_VK_DYNAMIC_CB_WRITE_MASKS);
3420*61046927SAndroid Build Coastguard Worker BITSET_CLEAR(remove, MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS);
3421*61046927SAndroid Build Coastguard Worker }
3422*61046927SAndroid Build Coastguard Worker DRAW_STATE_COND(rast, TU_DYNAMIC_STATE_RAST,
3423*61046927SAndroid Build Coastguard Worker pipeline_contains_all_shader_state(pipeline),
3424*61046927SAndroid Build Coastguard Worker builder->graphics_state.rs,
3425*61046927SAndroid Build Coastguard Worker builder->graphics_state.vp,
3426*61046927SAndroid Build Coastguard Worker builder->graphics_state.rp->view_mask != 0,
3427*61046927SAndroid Build Coastguard Worker pipeline->program.per_view_viewport);
3428*61046927SAndroid Build Coastguard Worker DRAW_STATE_COND(ds, TU_DYNAMIC_STATE_DS,
3429*61046927SAndroid Build Coastguard Worker attachments_valid,
3430*61046927SAndroid Build Coastguard Worker builder->graphics_state.ds,
3431*61046927SAndroid Build Coastguard Worker builder->graphics_state.rp);
3432*61046927SAndroid Build Coastguard Worker DRAW_STATE_COND(rb_depth_cntl, TU_DYNAMIC_STATE_RB_DEPTH_CNTL,
3433*61046927SAndroid Build Coastguard Worker attachments_valid,
3434*61046927SAndroid Build Coastguard Worker builder->graphics_state.ds,
3435*61046927SAndroid Build Coastguard Worker builder->graphics_state.rp,
3436*61046927SAndroid Build Coastguard Worker builder->graphics_state.rs);
3437*61046927SAndroid Build Coastguard Worker DRAW_STATE_COND(patch_control_points,
3438*61046927SAndroid Build Coastguard Worker TU_DYNAMIC_STATE_PATCH_CONTROL_POINTS,
3439*61046927SAndroid Build Coastguard Worker pipeline_contains_all_shader_state(pipeline),
3440*61046927SAndroid Build Coastguard Worker pipeline->shaders[MESA_SHADER_VERTEX],
3441*61046927SAndroid Build Coastguard Worker pipeline->shaders[MESA_SHADER_TESS_CTRL],
3442*61046927SAndroid Build Coastguard Worker pipeline->shaders[MESA_SHADER_TESS_EVAL],
3443*61046927SAndroid Build Coastguard Worker &pipeline->program,
3444*61046927SAndroid Build Coastguard Worker builder->graphics_state.ts->patch_control_points);
3445*61046927SAndroid Build Coastguard Worker bool has_raster_order_state = false;
3446*61046927SAndroid Build Coastguard Worker if (pipeline->type == TU_PIPELINE_GRAPHICS) {
3447*61046927SAndroid Build Coastguard Worker has_raster_order_state = true;
3448*61046927SAndroid Build Coastguard Worker } else {
3449*61046927SAndroid Build Coastguard Worker struct tu_graphics_lib_pipeline *lib =
3450*61046927SAndroid Build Coastguard Worker tu_pipeline_to_graphics_lib(pipeline);
3451*61046927SAndroid Build Coastguard Worker has_raster_order_state =
3452*61046927SAndroid Build Coastguard Worker (lib->state & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT) &&
3453*61046927SAndroid Build Coastguard Worker (lib->state &
3454*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT);
3455*61046927SAndroid Build Coastguard Worker }
3456*61046927SAndroid Build Coastguard Worker if (!builder->device->physical_device->info->a6xx.has_coherent_ubwc_flag_caches) {
3457*61046927SAndroid Build Coastguard Worker DRAW_STATE_COND(prim_mode_sysmem,
3458*61046927SAndroid Build Coastguard Worker TU_DYNAMIC_STATE_PRIM_MODE_SYSMEM,
3459*61046927SAndroid Build Coastguard Worker has_raster_order_state,
3460*61046927SAndroid Build Coastguard Worker pipeline->output.raster_order_attachment_access ||
3461*61046927SAndroid Build Coastguard Worker pipeline->ds.raster_order_attachment_access,
3462*61046927SAndroid Build Coastguard Worker vk_pipeline_flags_feedback_loops(builder->graphics_state.pipeline_flags),
3463*61046927SAndroid Build Coastguard Worker &pipeline->prim_order.sysmem_single_prim_mode);
3464*61046927SAndroid Build Coastguard Worker }
3465*61046927SAndroid Build Coastguard Worker #undef DRAW_STATE
3466*61046927SAndroid Build Coastguard Worker #undef DRAW_STATE_COND
3467*61046927SAndroid Build Coastguard Worker #undef EMIT_STATE
3468*61046927SAndroid Build Coastguard Worker
3469*61046927SAndroid Build Coastguard Worker /* LRZ always needs depth/stencil state at draw time */
3470*61046927SAndroid Build Coastguard Worker BITSET_SET(keep, MESA_VK_DYNAMIC_DS_DEPTH_TEST_ENABLE);
3471*61046927SAndroid Build Coastguard Worker BITSET_SET(keep, MESA_VK_DYNAMIC_DS_DEPTH_WRITE_ENABLE);
3472*61046927SAndroid Build Coastguard Worker BITSET_SET(keep, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_ENABLE);
3473*61046927SAndroid Build Coastguard Worker BITSET_SET(keep, MESA_VK_DYNAMIC_DS_DEPTH_COMPARE_OP);
3474*61046927SAndroid Build Coastguard Worker BITSET_SET(keep, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE);
3475*61046927SAndroid Build Coastguard Worker BITSET_SET(keep, MESA_VK_DYNAMIC_DS_STENCIL_OP);
3476*61046927SAndroid Build Coastguard Worker BITSET_SET(keep, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK);
3477*61046927SAndroid Build Coastguard Worker BITSET_SET(keep, MESA_VK_DYNAMIC_MS_ALPHA_TO_COVERAGE_ENABLE);
3478*61046927SAndroid Build Coastguard Worker
3479*61046927SAndroid Build Coastguard Worker /* MSAA needs line mode */
3480*61046927SAndroid Build Coastguard Worker BITSET_SET(keep, MESA_VK_DYNAMIC_RS_LINE_MODE);
3481*61046927SAndroid Build Coastguard Worker
3482*61046927SAndroid Build Coastguard Worker /* The patch control points is part of the draw */
3483*61046927SAndroid Build Coastguard Worker BITSET_SET(keep, MESA_VK_DYNAMIC_TS_PATCH_CONTROL_POINTS);
3484*61046927SAndroid Build Coastguard Worker
3485*61046927SAndroid Build Coastguard Worker /* Vertex buffer state needs to know the max valid binding */
3486*61046927SAndroid Build Coastguard Worker BITSET_SET(keep, MESA_VK_DYNAMIC_VI_BINDINGS_VALID);
3487*61046927SAndroid Build Coastguard Worker
3488*61046927SAndroid Build Coastguard Worker /* Remove state which has been emitted and we no longer need to set when
3489*61046927SAndroid Build Coastguard Worker * binding the pipeline by making it "dynamic".
3490*61046927SAndroid Build Coastguard Worker */
3491*61046927SAndroid Build Coastguard Worker BITSET_ANDNOT(remove, remove, keep);
3492*61046927SAndroid Build Coastguard Worker
3493*61046927SAndroid Build Coastguard Worker BITSET_OR(pipeline->static_state_mask, pipeline->static_state_mask, remove);
3494*61046927SAndroid Build Coastguard Worker
3495*61046927SAndroid Build Coastguard Worker BITSET_OR(builder->graphics_state.dynamic, builder->graphics_state.dynamic,
3496*61046927SAndroid Build Coastguard Worker remove);
3497*61046927SAndroid Build Coastguard Worker }
3498*61046927SAndroid Build Coastguard Worker
3499*61046927SAndroid Build Coastguard Worker static inline bool
emit_draw_state(const struct vk_dynamic_graphics_state * dynamic_state,const enum mesa_vk_dynamic_graphics_state * state_array,unsigned num_states)3500*61046927SAndroid Build Coastguard Worker emit_draw_state(const struct vk_dynamic_graphics_state *dynamic_state,
3501*61046927SAndroid Build Coastguard Worker const enum mesa_vk_dynamic_graphics_state *state_array,
3502*61046927SAndroid Build Coastguard Worker unsigned num_states)
3503*61046927SAndroid Build Coastguard Worker {
3504*61046927SAndroid Build Coastguard Worker BITSET_DECLARE(state, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX) = {};
3505*61046927SAndroid Build Coastguard Worker
3506*61046927SAndroid Build Coastguard Worker /* Unrolling this loop should produce a constant value once the function is
3507*61046927SAndroid Build Coastguard Worker * inlined, because state_array and num_states are a per-draw-state
3508*61046927SAndroid Build Coastguard Worker * constant, but GCC seems to need a little encouragement. clang does a
3509*61046927SAndroid Build Coastguard Worker * little better but still needs a pragma when there are a large number of
3510*61046927SAndroid Build Coastguard Worker * states.
3511*61046927SAndroid Build Coastguard Worker */
3512*61046927SAndroid Build Coastguard Worker #if defined(__clang__)
3513*61046927SAndroid Build Coastguard Worker #pragma clang loop unroll(full)
3514*61046927SAndroid Build Coastguard Worker #elif defined(__GNUC__) && __GNUC__ >= 8
3515*61046927SAndroid Build Coastguard Worker #pragma GCC unroll MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX
3516*61046927SAndroid Build Coastguard Worker #endif
3517*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_states; i++) {
3518*61046927SAndroid Build Coastguard Worker BITSET_SET(state, state_array[i]);
3519*61046927SAndroid Build Coastguard Worker }
3520*61046927SAndroid Build Coastguard Worker
3521*61046927SAndroid Build Coastguard Worker BITSET_DECLARE(temp, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX);
3522*61046927SAndroid Build Coastguard Worker BITSET_AND(temp, state, dynamic_state->dirty);
3523*61046927SAndroid Build Coastguard Worker return !BITSET_IS_EMPTY(temp);
3524*61046927SAndroid Build Coastguard Worker }
3525*61046927SAndroid Build Coastguard Worker
3526*61046927SAndroid Build Coastguard Worker template <chip CHIP>
3527*61046927SAndroid Build Coastguard Worker uint32_t
tu_emit_draw_state(struct tu_cmd_buffer * cmd)3528*61046927SAndroid Build Coastguard Worker tu_emit_draw_state(struct tu_cmd_buffer *cmd)
3529*61046927SAndroid Build Coastguard Worker {
3530*61046927SAndroid Build Coastguard Worker struct tu_cs cs;
3531*61046927SAndroid Build Coastguard Worker uint32_t dirty_draw_states = 0;
3532*61046927SAndroid Build Coastguard Worker
3533*61046927SAndroid Build Coastguard Worker #define EMIT_STATE(name) \
3534*61046927SAndroid Build Coastguard Worker emit_draw_state(&cmd->vk.dynamic_graphics_state, tu_##name##_state, \
3535*61046927SAndroid Build Coastguard Worker ARRAY_SIZE(tu_##name##_state))
3536*61046927SAndroid Build Coastguard Worker #define DRAW_STATE_COND(name, id, extra_cond, ...) \
3537*61046927SAndroid Build Coastguard Worker if ((EMIT_STATE(name) || (extra_cond)) && \
3538*61046927SAndroid Build Coastguard Worker !(cmd->state.pipeline_draw_states & (1u << id))) { \
3539*61046927SAndroid Build Coastguard Worker unsigned size = tu6_##name##_size<CHIP>(cmd->device, __VA_ARGS__); \
3540*61046927SAndroid Build Coastguard Worker if (size > 0) { \
3541*61046927SAndroid Build Coastguard Worker tu_cs_begin_sub_stream(&cmd->sub_cs, size, &cs); \
3542*61046927SAndroid Build Coastguard Worker tu6_emit_##name<CHIP>(&cs, __VA_ARGS__); \
3543*61046927SAndroid Build Coastguard Worker cmd->state.dynamic_state[id] = \
3544*61046927SAndroid Build Coastguard Worker tu_cs_end_draw_state(&cmd->sub_cs, &cs); \
3545*61046927SAndroid Build Coastguard Worker } else { \
3546*61046927SAndroid Build Coastguard Worker cmd->state.dynamic_state[id] = {}; \
3547*61046927SAndroid Build Coastguard Worker } \
3548*61046927SAndroid Build Coastguard Worker dirty_draw_states |= (1u << id); \
3549*61046927SAndroid Build Coastguard Worker }
3550*61046927SAndroid Build Coastguard Worker #define DRAW_STATE_FDM(name, id, ...) \
3551*61046927SAndroid Build Coastguard Worker if ((EMIT_STATE(name) || (cmd->state.dirty & TU_CMD_DIRTY_FDM)) && \
3552*61046927SAndroid Build Coastguard Worker !(cmd->state.pipeline_draw_states & (1u << id))) { \
3553*61046927SAndroid Build Coastguard Worker if (cmd->state.shaders[MESA_SHADER_FRAGMENT]->fs.has_fdm) { \
3554*61046927SAndroid Build Coastguard Worker tu_cs_set_writeable(&cmd->sub_cs, true); \
3555*61046927SAndroid Build Coastguard Worker tu6_emit_##name##_fdm(&cs, cmd, __VA_ARGS__); \
3556*61046927SAndroid Build Coastguard Worker cmd->state.dynamic_state[id] = \
3557*61046927SAndroid Build Coastguard Worker tu_cs_end_draw_state(&cmd->sub_cs, &cs); \
3558*61046927SAndroid Build Coastguard Worker tu_cs_set_writeable(&cmd->sub_cs, false); \
3559*61046927SAndroid Build Coastguard Worker } else { \
3560*61046927SAndroid Build Coastguard Worker unsigned size = tu6_##name##_size<CHIP>(cmd->device, __VA_ARGS__); \
3561*61046927SAndroid Build Coastguard Worker if (size > 0) { \
3562*61046927SAndroid Build Coastguard Worker tu_cs_begin_sub_stream(&cmd->sub_cs, size, &cs); \
3563*61046927SAndroid Build Coastguard Worker tu6_emit_##name<CHIP>(&cs, __VA_ARGS__); \
3564*61046927SAndroid Build Coastguard Worker cmd->state.dynamic_state[id] = \
3565*61046927SAndroid Build Coastguard Worker tu_cs_end_draw_state(&cmd->sub_cs, &cs); \
3566*61046927SAndroid Build Coastguard Worker } else { \
3567*61046927SAndroid Build Coastguard Worker cmd->state.dynamic_state[id] = {}; \
3568*61046927SAndroid Build Coastguard Worker } \
3569*61046927SAndroid Build Coastguard Worker tu_cs_begin_sub_stream(&cmd->sub_cs, \
3570*61046927SAndroid Build Coastguard Worker tu6_##name##_size<CHIP>(cmd->device, __VA_ARGS__), \
3571*61046927SAndroid Build Coastguard Worker &cs); \
3572*61046927SAndroid Build Coastguard Worker tu6_emit_##name<CHIP>(&cs, __VA_ARGS__); \
3573*61046927SAndroid Build Coastguard Worker cmd->state.dynamic_state[id] = \
3574*61046927SAndroid Build Coastguard Worker tu_cs_end_draw_state(&cmd->sub_cs, &cs); \
3575*61046927SAndroid Build Coastguard Worker } \
3576*61046927SAndroid Build Coastguard Worker dirty_draw_states |= (1u << id); \
3577*61046927SAndroid Build Coastguard Worker }
3578*61046927SAndroid Build Coastguard Worker #define DRAW_STATE(name, id, ...) DRAW_STATE_COND(name, id, false, __VA_ARGS__)
3579*61046927SAndroid Build Coastguard Worker
3580*61046927SAndroid Build Coastguard Worker DRAW_STATE(vertex_input, TU_DYNAMIC_STATE_VERTEX_INPUT,
3581*61046927SAndroid Build Coastguard Worker cmd->vk.dynamic_graphics_state.vi);
3582*61046927SAndroid Build Coastguard Worker
3583*61046927SAndroid Build Coastguard Worker /* Vertex input stride is special because it's part of the vertex input in
3584*61046927SAndroid Build Coastguard Worker * the pipeline but a separate array when it's dynamic state so we have to
3585*61046927SAndroid Build Coastguard Worker * use two separate functions.
3586*61046927SAndroid Build Coastguard Worker */
3587*61046927SAndroid Build Coastguard Worker #define tu6_emit_vertex_stride tu6_emit_vertex_stride_dyn
3588*61046927SAndroid Build Coastguard Worker #define tu6_vertex_stride_size tu6_vertex_stride_size_dyn
3589*61046927SAndroid Build Coastguard Worker
3590*61046927SAndroid Build Coastguard Worker DRAW_STATE(vertex_stride, TU_DYNAMIC_STATE_VB_STRIDE,
3591*61046927SAndroid Build Coastguard Worker cmd->vk.dynamic_graphics_state.vi_binding_strides,
3592*61046927SAndroid Build Coastguard Worker cmd->vk.dynamic_graphics_state.vi_bindings_valid);
3593*61046927SAndroid Build Coastguard Worker
3594*61046927SAndroid Build Coastguard Worker #undef tu6_emit_vertex_stride
3595*61046927SAndroid Build Coastguard Worker #undef tu6_vertex_stride_size
3596*61046927SAndroid Build Coastguard Worker
3597*61046927SAndroid Build Coastguard Worker DRAW_STATE_FDM(viewport, TU_DYNAMIC_STATE_VIEWPORT,
3598*61046927SAndroid Build Coastguard Worker &cmd->vk.dynamic_graphics_state.vp,
3599*61046927SAndroid Build Coastguard Worker &cmd->vk.dynamic_graphics_state.rs);
3600*61046927SAndroid Build Coastguard Worker DRAW_STATE_FDM(scissor, TU_DYNAMIC_STATE_SCISSOR,
3601*61046927SAndroid Build Coastguard Worker &cmd->vk.dynamic_graphics_state.vp);
3602*61046927SAndroid Build Coastguard Worker DRAW_STATE(sample_locations,
3603*61046927SAndroid Build Coastguard Worker TU_DYNAMIC_STATE_SAMPLE_LOCATIONS,
3604*61046927SAndroid Build Coastguard Worker cmd->vk.dynamic_graphics_state.ms.sample_locations_enable,
3605*61046927SAndroid Build Coastguard Worker cmd->vk.dynamic_graphics_state.ms.sample_locations);
3606*61046927SAndroid Build Coastguard Worker DRAW_STATE(depth_bias, TU_DYNAMIC_STATE_DEPTH_BIAS,
3607*61046927SAndroid Build Coastguard Worker &cmd->vk.dynamic_graphics_state.rs);
3608*61046927SAndroid Build Coastguard Worker DRAW_STATE(blend, TU_DYNAMIC_STATE_BLEND,
3609*61046927SAndroid Build Coastguard Worker &cmd->vk.dynamic_graphics_state.cb,
3610*61046927SAndroid Build Coastguard Worker cmd->vk.dynamic_graphics_state.ms.alpha_to_coverage_enable,
3611*61046927SAndroid Build Coastguard Worker cmd->vk.dynamic_graphics_state.ms.alpha_to_one_enable,
3612*61046927SAndroid Build Coastguard Worker cmd->vk.dynamic_graphics_state.ms.sample_mask);
3613*61046927SAndroid Build Coastguard Worker if (EMIT_STATE(blend_lrz) ||
3614*61046927SAndroid Build Coastguard Worker ((cmd->state.dirty & TU_CMD_DIRTY_SUBPASS) &&
3615*61046927SAndroid Build Coastguard Worker !cmd->state.pipeline_blend_lrz)) {
3616*61046927SAndroid Build Coastguard Worker bool blend_reads_dest = tu6_calc_blend_lrz(&cmd->vk.dynamic_graphics_state.cb,
3617*61046927SAndroid Build Coastguard Worker &cmd->state.vk_rp);
3618*61046927SAndroid Build Coastguard Worker if (blend_reads_dest != cmd->state.blend_reads_dest) {
3619*61046927SAndroid Build Coastguard Worker cmd->state.blend_reads_dest = blend_reads_dest;
3620*61046927SAndroid Build Coastguard Worker cmd->state.dirty |= TU_CMD_DIRTY_LRZ;
3621*61046927SAndroid Build Coastguard Worker }
3622*61046927SAndroid Build Coastguard Worker }
3623*61046927SAndroid Build Coastguard Worker if (EMIT_STATE(bandwidth) ||
3624*61046927SAndroid Build Coastguard Worker ((cmd->state.dirty & TU_CMD_DIRTY_SUBPASS) &&
3625*61046927SAndroid Build Coastguard Worker !cmd->state.pipeline_bandwidth))
3626*61046927SAndroid Build Coastguard Worker tu_calc_bandwidth(&cmd->state.bandwidth, &cmd->vk.dynamic_graphics_state.cb,
3627*61046927SAndroid Build Coastguard Worker &cmd->state.vk_rp);
3628*61046927SAndroid Build Coastguard Worker DRAW_STATE(blend_constants, VK_DYNAMIC_STATE_BLEND_CONSTANTS,
3629*61046927SAndroid Build Coastguard Worker &cmd->vk.dynamic_graphics_state.cb);
3630*61046927SAndroid Build Coastguard Worker DRAW_STATE_COND(rast, TU_DYNAMIC_STATE_RAST,
3631*61046927SAndroid Build Coastguard Worker cmd->state.dirty & (TU_CMD_DIRTY_SUBPASS |
3632*61046927SAndroid Build Coastguard Worker TU_CMD_DIRTY_PER_VIEW_VIEWPORT),
3633*61046927SAndroid Build Coastguard Worker &cmd->vk.dynamic_graphics_state.rs,
3634*61046927SAndroid Build Coastguard Worker &cmd->vk.dynamic_graphics_state.vp,
3635*61046927SAndroid Build Coastguard Worker cmd->state.vk_rp.view_mask != 0,
3636*61046927SAndroid Build Coastguard Worker cmd->state.per_view_viewport);
3637*61046927SAndroid Build Coastguard Worker DRAW_STATE_COND(ds, TU_DYNAMIC_STATE_DS,
3638*61046927SAndroid Build Coastguard Worker cmd->state.dirty & TU_CMD_DIRTY_SUBPASS,
3639*61046927SAndroid Build Coastguard Worker &cmd->vk.dynamic_graphics_state.ds,
3640*61046927SAndroid Build Coastguard Worker &cmd->state.vk_rp);
3641*61046927SAndroid Build Coastguard Worker DRAW_STATE_COND(rb_depth_cntl, TU_DYNAMIC_STATE_RB_DEPTH_CNTL,
3642*61046927SAndroid Build Coastguard Worker cmd->state.dirty & TU_CMD_DIRTY_SUBPASS,
3643*61046927SAndroid Build Coastguard Worker &cmd->vk.dynamic_graphics_state.ds,
3644*61046927SAndroid Build Coastguard Worker &cmd->state.vk_rp,
3645*61046927SAndroid Build Coastguard Worker &cmd->vk.dynamic_graphics_state.rs);
3646*61046927SAndroid Build Coastguard Worker DRAW_STATE_COND(patch_control_points,
3647*61046927SAndroid Build Coastguard Worker TU_DYNAMIC_STATE_PATCH_CONTROL_POINTS,
3648*61046927SAndroid Build Coastguard Worker cmd->state.dirty & TU_CMD_DIRTY_PROGRAM,
3649*61046927SAndroid Build Coastguard Worker cmd->state.shaders[MESA_SHADER_VERTEX],
3650*61046927SAndroid Build Coastguard Worker cmd->state.shaders[MESA_SHADER_TESS_CTRL],
3651*61046927SAndroid Build Coastguard Worker cmd->state.shaders[MESA_SHADER_TESS_EVAL],
3652*61046927SAndroid Build Coastguard Worker &cmd->state.program,
3653*61046927SAndroid Build Coastguard Worker cmd->vk.dynamic_graphics_state.ts.patch_control_points);
3654*61046927SAndroid Build Coastguard Worker if (!cmd->device->physical_device->info->a6xx.has_coherent_ubwc_flag_caches) {
3655*61046927SAndroid Build Coastguard Worker DRAW_STATE_COND(prim_mode_sysmem,
3656*61046927SAndroid Build Coastguard Worker TU_DYNAMIC_STATE_PRIM_MODE_SYSMEM,
3657*61046927SAndroid Build Coastguard Worker cmd->state.dirty & (TU_CMD_DIRTY_RAST_ORDER |
3658*61046927SAndroid Build Coastguard Worker TU_CMD_DIRTY_FEEDBACK_LOOPS),
3659*61046927SAndroid Build Coastguard Worker cmd->state.raster_order_attachment_access,
3660*61046927SAndroid Build Coastguard Worker cmd->vk.dynamic_graphics_state.feedback_loops |
3661*61046927SAndroid Build Coastguard Worker cmd->state.pipeline_feedback_loops,
3662*61046927SAndroid Build Coastguard Worker &cmd->state.rp.sysmem_single_prim_mode);
3663*61046927SAndroid Build Coastguard Worker }
3664*61046927SAndroid Build Coastguard Worker #undef DRAW_STATE
3665*61046927SAndroid Build Coastguard Worker #undef DRAW_STATE_COND
3666*61046927SAndroid Build Coastguard Worker #undef EMIT_STATE
3667*61046927SAndroid Build Coastguard Worker
3668*61046927SAndroid Build Coastguard Worker return dirty_draw_states;
3669*61046927SAndroid Build Coastguard Worker }
3670*61046927SAndroid Build Coastguard Worker TU_GENX(tu_emit_draw_state);
3671*61046927SAndroid Build Coastguard Worker
3672*61046927SAndroid Build Coastguard Worker static void
tu_pipeline_builder_parse_depth_stencil(struct tu_pipeline_builder * builder,struct tu_pipeline * pipeline)3673*61046927SAndroid Build Coastguard Worker tu_pipeline_builder_parse_depth_stencil(
3674*61046927SAndroid Build Coastguard Worker struct tu_pipeline_builder *builder, struct tu_pipeline *pipeline)
3675*61046927SAndroid Build Coastguard Worker {
3676*61046927SAndroid Build Coastguard Worker const VkPipelineDepthStencilStateCreateInfo *ds_info =
3677*61046927SAndroid Build Coastguard Worker builder->create_info->pDepthStencilState;
3678*61046927SAndroid Build Coastguard Worker
3679*61046927SAndroid Build Coastguard Worker if ((builder->graphics_state.rp->attachments ==
3680*61046927SAndroid Build Coastguard Worker MESA_VK_RP_ATTACHMENT_INFO_INVALID) ||
3681*61046927SAndroid Build Coastguard Worker (builder->graphics_state.rp->attachments &
3682*61046927SAndroid Build Coastguard Worker MESA_VK_RP_ATTACHMENT_DEPTH_BIT)) {
3683*61046927SAndroid Build Coastguard Worker pipeline->ds.raster_order_attachment_access =
3684*61046927SAndroid Build Coastguard Worker ds_info && (ds_info->flags &
3685*61046927SAndroid Build Coastguard Worker (VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT |
3686*61046927SAndroid Build Coastguard Worker VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT));
3687*61046927SAndroid Build Coastguard Worker }
3688*61046927SAndroid Build Coastguard Worker }
3689*61046927SAndroid Build Coastguard Worker
3690*61046927SAndroid Build Coastguard Worker static void
tu_pipeline_builder_parse_multisample_and_color_blend(struct tu_pipeline_builder * builder,struct tu_pipeline * pipeline)3691*61046927SAndroid Build Coastguard Worker tu_pipeline_builder_parse_multisample_and_color_blend(
3692*61046927SAndroid Build Coastguard Worker struct tu_pipeline_builder *builder, struct tu_pipeline *pipeline)
3693*61046927SAndroid Build Coastguard Worker {
3694*61046927SAndroid Build Coastguard Worker /* The spec says:
3695*61046927SAndroid Build Coastguard Worker *
3696*61046927SAndroid Build Coastguard Worker * pMultisampleState is a pointer to an instance of the
3697*61046927SAndroid Build Coastguard Worker * VkPipelineMultisampleStateCreateInfo, and is ignored if the pipeline
3698*61046927SAndroid Build Coastguard Worker * has rasterization disabled.
3699*61046927SAndroid Build Coastguard Worker *
3700*61046927SAndroid Build Coastguard Worker * Also,
3701*61046927SAndroid Build Coastguard Worker *
3702*61046927SAndroid Build Coastguard Worker * pColorBlendState is a pointer to an instance of the
3703*61046927SAndroid Build Coastguard Worker * VkPipelineColorBlendStateCreateInfo structure, and is ignored if the
3704*61046927SAndroid Build Coastguard Worker * pipeline has rasterization disabled or if the subpass of the render
3705*61046927SAndroid Build Coastguard Worker * pass the pipeline is created against does not use any color
3706*61046927SAndroid Build Coastguard Worker * attachments.
3707*61046927SAndroid Build Coastguard Worker *
3708*61046927SAndroid Build Coastguard Worker * We leave the relevant registers stale when rasterization is disabled.
3709*61046927SAndroid Build Coastguard Worker */
3710*61046927SAndroid Build Coastguard Worker if (builder->rasterizer_discard) {
3711*61046927SAndroid Build Coastguard Worker return;
3712*61046927SAndroid Build Coastguard Worker }
3713*61046927SAndroid Build Coastguard Worker
3714*61046927SAndroid Build Coastguard Worker static const VkPipelineColorBlendStateCreateInfo dummy_blend_info = {};
3715*61046927SAndroid Build Coastguard Worker
3716*61046927SAndroid Build Coastguard Worker const VkPipelineColorBlendStateCreateInfo *blend_info =
3717*61046927SAndroid Build Coastguard Worker (builder->graphics_state.rp->attachments &
3718*61046927SAndroid Build Coastguard Worker MESA_VK_RP_ATTACHMENT_ANY_COLOR_BITS)
3719*61046927SAndroid Build Coastguard Worker ? builder->create_info->pColorBlendState
3720*61046927SAndroid Build Coastguard Worker : &dummy_blend_info;
3721*61046927SAndroid Build Coastguard Worker
3722*61046927SAndroid Build Coastguard Worker if (builder->graphics_state.rp->attachments &
3723*61046927SAndroid Build Coastguard Worker MESA_VK_RP_ATTACHMENT_ANY_COLOR_BITS) {
3724*61046927SAndroid Build Coastguard Worker pipeline->output.raster_order_attachment_access =
3725*61046927SAndroid Build Coastguard Worker blend_info && (blend_info->flags &
3726*61046927SAndroid Build Coastguard Worker VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT);
3727*61046927SAndroid Build Coastguard Worker }
3728*61046927SAndroid Build Coastguard Worker }
3729*61046927SAndroid Build Coastguard Worker
3730*61046927SAndroid Build Coastguard Worker static void
tu_pipeline_builder_parse_rasterization_order(struct tu_pipeline_builder * builder,struct tu_pipeline * pipeline)3731*61046927SAndroid Build Coastguard Worker tu_pipeline_builder_parse_rasterization_order(
3732*61046927SAndroid Build Coastguard Worker struct tu_pipeline_builder *builder, struct tu_pipeline *pipeline)
3733*61046927SAndroid Build Coastguard Worker {
3734*61046927SAndroid Build Coastguard Worker if (builder->rasterizer_discard)
3735*61046927SAndroid Build Coastguard Worker return;
3736*61046927SAndroid Build Coastguard Worker
3737*61046927SAndroid Build Coastguard Worker bool raster_order_attachment_access =
3738*61046927SAndroid Build Coastguard Worker pipeline->output.raster_order_attachment_access ||
3739*61046927SAndroid Build Coastguard Worker pipeline->ds.raster_order_attachment_access ||
3740*61046927SAndroid Build Coastguard Worker TU_DEBUG(RAST_ORDER);
3741*61046927SAndroid Build Coastguard Worker
3742*61046927SAndroid Build Coastguard Worker /* VK_EXT_blend_operation_advanced would also require ordered access
3743*61046927SAndroid Build Coastguard Worker * when implemented in the future.
3744*61046927SAndroid Build Coastguard Worker */
3745*61046927SAndroid Build Coastguard Worker
3746*61046927SAndroid Build Coastguard Worker enum a6xx_single_prim_mode gmem_prim_mode = NO_FLUSH;
3747*61046927SAndroid Build Coastguard Worker
3748*61046927SAndroid Build Coastguard Worker if (raster_order_attachment_access) {
3749*61046927SAndroid Build Coastguard Worker /* VK_EXT_rasterization_order_attachment_access:
3750*61046927SAndroid Build Coastguard Worker *
3751*61046927SAndroid Build Coastguard Worker * This extension allow access to framebuffer attachments when used as
3752*61046927SAndroid Build Coastguard Worker * both input and color attachments from one fragment to the next,
3753*61046927SAndroid Build Coastguard Worker * in rasterization order, without explicit synchronization.
3754*61046927SAndroid Build Coastguard Worker */
3755*61046927SAndroid Build Coastguard Worker gmem_prim_mode = FLUSH_PER_OVERLAP;
3756*61046927SAndroid Build Coastguard Worker }
3757*61046927SAndroid Build Coastguard Worker
3758*61046927SAndroid Build Coastguard Worker struct tu_cs cs;
3759*61046927SAndroid Build Coastguard Worker
3760*61046927SAndroid Build Coastguard Worker pipeline->prim_order.state_gmem = tu_cs_draw_state(&pipeline->cs, &cs, 2);
3761*61046927SAndroid Build Coastguard Worker tu_cs_emit_write_reg(&cs, REG_A6XX_GRAS_SC_CNTL,
3762*61046927SAndroid Build Coastguard Worker A6XX_GRAS_SC_CNTL_CCUSINGLECACHELINESIZE(2) |
3763*61046927SAndroid Build Coastguard Worker A6XX_GRAS_SC_CNTL_SINGLE_PRIM_MODE(gmem_prim_mode));
3764*61046927SAndroid Build Coastguard Worker }
3765*61046927SAndroid Build Coastguard Worker
3766*61046927SAndroid Build Coastguard Worker static void
tu_pipeline_finish(struct tu_pipeline * pipeline,struct tu_device * dev,const VkAllocationCallbacks * alloc)3767*61046927SAndroid Build Coastguard Worker tu_pipeline_finish(struct tu_pipeline *pipeline,
3768*61046927SAndroid Build Coastguard Worker struct tu_device *dev,
3769*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc)
3770*61046927SAndroid Build Coastguard Worker {
3771*61046927SAndroid Build Coastguard Worker tu_cs_finish(&pipeline->cs);
3772*61046927SAndroid Build Coastguard Worker TU_RMV(resource_destroy, dev, &pipeline->bo);
3773*61046927SAndroid Build Coastguard Worker
3774*61046927SAndroid Build Coastguard Worker mtx_lock(&dev->pipeline_mutex);
3775*61046927SAndroid Build Coastguard Worker tu_suballoc_bo_free(&dev->pipeline_suballoc, &pipeline->bo);
3776*61046927SAndroid Build Coastguard Worker mtx_unlock(&dev->pipeline_mutex);
3777*61046927SAndroid Build Coastguard Worker
3778*61046927SAndroid Build Coastguard Worker if (pipeline->type == TU_PIPELINE_GRAPHICS_LIB) {
3779*61046927SAndroid Build Coastguard Worker struct tu_graphics_lib_pipeline *library =
3780*61046927SAndroid Build Coastguard Worker tu_pipeline_to_graphics_lib(pipeline);
3781*61046927SAndroid Build Coastguard Worker
3782*61046927SAndroid Build Coastguard Worker if (library->nir_shaders)
3783*61046927SAndroid Build Coastguard Worker vk_pipeline_cache_object_unref(&dev->vk,
3784*61046927SAndroid Build Coastguard Worker &library->nir_shaders->base);
3785*61046927SAndroid Build Coastguard Worker
3786*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < library->num_sets; i++) {
3787*61046927SAndroid Build Coastguard Worker if (library->layouts[i])
3788*61046927SAndroid Build Coastguard Worker vk_descriptor_set_layout_unref(&dev->vk, &library->layouts[i]->vk);
3789*61046927SAndroid Build Coastguard Worker }
3790*61046927SAndroid Build Coastguard Worker
3791*61046927SAndroid Build Coastguard Worker vk_free2(&dev->vk.alloc, alloc, library->state_data);
3792*61046927SAndroid Build Coastguard Worker }
3793*61046927SAndroid Build Coastguard Worker
3794*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < ARRAY_SIZE(pipeline->shaders); i++) {
3795*61046927SAndroid Build Coastguard Worker if (pipeline->shaders[i])
3796*61046927SAndroid Build Coastguard Worker vk_pipeline_cache_object_unref(&dev->vk,
3797*61046927SAndroid Build Coastguard Worker &pipeline->shaders[i]->base);
3798*61046927SAndroid Build Coastguard Worker }
3799*61046927SAndroid Build Coastguard Worker
3800*61046927SAndroid Build Coastguard Worker ralloc_free(pipeline->executables_mem_ctx);
3801*61046927SAndroid Build Coastguard Worker }
3802*61046927SAndroid Build Coastguard Worker
3803*61046927SAndroid Build Coastguard Worker static VkGraphicsPipelineLibraryFlagBitsEXT
vk_shader_stage_to_pipeline_library_flags(VkShaderStageFlagBits stage)3804*61046927SAndroid Build Coastguard Worker vk_shader_stage_to_pipeline_library_flags(VkShaderStageFlagBits stage)
3805*61046927SAndroid Build Coastguard Worker {
3806*61046927SAndroid Build Coastguard Worker assert(util_bitcount(stage) == 1);
3807*61046927SAndroid Build Coastguard Worker switch (stage) {
3808*61046927SAndroid Build Coastguard Worker case VK_SHADER_STAGE_VERTEX_BIT:
3809*61046927SAndroid Build Coastguard Worker case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
3810*61046927SAndroid Build Coastguard Worker case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
3811*61046927SAndroid Build Coastguard Worker case VK_SHADER_STAGE_GEOMETRY_BIT:
3812*61046927SAndroid Build Coastguard Worker case VK_SHADER_STAGE_TASK_BIT_EXT:
3813*61046927SAndroid Build Coastguard Worker case VK_SHADER_STAGE_MESH_BIT_EXT:
3814*61046927SAndroid Build Coastguard Worker return VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT;
3815*61046927SAndroid Build Coastguard Worker case VK_SHADER_STAGE_FRAGMENT_BIT:
3816*61046927SAndroid Build Coastguard Worker return VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT;
3817*61046927SAndroid Build Coastguard Worker default:
3818*61046927SAndroid Build Coastguard Worker unreachable("Invalid shader stage");
3819*61046927SAndroid Build Coastguard Worker }
3820*61046927SAndroid Build Coastguard Worker }
3821*61046927SAndroid Build Coastguard Worker
3822*61046927SAndroid Build Coastguard Worker template <chip CHIP>
3823*61046927SAndroid Build Coastguard Worker static VkResult
tu_pipeline_builder_build(struct tu_pipeline_builder * builder,struct tu_pipeline ** pipeline)3824*61046927SAndroid Build Coastguard Worker tu_pipeline_builder_build(struct tu_pipeline_builder *builder,
3825*61046927SAndroid Build Coastguard Worker struct tu_pipeline **pipeline)
3826*61046927SAndroid Build Coastguard Worker {
3827*61046927SAndroid Build Coastguard Worker VkResult result;
3828*61046927SAndroid Build Coastguard Worker
3829*61046927SAndroid Build Coastguard Worker if (builder->create_flags & VK_PIPELINE_CREATE_2_LIBRARY_BIT_KHR) {
3830*61046927SAndroid Build Coastguard Worker *pipeline = (struct tu_pipeline *) vk_object_zalloc(
3831*61046927SAndroid Build Coastguard Worker &builder->device->vk, builder->alloc,
3832*61046927SAndroid Build Coastguard Worker sizeof(struct tu_graphics_lib_pipeline),
3833*61046927SAndroid Build Coastguard Worker VK_OBJECT_TYPE_PIPELINE);
3834*61046927SAndroid Build Coastguard Worker if (!*pipeline)
3835*61046927SAndroid Build Coastguard Worker return VK_ERROR_OUT_OF_HOST_MEMORY;
3836*61046927SAndroid Build Coastguard Worker (*pipeline)->type = TU_PIPELINE_GRAPHICS_LIB;
3837*61046927SAndroid Build Coastguard Worker } else {
3838*61046927SAndroid Build Coastguard Worker *pipeline = (struct tu_pipeline *) vk_object_zalloc(
3839*61046927SAndroid Build Coastguard Worker &builder->device->vk, builder->alloc,
3840*61046927SAndroid Build Coastguard Worker sizeof(struct tu_graphics_pipeline),
3841*61046927SAndroid Build Coastguard Worker VK_OBJECT_TYPE_PIPELINE);
3842*61046927SAndroid Build Coastguard Worker if (!*pipeline)
3843*61046927SAndroid Build Coastguard Worker return VK_ERROR_OUT_OF_HOST_MEMORY;
3844*61046927SAndroid Build Coastguard Worker (*pipeline)->type = TU_PIPELINE_GRAPHICS;
3845*61046927SAndroid Build Coastguard Worker }
3846*61046927SAndroid Build Coastguard Worker
3847*61046927SAndroid Build Coastguard Worker (*pipeline)->executables_mem_ctx = ralloc_context(NULL);
3848*61046927SAndroid Build Coastguard Worker util_dynarray_init(&(*pipeline)->executables, (*pipeline)->executables_mem_ctx);
3849*61046927SAndroid Build Coastguard Worker
3850*61046927SAndroid Build Coastguard Worker tu_pipeline_builder_parse_libraries(builder, *pipeline);
3851*61046927SAndroid Build Coastguard Worker
3852*61046927SAndroid Build Coastguard Worker VkShaderStageFlags stages = 0;
3853*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < builder->create_info->stageCount; i++) {
3854*61046927SAndroid Build Coastguard Worker VkShaderStageFlagBits stage = builder->create_info->pStages[i].stage;
3855*61046927SAndroid Build Coastguard Worker
3856*61046927SAndroid Build Coastguard Worker /* Ignore shader stages that don't need to be imported. */
3857*61046927SAndroid Build Coastguard Worker if (!(vk_shader_stage_to_pipeline_library_flags(stage) & builder->state))
3858*61046927SAndroid Build Coastguard Worker continue;
3859*61046927SAndroid Build Coastguard Worker
3860*61046927SAndroid Build Coastguard Worker stages |= stage;
3861*61046927SAndroid Build Coastguard Worker }
3862*61046927SAndroid Build Coastguard Worker builder->active_stages = stages;
3863*61046927SAndroid Build Coastguard Worker
3864*61046927SAndroid Build Coastguard Worker (*pipeline)->active_stages = stages;
3865*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < builder->num_libraries; i++)
3866*61046927SAndroid Build Coastguard Worker (*pipeline)->active_stages |= builder->libraries[i]->base.active_stages;
3867*61046927SAndroid Build Coastguard Worker
3868*61046927SAndroid Build Coastguard Worker /* Compile and upload shaders unless a library has already done that. */
3869*61046927SAndroid Build Coastguard Worker if ((*pipeline)->program.vs_state.size == 0) {
3870*61046927SAndroid Build Coastguard Worker tu_pipeline_builder_parse_layout(builder, *pipeline);
3871*61046927SAndroid Build Coastguard Worker
3872*61046927SAndroid Build Coastguard Worker result = tu_pipeline_builder_compile_shaders(builder, *pipeline);
3873*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
3874*61046927SAndroid Build Coastguard Worker vk_object_free(&builder->device->vk, builder->alloc, *pipeline);
3875*61046927SAndroid Build Coastguard Worker return result;
3876*61046927SAndroid Build Coastguard Worker }
3877*61046927SAndroid Build Coastguard Worker }
3878*61046927SAndroid Build Coastguard Worker
3879*61046927SAndroid Build Coastguard Worker result = tu_pipeline_allocate_cs(builder->device, *pipeline,
3880*61046927SAndroid Build Coastguard Worker &builder->layout, builder, NULL);
3881*61046927SAndroid Build Coastguard Worker
3882*61046927SAndroid Build Coastguard Worker
3883*61046927SAndroid Build Coastguard Worker if (set_combined_state(builder, *pipeline,
3884*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT |
3885*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT)) {
3886*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
3887*61046927SAndroid Build Coastguard Worker vk_object_free(&builder->device->vk, builder->alloc, *pipeline);
3888*61046927SAndroid Build Coastguard Worker return result;
3889*61046927SAndroid Build Coastguard Worker }
3890*61046927SAndroid Build Coastguard Worker
3891*61046927SAndroid Build Coastguard Worker tu_emit_program_state<CHIP>(&(*pipeline)->cs, &(*pipeline)->program,
3892*61046927SAndroid Build Coastguard Worker (*pipeline)->shaders);
3893*61046927SAndroid Build Coastguard Worker
3894*61046927SAndroid Build Coastguard Worker if (CHIP == A6XX) {
3895*61046927SAndroid Build Coastguard Worker /* Blob doesn't preload state on A7XX, likely preloading either
3896*61046927SAndroid Build Coastguard Worker * doesn't work or doesn't provide benefits.
3897*61046927SAndroid Build Coastguard Worker */
3898*61046927SAndroid Build Coastguard Worker tu6_emit_load_state(builder->device, *pipeline, &builder->layout);
3899*61046927SAndroid Build Coastguard Worker }
3900*61046927SAndroid Build Coastguard Worker }
3901*61046927SAndroid Build Coastguard Worker
3902*61046927SAndroid Build Coastguard Worker if (builder->state & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT) {
3903*61046927SAndroid Build Coastguard Worker tu_pipeline_builder_parse_depth_stencil(builder, *pipeline);
3904*61046927SAndroid Build Coastguard Worker }
3905*61046927SAndroid Build Coastguard Worker
3906*61046927SAndroid Build Coastguard Worker if (builder->state &
3907*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT) {
3908*61046927SAndroid Build Coastguard Worker tu_pipeline_builder_parse_multisample_and_color_blend(builder, *pipeline);
3909*61046927SAndroid Build Coastguard Worker }
3910*61046927SAndroid Build Coastguard Worker
3911*61046927SAndroid Build Coastguard Worker if (set_combined_state(builder, *pipeline,
3912*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT |
3913*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT)) {
3914*61046927SAndroid Build Coastguard Worker tu_pipeline_builder_parse_rasterization_order(builder, *pipeline);
3915*61046927SAndroid Build Coastguard Worker }
3916*61046927SAndroid Build Coastguard Worker
3917*61046927SAndroid Build Coastguard Worker tu_pipeline_builder_emit_state<CHIP>(builder, *pipeline);
3918*61046927SAndroid Build Coastguard Worker
3919*61046927SAndroid Build Coastguard Worker if ((*pipeline)->type == TU_PIPELINE_GRAPHICS_LIB) {
3920*61046927SAndroid Build Coastguard Worker struct tu_graphics_lib_pipeline *library =
3921*61046927SAndroid Build Coastguard Worker tu_pipeline_to_graphics_lib(*pipeline);
3922*61046927SAndroid Build Coastguard Worker result = vk_graphics_pipeline_state_copy(&builder->device->vk,
3923*61046927SAndroid Build Coastguard Worker &library->graphics_state,
3924*61046927SAndroid Build Coastguard Worker &builder->graphics_state,
3925*61046927SAndroid Build Coastguard Worker builder->alloc,
3926*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_OBJECT,
3927*61046927SAndroid Build Coastguard Worker &library->state_data);
3928*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
3929*61046927SAndroid Build Coastguard Worker tu_pipeline_finish(*pipeline, builder->device, builder->alloc);
3930*61046927SAndroid Build Coastguard Worker return result;
3931*61046927SAndroid Build Coastguard Worker }
3932*61046927SAndroid Build Coastguard Worker } else {
3933*61046927SAndroid Build Coastguard Worker struct tu_graphics_pipeline *gfx_pipeline =
3934*61046927SAndroid Build Coastguard Worker tu_pipeline_to_graphics(*pipeline);
3935*61046927SAndroid Build Coastguard Worker gfx_pipeline->dynamic_state.ms.sample_locations =
3936*61046927SAndroid Build Coastguard Worker &gfx_pipeline->sample_locations;
3937*61046927SAndroid Build Coastguard Worker vk_dynamic_graphics_state_fill(&gfx_pipeline->dynamic_state,
3938*61046927SAndroid Build Coastguard Worker &builder->graphics_state);
3939*61046927SAndroid Build Coastguard Worker gfx_pipeline->feedback_loops =
3940*61046927SAndroid Build Coastguard Worker vk_pipeline_flags_feedback_loops(builder->graphics_state.pipeline_flags);
3941*61046927SAndroid Build Coastguard Worker gfx_pipeline->feedback_loop_may_involve_textures =
3942*61046927SAndroid Build Coastguard Worker builder->graphics_state.feedback_loop_not_input_only;
3943*61046927SAndroid Build Coastguard Worker }
3944*61046927SAndroid Build Coastguard Worker
3945*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
3946*61046927SAndroid Build Coastguard Worker }
3947*61046927SAndroid Build Coastguard Worker
3948*61046927SAndroid Build Coastguard Worker static void
tu_pipeline_builder_finish(struct tu_pipeline_builder * builder)3949*61046927SAndroid Build Coastguard Worker tu_pipeline_builder_finish(struct tu_pipeline_builder *builder)
3950*61046927SAndroid Build Coastguard Worker {
3951*61046927SAndroid Build Coastguard Worker ralloc_free(builder->mem_ctx);
3952*61046927SAndroid Build Coastguard Worker }
3953*61046927SAndroid Build Coastguard Worker
3954*61046927SAndroid Build Coastguard Worker void
tu_fill_render_pass_state(struct vk_render_pass_state * rp,const struct tu_render_pass * pass,const struct tu_subpass * subpass)3955*61046927SAndroid Build Coastguard Worker tu_fill_render_pass_state(struct vk_render_pass_state *rp,
3956*61046927SAndroid Build Coastguard Worker const struct tu_render_pass *pass,
3957*61046927SAndroid Build Coastguard Worker const struct tu_subpass *subpass)
3958*61046927SAndroid Build Coastguard Worker {
3959*61046927SAndroid Build Coastguard Worker rp->view_mask = subpass->multiview_mask;
3960*61046927SAndroid Build Coastguard Worker rp->color_attachment_count = subpass->color_count;
3961*61046927SAndroid Build Coastguard Worker
3962*61046927SAndroid Build Coastguard Worker const uint32_t a = subpass->depth_stencil_attachment.attachment;
3963*61046927SAndroid Build Coastguard Worker rp->depth_attachment_format = VK_FORMAT_UNDEFINED;
3964*61046927SAndroid Build Coastguard Worker rp->stencil_attachment_format = VK_FORMAT_UNDEFINED;
3965*61046927SAndroid Build Coastguard Worker rp->attachments = MESA_VK_RP_ATTACHMENT_NONE;
3966*61046927SAndroid Build Coastguard Worker if (a != VK_ATTACHMENT_UNUSED) {
3967*61046927SAndroid Build Coastguard Worker VkFormat ds_format = pass->attachments[a].format;
3968*61046927SAndroid Build Coastguard Worker if (vk_format_has_depth(ds_format) && subpass->depth_used) {
3969*61046927SAndroid Build Coastguard Worker rp->depth_attachment_format = ds_format;
3970*61046927SAndroid Build Coastguard Worker rp->attachments |= MESA_VK_RP_ATTACHMENT_DEPTH_BIT;
3971*61046927SAndroid Build Coastguard Worker }
3972*61046927SAndroid Build Coastguard Worker if (vk_format_has_stencil(ds_format) && subpass->stencil_used) {
3973*61046927SAndroid Build Coastguard Worker rp->stencil_attachment_format = ds_format;
3974*61046927SAndroid Build Coastguard Worker rp->attachments |= MESA_VK_RP_ATTACHMENT_STENCIL_BIT;
3975*61046927SAndroid Build Coastguard Worker }
3976*61046927SAndroid Build Coastguard Worker }
3977*61046927SAndroid Build Coastguard Worker
3978*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < subpass->color_count; i++) {
3979*61046927SAndroid Build Coastguard Worker const uint32_t a = subpass->color_attachments[i].attachment;
3980*61046927SAndroid Build Coastguard Worker if (a == VK_ATTACHMENT_UNUSED) {
3981*61046927SAndroid Build Coastguard Worker rp->color_attachment_formats[i] = VK_FORMAT_UNDEFINED;
3982*61046927SAndroid Build Coastguard Worker continue;
3983*61046927SAndroid Build Coastguard Worker }
3984*61046927SAndroid Build Coastguard Worker
3985*61046927SAndroid Build Coastguard Worker rp->color_attachment_formats[i] = pass->attachments[a].format;
3986*61046927SAndroid Build Coastguard Worker rp->attachments |= MESA_VK_RP_ATTACHMENT_COLOR_BIT(i);
3987*61046927SAndroid Build Coastguard Worker }
3988*61046927SAndroid Build Coastguard Worker }
3989*61046927SAndroid Build Coastguard Worker
3990*61046927SAndroid Build Coastguard Worker static void
tu_pipeline_builder_init_graphics(struct tu_pipeline_builder * builder,struct tu_device * dev,struct vk_pipeline_cache * cache,const VkGraphicsPipelineCreateInfo * create_info,VkPipelineCreateFlags2KHR flags,const VkAllocationCallbacks * alloc)3991*61046927SAndroid Build Coastguard Worker tu_pipeline_builder_init_graphics(
3992*61046927SAndroid Build Coastguard Worker struct tu_pipeline_builder *builder,
3993*61046927SAndroid Build Coastguard Worker struct tu_device *dev,
3994*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache *cache,
3995*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *create_info,
3996*61046927SAndroid Build Coastguard Worker VkPipelineCreateFlags2KHR flags,
3997*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc)
3998*61046927SAndroid Build Coastguard Worker {
3999*61046927SAndroid Build Coastguard Worker *builder = (struct tu_pipeline_builder) {
4000*61046927SAndroid Build Coastguard Worker .device = dev,
4001*61046927SAndroid Build Coastguard Worker .mem_ctx = ralloc_context(NULL),
4002*61046927SAndroid Build Coastguard Worker .cache = cache,
4003*61046927SAndroid Build Coastguard Worker .alloc = alloc,
4004*61046927SAndroid Build Coastguard Worker .create_info = create_info,
4005*61046927SAndroid Build Coastguard Worker .create_flags = flags,
4006*61046927SAndroid Build Coastguard Worker };
4007*61046927SAndroid Build Coastguard Worker
4008*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineLibraryCreateInfoEXT *gpl_info =
4009*61046927SAndroid Build Coastguard Worker vk_find_struct_const(builder->create_info->pNext,
4010*61046927SAndroid Build Coastguard Worker GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT);
4011*61046927SAndroid Build Coastguard Worker
4012*61046927SAndroid Build Coastguard Worker const VkPipelineLibraryCreateInfoKHR *library_info =
4013*61046927SAndroid Build Coastguard Worker vk_find_struct_const(builder->create_info->pNext,
4014*61046927SAndroid Build Coastguard Worker PIPELINE_LIBRARY_CREATE_INFO_KHR);
4015*61046927SAndroid Build Coastguard Worker
4016*61046927SAndroid Build Coastguard Worker if (gpl_info) {
4017*61046927SAndroid Build Coastguard Worker builder->state = gpl_info->flags;
4018*61046927SAndroid Build Coastguard Worker } else {
4019*61046927SAndroid Build Coastguard Worker /* Implement this bit of spec text:
4020*61046927SAndroid Build Coastguard Worker *
4021*61046927SAndroid Build Coastguard Worker * If this structure is omitted, and either
4022*61046927SAndroid Build Coastguard Worker * VkGraphicsPipelineCreateInfo::flags includes
4023*61046927SAndroid Build Coastguard Worker * VK_PIPELINE_CREATE_LIBRARY_BIT_KHR or the
4024*61046927SAndroid Build Coastguard Worker * VkGraphicsPipelineCreateInfo::pNext chain includes a
4025*61046927SAndroid Build Coastguard Worker * VkPipelineLibraryCreateInfoKHR structure with a libraryCount
4026*61046927SAndroid Build Coastguard Worker * greater than 0, it is as if flags is 0. Otherwise if this
4027*61046927SAndroid Build Coastguard Worker * structure is omitted, it is as if flags includes all possible
4028*61046927SAndroid Build Coastguard Worker * subsets of the graphics pipeline (i.e. a complete graphics
4029*61046927SAndroid Build Coastguard Worker * pipeline).
4030*61046927SAndroid Build Coastguard Worker */
4031*61046927SAndroid Build Coastguard Worker if ((library_info && library_info->libraryCount > 0) ||
4032*61046927SAndroid Build Coastguard Worker (builder->create_flags & VK_PIPELINE_CREATE_2_LIBRARY_BIT_KHR)) {
4033*61046927SAndroid Build Coastguard Worker builder->state = 0;
4034*61046927SAndroid Build Coastguard Worker } else {
4035*61046927SAndroid Build Coastguard Worker builder->state =
4036*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT |
4037*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT |
4038*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT |
4039*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT;
4040*61046927SAndroid Build Coastguard Worker }
4041*61046927SAndroid Build Coastguard Worker }
4042*61046927SAndroid Build Coastguard Worker
4043*61046927SAndroid Build Coastguard Worker bool rasterizer_discard_dynamic = false;
4044*61046927SAndroid Build Coastguard Worker if (create_info->pDynamicState) {
4045*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < create_info->pDynamicState->dynamicStateCount; i++) {
4046*61046927SAndroid Build Coastguard Worker if (create_info->pDynamicState->pDynamicStates[i] ==
4047*61046927SAndroid Build Coastguard Worker VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE) {
4048*61046927SAndroid Build Coastguard Worker rasterizer_discard_dynamic = true;
4049*61046927SAndroid Build Coastguard Worker break;
4050*61046927SAndroid Build Coastguard Worker }
4051*61046927SAndroid Build Coastguard Worker }
4052*61046927SAndroid Build Coastguard Worker }
4053*61046927SAndroid Build Coastguard Worker
4054*61046927SAndroid Build Coastguard Worker builder->rasterizer_discard =
4055*61046927SAndroid Build Coastguard Worker (builder->state & VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT) &&
4056*61046927SAndroid Build Coastguard Worker !rasterizer_discard_dynamic &&
4057*61046927SAndroid Build Coastguard Worker builder->create_info->pRasterizationState->rasterizerDiscardEnable;
4058*61046927SAndroid Build Coastguard Worker
4059*61046927SAndroid Build Coastguard Worker struct vk_render_pass_state rp_state = {};
4060*61046927SAndroid Build Coastguard Worker const struct vk_render_pass_state *driver_rp = NULL;
4061*61046927SAndroid Build Coastguard Worker VkPipelineCreateFlags2KHR rp_flags = 0;
4062*61046927SAndroid Build Coastguard Worker
4063*61046927SAndroid Build Coastguard Worker builder->unscaled_input_fragcoord = 0;
4064*61046927SAndroid Build Coastguard Worker
4065*61046927SAndroid Build Coastguard Worker /* Extract information we need from the turnip renderpass. This will be
4066*61046927SAndroid Build Coastguard Worker * filled out automatically if the app is using dynamic rendering or
4067*61046927SAndroid Build Coastguard Worker * renderpasses are emulated.
4068*61046927SAndroid Build Coastguard Worker */
4069*61046927SAndroid Build Coastguard Worker if (!TU_DEBUG(DYNAMIC) &&
4070*61046927SAndroid Build Coastguard Worker (builder->state &
4071*61046927SAndroid Build Coastguard Worker (VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT |
4072*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT |
4073*61046927SAndroid Build Coastguard Worker VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT)) &&
4074*61046927SAndroid Build Coastguard Worker builder->create_info->renderPass) {
4075*61046927SAndroid Build Coastguard Worker const struct tu_render_pass *pass =
4076*61046927SAndroid Build Coastguard Worker tu_render_pass_from_handle(create_info->renderPass);
4077*61046927SAndroid Build Coastguard Worker const struct tu_subpass *subpass =
4078*61046927SAndroid Build Coastguard Worker &pass->subpasses[create_info->subpass];
4079*61046927SAndroid Build Coastguard Worker
4080*61046927SAndroid Build Coastguard Worker tu_fill_render_pass_state(&rp_state, pass, subpass);
4081*61046927SAndroid Build Coastguard Worker
4082*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < subpass->input_count; i++) {
4083*61046927SAndroid Build Coastguard Worker /* Input attachments stored in GMEM must be loaded with unscaled
4084*61046927SAndroid Build Coastguard Worker * FragCoord.
4085*61046927SAndroid Build Coastguard Worker */
4086*61046927SAndroid Build Coastguard Worker if (subpass->input_attachments[i].patch_input_gmem)
4087*61046927SAndroid Build Coastguard Worker builder->unscaled_input_fragcoord |= 1u << i;
4088*61046927SAndroid Build Coastguard Worker }
4089*61046927SAndroid Build Coastguard Worker
4090*61046927SAndroid Build Coastguard Worker if (subpass->feedback_loop_color) {
4091*61046927SAndroid Build Coastguard Worker rp_flags |=
4092*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATE_2_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
4093*61046927SAndroid Build Coastguard Worker }
4094*61046927SAndroid Build Coastguard Worker
4095*61046927SAndroid Build Coastguard Worker if (subpass->feedback_loop_ds) {
4096*61046927SAndroid Build Coastguard Worker rp_flags |=
4097*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATE_2_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
4098*61046927SAndroid Build Coastguard Worker }
4099*61046927SAndroid Build Coastguard Worker
4100*61046927SAndroid Build Coastguard Worker if (pass->fragment_density_map.attachment != VK_ATTACHMENT_UNUSED) {
4101*61046927SAndroid Build Coastguard Worker rp_flags |=
4102*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT;
4103*61046927SAndroid Build Coastguard Worker }
4104*61046927SAndroid Build Coastguard Worker
4105*61046927SAndroid Build Coastguard Worker builder->unscaled_input_fragcoord = 0;
4106*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < subpass->input_count; i++) {
4107*61046927SAndroid Build Coastguard Worker /* Input attachments stored in GMEM must be loaded with unscaled
4108*61046927SAndroid Build Coastguard Worker * FragCoord.
4109*61046927SAndroid Build Coastguard Worker */
4110*61046927SAndroid Build Coastguard Worker if (subpass->input_attachments[i].patch_input_gmem)
4111*61046927SAndroid Build Coastguard Worker builder->unscaled_input_fragcoord |= 1u << i;
4112*61046927SAndroid Build Coastguard Worker }
4113*61046927SAndroid Build Coastguard Worker
4114*61046927SAndroid Build Coastguard Worker driver_rp = &rp_state;
4115*61046927SAndroid Build Coastguard Worker }
4116*61046927SAndroid Build Coastguard Worker
4117*61046927SAndroid Build Coastguard Worker vk_graphics_pipeline_state_fill(&dev->vk,
4118*61046927SAndroid Build Coastguard Worker &builder->graphics_state,
4119*61046927SAndroid Build Coastguard Worker builder->create_info,
4120*61046927SAndroid Build Coastguard Worker driver_rp,
4121*61046927SAndroid Build Coastguard Worker rp_flags,
4122*61046927SAndroid Build Coastguard Worker &builder->all_state,
4123*61046927SAndroid Build Coastguard Worker NULL, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT,
4124*61046927SAndroid Build Coastguard Worker NULL);
4125*61046927SAndroid Build Coastguard Worker
4126*61046927SAndroid Build Coastguard Worker if (builder->graphics_state.rp) {
4127*61046927SAndroid Build Coastguard Worker builder->fragment_density_map = (builder->graphics_state.pipeline_flags &
4128*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT) ||
4129*61046927SAndroid Build Coastguard Worker TU_DEBUG(FDM);
4130*61046927SAndroid Build Coastguard Worker }
4131*61046927SAndroid Build Coastguard Worker }
4132*61046927SAndroid Build Coastguard Worker
4133*61046927SAndroid Build Coastguard Worker template <chip CHIP>
4134*61046927SAndroid Build Coastguard Worker static VkResult
tu_graphics_pipeline_create(VkDevice device,VkPipelineCache pipelineCache,const VkGraphicsPipelineCreateInfo * pCreateInfo,VkPipelineCreateFlags2KHR flags,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipeline)4135*61046927SAndroid Build Coastguard Worker tu_graphics_pipeline_create(VkDevice device,
4136*61046927SAndroid Build Coastguard Worker VkPipelineCache pipelineCache,
4137*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *pCreateInfo,
4138*61046927SAndroid Build Coastguard Worker VkPipelineCreateFlags2KHR flags,
4139*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator,
4140*61046927SAndroid Build Coastguard Worker VkPipeline *pPipeline)
4141*61046927SAndroid Build Coastguard Worker {
4142*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(tu_device, dev, device);
4143*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(vk_pipeline_cache, cache, pipelineCache);
4144*61046927SAndroid Build Coastguard Worker
4145*61046927SAndroid Build Coastguard Worker cache = cache ? cache : dev->mem_cache;
4146*61046927SAndroid Build Coastguard Worker
4147*61046927SAndroid Build Coastguard Worker struct tu_pipeline_builder builder;
4148*61046927SAndroid Build Coastguard Worker tu_pipeline_builder_init_graphics(&builder, dev, cache,
4149*61046927SAndroid Build Coastguard Worker pCreateInfo, flags, pAllocator);
4150*61046927SAndroid Build Coastguard Worker
4151*61046927SAndroid Build Coastguard Worker struct tu_pipeline *pipeline = NULL;
4152*61046927SAndroid Build Coastguard Worker VkResult result = tu_pipeline_builder_build<CHIP>(&builder, &pipeline);
4153*61046927SAndroid Build Coastguard Worker tu_pipeline_builder_finish(&builder);
4154*61046927SAndroid Build Coastguard Worker
4155*61046927SAndroid Build Coastguard Worker if (result == VK_SUCCESS) {
4156*61046927SAndroid Build Coastguard Worker TU_RMV(graphics_pipeline_create, dev, tu_pipeline_to_graphics(pipeline));
4157*61046927SAndroid Build Coastguard Worker
4158*61046927SAndroid Build Coastguard Worker *pPipeline = tu_pipeline_to_handle(pipeline);
4159*61046927SAndroid Build Coastguard Worker } else
4160*61046927SAndroid Build Coastguard Worker *pPipeline = VK_NULL_HANDLE;
4161*61046927SAndroid Build Coastguard Worker
4162*61046927SAndroid Build Coastguard Worker return result;
4163*61046927SAndroid Build Coastguard Worker }
4164*61046927SAndroid Build Coastguard Worker
4165*61046927SAndroid Build Coastguard Worker template <chip CHIP>
4166*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
tu_CreateGraphicsPipelines(VkDevice device,VkPipelineCache pipelineCache,uint32_t count,const VkGraphicsPipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)4167*61046927SAndroid Build Coastguard Worker tu_CreateGraphicsPipelines(VkDevice device,
4168*61046927SAndroid Build Coastguard Worker VkPipelineCache pipelineCache,
4169*61046927SAndroid Build Coastguard Worker uint32_t count,
4170*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *pCreateInfos,
4171*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator,
4172*61046927SAndroid Build Coastguard Worker VkPipeline *pPipelines)
4173*61046927SAndroid Build Coastguard Worker {
4174*61046927SAndroid Build Coastguard Worker MESA_TRACE_FUNC();
4175*61046927SAndroid Build Coastguard Worker VkResult final_result = VK_SUCCESS;
4176*61046927SAndroid Build Coastguard Worker uint32_t i = 0;
4177*61046927SAndroid Build Coastguard Worker
4178*61046927SAndroid Build Coastguard Worker for (; i < count; i++) {
4179*61046927SAndroid Build Coastguard Worker VkPipelineCreateFlags2KHR flags =
4180*61046927SAndroid Build Coastguard Worker vk_graphics_pipeline_create_flags(&pCreateInfos[i]);
4181*61046927SAndroid Build Coastguard Worker
4182*61046927SAndroid Build Coastguard Worker VkResult result =
4183*61046927SAndroid Build Coastguard Worker tu_graphics_pipeline_create<CHIP>(device, pipelineCache,
4184*61046927SAndroid Build Coastguard Worker &pCreateInfos[i], flags,
4185*61046927SAndroid Build Coastguard Worker pAllocator, &pPipelines[i]);
4186*61046927SAndroid Build Coastguard Worker
4187*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
4188*61046927SAndroid Build Coastguard Worker final_result = result;
4189*61046927SAndroid Build Coastguard Worker pPipelines[i] = VK_NULL_HANDLE;
4190*61046927SAndroid Build Coastguard Worker
4191*61046927SAndroid Build Coastguard Worker if (flags & VK_PIPELINE_CREATE_2_EARLY_RETURN_ON_FAILURE_BIT_KHR)
4192*61046927SAndroid Build Coastguard Worker break;
4193*61046927SAndroid Build Coastguard Worker }
4194*61046927SAndroid Build Coastguard Worker }
4195*61046927SAndroid Build Coastguard Worker
4196*61046927SAndroid Build Coastguard Worker for (; i < count; i++)
4197*61046927SAndroid Build Coastguard Worker pPipelines[i] = VK_NULL_HANDLE;
4198*61046927SAndroid Build Coastguard Worker
4199*61046927SAndroid Build Coastguard Worker return final_result;
4200*61046927SAndroid Build Coastguard Worker }
4201*61046927SAndroid Build Coastguard Worker TU_GENX(tu_CreateGraphicsPipelines);
4202*61046927SAndroid Build Coastguard Worker
4203*61046927SAndroid Build Coastguard Worker template <chip CHIP>
4204*61046927SAndroid Build Coastguard Worker static VkResult
tu_compute_pipeline_create(VkDevice device,VkPipelineCache pipelineCache,const VkComputePipelineCreateInfo * pCreateInfo,VkPipelineCreateFlags2KHR flags,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipeline)4205*61046927SAndroid Build Coastguard Worker tu_compute_pipeline_create(VkDevice device,
4206*61046927SAndroid Build Coastguard Worker VkPipelineCache pipelineCache,
4207*61046927SAndroid Build Coastguard Worker const VkComputePipelineCreateInfo *pCreateInfo,
4208*61046927SAndroid Build Coastguard Worker VkPipelineCreateFlags2KHR flags,
4209*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator,
4210*61046927SAndroid Build Coastguard Worker VkPipeline *pPipeline)
4211*61046927SAndroid Build Coastguard Worker {
4212*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(tu_device, dev, device);
4213*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(vk_pipeline_cache, cache, pipelineCache);
4214*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(tu_pipeline_layout, layout, pCreateInfo->layout);
4215*61046927SAndroid Build Coastguard Worker const VkPipelineShaderStageCreateInfo *stage_info = &pCreateInfo->stage;
4216*61046927SAndroid Build Coastguard Worker VkResult result;
4217*61046927SAndroid Build Coastguard Worker const struct ir3_shader_variant *v = NULL;
4218*61046927SAndroid Build Coastguard Worker
4219*61046927SAndroid Build Coastguard Worker cache = cache ? cache : dev->mem_cache;
4220*61046927SAndroid Build Coastguard Worker
4221*61046927SAndroid Build Coastguard Worker struct tu_compute_pipeline *pipeline;
4222*61046927SAndroid Build Coastguard Worker
4223*61046927SAndroid Build Coastguard Worker *pPipeline = VK_NULL_HANDLE;
4224*61046927SAndroid Build Coastguard Worker
4225*61046927SAndroid Build Coastguard Worker VkPipelineCreationFeedback pipeline_feedback = {
4226*61046927SAndroid Build Coastguard Worker .flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT,
4227*61046927SAndroid Build Coastguard Worker };
4228*61046927SAndroid Build Coastguard Worker
4229*61046927SAndroid Build Coastguard Worker const VkPipelineCreationFeedbackCreateInfo *creation_feedback =
4230*61046927SAndroid Build Coastguard Worker vk_find_struct_const(pCreateInfo->pNext, PIPELINE_CREATION_FEEDBACK_CREATE_INFO);
4231*61046927SAndroid Build Coastguard Worker
4232*61046927SAndroid Build Coastguard Worker int64_t pipeline_start = os_time_get_nano();
4233*61046927SAndroid Build Coastguard Worker
4234*61046927SAndroid Build Coastguard Worker pipeline = (struct tu_compute_pipeline *) vk_object_zalloc(
4235*61046927SAndroid Build Coastguard Worker &dev->vk, pAllocator, sizeof(*pipeline), VK_OBJECT_TYPE_PIPELINE);
4236*61046927SAndroid Build Coastguard Worker if (!pipeline)
4237*61046927SAndroid Build Coastguard Worker return VK_ERROR_OUT_OF_HOST_MEMORY;
4238*61046927SAndroid Build Coastguard Worker pipeline->base.type = TU_PIPELINE_COMPUTE;
4239*61046927SAndroid Build Coastguard Worker
4240*61046927SAndroid Build Coastguard Worker pipeline->base.executables_mem_ctx = ralloc_context(NULL);
4241*61046927SAndroid Build Coastguard Worker util_dynarray_init(&pipeline->base.executables, pipeline->base.executables_mem_ctx);
4242*61046927SAndroid Build Coastguard Worker pipeline->base.active_stages = VK_SHADER_STAGE_COMPUTE_BIT;
4243*61046927SAndroid Build Coastguard Worker
4244*61046927SAndroid Build Coastguard Worker struct tu_shader_key key = { };
4245*61046927SAndroid Build Coastguard Worker bool allow_varying_subgroup_size =
4246*61046927SAndroid Build Coastguard Worker (stage_info->flags &
4247*61046927SAndroid Build Coastguard Worker VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT);
4248*61046927SAndroid Build Coastguard Worker bool require_full_subgroups =
4249*61046927SAndroid Build Coastguard Worker stage_info->flags &
4250*61046927SAndroid Build Coastguard Worker VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT;
4251*61046927SAndroid Build Coastguard Worker const VkPipelineShaderStageRequiredSubgroupSizeCreateInfo *subgroup_info =
4252*61046927SAndroid Build Coastguard Worker vk_find_struct_const(stage_info,
4253*61046927SAndroid Build Coastguard Worker PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO);
4254*61046927SAndroid Build Coastguard Worker tu_shader_key_subgroup_size(&key, allow_varying_subgroup_size,
4255*61046927SAndroid Build Coastguard Worker require_full_subgroups, subgroup_info,
4256*61046927SAndroid Build Coastguard Worker dev);
4257*61046927SAndroid Build Coastguard Worker
4258*61046927SAndroid Build Coastguard Worker void *pipeline_mem_ctx = ralloc_context(NULL);
4259*61046927SAndroid Build Coastguard Worker
4260*61046927SAndroid Build Coastguard Worker unsigned char pipeline_sha1[20];
4261*61046927SAndroid Build Coastguard Worker tu_hash_compute(pipeline_sha1, flags, stage_info, layout, &key, dev->compiler);
4262*61046927SAndroid Build Coastguard Worker
4263*61046927SAndroid Build Coastguard Worker struct tu_shader *shader = NULL;
4264*61046927SAndroid Build Coastguard Worker
4265*61046927SAndroid Build Coastguard Worker const bool executable_info = flags &
4266*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATE_2_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR;
4267*61046927SAndroid Build Coastguard Worker
4268*61046927SAndroid Build Coastguard Worker bool application_cache_hit = false;
4269*61046927SAndroid Build Coastguard Worker
4270*61046927SAndroid Build Coastguard Worker if (!executable_info) {
4271*61046927SAndroid Build Coastguard Worker shader =
4272*61046927SAndroid Build Coastguard Worker tu_pipeline_cache_lookup(cache, pipeline_sha1, sizeof(pipeline_sha1),
4273*61046927SAndroid Build Coastguard Worker &application_cache_hit);
4274*61046927SAndroid Build Coastguard Worker }
4275*61046927SAndroid Build Coastguard Worker
4276*61046927SAndroid Build Coastguard Worker if (application_cache_hit && cache != dev->mem_cache) {
4277*61046927SAndroid Build Coastguard Worker pipeline_feedback.flags |=
4278*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT;
4279*61046927SAndroid Build Coastguard Worker }
4280*61046927SAndroid Build Coastguard Worker
4281*61046927SAndroid Build Coastguard Worker char *nir_initial_disasm = NULL;
4282*61046927SAndroid Build Coastguard Worker
4283*61046927SAndroid Build Coastguard Worker if (!shader) {
4284*61046927SAndroid Build Coastguard Worker if (flags &
4285*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_KHR) {
4286*61046927SAndroid Build Coastguard Worker result = VK_PIPELINE_COMPILE_REQUIRED;
4287*61046927SAndroid Build Coastguard Worker goto fail;
4288*61046927SAndroid Build Coastguard Worker }
4289*61046927SAndroid Build Coastguard Worker
4290*61046927SAndroid Build Coastguard Worker struct ir3_shader_key ir3_key = {};
4291*61046927SAndroid Build Coastguard Worker
4292*61046927SAndroid Build Coastguard Worker nir_shader *nir = tu_spirv_to_nir(dev, pipeline_mem_ctx, flags,
4293*61046927SAndroid Build Coastguard Worker stage_info, MESA_SHADER_COMPUTE);
4294*61046927SAndroid Build Coastguard Worker
4295*61046927SAndroid Build Coastguard Worker nir_initial_disasm = executable_info ?
4296*61046927SAndroid Build Coastguard Worker nir_shader_as_str(nir, pipeline->base.executables_mem_ctx) : NULL;
4297*61046927SAndroid Build Coastguard Worker
4298*61046927SAndroid Build Coastguard Worker result = tu_shader_create(dev, &shader, nir, &key, &ir3_key,
4299*61046927SAndroid Build Coastguard Worker pipeline_sha1, sizeof(pipeline_sha1), layout,
4300*61046927SAndroid Build Coastguard Worker executable_info);
4301*61046927SAndroid Build Coastguard Worker if (!shader) {
4302*61046927SAndroid Build Coastguard Worker goto fail;
4303*61046927SAndroid Build Coastguard Worker }
4304*61046927SAndroid Build Coastguard Worker
4305*61046927SAndroid Build Coastguard Worker shader = tu_pipeline_cache_insert(cache, shader);
4306*61046927SAndroid Build Coastguard Worker }
4307*61046927SAndroid Build Coastguard Worker
4308*61046927SAndroid Build Coastguard Worker pipeline_feedback.duration = os_time_get_nano() - pipeline_start;
4309*61046927SAndroid Build Coastguard Worker
4310*61046927SAndroid Build Coastguard Worker if (creation_feedback) {
4311*61046927SAndroid Build Coastguard Worker *creation_feedback->pPipelineCreationFeedback = pipeline_feedback;
4312*61046927SAndroid Build Coastguard Worker assert(creation_feedback->pipelineStageCreationFeedbackCount == 1);
4313*61046927SAndroid Build Coastguard Worker creation_feedback->pPipelineStageCreationFeedbacks[0] = pipeline_feedback;
4314*61046927SAndroid Build Coastguard Worker }
4315*61046927SAndroid Build Coastguard Worker
4316*61046927SAndroid Build Coastguard Worker pipeline->base.active_desc_sets = shader->active_desc_sets;
4317*61046927SAndroid Build Coastguard Worker
4318*61046927SAndroid Build Coastguard Worker v = shader->variant;
4319*61046927SAndroid Build Coastguard Worker
4320*61046927SAndroid Build Coastguard Worker tu_pipeline_set_linkage(&pipeline->base.program.link[MESA_SHADER_COMPUTE],
4321*61046927SAndroid Build Coastguard Worker &shader->const_state, v);
4322*61046927SAndroid Build Coastguard Worker
4323*61046927SAndroid Build Coastguard Worker result = tu_pipeline_allocate_cs(dev, &pipeline->base, layout, NULL, v);
4324*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
4325*61046927SAndroid Build Coastguard Worker goto fail;
4326*61046927SAndroid Build Coastguard Worker
4327*61046927SAndroid Build Coastguard Worker for (int i = 0; i < 3; i++)
4328*61046927SAndroid Build Coastguard Worker pipeline->local_size[i] = v->local_size[i];
4329*61046927SAndroid Build Coastguard Worker
4330*61046927SAndroid Build Coastguard Worker if (CHIP == A6XX) {
4331*61046927SAndroid Build Coastguard Worker tu6_emit_load_state(dev, &pipeline->base, layout);
4332*61046927SAndroid Build Coastguard Worker }
4333*61046927SAndroid Build Coastguard Worker
4334*61046927SAndroid Build Coastguard Worker tu_append_executable(&pipeline->base, v, nir_initial_disasm);
4335*61046927SAndroid Build Coastguard Worker
4336*61046927SAndroid Build Coastguard Worker pipeline->instrlen = v->instrlen;
4337*61046927SAndroid Build Coastguard Worker
4338*61046927SAndroid Build Coastguard Worker pipeline->base.shaders[MESA_SHADER_COMPUTE] = shader;
4339*61046927SAndroid Build Coastguard Worker
4340*61046927SAndroid Build Coastguard Worker ralloc_free(pipeline_mem_ctx);
4341*61046927SAndroid Build Coastguard Worker
4342*61046927SAndroid Build Coastguard Worker TU_RMV(compute_pipeline_create, dev, pipeline);
4343*61046927SAndroid Build Coastguard Worker
4344*61046927SAndroid Build Coastguard Worker *pPipeline = tu_pipeline_to_handle(&pipeline->base);
4345*61046927SAndroid Build Coastguard Worker
4346*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
4347*61046927SAndroid Build Coastguard Worker
4348*61046927SAndroid Build Coastguard Worker fail:
4349*61046927SAndroid Build Coastguard Worker if (shader)
4350*61046927SAndroid Build Coastguard Worker vk_pipeline_cache_object_unref(&dev->vk, &shader->base);
4351*61046927SAndroid Build Coastguard Worker
4352*61046927SAndroid Build Coastguard Worker ralloc_free(pipeline_mem_ctx);
4353*61046927SAndroid Build Coastguard Worker
4354*61046927SAndroid Build Coastguard Worker vk_object_free(&dev->vk, pAllocator, pipeline);
4355*61046927SAndroid Build Coastguard Worker
4356*61046927SAndroid Build Coastguard Worker return result;
4357*61046927SAndroid Build Coastguard Worker }
4358*61046927SAndroid Build Coastguard Worker
4359*61046927SAndroid Build Coastguard Worker template <chip CHIP>
4360*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
tu_CreateComputePipelines(VkDevice device,VkPipelineCache pipelineCache,uint32_t count,const VkComputePipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)4361*61046927SAndroid Build Coastguard Worker tu_CreateComputePipelines(VkDevice device,
4362*61046927SAndroid Build Coastguard Worker VkPipelineCache pipelineCache,
4363*61046927SAndroid Build Coastguard Worker uint32_t count,
4364*61046927SAndroid Build Coastguard Worker const VkComputePipelineCreateInfo *pCreateInfos,
4365*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator,
4366*61046927SAndroid Build Coastguard Worker VkPipeline *pPipelines)
4367*61046927SAndroid Build Coastguard Worker {
4368*61046927SAndroid Build Coastguard Worker MESA_TRACE_FUNC();
4369*61046927SAndroid Build Coastguard Worker VkResult final_result = VK_SUCCESS;
4370*61046927SAndroid Build Coastguard Worker uint32_t i = 0;
4371*61046927SAndroid Build Coastguard Worker
4372*61046927SAndroid Build Coastguard Worker for (; i < count; i++) {
4373*61046927SAndroid Build Coastguard Worker VkPipelineCreateFlags2KHR flags =
4374*61046927SAndroid Build Coastguard Worker vk_compute_pipeline_create_flags(&pCreateInfos[i]);
4375*61046927SAndroid Build Coastguard Worker
4376*61046927SAndroid Build Coastguard Worker VkResult result =
4377*61046927SAndroid Build Coastguard Worker tu_compute_pipeline_create<CHIP>(device, pipelineCache,
4378*61046927SAndroid Build Coastguard Worker &pCreateInfos[i], flags,
4379*61046927SAndroid Build Coastguard Worker pAllocator, &pPipelines[i]);
4380*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
4381*61046927SAndroid Build Coastguard Worker final_result = result;
4382*61046927SAndroid Build Coastguard Worker pPipelines[i] = VK_NULL_HANDLE;
4383*61046927SAndroid Build Coastguard Worker
4384*61046927SAndroid Build Coastguard Worker if (flags &
4385*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATE_2_EARLY_RETURN_ON_FAILURE_BIT_KHR)
4386*61046927SAndroid Build Coastguard Worker break;
4387*61046927SAndroid Build Coastguard Worker }
4388*61046927SAndroid Build Coastguard Worker }
4389*61046927SAndroid Build Coastguard Worker
4390*61046927SAndroid Build Coastguard Worker for (; i < count; i++)
4391*61046927SAndroid Build Coastguard Worker pPipelines[i] = VK_NULL_HANDLE;
4392*61046927SAndroid Build Coastguard Worker
4393*61046927SAndroid Build Coastguard Worker return final_result;
4394*61046927SAndroid Build Coastguard Worker }
4395*61046927SAndroid Build Coastguard Worker TU_GENX(tu_CreateComputePipelines);
4396*61046927SAndroid Build Coastguard Worker
4397*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
tu_DestroyPipeline(VkDevice _device,VkPipeline _pipeline,const VkAllocationCallbacks * pAllocator)4398*61046927SAndroid Build Coastguard Worker tu_DestroyPipeline(VkDevice _device,
4399*61046927SAndroid Build Coastguard Worker VkPipeline _pipeline,
4400*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator)
4401*61046927SAndroid Build Coastguard Worker {
4402*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(tu_device, dev, _device);
4403*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(tu_pipeline, pipeline, _pipeline);
4404*61046927SAndroid Build Coastguard Worker
4405*61046927SAndroid Build Coastguard Worker if (!_pipeline)
4406*61046927SAndroid Build Coastguard Worker return;
4407*61046927SAndroid Build Coastguard Worker
4408*61046927SAndroid Build Coastguard Worker TU_RMV(resource_destroy, dev, pipeline);
4409*61046927SAndroid Build Coastguard Worker
4410*61046927SAndroid Build Coastguard Worker tu_pipeline_finish(pipeline, dev, pAllocator);
4411*61046927SAndroid Build Coastguard Worker vk_object_free(&dev->vk, pAllocator, pipeline);
4412*61046927SAndroid Build Coastguard Worker }
4413*61046927SAndroid Build Coastguard Worker
4414*61046927SAndroid Build Coastguard Worker #define WRITE_STR(field, ...) ({ \
4415*61046927SAndroid Build Coastguard Worker memset(field, 0, sizeof(field)); \
4416*61046927SAndroid Build Coastguard Worker UNUSED int _i = snprintf(field, sizeof(field), __VA_ARGS__); \
4417*61046927SAndroid Build Coastguard Worker assert(_i > 0 && _i < sizeof(field)); \
4418*61046927SAndroid Build Coastguard Worker })
4419*61046927SAndroid Build Coastguard Worker
4420*61046927SAndroid Build Coastguard Worker static const struct tu_pipeline_executable *
tu_pipeline_get_executable(struct tu_pipeline * pipeline,uint32_t index)4421*61046927SAndroid Build Coastguard Worker tu_pipeline_get_executable(struct tu_pipeline *pipeline, uint32_t index)
4422*61046927SAndroid Build Coastguard Worker {
4423*61046927SAndroid Build Coastguard Worker assert(index < util_dynarray_num_elements(&pipeline->executables,
4424*61046927SAndroid Build Coastguard Worker struct tu_pipeline_executable));
4425*61046927SAndroid Build Coastguard Worker return util_dynarray_element(
4426*61046927SAndroid Build Coastguard Worker &pipeline->executables, struct tu_pipeline_executable, index);
4427*61046927SAndroid Build Coastguard Worker }
4428*61046927SAndroid Build Coastguard Worker
4429*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
tu_GetPipelineExecutablePropertiesKHR(VkDevice _device,const VkPipelineInfoKHR * pPipelineInfo,uint32_t * pExecutableCount,VkPipelineExecutablePropertiesKHR * pProperties)4430*61046927SAndroid Build Coastguard Worker tu_GetPipelineExecutablePropertiesKHR(
4431*61046927SAndroid Build Coastguard Worker VkDevice _device,
4432*61046927SAndroid Build Coastguard Worker const VkPipelineInfoKHR* pPipelineInfo,
4433*61046927SAndroid Build Coastguard Worker uint32_t* pExecutableCount,
4434*61046927SAndroid Build Coastguard Worker VkPipelineExecutablePropertiesKHR* pProperties)
4435*61046927SAndroid Build Coastguard Worker {
4436*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(tu_device, dev, _device);
4437*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(tu_pipeline, pipeline, pPipelineInfo->pipeline);
4438*61046927SAndroid Build Coastguard Worker VK_OUTARRAY_MAKE_TYPED(VkPipelineExecutablePropertiesKHR, out,
4439*61046927SAndroid Build Coastguard Worker pProperties, pExecutableCount);
4440*61046927SAndroid Build Coastguard Worker
4441*61046927SAndroid Build Coastguard Worker util_dynarray_foreach (&pipeline->executables, struct tu_pipeline_executable, exe) {
4442*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutablePropertiesKHR, &out, props) {
4443*61046927SAndroid Build Coastguard Worker gl_shader_stage stage = exe->stage;
4444*61046927SAndroid Build Coastguard Worker props->stages = mesa_to_vk_shader_stage(stage);
4445*61046927SAndroid Build Coastguard Worker
4446*61046927SAndroid Build Coastguard Worker if (!exe->is_binning)
4447*61046927SAndroid Build Coastguard Worker WRITE_STR(props->name, "%s", _mesa_shader_stage_to_abbrev(stage));
4448*61046927SAndroid Build Coastguard Worker else
4449*61046927SAndroid Build Coastguard Worker WRITE_STR(props->name, "Binning VS");
4450*61046927SAndroid Build Coastguard Worker
4451*61046927SAndroid Build Coastguard Worker WRITE_STR(props->description, "%s", _mesa_shader_stage_to_string(stage));
4452*61046927SAndroid Build Coastguard Worker
4453*61046927SAndroid Build Coastguard Worker props->subgroupSize =
4454*61046927SAndroid Build Coastguard Worker dev->compiler->threadsize_base * (exe->stats.double_threadsize ? 2 : 1);
4455*61046927SAndroid Build Coastguard Worker }
4456*61046927SAndroid Build Coastguard Worker }
4457*61046927SAndroid Build Coastguard Worker
4458*61046927SAndroid Build Coastguard Worker return vk_outarray_status(&out);
4459*61046927SAndroid Build Coastguard Worker }
4460*61046927SAndroid Build Coastguard Worker
4461*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
tu_GetPipelineExecutableStatisticsKHR(VkDevice _device,const VkPipelineExecutableInfoKHR * pExecutableInfo,uint32_t * pStatisticCount,VkPipelineExecutableStatisticKHR * pStatistics)4462*61046927SAndroid Build Coastguard Worker tu_GetPipelineExecutableStatisticsKHR(
4463*61046927SAndroid Build Coastguard Worker VkDevice _device,
4464*61046927SAndroid Build Coastguard Worker const VkPipelineExecutableInfoKHR* pExecutableInfo,
4465*61046927SAndroid Build Coastguard Worker uint32_t* pStatisticCount,
4466*61046927SAndroid Build Coastguard Worker VkPipelineExecutableStatisticKHR* pStatistics)
4467*61046927SAndroid Build Coastguard Worker {
4468*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(tu_pipeline, pipeline, pExecutableInfo->pipeline);
4469*61046927SAndroid Build Coastguard Worker VK_OUTARRAY_MAKE_TYPED(VkPipelineExecutableStatisticKHR, out,
4470*61046927SAndroid Build Coastguard Worker pStatistics, pStatisticCount);
4471*61046927SAndroid Build Coastguard Worker
4472*61046927SAndroid Build Coastguard Worker const struct tu_pipeline_executable *exe =
4473*61046927SAndroid Build Coastguard Worker tu_pipeline_get_executable(pipeline, pExecutableInfo->executableIndex);
4474*61046927SAndroid Build Coastguard Worker
4475*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4476*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Max Waves Per Core");
4477*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4478*61046927SAndroid Build Coastguard Worker "Maximum number of simultaneous waves per core.");
4479*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4480*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.max_waves;
4481*61046927SAndroid Build Coastguard Worker }
4482*61046927SAndroid Build Coastguard Worker
4483*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4484*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Instruction Count");
4485*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4486*61046927SAndroid Build Coastguard Worker "Total number of IR3 instructions in the final generated "
4487*61046927SAndroid Build Coastguard Worker "shader executable.");
4488*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4489*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.instrs_count;
4490*61046927SAndroid Build Coastguard Worker }
4491*61046927SAndroid Build Coastguard Worker
4492*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4493*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Code size");
4494*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4495*61046927SAndroid Build Coastguard Worker "Total number of dwords in the final generated "
4496*61046927SAndroid Build Coastguard Worker "shader executable.");
4497*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4498*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.sizedwords;
4499*61046927SAndroid Build Coastguard Worker }
4500*61046927SAndroid Build Coastguard Worker
4501*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4502*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "NOPs Count");
4503*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4504*61046927SAndroid Build Coastguard Worker "Number of NOP instructions in the final generated "
4505*61046927SAndroid Build Coastguard Worker "shader executable.");
4506*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4507*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.nops_count;
4508*61046927SAndroid Build Coastguard Worker }
4509*61046927SAndroid Build Coastguard Worker
4510*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4511*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "MOV Count");
4512*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4513*61046927SAndroid Build Coastguard Worker "Number of MOV instructions in the final generated "
4514*61046927SAndroid Build Coastguard Worker "shader executable.");
4515*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4516*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.mov_count;
4517*61046927SAndroid Build Coastguard Worker }
4518*61046927SAndroid Build Coastguard Worker
4519*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4520*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "COV Count");
4521*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4522*61046927SAndroid Build Coastguard Worker "Number of COV instructions in the final generated "
4523*61046927SAndroid Build Coastguard Worker "shader executable.");
4524*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4525*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.cov_count;
4526*61046927SAndroid Build Coastguard Worker }
4527*61046927SAndroid Build Coastguard Worker
4528*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4529*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Registers used");
4530*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4531*61046927SAndroid Build Coastguard Worker "Number of registers used in the final generated "
4532*61046927SAndroid Build Coastguard Worker "shader executable.");
4533*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4534*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.max_reg + 1;
4535*61046927SAndroid Build Coastguard Worker }
4536*61046927SAndroid Build Coastguard Worker
4537*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4538*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Half-registers used");
4539*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4540*61046927SAndroid Build Coastguard Worker "Number of half-registers used in the final generated "
4541*61046927SAndroid Build Coastguard Worker "shader executable.");
4542*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4543*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.max_half_reg + 1;
4544*61046927SAndroid Build Coastguard Worker }
4545*61046927SAndroid Build Coastguard Worker
4546*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4547*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Last interpolation instruction");
4548*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4549*61046927SAndroid Build Coastguard Worker "The instruction where varying storage in Local Memory is released");
4550*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4551*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.last_baryf;
4552*61046927SAndroid Build Coastguard Worker }
4553*61046927SAndroid Build Coastguard Worker
4554*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4555*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Last helper instruction");
4556*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4557*61046927SAndroid Build Coastguard Worker "The instruction where helper invocations are killed");
4558*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4559*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.last_helper;
4560*61046927SAndroid Build Coastguard Worker }
4561*61046927SAndroid Build Coastguard Worker
4562*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4563*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Instructions with SS sync bit");
4564*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4565*61046927SAndroid Build Coastguard Worker "SS bit is set for instructions which depend on a result "
4566*61046927SAndroid Build Coastguard Worker "of \"long\" instructions to prevent RAW hazard.");
4567*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4568*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.ss;
4569*61046927SAndroid Build Coastguard Worker }
4570*61046927SAndroid Build Coastguard Worker
4571*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4572*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Instructions with SY sync bit");
4573*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4574*61046927SAndroid Build Coastguard Worker "SY bit is set for instructions which depend on a result "
4575*61046927SAndroid Build Coastguard Worker "of loads from global memory to prevent RAW hazard.");
4576*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4577*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.sy;
4578*61046927SAndroid Build Coastguard Worker }
4579*61046927SAndroid Build Coastguard Worker
4580*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4581*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Estimated cycles stalled on SS");
4582*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4583*61046927SAndroid Build Coastguard Worker "A better metric to estimate the impact of SS syncs.");
4584*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4585*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.sstall;
4586*61046927SAndroid Build Coastguard Worker }
4587*61046927SAndroid Build Coastguard Worker
4588*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4589*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Estimated cycles stalled on SY");
4590*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4591*61046927SAndroid Build Coastguard Worker "A better metric to estimate the impact of SY syncs.");
4592*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4593*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.systall;
4594*61046927SAndroid Build Coastguard Worker }
4595*61046927SAndroid Build Coastguard Worker
4596*61046927SAndroid Build Coastguard Worker for (int i = 0; i < ARRAY_SIZE(exe->stats.instrs_per_cat); i++) {
4597*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4598*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "cat%d instructions", i);
4599*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4600*61046927SAndroid Build Coastguard Worker "Number of cat%d instructions.", i);
4601*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4602*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.instrs_per_cat[i];
4603*61046927SAndroid Build Coastguard Worker }
4604*61046927SAndroid Build Coastguard Worker }
4605*61046927SAndroid Build Coastguard Worker
4606*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4607*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "STP Count");
4608*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4609*61046927SAndroid Build Coastguard Worker "Number of STore Private instructions in the final generated "
4610*61046927SAndroid Build Coastguard Worker "shader executable.");
4611*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4612*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.stp_count;
4613*61046927SAndroid Build Coastguard Worker }
4614*61046927SAndroid Build Coastguard Worker
4615*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4616*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "LDP Count");
4617*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4618*61046927SAndroid Build Coastguard Worker "Number of LoaD Private instructions in the final generated "
4619*61046927SAndroid Build Coastguard Worker "shader executable.");
4620*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4621*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.ldp_count;
4622*61046927SAndroid Build Coastguard Worker }
4623*61046927SAndroid Build Coastguard Worker
4624*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4625*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Early preamble");
4626*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4627*61046927SAndroid Build Coastguard Worker "Whether the preamble will be executed early.");
4628*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR;
4629*61046927SAndroid Build Coastguard Worker stat->value.b32 = exe->stats.early_preamble;
4630*61046927SAndroid Build Coastguard Worker }
4631*61046927SAndroid Build Coastguard Worker
4632*61046927SAndroid Build Coastguard Worker return vk_outarray_status(&out);
4633*61046927SAndroid Build Coastguard Worker }
4634*61046927SAndroid Build Coastguard Worker
4635*61046927SAndroid Build Coastguard Worker static bool
write_ir_text(VkPipelineExecutableInternalRepresentationKHR * ir,const char * data)4636*61046927SAndroid Build Coastguard Worker write_ir_text(VkPipelineExecutableInternalRepresentationKHR* ir,
4637*61046927SAndroid Build Coastguard Worker const char *data)
4638*61046927SAndroid Build Coastguard Worker {
4639*61046927SAndroid Build Coastguard Worker ir->isText = VK_TRUE;
4640*61046927SAndroid Build Coastguard Worker
4641*61046927SAndroid Build Coastguard Worker size_t data_len = strlen(data) + 1;
4642*61046927SAndroid Build Coastguard Worker
4643*61046927SAndroid Build Coastguard Worker if (ir->pData == NULL) {
4644*61046927SAndroid Build Coastguard Worker ir->dataSize = data_len;
4645*61046927SAndroid Build Coastguard Worker return true;
4646*61046927SAndroid Build Coastguard Worker }
4647*61046927SAndroid Build Coastguard Worker
4648*61046927SAndroid Build Coastguard Worker strncpy((char *) ir->pData, data, ir->dataSize);
4649*61046927SAndroid Build Coastguard Worker if (ir->dataSize < data_len)
4650*61046927SAndroid Build Coastguard Worker return false;
4651*61046927SAndroid Build Coastguard Worker
4652*61046927SAndroid Build Coastguard Worker ir->dataSize = data_len;
4653*61046927SAndroid Build Coastguard Worker return true;
4654*61046927SAndroid Build Coastguard Worker }
4655*61046927SAndroid Build Coastguard Worker
4656*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
tu_GetPipelineExecutableInternalRepresentationsKHR(VkDevice _device,const VkPipelineExecutableInfoKHR * pExecutableInfo,uint32_t * pInternalRepresentationCount,VkPipelineExecutableInternalRepresentationKHR * pInternalRepresentations)4657*61046927SAndroid Build Coastguard Worker tu_GetPipelineExecutableInternalRepresentationsKHR(
4658*61046927SAndroid Build Coastguard Worker VkDevice _device,
4659*61046927SAndroid Build Coastguard Worker const VkPipelineExecutableInfoKHR* pExecutableInfo,
4660*61046927SAndroid Build Coastguard Worker uint32_t* pInternalRepresentationCount,
4661*61046927SAndroid Build Coastguard Worker VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations)
4662*61046927SAndroid Build Coastguard Worker {
4663*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(tu_pipeline, pipeline, pExecutableInfo->pipeline);
4664*61046927SAndroid Build Coastguard Worker VK_OUTARRAY_MAKE_TYPED(VkPipelineExecutableInternalRepresentationKHR, out,
4665*61046927SAndroid Build Coastguard Worker pInternalRepresentations, pInternalRepresentationCount);
4666*61046927SAndroid Build Coastguard Worker bool incomplete_text = false;
4667*61046927SAndroid Build Coastguard Worker
4668*61046927SAndroid Build Coastguard Worker const struct tu_pipeline_executable *exe =
4669*61046927SAndroid Build Coastguard Worker tu_pipeline_get_executable(pipeline, pExecutableInfo->executableIndex);
4670*61046927SAndroid Build Coastguard Worker
4671*61046927SAndroid Build Coastguard Worker if (exe->nir_from_spirv) {
4672*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableInternalRepresentationKHR, &out, ir) {
4673*61046927SAndroid Build Coastguard Worker WRITE_STR(ir->name, "NIR from SPIRV");
4674*61046927SAndroid Build Coastguard Worker WRITE_STR(ir->description,
4675*61046927SAndroid Build Coastguard Worker "Initial NIR before any optimizations");
4676*61046927SAndroid Build Coastguard Worker
4677*61046927SAndroid Build Coastguard Worker if (!write_ir_text(ir, exe->nir_from_spirv))
4678*61046927SAndroid Build Coastguard Worker incomplete_text = true;
4679*61046927SAndroid Build Coastguard Worker }
4680*61046927SAndroid Build Coastguard Worker }
4681*61046927SAndroid Build Coastguard Worker
4682*61046927SAndroid Build Coastguard Worker if (exe->nir_final) {
4683*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableInternalRepresentationKHR, &out, ir) {
4684*61046927SAndroid Build Coastguard Worker WRITE_STR(ir->name, "Final NIR");
4685*61046927SAndroid Build Coastguard Worker WRITE_STR(ir->description,
4686*61046927SAndroid Build Coastguard Worker "Final NIR before going into the back-end compiler");
4687*61046927SAndroid Build Coastguard Worker
4688*61046927SAndroid Build Coastguard Worker if (!write_ir_text(ir, exe->nir_final))
4689*61046927SAndroid Build Coastguard Worker incomplete_text = true;
4690*61046927SAndroid Build Coastguard Worker }
4691*61046927SAndroid Build Coastguard Worker }
4692*61046927SAndroid Build Coastguard Worker
4693*61046927SAndroid Build Coastguard Worker if (exe->disasm) {
4694*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableInternalRepresentationKHR, &out, ir) {
4695*61046927SAndroid Build Coastguard Worker WRITE_STR(ir->name, "IR3 Assembly");
4696*61046927SAndroid Build Coastguard Worker WRITE_STR(ir->description,
4697*61046927SAndroid Build Coastguard Worker "Final IR3 assembly for the generated shader binary");
4698*61046927SAndroid Build Coastguard Worker
4699*61046927SAndroid Build Coastguard Worker if (!write_ir_text(ir, exe->disasm))
4700*61046927SAndroid Build Coastguard Worker incomplete_text = true;
4701*61046927SAndroid Build Coastguard Worker }
4702*61046927SAndroid Build Coastguard Worker }
4703*61046927SAndroid Build Coastguard Worker
4704*61046927SAndroid Build Coastguard Worker return incomplete_text ? VK_INCOMPLETE : vk_outarray_status(&out);
4705*61046927SAndroid Build Coastguard Worker }
4706