• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2019 Red Hat.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 /* use a gallium context to execute a command buffer */
25 
26 #include "lvp_private.h"
27 #include "lvp_acceleration_structure.h"
28 
29 #include "pipe/p_context.h"
30 #include "pipe/p_state.h"
31 #include "lvp_conv.h"
32 
33 #include "pipe/p_shader_tokens.h"
34 #include "tgsi/tgsi_from_mesa.h"
35 
36 #include "util/format/u_format.h"
37 #include "util/u_surface.h"
38 #include "util/u_sampler.h"
39 #include "util/box.h"
40 #include "util/u_inlines.h"
41 #include "util/u_math.h"
42 #include "util/u_memory.h"
43 #include "util/u_prim.h"
44 #include "util/u_prim_restart.h"
45 #include "util/format/u_format_zs.h"
46 #include "util/ptralloc.h"
47 #include "tgsi/tgsi_from_mesa.h"
48 
49 #include "vk_blend.h"
50 #include "vk_cmd_enqueue_entrypoints.h"
51 #include "vk_descriptor_update_template.h"
52 #include "vk_util.h"
53 #include "vk_enum_to_str.h"
54 
55 #define VK_PROTOTYPES
56 #include <vulkan/vulkan.h>
57 
58 #define DOUBLE_EQ(a, b) (fabs((a) - (b)) < DBL_EPSILON)
59 
60 enum gs_output {
61   GS_OUTPUT_NONE,
62   GS_OUTPUT_NOT_LINES,
63   GS_OUTPUT_LINES,
64 };
65 
66 struct descriptor_buffer_offset {
67    uint32_t buffer_index;
68    VkDeviceSize offset;
69 
70    const struct lvp_descriptor_set_layout *sampler_layout;
71 };
72 
73 struct lvp_render_attachment {
74    struct lvp_image_view *imgv;
75    VkResolveModeFlags resolve_mode;
76    struct lvp_image_view *resolve_imgv;
77    VkAttachmentLoadOp load_op;
78    VkAttachmentStoreOp store_op;
79    VkClearValue clear_value;
80    bool read_only;
81 };
82 
83 struct rendering_state {
84    struct pipe_context *pctx;
85    struct lvp_device *device; //for uniform inlining only
86    struct u_upload_mgr *uploader;
87    struct cso_context *cso;
88 
89    bool blend_dirty;
90    bool rs_dirty;
91    bool dsa_dirty;
92    bool dsa_no_stencil;
93    bool stencil_ref_dirty;
94    bool clip_state_dirty;
95    bool blend_color_dirty;
96    bool ve_dirty;
97    bool vb_dirty;
98    bool constbuf_dirty[LVP_SHADER_STAGES];
99    bool pcbuf_dirty[LVP_SHADER_STAGES];
100    bool has_pcbuf[LVP_SHADER_STAGES];
101    bool inlines_dirty[LVP_SHADER_STAGES];
102    bool vp_dirty;
103    bool scissor_dirty;
104    bool ib_dirty;
105    bool sample_mask_dirty;
106    bool min_samples_dirty;
107    bool poison_mem;
108    bool noop_fs_bound;
109    struct pipe_draw_indirect_info indirect_info;
110    struct pipe_draw_info info;
111 
112    struct pipe_grid_info dispatch_info;
113    struct pipe_grid_info trace_rays_info;
114    struct pipe_framebuffer_state framebuffer;
115    int fb_map[PIPE_MAX_COLOR_BUFS];
116    bool fb_remapped;
117 
118    struct pipe_blend_state blend_state;
119    struct {
120       float offset_units;
121       float offset_scale;
122       float offset_clamp;
123       bool enabled;
124    } depth_bias;
125    struct pipe_rasterizer_state rs_state;
126    struct pipe_depth_stencil_alpha_state dsa_state;
127 
128    struct pipe_blend_color blend_color;
129    struct pipe_stencil_ref stencil_ref;
130    struct pipe_clip_state clip_state;
131 
132    int num_scissors;
133    struct pipe_scissor_state scissors[16];
134 
135    int num_viewports;
136    struct pipe_viewport_state viewports[16];
137    struct {
138       float min, max;
139    } depth[16];
140 
141    uint8_t patch_vertices;
142    uint8_t index_size;
143    unsigned index_offset;
144    unsigned index_buffer_size; //UINT32_MAX for unset
145    struct pipe_resource *index_buffer;
146    struct pipe_constant_buffer const_buffer[LVP_SHADER_STAGES][16];
147    struct lvp_descriptor_set *desc_sets[LVP_PIPELINE_TYPE_COUNT][MAX_SETS];
148    struct pipe_resource *desc_buffers[MAX_SETS];
149    uint8_t *desc_buffer_addrs[MAX_SETS];
150    struct descriptor_buffer_offset desc_buffer_offsets[LVP_PIPELINE_TYPE_COUNT][MAX_SETS];
151    int num_const_bufs[LVP_SHADER_STAGES];
152    int num_vb;
153    unsigned start_vb;
154    bool vb_strides_dirty;
155    unsigned vb_strides[PIPE_MAX_ATTRIBS];
156    struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];
157    size_t vb_sizes[PIPE_MAX_ATTRIBS]; //UINT32_MAX for unset
158    uint8_t vertex_buffer_index[PIPE_MAX_ATTRIBS]; /* temp storage to sort for start_vb */
159    struct cso_velems_state velem;
160 
161    bool disable_multisample;
162    enum gs_output gs_output_lines : 2;
163 
164    uint32_t color_write_disables:8;
165    uint32_t pad:13;
166 
167    void *velems_cso;
168 
169    uint8_t push_constants[128 * 4];
170    uint16_t push_size[LVP_PIPELINE_TYPE_COUNT];
171    uint16_t gfx_push_sizes[LVP_SHADER_STAGES];
172 
173    VkRect2D render_area;
174    bool suspending;
175    bool render_cond;
176    uint32_t color_att_count;
177    struct lvp_render_attachment color_att[PIPE_MAX_COLOR_BUFS];
178    struct lvp_render_attachment depth_att;
179    struct lvp_render_attachment stencil_att;
180    struct lvp_image_view *ds_imgv;
181    struct lvp_image_view *ds_resolve_imgv;
182    uint32_t                                     forced_sample_count;
183    VkResolveModeFlagBits                        forced_depth_resolve_mode;
184    VkResolveModeFlagBits                        forced_stencil_resolve_mode;
185 
186    uint32_t sample_mask;
187    unsigned min_samples;
188    unsigned rast_samples;
189    float min_sample_shading;
190    bool force_min_sample;
191    bool sample_shading;
192    bool depth_clamp_sets_clip;
193 
194    uint32_t num_so_targets;
195    struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_BUFFERS];
196    uint32_t so_offsets[PIPE_MAX_SO_BUFFERS];
197 
198    struct lvp_shader *shaders[LVP_SHADER_STAGES];
199    bool compute_shader_dirty;
200 
201    bool tess_ccw;
202    void *tess_states[2];
203 
204    struct util_dynarray push_desc_sets;
205    struct util_dynarray internal_buffers;
206 
207    struct lvp_pipeline *exec_graph;
208 };
209 
210 static struct pipe_resource *
get_buffer_resource(struct pipe_context * ctx,void * mem)211 get_buffer_resource(struct pipe_context *ctx, void *mem)
212 {
213    struct pipe_screen *pscreen = ctx->screen;
214    struct pipe_resource templ = {0};
215 
216    if (!mem)
217       return NULL;
218 
219    templ.screen = pscreen;
220    templ.target = PIPE_BUFFER;
221    templ.format = PIPE_FORMAT_R8_UNORM;
222    templ.width0 = UINT32_MAX;
223    templ.height0 = 1;
224    templ.depth0 = 1;
225    templ.array_size = 1;
226    templ.bind |= PIPE_BIND_CONSTANT_BUFFER;
227    templ.flags = PIPE_RESOURCE_FLAG_DONT_OVER_ALLOCATE;
228 
229    uint64_t size;
230    struct pipe_resource *pres = pscreen->resource_create_unbacked(pscreen, &templ, &size);
231 
232    struct llvmpipe_memory_allocation alloc = {
233       .cpu_addr = mem,
234    };
235 
236    pscreen->resource_bind_backing(pscreen, pres, (void *)&alloc, 0, 0, 0);
237    return pres;
238 }
239 
240 ALWAYS_INLINE static void
assert_subresource_layers(const struct pipe_resource * pres,const struct lvp_image * image,const VkImageSubresourceLayers * layers,const VkOffset3D * offsets)241 assert_subresource_layers(const struct pipe_resource *pres,
242                           const struct lvp_image *image,
243                           const VkImageSubresourceLayers *layers, const VkOffset3D *offsets)
244 {
245 #ifndef NDEBUG
246    if (pres->target == PIPE_TEXTURE_3D) {
247       assert(layers->baseArrayLayer == 0);
248       assert(layers->layerCount == 1);
249       assert(offsets[0].z <= pres->depth0);
250       assert(offsets[1].z <= pres->depth0);
251    } else {
252       assert(layers->baseArrayLayer < pres->array_size);
253       assert(layers->baseArrayLayer + vk_image_subresource_layer_count(&image->vk, layers) <= pres->array_size);
254       assert(offsets[0].z == 0);
255       assert(offsets[1].z == 1);
256    }
257 #endif
258 }
259 
finish_fence(struct rendering_state * state)260 static void finish_fence(struct rendering_state *state)
261 {
262    struct pipe_fence_handle *handle = NULL;
263 
264    state->pctx->flush(state->pctx, &handle, 0);
265 
266    state->pctx->screen->fence_finish(state->pctx->screen,
267                                      NULL,
268                                      handle, OS_TIMEOUT_INFINITE);
269    state->pctx->screen->fence_reference(state->pctx->screen,
270                                         &handle, NULL);
271 }
272 
273 static unsigned
get_pcbuf_size(struct rendering_state * state,enum pipe_shader_type pstage)274 get_pcbuf_size(struct rendering_state *state, enum pipe_shader_type pstage)
275 {
276    enum lvp_pipeline_type type =
277       ffs(lvp_pipeline_types_from_shader_stages(mesa_to_vk_shader_stage(pstage))) - 1;
278    return state->has_pcbuf[pstage] ? state->push_size[type] : 0;
279 }
280 
281 static void
update_pcbuf(struct rendering_state * state,enum pipe_shader_type pstage,enum pipe_shader_type api_stage)282 update_pcbuf(struct rendering_state *state, enum pipe_shader_type pstage,
283              enum pipe_shader_type api_stage)
284 {
285    unsigned size = get_pcbuf_size(state, api_stage);
286    if (size) {
287       uint8_t *mem;
288       struct pipe_constant_buffer cbuf;
289       cbuf.buffer_size = size;
290       cbuf.buffer = NULL;
291       cbuf.user_buffer = NULL;
292       u_upload_alloc(state->uploader, 0, size, 64, &cbuf.buffer_offset, &cbuf.buffer, (void**)&mem);
293       memcpy(mem, state->push_constants, size);
294       state->pctx->set_constant_buffer(state->pctx, pstage, 0, true, &cbuf);
295    }
296    state->pcbuf_dirty[api_stage] = false;
297 }
298 
299 static void
update_inline_shader_state(struct rendering_state * state,enum pipe_shader_type sh,bool pcbuf_dirty)300 update_inline_shader_state(struct rendering_state *state, enum pipe_shader_type sh, bool pcbuf_dirty)
301 {
302    unsigned stage = tgsi_processor_to_shader_stage(sh);
303    state->inlines_dirty[sh] = false;
304    struct lvp_shader *shader = state->shaders[stage];
305    if (!shader || !shader->inlines.can_inline)
306       return;
307    struct lvp_inline_variant v;
308    v.mask = shader->inlines.can_inline;
309    /* these buffers have already been flushed in llvmpipe, so they're safe to read */
310    nir_shader *base_nir = shader->pipeline_nir->nir;
311    if (stage == MESA_SHADER_TESS_EVAL && state->tess_ccw)
312       base_nir = shader->tess_ccw->nir;
313    nir_function_impl *impl = nir_shader_get_entrypoint(base_nir);
314    unsigned ssa_alloc = impl->ssa_alloc;
315    unsigned count = shader->inlines.count[0];
316    if (count && pcbuf_dirty) {
317       unsigned push_size = get_pcbuf_size(state, sh);
318       for (unsigned i = 0; i < count; i++) {
319          unsigned offset = shader->inlines.uniform_offsets[0][i];
320          if (offset < push_size) {
321             memcpy(&v.vals[0][i], &state->push_constants[offset], sizeof(uint32_t));
322          }
323       }
324       for (unsigned i = count; i < MAX_INLINABLE_UNIFORMS; i++)
325          v.vals[0][i] = 0;
326    }
327    bool found = false;
328    struct set_entry *entry = _mesa_set_search_or_add_pre_hashed(&shader->inlines.variants, v.mask, &v, &found);
329    void *shader_state;
330    if (found) {
331       const struct lvp_inline_variant *variant = entry->key;
332       shader_state = variant->cso;
333    } else {
334       nir_shader *nir = nir_shader_clone(NULL, base_nir);
335       NIR_PASS_V(nir, lvp_inline_uniforms, shader, v.vals[0], 0);
336       lvp_shader_optimize(nir);
337       impl = nir_shader_get_entrypoint(nir);
338       if (ssa_alloc - impl->ssa_alloc < ssa_alloc / 2 &&
339          !shader->inlines.must_inline) {
340          /* not enough change; don't inline further */
341          shader->inlines.can_inline = 0;
342          ralloc_free(nir);
343          shader->shader_cso = lvp_shader_compile(state->device, shader, nir_shader_clone(NULL, shader->pipeline_nir->nir), true);
344          _mesa_set_remove(&shader->inlines.variants, entry);
345          shader_state = shader->shader_cso;
346       } else {
347          shader_state = lvp_shader_compile(state->device, shader, nir, true);
348          struct lvp_inline_variant *variant = mem_dup(&v, sizeof(v));
349          variant->cso = shader_state;
350          entry->key = variant;
351       }
352    }
353    switch (sh) {
354    case MESA_SHADER_VERTEX:
355       state->pctx->bind_vs_state(state->pctx, shader_state);
356       break;
357    case MESA_SHADER_TESS_CTRL:
358       state->pctx->bind_tcs_state(state->pctx, shader_state);
359       break;
360    case MESA_SHADER_TESS_EVAL:
361       state->pctx->bind_tes_state(state->pctx, shader_state);
362       break;
363    case MESA_SHADER_GEOMETRY:
364       state->pctx->bind_gs_state(state->pctx, shader_state);
365       break;
366    case MESA_SHADER_TASK:
367       state->pctx->bind_ts_state(state->pctx, shader_state);
368       break;
369    case MESA_SHADER_MESH:
370       state->pctx->bind_ms_state(state->pctx, shader_state);
371       break;
372    case MESA_SHADER_FRAGMENT:
373       state->pctx->bind_fs_state(state->pctx, shader_state);
374       state->noop_fs_bound = false;
375       break;
376    case MESA_SHADER_COMPUTE:
377       state->pctx->bind_compute_state(state->pctx, shader_state);
378       break;
379    default: break;
380    }
381 }
382 
emit_compute_state(struct rendering_state * state)383 static void emit_compute_state(struct rendering_state *state)
384 {
385    bool pcbuf_dirty = state->pcbuf_dirty[MESA_SHADER_COMPUTE];
386    if (state->pcbuf_dirty[MESA_SHADER_COMPUTE])
387       update_pcbuf(state, MESA_SHADER_COMPUTE, MESA_SHADER_COMPUTE);
388 
389    if (state->constbuf_dirty[MESA_SHADER_COMPUTE]) {
390       for (unsigned i = 0; i < state->num_const_bufs[MESA_SHADER_COMPUTE]; i++)
391          state->pctx->set_constant_buffer(state->pctx, MESA_SHADER_COMPUTE,
392                                           i + 1, false, &state->const_buffer[MESA_SHADER_COMPUTE][i]);
393       state->constbuf_dirty[MESA_SHADER_COMPUTE] = false;
394    }
395 
396    if (state->inlines_dirty[MESA_SHADER_COMPUTE] &&
397        state->shaders[MESA_SHADER_COMPUTE]->inlines.can_inline) {
398       update_inline_shader_state(state, MESA_SHADER_COMPUTE, pcbuf_dirty);
399    } else if (state->compute_shader_dirty) {
400       state->pctx->bind_compute_state(state->pctx, state->shaders[MESA_SHADER_COMPUTE]->shader_cso);
401    }
402 
403    state->compute_shader_dirty = false;
404 
405    state->pcbuf_dirty[MESA_SHADER_RAYGEN] = true;
406    state->constbuf_dirty[MESA_SHADER_RAYGEN] = true;
407 }
408 
409 static void
emit_fb_state(struct rendering_state * state)410 emit_fb_state(struct rendering_state *state)
411 {
412    if (state->fb_remapped) {
413       struct pipe_framebuffer_state fb = state->framebuffer;
414       memset(fb.cbufs, 0, sizeof(fb.cbufs));
415       for (unsigned i = 0; i < fb.nr_cbufs; i++) {
416          if (state->fb_map[i] < PIPE_MAX_COLOR_BUFS)
417             fb.cbufs[state->fb_map[i]] = state->framebuffer.cbufs[i];
418       }
419       state->pctx->set_framebuffer_state(state->pctx, &fb);
420    } else {
421       state->pctx->set_framebuffer_state(state->pctx, &state->framebuffer);
422    }
423 }
424 
425 static void
update_min_samples(struct rendering_state * state)426 update_min_samples(struct rendering_state *state)
427 {
428    state->min_samples = 1;
429    if (state->sample_shading) {
430       state->min_samples = ceil(state->rast_samples * state->min_sample_shading);
431       if (state->min_samples > 1)
432          state->min_samples = state->rast_samples;
433       if (state->min_samples < 1)
434          state->min_samples = 1;
435    }
436    if (state->force_min_sample)
437       state->min_samples = state->rast_samples;
438    if (state->rast_samples != state->framebuffer.samples) {
439       state->framebuffer.samples = state->rast_samples;
440       emit_fb_state(state);
441    }
442 }
443 
update_vertex_elements_buffer_index(struct rendering_state * state)444 static void update_vertex_elements_buffer_index(struct rendering_state *state)
445 {
446    for (int i = 0; i < state->velem.count; i++)
447       state->velem.velems[i].vertex_buffer_index = state->vertex_buffer_index[i] - state->start_vb;
448 }
449 
emit_state(struct rendering_state * state)450 static void emit_state(struct rendering_state *state)
451 {
452    if (!state->shaders[MESA_SHADER_FRAGMENT] && !state->noop_fs_bound) {
453       state->pctx->bind_fs_state(state->pctx, state->device->noop_fs);
454       state->noop_fs_bound = true;
455    }
456    if (state->blend_dirty) {
457       uint32_t mask = 0;
458       /* zero out the colormask values for disabled attachments */
459       if (state->color_write_disables) {
460          u_foreach_bit(att, state->color_write_disables) {
461             mask |= state->blend_state.rt[att].colormask << (att * 4);
462             state->blend_state.rt[att].colormask = 0;
463          }
464       }
465       if (state->fb_remapped) {
466          struct pipe_blend_state blend = state->blend_state;
467          for (unsigned i = 0; i < state->framebuffer.nr_cbufs; i++) {
468             if (state->fb_map[i] < PIPE_MAX_COLOR_BUFS) {
469                blend.rt[state->fb_map[i]] = state->blend_state.rt[i];
470             }
471          }
472          cso_set_blend(state->cso, &blend);
473       } else {
474          cso_set_blend(state->cso, &state->blend_state);
475       }
476       /* reset colormasks using saved bitmask */
477       if (state->color_write_disables) {
478          const uint32_t att_mask = BITFIELD_MASK(4);
479          u_foreach_bit(att, state->color_write_disables) {
480             state->blend_state.rt[att].colormask = (mask >> (att * 4)) & att_mask;
481          }
482       }
483       state->blend_dirty = false;
484    }
485 
486    if (state->rs_dirty) {
487       bool ms = state->rs_state.multisample;
488       if (state->disable_multisample &&
489           (state->gs_output_lines == GS_OUTPUT_LINES ||
490            (!state->shaders[MESA_SHADER_GEOMETRY] && u_reduced_prim(state->info.mode) == MESA_PRIM_LINES)))
491          state->rs_state.multisample = false;
492       assert(offsetof(struct pipe_rasterizer_state, offset_clamp) - offsetof(struct pipe_rasterizer_state, offset_units) == sizeof(float) * 2);
493       if (state->depth_bias.enabled) {
494          state->rs_state.offset_units = state->depth_bias.offset_units;
495          state->rs_state.offset_scale = state->depth_bias.offset_scale;
496          state->rs_state.offset_clamp = state->depth_bias.offset_clamp;
497          state->rs_state.offset_tri = true;
498          state->rs_state.offset_line = true;
499          state->rs_state.offset_point = true;
500       } else {
501          state->rs_state.offset_units = 0.0f;
502          state->rs_state.offset_scale = 0.0f;
503          state->rs_state.offset_clamp = 0.0f;
504          state->rs_state.offset_tri = false;
505          state->rs_state.offset_line = false;
506          state->rs_state.offset_point = false;
507       }
508       cso_set_rasterizer(state->cso, &state->rs_state);
509       state->rs_dirty = false;
510       state->rs_state.multisample = ms;
511    }
512 
513    if (state->dsa_dirty) {
514       bool s0_enabled = state->dsa_state.stencil[0].enabled;
515       bool s1_enabled = state->dsa_state.stencil[1].enabled;
516       if (state->dsa_no_stencil) {
517          state->dsa_state.stencil[0].enabled = false;
518          state->dsa_state.stencil[1].enabled = false;
519       }
520       cso_set_depth_stencil_alpha(state->cso, &state->dsa_state);
521       state->dsa_dirty = false;
522       state->dsa_state.stencil[0].enabled = s0_enabled;
523       state->dsa_state.stencil[1].enabled = s1_enabled;
524    }
525 
526    if (state->sample_mask_dirty) {
527       cso_set_sample_mask(state->cso, state->sample_mask);
528       state->sample_mask_dirty = false;
529    }
530 
531    if (state->min_samples_dirty) {
532       update_min_samples(state);
533       cso_set_min_samples(state->cso, state->min_samples);
534       state->min_samples_dirty = false;
535    }
536 
537    if (state->blend_color_dirty) {
538       state->pctx->set_blend_color(state->pctx, &state->blend_color);
539       state->blend_color_dirty = false;
540    }
541 
542    if (state->stencil_ref_dirty) {
543       cso_set_stencil_ref(state->cso, state->stencil_ref);
544       state->stencil_ref_dirty = false;
545    }
546 
547    if (state->ve_dirty)
548       update_vertex_elements_buffer_index(state);
549 
550    if (state->vb_strides_dirty) {
551       for (unsigned i = 0; i < state->velem.count; i++)
552          state->velem.velems[i].src_stride = state->vb_strides[state->velem.velems[i].vertex_buffer_index];
553       state->ve_dirty = true;
554       state->vb_strides_dirty = false;
555    }
556 
557    if (state->ve_dirty) {
558       cso_set_vertex_elements(state->cso, &state->velem);
559       state->ve_dirty = false;
560    }
561 
562    if (state->vb_dirty) {
563       cso_set_vertex_buffers(state->cso, state->num_vb, false, state->vb);
564       state->vb_dirty = false;
565    }
566 
567    bool pcbuf_dirty[LVP_SHADER_STAGES] = {false};
568 
569    lvp_forall_gfx_stage(sh) {
570       if (state->constbuf_dirty[sh]) {
571          for (unsigned idx = 0; idx < state->num_const_bufs[sh]; idx++)
572             state->pctx->set_constant_buffer(state->pctx, sh,
573                                              idx + 1, false, &state->const_buffer[sh][idx]);
574       }
575       state->constbuf_dirty[sh] = false;
576    }
577 
578    lvp_forall_gfx_stage(sh) {
579       pcbuf_dirty[sh] = state->pcbuf_dirty[sh];
580       if (state->pcbuf_dirty[sh])
581          update_pcbuf(state, sh, sh);
582    }
583 
584    lvp_forall_gfx_stage(sh) {
585       if (state->inlines_dirty[sh])
586          update_inline_shader_state(state, sh, pcbuf_dirty[sh]);
587    }
588 
589    if (state->vp_dirty) {
590       state->pctx->set_viewport_states(state->pctx, 0, state->num_viewports, state->viewports);
591       state->vp_dirty = false;
592    }
593 
594    if (state->scissor_dirty) {
595       state->pctx->set_scissor_states(state->pctx, 0, state->num_scissors, state->scissors);
596       state->scissor_dirty = false;
597    }
598 }
599 
600 static void
handle_compute_shader(struct rendering_state * state,struct lvp_shader * shader)601 handle_compute_shader(struct rendering_state *state, struct lvp_shader *shader)
602 {
603    state->shaders[MESA_SHADER_COMPUTE] = shader;
604 
605    state->has_pcbuf[MESA_SHADER_COMPUTE] = shader->push_constant_size > 0;
606 
607    if (!state->has_pcbuf[MESA_SHADER_COMPUTE])
608       state->pcbuf_dirty[MESA_SHADER_COMPUTE] = false;
609 
610    state->dispatch_info.block[0] = shader->pipeline_nir->nir->info.workgroup_size[0];
611    state->dispatch_info.block[1] = shader->pipeline_nir->nir->info.workgroup_size[1];
612    state->dispatch_info.block[2] = shader->pipeline_nir->nir->info.workgroup_size[2];
613    state->inlines_dirty[MESA_SHADER_COMPUTE] = shader->inlines.can_inline;
614    if (!shader->inlines.can_inline)
615       state->compute_shader_dirty = true;
616 }
617 
handle_compute_pipeline(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)618 static void handle_compute_pipeline(struct vk_cmd_queue_entry *cmd,
619                                     struct rendering_state *state)
620 {
621    LVP_FROM_HANDLE(lvp_pipeline, pipeline, cmd->u.bind_pipeline.pipeline);
622 
623    handle_compute_shader(state, &pipeline->shaders[MESA_SHADER_COMPUTE]);
624 }
625 
handle_ray_tracing_pipeline(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)626 static void handle_ray_tracing_pipeline(struct vk_cmd_queue_entry *cmd,
627                                     struct rendering_state *state)
628 {
629    LVP_FROM_HANDLE(lvp_pipeline, pipeline, cmd->u.bind_pipeline.pipeline);
630 
631    struct lvp_shader *shader = &pipeline->shaders[MESA_SHADER_RAYGEN];
632 
633    state->shaders[MESA_SHADER_RAYGEN] = shader;
634 
635    state->has_pcbuf[MESA_SHADER_RAYGEN] = shader->push_constant_size > 0;
636 
637    if (!state->has_pcbuf[MESA_SHADER_RAYGEN])
638       state->pcbuf_dirty[MESA_SHADER_RAYGEN] = false;
639 
640    state->trace_rays_info.block[0] = shader->pipeline_nir->nir->info.workgroup_size[0];
641    state->trace_rays_info.block[1] = shader->pipeline_nir->nir->info.workgroup_size[1];
642    state->trace_rays_info.block[2] = shader->pipeline_nir->nir->info.workgroup_size[2];
643 }
644 
645 static void
set_viewport_depth_xform(struct rendering_state * state,unsigned idx)646 set_viewport_depth_xform(struct rendering_state *state, unsigned idx)
647 {
648    double n = state->depth[idx].min;
649    double f = state->depth[idx].max;
650 
651    if (!state->rs_state.clip_halfz) {
652       state->viewports[idx].scale[2] = 0.5 * (f - n);
653       state->viewports[idx].translate[2] = 0.5 * (n + f);
654    } else {
655       state->viewports[idx].scale[2] = (f - n);
656       state->viewports[idx].translate[2] = n;
657    }
658 }
659 
660 static void
get_viewport_xform(struct rendering_state * state,const VkViewport * viewport,unsigned idx)661 get_viewport_xform(struct rendering_state *state,
662                    const VkViewport *viewport,
663                    unsigned idx)
664 {
665    float x = viewport->x;
666    float y = viewport->y;
667    float half_width = 0.5f * viewport->width;
668    float half_height = 0.5f * viewport->height;
669 
670    state->viewports[idx].scale[0] = half_width;
671    state->viewports[idx].translate[0] = half_width + x;
672    state->viewports[idx].scale[1] = half_height;
673    state->viewports[idx].translate[1] = half_height + y;
674 
675    memcpy(&state->depth[idx].min, &viewport->minDepth, sizeof(float) * 2);
676 }
677 
678 static void
update_samples(struct rendering_state * state,VkSampleCountFlags samples)679 update_samples(struct rendering_state *state, VkSampleCountFlags samples)
680 {
681    state->rast_samples = samples;
682    state->rs_dirty |= state->rs_state.multisample != (samples > 1);
683    state->rs_state.multisample = samples > 1;
684    state->min_samples_dirty = true;
685 }
686 
687 static void
handle_graphics_stages(struct rendering_state * state,VkShaderStageFlagBits shader_stages,bool dynamic_tess_origin)688 handle_graphics_stages(struct rendering_state *state, VkShaderStageFlagBits shader_stages, bool dynamic_tess_origin)
689 {
690    u_foreach_bit(b, shader_stages) {
691       VkShaderStageFlagBits vk_stage = (1 << b);
692       gl_shader_stage stage = vk_to_mesa_shader_stage(vk_stage);
693 
694       state->has_pcbuf[stage] = false;
695 
696       switch (vk_stage) {
697       case VK_SHADER_STAGE_FRAGMENT_BIT:
698          state->inlines_dirty[MESA_SHADER_FRAGMENT] = state->shaders[MESA_SHADER_FRAGMENT]->inlines.can_inline;
699          if (!state->shaders[MESA_SHADER_FRAGMENT]->inlines.can_inline) {
700             state->pctx->bind_fs_state(state->pctx, state->shaders[MESA_SHADER_FRAGMENT]->shader_cso);
701             state->noop_fs_bound = false;
702          }
703          break;
704       case VK_SHADER_STAGE_VERTEX_BIT:
705          state->inlines_dirty[MESA_SHADER_VERTEX] = state->shaders[MESA_SHADER_VERTEX]->inlines.can_inline;
706          if (!state->shaders[MESA_SHADER_VERTEX]->inlines.can_inline)
707             state->pctx->bind_vs_state(state->pctx, state->shaders[MESA_SHADER_VERTEX]->shader_cso);
708          break;
709       case VK_SHADER_STAGE_GEOMETRY_BIT:
710          state->inlines_dirty[MESA_SHADER_GEOMETRY] = state->shaders[MESA_SHADER_GEOMETRY]->inlines.can_inline;
711          if (!state->shaders[MESA_SHADER_GEOMETRY]->inlines.can_inline)
712             state->pctx->bind_gs_state(state->pctx, state->shaders[MESA_SHADER_GEOMETRY]->shader_cso);
713          state->gs_output_lines = state->shaders[MESA_SHADER_GEOMETRY]->pipeline_nir->nir->info.gs.output_primitive == MESA_PRIM_LINES ? GS_OUTPUT_LINES : GS_OUTPUT_NOT_LINES;
714          break;
715       case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
716          state->inlines_dirty[MESA_SHADER_TESS_CTRL] = state->shaders[MESA_SHADER_TESS_CTRL]->inlines.can_inline;
717          if (!state->shaders[MESA_SHADER_TESS_CTRL]->inlines.can_inline)
718             state->pctx->bind_tcs_state(state->pctx, state->shaders[MESA_SHADER_TESS_CTRL]->shader_cso);
719          break;
720       case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
721          state->inlines_dirty[MESA_SHADER_TESS_EVAL] = state->shaders[MESA_SHADER_TESS_EVAL]->inlines.can_inline;
722          state->tess_states[0] = NULL;
723          state->tess_states[1] = NULL;
724          if (!state->shaders[MESA_SHADER_TESS_EVAL]->inlines.can_inline) {
725             if (dynamic_tess_origin) {
726                state->tess_states[0] = state->shaders[MESA_SHADER_TESS_EVAL]->shader_cso;
727                state->tess_states[1] = state->shaders[MESA_SHADER_TESS_EVAL]->tess_ccw_cso;
728                state->pctx->bind_tes_state(state->pctx, state->tess_states[state->tess_ccw]);
729             } else {
730                state->pctx->bind_tes_state(state->pctx, state->shaders[MESA_SHADER_TESS_EVAL]->shader_cso);
731             }
732          }
733          if (!dynamic_tess_origin)
734             state->tess_ccw = false;
735          break;
736       case VK_SHADER_STAGE_TASK_BIT_EXT:
737          state->inlines_dirty[MESA_SHADER_TASK] = state->shaders[MESA_SHADER_TASK]->inlines.can_inline;
738          if (!state->shaders[MESA_SHADER_TASK]->inlines.can_inline)
739             state->pctx->bind_ts_state(state->pctx, state->shaders[MESA_SHADER_TASK]->shader_cso);
740          break;
741       case VK_SHADER_STAGE_MESH_BIT_EXT:
742          state->inlines_dirty[MESA_SHADER_MESH] = state->shaders[MESA_SHADER_MESH]->inlines.can_inline;
743          if (!state->shaders[MESA_SHADER_MESH]->inlines.can_inline)
744             state->pctx->bind_ms_state(state->pctx, state->shaders[MESA_SHADER_MESH]->shader_cso);
745          break;
746       default:
747          assert(0);
748          break;
749       }
750    }
751 }
752 
753 static void
unbind_graphics_stages(struct rendering_state * state,VkShaderStageFlagBits shader_stages)754 unbind_graphics_stages(struct rendering_state *state, VkShaderStageFlagBits shader_stages)
755 {
756    u_foreach_bit(vkstage, shader_stages) {
757       gl_shader_stage stage = vk_to_mesa_shader_stage(1<<vkstage);
758       state->has_pcbuf[stage] = false;
759       switch (stage) {
760       case MESA_SHADER_FRAGMENT:
761          if (state->shaders[MESA_SHADER_FRAGMENT])
762             state->pctx->bind_fs_state(state->pctx, NULL);
763          state->noop_fs_bound = false;
764          break;
765       case MESA_SHADER_GEOMETRY:
766          if (state->shaders[MESA_SHADER_GEOMETRY])
767             state->pctx->bind_gs_state(state->pctx, NULL);
768          break;
769       case MESA_SHADER_TESS_CTRL:
770          if (state->shaders[MESA_SHADER_TESS_CTRL])
771             state->pctx->bind_tcs_state(state->pctx, NULL);
772          break;
773       case MESA_SHADER_TESS_EVAL:
774          if (state->shaders[MESA_SHADER_TESS_EVAL])
775             state->pctx->bind_tes_state(state->pctx, NULL);
776          break;
777       case MESA_SHADER_VERTEX:
778          if (state->shaders[MESA_SHADER_VERTEX])
779             state->pctx->bind_vs_state(state->pctx, NULL);
780          break;
781       case MESA_SHADER_TASK:
782          if (state->shaders[MESA_SHADER_TASK])
783             state->pctx->bind_ts_state(state->pctx, NULL);
784          break;
785       case MESA_SHADER_MESH:
786          if (state->shaders[MESA_SHADER_MESH])
787             state->pctx->bind_ms_state(state->pctx, NULL);
788          break;
789       default:
790          unreachable("what stage is this?!");
791       }
792       state->shaders[stage] = NULL;
793    }
794 }
795 
796 static void
handle_graphics_pushconsts(struct rendering_state * state,gl_shader_stage stage,struct lvp_shader * shader)797 handle_graphics_pushconsts(struct rendering_state *state, gl_shader_stage stage, struct lvp_shader *shader)
798 {
799    state->has_pcbuf[stage] = shader->push_constant_size > 0;
800    if (!state->has_pcbuf[stage])
801       state->pcbuf_dirty[stage] = false;
802 }
803 
handle_graphics_pipeline(struct lvp_pipeline * pipeline,struct rendering_state * state)804 static void handle_graphics_pipeline(struct lvp_pipeline *pipeline,
805                                      struct rendering_state *state)
806 {
807    const struct vk_graphics_pipeline_state *ps = &pipeline->graphics_state;
808    lvp_pipeline_shaders_compile(pipeline, true);
809    bool dynamic_tess_origin = BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_TS_DOMAIN_ORIGIN);
810    unbind_graphics_stages(state,
811                           (~pipeline->graphics_state.shader_stages) &
812                           (VK_SHADER_STAGE_ALL_GRAPHICS |
813                            VK_SHADER_STAGE_TASK_BIT_EXT |
814                            VK_SHADER_STAGE_MESH_BIT_EXT));
815    lvp_forall_gfx_stage(sh) {
816       if (pipeline->graphics_state.shader_stages & mesa_to_vk_shader_stage(sh))
817          state->shaders[sh] = &pipeline->shaders[sh];
818    }
819 
820    handle_graphics_stages(state, pipeline->graphics_state.shader_stages, dynamic_tess_origin);
821    lvp_forall_gfx_stage(sh) {
822       handle_graphics_pushconsts(state, sh, &pipeline->shaders[sh]);
823    }
824 
825    /* rasterization state */
826    if (ps->rs) {
827       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_RS_DEPTH_CLAMP_ENABLE))
828          state->rs_state.depth_clamp = ps->rs->depth_clamp_enable;
829       if (BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_RS_DEPTH_CLIP_ENABLE)) {
830          state->depth_clamp_sets_clip = false;
831       } else {
832          state->depth_clamp_sets_clip =
833             ps->rs->depth_clip_enable == VK_MESA_DEPTH_CLIP_ENABLE_NOT_CLAMP;
834          if (state->depth_clamp_sets_clip)
835             state->rs_state.depth_clip_near = state->rs_state.depth_clip_far = !state->rs_state.depth_clamp;
836          else
837             state->rs_state.depth_clip_near = state->rs_state.depth_clip_far =
838                vk_rasterization_state_depth_clip_enable(ps->rs);
839       }
840 
841       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_RS_RASTERIZER_DISCARD_ENABLE))
842          state->rs_state.rasterizer_discard = ps->rs->rasterizer_discard_enable;
843 
844       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_RS_LINE_MODE)) {
845          state->rs_state.line_smooth = pipeline->line_smooth;
846          state->rs_state.line_rectangular = pipeline->line_rectangular;
847       }
848       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_RS_LINE_STIPPLE_ENABLE))
849          state->rs_state.line_stipple_enable = ps->rs->line.stipple.enable;
850       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_RS_POLYGON_MODE)) {
851          state->rs_state.fill_front = vk_polygon_mode_to_pipe(ps->rs->polygon_mode);
852          state->rs_state.fill_back = vk_polygon_mode_to_pipe(ps->rs->polygon_mode);
853       }
854       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_RS_PROVOKING_VERTEX)) {
855          state->rs_state.flatshade_first =
856             ps->rs->provoking_vertex == VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT;
857       }
858 
859       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_RS_LINE_WIDTH))
860          state->rs_state.line_width = ps->rs->line.width;
861       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_RS_LINE_STIPPLE)) {
862          state->rs_state.line_stipple_factor = ps->rs->line.stipple.factor - 1;
863          state->rs_state.line_stipple_pattern = ps->rs->line.stipple.pattern;
864       }
865 
866       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_RS_DEPTH_BIAS_ENABLE))
867          state->depth_bias.enabled = ps->rs->depth_bias.enable;
868       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS)) {
869          state->depth_bias.offset_units = ps->rs->depth_bias.constant_factor;
870          state->depth_bias.offset_scale = ps->rs->depth_bias.slope_factor;
871          state->depth_bias.offset_clamp = ps->rs->depth_bias.clamp;
872       }
873 
874       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_RS_CULL_MODE))
875          state->rs_state.cull_face = vk_cull_to_pipe(ps->rs->cull_mode);
876 
877       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_RS_FRONT_FACE))
878          state->rs_state.front_ccw = (ps->rs->front_face == VK_FRONT_FACE_COUNTER_CLOCKWISE);
879       state->rs_dirty = true;
880    }
881 
882    if (ps->ds) {
883       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_DS_DEPTH_TEST_ENABLE))
884          state->dsa_state.depth_enabled = ps->ds->depth.test_enable;
885       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_DS_DEPTH_WRITE_ENABLE))
886          state->dsa_state.depth_writemask = ps->ds->depth.write_enable;
887       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_DS_DEPTH_COMPARE_OP))
888          state->dsa_state.depth_func = ps->ds->depth.compare_op;
889       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_ENABLE))
890          state->dsa_state.depth_bounds_test = ps->ds->depth.bounds_test.enable;
891 
892       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_BOUNDS)) {
893          state->dsa_state.depth_bounds_min = ps->ds->depth.bounds_test.min;
894          state->dsa_state.depth_bounds_max = ps->ds->depth.bounds_test.max;
895       }
896 
897       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE)) {
898          state->dsa_state.stencil[0].enabled = ps->ds->stencil.test_enable;
899          state->dsa_state.stencil[1].enabled = ps->ds->stencil.test_enable;
900       }
901 
902       const struct vk_stencil_test_face_state *front = &ps->ds->stencil.front;
903       const struct vk_stencil_test_face_state *back = &ps->ds->stencil.back;
904 
905       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_OP)) {
906          state->dsa_state.stencil[0].func = front->op.compare;
907          state->dsa_state.stencil[0].fail_op = vk_conv_stencil_op(front->op.fail);
908          state->dsa_state.stencil[0].zpass_op = vk_conv_stencil_op(front->op.pass);
909          state->dsa_state.stencil[0].zfail_op = vk_conv_stencil_op(front->op.depth_fail);
910 
911          state->dsa_state.stencil[1].func = back->op.compare;
912          state->dsa_state.stencil[1].fail_op = vk_conv_stencil_op(back->op.fail);
913          state->dsa_state.stencil[1].zpass_op = vk_conv_stencil_op(back->op.pass);
914          state->dsa_state.stencil[1].zfail_op = vk_conv_stencil_op(back->op.depth_fail);
915       }
916 
917       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK)) {
918          state->dsa_state.stencil[0].valuemask = front->compare_mask;
919          state->dsa_state.stencil[1].valuemask = back->compare_mask;
920       }
921 
922       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK)) {
923          state->dsa_state.stencil[0].writemask = front->write_mask;
924          state->dsa_state.stencil[1].writemask = back->write_mask;
925       }
926 
927       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE)) {
928          state->stencil_ref.ref_value[0] = front->reference;
929          state->stencil_ref.ref_value[1] = back->reference;
930          state->stencil_ref_dirty = true;
931       }
932       state->dsa_dirty = true;
933    }
934 
935    if (ps->cb) {
936       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_CB_LOGIC_OP_ENABLE))
937          state->blend_state.logicop_enable = ps->cb->logic_op_enable;
938       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_CB_LOGIC_OP))
939          state->blend_state.logicop_func = vk_logic_op_to_pipe(ps->cb->logic_op);
940 
941       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES))
942          state->color_write_disables = ~ps->cb->color_write_enables;
943 
944       for (unsigned i = 0; i < ps->cb->attachment_count; i++) {
945          const struct vk_color_blend_attachment_state *att = &ps->cb->attachments[i];
946          if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_CB_WRITE_MASKS))
947             state->blend_state.rt[i].colormask = att->write_mask;
948          if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_CB_BLEND_ENABLES))
949             state->blend_state.rt[i].blend_enable = att->blend_enable;
950 
951          if (!att->blend_enable) {
952             state->blend_state.rt[i].rgb_func = 0;
953             state->blend_state.rt[i].rgb_src_factor = 0;
954             state->blend_state.rt[i].rgb_dst_factor = 0;
955             state->blend_state.rt[i].alpha_func = 0;
956             state->blend_state.rt[i].alpha_src_factor = 0;
957             state->blend_state.rt[i].alpha_dst_factor = 0;
958          } else if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_CB_BLEND_EQUATIONS)) {
959             state->blend_state.rt[i].rgb_func = vk_blend_op_to_pipe(att->color_blend_op);
960             state->blend_state.rt[i].rgb_src_factor = vk_blend_factor_to_pipe(att->src_color_blend_factor);
961             state->blend_state.rt[i].rgb_dst_factor = vk_blend_factor_to_pipe(att->dst_color_blend_factor);
962             state->blend_state.rt[i].alpha_func = vk_blend_op_to_pipe(att->alpha_blend_op);
963             state->blend_state.rt[i].alpha_src_factor = vk_blend_factor_to_pipe(att->src_alpha_blend_factor);
964             state->blend_state.rt[i].alpha_dst_factor = vk_blend_factor_to_pipe(att->dst_alpha_blend_factor);
965          }
966 
967          /* At least llvmpipe applies the blend factor prior to the blend function,
968           * regardless of what function is used. (like i965 hardware).
969           * It means for MIN/MAX the blend factor has to be stomped to ONE.
970           */
971          if (att->color_blend_op == VK_BLEND_OP_MIN ||
972              att->color_blend_op == VK_BLEND_OP_MAX) {
973             state->blend_state.rt[i].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
974             state->blend_state.rt[i].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
975          }
976 
977          if (att->alpha_blend_op == VK_BLEND_OP_MIN ||
978              att->alpha_blend_op == VK_BLEND_OP_MAX) {
979             state->blend_state.rt[i].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
980             state->blend_state.rt[i].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
981          }
982       }
983       state->blend_dirty = true;
984       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS)) {
985          memcpy(state->blend_color.color, ps->cb->blend_constants, 4 * sizeof(float));
986          state->blend_color_dirty = true;
987       }
988    } else if (ps->rp->color_attachment_count == 0) {
989       memset(&state->blend_state, 0, sizeof(state->blend_state));
990       state->blend_state.rt[0].colormask = 0xf;
991       state->blend_dirty = true;
992    }
993 
994    if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_RS_LINE_MODE))
995       state->disable_multisample = pipeline->disable_multisample;
996    if (ps->ms) {
997       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_MS_SAMPLE_MASK)) {
998          state->sample_mask = ps->ms->sample_mask;
999          state->sample_mask_dirty = true;
1000       }
1001       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_MS_ALPHA_TO_COVERAGE_ENABLE)) {
1002          state->blend_state.alpha_to_coverage = ps->ms->alpha_to_coverage_enable;
1003          state->blend_state.alpha_to_coverage_dither = state->blend_state.alpha_to_coverage;
1004       }
1005       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_MS_ALPHA_TO_ONE_ENABLE))
1006          state->blend_state.alpha_to_one = ps->ms->alpha_to_one_enable;
1007       state->force_min_sample = pipeline->force_min_sample;
1008       state->sample_shading = ps->ms->sample_shading_enable;
1009       state->min_sample_shading = ps->ms->min_sample_shading;
1010       state->min_samples_dirty = true;
1011       state->blend_dirty = true;
1012       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_MS_RASTERIZATION_SAMPLES))
1013          update_samples(state, ps->ms->rasterization_samples);
1014    } else {
1015       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_MS_SAMPLE_MASK) &&
1016           !BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_MS_ALPHA_TO_ONE_ENABLE))
1017          state->rs_state.multisample = false;
1018       state->sample_shading = false;
1019       state->force_min_sample = false;
1020       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_MS_SAMPLE_MASK)) {
1021          state->sample_mask_dirty = state->sample_mask != 0xffffffff;
1022          state->sample_mask = 0xffffffff;
1023          state->min_samples_dirty = !!state->min_samples;
1024          state->min_samples = 0;
1025       }
1026       state->blend_dirty |= state->blend_state.alpha_to_coverage || state->blend_state.alpha_to_one;
1027       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_MS_ALPHA_TO_COVERAGE_ENABLE)) {
1028          state->blend_state.alpha_to_coverage = false;
1029          state->blend_state.alpha_to_coverage_dither = false;
1030       }
1031       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_MS_ALPHA_TO_ONE_ENABLE))
1032          state->blend_state.alpha_to_one = false;
1033       state->rs_dirty = true;
1034    }
1035 
1036    if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_VI) && ps->vi) {
1037       u_foreach_bit(a, ps->vi->attributes_valid) {
1038          uint32_t b = ps->vi->attributes[a].binding;
1039          state->velem.velems[a].src_offset = ps->vi->attributes[a].offset;
1040          state->vertex_buffer_index[a] = b;
1041          state->velem.velems[a].src_format =
1042             lvp_vk_format_to_pipe_format(ps->vi->attributes[a].format);
1043          state->velem.velems[a].dual_slot = false;
1044 
1045          uint32_t d = ps->vi->bindings[b].divisor;
1046          switch (ps->vi->bindings[b].input_rate) {
1047          case VK_VERTEX_INPUT_RATE_VERTEX:
1048             state->velem.velems[a].instance_divisor = 0;
1049             break;
1050          case VK_VERTEX_INPUT_RATE_INSTANCE:
1051             state->velem.velems[a].instance_divisor = d ? d : UINT32_MAX;
1052             break;
1053          default:
1054             unreachable("Invalid vertex input rate");
1055          }
1056 
1057          if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_VI_BINDING_STRIDES)) {
1058             state->vb_strides[b] = ps->vi->bindings[b].stride;
1059             state->vb_strides_dirty = true;
1060             state->ve_dirty = true;
1061          }
1062       }
1063 
1064       state->velem.count = util_last_bit(ps->vi->attributes_valid);
1065       state->vb_dirty = true;
1066       state->ve_dirty = true;
1067    }
1068 
1069    if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_IA_PRIMITIVE_TOPOLOGY) && ps->ia) {
1070       state->info.mode = vk_conv_topology(ps->ia->primitive_topology);
1071       state->rs_dirty = true;
1072    }
1073    if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_IA_PRIMITIVE_RESTART_ENABLE) && ps->ia)
1074       state->info.primitive_restart = ps->ia->primitive_restart_enable;
1075 
1076    if (ps->ts && !BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_TS_PATCH_CONTROL_POINTS)) {
1077       if (state->patch_vertices != ps->ts->patch_control_points)
1078          state->pctx->set_patch_vertices(state->pctx, ps->ts->patch_control_points);
1079       state->patch_vertices = ps->ts->patch_control_points;
1080    }
1081 
1082    if (ps->vp) {
1083       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_VP_VIEWPORT_COUNT)) {
1084          state->num_viewports = ps->vp->viewport_count;
1085          state->vp_dirty = true;
1086       }
1087       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_VP_SCISSOR_COUNT)) {
1088          state->num_scissors = ps->vp->scissor_count;
1089          state->scissor_dirty = true;
1090       }
1091 
1092       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_VP_VIEWPORTS)) {
1093          for (uint32_t i = 0; i < ps->vp->viewport_count; i++) {
1094             get_viewport_xform(state, &ps->vp->viewports[i], i);
1095             set_viewport_depth_xform(state, i);
1096          }
1097          state->vp_dirty = true;
1098       }
1099       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_VP_SCISSORS)) {
1100          for (uint32_t i = 0; i < ps->vp->scissor_count; i++) {
1101             const VkRect2D *ss = &ps->vp->scissors[i];
1102             state->scissors[i].minx = ss->offset.x;
1103             state->scissors[i].miny = ss->offset.y;
1104             state->scissors[i].maxx = ss->offset.x + ss->extent.width;
1105             state->scissors[i].maxy = ss->offset.y + ss->extent.height;
1106          }
1107          state->scissor_dirty = true;
1108       }
1109 
1110       if (!BITSET_TEST(ps->dynamic, MESA_VK_DYNAMIC_VP_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE) &&
1111           state->rs_state.clip_halfz != !ps->vp->depth_clip_negative_one_to_one) {
1112          state->rs_state.clip_halfz = !ps->vp->depth_clip_negative_one_to_one;
1113          state->rs_dirty = true;
1114          for (uint32_t i = 0; i < state->num_viewports; i++)
1115             set_viewport_depth_xform(state, i);
1116          state->vp_dirty = true;
1117       }
1118    }
1119 }
1120 
handle_pipeline(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1121 static void handle_pipeline(struct vk_cmd_queue_entry *cmd,
1122                             struct rendering_state *state)
1123 {
1124    LVP_FROM_HANDLE(lvp_pipeline, pipeline, cmd->u.bind_pipeline.pipeline);
1125    pipeline->used = true;
1126    if (pipeline->type == LVP_PIPELINE_COMPUTE) {
1127       handle_compute_pipeline(cmd, state);
1128    } else if (pipeline->type == LVP_PIPELINE_RAY_TRACING) {
1129       handle_ray_tracing_pipeline(cmd, state);
1130    } else if (pipeline->type == LVP_PIPELINE_GRAPHICS) {
1131       handle_graphics_pipeline(pipeline, state);
1132    } else if (pipeline->type == LVP_PIPELINE_EXEC_GRAPH) {
1133       state->exec_graph = pipeline;
1134    }
1135    if (pipeline->layout) {
1136       state->push_size[pipeline->type] = pipeline->layout->push_constant_size;
1137    } else {
1138       for (unsigned i = 0; i < ARRAY_SIZE(pipeline->shaders); i++)
1139          if (pipeline->shaders[i].push_constant_size) {
1140             state->push_size[pipeline->type] = pipeline->shaders[i].push_constant_size;
1141             break;
1142          }
1143    }
1144 }
1145 
handle_vertex_buffers2(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1146 static void handle_vertex_buffers2(struct vk_cmd_queue_entry *cmd,
1147                                    struct rendering_state *state)
1148 {
1149    struct vk_cmd_bind_vertex_buffers2 *vcb = &cmd->u.bind_vertex_buffers2;
1150 
1151    int i;
1152    for (i = 0; i < vcb->binding_count; i++) {
1153       int idx = i + vcb->first_binding;
1154 
1155       state->vb[idx].buffer_offset = vcb->offsets[i];
1156       if (state->vb_sizes[idx] != UINT32_MAX)
1157          pipe_resource_reference(&state->vb[idx].buffer.resource, NULL);
1158       state->vb[idx].buffer.resource = vcb->buffers[i] && (!vcb->sizes || vcb->sizes[i]) ? lvp_buffer_from_handle(vcb->buffers[i])->bo : NULL;
1159       if (state->vb[idx].buffer.resource && vcb->sizes) {
1160          if (vcb->sizes[i] == VK_WHOLE_SIZE || vcb->offsets[i] + vcb->sizes[i] >= state->vb[idx].buffer.resource->width0) {
1161             state->vb_sizes[idx] = UINT32_MAX;
1162          } else {
1163             struct pipe_transfer *xfer;
1164             uint8_t *mem = pipe_buffer_map(state->pctx, state->vb[idx].buffer.resource, 0, &xfer);
1165             state->pctx->buffer_unmap(state->pctx, xfer);
1166             state->vb[idx].buffer.resource = get_buffer_resource(state->pctx, mem);
1167             state->vb[idx].buffer.resource->width0 = MIN2(vcb->offsets[i] + vcb->sizes[i], state->vb[idx].buffer.resource->width0);
1168             state->vb_sizes[idx] = vcb->sizes[i];
1169          }
1170       } else {
1171          state->vb_sizes[idx] = UINT32_MAX;
1172       }
1173 
1174       if (vcb->strides) {
1175          state->vb_strides[idx] = vcb->strides[i];
1176          state->vb_strides_dirty = true;
1177       }
1178    }
1179    if (vcb->first_binding < state->start_vb)
1180       state->start_vb = vcb->first_binding;
1181    if (vcb->first_binding + vcb->binding_count >= state->num_vb)
1182       state->num_vb = vcb->first_binding + vcb->binding_count;
1183    state->vb_dirty = true;
1184 }
1185 
1186 static void
handle_set_stage_buffer(struct rendering_state * state,struct pipe_resource * bo,size_t offset,gl_shader_stage stage,uint32_t index)1187 handle_set_stage_buffer(struct rendering_state *state,
1188                         struct pipe_resource *bo,
1189                         size_t offset,
1190                         gl_shader_stage stage,
1191                         uint32_t index)
1192 {
1193    state->const_buffer[stage][index].buffer = bo;
1194    state->const_buffer[stage][index].buffer_offset = offset;
1195    state->const_buffer[stage][index].buffer_size = bo->width0;
1196    state->const_buffer[stage][index].user_buffer = NULL;
1197 
1198    state->constbuf_dirty[stage] = true;
1199 
1200    if (state->num_const_bufs[stage] <= index)
1201       state->num_const_bufs[stage] = index + 1;
1202 }
1203 
handle_set_stage(struct rendering_state * state,struct lvp_descriptor_set * set,enum lvp_pipeline_type pipeline_type,gl_shader_stage stage,uint32_t index)1204 static void handle_set_stage(struct rendering_state *state,
1205                              struct lvp_descriptor_set *set,
1206                              enum lvp_pipeline_type pipeline_type,
1207                              gl_shader_stage stage,
1208                              uint32_t index)
1209 {
1210    state->desc_sets[pipeline_type][index] = set;
1211    handle_set_stage_buffer(state, set->bo, 0, stage, index);
1212 }
1213 
1214 static void
apply_dynamic_offsets(struct lvp_descriptor_set ** out_set,const uint32_t * offsets,uint32_t offset_count,struct rendering_state * state)1215 apply_dynamic_offsets(struct lvp_descriptor_set **out_set, const uint32_t *offsets, uint32_t offset_count,
1216                       struct rendering_state *state)
1217 {
1218    if (!offset_count)
1219       return;
1220 
1221    struct lvp_descriptor_set *in_set = *out_set;
1222 
1223    struct lvp_descriptor_set *set;
1224    lvp_descriptor_set_create(state->device, in_set->layout, &set);
1225 
1226    util_dynarray_append(&state->push_desc_sets, struct lvp_descriptor_set *, set);
1227 
1228    memcpy(set->map, in_set->map, in_set->bo->width0);
1229 
1230    *out_set = set;
1231 
1232    for (uint32_t i = 0; i < set->layout->binding_count; i++) {
1233       const struct lvp_descriptor_set_binding_layout *binding = &set->layout->binding[i];
1234       if (!vk_descriptor_type_is_dynamic(binding->type))
1235          continue;
1236 
1237       struct lp_descriptor *desc = set->map;
1238       desc += binding->descriptor_index;
1239 
1240       for (uint32_t j = 0; j < binding->array_size; j++) {
1241          uint32_t offset_index = binding->dynamic_index + j;
1242          if (offset_index >= offset_count)
1243             return;
1244 
1245          desc[j].buffer.u = (uint32_t *)((uint8_t *)desc[j].buffer.u + offsets[offset_index]);
1246       }
1247    }
1248 }
1249 
1250 static void
handle_descriptor_sets(VkBindDescriptorSetsInfoKHR * bds,struct rendering_state * state)1251 handle_descriptor_sets(VkBindDescriptorSetsInfoKHR *bds, struct rendering_state *state)
1252 {
1253    LVP_FROM_HANDLE(lvp_pipeline_layout, layout, bds->layout);
1254 
1255    uint32_t dynamic_offset_index = 0;
1256 
1257    uint32_t types = lvp_pipeline_types_from_shader_stages(bds->stageFlags);
1258    u_foreach_bit(pipeline_type, types) {
1259       for (uint32_t i = 0; i < bds->descriptorSetCount; i++) {
1260          if (state->desc_buffers[bds->firstSet + i]) {
1261             /* always unset descriptor buffers when binding sets */
1262             if (pipeline_type == LVP_PIPELINE_COMPUTE) {
1263                   bool changed = state->const_buffer[MESA_SHADER_COMPUTE][bds->firstSet + i].buffer == state->desc_buffers[bds->firstSet + i];
1264                   state->constbuf_dirty[MESA_SHADER_COMPUTE] |= changed;
1265             } else if (pipeline_type == LVP_PIPELINE_RAY_TRACING) {
1266                   bool changed = state->const_buffer[MESA_SHADER_RAYGEN][bds->firstSet + i].buffer == state->desc_buffers[bds->firstSet + i];
1267                   state->constbuf_dirty[MESA_SHADER_RAYGEN] |= changed;
1268             } else {
1269                lvp_forall_gfx_stage(j) {
1270                   bool changed = state->const_buffer[j][bds->firstSet + i].buffer == state->desc_buffers[bds->firstSet + i];
1271                   state->constbuf_dirty[j] |= changed;
1272                }
1273             }
1274          }
1275          if (!layout->vk.set_layouts[bds->firstSet + i])
1276             continue;
1277 
1278          struct lvp_descriptor_set *set = lvp_descriptor_set_from_handle(bds->pDescriptorSets[i]);
1279          if (!set)
1280             continue;
1281 
1282          apply_dynamic_offsets(&set, bds->pDynamicOffsets + dynamic_offset_index,
1283                               bds->dynamicOffsetCount - dynamic_offset_index, state);
1284 
1285          dynamic_offset_index += set->layout->dynamic_offset_count;
1286 
1287          if (pipeline_type == LVP_PIPELINE_COMPUTE || pipeline_type == LVP_PIPELINE_EXEC_GRAPH) {
1288             if (set->layout->shader_stages & VK_SHADER_STAGE_COMPUTE_BIT)
1289                handle_set_stage(state, set, pipeline_type, MESA_SHADER_COMPUTE, bds->firstSet + i);
1290             continue;
1291          }
1292 
1293          if (pipeline_type == LVP_PIPELINE_RAY_TRACING) {
1294             if (set->layout->shader_stages & LVP_RAY_TRACING_STAGES)
1295                handle_set_stage(state, set, pipeline_type, MESA_SHADER_RAYGEN, bds->firstSet + i);
1296             continue;
1297          }
1298 
1299          if (set->layout->shader_stages & VK_SHADER_STAGE_VERTEX_BIT)
1300             handle_set_stage(state, set, pipeline_type, MESA_SHADER_VERTEX, bds->firstSet + i);
1301 
1302          if (set->layout->shader_stages & VK_SHADER_STAGE_GEOMETRY_BIT)
1303             handle_set_stage(state, set, pipeline_type, MESA_SHADER_GEOMETRY, bds->firstSet + i);
1304 
1305          if (set->layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
1306             handle_set_stage(state, set, pipeline_type, MESA_SHADER_TESS_CTRL, bds->firstSet + i);
1307 
1308          if (set->layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
1309             handle_set_stage(state, set, pipeline_type, MESA_SHADER_TESS_EVAL, bds->firstSet + i);
1310 
1311          if (set->layout->shader_stages & VK_SHADER_STAGE_FRAGMENT_BIT)
1312             handle_set_stage(state, set, pipeline_type, MESA_SHADER_FRAGMENT, bds->firstSet + i);
1313 
1314          if (set->layout->shader_stages & VK_SHADER_STAGE_TASK_BIT_EXT)
1315             handle_set_stage(state, set, pipeline_type, MESA_SHADER_TASK, bds->firstSet + i);
1316 
1317          if (set->layout->shader_stages & VK_SHADER_STAGE_MESH_BIT_EXT)
1318             handle_set_stage(state, set, pipeline_type, MESA_SHADER_MESH, bds->firstSet + i);
1319       }
1320    }
1321 }
1322 
1323 static void
handle_descriptor_sets_cmd(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1324 handle_descriptor_sets_cmd(struct vk_cmd_queue_entry *cmd, struct rendering_state *state)
1325 {
1326    VkBindDescriptorSetsInfoKHR *bds = cmd->u.bind_descriptor_sets2.bind_descriptor_sets_info;
1327    handle_descriptor_sets(bds, state);
1328 }
1329 
create_img_surface_bo(struct rendering_state * state,VkImageSubresourceRange * range,struct pipe_resource * bo,enum pipe_format pformat,int width,int height,int base_layer,int layer_count,int level)1330 static struct pipe_surface *create_img_surface_bo(struct rendering_state *state,
1331                                                   VkImageSubresourceRange *range,
1332                                                   struct pipe_resource *bo,
1333                                                   enum pipe_format pformat,
1334                                                   int width,
1335                                                   int height,
1336                                                   int base_layer, int layer_count,
1337                                                   int level)
1338 {
1339    if (pformat == PIPE_FORMAT_NONE)
1340       return NULL;
1341 
1342    const struct pipe_surface template = {
1343       .format = pformat,
1344       .width = width,
1345       .height = height,
1346       .u.tex.first_layer = range->baseArrayLayer + base_layer,
1347       .u.tex.last_layer = range->baseArrayLayer + base_layer + layer_count - 1,
1348       .u.tex.level = range->baseMipLevel + level,
1349    };
1350 
1351    return state->pctx->create_surface(state->pctx,
1352                                       bo, &template);
1353 
1354 }
create_img_surface(struct rendering_state * state,struct lvp_image_view * imgv,VkFormat format,int width,int height,int base_layer,int layer_count)1355 static struct pipe_surface *create_img_surface(struct rendering_state *state,
1356                                                struct lvp_image_view *imgv,
1357                                                VkFormat format, int width,
1358                                                int height,
1359                                                int base_layer, int layer_count)
1360 {
1361    VkImageSubresourceRange imgv_subres =
1362       vk_image_view_subresource_range(&imgv->vk);
1363 
1364    return create_img_surface_bo(state, &imgv_subres, imgv->image->planes[0].bo,
1365                                 lvp_vk_format_to_pipe_format(format),
1366                                 width, height, base_layer, layer_count, 0);
1367 }
1368 
add_img_view_surface(struct rendering_state * state,struct lvp_image_view * imgv,int width,int height,int layer_count)1369 static void add_img_view_surface(struct rendering_state *state,
1370                                  struct lvp_image_view *imgv, int width, int height,
1371                                  int layer_count)
1372 {
1373    if (imgv->surface) {
1374       if ((imgv->surface->u.tex.last_layer - imgv->surface->u.tex.first_layer) != (layer_count - 1))
1375          pipe_surface_reference(&imgv->surface, NULL);
1376    }
1377 
1378    if (!imgv->surface) {
1379       imgv->surface = create_img_surface(state, imgv, imgv->vk.format,
1380                                          width, height,
1381                                          0, layer_count);
1382    }
1383 }
1384 
1385 static bool
render_needs_clear(struct rendering_state * state)1386 render_needs_clear(struct rendering_state *state)
1387 {
1388    for (uint32_t i = 0; i < state->color_att_count; i++) {
1389       if (state->color_att[i].load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
1390          return true;
1391    }
1392    if (state->depth_att.load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
1393       return true;
1394    if (state->stencil_att.load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
1395       return true;
1396    return false;
1397 }
1398 
clear_attachment_layers(struct rendering_state * state,struct lvp_image_view * imgv,const VkRect2D * rect,unsigned base_layer,unsigned layer_count,unsigned ds_clear_flags,double dclear_val,uint32_t sclear_val,union pipe_color_union * col_val)1399 static void clear_attachment_layers(struct rendering_state *state,
1400                                     struct lvp_image_view *imgv,
1401                                     const VkRect2D *rect,
1402                                     unsigned base_layer, unsigned layer_count,
1403                                     unsigned ds_clear_flags, double dclear_val,
1404                                     uint32_t sclear_val,
1405                                     union pipe_color_union *col_val)
1406 {
1407    struct pipe_surface *clear_surf = create_img_surface(state,
1408                                                         imgv,
1409                                                         imgv->vk.format,
1410                                                         state->framebuffer.width,
1411                                                         state->framebuffer.height,
1412                                                         base_layer,
1413                                                         layer_count);
1414 
1415    if (ds_clear_flags) {
1416       state->pctx->clear_depth_stencil(state->pctx,
1417                                        clear_surf,
1418                                        ds_clear_flags,
1419                                        dclear_val, sclear_val,
1420                                        rect->offset.x, rect->offset.y,
1421                                        rect->extent.width, rect->extent.height,
1422                                        true);
1423    } else {
1424       state->pctx->clear_render_target(state->pctx, clear_surf,
1425                                        col_val,
1426                                        rect->offset.x, rect->offset.y,
1427                                        rect->extent.width, rect->extent.height,
1428                                        true);
1429    }
1430    state->pctx->surface_destroy(state->pctx, clear_surf);
1431 }
1432 
render_clear(struct rendering_state * state)1433 static void render_clear(struct rendering_state *state)
1434 {
1435    for (uint32_t i = 0; i < state->color_att_count; i++) {
1436       if (state->color_att[i].load_op != VK_ATTACHMENT_LOAD_OP_CLEAR)
1437          continue;
1438 
1439       union pipe_color_union color_clear_val = { 0 };
1440       const VkClearValue value = state->color_att[i].clear_value;
1441       color_clear_val.ui[0] = value.color.uint32[0];
1442       color_clear_val.ui[1] = value.color.uint32[1];
1443       color_clear_val.ui[2] = value.color.uint32[2];
1444       color_clear_val.ui[3] = value.color.uint32[3];
1445 
1446       struct lvp_image_view *imgv = state->color_att[i].imgv;
1447       assert(imgv->surface);
1448 
1449       if (state->framebuffer.viewmask) {
1450          u_foreach_bit(i, state->framebuffer.viewmask)
1451             clear_attachment_layers(state, imgv, &state->render_area,
1452                                     i, 1, 0, 0, 0, &color_clear_val);
1453       } else {
1454          state->pctx->clear_render_target(state->pctx,
1455                                           imgv->surface,
1456                                           &color_clear_val,
1457                                           state->render_area.offset.x,
1458                                           state->render_area.offset.y,
1459                                           state->render_area.extent.width,
1460                                           state->render_area.extent.height,
1461                                           false);
1462       }
1463    }
1464 
1465    uint32_t ds_clear_flags = 0;
1466    double dclear_val = 0;
1467    if (state->depth_att.load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
1468       ds_clear_flags |= PIPE_CLEAR_DEPTH;
1469       dclear_val = state->depth_att.clear_value.depthStencil.depth;
1470    }
1471 
1472    uint32_t sclear_val = 0;
1473    if (state->stencil_att.load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
1474       ds_clear_flags |= PIPE_CLEAR_STENCIL;
1475       sclear_val = state->stencil_att.clear_value.depthStencil.stencil;
1476    }
1477 
1478    if (ds_clear_flags) {
1479       if (state->framebuffer.viewmask) {
1480          u_foreach_bit(i, state->framebuffer.viewmask)
1481             clear_attachment_layers(state, state->ds_imgv, &state->render_area,
1482                                     i, 1, ds_clear_flags, dclear_val, sclear_val, NULL);
1483       } else {
1484          state->pctx->clear_depth_stencil(state->pctx,
1485                                           state->ds_imgv->surface,
1486                                           ds_clear_flags,
1487                                           dclear_val, sclear_val,
1488                                           state->render_area.offset.x,
1489                                           state->render_area.offset.y,
1490                                           state->render_area.extent.width,
1491                                           state->render_area.extent.height,
1492                                           false);
1493       }
1494    }
1495 }
1496 
render_clear_fast(struct rendering_state * state)1497 static void render_clear_fast(struct rendering_state *state)
1498 {
1499    /*
1500     * the state tracker clear interface only works if all the attachments have the same
1501     * clear color.
1502     */
1503    /* llvmpipe doesn't support scissored clears yet */
1504    if (state->render_area.offset.x || state->render_area.offset.y)
1505       goto slow_clear;
1506 
1507    if (state->render_area.extent.width != state->framebuffer.width ||
1508        state->render_area.extent.height != state->framebuffer.height)
1509       goto slow_clear;
1510 
1511    if (state->framebuffer.viewmask)
1512       goto slow_clear;
1513 
1514    if (state->render_cond)
1515       goto slow_clear;
1516 
1517    uint32_t buffers = 0;
1518    bool has_color_value = false;
1519    VkClearValue color_value = {0};
1520    for (uint32_t i = 0; i < state->color_att_count; i++) {
1521       if (state->color_att[i].load_op != VK_ATTACHMENT_LOAD_OP_CLEAR)
1522          continue;
1523 
1524       buffers |= (PIPE_CLEAR_COLOR0 << i);
1525 
1526       if (has_color_value) {
1527          if (memcmp(&color_value, &state->color_att[i].clear_value, sizeof(VkClearValue)))
1528             goto slow_clear;
1529       } else {
1530          memcpy(&color_value, &state->color_att[i].clear_value, sizeof(VkClearValue));
1531          has_color_value = true;
1532       }
1533    }
1534 
1535    double dclear_val = 0;
1536    if (state->depth_att.load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
1537       buffers |= PIPE_CLEAR_DEPTH;
1538       dclear_val = state->depth_att.clear_value.depthStencil.depth;
1539    }
1540 
1541    uint32_t sclear_val = 0;
1542    if (state->stencil_att.load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
1543       buffers |= PIPE_CLEAR_STENCIL;
1544       sclear_val = state->stencil_att.clear_value.depthStencil.stencil;
1545    }
1546 
1547    union pipe_color_union col_val;
1548    for (unsigned i = 0; i < 4; i++)
1549       col_val.ui[i] = color_value.color.uint32[i];
1550 
1551    state->pctx->clear(state->pctx, buffers,
1552                       NULL, &col_val,
1553                       dclear_val, sclear_val);
1554    return;
1555 
1556 slow_clear:
1557    render_clear(state);
1558 }
1559 
1560 static struct lvp_image_view *
destroy_multisample_surface(struct rendering_state * state,struct lvp_image_view * imgv)1561 destroy_multisample_surface(struct rendering_state *state, struct lvp_image_view *imgv)
1562 {
1563    assert(imgv->image->vk.samples > 1);
1564    struct lvp_image_view *base = imgv->multisample;
1565    base->multisample = NULL;
1566    free((void*)imgv->image);
1567    pipe_surface_reference(&imgv->surface, NULL);
1568    free(imgv);
1569    return base;
1570 }
1571 
1572 static void
resolve_ds(struct rendering_state * state,bool multi)1573 resolve_ds(struct rendering_state *state, bool multi)
1574 {
1575    VkResolveModeFlagBits depth_resolve_mode = multi ? state->forced_depth_resolve_mode : state->depth_att.resolve_mode;
1576    VkResolveModeFlagBits stencil_resolve_mode = multi ? state->forced_stencil_resolve_mode : state->stencil_att.resolve_mode;
1577    if (!depth_resolve_mode && !stencil_resolve_mode)
1578       return;
1579 
1580    struct lvp_image_view *src_imgv = state->ds_imgv;
1581    if (multi && !src_imgv->multisample)
1582       return;
1583    if (!multi && src_imgv->image->vk.samples == 1)
1584       return;
1585 
1586    assert(state->depth_att.resolve_imgv == NULL ||
1587           state->stencil_att.resolve_imgv == NULL ||
1588           state->depth_att.resolve_imgv == state->stencil_att.resolve_imgv ||
1589           multi);
1590    struct lvp_image_view *dst_imgv =
1591       multi ? src_imgv->multisample :
1592       state->depth_att.resolve_imgv ? state->depth_att.resolve_imgv :
1593                                       state->stencil_att.resolve_imgv;
1594 
1595    unsigned num_blits = 1;
1596    if (depth_resolve_mode != stencil_resolve_mode)
1597       num_blits = 2;
1598 
1599    for (unsigned i = 0; i < num_blits; i++) {
1600       if (i == 0 && depth_resolve_mode == VK_RESOLVE_MODE_NONE)
1601          continue;
1602 
1603       if (i == 1 && stencil_resolve_mode == VK_RESOLVE_MODE_NONE)
1604          continue;
1605 
1606       struct pipe_blit_info info = {0};
1607 
1608       info.src.resource = src_imgv->image->planes[0].bo;
1609       info.dst.resource = dst_imgv->image->planes[0].bo;
1610       info.src.format = src_imgv->pformat;
1611       info.dst.format = dst_imgv->pformat;
1612       info.filter = PIPE_TEX_FILTER_NEAREST;
1613 
1614       if (num_blits == 1)
1615          info.mask = PIPE_MASK_ZS;
1616       else if (i == 0)
1617          info.mask = PIPE_MASK_Z;
1618       else
1619          info.mask = PIPE_MASK_S;
1620 
1621       if (i == 0 && depth_resolve_mode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT)
1622          info.sample0_only = true;
1623       if (i == 1 && stencil_resolve_mode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT)
1624          info.sample0_only = true;
1625 
1626       info.src.box.x = state->render_area.offset.x;
1627       info.src.box.y = state->render_area.offset.y;
1628       info.src.box.width = state->render_area.extent.width;
1629       info.src.box.height = state->render_area.extent.height;
1630       info.src.box.depth = state->framebuffer.layers;
1631 
1632       info.dst.box = info.src.box;
1633 
1634       state->pctx->blit(state->pctx, &info);
1635    }
1636    if (multi)
1637       state->ds_imgv = destroy_multisample_surface(state, state->ds_imgv);
1638 }
1639 
1640 static void
resolve_color(struct rendering_state * state,bool multi)1641 resolve_color(struct rendering_state *state, bool multi)
1642 {
1643    for (uint32_t i = 0; i < state->color_att_count; i++) {
1644       if (!state->color_att[i].resolve_mode &&
1645           !(multi && state->forced_sample_count && state->color_att[i].imgv))
1646          continue;
1647 
1648       struct lvp_image_view *src_imgv = state->color_att[i].imgv;
1649       /* skip non-msrtss resolves during msrtss resolve */
1650       if (multi && !src_imgv->multisample)
1651          continue;
1652       struct lvp_image_view *dst_imgv = multi ? src_imgv->multisample : state->color_att[i].resolve_imgv;
1653 
1654       struct pipe_blit_info info = { 0 };
1655 
1656       info.src.resource = src_imgv->image->planes[0].bo;
1657       info.dst.resource = dst_imgv->image->planes[0].bo;
1658       info.src.format = src_imgv->pformat;
1659       info.dst.format = dst_imgv->pformat;
1660       info.filter = PIPE_TEX_FILTER_NEAREST;
1661       info.mask = PIPE_MASK_RGBA;
1662       info.src.box.x = state->render_area.offset.x;
1663       info.src.box.y = state->render_area.offset.y;
1664       info.src.box.width = state->render_area.extent.width;
1665       info.src.box.height = state->render_area.extent.height;
1666       info.src.box.depth = state->framebuffer.layers;
1667 
1668       info.dst.box = info.src.box;
1669       info.src.box.z = src_imgv->vk.base_array_layer;
1670       info.dst.box.z = dst_imgv->vk.base_array_layer;
1671 
1672       info.src.level = src_imgv->vk.base_mip_level;
1673       info.dst.level = dst_imgv->vk.base_mip_level;
1674 
1675       state->pctx->blit(state->pctx, &info);
1676    }
1677 
1678    if (!multi)
1679       return;
1680    for (uint32_t i = 0; i < state->color_att_count; i++) {
1681       struct lvp_image_view *src_imgv = state->color_att[i].imgv;
1682       if (src_imgv && src_imgv->multisample) //check if it has a msrtss view
1683          state->color_att[i].imgv = destroy_multisample_surface(state, src_imgv);
1684    }
1685 }
1686 
render_resolve(struct rendering_state * state)1687 static void render_resolve(struct rendering_state *state)
1688 {
1689    if (state->forced_sample_count) {
1690       resolve_ds(state, true);
1691       resolve_color(state, true);
1692    }
1693    resolve_ds(state, false);
1694    resolve_color(state, false);
1695 }
1696 
1697 static void
replicate_attachment(struct rendering_state * state,struct lvp_image_view * src,struct lvp_image_view * dst)1698 replicate_attachment(struct rendering_state *state,
1699                      struct lvp_image_view *src,
1700                      struct lvp_image_view *dst)
1701 {
1702    unsigned level = dst->surface->u.tex.level;
1703    const struct pipe_box box = {
1704       .x = 0,
1705       .y = 0,
1706       .z = 0,
1707       .width = u_minify(dst->image->planes[0].bo->width0, level),
1708       .height = u_minify(dst->image->planes[0].bo->height0, level),
1709       .depth = u_minify(dst->image->planes[0].bo->depth0, level),
1710    };
1711    state->pctx->resource_copy_region(state->pctx, dst->image->planes[0].bo, level,
1712                                      0, 0, 0, src->image->planes[0].bo, level, &box);
1713 }
1714 
1715 static struct lvp_image_view *
create_multisample_surface(struct rendering_state * state,struct lvp_image_view * imgv,uint32_t samples,bool replicate)1716 create_multisample_surface(struct rendering_state *state, struct lvp_image_view *imgv, uint32_t samples, bool replicate)
1717 {
1718    assert(!imgv->multisample);
1719 
1720    struct pipe_resource templ = *imgv->surface->texture;
1721    templ.nr_samples = samples;
1722    struct lvp_image *image = mem_dup(imgv->image, sizeof(struct lvp_image));
1723    image->vk.samples = samples;
1724    image->planes[0].pmem = NULL;
1725    image->planes[0].bo = state->pctx->screen->resource_create(state->pctx->screen, &templ);
1726 
1727    struct lvp_image_view *multi = mem_dup(imgv, sizeof(struct lvp_image_view));
1728    multi->image = image;
1729    multi->surface = state->pctx->create_surface(state->pctx, image->planes[0].bo, imgv->surface);
1730    struct pipe_resource *ref = image->planes[0].bo;
1731    pipe_resource_reference(&ref, NULL);
1732    imgv->multisample = multi;
1733    multi->multisample = imgv;
1734    if (replicate)
1735       replicate_attachment(state, imgv, multi);
1736    return multi;
1737 }
1738 
1739 static bool
att_needs_replicate(const struct rendering_state * state,const struct lvp_image_view * imgv,VkAttachmentLoadOp load_op)1740 att_needs_replicate(const struct rendering_state *state,
1741                     const struct lvp_image_view *imgv,
1742                     VkAttachmentLoadOp load_op)
1743 {
1744    if (load_op == VK_ATTACHMENT_LOAD_OP_LOAD ||
1745        load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
1746       return true;
1747    if (state->render_area.offset.x || state->render_area.offset.y)
1748       return true;
1749    if (state->render_area.extent.width < imgv->image->vk.extent.width ||
1750        state->render_area.extent.height < imgv->image->vk.extent.height)
1751       return true;
1752    return false;
1753 }
1754 
1755 
1756 static void
render_att_init(struct lvp_render_attachment * att,const VkRenderingAttachmentInfo * vk_att,bool poison_mem,bool stencil)1757 render_att_init(struct lvp_render_attachment* att,
1758                 const VkRenderingAttachmentInfo *vk_att,
1759                 bool poison_mem, bool stencil)
1760 {
1761    if (vk_att == NULL || vk_att->imageView == VK_NULL_HANDLE) {
1762       *att = (struct lvp_render_attachment) {
1763          .load_op = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1764       };
1765       return;
1766    }
1767 
1768    *att = (struct lvp_render_attachment) {
1769       .imgv = lvp_image_view_from_handle(vk_att->imageView),
1770       .load_op = vk_att->loadOp,
1771       .store_op = vk_att->storeOp,
1772       .clear_value = vk_att->clearValue,
1773    };
1774    if (util_format_is_depth_or_stencil(att->imgv->pformat)) {
1775       if (stencil) {
1776          att->read_only =
1777             (vk_att->imageLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL ||
1778              vk_att->imageLayout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL);
1779       } else {
1780          att->read_only =
1781             (vk_att->imageLayout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL ||
1782              vk_att->imageLayout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL);
1783       }
1784    }
1785    if (poison_mem && !att->read_only && att->load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE) {
1786       att->load_op = VK_ATTACHMENT_LOAD_OP_CLEAR;
1787       if (util_format_is_depth_or_stencil(att->imgv->pformat)) {
1788          att->clear_value.depthStencil.depth = 0.12351251;
1789          att->clear_value.depthStencil.stencil = rand() % UINT8_MAX;
1790       } else {
1791          memset(att->clear_value.color.uint32, rand() % UINT8_MAX,
1792                 sizeof(att->clear_value.color.uint32));
1793       }
1794    }
1795 
1796    if (vk_att->resolveImageView && vk_att->resolveMode) {
1797       att->resolve_imgv = lvp_image_view_from_handle(vk_att->resolveImageView);
1798       att->resolve_mode = vk_att->resolveMode;
1799    }
1800 }
1801 
1802 
1803 static void
handle_begin_rendering(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1804 handle_begin_rendering(struct vk_cmd_queue_entry *cmd,
1805                        struct rendering_state *state)
1806 {
1807    const VkRenderingInfo *info = cmd->u.begin_rendering.rendering_info;
1808    bool resuming = (info->flags & VK_RENDERING_RESUMING_BIT) == VK_RENDERING_RESUMING_BIT;
1809    bool suspending = (info->flags & VK_RENDERING_SUSPENDING_BIT) == VK_RENDERING_SUSPENDING_BIT;
1810 
1811    state->fb_remapped = false;
1812    for (unsigned i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
1813       state->fb_map[i] = i;
1814 
1815    const VkMultisampledRenderToSingleSampledInfoEXT *ssi =
1816          vk_find_struct_const(info->pNext, MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_INFO_EXT);
1817    if (ssi && ssi->multisampledRenderToSingleSampledEnable) {
1818       state->forced_sample_count = ssi->rasterizationSamples;
1819       state->forced_depth_resolve_mode = info->pDepthAttachment ? info->pDepthAttachment->resolveMode : 0;
1820       state->forced_stencil_resolve_mode = info->pStencilAttachment ? info->pStencilAttachment->resolveMode : 0;
1821    } else {
1822       state->forced_sample_count = 0;
1823       state->forced_depth_resolve_mode = 0;
1824       state->forced_stencil_resolve_mode = 0;
1825    }
1826 
1827    state->framebuffer.viewmask = info->viewMask;
1828    state->render_area = info->renderArea;
1829    state->suspending = suspending;
1830    state->framebuffer.width = info->renderArea.offset.x +
1831                               info->renderArea.extent.width;
1832    state->framebuffer.height = info->renderArea.offset.y +
1833                                info->renderArea.extent.height;
1834    state->framebuffer.layers = info->viewMask ? util_last_bit(info->viewMask) : info->layerCount;
1835    assert(info->colorAttachmentCount <= PIPE_MAX_COLOR_BUFS);
1836    state->framebuffer.nr_cbufs = info->colorAttachmentCount;
1837 
1838    state->color_att_count = info->colorAttachmentCount;
1839    memset(state->framebuffer.cbufs, 0, sizeof(state->framebuffer.cbufs));
1840    for (unsigned i = 0; i < info->colorAttachmentCount; i++) {
1841       render_att_init(&state->color_att[i], &info->pColorAttachments[i], state->poison_mem, false);
1842       if (state->color_att[i].imgv) {
1843          struct lvp_image_view *imgv = state->color_att[i].imgv;
1844          add_img_view_surface(state, imgv,
1845                               state->framebuffer.width, state->framebuffer.height,
1846                               state->framebuffer.layers);
1847          if (state->forced_sample_count && imgv->image->vk.samples == 1)
1848             state->color_att[i].imgv = create_multisample_surface(state, imgv, state->forced_sample_count,
1849                                                                   att_needs_replicate(state, imgv, state->color_att[i].load_op));
1850          state->framebuffer.cbufs[i] = state->color_att[i].imgv->surface;
1851          assert(state->render_area.offset.x + state->render_area.extent.width <= state->framebuffer.cbufs[i]->texture->width0);
1852          assert(state->render_area.offset.y + state->render_area.extent.height <= state->framebuffer.cbufs[i]->texture->height0);
1853       } else {
1854          state->framebuffer.cbufs[i] = NULL;
1855       }
1856    }
1857 
1858    render_att_init(&state->depth_att, info->pDepthAttachment, state->poison_mem, false);
1859    render_att_init(&state->stencil_att, info->pStencilAttachment, state->poison_mem, true);
1860    state->dsa_no_stencil = !state->stencil_att.imgv;
1861    state->dsa_dirty = true;
1862    if (state->depth_att.imgv || state->stencil_att.imgv) {
1863       assert(state->depth_att.imgv == NULL ||
1864              state->stencil_att.imgv == NULL ||
1865              state->depth_att.imgv == state->stencil_att.imgv);
1866       state->ds_imgv = state->depth_att.imgv ? state->depth_att.imgv :
1867                                                state->stencil_att.imgv;
1868       struct lvp_image_view *imgv = state->ds_imgv;
1869       add_img_view_surface(state, imgv,
1870                            state->framebuffer.width, state->framebuffer.height,
1871                            state->framebuffer.layers);
1872       if (state->forced_sample_count && imgv->image->vk.samples == 1) {
1873          VkAttachmentLoadOp load_op;
1874          if (state->depth_att.load_op == VK_ATTACHMENT_LOAD_OP_CLEAR ||
1875              state->stencil_att.load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
1876             load_op = VK_ATTACHMENT_LOAD_OP_CLEAR;
1877          else if (state->depth_att.load_op == VK_ATTACHMENT_LOAD_OP_LOAD ||
1878                   state->stencil_att.load_op == VK_ATTACHMENT_LOAD_OP_LOAD)
1879             load_op = VK_ATTACHMENT_LOAD_OP_LOAD;
1880          else
1881             load_op = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1882          state->ds_imgv = create_multisample_surface(state, imgv, state->forced_sample_count,
1883                                                      att_needs_replicate(state, imgv, load_op));
1884       }
1885       state->framebuffer.zsbuf = state->ds_imgv->surface;
1886       assert(state->render_area.offset.x + state->render_area.extent.width <= state->framebuffer.zsbuf->texture->width0);
1887       assert(state->render_area.offset.y + state->render_area.extent.height <= state->framebuffer.zsbuf->texture->height0);
1888    } else {
1889       state->ds_imgv = NULL;
1890       state->framebuffer.zsbuf = NULL;
1891    }
1892 
1893    state->pctx->set_framebuffer_state(state->pctx,
1894                                       &state->framebuffer);
1895 
1896    if (!resuming && render_needs_clear(state))
1897       render_clear_fast(state);
1898 }
1899 
handle_end_rendering(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1900 static void handle_end_rendering(struct vk_cmd_queue_entry *cmd,
1901                                  struct rendering_state *state)
1902 {
1903    if (state->suspending)
1904       return;
1905    render_resolve(state);
1906    if (!state->poison_mem)
1907       return;
1908 
1909    union pipe_color_union color_clear_val;
1910    memset(color_clear_val.ui, rand() % UINT8_MAX, sizeof(color_clear_val.ui));
1911 
1912    for (unsigned i = 0; i < state->framebuffer.nr_cbufs; i++) {
1913       if (state->color_att[i].imgv && state->color_att[i].store_op == VK_ATTACHMENT_STORE_OP_DONT_CARE) {
1914          if (state->framebuffer.viewmask) {
1915             u_foreach_bit(i, state->framebuffer.viewmask)
1916                clear_attachment_layers(state, state->color_att[i].imgv, &state->render_area,
1917                                        i, 1, 0, 0, 0, &color_clear_val);
1918          } else {
1919             state->pctx->clear_render_target(state->pctx,
1920                                              state->color_att[i].imgv->surface,
1921                                              &color_clear_val,
1922                                              state->render_area.offset.x,
1923                                              state->render_area.offset.y,
1924                                              state->render_area.extent.width,
1925                                              state->render_area.extent.height,
1926                                              false);
1927          }
1928       }
1929    }
1930    uint32_t ds_clear_flags = 0;
1931    if (state->depth_att.imgv && !state->depth_att.read_only && state->depth_att.store_op == VK_ATTACHMENT_STORE_OP_DONT_CARE)
1932       ds_clear_flags |= PIPE_CLEAR_DEPTH;
1933    if (state->stencil_att.imgv && !state->stencil_att.read_only && state->stencil_att.store_op == VK_ATTACHMENT_STORE_OP_DONT_CARE)
1934       ds_clear_flags |= PIPE_CLEAR_STENCIL;
1935    double dclear_val = 0.2389234;
1936    uint32_t sclear_val = rand() % UINT8_MAX;
1937    if (ds_clear_flags) {
1938       if (state->framebuffer.viewmask) {
1939          u_foreach_bit(i, state->framebuffer.viewmask)
1940             clear_attachment_layers(state, state->ds_imgv, &state->render_area,
1941                                     i, 1, ds_clear_flags, dclear_val, sclear_val, NULL);
1942       } else {
1943          state->pctx->clear_depth_stencil(state->pctx,
1944                                           state->ds_imgv->surface,
1945                                           ds_clear_flags,
1946                                           dclear_val, sclear_val,
1947                                           state->render_area.offset.x,
1948                                           state->render_area.offset.y,
1949                                           state->render_area.extent.width,
1950                                           state->render_area.extent.height,
1951                                           false);
1952       }
1953    }
1954 }
1955 
1956 static void
handle_rendering_attachment_locations(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1957 handle_rendering_attachment_locations(struct vk_cmd_queue_entry *cmd, struct rendering_state *state)
1958 {
1959    VkRenderingAttachmentLocationInfoKHR *set = cmd->u.set_rendering_attachment_locations.location_info;
1960    state->fb_remapped = true;
1961    memset(state->fb_map, PIPE_MAX_COLOR_BUFS, sizeof(state->fb_map));
1962    assert(state->color_att_count == set->colorAttachmentCount);
1963    for (unsigned i = 0; i < state->color_att_count; i++) {
1964       if (set->pColorAttachmentLocations[i] == VK_ATTACHMENT_UNUSED)
1965          continue;
1966       state->fb_map[i] = set->pColorAttachmentLocations[i];
1967    }
1968    emit_fb_state(state);
1969 }
1970 
1971 static void
handle_rendering_input_attachment_indices(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1972 handle_rendering_input_attachment_indices(struct vk_cmd_queue_entry *cmd, struct rendering_state *state)
1973 {
1974    /* do nothing */
1975 }
1976 
handle_draw(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1977 static void handle_draw(struct vk_cmd_queue_entry *cmd,
1978                         struct rendering_state *state)
1979 {
1980    struct pipe_draw_start_count_bias draw;
1981 
1982    state->info.index_size = 0;
1983    state->info.index.resource = NULL;
1984    state->info.start_instance = cmd->u.draw.first_instance;
1985    state->info.instance_count = cmd->u.draw.instance_count;
1986 
1987    draw.start = cmd->u.draw.first_vertex;
1988    draw.count = cmd->u.draw.vertex_count;
1989    draw.index_bias = 0;
1990 
1991    state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, &draw, 1);
1992 }
1993 
handle_draw_multi(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1994 static void handle_draw_multi(struct vk_cmd_queue_entry *cmd,
1995                               struct rendering_state *state)
1996 {
1997    struct pipe_draw_start_count_bias *draws = calloc(cmd->u.draw_multi_ext.draw_count,
1998                                                      sizeof(*draws));
1999 
2000    state->info.index_size = 0;
2001    state->info.index.resource = NULL;
2002    state->info.start_instance = cmd->u.draw_multi_ext.first_instance;
2003    state->info.instance_count = cmd->u.draw_multi_ext.instance_count;
2004    if (cmd->u.draw_multi_ext.draw_count > 1)
2005       state->info.increment_draw_id = true;
2006 
2007    for (unsigned i = 0; i < cmd->u.draw_multi_ext.draw_count; i++) {
2008       draws[i].start = cmd->u.draw_multi_ext.vertex_info[i].firstVertex;
2009       draws[i].count = cmd->u.draw_multi_ext.vertex_info[i].vertexCount;
2010       draws[i].index_bias = 0;
2011    }
2012 
2013    if (cmd->u.draw_multi_indexed_ext.draw_count)
2014       state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, draws, cmd->u.draw_multi_ext.draw_count);
2015 
2016    free(draws);
2017 }
2018 
set_viewport(unsigned first_viewport,unsigned viewport_count,const VkViewport * viewports,struct rendering_state * state)2019 static void set_viewport(unsigned first_viewport, unsigned viewport_count,
2020                          const VkViewport* viewports,
2021                          struct rendering_state *state)
2022 {
2023    unsigned base = 0;
2024    if (first_viewport == UINT32_MAX)
2025       state->num_viewports = viewport_count;
2026    else
2027       base = first_viewport;
2028 
2029    for (unsigned i = 0; i < viewport_count; i++) {
2030       int idx = i + base;
2031       const VkViewport *vp = &viewports[i];
2032       get_viewport_xform(state, vp, idx);
2033       set_viewport_depth_xform(state, idx);
2034    }
2035    state->vp_dirty = true;
2036 }
2037 
handle_set_viewport(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2038 static void handle_set_viewport(struct vk_cmd_queue_entry *cmd,
2039                                 struct rendering_state *state)
2040 {
2041    set_viewport(cmd->u.set_viewport.first_viewport,
2042                 cmd->u.set_viewport.viewport_count,
2043                 cmd->u.set_viewport.viewports,
2044                 state);
2045 }
2046 
handle_set_viewport_with_count(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2047 static void handle_set_viewport_with_count(struct vk_cmd_queue_entry *cmd,
2048                                            struct rendering_state *state)
2049 {
2050    set_viewport(UINT32_MAX,
2051                 cmd->u.set_viewport_with_count.viewport_count,
2052                 cmd->u.set_viewport_with_count.viewports,
2053                 state);
2054 }
2055 
set_scissor(unsigned first_scissor,unsigned scissor_count,const VkRect2D * scissors,struct rendering_state * state)2056 static void set_scissor(unsigned first_scissor,
2057                         unsigned scissor_count,
2058                         const VkRect2D *scissors,
2059                         struct rendering_state *state)
2060 {
2061    unsigned base = 0;
2062    if (first_scissor == UINT32_MAX)
2063       state->num_scissors = scissor_count;
2064    else
2065       base = first_scissor;
2066 
2067    for (unsigned i = 0; i < scissor_count; i++) {
2068       unsigned idx = i + base;
2069       const VkRect2D *ss = &scissors[i];
2070       state->scissors[idx].minx = ss->offset.x;
2071       state->scissors[idx].miny = ss->offset.y;
2072       state->scissors[idx].maxx = ss->offset.x + ss->extent.width;
2073       state->scissors[idx].maxy = ss->offset.y + ss->extent.height;
2074    }
2075    state->scissor_dirty = true;
2076 }
2077 
handle_set_scissor(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2078 static void handle_set_scissor(struct vk_cmd_queue_entry *cmd,
2079                                struct rendering_state *state)
2080 {
2081    set_scissor(cmd->u.set_scissor.first_scissor,
2082                cmd->u.set_scissor.scissor_count,
2083                cmd->u.set_scissor.scissors,
2084                state);
2085 }
2086 
handle_set_scissor_with_count(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2087 static void handle_set_scissor_with_count(struct vk_cmd_queue_entry *cmd,
2088                                           struct rendering_state *state)
2089 {
2090    set_scissor(UINT32_MAX,
2091                cmd->u.set_scissor_with_count.scissor_count,
2092                cmd->u.set_scissor_with_count.scissors,
2093                state);
2094 }
2095 
handle_set_line_width(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2096 static void handle_set_line_width(struct vk_cmd_queue_entry *cmd,
2097                                   struct rendering_state *state)
2098 {
2099    state->rs_state.line_width = cmd->u.set_line_width.line_width;
2100    state->rs_dirty = true;
2101 }
2102 
handle_set_depth_bias(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2103 static void handle_set_depth_bias(struct vk_cmd_queue_entry *cmd,
2104                                   struct rendering_state *state)
2105 {
2106    state->depth_bias.offset_units = cmd->u.set_depth_bias.depth_bias_constant_factor;
2107    state->depth_bias.offset_scale = cmd->u.set_depth_bias.depth_bias_slope_factor;
2108    state->depth_bias.offset_clamp = cmd->u.set_depth_bias.depth_bias_clamp;
2109    state->rs_dirty = true;
2110 }
2111 
handle_set_blend_constants(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2112 static void handle_set_blend_constants(struct vk_cmd_queue_entry *cmd,
2113                                        struct rendering_state *state)
2114 {
2115    memcpy(state->blend_color.color, cmd->u.set_blend_constants.blend_constants, 4 * sizeof(float));
2116    state->blend_color_dirty = true;
2117 }
2118 
handle_set_depth_bounds(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2119 static void handle_set_depth_bounds(struct vk_cmd_queue_entry *cmd,
2120                                     struct rendering_state *state)
2121 {
2122    state->dsa_dirty |= !DOUBLE_EQ(state->dsa_state.depth_bounds_min, cmd->u.set_depth_bounds.min_depth_bounds);
2123    state->dsa_dirty |= !DOUBLE_EQ(state->dsa_state.depth_bounds_max, cmd->u.set_depth_bounds.max_depth_bounds);
2124    state->dsa_state.depth_bounds_min = cmd->u.set_depth_bounds.min_depth_bounds;
2125    state->dsa_state.depth_bounds_max = cmd->u.set_depth_bounds.max_depth_bounds;
2126 }
2127 
handle_set_stencil_compare_mask(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2128 static void handle_set_stencil_compare_mask(struct vk_cmd_queue_entry *cmd,
2129                                             struct rendering_state *state)
2130 {
2131    if (cmd->u.set_stencil_compare_mask.face_mask & VK_STENCIL_FACE_FRONT_BIT)
2132       state->dsa_state.stencil[0].valuemask = cmd->u.set_stencil_compare_mask.compare_mask;
2133    if (cmd->u.set_stencil_compare_mask.face_mask & VK_STENCIL_FACE_BACK_BIT)
2134       state->dsa_state.stencil[1].valuemask = cmd->u.set_stencil_compare_mask.compare_mask;
2135    state->dsa_dirty = true;
2136 }
2137 
handle_set_stencil_write_mask(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2138 static void handle_set_stencil_write_mask(struct vk_cmd_queue_entry *cmd,
2139                                           struct rendering_state *state)
2140 {
2141    if (cmd->u.set_stencil_write_mask.face_mask & VK_STENCIL_FACE_FRONT_BIT)
2142       state->dsa_state.stencil[0].writemask = cmd->u.set_stencil_write_mask.write_mask;
2143    if (cmd->u.set_stencil_write_mask.face_mask & VK_STENCIL_FACE_BACK_BIT)
2144       state->dsa_state.stencil[1].writemask = cmd->u.set_stencil_write_mask.write_mask;
2145    state->dsa_dirty = true;
2146 }
2147 
handle_set_stencil_reference(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2148 static void handle_set_stencil_reference(struct vk_cmd_queue_entry *cmd,
2149                                          struct rendering_state *state)
2150 {
2151    if (cmd->u.set_stencil_reference.face_mask & VK_STENCIL_FACE_FRONT_BIT)
2152       state->stencil_ref.ref_value[0] = cmd->u.set_stencil_reference.reference;
2153    if (cmd->u.set_stencil_reference.face_mask & VK_STENCIL_FACE_BACK_BIT)
2154       state->stencil_ref.ref_value[1] = cmd->u.set_stencil_reference.reference;
2155    state->stencil_ref_dirty = true;
2156 }
2157 
2158 static void
copy_depth_rect(uint8_t * dst,enum pipe_format dst_format,unsigned dst_stride,unsigned dst_x,unsigned dst_y,unsigned width,unsigned height,const uint8_t * src,enum pipe_format src_format,int src_stride,unsigned src_x,unsigned src_y)2159 copy_depth_rect(uint8_t * dst,
2160                 enum pipe_format dst_format,
2161                 unsigned dst_stride,
2162                 unsigned dst_x,
2163                 unsigned dst_y,
2164                 unsigned width,
2165                 unsigned height,
2166                 const uint8_t * src,
2167                 enum pipe_format src_format,
2168                 int src_stride,
2169                 unsigned src_x,
2170                 unsigned src_y)
2171 {
2172    int src_stride_pos = src_stride < 0 ? -src_stride : src_stride;
2173    int src_blocksize = util_format_get_blocksize(src_format);
2174    int src_blockwidth = util_format_get_blockwidth(src_format);
2175    int src_blockheight = util_format_get_blockheight(src_format);
2176    int dst_blocksize = util_format_get_blocksize(dst_format);
2177    int dst_blockwidth = util_format_get_blockwidth(dst_format);
2178    int dst_blockheight = util_format_get_blockheight(dst_format);
2179 
2180    assert(src_blocksize > 0);
2181    assert(src_blockwidth > 0);
2182    assert(src_blockheight > 0);
2183 
2184    dst_x /= dst_blockwidth;
2185    dst_y /= dst_blockheight;
2186    width = (width + src_blockwidth - 1)/src_blockwidth;
2187    height = (height + src_blockheight - 1)/src_blockheight;
2188    src_x /= src_blockwidth;
2189    src_y /= src_blockheight;
2190 
2191    dst += dst_x * dst_blocksize;
2192    src += src_x * src_blocksize;
2193    dst += dst_y * dst_stride;
2194    src += src_y * src_stride_pos;
2195 
2196    if (dst_format == PIPE_FORMAT_S8_UINT) {
2197       if (src_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
2198          util_format_z32_float_s8x24_uint_unpack_s_8uint(dst, dst_stride,
2199                                                          src, src_stride,
2200                                                          width, height);
2201       } else if (src_format == PIPE_FORMAT_Z24_UNORM_S8_UINT) {
2202          util_format_z24_unorm_s8_uint_unpack_s_8uint(dst, dst_stride,
2203                                                       src, src_stride,
2204                                                       width, height);
2205       } else {
2206          abort();
2207       }
2208    } else if (dst_format == PIPE_FORMAT_Z24X8_UNORM) {
2209       util_format_z24_unorm_s8_uint_unpack_z24(dst, dst_stride,
2210                                                src, src_stride,
2211                                                width, height);
2212    } else if (dst_format == PIPE_FORMAT_Z32_FLOAT) {
2213       if (src_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
2214          util_format_z32_float_s8x24_uint_unpack_z_float((float *)dst, dst_stride,
2215                                                          src, src_stride,
2216                                                          width, height);
2217       } else {
2218          abort();
2219       }
2220    } else if (dst_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
2221       if (src_format == PIPE_FORMAT_Z32_FLOAT)
2222          util_format_z32_float_s8x24_uint_pack_z_float(dst, dst_stride,
2223                                                        (float *)src, src_stride,
2224                                                        width, height);
2225       else if (src_format == PIPE_FORMAT_S8_UINT)
2226          util_format_z32_float_s8x24_uint_pack_s_8uint(dst, dst_stride,
2227                                                        src, src_stride,
2228                                                        width, height);
2229       else
2230          abort();
2231    } else if (dst_format == PIPE_FORMAT_Z24_UNORM_S8_UINT) {
2232       if (src_format == PIPE_FORMAT_S8_UINT)
2233          util_format_z24_unorm_s8_uint_pack_s_8uint(dst, dst_stride,
2234                                                     src, src_stride,
2235                                                     width, height);
2236       else if (src_format == PIPE_FORMAT_Z24X8_UNORM)
2237          util_format_z24_unorm_s8_uint_pack_z24(dst, dst_stride,
2238                                                 src, src_stride,
2239                                                 width, height);
2240       else
2241          abort();
2242    }
2243 }
2244 
2245 static void
copy_depth_box(uint8_t * dst,enum pipe_format dst_format,unsigned dst_stride,uint64_t dst_slice_stride,unsigned dst_x,unsigned dst_y,unsigned dst_z,unsigned width,unsigned height,unsigned depth,const uint8_t * src,enum pipe_format src_format,int src_stride,uint64_t src_slice_stride,unsigned src_x,unsigned src_y,unsigned src_z)2246 copy_depth_box(uint8_t *dst,
2247                enum pipe_format dst_format,
2248                unsigned dst_stride, uint64_t dst_slice_stride,
2249                unsigned dst_x, unsigned dst_y, unsigned dst_z,
2250                unsigned width, unsigned height, unsigned depth,
2251                const uint8_t * src,
2252                enum pipe_format src_format,
2253                int src_stride, uint64_t src_slice_stride,
2254                unsigned src_x, unsigned src_y, unsigned src_z)
2255 {
2256    dst += dst_z * dst_slice_stride;
2257    src += src_z * src_slice_stride;
2258    for (unsigned z = 0; z < depth; ++z) {
2259       copy_depth_rect(dst,
2260                       dst_format,
2261                       dst_stride,
2262                       dst_x, dst_y,
2263                       width, height,
2264                       src,
2265                       src_format,
2266                       src_stride,
2267                       src_x, src_y);
2268 
2269       dst += dst_slice_stride;
2270       src += src_slice_stride;
2271    }
2272 }
2273 
2274 static unsigned
subresource_layercount(const struct lvp_image * image,const VkImageSubresourceLayers * sub)2275 subresource_layercount(const struct lvp_image *image, const VkImageSubresourceLayers *sub)
2276 {
2277    if (sub->layerCount != VK_REMAINING_ARRAY_LAYERS)
2278       return sub->layerCount;
2279    return image->vk.array_layers - sub->baseArrayLayer;
2280 }
2281 
handle_copy_image_to_buffer2(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2282 static void handle_copy_image_to_buffer2(struct vk_cmd_queue_entry *cmd,
2283                                              struct rendering_state *state)
2284 {
2285    const struct VkCopyImageToBufferInfo2 *copycmd = cmd->u.copy_image_to_buffer2.copy_image_to_buffer_info;
2286    LVP_FROM_HANDLE(lvp_image, src_image, copycmd->srcImage);
2287    struct pipe_box box, dbox;
2288    struct pipe_transfer *src_t, *dst_t;
2289    uint8_t *src_data, *dst_data;
2290 
2291    for (uint32_t i = 0; i < copycmd->regionCount; i++) {
2292       const VkBufferImageCopy2 *region = &copycmd->pRegions[i];
2293       const VkImageAspectFlagBits aspects = copycmd->pRegions[i].imageSubresource.aspectMask;
2294       uint8_t plane = lvp_image_aspects_to_plane(src_image, aspects);
2295 
2296       box.x = region->imageOffset.x;
2297       box.y = region->imageOffset.y;
2298       box.z = src_image->vk.image_type == VK_IMAGE_TYPE_3D ? region->imageOffset.z : region->imageSubresource.baseArrayLayer;
2299       box.width = region->imageExtent.width;
2300       box.height = region->imageExtent.height;
2301       box.depth = src_image->vk.image_type == VK_IMAGE_TYPE_3D ? region->imageExtent.depth : subresource_layercount(src_image, &region->imageSubresource);
2302 
2303       src_data = state->pctx->texture_map(state->pctx,
2304                                            src_image->planes[plane].bo,
2305                                            region->imageSubresource.mipLevel,
2306                                            PIPE_MAP_READ,
2307                                            &box,
2308                                            &src_t);
2309 
2310       dbox.x = region->bufferOffset;
2311       dbox.y = 0;
2312       dbox.z = 0;
2313       dbox.width = lvp_buffer_from_handle(copycmd->dstBuffer)->bo->width0 - region->bufferOffset;
2314       dbox.height = 1;
2315       dbox.depth = 1;
2316       dst_data = state->pctx->buffer_map(state->pctx,
2317                                            lvp_buffer_from_handle(copycmd->dstBuffer)->bo,
2318                                            0,
2319                                            PIPE_MAP_WRITE,
2320                                            &dbox,
2321                                            &dst_t);
2322 
2323       enum pipe_format src_format = src_image->planes[plane].bo->format;
2324       enum pipe_format dst_format = src_format;
2325       if (util_format_is_depth_or_stencil(src_format)) {
2326          if (region->imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) {
2327             dst_format = util_format_get_depth_only(src_format);
2328          } else if (region->imageSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {
2329             dst_format = PIPE_FORMAT_S8_UINT;
2330          }
2331       }
2332 
2333       const struct vk_image_buffer_layout buffer_layout =
2334          vk_image_buffer_copy_layout(&src_image->vk, &copycmd->pRegions[i]);
2335       if (src_format != dst_format) {
2336          copy_depth_box(dst_data, dst_format,
2337                         buffer_layout.row_stride_B,
2338                         buffer_layout.image_stride_B,
2339                         0, 0, 0,
2340                         region->imageExtent.width,
2341                         region->imageExtent.height,
2342                         box.depth,
2343                         src_data, src_format, src_t->stride, src_t->layer_stride, 0, 0, 0);
2344       } else {
2345          util_copy_box((uint8_t *)dst_data, src_format,
2346                        buffer_layout.row_stride_B,
2347                        buffer_layout.image_stride_B,
2348                        0, 0, 0,
2349                        region->imageExtent.width,
2350                        region->imageExtent.height,
2351                        box.depth,
2352                        src_data, src_t->stride, src_t->layer_stride, 0, 0, 0);
2353       }
2354       state->pctx->texture_unmap(state->pctx, src_t);
2355       state->pctx->buffer_unmap(state->pctx, dst_t);
2356    }
2357 }
2358 
handle_copy_buffer_to_image(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2359 static void handle_copy_buffer_to_image(struct vk_cmd_queue_entry *cmd,
2360                                         struct rendering_state *state)
2361 {
2362    const struct VkCopyBufferToImageInfo2 *copycmd = cmd->u.copy_buffer_to_image2.copy_buffer_to_image_info;
2363    LVP_FROM_HANDLE(lvp_image, dst_image, copycmd->dstImage);
2364 
2365    for (uint32_t i = 0; i < copycmd->regionCount; i++) {
2366       const VkBufferImageCopy2 *region = &copycmd->pRegions[i];
2367       struct pipe_box box, sbox;
2368       struct pipe_transfer *src_t, *dst_t;
2369       void *src_data, *dst_data;
2370       const VkImageAspectFlagBits aspects = copycmd->pRegions[i].imageSubresource.aspectMask;
2371       uint8_t plane = lvp_image_aspects_to_plane(dst_image, aspects);
2372 
2373       sbox.x = region->bufferOffset;
2374       sbox.y = 0;
2375       sbox.z = 0;
2376       sbox.width = lvp_buffer_from_handle(copycmd->srcBuffer)->bo->width0;
2377       sbox.height = 1;
2378       sbox.depth = 1;
2379       src_data = state->pctx->buffer_map(state->pctx,
2380                                            lvp_buffer_from_handle(copycmd->srcBuffer)->bo,
2381                                            0,
2382                                            PIPE_MAP_READ,
2383                                            &sbox,
2384                                            &src_t);
2385 
2386 
2387       box.x = region->imageOffset.x;
2388       box.y = region->imageOffset.y;
2389       box.z = dst_image->vk.image_type == VK_IMAGE_TYPE_3D ? region->imageOffset.z : region->imageSubresource.baseArrayLayer;
2390       box.width = region->imageExtent.width;
2391       box.height = region->imageExtent.height;
2392       box.depth = dst_image->vk.image_type == VK_IMAGE_TYPE_3D ? region->imageExtent.depth : subresource_layercount(dst_image, &region->imageSubresource);
2393 
2394       dst_data = state->pctx->texture_map(state->pctx,
2395                                            dst_image->planes[plane].bo,
2396                                            region->imageSubresource.mipLevel,
2397                                            PIPE_MAP_WRITE,
2398                                            &box,
2399                                            &dst_t);
2400 
2401       enum pipe_format dst_format = dst_image->planes[plane].bo->format;
2402       enum pipe_format src_format = dst_format;
2403       if (util_format_is_depth_or_stencil(dst_format)) {
2404          if (region->imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) {
2405             src_format = util_format_get_depth_only(dst_image->planes[plane].bo->format);
2406          } else if (region->imageSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {
2407             src_format = PIPE_FORMAT_S8_UINT;
2408          }
2409       }
2410 
2411       const struct vk_image_buffer_layout buffer_layout =
2412          vk_image_buffer_copy_layout(&dst_image->vk, &copycmd->pRegions[i]);
2413       if (src_format != dst_format) {
2414          copy_depth_box(dst_data, dst_format,
2415                         dst_t->stride, dst_t->layer_stride,
2416                         0, 0, 0,
2417                         region->imageExtent.width,
2418                         region->imageExtent.height,
2419                         box.depth,
2420                         src_data, src_format,
2421                         buffer_layout.row_stride_B,
2422                         buffer_layout.image_stride_B,
2423                         0, 0, 0);
2424       } else {
2425          util_copy_box(dst_data, dst_format,
2426                        dst_t->stride, dst_t->layer_stride,
2427                        0, 0, 0,
2428                        region->imageExtent.width,
2429                        region->imageExtent.height,
2430                        box.depth,
2431                        src_data,
2432                        buffer_layout.row_stride_B,
2433                        buffer_layout.image_stride_B,
2434                        0, 0, 0);
2435       }
2436       state->pctx->buffer_unmap(state->pctx, src_t);
2437       state->pctx->texture_unmap(state->pctx, dst_t);
2438    }
2439 }
2440 
2441 static enum pipe_format
find_depth_format(VkFormat format,VkImageAspectFlagBits aspect)2442 find_depth_format(VkFormat format, VkImageAspectFlagBits aspect)
2443 {
2444    if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {
2445       switch (format) {
2446       case VK_FORMAT_D32_SFLOAT:
2447       case VK_FORMAT_D32_SFLOAT_S8_UINT:
2448       case VK_FORMAT_D24_UNORM_S8_UINT:
2449          return PIPE_FORMAT_Z32_FLOAT;
2450       case VK_FORMAT_D16_UNORM:
2451       case VK_FORMAT_D16_UNORM_S8_UINT:
2452          return PIPE_FORMAT_Z16_UNORM;
2453       default:
2454          unreachable("unsupported format/aspect combo");
2455       }
2456    }
2457    assert(aspect == VK_IMAGE_ASPECT_STENCIL_BIT);
2458    switch (format) {
2459    case VK_FORMAT_D32_SFLOAT_S8_UINT:
2460    case VK_FORMAT_D24_UNORM_S8_UINT:
2461    case VK_FORMAT_D16_UNORM_S8_UINT:
2462    case VK_FORMAT_S8_UINT:
2463       return PIPE_FORMAT_S8_UINT;
2464    default:
2465       unreachable("unsupported format/aspect combo");
2466    }
2467 }
2468 
handle_copy_image(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2469 static void handle_copy_image(struct vk_cmd_queue_entry *cmd,
2470                               struct rendering_state *state)
2471 {
2472    const struct VkCopyImageInfo2 *copycmd = cmd->u.copy_image2.copy_image_info;
2473    LVP_FROM_HANDLE(lvp_image, src_image, copycmd->srcImage);
2474    LVP_FROM_HANDLE(lvp_image, dst_image, copycmd->dstImage);
2475 
2476    for (uint32_t i = 0; i < copycmd->regionCount; i++) {
2477       const VkImageCopy2 *region = &copycmd->pRegions[i];
2478       const VkImageAspectFlagBits src_aspects =
2479          copycmd->pRegions[i].srcSubresource.aspectMask;
2480       uint8_t src_plane = lvp_image_aspects_to_plane(src_image, src_aspects);
2481       const VkImageAspectFlagBits dst_aspects =
2482          copycmd->pRegions[i].dstSubresource.aspectMask;
2483       uint8_t dst_plane = lvp_image_aspects_to_plane(dst_image, dst_aspects);
2484       struct pipe_box src_box, dst_box;
2485       src_box.x = region->srcOffset.x;
2486       src_box.y = region->srcOffset.y;
2487       dst_box.x = region->dstOffset.x;
2488       dst_box.y = region->dstOffset.y;
2489       dst_box.width = src_box.width = region->extent.width;
2490       dst_box.height = src_box.height = region->extent.height;
2491       if (src_image->planes[src_plane].bo->target == PIPE_TEXTURE_3D) {
2492          dst_box.depth = src_box.depth = region->extent.depth;
2493          src_box.z = region->srcOffset.z;
2494          dst_box.z = region->dstOffset.z;
2495       } else {
2496          src_box.depth = subresource_layercount(src_image, &region->srcSubresource);
2497          dst_box.depth = subresource_layercount(dst_image, &region->dstSubresource);
2498          src_box.z = region->srcSubresource.baseArrayLayer;
2499          dst_box.z = region->dstSubresource.baseArrayLayer;
2500       }
2501 
2502 
2503       unsigned dstz = dst_image->planes[dst_plane].bo->target == PIPE_TEXTURE_3D ?
2504                       region->dstOffset.z :
2505                       region->dstSubresource.baseArrayLayer;
2506       enum pipe_format src_format = src_image->planes[src_plane].bo->format,
2507                        dst_format = dst_image->planes[dst_plane].bo->format;
2508       /* special-casing for maintenance8 zs<->color copies */
2509       if (util_format_is_depth_or_stencil(src_format) !=
2510           util_format_is_depth_or_stencil(dst_format) &&
2511           util_format_get_blocksize(src_format) != util_format_get_blocksize(dst_format)) {
2512          if (util_format_is_depth_or_stencil(src_image->planes[src_plane].bo->format))
2513             dst_format = find_depth_format(src_image->vk.format, region->srcSubresource.aspectMask);
2514          else
2515             src_format = find_depth_format(dst_image->vk.format, region->dstSubresource.aspectMask);
2516          struct pipe_transfer *src_t, *dst_t;
2517          void *src_data, *dst_data;
2518          src_data = state->pctx->texture_map(state->pctx,
2519                                              src_image->planes[src_plane].bo,
2520                                              region->srcSubresource.mipLevel,
2521                                              PIPE_MAP_READ,
2522                                              &src_box,
2523                                              &src_t);
2524          dst_data = state->pctx->texture_map(state->pctx,
2525                                              dst_image->planes[dst_plane].bo,
2526                                              region->dstSubresource.mipLevel,
2527                                              PIPE_MAP_WRITE,
2528                                              &dst_box,
2529                                              &dst_t);
2530          copy_depth_box(dst_data, dst_format,
2531                         dst_t->stride, dst_t->layer_stride,
2532                         0, 0, 0,
2533                         region->extent.width,
2534                         region->extent.height,
2535                         dst_box.depth,
2536                         src_data, src_format,
2537                         src_t->stride, src_t->layer_stride,
2538                         0, 0, 0);
2539          state->pctx->texture_unmap(state->pctx, src_t);
2540          state->pctx->texture_unmap(state->pctx, dst_t);
2541       } else {
2542          state->pctx->resource_copy_region(state->pctx, dst_image->planes[dst_plane].bo,
2543                                           region->dstSubresource.mipLevel,
2544                                           region->dstOffset.x,
2545                                           region->dstOffset.y,
2546                                           dstz,
2547                                           src_image->planes[src_plane].bo,
2548                                           region->srcSubresource.mipLevel,
2549                                           &src_box);
2550       }
2551    }
2552 }
2553 
handle_copy_buffer(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2554 static void handle_copy_buffer(struct vk_cmd_queue_entry *cmd,
2555                                struct rendering_state *state)
2556 {
2557    const VkCopyBufferInfo2 *copycmd = cmd->u.copy_buffer2.copy_buffer_info;
2558 
2559    for (uint32_t i = 0; i < copycmd->regionCount; i++) {
2560       const VkBufferCopy2 *region = &copycmd->pRegions[i];
2561       struct pipe_box box = { 0 };
2562       u_box_1d(region->srcOffset, region->size, &box);
2563       state->pctx->resource_copy_region(state->pctx, lvp_buffer_from_handle(copycmd->dstBuffer)->bo, 0,
2564                                         region->dstOffset, 0, 0,
2565                                         lvp_buffer_from_handle(copycmd->srcBuffer)->bo, 0, &box);
2566    }
2567 }
2568 
handle_blit_image(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2569 static void handle_blit_image(struct vk_cmd_queue_entry *cmd,
2570                               struct rendering_state *state)
2571 {
2572    VkBlitImageInfo2 *blitcmd = cmd->u.blit_image2.blit_image_info;
2573    LVP_FROM_HANDLE(lvp_image, src_image, blitcmd->srcImage);
2574    LVP_FROM_HANDLE(lvp_image, dst_image, blitcmd->dstImage);
2575 
2576    struct pipe_blit_info info = {
2577       .src.resource = src_image->planes[0].bo,
2578       .dst.resource = dst_image->planes[0].bo,
2579       .src.format = src_image->planes[0].bo->format,
2580       .dst.format = dst_image->planes[0].bo->format,
2581       .mask = util_format_is_depth_or_stencil(info.src.format) ? PIPE_MASK_ZS : PIPE_MASK_RGBA,
2582       .filter = blitcmd->filter == VK_FILTER_NEAREST ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR,
2583    };
2584 
2585    for (uint32_t i = 0; i < blitcmd->regionCount; i++) {
2586       int srcX0, srcX1, srcY0, srcY1, srcZ0, srcZ1;
2587       unsigned dstX0, dstX1, dstY0, dstY1, dstZ0, dstZ1;
2588 
2589       srcX0 = blitcmd->pRegions[i].srcOffsets[0].x;
2590       srcX1 = blitcmd->pRegions[i].srcOffsets[1].x;
2591       srcY0 = blitcmd->pRegions[i].srcOffsets[0].y;
2592       srcY1 = blitcmd->pRegions[i].srcOffsets[1].y;
2593       srcZ0 = blitcmd->pRegions[i].srcOffsets[0].z;
2594       srcZ1 = blitcmd->pRegions[i].srcOffsets[1].z;
2595 
2596       dstX0 = blitcmd->pRegions[i].dstOffsets[0].x;
2597       dstX1 = blitcmd->pRegions[i].dstOffsets[1].x;
2598       dstY0 = blitcmd->pRegions[i].dstOffsets[0].y;
2599       dstY1 = blitcmd->pRegions[i].dstOffsets[1].y;
2600       dstZ0 = blitcmd->pRegions[i].dstOffsets[0].z;
2601       dstZ1 = blitcmd->pRegions[i].dstOffsets[1].z;
2602 
2603       if (dstX0 < dstX1) {
2604          info.dst.box.x = dstX0;
2605          info.src.box.x = srcX0;
2606          info.dst.box.width = dstX1 - dstX0;
2607          info.src.box.width = srcX1 - srcX0;
2608       } else {
2609          info.dst.box.x = dstX1;
2610          info.src.box.x = srcX1;
2611          info.dst.box.width = dstX0 - dstX1;
2612          info.src.box.width = srcX0 - srcX1;
2613       }
2614 
2615       if (dstY0 < dstY1) {
2616          info.dst.box.y = dstY0;
2617          info.src.box.y = srcY0;
2618          info.dst.box.height = dstY1 - dstY0;
2619          info.src.box.height = srcY1 - srcY0;
2620       } else {
2621          info.dst.box.y = dstY1;
2622          info.src.box.y = srcY1;
2623          info.dst.box.height = dstY0 - dstY1;
2624          info.src.box.height = srcY0 - srcY1;
2625       }
2626 
2627       assert_subresource_layers(info.src.resource, src_image, &blitcmd->pRegions[i].srcSubresource, blitcmd->pRegions[i].srcOffsets);
2628       assert_subresource_layers(info.dst.resource, dst_image, &blitcmd->pRegions[i].dstSubresource, blitcmd->pRegions[i].dstOffsets);
2629       if (src_image->planes[0].bo->target == PIPE_TEXTURE_3D) {
2630          if (dstZ0 < dstZ1) {
2631             if (dst_image->planes[0].bo->target == PIPE_TEXTURE_3D) {
2632                info.dst.box.z = dstZ0;
2633                info.dst.box.depth = dstZ1 - dstZ0;
2634             } else {
2635                info.dst.box.z = blitcmd->pRegions[i].dstSubresource.baseArrayLayer;
2636                info.dst.box.depth = subresource_layercount(dst_image, &blitcmd->pRegions[i].dstSubresource);
2637             }
2638             info.src.box.z = srcZ0;
2639             info.src.box.depth = srcZ1 - srcZ0;
2640          } else {
2641             if (dst_image->planes[0].bo->target == PIPE_TEXTURE_3D) {
2642                info.dst.box.z = dstZ1;
2643                info.dst.box.depth = dstZ0 - dstZ1;
2644             } else {
2645                info.dst.box.z = blitcmd->pRegions[i].dstSubresource.baseArrayLayer;
2646                info.dst.box.depth = subresource_layercount(dst_image, &blitcmd->pRegions[i].dstSubresource);
2647             }
2648             info.src.box.z = srcZ1;
2649             info.src.box.depth = srcZ0 - srcZ1;
2650          }
2651       } else {
2652          info.src.box.z = blitcmd->pRegions[i].srcSubresource.baseArrayLayer;
2653          info.dst.box.z = blitcmd->pRegions[i].dstSubresource.baseArrayLayer;
2654          info.src.box.depth = subresource_layercount(src_image, &blitcmd->pRegions[i].srcSubresource);
2655          info.dst.box.depth = subresource_layercount(dst_image, &blitcmd->pRegions[i].dstSubresource);
2656       }
2657 
2658       info.src.level = blitcmd->pRegions[i].srcSubresource.mipLevel;
2659       info.dst.level = blitcmd->pRegions[i].dstSubresource.mipLevel;
2660       state->pctx->blit(state->pctx, &info);
2661    }
2662 }
2663 
handle_fill_buffer(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2664 static void handle_fill_buffer(struct vk_cmd_queue_entry *cmd,
2665                                struct rendering_state *state)
2666 {
2667    struct vk_cmd_fill_buffer *fillcmd = &cmd->u.fill_buffer;
2668    uint32_t size = fillcmd->size;
2669    struct lvp_buffer *dst = lvp_buffer_from_handle(fillcmd->dst_buffer);
2670 
2671    size = vk_buffer_range(&dst->vk, fillcmd->dst_offset, fillcmd->size);
2672    if (fillcmd->size == VK_WHOLE_SIZE)
2673       size = ROUND_DOWN_TO(size, 4);
2674 
2675    state->pctx->clear_buffer(state->pctx,
2676                              dst->bo,
2677                              fillcmd->dst_offset,
2678                              size,
2679                              &fillcmd->data,
2680                              4);
2681 }
2682 
handle_update_buffer(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2683 static void handle_update_buffer(struct vk_cmd_queue_entry *cmd,
2684                                  struct rendering_state *state)
2685 {
2686    struct vk_cmd_update_buffer *updcmd = &cmd->u.update_buffer;
2687    uint32_t *dst;
2688    struct pipe_transfer *dst_t;
2689    struct pipe_box box;
2690 
2691    u_box_1d(updcmd->dst_offset, updcmd->data_size, &box);
2692    dst = state->pctx->buffer_map(state->pctx,
2693                                    lvp_buffer_from_handle(updcmd->dst_buffer)->bo,
2694                                    0,
2695                                    PIPE_MAP_WRITE,
2696                                    &box,
2697                                    &dst_t);
2698 
2699    memcpy(dst, updcmd->data, updcmd->data_size);
2700    state->pctx->buffer_unmap(state->pctx, dst_t);
2701 }
2702 
handle_draw_indexed(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2703 static void handle_draw_indexed(struct vk_cmd_queue_entry *cmd,
2704                                 struct rendering_state *state)
2705 {
2706    struct pipe_draw_start_count_bias draw = {0};
2707 
2708    state->info.index_bounds_valid = false;
2709    state->info.min_index = 0;
2710    state->info.max_index = ~0U;
2711    state->info.index_size = state->index_size;
2712    state->info.index.resource = state->index_buffer;
2713    state->info.start_instance = cmd->u.draw_indexed.first_instance;
2714    state->info.instance_count = cmd->u.draw_indexed.instance_count;
2715 
2716    if (state->info.primitive_restart)
2717       state->info.restart_index = util_prim_restart_index_from_size(state->info.index_size);
2718 
2719    draw.count = MIN2(cmd->u.draw_indexed.index_count, state->index_buffer_size / state->index_size);
2720    draw.index_bias = cmd->u.draw_indexed.vertex_offset;
2721    /* TODO: avoid calculating multiple times if cmdbuf is submitted again */
2722    draw.start = util_clamped_uadd(state->index_offset / state->index_size,
2723                                   cmd->u.draw_indexed.first_index);
2724 
2725    state->info.index_bias_varies = !cmd->u.draw_indexed.vertex_offset;
2726    state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, &draw, 1);
2727 }
2728 
handle_draw_multi_indexed(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2729 static void handle_draw_multi_indexed(struct vk_cmd_queue_entry *cmd,
2730                                       struct rendering_state *state)
2731 {
2732    struct pipe_draw_start_count_bias *draws = calloc(cmd->u.draw_multi_indexed_ext.draw_count,
2733                                                      sizeof(*draws));
2734 
2735    state->info.index_bounds_valid = false;
2736    state->info.min_index = 0;
2737    state->info.max_index = ~0U;
2738    state->info.index_size = state->index_size;
2739    state->info.index.resource = state->index_buffer;
2740    state->info.start_instance = cmd->u.draw_multi_indexed_ext.first_instance;
2741    state->info.instance_count = cmd->u.draw_multi_indexed_ext.instance_count;
2742    if (cmd->u.draw_multi_indexed_ext.draw_count > 1)
2743       state->info.increment_draw_id = true;
2744 
2745    if (state->info.primitive_restart)
2746       state->info.restart_index = util_prim_restart_index_from_size(state->info.index_size);
2747 
2748    unsigned size = cmd->u.draw_multi_indexed_ext.draw_count * sizeof(struct pipe_draw_start_count_bias);
2749    memcpy(draws, cmd->u.draw_multi_indexed_ext.index_info, size);
2750    if (state->index_buffer_size != UINT32_MAX) {
2751       for (unsigned i = 0; i < cmd->u.draw_multi_indexed_ext.draw_count; i++)
2752          draws[i].count = MIN2(draws[i].count, state->index_buffer_size / state->index_size - draws[i].start);
2753    }
2754 
2755    /* only the first member is read if index_bias_varies is true */
2756    if (cmd->u.draw_multi_indexed_ext.draw_count &&
2757        cmd->u.draw_multi_indexed_ext.vertex_offset)
2758       draws[0].index_bias = *cmd->u.draw_multi_indexed_ext.vertex_offset;
2759 
2760    /* TODO: avoid calculating multiple times if cmdbuf is submitted again */
2761    for (unsigned i = 0; i < cmd->u.draw_multi_indexed_ext.draw_count; i++)
2762       draws[i].start = util_clamped_uadd(state->index_offset / state->index_size,
2763                                          draws[i].start);
2764 
2765    state->info.index_bias_varies = !cmd->u.draw_multi_indexed_ext.vertex_offset;
2766 
2767    if (cmd->u.draw_multi_indexed_ext.draw_count)
2768       state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, draws, cmd->u.draw_multi_indexed_ext.draw_count);
2769 
2770    free(draws);
2771 }
2772 
handle_draw_indirect(struct vk_cmd_queue_entry * cmd,struct rendering_state * state,bool indexed)2773 static void handle_draw_indirect(struct vk_cmd_queue_entry *cmd,
2774                                  struct rendering_state *state, bool indexed)
2775 {
2776    struct pipe_draw_start_count_bias draw = {0};
2777    struct pipe_resource *index = NULL;
2778    if (indexed) {
2779       state->info.index_bounds_valid = false;
2780       state->info.index_size = state->index_size;
2781       state->info.index.resource = state->index_buffer;
2782       state->info.max_index = ~0U;
2783       if (state->info.primitive_restart)
2784          state->info.restart_index = util_prim_restart_index_from_size(state->info.index_size);
2785       if (state->index_offset || state->index_buffer_size != UINT32_MAX) {
2786          struct pipe_transfer *xfer;
2787          uint8_t *mem = pipe_buffer_map(state->pctx, state->index_buffer, 0, &xfer);
2788          state->pctx->buffer_unmap(state->pctx, xfer);
2789          index = get_buffer_resource(state->pctx, mem + state->index_offset);
2790          index->width0 = MIN2(state->index_buffer->width0 - state->index_offset, state->index_buffer_size);
2791          state->info.index.resource = index;
2792       }
2793    } else
2794       state->info.index_size = 0;
2795    state->indirect_info.offset = cmd->u.draw_indirect.offset;
2796    state->indirect_info.stride = cmd->u.draw_indirect.stride;
2797    state->indirect_info.draw_count = cmd->u.draw_indirect.draw_count;
2798    state->indirect_info.buffer = lvp_buffer_from_handle(cmd->u.draw_indirect.buffer)->bo;
2799 
2800    state->pctx->draw_vbo(state->pctx, &state->info, 0, &state->indirect_info, &draw, 1);
2801    pipe_resource_reference(&index, NULL);
2802 }
2803 
handle_index_buffer(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2804 static void handle_index_buffer(struct vk_cmd_queue_entry *cmd,
2805                                 struct rendering_state *state)
2806 {
2807    struct vk_cmd_bind_index_buffer *ib = &cmd->u.bind_index_buffer;
2808    state->index_size = vk_index_type_to_bytes(ib->index_type);
2809    state->index_buffer_size = UINT32_MAX;
2810 
2811    if (ib->buffer) {
2812       state->index_offset = ib->offset;
2813       state->index_buffer = lvp_buffer_from_handle(ib->buffer)->bo;
2814    } else {
2815       state->index_offset = 0;
2816       state->index_buffer = state->device->zero_buffer;
2817    }
2818 
2819    state->ib_dirty = true;
2820 }
2821 
handle_index_buffer2(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2822 static void handle_index_buffer2(struct vk_cmd_queue_entry *cmd,
2823                                  struct rendering_state *state)
2824 {
2825    struct vk_cmd_bind_index_buffer2 *ib = &cmd->u.bind_index_buffer2;
2826 
2827    if (ib->buffer) {
2828       state->index_size = vk_index_type_to_bytes(ib->index_type);
2829       state->index_buffer_size = ib->size;
2830       state->index_offset = ib->offset;
2831       state->index_buffer = lvp_buffer_from_handle(ib->buffer)->bo;
2832    } else {
2833       state->index_size = 4;
2834       state->index_buffer_size = UINT32_MAX;
2835       state->index_offset = 0;
2836       state->index_buffer = state->device->zero_buffer;
2837    }
2838 
2839    state->ib_dirty = true;
2840 }
2841 
handle_dispatch(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2842 static void handle_dispatch(struct vk_cmd_queue_entry *cmd,
2843                             struct rendering_state *state)
2844 {
2845    state->dispatch_info.grid[0] = cmd->u.dispatch.group_count_x;
2846    state->dispatch_info.grid[1] = cmd->u.dispatch.group_count_y;
2847    state->dispatch_info.grid[2] = cmd->u.dispatch.group_count_z;
2848    state->dispatch_info.grid_base[0] = 0;
2849    state->dispatch_info.grid_base[1] = 0;
2850    state->dispatch_info.grid_base[2] = 0;
2851    state->dispatch_info.indirect = NULL;
2852    state->pctx->launch_grid(state->pctx, &state->dispatch_info);
2853 }
2854 
handle_dispatch_base(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2855 static void handle_dispatch_base(struct vk_cmd_queue_entry *cmd,
2856                                  struct rendering_state *state)
2857 {
2858    state->dispatch_info.grid[0] = cmd->u.dispatch_base.group_count_x;
2859    state->dispatch_info.grid[1] = cmd->u.dispatch_base.group_count_y;
2860    state->dispatch_info.grid[2] = cmd->u.dispatch_base.group_count_z;
2861    state->dispatch_info.grid_base[0] = cmd->u.dispatch_base.base_group_x;
2862    state->dispatch_info.grid_base[1] = cmd->u.dispatch_base.base_group_y;
2863    state->dispatch_info.grid_base[2] = cmd->u.dispatch_base.base_group_z;
2864    state->dispatch_info.indirect = NULL;
2865    state->pctx->launch_grid(state->pctx, &state->dispatch_info);
2866 }
2867 
handle_dispatch_indirect(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2868 static void handle_dispatch_indirect(struct vk_cmd_queue_entry *cmd,
2869                                      struct rendering_state *state)
2870 {
2871    state->dispatch_info.indirect = lvp_buffer_from_handle(cmd->u.dispatch_indirect.buffer)->bo;
2872    state->dispatch_info.indirect_offset = cmd->u.dispatch_indirect.offset;
2873    state->pctx->launch_grid(state->pctx, &state->dispatch_info);
2874 }
2875 
handle_push_constants(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2876 static void handle_push_constants(struct vk_cmd_queue_entry *cmd,
2877                                   struct rendering_state *state)
2878 {
2879    VkPushConstantsInfoKHR *pci = cmd->u.push_constants2.push_constants_info;
2880    memcpy(state->push_constants + pci->offset, pci->pValues, pci->size);
2881 
2882    VkShaderStageFlags stage_flags = pci->stageFlags;
2883    state->pcbuf_dirty[MESA_SHADER_VERTEX] |= (stage_flags & VK_SHADER_STAGE_VERTEX_BIT) > 0;
2884    state->pcbuf_dirty[MESA_SHADER_FRAGMENT] |= (stage_flags & VK_SHADER_STAGE_FRAGMENT_BIT) > 0;
2885    state->pcbuf_dirty[MESA_SHADER_GEOMETRY] |= (stage_flags & VK_SHADER_STAGE_GEOMETRY_BIT) > 0;
2886    state->pcbuf_dirty[MESA_SHADER_TESS_CTRL] |= (stage_flags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) > 0;
2887    state->pcbuf_dirty[MESA_SHADER_TESS_EVAL] |= (stage_flags & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) > 0;
2888    state->pcbuf_dirty[MESA_SHADER_COMPUTE] |= (stage_flags & VK_SHADER_STAGE_COMPUTE_BIT) > 0;
2889    state->pcbuf_dirty[MESA_SHADER_TASK] |= (stage_flags & VK_SHADER_STAGE_TASK_BIT_EXT) > 0;
2890    state->pcbuf_dirty[MESA_SHADER_MESH] |= (stage_flags & VK_SHADER_STAGE_MESH_BIT_EXT) > 0;
2891    state->pcbuf_dirty[MESA_SHADER_RAYGEN] |= (stage_flags & LVP_RAY_TRACING_STAGES) > 0;
2892    state->inlines_dirty[MESA_SHADER_VERTEX] |= (stage_flags & VK_SHADER_STAGE_VERTEX_BIT) > 0;
2893    state->inlines_dirty[MESA_SHADER_FRAGMENT] |= (stage_flags & VK_SHADER_STAGE_FRAGMENT_BIT) > 0;
2894    state->inlines_dirty[MESA_SHADER_GEOMETRY] |= (stage_flags & VK_SHADER_STAGE_GEOMETRY_BIT) > 0;
2895    state->inlines_dirty[MESA_SHADER_TESS_CTRL] |= (stage_flags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) > 0;
2896    state->inlines_dirty[MESA_SHADER_TESS_EVAL] |= (stage_flags & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) > 0;
2897    state->inlines_dirty[MESA_SHADER_COMPUTE] |= (stage_flags & VK_SHADER_STAGE_COMPUTE_BIT) > 0;
2898    state->inlines_dirty[MESA_SHADER_TASK] |= (stage_flags & VK_SHADER_STAGE_TASK_BIT_EXT) > 0;
2899    state->inlines_dirty[MESA_SHADER_MESH] |= (stage_flags & VK_SHADER_STAGE_MESH_BIT_EXT) > 0;
2900 }
2901 
2902 static void lvp_execute_cmd_buffer(struct list_head *cmds,
2903                                    struct rendering_state *state, bool print_cmds);
2904 
handle_execute_commands(struct vk_cmd_queue_entry * cmd,struct rendering_state * state,bool print_cmds)2905 static void handle_execute_commands(struct vk_cmd_queue_entry *cmd,
2906                                     struct rendering_state *state, bool print_cmds)
2907 {
2908    for (unsigned i = 0; i < cmd->u.execute_commands.command_buffer_count; i++) {
2909       LVP_FROM_HANDLE(lvp_cmd_buffer, secondary_buf, cmd->u.execute_commands.command_buffers[i]);
2910       lvp_execute_cmd_buffer(&secondary_buf->vk.cmd_queue.cmds, state, print_cmds);
2911    }
2912 }
2913 
handle_event_set2(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2914 static void handle_event_set2(struct vk_cmd_queue_entry *cmd,
2915                              struct rendering_state *state)
2916 {
2917    LVP_FROM_HANDLE(lvp_event, event, cmd->u.set_event2.event);
2918 
2919    VkPipelineStageFlags2 src_stage_mask = 0;
2920 
2921    for (uint32_t i = 0; i < cmd->u.set_event2.dependency_info->memoryBarrierCount; i++)
2922       src_stage_mask |= cmd->u.set_event2.dependency_info->pMemoryBarriers[i].srcStageMask;
2923    for (uint32_t i = 0; i < cmd->u.set_event2.dependency_info->bufferMemoryBarrierCount; i++)
2924       src_stage_mask |= cmd->u.set_event2.dependency_info->pBufferMemoryBarriers[i].srcStageMask;
2925    for (uint32_t i = 0; i < cmd->u.set_event2.dependency_info->imageMemoryBarrierCount; i++)
2926       src_stage_mask |= cmd->u.set_event2.dependency_info->pImageMemoryBarriers[i].srcStageMask;
2927 
2928    if (src_stage_mask & VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT)
2929       state->pctx->flush(state->pctx, NULL, 0);
2930    event->event_storage = 1;
2931 }
2932 
handle_event_reset2(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2933 static void handle_event_reset2(struct vk_cmd_queue_entry *cmd,
2934                                struct rendering_state *state)
2935 {
2936    LVP_FROM_HANDLE(lvp_event, event, cmd->u.reset_event2.event);
2937 
2938    if (cmd->u.reset_event2.stage_mask == VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
2939       state->pctx->flush(state->pctx, NULL, 0);
2940    event->event_storage = 0;
2941 }
2942 
handle_wait_events2(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2943 static void handle_wait_events2(struct vk_cmd_queue_entry *cmd,
2944                                struct rendering_state *state)
2945 {
2946    finish_fence(state);
2947    for (unsigned i = 0; i < cmd->u.wait_events2.event_count; i++) {
2948       LVP_FROM_HANDLE(lvp_event, event, cmd->u.wait_events2.events[i]);
2949 
2950       while (event->event_storage != true);
2951    }
2952 }
2953 
handle_pipeline_barrier(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2954 static void handle_pipeline_barrier(struct vk_cmd_queue_entry *cmd,
2955                                     struct rendering_state *state)
2956 {
2957    finish_fence(state);
2958 }
2959 
handle_begin_query(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2960 static void handle_begin_query(struct vk_cmd_queue_entry *cmd,
2961                                struct rendering_state *state)
2962 {
2963    struct vk_cmd_begin_query *qcmd = &cmd->u.begin_query;
2964    LVP_FROM_HANDLE(lvp_query_pool, pool, qcmd->query_pool);
2965 
2966    if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS &&
2967        pool->pipeline_stats & VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT)
2968       emit_compute_state(state);
2969 
2970    emit_state(state);
2971 
2972    uint32_t count = util_bitcount(state->framebuffer.viewmask ? state->framebuffer.viewmask : BITFIELD_BIT(0));
2973    for (unsigned idx = 0; idx < count; idx++) {
2974       if (!pool->queries[qcmd->query + idx]) {
2975          enum pipe_query_type qtype = pool->base_type;
2976          pool->queries[qcmd->query + idx] = state->pctx->create_query(state->pctx,
2977                                                                qtype, 0);
2978       }
2979 
2980       state->pctx->begin_query(state->pctx, pool->queries[qcmd->query + idx]);
2981       if (idx)
2982          state->pctx->end_query(state->pctx, pool->queries[qcmd->query + idx]);
2983    }
2984 }
2985 
handle_end_query(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2986 static void handle_end_query(struct vk_cmd_queue_entry *cmd,
2987                              struct rendering_state *state)
2988 {
2989    struct vk_cmd_end_query *qcmd = &cmd->u.end_query;
2990    LVP_FROM_HANDLE(lvp_query_pool, pool, qcmd->query_pool);
2991    assert(pool->queries[qcmd->query]);
2992 
2993    state->pctx->end_query(state->pctx, pool->queries[qcmd->query]);
2994 }
2995 
2996 
handle_begin_query_indexed_ext(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2997 static void handle_begin_query_indexed_ext(struct vk_cmd_queue_entry *cmd,
2998                                            struct rendering_state *state)
2999 {
3000    struct vk_cmd_begin_query_indexed_ext *qcmd = &cmd->u.begin_query_indexed_ext;
3001    LVP_FROM_HANDLE(lvp_query_pool, pool, qcmd->query_pool);
3002 
3003    if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS &&
3004        pool->pipeline_stats & VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT)
3005       emit_compute_state(state);
3006 
3007    emit_state(state);
3008 
3009    uint32_t count = util_bitcount(state->framebuffer.viewmask ? state->framebuffer.viewmask : BITFIELD_BIT(0));
3010    for (unsigned idx = 0; idx < count; idx++) {
3011       if (!pool->queries[qcmd->query + idx]) {
3012          enum pipe_query_type qtype = pool->base_type;
3013          pool->queries[qcmd->query + idx] = state->pctx->create_query(state->pctx,
3014                                                                       qtype, qcmd->index);
3015       }
3016 
3017       state->pctx->begin_query(state->pctx, pool->queries[qcmd->query + idx]);
3018       if (idx)
3019          state->pctx->end_query(state->pctx, pool->queries[qcmd->query + idx]);
3020    }
3021 }
3022 
handle_end_query_indexed_ext(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3023 static void handle_end_query_indexed_ext(struct vk_cmd_queue_entry *cmd,
3024                                          struct rendering_state *state)
3025 {
3026    struct vk_cmd_end_query_indexed_ext *qcmd = &cmd->u.end_query_indexed_ext;
3027    LVP_FROM_HANDLE(lvp_query_pool, pool, qcmd->query_pool);
3028    assert(pool->queries[qcmd->query]);
3029 
3030    state->pctx->end_query(state->pctx, pool->queries[qcmd->query]);
3031 }
3032 
handle_reset_query_pool(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3033 static void handle_reset_query_pool(struct vk_cmd_queue_entry *cmd,
3034                                     struct rendering_state *state)
3035 {
3036    struct vk_cmd_reset_query_pool *qcmd = &cmd->u.reset_query_pool;
3037    LVP_FROM_HANDLE(lvp_query_pool, pool, qcmd->query_pool);
3038 
3039    if (pool->base_type >= PIPE_QUERY_TYPES)
3040       return;
3041 
3042    for (unsigned i = qcmd->first_query; i < qcmd->first_query + qcmd->query_count; i++) {
3043       if (pool->queries[i]) {
3044          state->pctx->destroy_query(state->pctx, pool->queries[i]);
3045          pool->queries[i] = NULL;
3046       }
3047    }
3048 }
3049 
handle_write_timestamp2(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3050 static void handle_write_timestamp2(struct vk_cmd_queue_entry *cmd,
3051                                     struct rendering_state *state)
3052 {
3053    struct vk_cmd_write_timestamp2 *qcmd = &cmd->u.write_timestamp2;
3054    LVP_FROM_HANDLE(lvp_query_pool, pool, qcmd->query_pool);
3055 
3056    if (!(qcmd->stage == VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT))
3057       state->pctx->flush(state->pctx, NULL, 0);
3058 
3059    uint32_t count = util_bitcount(state->framebuffer.viewmask ? state->framebuffer.viewmask : BITFIELD_BIT(0));
3060    for (unsigned idx = 0; idx < count; idx++) {
3061       if (!pool->queries[qcmd->query + idx]) {
3062          pool->queries[qcmd->query + idx] = state->pctx->create_query(state->pctx, PIPE_QUERY_TIMESTAMP, 0);
3063       }
3064 
3065       state->pctx->end_query(state->pctx, pool->queries[qcmd->query + idx]);
3066    }
3067 }
3068 
handle_copy_query_pool_results(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3069 static void handle_copy_query_pool_results(struct vk_cmd_queue_entry *cmd,
3070                                            struct rendering_state *state)
3071 {
3072    struct vk_cmd_copy_query_pool_results *copycmd = &cmd->u.copy_query_pool_results;
3073    LVP_FROM_HANDLE(lvp_query_pool, pool, copycmd->query_pool);
3074    enum pipe_query_flags flags = (copycmd->flags & VK_QUERY_RESULT_WAIT_BIT) ? PIPE_QUERY_WAIT : 0;
3075 
3076    if (copycmd->flags & VK_QUERY_RESULT_PARTIAL_BIT)
3077       flags |= PIPE_QUERY_PARTIAL;
3078    unsigned result_size = copycmd->flags & VK_QUERY_RESULT_64_BIT ? 8 : 4;
3079    for (unsigned i = copycmd->first_query; i < copycmd->first_query + copycmd->query_count; i++) {
3080       unsigned offset = copycmd->dst_offset + (copycmd->stride * (i - copycmd->first_query));
3081 
3082       if (pool->base_type >= PIPE_QUERY_TYPES) {
3083          struct pipe_transfer *transfer;
3084          uint8_t *map = pipe_buffer_map(state->pctx, lvp_buffer_from_handle(copycmd->dst_buffer)->bo, PIPE_MAP_WRITE, &transfer);
3085          map += offset;
3086 
3087          if (flags & VK_QUERY_RESULT_64_BIT) {
3088             uint64_t *dst = (uint64_t *)map;
3089             uint64_t *src = (uint64_t *)pool->data;
3090             *dst = src[i];
3091          } else {
3092             uint32_t *dst = (uint32_t *)map;
3093             uint64_t *src = (uint64_t *)pool->data;
3094             *dst = (uint32_t) (src[i] & UINT32_MAX);
3095          }
3096 
3097          state->pctx->buffer_unmap(state->pctx, transfer);
3098 
3099          continue;
3100       }
3101 
3102       if (pool->queries[i]) {
3103          unsigned num_results = 0;
3104          if (copycmd->flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) {
3105             if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS) {
3106                num_results = util_bitcount(pool->pipeline_stats);
3107             } else
3108                num_results = pool-> type == VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT ? 2 : 1;
3109             state->pctx->get_query_result_resource(state->pctx,
3110                                                    pool->queries[i],
3111                                                    flags,
3112                                                    copycmd->flags & VK_QUERY_RESULT_64_BIT ? PIPE_QUERY_TYPE_U64 : PIPE_QUERY_TYPE_U32,
3113                                                    -1,
3114                                                    lvp_buffer_from_handle(copycmd->dst_buffer)->bo,
3115                                                    offset + num_results * result_size);
3116          }
3117          if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS) {
3118             num_results = 0;
3119             u_foreach_bit(bit, pool->pipeline_stats)
3120                state->pctx->get_query_result_resource(state->pctx,
3121                                                       pool->queries[i],
3122                                                       flags,
3123                                                       copycmd->flags & VK_QUERY_RESULT_64_BIT ? PIPE_QUERY_TYPE_U64 : PIPE_QUERY_TYPE_U32,
3124                                                       bit,
3125                                                       lvp_buffer_from_handle(copycmd->dst_buffer)->bo,
3126                                                       offset + num_results++ * result_size);
3127          } else {
3128             state->pctx->get_query_result_resource(state->pctx,
3129                                                    pool->queries[i],
3130                                                    flags,
3131                                                    copycmd->flags & VK_QUERY_RESULT_64_BIT ? PIPE_QUERY_TYPE_U64 : PIPE_QUERY_TYPE_U32,
3132                                                    0,
3133                                                    lvp_buffer_from_handle(copycmd->dst_buffer)->bo,
3134                                                    offset);
3135          }
3136       } else {
3137          /* if no queries emitted yet, just reset the buffer to 0 so avail is reported correctly */
3138          if (copycmd->flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) {
3139             struct pipe_transfer *src_t;
3140             uint32_t *map;
3141 
3142             struct pipe_box box = {0};
3143             box.x = offset;
3144             box.width = copycmd->stride;
3145             box.height = 1;
3146             box.depth = 1;
3147             map = state->pctx->buffer_map(state->pctx,
3148                                             lvp_buffer_from_handle(copycmd->dst_buffer)->bo, 0, PIPE_MAP_READ, &box,
3149                                             &src_t);
3150 
3151             memset(map, 0, box.width);
3152             state->pctx->buffer_unmap(state->pctx, src_t);
3153          }
3154       }
3155    }
3156 }
3157 
handle_clear_color_image(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3158 static void handle_clear_color_image(struct vk_cmd_queue_entry *cmd,
3159                                      struct rendering_state *state)
3160 {
3161    LVP_FROM_HANDLE(lvp_image, image, cmd->u.clear_color_image.image);
3162    union util_color uc;
3163    uint32_t *col_val = uc.ui;
3164    util_pack_color_union(image->planes[0].bo->format, &uc, (void*)cmd->u.clear_color_image.color);
3165    for (unsigned i = 0; i < cmd->u.clear_color_image.range_count; i++) {
3166       VkImageSubresourceRange *range = &cmd->u.clear_color_image.ranges[i];
3167       struct pipe_box box;
3168       box.x = 0;
3169       box.y = 0;
3170       box.z = 0;
3171 
3172       uint32_t level_count = vk_image_subresource_level_count(&image->vk, range);
3173       for (unsigned j = range->baseMipLevel; j < range->baseMipLevel + level_count; j++) {
3174          box.width = u_minify(image->planes[0].bo->width0, j);
3175          box.height = u_minify(image->planes[0].bo->height0, j);
3176          box.depth = 1;
3177          if (image->planes[0].bo->target == PIPE_TEXTURE_3D) {
3178             box.depth = u_minify(image->planes[0].bo->depth0, j);
3179          } else if (image->planes[0].bo->target == PIPE_TEXTURE_1D_ARRAY) {
3180             box.y = range->baseArrayLayer;
3181             box.height = vk_image_subresource_layer_count(&image->vk, range);
3182             box.depth = 1;
3183          } else {
3184             box.z = range->baseArrayLayer;
3185             box.depth = vk_image_subresource_layer_count(&image->vk, range);
3186          }
3187 
3188          state->pctx->clear_texture(state->pctx, image->planes[0].bo,
3189                                     j, &box, (void *)col_val);
3190       }
3191    }
3192 }
3193 
handle_clear_ds_image(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3194 static void handle_clear_ds_image(struct vk_cmd_queue_entry *cmd,
3195                                   struct rendering_state *state)
3196 {
3197    LVP_FROM_HANDLE(lvp_image, image, cmd->u.clear_depth_stencil_image.image);
3198    for (unsigned i = 0; i < cmd->u.clear_depth_stencil_image.range_count; i++) {
3199       VkImageSubresourceRange *range = &cmd->u.clear_depth_stencil_image.ranges[i];
3200       uint32_t ds_clear_flags = 0;
3201       if (range->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)
3202          ds_clear_flags |= PIPE_CLEAR_DEPTH;
3203       if (range->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)
3204          ds_clear_flags |= PIPE_CLEAR_STENCIL;
3205 
3206       uint32_t level_count = vk_image_subresource_level_count(&image->vk, range);
3207       for (unsigned j = 0; j < level_count; j++) {
3208          struct pipe_surface *surf;
3209          unsigned width, height, depth;
3210          width = u_minify(image->planes[0].bo->width0, range->baseMipLevel + j);
3211          height = u_minify(image->planes[0].bo->height0, range->baseMipLevel + j);
3212 
3213          if (image->planes[0].bo->target == PIPE_TEXTURE_3D) {
3214             depth = u_minify(image->planes[0].bo->depth0, range->baseMipLevel + j);
3215          } else {
3216             depth = vk_image_subresource_layer_count(&image->vk, range);
3217          }
3218 
3219          surf = create_img_surface_bo(state, range,
3220                                       image->planes[0].bo, image->planes[0].bo->format,
3221                                       width, height,
3222                                       0, depth, j);
3223 
3224          state->pctx->clear_depth_stencil(state->pctx,
3225                                           surf,
3226                                           ds_clear_flags,
3227                                           cmd->u.clear_depth_stencil_image.depth_stencil->depth,
3228                                           cmd->u.clear_depth_stencil_image.depth_stencil->stencil,
3229                                           0, 0,
3230                                           width, height, false);
3231          state->pctx->surface_destroy(state->pctx, surf);
3232       }
3233    }
3234 }
3235 
handle_clear_attachments(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3236 static void handle_clear_attachments(struct vk_cmd_queue_entry *cmd,
3237                                      struct rendering_state *state)
3238 {
3239    for (uint32_t a = 0; a < cmd->u.clear_attachments.attachment_count; a++) {
3240       VkClearAttachment *att = &cmd->u.clear_attachments.attachments[a];
3241       struct lvp_image_view *imgv;
3242 
3243       if (att->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) {
3244          imgv = state->color_att[att->colorAttachment].imgv;
3245       } else {
3246          imgv = state->ds_imgv;
3247       }
3248       if (!imgv)
3249          continue;
3250 
3251       union pipe_color_union col_val;
3252       double dclear_val = 0;
3253       uint32_t sclear_val = 0;
3254       uint32_t ds_clear_flags = 0;
3255       if (att->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) {
3256          ds_clear_flags |= PIPE_CLEAR_DEPTH;
3257          dclear_val = att->clearValue.depthStencil.depth;
3258       }
3259       if (att->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) {
3260          ds_clear_flags |= PIPE_CLEAR_STENCIL;
3261          sclear_val = att->clearValue.depthStencil.stencil;
3262       }
3263       if (att->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
3264          for (unsigned i = 0; i < 4; i++)
3265             col_val.ui[i] = att->clearValue.color.uint32[i];
3266       }
3267 
3268       for (uint32_t r = 0; r < cmd->u.clear_attachments.rect_count; r++) {
3269 
3270          VkClearRect *rect = &cmd->u.clear_attachments.rects[r];
3271          /* avoid crashing on spec violations */
3272          rect->rect.offset.x = MAX2(rect->rect.offset.x, 0);
3273          rect->rect.offset.y = MAX2(rect->rect.offset.y, 0);
3274          rect->rect.extent.width = MIN2(rect->rect.extent.width, state->framebuffer.width - rect->rect.offset.x);
3275          rect->rect.extent.height = MIN2(rect->rect.extent.height, state->framebuffer.height - rect->rect.offset.y);
3276          if (state->framebuffer.viewmask) {
3277             u_foreach_bit(i, state->framebuffer.viewmask)
3278                clear_attachment_layers(state, imgv, &rect->rect,
3279                                        i, 1,
3280                                        ds_clear_flags, dclear_val, sclear_val,
3281                                        &col_val);
3282          } else
3283             clear_attachment_layers(state, imgv, &rect->rect,
3284                                     rect->baseArrayLayer, rect->layerCount,
3285                                     ds_clear_flags, dclear_val, sclear_val,
3286                                     &col_val);
3287       }
3288    }
3289 }
3290 
handle_resolve_image(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3291 static void handle_resolve_image(struct vk_cmd_queue_entry *cmd,
3292                                  struct rendering_state *state)
3293 {
3294    VkResolveImageInfo2 *resolvecmd = cmd->u.resolve_image2.resolve_image_info;
3295    LVP_FROM_HANDLE(lvp_image, src_image, resolvecmd->srcImage);
3296    LVP_FROM_HANDLE(lvp_image, dst_image, resolvecmd->dstImage);
3297 
3298    struct pipe_blit_info info = {0};
3299    info.src.resource = src_image->planes[0].bo;
3300    info.dst.resource = dst_image->planes[0].bo;
3301    info.src.format = src_image->planes[0].bo->format;
3302    info.dst.format = dst_image->planes[0].bo->format;
3303    info.mask = util_format_is_depth_or_stencil(info.src.format) ? PIPE_MASK_ZS : PIPE_MASK_RGBA;
3304    info.filter = PIPE_TEX_FILTER_NEAREST;
3305 
3306    for (uint32_t i = 0; i < resolvecmd->regionCount; i++) {
3307       int srcX0, srcY0;
3308       unsigned dstX0, dstY0;
3309 
3310       srcX0 = resolvecmd->pRegions[i].srcOffset.x;
3311       srcY0 = resolvecmd->pRegions[i].srcOffset.y;
3312 
3313       dstX0 = resolvecmd->pRegions[i].dstOffset.x;
3314       dstY0 = resolvecmd->pRegions[i].dstOffset.y;
3315 
3316       info.dst.box.x = dstX0;
3317       info.dst.box.y = dstY0;
3318       info.src.box.x = srcX0;
3319       info.src.box.y = srcY0;
3320 
3321       info.dst.box.width = resolvecmd->pRegions[i].extent.width;
3322       info.src.box.width = resolvecmd->pRegions[i].extent.width;
3323       info.dst.box.height = resolvecmd->pRegions[i].extent.height;
3324       info.src.box.height = resolvecmd->pRegions[i].extent.height;
3325 
3326       info.dst.box.depth = subresource_layercount(dst_image, &resolvecmd->pRegions[i].dstSubresource);
3327       info.src.box.depth = subresource_layercount(src_image, &resolvecmd->pRegions[i].srcSubresource);
3328 
3329       info.src.level = resolvecmd->pRegions[i].srcSubresource.mipLevel;
3330       info.src.box.z = resolvecmd->pRegions[i].srcOffset.z + resolvecmd->pRegions[i].srcSubresource.baseArrayLayer;
3331 
3332       info.dst.level = resolvecmd->pRegions[i].dstSubresource.mipLevel;
3333       info.dst.box.z = resolvecmd->pRegions[i].dstOffset.z + resolvecmd->pRegions[i].dstSubresource.baseArrayLayer;
3334 
3335       state->pctx->blit(state->pctx, &info);
3336    }
3337 }
3338 
handle_draw_indirect_count(struct vk_cmd_queue_entry * cmd,struct rendering_state * state,bool indexed)3339 static void handle_draw_indirect_count(struct vk_cmd_queue_entry *cmd,
3340                                        struct rendering_state *state, bool indexed)
3341 {
3342    struct pipe_draw_start_count_bias draw = {0};
3343    struct pipe_resource *index = NULL;
3344    if (indexed) {
3345       state->info.index_bounds_valid = false;
3346       state->info.index_size = state->index_size;
3347       state->info.index.resource = state->index_buffer;
3348       state->info.max_index = ~0U;
3349       if (state->index_offset || state->index_buffer_size != UINT32_MAX) {
3350          struct pipe_transfer *xfer;
3351          uint8_t *mem = pipe_buffer_map(state->pctx, state->index_buffer, 0, &xfer);
3352          state->pctx->buffer_unmap(state->pctx, xfer);
3353          index = get_buffer_resource(state->pctx, mem + state->index_offset);
3354          index->width0 = MIN2(state->index_buffer->width0 - state->index_offset, state->index_buffer_size);
3355          state->info.index.resource = index;
3356       }
3357    } else
3358       state->info.index_size = 0;
3359    state->indirect_info.offset = cmd->u.draw_indirect_count.offset;
3360    state->indirect_info.stride = cmd->u.draw_indirect_count.stride;
3361    state->indirect_info.draw_count = cmd->u.draw_indirect_count.max_draw_count;
3362    state->indirect_info.buffer = lvp_buffer_from_handle(cmd->u.draw_indirect_count.buffer)->bo;
3363    state->indirect_info.indirect_draw_count_offset = cmd->u.draw_indirect_count.count_buffer_offset;
3364    state->indirect_info.indirect_draw_count = lvp_buffer_from_handle(cmd->u.draw_indirect_count.count_buffer)->bo;
3365 
3366    state->pctx->draw_vbo(state->pctx, &state->info, 0, &state->indirect_info, &draw, 1);
3367    pipe_resource_reference(&index, NULL);
3368 }
3369 
handle_push_descriptor_set(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3370 static void handle_push_descriptor_set(struct vk_cmd_queue_entry *cmd,
3371                                        struct rendering_state *state)
3372 {
3373    VkPushDescriptorSetInfoKHR *pds = cmd->u.push_descriptor_set2.push_descriptor_set_info;
3374    LVP_FROM_HANDLE(lvp_pipeline_layout, layout, pds->layout);
3375    struct lvp_descriptor_set_layout *set_layout = (struct lvp_descriptor_set_layout *)layout->vk.set_layouts[pds->set];
3376 
3377    struct lvp_descriptor_set *set;
3378    lvp_descriptor_set_create(state->device, set_layout, &set);
3379 
3380    util_dynarray_append(&state->push_desc_sets, struct lvp_descriptor_set *, set);
3381 
3382    uint32_t types = lvp_pipeline_types_from_shader_stages(pds->stageFlags);
3383    u_foreach_bit(pipeline_type, types) {
3384       struct lvp_descriptor_set *base = state->desc_sets[pipeline_type][pds->set];
3385       if (base)
3386          memcpy(set->map, base->map, MIN2(set->bo->width0, base->bo->width0));
3387 
3388       VkDescriptorSet set_handle = lvp_descriptor_set_to_handle(set);
3389 
3390       VkWriteDescriptorSet *writes = (void*)pds->pDescriptorWrites;
3391       for (uint32_t i = 0; i < pds->descriptorWriteCount; i++)
3392          writes[i].dstSet = set_handle;
3393 
3394       lvp_UpdateDescriptorSets(lvp_device_to_handle(state->device), pds->descriptorWriteCount, pds->pDescriptorWrites, 0, NULL);
3395 
3396       VkBindDescriptorSetsInfoKHR bind_info = {
3397          .stageFlags = pds->stageFlags,
3398          .layout = pds->layout,
3399          .firstSet = pds->set,
3400          .descriptorSetCount = 1,
3401          .pDescriptorSets = &set_handle,
3402       };
3403       handle_descriptor_sets(&bind_info, state);
3404    }
3405 }
3406 
handle_push_descriptor_set_with_template(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3407 static void handle_push_descriptor_set_with_template(struct vk_cmd_queue_entry *cmd,
3408                                                      struct rendering_state *state)
3409 {
3410    VkPushDescriptorSetWithTemplateInfoKHR *pds = cmd->u.push_descriptor_set_with_template2.push_descriptor_set_with_template_info;
3411    LVP_FROM_HANDLE(vk_descriptor_update_template, templ, pds->descriptorUpdateTemplate);
3412    LVP_FROM_HANDLE(lvp_pipeline_layout, layout, pds->layout);
3413    struct lvp_descriptor_set_layout *set_layout = (struct lvp_descriptor_set_layout *)layout->vk.set_layouts[pds->set];
3414 
3415    struct lvp_descriptor_set *set;
3416    lvp_descriptor_set_create(state->device, set_layout, &set);
3417 
3418    util_dynarray_append(&state->push_desc_sets, struct lvp_descriptor_set *, set);
3419 
3420    struct lvp_descriptor_set *base = state->desc_sets[lvp_pipeline_type_from_bind_point(templ->bind_point)][pds->set];
3421    if (base)
3422       memcpy(set->map, base->map, MIN2(set->bo->width0, base->bo->width0));
3423 
3424    VkDescriptorSet set_handle = lvp_descriptor_set_to_handle(set);
3425    lvp_descriptor_set_update_with_template(lvp_device_to_handle(state->device), set_handle,
3426                                            pds->descriptorUpdateTemplate, pds->pData);
3427 
3428    VkBindDescriptorSetsInfoKHR bind_cmd = {
3429       .stageFlags = vk_shader_stages_from_bind_point(templ->bind_point),
3430       .layout = pds->layout,
3431       .firstSet = pds->set,
3432       .descriptorSetCount = 1,
3433       .pDescriptorSets = &set_handle,
3434    };
3435    handle_descriptor_sets(&bind_cmd, state);
3436 }
3437 
handle_bind_transform_feedback_buffers(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3438 static void handle_bind_transform_feedback_buffers(struct vk_cmd_queue_entry *cmd,
3439                                                    struct rendering_state *state)
3440 {
3441    struct vk_cmd_bind_transform_feedback_buffers_ext *btfb = &cmd->u.bind_transform_feedback_buffers_ext;
3442 
3443    for (unsigned i = 0; i < btfb->binding_count; i++) {
3444       int idx = i + btfb->first_binding;
3445       uint32_t size;
3446       struct lvp_buffer *buf = lvp_buffer_from_handle(btfb->buffers[i]);
3447 
3448       size = vk_buffer_range(&buf->vk, btfb->offsets[i], btfb->sizes ? btfb->sizes[i] : VK_WHOLE_SIZE);
3449 
3450       if (state->so_targets[idx])
3451          state->pctx->stream_output_target_destroy(state->pctx, state->so_targets[idx]);
3452 
3453       state->so_targets[idx] = state->pctx->create_stream_output_target(state->pctx,
3454                                                                         lvp_buffer_from_handle(btfb->buffers[i])->bo,
3455                                                                         btfb->offsets[i],
3456                                                                         size);
3457    }
3458    state->num_so_targets = btfb->first_binding + btfb->binding_count;
3459 }
3460 
handle_begin_transform_feedback(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3461 static void handle_begin_transform_feedback(struct vk_cmd_queue_entry *cmd,
3462                                             struct rendering_state *state)
3463 {
3464    struct vk_cmd_begin_transform_feedback_ext *btf = &cmd->u.begin_transform_feedback_ext;
3465    uint32_t offsets[4] = {0};
3466 
3467    for (unsigned i = 0; btf->counter_buffers && i < btf->counter_buffer_count; i++) {
3468       if (!btf->counter_buffers[i])
3469          continue;
3470 
3471       pipe_buffer_read(state->pctx,
3472                        btf->counter_buffers ? lvp_buffer_from_handle(btf->counter_buffers[i])->bo : NULL,
3473                        btf->counter_buffer_offsets ? btf->counter_buffer_offsets[i] : 0,
3474                        4,
3475                        &offsets[i]);
3476    }
3477    state->pctx->set_stream_output_targets(state->pctx, state->num_so_targets,
3478                                           state->so_targets, offsets, MESA_PRIM_UNKNOWN);
3479 }
3480 
handle_end_transform_feedback(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3481 static void handle_end_transform_feedback(struct vk_cmd_queue_entry *cmd,
3482                                           struct rendering_state *state)
3483 {
3484    struct vk_cmd_end_transform_feedback_ext *etf = &cmd->u.end_transform_feedback_ext;
3485 
3486    if (etf->counter_buffer_count) {
3487       for (unsigned i = 0; etf->counter_buffers && i < etf->counter_buffer_count; i++) {
3488          if (!etf->counter_buffers[i])
3489             continue;
3490 
3491          uint32_t offset;
3492          offset = state->pctx->stream_output_target_offset(state->so_targets[i]);
3493 
3494          pipe_buffer_write(state->pctx,
3495                            etf->counter_buffers ? lvp_buffer_from_handle(etf->counter_buffers[i])->bo : NULL,
3496                            etf->counter_buffer_offsets ? etf->counter_buffer_offsets[i] : 0,
3497                            4,
3498                            &offset);
3499       }
3500    }
3501    state->pctx->set_stream_output_targets(state->pctx, 0, NULL, NULL, 0);
3502 }
3503 
handle_draw_indirect_byte_count(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3504 static void handle_draw_indirect_byte_count(struct vk_cmd_queue_entry *cmd,
3505                                             struct rendering_state *state)
3506 {
3507    struct vk_cmd_draw_indirect_byte_count_ext *dibc = &cmd->u.draw_indirect_byte_count_ext;
3508    struct pipe_draw_start_count_bias draw = {0};
3509 
3510    pipe_buffer_read(state->pctx,
3511                     lvp_buffer_from_handle(dibc->counter_buffer)->bo,
3512                     dibc->counter_buffer_offset,
3513                     4, &draw.count);
3514 
3515    state->info.start_instance = cmd->u.draw_indirect_byte_count_ext.first_instance;
3516    state->info.instance_count = cmd->u.draw_indirect_byte_count_ext.instance_count;
3517    state->info.index_size = 0;
3518 
3519    draw.count /= cmd->u.draw_indirect_byte_count_ext.vertex_stride;
3520    state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, &draw, 1);
3521 }
3522 
handle_begin_conditional_rendering(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3523 static void handle_begin_conditional_rendering(struct vk_cmd_queue_entry *cmd,
3524                                                struct rendering_state *state)
3525 {
3526    struct VkConditionalRenderingBeginInfoEXT *bcr = cmd->u.begin_conditional_rendering_ext.conditional_rendering_begin;
3527    state->render_cond = true;
3528    state->pctx->render_condition_mem(state->pctx,
3529                                      lvp_buffer_from_handle(bcr->buffer)->bo,
3530                                      bcr->offset,
3531                                      bcr->flags & VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT);
3532 }
3533 
handle_end_conditional_rendering(struct rendering_state * state)3534 static void handle_end_conditional_rendering(struct rendering_state *state)
3535 {
3536    state->render_cond = false;
3537    state->pctx->render_condition_mem(state->pctx, NULL, 0, false);
3538 }
3539 
handle_set_vertex_input(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3540 static void handle_set_vertex_input(struct vk_cmd_queue_entry *cmd,
3541                                     struct rendering_state *state)
3542 {
3543    const struct vk_cmd_set_vertex_input_ext *vertex_input = &cmd->u.set_vertex_input_ext;
3544    const struct VkVertexInputBindingDescription2EXT *bindings = vertex_input->vertex_binding_descriptions;
3545    const struct VkVertexInputAttributeDescription2EXT *attrs = vertex_input->vertex_attribute_descriptions;
3546    int max_location = -1;
3547    for (unsigned i = 0; i < vertex_input->vertex_attribute_description_count; i++) {
3548       const struct VkVertexInputBindingDescription2EXT *binding = NULL;
3549       unsigned location = attrs[i].location;
3550 
3551       for (unsigned j = 0; j < vertex_input->vertex_binding_description_count; j++) {
3552          const struct VkVertexInputBindingDescription2EXT *b = &bindings[j];
3553          if (b->binding == attrs[i].binding) {
3554             binding = b;
3555             break;
3556          }
3557       }
3558       assert(binding);
3559       state->velem.velems[location].src_offset = attrs[i].offset;
3560       state->vertex_buffer_index[location] = attrs[i].binding;
3561       state->velem.velems[location].src_format = lvp_vk_format_to_pipe_format(attrs[i].format);
3562       state->velem.velems[location].src_stride = binding->stride;
3563       uint32_t d = binding->divisor;
3564       switch (binding->inputRate) {
3565       case VK_VERTEX_INPUT_RATE_VERTEX:
3566          state->velem.velems[location].instance_divisor = 0;
3567          break;
3568       case VK_VERTEX_INPUT_RATE_INSTANCE:
3569          state->velem.velems[location].instance_divisor = d ? d : UINT32_MAX;
3570          break;
3571       default:
3572          assert(0);
3573          break;
3574       }
3575 
3576       if ((int)location > max_location)
3577          max_location = location;
3578    }
3579    state->velem.count = max_location + 1;
3580    state->vb_strides_dirty = false;
3581    state->vb_dirty = true;
3582    state->ve_dirty = true;
3583 }
3584 
handle_set_cull_mode(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3585 static void handle_set_cull_mode(struct vk_cmd_queue_entry *cmd,
3586                                  struct rendering_state *state)
3587 {
3588    state->rs_state.cull_face = vk_cull_to_pipe(cmd->u.set_cull_mode.cull_mode);
3589    state->rs_dirty = true;
3590 }
3591 
handle_set_front_face(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3592 static void handle_set_front_face(struct vk_cmd_queue_entry *cmd,
3593                                   struct rendering_state *state)
3594 {
3595    state->rs_state.front_ccw = (cmd->u.set_front_face.front_face == VK_FRONT_FACE_COUNTER_CLOCKWISE);
3596    state->rs_dirty = true;
3597 }
3598 
handle_set_primitive_topology(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3599 static void handle_set_primitive_topology(struct vk_cmd_queue_entry *cmd,
3600                                           struct rendering_state *state)
3601 {
3602    state->info.mode = vk_conv_topology(cmd->u.set_primitive_topology.primitive_topology);
3603    state->rs_dirty = true;
3604 }
3605 
handle_set_depth_test_enable(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3606 static void handle_set_depth_test_enable(struct vk_cmd_queue_entry *cmd,
3607                                          struct rendering_state *state)
3608 {
3609    state->dsa_dirty |= state->dsa_state.depth_enabled != cmd->u.set_depth_test_enable.depth_test_enable;
3610    state->dsa_state.depth_enabled = cmd->u.set_depth_test_enable.depth_test_enable;
3611 }
3612 
handle_set_depth_write_enable(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3613 static void handle_set_depth_write_enable(struct vk_cmd_queue_entry *cmd,
3614                                           struct rendering_state *state)
3615 {
3616    state->dsa_dirty |= state->dsa_state.depth_writemask != cmd->u.set_depth_write_enable.depth_write_enable;
3617    state->dsa_state.depth_writemask = cmd->u.set_depth_write_enable.depth_write_enable;
3618 }
3619 
handle_set_depth_compare_op(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3620 static void handle_set_depth_compare_op(struct vk_cmd_queue_entry *cmd,
3621                                         struct rendering_state *state)
3622 {
3623    state->dsa_dirty |= state->dsa_state.depth_func != cmd->u.set_depth_compare_op.depth_compare_op;
3624    state->dsa_state.depth_func = cmd->u.set_depth_compare_op.depth_compare_op;
3625 }
3626 
handle_set_depth_bounds_test_enable(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3627 static void handle_set_depth_bounds_test_enable(struct vk_cmd_queue_entry *cmd,
3628                                                 struct rendering_state *state)
3629 {
3630    state->dsa_dirty |= state->dsa_state.depth_bounds_test != cmd->u.set_depth_bounds_test_enable.depth_bounds_test_enable;
3631    state->dsa_state.depth_bounds_test = cmd->u.set_depth_bounds_test_enable.depth_bounds_test_enable;
3632 }
3633 
handle_set_stencil_test_enable(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3634 static void handle_set_stencil_test_enable(struct vk_cmd_queue_entry *cmd,
3635                                            struct rendering_state *state)
3636 {
3637    state->dsa_dirty |= state->dsa_state.stencil[0].enabled != cmd->u.set_stencil_test_enable.stencil_test_enable ||
3638                        state->dsa_state.stencil[1].enabled != cmd->u.set_stencil_test_enable.stencil_test_enable;
3639    state->dsa_state.stencil[0].enabled = cmd->u.set_stencil_test_enable.stencil_test_enable;
3640    state->dsa_state.stencil[1].enabled = cmd->u.set_stencil_test_enable.stencil_test_enable;
3641 }
3642 
handle_set_stencil_op(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3643 static void handle_set_stencil_op(struct vk_cmd_queue_entry *cmd,
3644                                   struct rendering_state *state)
3645 {
3646    if (cmd->u.set_stencil_op.face_mask & VK_STENCIL_FACE_FRONT_BIT) {
3647       state->dsa_state.stencil[0].func = cmd->u.set_stencil_op.compare_op;
3648       state->dsa_state.stencil[0].fail_op = vk_conv_stencil_op(cmd->u.set_stencil_op.fail_op);
3649       state->dsa_state.stencil[0].zpass_op = vk_conv_stencil_op(cmd->u.set_stencil_op.pass_op);
3650       state->dsa_state.stencil[0].zfail_op = vk_conv_stencil_op(cmd->u.set_stencil_op.depth_fail_op);
3651    }
3652 
3653    if (cmd->u.set_stencil_op.face_mask & VK_STENCIL_FACE_BACK_BIT) {
3654       state->dsa_state.stencil[1].func = cmd->u.set_stencil_op.compare_op;
3655       state->dsa_state.stencil[1].fail_op = vk_conv_stencil_op(cmd->u.set_stencil_op.fail_op);
3656       state->dsa_state.stencil[1].zpass_op = vk_conv_stencil_op(cmd->u.set_stencil_op.pass_op);
3657       state->dsa_state.stencil[1].zfail_op = vk_conv_stencil_op(cmd->u.set_stencil_op.depth_fail_op);
3658    }
3659    state->dsa_dirty = true;
3660 }
3661 
handle_set_line_stipple(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3662 static void handle_set_line_stipple(struct vk_cmd_queue_entry *cmd,
3663                                     struct rendering_state *state)
3664 {
3665    state->rs_state.line_stipple_factor = cmd->u.set_line_stipple.line_stipple_factor - 1;
3666    state->rs_state.line_stipple_pattern = cmd->u.set_line_stipple.line_stipple_pattern;
3667    state->rs_dirty = true;
3668 }
3669 
handle_set_depth_bias_enable(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3670 static void handle_set_depth_bias_enable(struct vk_cmd_queue_entry *cmd,
3671                                          struct rendering_state *state)
3672 {
3673    state->rs_dirty |= state->depth_bias.enabled != cmd->u.set_depth_bias_enable.depth_bias_enable;
3674    state->depth_bias.enabled = cmd->u.set_depth_bias_enable.depth_bias_enable;
3675 }
3676 
handle_set_logic_op(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3677 static void handle_set_logic_op(struct vk_cmd_queue_entry *cmd,
3678                                 struct rendering_state *state)
3679 {
3680    unsigned op = vk_logic_op_to_pipe(cmd->u.set_logic_op_ext.logic_op);
3681    state->rs_dirty |= state->blend_state.logicop_func != op;
3682    state->blend_state.logicop_func = op;
3683 }
3684 
handle_set_patch_control_points(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3685 static void handle_set_patch_control_points(struct vk_cmd_queue_entry *cmd,
3686                                             struct rendering_state *state)
3687 {
3688    if (state->patch_vertices != cmd->u.set_patch_control_points_ext.patch_control_points)
3689       state->pctx->set_patch_vertices(state->pctx, cmd->u.set_patch_control_points_ext.patch_control_points);
3690    state->patch_vertices = cmd->u.set_patch_control_points_ext.patch_control_points;
3691 }
3692 
handle_set_primitive_restart_enable(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3693 static void handle_set_primitive_restart_enable(struct vk_cmd_queue_entry *cmd,
3694                                                 struct rendering_state *state)
3695 {
3696    state->info.primitive_restart = cmd->u.set_primitive_restart_enable.primitive_restart_enable;
3697 }
3698 
handle_set_rasterizer_discard_enable(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3699 static void handle_set_rasterizer_discard_enable(struct vk_cmd_queue_entry *cmd,
3700                                                  struct rendering_state *state)
3701 {
3702    state->rs_dirty |= state->rs_state.rasterizer_discard != cmd->u.set_rasterizer_discard_enable.rasterizer_discard_enable;
3703    state->rs_state.rasterizer_discard = cmd->u.set_rasterizer_discard_enable.rasterizer_discard_enable;
3704 }
3705 
handle_set_color_write_enable(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3706 static void handle_set_color_write_enable(struct vk_cmd_queue_entry *cmd,
3707                                           struct rendering_state *state)
3708 {
3709    uint8_t disable_mask = 0; //PIPE_MAX_COLOR_BUFS is max attachment count
3710 
3711    for (unsigned i = 0; i < cmd->u.set_color_write_enable_ext.attachment_count; i++) {
3712       /* this is inverted because cmdbufs are zero-initialized, meaning only 'true'
3713        * can be detected with a bool, and the default is to enable color writes
3714        */
3715       if (cmd->u.set_color_write_enable_ext.color_write_enables[i] != VK_TRUE)
3716          disable_mask |= BITFIELD_BIT(i);
3717    }
3718 
3719    state->blend_dirty |= state->color_write_disables != disable_mask;
3720    state->color_write_disables = disable_mask;
3721 }
3722 
handle_set_polygon_mode(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3723 static void handle_set_polygon_mode(struct vk_cmd_queue_entry *cmd,
3724                                     struct rendering_state *state)
3725 {
3726    unsigned polygon_mode = vk_polygon_mode_to_pipe(cmd->u.set_polygon_mode_ext.polygon_mode);
3727    if (state->rs_state.fill_front != polygon_mode)
3728       state->rs_dirty = true;
3729    state->rs_state.fill_front = polygon_mode;
3730    if (state->rs_state.fill_back != polygon_mode)
3731       state->rs_dirty = true;
3732    state->rs_state.fill_back = polygon_mode;
3733 }
3734 
handle_set_tessellation_domain_origin(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3735 static void handle_set_tessellation_domain_origin(struct vk_cmd_queue_entry *cmd,
3736                                                   struct rendering_state *state)
3737 {
3738    bool tess_ccw = cmd->u.set_tessellation_domain_origin_ext.domain_origin == VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT;
3739    if (tess_ccw == state->tess_ccw)
3740       return;
3741    state->tess_ccw = tess_ccw;
3742    if (state->tess_states[state->tess_ccw])
3743       state->pctx->bind_tes_state(state->pctx, state->tess_states[state->tess_ccw]);
3744 }
3745 
handle_set_depth_clamp_enable(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3746 static void handle_set_depth_clamp_enable(struct vk_cmd_queue_entry *cmd,
3747                                           struct rendering_state *state)
3748 {
3749    state->rs_dirty |= state->rs_state.depth_clamp != cmd->u.set_depth_clamp_enable_ext.depth_clamp_enable;
3750    state->rs_state.depth_clamp = !!cmd->u.set_depth_clamp_enable_ext.depth_clamp_enable;
3751    if (state->depth_clamp_sets_clip)
3752       state->rs_state.depth_clip_near = state->rs_state.depth_clip_far = !state->rs_state.depth_clamp;
3753 }
3754 
handle_set_depth_clip_enable(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3755 static void handle_set_depth_clip_enable(struct vk_cmd_queue_entry *cmd,
3756                                          struct rendering_state *state)
3757 {
3758    state->rs_dirty |= state->rs_state.depth_clip_far != !!cmd->u.set_depth_clip_enable_ext.depth_clip_enable;
3759    state->rs_state.depth_clip_near = state->rs_state.depth_clip_far = !!cmd->u.set_depth_clip_enable_ext.depth_clip_enable;
3760 }
3761 
handle_set_logic_op_enable(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3762 static void handle_set_logic_op_enable(struct vk_cmd_queue_entry *cmd,
3763                                          struct rendering_state *state)
3764 {
3765    state->blend_dirty |= state->blend_state.logicop_enable != !!cmd->u.set_logic_op_enable_ext.logic_op_enable;
3766    state->blend_state.logicop_enable = !!cmd->u.set_logic_op_enable_ext.logic_op_enable;
3767 }
3768 
handle_set_sample_mask(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3769 static void handle_set_sample_mask(struct vk_cmd_queue_entry *cmd,
3770                                    struct rendering_state *state)
3771 {
3772    unsigned mask = cmd->u.set_sample_mask_ext.sample_mask ? cmd->u.set_sample_mask_ext.sample_mask[0] : 0xffffffff;
3773    state->sample_mask_dirty |= state->sample_mask != mask;
3774    state->sample_mask = mask;
3775 }
3776 
handle_set_samples(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3777 static void handle_set_samples(struct vk_cmd_queue_entry *cmd,
3778                                struct rendering_state *state)
3779 {
3780    update_samples(state, cmd->u.set_rasterization_samples_ext.rasterization_samples);
3781 }
3782 
handle_set_alpha_to_coverage(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3783 static void handle_set_alpha_to_coverage(struct vk_cmd_queue_entry *cmd,
3784                                          struct rendering_state *state)
3785 {
3786    state->blend_dirty |=
3787       state->blend_state.alpha_to_coverage != !!cmd->u.set_alpha_to_coverage_enable_ext.alpha_to_coverage_enable;
3788    state->blend_state.alpha_to_coverage = !!cmd->u.set_alpha_to_coverage_enable_ext.alpha_to_coverage_enable;
3789    state->blend_state.alpha_to_coverage_dither = state->blend_state.alpha_to_coverage;
3790 }
3791 
handle_set_alpha_to_one(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3792 static void handle_set_alpha_to_one(struct vk_cmd_queue_entry *cmd,
3793                                          struct rendering_state *state)
3794 {
3795    state->blend_dirty |=
3796       state->blend_state.alpha_to_one != !!cmd->u.set_alpha_to_one_enable_ext.alpha_to_one_enable;
3797    state->blend_state.alpha_to_one = !!cmd->u.set_alpha_to_one_enable_ext.alpha_to_one_enable;
3798    if (state->blend_state.alpha_to_one)
3799       state->rs_state.multisample = true;
3800 }
3801 
handle_set_halfz(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3802 static void handle_set_halfz(struct vk_cmd_queue_entry *cmd,
3803                              struct rendering_state *state)
3804 {
3805    if (state->rs_state.clip_halfz == !cmd->u.set_depth_clip_negative_one_to_one_ext.negative_one_to_one)
3806       return;
3807    state->rs_dirty = true;
3808    state->rs_state.clip_halfz = !cmd->u.set_depth_clip_negative_one_to_one_ext.negative_one_to_one;
3809    /* handle dynamic state: convert from one transform to the other */
3810    for (unsigned i = 0; i < state->num_viewports; i++)
3811       set_viewport_depth_xform(state, i);
3812    state->vp_dirty = true;
3813 }
3814 
handle_set_line_rasterization_mode(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3815 static void handle_set_line_rasterization_mode(struct vk_cmd_queue_entry *cmd,
3816                                                struct rendering_state *state)
3817 {
3818    VkLineRasterizationModeKHR lineRasterizationMode = cmd->u.set_line_rasterization_mode_ext.line_rasterization_mode;
3819    /* not even going to bother trying dirty tracking on this */
3820    state->rs_dirty = true;
3821    state->rs_state.line_smooth = lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_KHR;
3822    state->rs_state.line_rectangular = lineRasterizationMode != VK_LINE_RASTERIZATION_MODE_BRESENHAM_KHR;;
3823    state->disable_multisample = lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_BRESENHAM_KHR ||
3824                                 lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_KHR;
3825 }
3826 
handle_set_line_stipple_enable(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3827 static void handle_set_line_stipple_enable(struct vk_cmd_queue_entry *cmd,
3828                                            struct rendering_state *state)
3829 {
3830    state->rs_dirty |= state->rs_state.line_stipple_enable != !!cmd->u.set_line_stipple_enable_ext.stippled_line_enable;
3831    state->rs_state.line_stipple_enable = cmd->u.set_line_stipple_enable_ext.stippled_line_enable;
3832 }
3833 
handle_set_provoking_vertex_mode(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3834 static void handle_set_provoking_vertex_mode(struct vk_cmd_queue_entry *cmd,
3835                                              struct rendering_state *state)
3836 {
3837    bool flatshade_first = cmd->u.set_provoking_vertex_mode_ext.provoking_vertex_mode != VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT;
3838    state->rs_dirty |= state->rs_state.flatshade_first != flatshade_first;
3839    state->rs_state.flatshade_first = flatshade_first;
3840 }
3841 
handle_set_color_blend_enable(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3842 static void handle_set_color_blend_enable(struct vk_cmd_queue_entry *cmd,
3843                                           struct rendering_state *state)
3844 {
3845    for (unsigned i = 0; i < cmd->u.set_color_blend_enable_ext.attachment_count; i++) {
3846       if (state->blend_state.rt[cmd->u.set_color_blend_enable_ext.first_attachment + i].blend_enable != !!cmd->u.set_color_blend_enable_ext.color_blend_enables[i]) {
3847          state->blend_dirty = true;
3848       }
3849       state->blend_state.rt[cmd->u.set_color_blend_enable_ext.first_attachment + i].blend_enable = !!cmd->u.set_color_blend_enable_ext.color_blend_enables[i];
3850    }
3851 }
3852 
handle_set_color_write_mask(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3853 static void handle_set_color_write_mask(struct vk_cmd_queue_entry *cmd,
3854                                         struct rendering_state *state)
3855 {
3856    for (unsigned i = 0; i < cmd->u.set_color_write_mask_ext.attachment_count; i++) {
3857       if (state->blend_state.rt[cmd->u.set_color_write_mask_ext.first_attachment + i].colormask != cmd->u.set_color_write_mask_ext.color_write_masks[i])
3858          state->blend_dirty = true;
3859       state->blend_state.rt[cmd->u.set_color_write_mask_ext.first_attachment + i].colormask = cmd->u.set_color_write_mask_ext.color_write_masks[i];
3860    }
3861 }
3862 
handle_set_color_blend_equation(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3863 static void handle_set_color_blend_equation(struct vk_cmd_queue_entry *cmd,
3864                                             struct rendering_state *state)
3865 {
3866    const VkColorBlendEquationEXT *cb = cmd->u.set_color_blend_equation_ext.color_blend_equations;
3867    state->blend_dirty = true;
3868    for (unsigned i = 0; i < cmd->u.set_color_blend_equation_ext.attachment_count; i++) {
3869       state->blend_state.rt[cmd->u.set_color_blend_equation_ext.first_attachment + i].rgb_func = vk_blend_op_to_pipe(cb[i].colorBlendOp);
3870       state->blend_state.rt[cmd->u.set_color_blend_equation_ext.first_attachment + i].rgb_src_factor = vk_blend_factor_to_pipe(cb[i].srcColorBlendFactor);
3871       state->blend_state.rt[cmd->u.set_color_blend_equation_ext.first_attachment + i].rgb_dst_factor = vk_blend_factor_to_pipe(cb[i].dstColorBlendFactor);
3872       state->blend_state.rt[cmd->u.set_color_blend_equation_ext.first_attachment + i].alpha_func = vk_blend_op_to_pipe(cb[i].alphaBlendOp);
3873       state->blend_state.rt[cmd->u.set_color_blend_equation_ext.first_attachment + i].alpha_src_factor = vk_blend_factor_to_pipe(cb[i].srcAlphaBlendFactor);
3874       state->blend_state.rt[cmd->u.set_color_blend_equation_ext.first_attachment + i].alpha_dst_factor = vk_blend_factor_to_pipe(cb[i].dstAlphaBlendFactor);
3875 
3876       /* At least llvmpipe applies the blend factor prior to the blend function,
3877        * regardless of what function is used. (like i965 hardware).
3878        * It means for MIN/MAX the blend factor has to be stomped to ONE.
3879        */
3880       if (cb[i].colorBlendOp == VK_BLEND_OP_MIN ||
3881           cb[i].colorBlendOp == VK_BLEND_OP_MAX) {
3882          state->blend_state.rt[cmd->u.set_color_blend_equation_ext.first_attachment + i].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
3883          state->blend_state.rt[cmd->u.set_color_blend_equation_ext.first_attachment + i].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
3884       }
3885 
3886       if (cb[i].alphaBlendOp == VK_BLEND_OP_MIN ||
3887           cb[i].alphaBlendOp == VK_BLEND_OP_MAX) {
3888          state->blend_state.rt[cmd->u.set_color_blend_equation_ext.first_attachment + i].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
3889          state->blend_state.rt[cmd->u.set_color_blend_equation_ext.first_attachment + i].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
3890       }
3891    }
3892 }
3893 
3894 static void
handle_shaders(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3895 handle_shaders(struct vk_cmd_queue_entry *cmd, struct rendering_state *state)
3896 {
3897    struct vk_cmd_bind_shaders_ext *bind = &cmd->u.bind_shaders_ext;
3898 
3899    bool gfx = false;
3900    VkShaderStageFlagBits vkstages = 0;
3901    unsigned new_stages = 0;
3902    unsigned null_stages = 0;
3903    for (unsigned i = 0; i < bind->stage_count; i++) {
3904       gl_shader_stage stage = vk_to_mesa_shader_stage(bind->stages[i]);
3905       assert(stage != MESA_SHADER_NONE && stage <= MESA_SHADER_MESH);
3906       LVP_FROM_HANDLE(lvp_shader, shader, bind->shaders ? bind->shaders[i] : VK_NULL_HANDLE);
3907       if (stage == MESA_SHADER_FRAGMENT) {
3908          if (shader) {
3909             state->force_min_sample = shader->pipeline_nir->nir->info.fs.uses_sample_shading;
3910             state->sample_shading = state->force_min_sample;
3911             update_samples(state, state->rast_samples);
3912          } else {
3913             state->force_min_sample = false;
3914             state->sample_shading = false;
3915          }
3916       }
3917       if (shader) {
3918          vkstages |= bind->stages[i];
3919          new_stages |= BITFIELD_BIT(stage);
3920          state->shaders[stage] = shader;
3921       } else {
3922          if (state->shaders[stage])
3923             null_stages |= bind->stages[i];
3924       }
3925 
3926       if (stage != MESA_SHADER_COMPUTE) {
3927          state->gfx_push_sizes[stage] = shader ? shader->layout->push_constant_size : 0;
3928          gfx = true;
3929       } else {
3930          state->push_size[1] = shader ? shader->layout->push_constant_size : 0;
3931       }
3932    }
3933 
3934    if ((new_stages | null_stages) & LVP_STAGE_MASK_GFX) {
3935       VkShaderStageFlags all_gfx = VK_SHADER_STAGE_ALL_GRAPHICS | VK_SHADER_STAGE_MESH_BIT_EXT | VK_SHADER_STAGE_TASK_BIT_EXT;
3936       unbind_graphics_stages(state, null_stages & all_gfx);
3937       handle_graphics_stages(state, vkstages & all_gfx, true);
3938       u_foreach_bit(i, new_stages) {
3939          handle_graphics_pushconsts(state, i, state->shaders[i]);
3940       }
3941    }
3942    /* ignore compute unbinds */
3943    if (new_stages & BITFIELD_BIT(MESA_SHADER_COMPUTE)) {
3944       handle_compute_shader(state, state->shaders[MESA_SHADER_COMPUTE]);
3945    }
3946 
3947    if (gfx) {
3948       state->push_size[0] = 0;
3949       for (unsigned i = 0; i < ARRAY_SIZE(state->gfx_push_sizes); i++)
3950          state->push_size[0] += state->gfx_push_sizes[i];
3951    }
3952 }
3953 
3954 static void
update_mesh_state(struct rendering_state * state)3955 update_mesh_state(struct rendering_state *state)
3956 {
3957    if (state->shaders[MESA_SHADER_TASK]) {
3958       state->dispatch_info.block[0] = state->shaders[MESA_SHADER_TASK]->pipeline_nir->nir->info.workgroup_size[0];
3959       state->dispatch_info.block[1] = state->shaders[MESA_SHADER_TASK]->pipeline_nir->nir->info.workgroup_size[1];
3960       state->dispatch_info.block[2] = state->shaders[MESA_SHADER_TASK]->pipeline_nir->nir->info.workgroup_size[2];
3961    } else {
3962       state->dispatch_info.block[0] = state->shaders[MESA_SHADER_MESH]->pipeline_nir->nir->info.workgroup_size[0];
3963       state->dispatch_info.block[1] = state->shaders[MESA_SHADER_MESH]->pipeline_nir->nir->info.workgroup_size[1];
3964       state->dispatch_info.block[2] = state->shaders[MESA_SHADER_MESH]->pipeline_nir->nir->info.workgroup_size[2];
3965    }
3966 }
3967 
handle_draw_mesh_tasks(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3968 static void handle_draw_mesh_tasks(struct vk_cmd_queue_entry *cmd,
3969                                    struct rendering_state *state)
3970 {
3971    update_mesh_state(state);
3972    state->dispatch_info.grid[0] = cmd->u.draw_mesh_tasks_ext.group_count_x;
3973    state->dispatch_info.grid[1] = cmd->u.draw_mesh_tasks_ext.group_count_y;
3974    state->dispatch_info.grid[2] = cmd->u.draw_mesh_tasks_ext.group_count_z;
3975    state->dispatch_info.grid_base[0] = 0;
3976    state->dispatch_info.grid_base[1] = 0;
3977    state->dispatch_info.grid_base[2] = 0;
3978    state->dispatch_info.draw_count = 1;
3979    state->dispatch_info.indirect = NULL;
3980    state->pctx->draw_mesh_tasks(state->pctx, 0, &state->dispatch_info);
3981 }
3982 
handle_draw_mesh_tasks_indirect(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3983 static void handle_draw_mesh_tasks_indirect(struct vk_cmd_queue_entry *cmd,
3984                                             struct rendering_state *state)
3985 {
3986    update_mesh_state(state);
3987    state->dispatch_info.indirect = lvp_buffer_from_handle(cmd->u.draw_mesh_tasks_indirect_ext.buffer)->bo;
3988    state->dispatch_info.indirect_offset = cmd->u.draw_mesh_tasks_indirect_ext.offset;
3989    state->dispatch_info.indirect_stride = cmd->u.draw_mesh_tasks_indirect_ext.stride;
3990    state->dispatch_info.draw_count = cmd->u.draw_mesh_tasks_indirect_ext.draw_count;
3991    state->pctx->draw_mesh_tasks(state->pctx, 0, &state->dispatch_info);
3992 }
3993 
handle_draw_mesh_tasks_indirect_count(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3994 static void handle_draw_mesh_tasks_indirect_count(struct vk_cmd_queue_entry *cmd,
3995                                                   struct rendering_state *state)
3996 {
3997    update_mesh_state(state);
3998    state->dispatch_info.indirect = lvp_buffer_from_handle(cmd->u.draw_mesh_tasks_indirect_count_ext.buffer)->bo;
3999    state->dispatch_info.indirect_offset = cmd->u.draw_mesh_tasks_indirect_count_ext.offset;
4000    state->dispatch_info.indirect_stride = cmd->u.draw_mesh_tasks_indirect_count_ext.stride;
4001    state->dispatch_info.draw_count = cmd->u.draw_mesh_tasks_indirect_count_ext.max_draw_count;
4002    state->dispatch_info.indirect_draw_count_offset = cmd->u.draw_mesh_tasks_indirect_count_ext.count_buffer_offset;
4003    state->dispatch_info.indirect_draw_count = lvp_buffer_from_handle(cmd->u.draw_mesh_tasks_indirect_count_ext.count_buffer)->bo;
4004    state->pctx->draw_mesh_tasks(state->pctx, 0, &state->dispatch_info);
4005 }
4006 
4007 static VkBuffer
get_buffer(struct rendering_state * state,const uint8_t * ptr,size_t * offset)4008 get_buffer(struct rendering_state *state, const uint8_t *ptr, size_t *offset)
4009 {
4010    simple_mtx_lock(&state->device->bda_lock);
4011    hash_table_foreach(&state->device->bda, he) {
4012       const uint8_t *bda = he->key;
4013       if (ptr < bda)
4014          continue;
4015       struct lvp_buffer *buffer = he->data;
4016       if (bda + buffer->vk.size > ptr) {
4017          *offset = ptr - bda;
4018          simple_mtx_unlock(&state->device->bda_lock);
4019          return lvp_buffer_to_handle(buffer);
4020       }
4021    }
4022    fprintf(stderr, "unrecognized BDA!\n");
4023    abort();
4024 }
4025 
4026 static size_t
process_sequence_ext(struct rendering_state * state,struct lvp_indirect_execution_set * iset,struct lvp_indirect_command_layout_ext * elayout,struct list_head * list,uint8_t * pbuf,size_t max_size,uint8_t * stream,uint32_t seq,uint32_t maxDrawCount,bool print_cmds)4027 process_sequence_ext(struct rendering_state *state,
4028                      struct lvp_indirect_execution_set *iset, struct lvp_indirect_command_layout_ext *elayout,
4029                      struct list_head *list, uint8_t *pbuf, size_t max_size,
4030                      uint8_t *stream, uint32_t seq, uint32_t maxDrawCount,
4031                      bool print_cmds)
4032 {
4033    size_t size = 0;
4034    assert(elayout->vk.token_count);
4035    for (uint32_t t = 0; t < elayout->vk.token_count; t++){
4036       const VkIndirectCommandsLayoutTokenEXT *token = &elayout->tokens[t];
4037       uint32_t offset = elayout->vk.stride * seq + token->offset;
4038       void *input = stream + offset;
4039 
4040       struct vk_cmd_queue_entry *cmd = (struct vk_cmd_queue_entry*)(pbuf + size);
4041       cmd->type = lvp_ext_dgc_token_to_cmd_type(elayout, token);
4042       size_t cmd_size = vk_cmd_queue_type_sizes[cmd->type];
4043       uint8_t *cmdptr = (void*)(pbuf + size + cmd_size);
4044 
4045       if (max_size < size + lvp_ext_dgc_token_size(elayout, token))
4046          abort();
4047 
4048       if (print_cmds)
4049          fprintf(stderr, "DGC %s\n", vk_IndirectCommandsTokenTypeEXT_to_str(token->type));
4050       switch (token->type) {
4051       case VK_INDIRECT_COMMANDS_TOKEN_TYPE_EXECUTION_SET_EXT: {
4052          uint32_t *data = input;
4053          const VkIndirectCommandsExecutionSetTokenEXT *info = token->data.pExecutionSet;
4054          if (info->type == VK_INDIRECT_EXECUTION_SET_INFO_TYPE_PIPELINES_EXT) {
4055             cmd->u.bind_pipeline.pipeline_bind_point = lvp_pipeline_types_from_shader_stages(info->shaderStages);
4056             cmd->u.bind_pipeline.pipeline = iset->array[*data];
4057             /* validate */
4058             lvp_pipeline_from_handle(cmd->u.bind_pipeline.pipeline);
4059 
4060             assert(cmd->u.bind_pipeline.pipeline && "cannot bind null pipeline!");
4061          } else {
4062             unsigned count = util_bitcount(info->shaderStages);
4063             cmd->u.bind_shaders_ext.stage_count = count;
4064             cmd->u.bind_shaders_ext.stages = (void*)cmdptr;
4065             int i = 0;
4066             u_foreach_bit(stage, info->shaderStages) {
4067                cmd->u.bind_shaders_ext.stages[i] = BITFIELD_BIT(stage);
4068                assert(cmd->u.bind_shaders_ext.stages[i] && "cannot bind null shader stage!");
4069                i++;
4070             }
4071             cmd->u.bind_shaders_ext.shaders = (void*)(cmdptr + sizeof(int64_t) * count);
4072             for (unsigned i = 0; i < count; i++) {
4073                cmd->u.bind_shaders_ext.shaders[i] = iset->array[data[i]];
4074                if (cmd->u.bind_shaders_ext.shaders[i])
4075                   lvp_shader_from_handle(cmd->u.bind_shaders_ext.shaders[i]);
4076             }
4077          }
4078          break;
4079       }
4080       case VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_EXT:
4081       case VK_INDIRECT_COMMANDS_TOKEN_TYPE_SEQUENCE_INDEX_EXT: {
4082          uint32_t *data = input;
4083          const VkIndirectCommandsPushConstantTokenEXT *info = token->data.pPushConstant;
4084          cmd->u.push_constants2.push_constants_info = (void*)cmdptr;
4085          VkPushConstantsInfoKHR *pci = cmd->u.push_constants2.push_constants_info;
4086          pci->layout = elayout->vk.layout;
4087          pci->stageFlags = VK_SHADER_STAGE_ALL;
4088          pci->offset = info->updateRange.offset;
4089          pci->size = info->updateRange.size;
4090          pci->pValues = (void*)((uint8_t*)cmdptr + sizeof(VkPushConstantsInfoKHR));
4091          if (token->type == VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_EXT)
4092             memcpy((void*)pci->pValues, data, info->updateRange.size);
4093          else
4094             memcpy((void*)pci->pValues, &seq, info->updateRange.size);
4095 
4096          break;
4097       }
4098 /* these are the DXGI format values to avoid needing the full header */
4099 #define DXGI_FORMAT_R32_UINT 42
4100 #define DXGI_FORMAT_R16_UINT 57
4101       case VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_EXT: {
4102          const VkIndirectCommandsIndexBufferTokenEXT *info = token->data.pIndexBuffer;
4103          VkBindIndexBufferIndirectCommandEXT *data = input;
4104          cmd->u.bind_index_buffer2.offset = 0;
4105          if (data->bufferAddress)
4106             cmd->u.bind_index_buffer2.buffer = get_buffer(state, (void*)(uintptr_t)data->bufferAddress, (size_t*)&cmd->u.bind_index_buffer.offset);
4107          else
4108             cmd->u.bind_index_buffer2.buffer = VK_NULL_HANDLE;
4109          if (info->mode == VK_INDIRECT_COMMANDS_INPUT_MODE_VULKAN_INDEX_BUFFER_EXT) {
4110             cmd->u.bind_index_buffer2.index_type = data->indexType;
4111          } else {
4112             switch ((int)data->indexType) {
4113             case DXGI_FORMAT_R32_UINT:
4114                cmd->u.bind_index_buffer2.index_type = VK_INDEX_TYPE_UINT32;
4115                break;
4116             case DXGI_FORMAT_R16_UINT:
4117                cmd->u.bind_index_buffer2.index_type = VK_INDEX_TYPE_UINT16;
4118                break;
4119             default:
4120                unreachable("unknown DXGI index type!");
4121             }
4122          }
4123          cmd->u.bind_index_buffer2.size = data->size;
4124          break;
4125       }
4126       case VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_EXT: {
4127          VkBindVertexBufferIndirectCommandEXT *data = input;
4128          cmd_size += sizeof(*cmd->u.bind_vertex_buffers2.buffers) + sizeof(*cmd->u.bind_vertex_buffers2.offsets);
4129          cmd_size += sizeof(*cmd->u.bind_vertex_buffers2.sizes) + sizeof(*cmd->u.bind_vertex_buffers2.strides);
4130          if (max_size < size + cmd_size)
4131             abort();
4132 
4133          cmd->u.bind_vertex_buffers2.first_binding = token->data.pVertexBuffer->vertexBindingUnit;
4134          cmd->u.bind_vertex_buffers2.binding_count = 1;
4135 
4136          cmd->u.bind_vertex_buffers2.buffers = (void*)cmdptr;
4137          uint32_t alloc_offset = sizeof(*cmd->u.bind_vertex_buffers2.buffers);
4138 
4139          cmd->u.bind_vertex_buffers2.offsets = (void*)(cmdptr + alloc_offset);
4140          alloc_offset += sizeof(*cmd->u.bind_vertex_buffers2.offsets);
4141 
4142          cmd->u.bind_vertex_buffers2.sizes = (void*)(cmdptr + alloc_offset);
4143          alloc_offset += sizeof(*cmd->u.bind_vertex_buffers2.sizes);
4144 
4145          cmd->u.bind_vertex_buffers2.offsets[0] = 0;
4146          cmd->u.bind_vertex_buffers2.buffers[0] = data->bufferAddress ? get_buffer(state, (void*)(uintptr_t)data->bufferAddress, (size_t*)&cmd->u.bind_vertex_buffers2.offsets[0]) : VK_NULL_HANDLE;
4147          cmd->u.bind_vertex_buffers2.sizes[0] = data->size;
4148 
4149          cmd->u.bind_vertex_buffers2.strides = (void*)(cmdptr + alloc_offset);
4150          cmd->u.bind_vertex_buffers2.strides[0] = data->stride;
4151          break;
4152       }
4153       case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_EXT: {
4154          VkDispatchIndirectCommand *data = input;
4155          memcpy(&cmd->u.dispatch, data, sizeof(VkDispatchIndirectCommand));
4156          break;
4157       }
4158       case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_EXT: {
4159          VkDrawIndexedIndirectCommand *data = input;
4160          memcpy(&cmd->u.draw_indexed, data, sizeof(VkDrawIndexedIndirectCommand));
4161          break;
4162       }
4163       case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_EXT: {
4164          VkDrawIndirectCommand *data = input;
4165          memcpy(&cmd->u.draw, data, sizeof(VkDrawIndirectCommand));
4166          break;
4167       }
4168       case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_COUNT_EXT: {
4169          VkDrawIndirectCountIndirectCommandEXT *data = input;
4170 
4171          cmd->u.draw_indexed_indirect.buffer = get_buffer(state, (void*)(uintptr_t)data->bufferAddress, (size_t*)&cmd->u.draw_indexed_indirect.offset);
4172          cmd->u.draw_indexed_indirect.draw_count = MIN2(data->commandCount, maxDrawCount);
4173          cmd->u.draw_indexed_indirect.stride = data->stride;
4174          break;
4175       }
4176       case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_COUNT_EXT: {
4177          VkDrawIndirectCountIndirectCommandEXT *data = input;
4178 
4179          cmd->u.draw_indirect.buffer = get_buffer(state, (void*)(uintptr_t)data->bufferAddress, (size_t*)&cmd->u.draw_indirect.offset);
4180          cmd->u.draw_indirect.draw_count = MIN2(data->commandCount, maxDrawCount);
4181          cmd->u.draw_indirect.stride = data->stride;
4182          break;
4183       }
4184       // only available if VK_EXT_mesh_shader is supported
4185       case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_EXT: {
4186          VkDrawMeshTasksIndirectCommandEXT *data = input;
4187          memcpy(&cmd->u.draw_mesh_tasks_ext, data, sizeof(VkDrawIndirectCountIndirectCommandEXT));
4188          break;
4189       }
4190       case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_COUNT_EXT: {
4191          VkDrawIndirectCountIndirectCommandEXT *data = input;
4192 
4193          cmd->u.draw_mesh_tasks_indirect_ext.buffer = get_buffer(state, (void*)(uintptr_t)data->bufferAddress, (size_t*)&cmd->u.draw_mesh_tasks_indirect_ext.offset);
4194          cmd->u.draw_mesh_tasks_indirect_ext.draw_count = MIN2(data->commandCount, maxDrawCount);
4195          cmd->u.draw_mesh_tasks_indirect_ext.stride = data->stride;
4196          break;
4197       }
4198       case VK_INDIRECT_COMMANDS_TOKEN_TYPE_TRACE_RAYS2_EXT: {
4199          VkTraceRaysIndirectCommand2KHR *data = input;
4200          VkStridedDeviceAddressRegionKHR *sbts = (void*)cmdptr;
4201 
4202          cmd->u.trace_rays_khr.raygen_shader_binding_table = &sbts[0];
4203          cmd->u.trace_rays_khr.raygen_shader_binding_table->deviceAddress = data->raygenShaderRecordAddress;
4204          cmd->u.trace_rays_khr.raygen_shader_binding_table->stride = data->raygenShaderRecordSize;
4205          cmd->u.trace_rays_khr.raygen_shader_binding_table->size = data->raygenShaderRecordSize;
4206 
4207          cmd->u.trace_rays_khr.miss_shader_binding_table = &sbts[1];
4208          cmd->u.trace_rays_khr.miss_shader_binding_table->deviceAddress = data->missShaderBindingTableAddress;
4209          cmd->u.trace_rays_khr.miss_shader_binding_table->stride = data->missShaderBindingTableStride;
4210          cmd->u.trace_rays_khr.miss_shader_binding_table->size = data->missShaderBindingTableSize;
4211 
4212          cmd->u.trace_rays_khr.hit_shader_binding_table = &sbts[2];
4213          cmd->u.trace_rays_khr.hit_shader_binding_table->deviceAddress = data->hitShaderBindingTableAddress;
4214          cmd->u.trace_rays_khr.hit_shader_binding_table->stride = data->hitShaderBindingTableStride;
4215          cmd->u.trace_rays_khr.hit_shader_binding_table->size = data->hitShaderBindingTableSize;
4216 
4217          cmd->u.trace_rays_khr.callable_shader_binding_table = &sbts[3];
4218          cmd->u.trace_rays_khr.callable_shader_binding_table->deviceAddress = data->callableShaderBindingTableAddress;
4219          cmd->u.trace_rays_khr.callable_shader_binding_table->stride = data->callableShaderBindingTableStride;
4220          cmd->u.trace_rays_khr.callable_shader_binding_table->size = data->callableShaderBindingTableSize;
4221 
4222          cmd->u.trace_rays_khr.width = data->width;
4223          cmd->u.trace_rays_khr.height = data->height;
4224          cmd->u.trace_rays_khr.depth = data->depth;
4225 
4226          break;
4227       }
4228       default:
4229          unreachable("unknown token type");
4230          break;
4231       }
4232       size += lvp_ext_dgc_token_size(elayout, token);
4233       list_addtail(&cmd->cmd_link, list);
4234    }
4235    return size;
4236 }
4237 
4238 static void
handle_preprocess_generated_commands_ext(struct vk_cmd_queue_entry * cmd,struct rendering_state * state,bool print_cmds)4239 handle_preprocess_generated_commands_ext(struct vk_cmd_queue_entry *cmd, struct rendering_state *state, bool print_cmds)
4240 {
4241    VkGeneratedCommandsInfoEXT *pre = cmd->u.preprocess_generated_commands_ext.generated_commands_info;
4242    VK_FROM_HANDLE(lvp_indirect_command_layout_ext, elayout, pre->indirectCommandsLayout);
4243    VK_FROM_HANDLE(lvp_indirect_execution_set, iset, pre->indirectExecutionSet);
4244 
4245    unsigned seq_count = pre->maxSequenceCount;
4246    if (pre->sequenceCountAddress) {
4247       uint32_t *count = (void*)(uintptr_t)pre->sequenceCountAddress;
4248       seq_count = MIN2(seq_count, *count);
4249    }
4250 
4251    struct list_head *list = (void*)(uintptr_t)pre->preprocessAddress;
4252    size_t size = sizeof(struct list_head);
4253    size_t max_size = pre->preprocessSize;
4254    if (size > max_size)
4255       abort();
4256    list_inithead(list);
4257 
4258    size_t offset = size;
4259    uint8_t *p = (void*)(uintptr_t)pre->preprocessAddress;
4260    for (unsigned i = 0; i < seq_count; i++) {
4261       offset += process_sequence_ext(state, iset, elayout, list, p + offset, max_size, (void*)(uintptr_t)pre->indirectAddress, i, pre->maxDrawCount, print_cmds);
4262       assert(offset);
4263    }
4264 
4265    /* vk_cmd_queue will copy the binary and break the list, so null the tail pointer */
4266    list->prev->next = NULL;
4267 }
4268 
4269 static void
handle_execute_generated_commands_ext(struct vk_cmd_queue_entry * cmd,struct rendering_state * state,bool print_cmds)4270 handle_execute_generated_commands_ext(struct vk_cmd_queue_entry *cmd, struct rendering_state *state, bool print_cmds)
4271 {
4272    VkGeneratedCommandsInfoEXT *gen = cmd->u.execute_generated_commands_ext.generated_commands_info;
4273    struct vk_cmd_execute_generated_commands_ext *exec = &cmd->u.execute_generated_commands_ext;
4274    if (!exec->is_preprocessed) {
4275       struct vk_cmd_queue_entry pre;
4276       pre.u.preprocess_generated_commands_ext.generated_commands_info = exec->generated_commands_info;
4277       handle_preprocess_generated_commands_ext(&pre, state, print_cmds);
4278    }
4279    uint8_t *p = (void*)(uintptr_t)gen->preprocessAddress;
4280    struct list_head *list = (void*)p;
4281 
4282    struct vk_cmd_queue_entry *exec_cmd = list_first_entry(list, struct vk_cmd_queue_entry, cmd_link);
4283    if (exec_cmd)
4284       lvp_execute_cmd_buffer(list, state, print_cmds);
4285 }
4286 
4287 static void
handle_descriptor_buffers(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)4288 handle_descriptor_buffers(struct vk_cmd_queue_entry *cmd, struct rendering_state *state)
4289 {
4290    const struct vk_cmd_bind_descriptor_buffers_ext *bind = &cmd->u.bind_descriptor_buffers_ext;
4291    for (unsigned i = 0; i < bind->buffer_count; i++) {
4292       struct pipe_resource *pres = get_buffer_resource(state->pctx, (void *)(uintptr_t)bind->binding_infos[i].address);
4293       state->desc_buffer_addrs[i] = (void *)(uintptr_t)bind->binding_infos[i].address;
4294       pipe_resource_reference(&state->desc_buffers[i], pres);
4295       /* leave only one ref on rendering_state */
4296       pipe_resource_reference(&pres, NULL);
4297    }
4298 }
4299 
4300 static bool
descriptor_layouts_equal(const struct lvp_descriptor_set_layout * a,const struct lvp_descriptor_set_layout * b)4301 descriptor_layouts_equal(const struct lvp_descriptor_set_layout *a, const struct lvp_descriptor_set_layout *b)
4302 {
4303    const uint8_t *pa = (const uint8_t*)a, *pb = (const uint8_t*)b;
4304    uint32_t hash_start_offset = sizeof(struct vk_descriptor_set_layout);
4305    uint32_t binding_offset = offsetof(struct lvp_descriptor_set_layout, binding);
4306    /* base equal */
4307    if (memcmp(pa + hash_start_offset, pb + hash_start_offset, binding_offset - hash_start_offset))
4308       return false;
4309 
4310    /* bindings equal */
4311    if (a->binding_count != b->binding_count)
4312       return false;
4313    size_t binding_size = a->binding_count * sizeof(struct lvp_descriptor_set_binding_layout);
4314    const struct lvp_descriptor_set_binding_layout *la = a->binding;
4315    const struct lvp_descriptor_set_binding_layout *lb = b->binding;
4316    if (memcmp(la, lb, binding_size)) {
4317       for (unsigned i = 0; i < a->binding_count; i++) {
4318          if (memcmp(&la[i], &lb[i], offsetof(struct lvp_descriptor_set_binding_layout, immutable_samplers)))
4319             return false;
4320       }
4321    }
4322 
4323    /* immutable sampler equal */
4324    if (a->immutable_sampler_count != b->immutable_sampler_count)
4325       return false;
4326    if (a->immutable_sampler_count) {
4327       size_t sampler_size = a->immutable_sampler_count * sizeof(struct lvp_sampler *);
4328       if (memcmp(pa + binding_offset + binding_size, pb + binding_offset + binding_size, sampler_size)) {
4329          struct lvp_sampler **sa = (struct lvp_sampler **)(pa + binding_offset);
4330          struct lvp_sampler **sb = (struct lvp_sampler **)(pb + binding_offset);
4331          for (unsigned i = 0; i < a->immutable_sampler_count; i++) {
4332             if (memcmp(sa[i], sb[i], sizeof(struct lvp_sampler)))
4333                return false;
4334          }
4335       }
4336    }
4337    return true;
4338 }
4339 
4340 static void
bind_db_samplers(struct rendering_state * state,enum lvp_pipeline_type pipeline_type,unsigned set)4341 bind_db_samplers(struct rendering_state *state, enum lvp_pipeline_type pipeline_type, unsigned set)
4342 {
4343    const struct lvp_descriptor_set_layout *set_layout = state->desc_buffer_offsets[pipeline_type][set].sampler_layout;
4344    if (!set_layout)
4345       return;
4346    unsigned buffer_index = state->desc_buffer_offsets[pipeline_type][set].buffer_index;
4347    if (!state->desc_buffer_addrs[buffer_index]) {
4348       if (set_layout->immutable_set) {
4349          state->desc_sets[pipeline_type][set] = set_layout->immutable_set;
4350          if (pipeline_type == LVP_PIPELINE_RAY_TRACING) {
4351             handle_set_stage_buffer(state, set_layout->immutable_set->bo, 0, MESA_SHADER_RAYGEN, set);
4352          } else {
4353             u_foreach_bit(stage, set_layout->shader_stages)
4354                handle_set_stage_buffer(state, set_layout->immutable_set->bo, 0, vk_to_mesa_shader_stage(1<<stage), set);
4355          }
4356       }
4357       return;
4358    }
4359    uint8_t *db = state->desc_buffer_addrs[buffer_index] + state->desc_buffer_offsets[pipeline_type][set].offset;
4360    uint32_t did_update = 0;
4361    for (uint32_t binding_index = 0; binding_index < set_layout->binding_count; binding_index++) {
4362       const struct lvp_descriptor_set_binding_layout *bind_layout = &set_layout->binding[binding_index];
4363       if (!bind_layout->immutable_samplers)
4364          continue;
4365 
4366       struct lp_descriptor *desc = (void*)db;
4367       desc += bind_layout->descriptor_index;
4368 
4369       for (uint32_t sampler_index = 0; sampler_index < bind_layout->array_size; sampler_index++) {
4370          if (bind_layout->immutable_samplers[sampler_index]) {
4371             struct lp_descriptor *immutable_desc = &bind_layout->immutable_samplers[sampler_index]->desc;
4372             desc[sampler_index].sampler = immutable_desc->sampler;
4373             desc[sampler_index].texture.sampler_index = immutable_desc->texture.sampler_index;
4374             if (pipeline_type == LVP_PIPELINE_RAY_TRACING) {
4375                did_update |= BITFIELD_BIT(MESA_SHADER_RAYGEN);
4376             } else {
4377                u_foreach_bit(stage, set_layout->shader_stages)
4378                   did_update |= BITFIELD_BIT(vk_to_mesa_shader_stage(1<<stage));
4379             }
4380          }
4381       }
4382    }
4383    u_foreach_bit(stage, did_update)
4384       state->constbuf_dirty[stage] = true;
4385 }
4386 
4387 static void
handle_descriptor_buffer_embedded_samplers(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)4388 handle_descriptor_buffer_embedded_samplers(struct vk_cmd_queue_entry *cmd, struct rendering_state *state)
4389 {
4390    const VkBindDescriptorBufferEmbeddedSamplersInfoEXT *bind = cmd->u.bind_descriptor_buffer_embedded_samplers2_ext.bind_descriptor_buffer_embedded_samplers_info;
4391    LVP_FROM_HANDLE(lvp_pipeline_layout, layout, bind->layout);
4392 
4393    if (!layout->vk.set_layouts[bind->set])
4394       return;
4395 
4396    const struct lvp_descriptor_set_layout *set_layout = get_set_layout(layout, bind->set);
4397    if (!set_layout->immutable_sampler_count)
4398       return;
4399    uint32_t types = lvp_pipeline_types_from_shader_stages(bind->stageFlags);
4400    u_foreach_bit(pipeline_type, types) {
4401       state->desc_buffer_offsets[pipeline_type][bind->set].sampler_layout = set_layout;
4402       bind_db_samplers(state, pipeline_type, bind->set);
4403    }
4404 }
4405 
4406 static void
handle_descriptor_buffer_offsets(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)4407 handle_descriptor_buffer_offsets(struct vk_cmd_queue_entry *cmd, struct rendering_state *state)
4408 {
4409    VkSetDescriptorBufferOffsetsInfoEXT *dbo = cmd->u.set_descriptor_buffer_offsets2_ext.set_descriptor_buffer_offsets_info;
4410    uint32_t types = lvp_pipeline_types_from_shader_stages(dbo->stageFlags);
4411    u_foreach_bit(pipeline_type, types) {
4412       for (unsigned i = 0; i < dbo->setCount; i++) {
4413          LVP_FROM_HANDLE(lvp_pipeline_layout, layout, dbo->layout);
4414          unsigned idx = dbo->firstSet + i;
4415          state->desc_buffer_offsets[pipeline_type][idx].buffer_index = dbo->pBufferIndices[i];
4416          state->desc_buffer_offsets[pipeline_type][idx].offset = dbo->pOffsets[i];
4417          const struct lvp_descriptor_set_layout *set_layout = get_set_layout(layout, idx);
4418 
4419          if (pipeline_type == LVP_PIPELINE_RAY_TRACING) {
4420             handle_set_stage_buffer(state, state->desc_buffers[dbo->pBufferIndices[i]], dbo->pOffsets[i], MESA_SHADER_RAYGEN, idx);
4421          } else {
4422             /* set for all stages */
4423             u_foreach_bit(stage, set_layout->shader_stages) {
4424                gl_shader_stage pstage = vk_to_mesa_shader_stage(1<<stage);
4425                handle_set_stage_buffer(state, state->desc_buffers[dbo->pBufferIndices[i]], dbo->pOffsets[i], pstage, idx);
4426             }
4427          }
4428          bind_db_samplers(state, pipeline_type, idx);
4429       }
4430    }
4431 }
4432 
4433 static void *
lvp_push_internal_buffer(struct rendering_state * state,gl_shader_stage stage,uint32_t size)4434 lvp_push_internal_buffer(struct rendering_state *state, gl_shader_stage stage, uint32_t size)
4435 {
4436    if (!size)
4437       return NULL;
4438 
4439    struct pipe_shader_buffer buffer = {
4440       .buffer_size = size,
4441    };
4442 
4443    uint8_t *mem;
4444    u_upload_alloc(state->uploader, 0, size, 64, &buffer.buffer_offset, &buffer.buffer, (void**)&mem);
4445 
4446    state->pctx->set_shader_buffers(state->pctx, stage, 0, 1, &buffer, 0x1);
4447 
4448    util_dynarray_append(&state->internal_buffers, struct pipe_resource *, buffer.buffer);
4449 
4450    return mem;
4451 }
4452 
4453 #ifdef VK_ENABLE_BETA_EXTENSIONS
4454 
4455 static void
dispatch_graph(struct rendering_state * state,const VkDispatchGraphInfoAMDX * info,void * scratch)4456 dispatch_graph(struct rendering_state *state, const VkDispatchGraphInfoAMDX *info, void *scratch)
4457 {
4458    VK_FROM_HANDLE(lvp_pipeline, pipeline, state->exec_graph->groups[info->nodeIndex]);
4459    struct lvp_shader *shader = &pipeline->shaders[MESA_SHADER_COMPUTE];
4460    nir_shader *nir = shader->pipeline_nir->nir;
4461 
4462    VkPipelineShaderStageNodeCreateInfoAMDX enqueue_node_info = {
4463       .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_NODE_CREATE_INFO_AMDX,
4464       .pName = pipeline->exec_graph.next_name,
4465    };
4466 
4467    for (uint32_t i = 0; i < info->payloadCount; i++) {
4468       const void *payload = (const void *)((const uint8_t *)info->payloads.hostAddress + i * info->payloadStride);
4469 
4470       /* The spec doesn't specify any useful limits for enqueued payloads.
4471        * Since we allocate them in scratch memory (provided to the dispatch entrypoint),
4472        * we need to execute recursive shaders one to keep scratch requirements finite.
4473        */
4474       VkDispatchIndirectCommand dispatch = *(const VkDispatchIndirectCommand *)payload;
4475       if (nir->info.cs.workgroup_count[0]) {
4476          dispatch.x = nir->info.cs.workgroup_count[0];
4477          dispatch.y = nir->info.cs.workgroup_count[1];
4478          dispatch.z = nir->info.cs.workgroup_count[2];
4479       }
4480 
4481       state->dispatch_info.indirect = NULL;
4482       state->dispatch_info.grid[0] = 1;
4483       state->dispatch_info.grid[1] = 1;
4484       state->dispatch_info.grid[2] = 1;
4485 
4486       for (uint32_t z = 0; z < dispatch.z; z++) {
4487          for (uint32_t y = 0; y < dispatch.y; y++) {
4488             for (uint32_t x = 0; x < dispatch.x; x++) {
4489                handle_compute_shader(state, shader);
4490                emit_compute_state(state);
4491 
4492                state->dispatch_info.grid_base[0] = x;
4493                state->dispatch_info.grid_base[1] = y;
4494                state->dispatch_info.grid_base[2] = z;
4495 
4496                struct lvp_exec_graph_internal_data *internal_data =
4497                   lvp_push_internal_buffer(state, MESA_SHADER_COMPUTE, sizeof(struct lvp_exec_graph_internal_data));
4498                internal_data->payload_in = (void *)payload;
4499                internal_data->payloads = (void *)scratch;
4500 
4501                state->pctx->launch_grid(state->pctx, &state->dispatch_info);
4502 
4503                /* Amazing performance. */
4504                finish_fence(state);
4505 
4506                for (uint32_t enqueue = 0; enqueue < ARRAY_SIZE(internal_data->outputs); enqueue++) {
4507                   struct lvp_exec_graph_shader_output *output = &internal_data->outputs[enqueue];
4508                   if (!output->payload_count)
4509                      continue;
4510 
4511                   VkDispatchGraphInfoAMDX enqueue_info = {
4512                      .payloadCount = output->payload_count,
4513                      .payloads.hostAddress = (uint8_t *)scratch + enqueue * nir->info.cs.node_payloads_size,
4514                      .payloadStride = nir->info.cs.node_payloads_size,
4515                   };
4516 
4517                   enqueue_node_info.index = output->node_index;
4518 
4519                   ASSERTED VkResult result = lvp_GetExecutionGraphPipelineNodeIndexAMDX(
4520                      lvp_device_to_handle(state->device), lvp_pipeline_to_handle(state->exec_graph),
4521                      &enqueue_node_info, &enqueue_info.nodeIndex);
4522                   assert(result == VK_SUCCESS);
4523 
4524                   dispatch_graph(state, &enqueue_info, (uint8_t *)scratch + pipeline->exec_graph.scratch_size);
4525                }
4526             }
4527          }
4528       }
4529    }
4530 }
4531 
4532 static void
handle_dispatch_graph(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)4533 handle_dispatch_graph(struct vk_cmd_queue_entry *cmd, struct rendering_state *state)
4534 {
4535    const struct vk_cmd_dispatch_graph_amdx *dispatch = &cmd->u.dispatch_graph_amdx;
4536 
4537    for (uint32_t i = 0; i < dispatch->count_info->count; i++) {
4538       const VkDispatchGraphInfoAMDX *info = (const void *)((const uint8_t *)dispatch->count_info->infos.hostAddress +
4539                                                            i * dispatch->count_info->stride);
4540 
4541       dispatch_graph(state, info, (void *)(uintptr_t)dispatch->scratch);
4542    }
4543 }
4544 #endif
4545 
4546 static struct pipe_resource *
get_buffer_pipe(struct rendering_state * state,const void * ptr)4547 get_buffer_pipe(struct rendering_state *state, const void *ptr)
4548 {
4549    size_t offset;
4550    VK_FROM_HANDLE(lvp_buffer, buffer, get_buffer(state, ptr, &offset));
4551    return buffer->bo;
4552 }
4553 
4554 static void
handle_copy_acceleration_structure(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)4555 handle_copy_acceleration_structure(struct vk_cmd_queue_entry *cmd, struct rendering_state *state)
4556 {
4557    struct vk_cmd_copy_acceleration_structure_khr *copy = &cmd->u.copy_acceleration_structure_khr;
4558 
4559    VK_FROM_HANDLE(vk_acceleration_structure, src, copy->info->src);
4560    VK_FROM_HANDLE(vk_acceleration_structure, dst, copy->info->dst);
4561 
4562    struct pipe_box box = { 0 };
4563    u_box_1d(src->offset, MIN2(src->size, dst->size), &box);
4564    state->pctx->resource_copy_region(state->pctx, lvp_buffer_from_handle(dst->buffer)->bo, 0,
4565                                      dst->offset, 0, 0,
4566                                      lvp_buffer_from_handle(src->buffer)->bo, 0, &box);
4567 }
4568 
4569 static void
handle_copy_memory_to_acceleration_structure(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)4570 handle_copy_memory_to_acceleration_structure(struct vk_cmd_queue_entry *cmd, struct rendering_state *state)
4571 {
4572    struct vk_cmd_copy_memory_to_acceleration_structure_khr *copy = &cmd->u.copy_memory_to_acceleration_structure_khr;
4573 
4574    VK_FROM_HANDLE(vk_acceleration_structure, accel_struct, copy->info->dst);
4575 
4576    struct lvp_bvh_header *dst = (void *)(uintptr_t)vk_acceleration_structure_get_va(accel_struct);
4577    const struct lvp_accel_struct_serialization_header *src = copy->info->src.hostAddress;
4578 
4579    memcpy(dst, &src->instances[src->instance_count], src->compacted_size);
4580 
4581    for (uint32_t i = 0; i < src->instance_count; i++) {
4582       uint8_t *leaf_nodes = (uint8_t *)dst;
4583       leaf_nodes += dst->leaf_nodes_offset;
4584       struct lvp_bvh_instance_node *node = (struct lvp_bvh_instance_node *)leaf_nodes;
4585       node[i].bvh_ptr = src->instances[i];
4586    }
4587 }
4588 
4589 static void
handle_copy_acceleration_structure_to_memory(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)4590 handle_copy_acceleration_structure_to_memory(struct vk_cmd_queue_entry *cmd, struct rendering_state *state)
4591 {
4592    struct vk_cmd_copy_acceleration_structure_to_memory_khr *copy = &cmd->u.copy_acceleration_structure_to_memory_khr;
4593 
4594    VK_FROM_HANDLE(vk_acceleration_structure, accel_struct, copy->info->src);
4595 
4596    struct lvp_bvh_header *src = (void *)(uintptr_t)vk_acceleration_structure_get_va(accel_struct);
4597    struct lvp_accel_struct_serialization_header *dst = copy->info->dst.hostAddress;
4598 
4599    lvp_device_get_cache_uuid(dst->driver_uuid);
4600    lvp_device_get_cache_uuid(dst->accel_struct_compat);
4601    dst->serialization_size = src->serialization_size;
4602    dst->compacted_size = accel_struct->size;
4603    dst->instance_count = src->instance_count;
4604 
4605    for (uint32_t i = 0; i < src->instance_count; i++) {
4606       uint8_t *leaf_nodes = (uint8_t *)src;
4607       leaf_nodes += src->leaf_nodes_offset;
4608       struct lvp_bvh_instance_node *node = (struct lvp_bvh_instance_node *)leaf_nodes;
4609       dst->instances[i] = node[i].bvh_ptr;
4610    }
4611 
4612    memcpy(&dst->instances[dst->instance_count], src, accel_struct->size);
4613 }
4614 
4615 static void
handle_build_acceleration_structures(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)4616 handle_build_acceleration_structures(struct vk_cmd_queue_entry *cmd, struct rendering_state *state)
4617 {
4618    struct vk_cmd_build_acceleration_structures_khr *build = &cmd->u.build_acceleration_structures_khr;
4619 
4620    for (uint32_t i = 0; i < build->info_count; i++)
4621       lvp_build_acceleration_structure(&build->infos[i], build->pp_build_range_infos[i]);
4622 }
4623 
4624 static void
handle_write_acceleration_structures_properties(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)4625 handle_write_acceleration_structures_properties(struct vk_cmd_queue_entry *cmd, struct rendering_state *state)
4626 {
4627    struct vk_cmd_write_acceleration_structures_properties_khr *write = &cmd->u.write_acceleration_structures_properties_khr;
4628 
4629    VK_FROM_HANDLE(lvp_query_pool, pool, write->query_pool);
4630 
4631    uint64_t *dst = pool->data;
4632    dst += write->first_query;
4633 
4634    for (uint32_t i = 0; i < write->acceleration_structure_count; i++) {
4635       VK_FROM_HANDLE(vk_acceleration_structure, accel_struct, write->acceleration_structures[i]);
4636 
4637       switch ((uint32_t)pool->base_type) {
4638       case LVP_QUERY_ACCELERATION_STRUCTURE_COMPACTED_SIZE:
4639          dst[i] = accel_struct->size;
4640          break;
4641       case LVP_QUERY_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE: {
4642          struct lvp_bvh_header *header = (void *)(uintptr_t)vk_acceleration_structure_get_va(accel_struct);
4643          dst[i] = header->serialization_size;
4644          break;
4645       }
4646       case LVP_QUERY_ACCELERATION_STRUCTURE_SIZE:
4647          dst[i] = accel_struct->size;
4648          break;
4649       case LVP_QUERY_ACCELERATION_STRUCTURE_INSTANCE_COUNT: {
4650          struct lvp_bvh_header *header = (void *)(uintptr_t)vk_acceleration_structure_get_va(accel_struct);
4651          dst[i] = header->instance_count;
4652          break;
4653       }
4654       default:
4655          unreachable("Unsupported query type");
4656       }
4657    }
4658 }
4659 
emit_ray_tracing_state(struct rendering_state * state)4660 static void emit_ray_tracing_state(struct rendering_state *state)
4661 {
4662    bool pcbuf_dirty = state->pcbuf_dirty[MESA_SHADER_RAYGEN];
4663    if (pcbuf_dirty)
4664       update_pcbuf(state, MESA_SHADER_COMPUTE, MESA_SHADER_RAYGEN);
4665 
4666    if (state->constbuf_dirty[MESA_SHADER_RAYGEN]) {
4667       for (unsigned i = 0; i < state->num_const_bufs[MESA_SHADER_RAYGEN]; i++)
4668          state->pctx->set_constant_buffer(state->pctx, MESA_SHADER_COMPUTE,
4669                                           i + 1, false, &state->const_buffer[MESA_SHADER_RAYGEN][i]);
4670       state->constbuf_dirty[MESA_SHADER_RAYGEN] = false;
4671    }
4672 
4673    state->pctx->bind_compute_state(state->pctx, state->shaders[MESA_SHADER_RAYGEN]->shader_cso);
4674 
4675    state->pcbuf_dirty[MESA_SHADER_COMPUTE] = true;
4676    state->constbuf_dirty[MESA_SHADER_COMPUTE] = true;
4677    state->compute_shader_dirty = true;
4678 }
4679 
4680 static void
handle_trace_rays(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)4681 handle_trace_rays(struct vk_cmd_queue_entry *cmd, struct rendering_state *state)
4682 {
4683    struct vk_cmd_trace_rays_khr *trace = &cmd->u.trace_rays_khr;
4684 
4685    emit_ray_tracing_state(state);
4686 
4687    VkTraceRaysIndirectCommand2KHR *command = lvp_push_internal_buffer(
4688       state, MESA_SHADER_COMPUTE, sizeof(VkTraceRaysIndirectCommand2KHR));
4689 
4690    *command = (VkTraceRaysIndirectCommand2KHR) {
4691       .raygenShaderRecordAddress = trace->raygen_shader_binding_table->deviceAddress,
4692       .raygenShaderRecordSize = trace->raygen_shader_binding_table->size,
4693       .missShaderBindingTableAddress = trace->miss_shader_binding_table->deviceAddress,
4694       .missShaderBindingTableSize = trace->miss_shader_binding_table->size,
4695       .missShaderBindingTableStride = trace->miss_shader_binding_table->stride,
4696       .hitShaderBindingTableAddress = trace->hit_shader_binding_table->deviceAddress,
4697       .hitShaderBindingTableSize = trace->hit_shader_binding_table->size,
4698       .hitShaderBindingTableStride = trace->hit_shader_binding_table->stride,
4699       .callableShaderBindingTableAddress = trace->callable_shader_binding_table->deviceAddress,
4700       .callableShaderBindingTableSize = trace->callable_shader_binding_table->size,
4701       .callableShaderBindingTableStride = trace->callable_shader_binding_table->stride,
4702       .width = trace->width,
4703       .height = trace->height,
4704       .depth = trace->depth,
4705    };
4706 
4707    state->trace_rays_info.grid[0] = DIV_ROUND_UP(trace->width, state->trace_rays_info.block[0]);
4708    state->trace_rays_info.grid[1] = DIV_ROUND_UP(trace->height, state->trace_rays_info.block[1]);
4709    state->trace_rays_info.grid[2] = DIV_ROUND_UP(trace->depth, state->trace_rays_info.block[2]);
4710 
4711    state->pctx->launch_grid(state->pctx, &state->trace_rays_info);
4712 }
4713 
4714 static void
handle_trace_rays_indirect(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)4715 handle_trace_rays_indirect(struct vk_cmd_queue_entry *cmd, struct rendering_state *state)
4716 {
4717    struct vk_cmd_trace_rays_indirect_khr *trace = &cmd->u.trace_rays_indirect_khr;
4718 
4719    emit_ray_tracing_state(state);
4720 
4721    size_t indirect_offset;
4722    VkBuffer _indirect = get_buffer(state, (void *)(uintptr_t)trace->indirect_device_address, &indirect_offset);
4723    VK_FROM_HANDLE(lvp_buffer, indirect, _indirect);
4724 
4725    struct pipe_transfer *transfer;
4726    const uint8_t *map = pipe_buffer_map(state->pctx, indirect->bo, PIPE_MAP_READ, &transfer);
4727    map += indirect_offset;
4728    const VkTraceRaysIndirectCommandKHR *src = (const void *)map;
4729 
4730    VkTraceRaysIndirectCommand2KHR *command = lvp_push_internal_buffer(
4731       state, MESA_SHADER_COMPUTE, sizeof(VkTraceRaysIndirectCommand2KHR));
4732 
4733    *command = (VkTraceRaysIndirectCommand2KHR) {
4734       .raygenShaderRecordAddress = trace->raygen_shader_binding_table->deviceAddress,
4735       .raygenShaderRecordSize = trace->raygen_shader_binding_table->size,
4736       .missShaderBindingTableAddress = trace->miss_shader_binding_table->deviceAddress,
4737       .missShaderBindingTableSize = trace->miss_shader_binding_table->size,
4738       .missShaderBindingTableStride = trace->miss_shader_binding_table->stride,
4739       .hitShaderBindingTableAddress = trace->hit_shader_binding_table->deviceAddress,
4740       .hitShaderBindingTableSize = trace->hit_shader_binding_table->size,
4741       .hitShaderBindingTableStride = trace->hit_shader_binding_table->stride,
4742       .callableShaderBindingTableAddress = trace->callable_shader_binding_table->deviceAddress,
4743       .callableShaderBindingTableSize = trace->callable_shader_binding_table->size,
4744       .callableShaderBindingTableStride = trace->callable_shader_binding_table->stride,
4745       .width = src->width,
4746       .height = src->height,
4747       .depth = src->depth,
4748    };
4749 
4750    state->trace_rays_info.grid[0] = DIV_ROUND_UP(src->width, state->trace_rays_info.block[0]);
4751    state->trace_rays_info.grid[1] = DIV_ROUND_UP(src->height, state->trace_rays_info.block[1]);
4752    state->trace_rays_info.grid[2] = DIV_ROUND_UP(src->depth, state->trace_rays_info.block[2]);
4753 
4754    state->pctx->buffer_unmap(state->pctx, transfer);
4755 
4756    state->pctx->launch_grid(state->pctx, &state->trace_rays_info);
4757 }
4758 
4759 static void
handle_trace_rays_indirect2(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)4760 handle_trace_rays_indirect2(struct vk_cmd_queue_entry *cmd, struct rendering_state *state)
4761 {
4762    struct vk_cmd_trace_rays_indirect2_khr *trace = &cmd->u.trace_rays_indirect2_khr;
4763 
4764    emit_ray_tracing_state(state);
4765 
4766    size_t indirect_offset;
4767    VkBuffer _indirect = get_buffer(state, (void *)(uintptr_t)trace->indirect_device_address, &indirect_offset);
4768    VK_FROM_HANDLE(lvp_buffer, indirect, _indirect);
4769 
4770    struct pipe_transfer *transfer;
4771    const uint8_t *map = pipe_buffer_map(state->pctx, indirect->bo, PIPE_MAP_READ, &transfer);
4772    map += indirect_offset;
4773    const VkTraceRaysIndirectCommand2KHR *src = (const void *)map;
4774 
4775    VkTraceRaysIndirectCommand2KHR *command = lvp_push_internal_buffer(
4776       state, MESA_SHADER_COMPUTE, sizeof(VkTraceRaysIndirectCommand2KHR));
4777    *command = *src;
4778 
4779    state->trace_rays_info.grid[0] = DIV_ROUND_UP(src->width, state->trace_rays_info.block[0]);
4780    state->trace_rays_info.grid[1] = DIV_ROUND_UP(src->height, state->trace_rays_info.block[1]);
4781    state->trace_rays_info.grid[2] = DIV_ROUND_UP(src->depth, state->trace_rays_info.block[2]);
4782 
4783    state->pctx->buffer_unmap(state->pctx, transfer);
4784 
4785    state->pctx->launch_grid(state->pctx, &state->trace_rays_info);
4786 }
4787 
lvp_add_enqueue_cmd_entrypoints(struct vk_device_dispatch_table * disp)4788 void lvp_add_enqueue_cmd_entrypoints(struct vk_device_dispatch_table *disp)
4789 {
4790    struct vk_device_dispatch_table cmd_enqueue_dispatch;
4791    vk_device_dispatch_table_from_entrypoints(&cmd_enqueue_dispatch,
4792       &vk_cmd_enqueue_device_entrypoints, true);
4793 
4794 #define ENQUEUE_CMD(CmdName) \
4795    assert(cmd_enqueue_dispatch.CmdName != NULL); \
4796    disp->CmdName = cmd_enqueue_dispatch.CmdName;
4797 
4798    /* This list needs to match what's in lvp_execute_cmd_buffer exactly */
4799    ENQUEUE_CMD(CmdBindPipeline)
4800    ENQUEUE_CMD(CmdSetViewport)
4801    ENQUEUE_CMD(CmdSetViewportWithCount)
4802    ENQUEUE_CMD(CmdSetScissor)
4803    ENQUEUE_CMD(CmdSetScissorWithCount)
4804    ENQUEUE_CMD(CmdSetLineWidth)
4805    ENQUEUE_CMD(CmdSetDepthBias)
4806    ENQUEUE_CMD(CmdSetBlendConstants)
4807    ENQUEUE_CMD(CmdSetDepthBounds)
4808    ENQUEUE_CMD(CmdSetStencilCompareMask)
4809    ENQUEUE_CMD(CmdSetStencilWriteMask)
4810    ENQUEUE_CMD(CmdSetStencilReference)
4811    ENQUEUE_CMD(CmdBindDescriptorSets2KHR)
4812    ENQUEUE_CMD(CmdBindIndexBuffer)
4813    ENQUEUE_CMD(CmdBindIndexBuffer2KHR)
4814    ENQUEUE_CMD(CmdBindVertexBuffers2)
4815    ENQUEUE_CMD(CmdDraw)
4816    ENQUEUE_CMD(CmdDrawMultiEXT)
4817    ENQUEUE_CMD(CmdDrawIndexed)
4818    ENQUEUE_CMD(CmdDrawIndirect)
4819    ENQUEUE_CMD(CmdDrawIndexedIndirect)
4820    ENQUEUE_CMD(CmdDrawMultiIndexedEXT)
4821    ENQUEUE_CMD(CmdDispatch)
4822    ENQUEUE_CMD(CmdDispatchBase)
4823    ENQUEUE_CMD(CmdDispatchIndirect)
4824    ENQUEUE_CMD(CmdCopyBuffer2)
4825    ENQUEUE_CMD(CmdCopyImage2)
4826    ENQUEUE_CMD(CmdBlitImage2)
4827    ENQUEUE_CMD(CmdCopyBufferToImage2)
4828    ENQUEUE_CMD(CmdCopyImageToBuffer2)
4829    ENQUEUE_CMD(CmdUpdateBuffer)
4830    ENQUEUE_CMD(CmdFillBuffer)
4831    ENQUEUE_CMD(CmdClearColorImage)
4832    ENQUEUE_CMD(CmdClearDepthStencilImage)
4833    ENQUEUE_CMD(CmdClearAttachments)
4834    ENQUEUE_CMD(CmdResolveImage2)
4835    ENQUEUE_CMD(CmdBeginQueryIndexedEXT)
4836    ENQUEUE_CMD(CmdEndQueryIndexedEXT)
4837    ENQUEUE_CMD(CmdBeginQuery)
4838    ENQUEUE_CMD(CmdEndQuery)
4839    ENQUEUE_CMD(CmdResetQueryPool)
4840    ENQUEUE_CMD(CmdCopyQueryPoolResults)
4841    ENQUEUE_CMD(CmdExecuteCommands)
4842    ENQUEUE_CMD(CmdDrawIndirectCount)
4843    ENQUEUE_CMD(CmdDrawIndexedIndirectCount)
4844    ENQUEUE_CMD(CmdBindTransformFeedbackBuffersEXT)
4845    ENQUEUE_CMD(CmdBeginTransformFeedbackEXT)
4846    ENQUEUE_CMD(CmdEndTransformFeedbackEXT)
4847    ENQUEUE_CMD(CmdDrawIndirectByteCountEXT)
4848    ENQUEUE_CMD(CmdBeginConditionalRenderingEXT)
4849    ENQUEUE_CMD(CmdEndConditionalRenderingEXT)
4850    ENQUEUE_CMD(CmdSetVertexInputEXT)
4851    ENQUEUE_CMD(CmdSetCullMode)
4852    ENQUEUE_CMD(CmdSetFrontFace)
4853    ENQUEUE_CMD(CmdSetPrimitiveTopology)
4854    ENQUEUE_CMD(CmdSetDepthTestEnable)
4855    ENQUEUE_CMD(CmdSetDepthWriteEnable)
4856    ENQUEUE_CMD(CmdSetDepthCompareOp)
4857    ENQUEUE_CMD(CmdSetDepthBoundsTestEnable)
4858    ENQUEUE_CMD(CmdSetStencilTestEnable)
4859    ENQUEUE_CMD(CmdSetStencilOp)
4860    ENQUEUE_CMD(CmdSetLineStippleEXT)
4861    ENQUEUE_CMD(CmdSetLineStippleKHR)
4862    ENQUEUE_CMD(CmdSetDepthBiasEnable)
4863    ENQUEUE_CMD(CmdSetLogicOpEXT)
4864    ENQUEUE_CMD(CmdSetPatchControlPointsEXT)
4865    ENQUEUE_CMD(CmdSetPrimitiveRestartEnable)
4866    ENQUEUE_CMD(CmdSetRasterizerDiscardEnable)
4867    ENQUEUE_CMD(CmdSetColorWriteEnableEXT)
4868    ENQUEUE_CMD(CmdBeginRendering)
4869    ENQUEUE_CMD(CmdEndRendering)
4870    ENQUEUE_CMD(CmdSetDeviceMask)
4871    ENQUEUE_CMD(CmdPipelineBarrier2)
4872    ENQUEUE_CMD(CmdResetEvent2)
4873    ENQUEUE_CMD(CmdSetEvent2)
4874    ENQUEUE_CMD(CmdWaitEvents2)
4875    ENQUEUE_CMD(CmdWriteTimestamp2)
4876    ENQUEUE_CMD(CmdPushConstants2KHR)
4877    ENQUEUE_CMD(CmdPushDescriptorSet2KHR)
4878    ENQUEUE_CMD(CmdPushDescriptorSetWithTemplate2KHR)
4879    ENQUEUE_CMD(CmdBindDescriptorBuffersEXT)
4880    ENQUEUE_CMD(CmdSetDescriptorBufferOffsets2EXT)
4881    ENQUEUE_CMD(CmdBindDescriptorBufferEmbeddedSamplers2EXT)
4882 
4883    ENQUEUE_CMD(CmdSetPolygonModeEXT)
4884    ENQUEUE_CMD(CmdSetTessellationDomainOriginEXT)
4885    ENQUEUE_CMD(CmdSetDepthClampEnableEXT)
4886    ENQUEUE_CMD(CmdSetDepthClipEnableEXT)
4887    ENQUEUE_CMD(CmdSetLogicOpEnableEXT)
4888    ENQUEUE_CMD(CmdSetSampleMaskEXT)
4889    ENQUEUE_CMD(CmdSetRasterizationSamplesEXT)
4890    ENQUEUE_CMD(CmdSetAlphaToCoverageEnableEXT)
4891    ENQUEUE_CMD(CmdSetAlphaToOneEnableEXT)
4892    ENQUEUE_CMD(CmdSetDepthClipNegativeOneToOneEXT)
4893    ENQUEUE_CMD(CmdSetLineRasterizationModeEXT)
4894    ENQUEUE_CMD(CmdSetLineStippleEnableEXT)
4895    ENQUEUE_CMD(CmdSetProvokingVertexModeEXT)
4896    ENQUEUE_CMD(CmdSetColorBlendEnableEXT)
4897    ENQUEUE_CMD(CmdSetColorBlendEquationEXT)
4898    ENQUEUE_CMD(CmdSetColorWriteMaskEXT)
4899 
4900    ENQUEUE_CMD(CmdBindShadersEXT)
4901    /* required for EXT_shader_object */
4902    ENQUEUE_CMD(CmdSetCoverageModulationModeNV)
4903    ENQUEUE_CMD(CmdSetCoverageModulationTableEnableNV)
4904    ENQUEUE_CMD(CmdSetCoverageModulationTableNV)
4905    ENQUEUE_CMD(CmdSetCoverageReductionModeNV)
4906    ENQUEUE_CMD(CmdSetCoverageToColorEnableNV)
4907    ENQUEUE_CMD(CmdSetCoverageToColorLocationNV)
4908    ENQUEUE_CMD(CmdSetRepresentativeFragmentTestEnableNV)
4909    ENQUEUE_CMD(CmdSetShadingRateImageEnableNV)
4910    ENQUEUE_CMD(CmdSetViewportSwizzleNV)
4911    ENQUEUE_CMD(CmdSetViewportWScalingEnableNV)
4912    ENQUEUE_CMD(CmdSetAttachmentFeedbackLoopEnableEXT)
4913    ENQUEUE_CMD(CmdDrawMeshTasksEXT)
4914    ENQUEUE_CMD(CmdDrawMeshTasksIndirectEXT)
4915    ENQUEUE_CMD(CmdDrawMeshTasksIndirectCountEXT)
4916 
4917    ENQUEUE_CMD(CmdBindPipelineShaderGroupNV)
4918    ENQUEUE_CMD(CmdPreprocessGeneratedCommandsNV)
4919    ENQUEUE_CMD(CmdExecuteGeneratedCommandsNV)
4920    ENQUEUE_CMD(CmdPreprocessGeneratedCommandsEXT)
4921    ENQUEUE_CMD(CmdExecuteGeneratedCommandsEXT)
4922 
4923 #ifdef VK_ENABLE_BETA_EXTENSIONS
4924    ENQUEUE_CMD(CmdInitializeGraphScratchMemoryAMDX)
4925    ENQUEUE_CMD(CmdDispatchGraphIndirectCountAMDX)
4926    ENQUEUE_CMD(CmdDispatchGraphIndirectAMDX)
4927    ENQUEUE_CMD(CmdDispatchGraphAMDX)
4928 #endif
4929 
4930    ENQUEUE_CMD(CmdSetRenderingAttachmentLocationsKHR)
4931    ENQUEUE_CMD(CmdSetRenderingInputAttachmentIndicesKHR)
4932 
4933    ENQUEUE_CMD(CmdCopyAccelerationStructureKHR)
4934    ENQUEUE_CMD(CmdCopyMemoryToAccelerationStructureKHR)
4935    ENQUEUE_CMD(CmdCopyAccelerationStructureToMemoryKHR)
4936    ENQUEUE_CMD(CmdBuildAccelerationStructuresKHR)
4937    ENQUEUE_CMD(CmdBuildAccelerationStructuresIndirectKHR)
4938    ENQUEUE_CMD(CmdWriteAccelerationStructuresPropertiesKHR)
4939 
4940    ENQUEUE_CMD(CmdSetRayTracingPipelineStackSizeKHR)
4941    ENQUEUE_CMD(CmdTraceRaysIndirect2KHR)
4942    ENQUEUE_CMD(CmdTraceRaysIndirectKHR)
4943    ENQUEUE_CMD(CmdTraceRaysKHR)
4944 
4945 #undef ENQUEUE_CMD
4946 }
4947 
lvp_execute_cmd_buffer(struct list_head * cmds,struct rendering_state * state,bool print_cmds)4948 static void lvp_execute_cmd_buffer(struct list_head *cmds,
4949                                    struct rendering_state *state, bool print_cmds)
4950 {
4951    struct vk_cmd_queue_entry *cmd;
4952    bool did_flush = false;
4953 
4954    LIST_FOR_EACH_ENTRY(cmd, cmds, cmd_link) {
4955       if (print_cmds)
4956          fprintf(stderr, "%s\n", vk_cmd_queue_type_names[cmd->type]);
4957       switch ((unsigned)cmd->type) {
4958       case VK_CMD_BIND_PIPELINE:
4959          handle_pipeline(cmd, state);
4960          break;
4961       case VK_CMD_SET_VIEWPORT:
4962          handle_set_viewport(cmd, state);
4963          break;
4964       case VK_CMD_SET_VIEWPORT_WITH_COUNT:
4965          handle_set_viewport_with_count(cmd, state);
4966          break;
4967       case VK_CMD_SET_SCISSOR:
4968          handle_set_scissor(cmd, state);
4969          break;
4970       case VK_CMD_SET_SCISSOR_WITH_COUNT:
4971          handle_set_scissor_with_count(cmd, state);
4972          break;
4973       case VK_CMD_SET_LINE_WIDTH:
4974          handle_set_line_width(cmd, state);
4975          break;
4976       case VK_CMD_SET_DEPTH_BIAS:
4977          handle_set_depth_bias(cmd, state);
4978          break;
4979       case VK_CMD_SET_BLEND_CONSTANTS:
4980          handle_set_blend_constants(cmd, state);
4981          break;
4982       case VK_CMD_SET_DEPTH_BOUNDS:
4983          handle_set_depth_bounds(cmd, state);
4984          break;
4985       case VK_CMD_SET_STENCIL_COMPARE_MASK:
4986          handle_set_stencil_compare_mask(cmd, state);
4987          break;
4988       case VK_CMD_SET_STENCIL_WRITE_MASK:
4989          handle_set_stencil_write_mask(cmd, state);
4990          break;
4991       case VK_CMD_SET_STENCIL_REFERENCE:
4992          handle_set_stencil_reference(cmd, state);
4993          break;
4994       case VK_CMD_BIND_DESCRIPTOR_SETS2:
4995          handle_descriptor_sets_cmd(cmd, state);
4996          break;
4997       case VK_CMD_BIND_INDEX_BUFFER:
4998          handle_index_buffer(cmd, state);
4999          break;
5000       case VK_CMD_BIND_INDEX_BUFFER2:
5001          handle_index_buffer2(cmd, state);
5002          break;
5003       case VK_CMD_BIND_VERTEX_BUFFERS2:
5004          handle_vertex_buffers2(cmd, state);
5005          break;
5006       case VK_CMD_DRAW:
5007          emit_state(state);
5008          handle_draw(cmd, state);
5009          break;
5010       case VK_CMD_DRAW_MULTI_EXT:
5011          emit_state(state);
5012          handle_draw_multi(cmd, state);
5013          break;
5014       case VK_CMD_DRAW_INDEXED:
5015          emit_state(state);
5016          handle_draw_indexed(cmd, state);
5017          break;
5018       case VK_CMD_DRAW_INDIRECT:
5019          emit_state(state);
5020          handle_draw_indirect(cmd, state, false);
5021          break;
5022       case VK_CMD_DRAW_INDEXED_INDIRECT:
5023          emit_state(state);
5024          handle_draw_indirect(cmd, state, true);
5025          break;
5026       case VK_CMD_DRAW_MULTI_INDEXED_EXT:
5027          emit_state(state);
5028          handle_draw_multi_indexed(cmd, state);
5029          break;
5030       case VK_CMD_DISPATCH:
5031          emit_compute_state(state);
5032          handle_dispatch(cmd, state);
5033          break;
5034       case VK_CMD_DISPATCH_BASE:
5035          emit_compute_state(state);
5036          handle_dispatch_base(cmd, state);
5037          break;
5038       case VK_CMD_DISPATCH_INDIRECT:
5039          emit_compute_state(state);
5040          handle_dispatch_indirect(cmd, state);
5041          break;
5042       case VK_CMD_COPY_BUFFER2:
5043          handle_copy_buffer(cmd, state);
5044          break;
5045       case VK_CMD_COPY_IMAGE2:
5046          handle_copy_image(cmd, state);
5047          break;
5048       case VK_CMD_BLIT_IMAGE2:
5049          handle_blit_image(cmd, state);
5050          break;
5051       case VK_CMD_COPY_BUFFER_TO_IMAGE2:
5052          handle_copy_buffer_to_image(cmd, state);
5053          break;
5054       case VK_CMD_COPY_IMAGE_TO_BUFFER2:
5055          handle_copy_image_to_buffer2(cmd, state);
5056          break;
5057       case VK_CMD_UPDATE_BUFFER:
5058          handle_update_buffer(cmd, state);
5059          break;
5060       case VK_CMD_FILL_BUFFER:
5061          handle_fill_buffer(cmd, state);
5062          break;
5063       case VK_CMD_CLEAR_COLOR_IMAGE:
5064          handle_clear_color_image(cmd, state);
5065          break;
5066       case VK_CMD_CLEAR_DEPTH_STENCIL_IMAGE:
5067          handle_clear_ds_image(cmd, state);
5068          break;
5069       case VK_CMD_CLEAR_ATTACHMENTS:
5070          handle_clear_attachments(cmd, state);
5071          break;
5072       case VK_CMD_RESOLVE_IMAGE2:
5073          handle_resolve_image(cmd, state);
5074          break;
5075       case VK_CMD_PIPELINE_BARRIER2:
5076          /* flushes are actually stalls, so multiple flushes are redundant */
5077          if (did_flush)
5078             continue;
5079          handle_pipeline_barrier(cmd, state);
5080          did_flush = true;
5081          continue;
5082       case VK_CMD_BEGIN_QUERY_INDEXED_EXT:
5083          handle_begin_query_indexed_ext(cmd, state);
5084          break;
5085       case VK_CMD_END_QUERY_INDEXED_EXT:
5086          handle_end_query_indexed_ext(cmd, state);
5087          break;
5088       case VK_CMD_BEGIN_QUERY:
5089          handle_begin_query(cmd, state);
5090          break;
5091       case VK_CMD_END_QUERY:
5092          handle_end_query(cmd, state);
5093          break;
5094       case VK_CMD_RESET_QUERY_POOL:
5095          handle_reset_query_pool(cmd, state);
5096          break;
5097       case VK_CMD_COPY_QUERY_POOL_RESULTS:
5098          handle_copy_query_pool_results(cmd, state);
5099          break;
5100       case VK_CMD_PUSH_CONSTANTS2:
5101          handle_push_constants(cmd, state);
5102          break;
5103       case VK_CMD_EXECUTE_COMMANDS:
5104          handle_execute_commands(cmd, state, print_cmds);
5105          break;
5106       case VK_CMD_DRAW_INDIRECT_COUNT:
5107          emit_state(state);
5108          handle_draw_indirect_count(cmd, state, false);
5109          break;
5110       case VK_CMD_DRAW_INDEXED_INDIRECT_COUNT:
5111          emit_state(state);
5112          handle_draw_indirect_count(cmd, state, true);
5113          break;
5114       case VK_CMD_PUSH_DESCRIPTOR_SET2:
5115          handle_push_descriptor_set(cmd, state);
5116          break;
5117       case VK_CMD_PUSH_DESCRIPTOR_SET_WITH_TEMPLATE2:
5118          handle_push_descriptor_set_with_template(cmd, state);
5119          break;
5120       case VK_CMD_BIND_TRANSFORM_FEEDBACK_BUFFERS_EXT:
5121          handle_bind_transform_feedback_buffers(cmd, state);
5122          break;
5123       case VK_CMD_BEGIN_TRANSFORM_FEEDBACK_EXT:
5124          handle_begin_transform_feedback(cmd, state);
5125          break;
5126       case VK_CMD_END_TRANSFORM_FEEDBACK_EXT:
5127          handle_end_transform_feedback(cmd, state);
5128          break;
5129       case VK_CMD_DRAW_INDIRECT_BYTE_COUNT_EXT:
5130          emit_state(state);
5131          handle_draw_indirect_byte_count(cmd, state);
5132          break;
5133       case VK_CMD_BEGIN_CONDITIONAL_RENDERING_EXT:
5134          handle_begin_conditional_rendering(cmd, state);
5135          break;
5136       case VK_CMD_END_CONDITIONAL_RENDERING_EXT:
5137          handle_end_conditional_rendering(state);
5138          break;
5139       case VK_CMD_SET_VERTEX_INPUT_EXT:
5140          handle_set_vertex_input(cmd, state);
5141          break;
5142       case VK_CMD_SET_CULL_MODE:
5143          handle_set_cull_mode(cmd, state);
5144          break;
5145       case VK_CMD_SET_FRONT_FACE:
5146          handle_set_front_face(cmd, state);
5147          break;
5148       case VK_CMD_SET_PRIMITIVE_TOPOLOGY:
5149          handle_set_primitive_topology(cmd, state);
5150          break;
5151       case VK_CMD_SET_DEPTH_TEST_ENABLE:
5152          handle_set_depth_test_enable(cmd, state);
5153          break;
5154       case VK_CMD_SET_DEPTH_WRITE_ENABLE:
5155          handle_set_depth_write_enable(cmd, state);
5156          break;
5157       case VK_CMD_SET_DEPTH_COMPARE_OP:
5158          handle_set_depth_compare_op(cmd, state);
5159          break;
5160       case VK_CMD_SET_DEPTH_BOUNDS_TEST_ENABLE:
5161          handle_set_depth_bounds_test_enable(cmd, state);
5162          break;
5163       case VK_CMD_SET_STENCIL_TEST_ENABLE:
5164          handle_set_stencil_test_enable(cmd, state);
5165          break;
5166       case VK_CMD_SET_STENCIL_OP:
5167          handle_set_stencil_op(cmd, state);
5168          break;
5169       case VK_CMD_SET_LINE_STIPPLE:
5170          handle_set_line_stipple(cmd, state);
5171          break;
5172       case VK_CMD_SET_DEPTH_BIAS_ENABLE:
5173          handle_set_depth_bias_enable(cmd, state);
5174          break;
5175       case VK_CMD_SET_LOGIC_OP_EXT:
5176          handle_set_logic_op(cmd, state);
5177          break;
5178       case VK_CMD_SET_PATCH_CONTROL_POINTS_EXT:
5179          handle_set_patch_control_points(cmd, state);
5180          break;
5181       case VK_CMD_SET_PRIMITIVE_RESTART_ENABLE:
5182          handle_set_primitive_restart_enable(cmd, state);
5183          break;
5184       case VK_CMD_SET_RASTERIZER_DISCARD_ENABLE:
5185          handle_set_rasterizer_discard_enable(cmd, state);
5186          break;
5187       case VK_CMD_SET_COLOR_WRITE_ENABLE_EXT:
5188          handle_set_color_write_enable(cmd, state);
5189          break;
5190       case VK_CMD_BEGIN_RENDERING:
5191          handle_begin_rendering(cmd, state);
5192          break;
5193       case VK_CMD_END_RENDERING:
5194          handle_end_rendering(cmd, state);
5195          break;
5196       case VK_CMD_SET_DEVICE_MASK:
5197          /* no-op */
5198          break;
5199       case VK_CMD_RESET_EVENT2:
5200          handle_event_reset2(cmd, state);
5201          break;
5202       case VK_CMD_SET_EVENT2:
5203          handle_event_set2(cmd, state);
5204          break;
5205       case VK_CMD_WAIT_EVENTS2:
5206          handle_wait_events2(cmd, state);
5207          break;
5208       case VK_CMD_WRITE_TIMESTAMP2:
5209          handle_write_timestamp2(cmd, state);
5210          break;
5211       case VK_CMD_SET_POLYGON_MODE_EXT:
5212          handle_set_polygon_mode(cmd, state);
5213          break;
5214       case VK_CMD_SET_TESSELLATION_DOMAIN_ORIGIN_EXT:
5215          handle_set_tessellation_domain_origin(cmd, state);
5216          break;
5217       case VK_CMD_SET_DEPTH_CLAMP_ENABLE_EXT:
5218          handle_set_depth_clamp_enable(cmd, state);
5219          break;
5220       case VK_CMD_SET_DEPTH_CLIP_ENABLE_EXT:
5221          handle_set_depth_clip_enable(cmd, state);
5222          break;
5223       case VK_CMD_SET_LOGIC_OP_ENABLE_EXT:
5224          handle_set_logic_op_enable(cmd, state);
5225          break;
5226       case VK_CMD_SET_SAMPLE_MASK_EXT:
5227          handle_set_sample_mask(cmd, state);
5228          break;
5229       case VK_CMD_SET_RASTERIZATION_SAMPLES_EXT:
5230          handle_set_samples(cmd, state);
5231          break;
5232       case VK_CMD_SET_ALPHA_TO_COVERAGE_ENABLE_EXT:
5233          handle_set_alpha_to_coverage(cmd, state);
5234          break;
5235       case VK_CMD_SET_ALPHA_TO_ONE_ENABLE_EXT:
5236          handle_set_alpha_to_one(cmd, state);
5237          break;
5238       case VK_CMD_SET_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT:
5239          handle_set_halfz(cmd, state);
5240          break;
5241       case VK_CMD_SET_LINE_RASTERIZATION_MODE_EXT:
5242          handle_set_line_rasterization_mode(cmd, state);
5243          break;
5244       case VK_CMD_SET_LINE_STIPPLE_ENABLE_EXT:
5245          handle_set_line_stipple_enable(cmd, state);
5246          break;
5247       case VK_CMD_SET_PROVOKING_VERTEX_MODE_EXT:
5248          handle_set_provoking_vertex_mode(cmd, state);
5249          break;
5250       case VK_CMD_SET_COLOR_BLEND_ENABLE_EXT:
5251          handle_set_color_blend_enable(cmd, state);
5252          break;
5253       case VK_CMD_SET_COLOR_WRITE_MASK_EXT:
5254          handle_set_color_write_mask(cmd, state);
5255          break;
5256       case VK_CMD_SET_COLOR_BLEND_EQUATION_EXT:
5257          handle_set_color_blend_equation(cmd, state);
5258          break;
5259       case VK_CMD_BIND_SHADERS_EXT:
5260          handle_shaders(cmd, state);
5261          break;
5262       case VK_CMD_SET_ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT:
5263          break;
5264       case VK_CMD_DRAW_MESH_TASKS_EXT:
5265          emit_state(state);
5266          handle_draw_mesh_tasks(cmd, state);
5267          break;
5268       case VK_CMD_DRAW_MESH_TASKS_INDIRECT_EXT:
5269          emit_state(state);
5270          handle_draw_mesh_tasks_indirect(cmd, state);
5271          break;
5272       case VK_CMD_DRAW_MESH_TASKS_INDIRECT_COUNT_EXT:
5273          emit_state(state);
5274          handle_draw_mesh_tasks_indirect_count(cmd, state);
5275          break;
5276       case VK_CMD_PREPROCESS_GENERATED_COMMANDS_EXT:
5277          handle_preprocess_generated_commands_ext(cmd, state, print_cmds);
5278          break;
5279       case VK_CMD_EXECUTE_GENERATED_COMMANDS_EXT:
5280          handle_execute_generated_commands_ext(cmd, state, print_cmds);
5281          break;
5282       case VK_CMD_BIND_DESCRIPTOR_BUFFERS_EXT:
5283          handle_descriptor_buffers(cmd, state);
5284          break;
5285       case VK_CMD_SET_DESCRIPTOR_BUFFER_OFFSETS2_EXT:
5286          handle_descriptor_buffer_offsets(cmd, state);
5287          break;
5288       case VK_CMD_BIND_DESCRIPTOR_BUFFER_EMBEDDED_SAMPLERS2_EXT:
5289          handle_descriptor_buffer_embedded_samplers(cmd, state);
5290          break;
5291 #ifdef VK_ENABLE_BETA_EXTENSIONS
5292       case VK_CMD_INITIALIZE_GRAPH_SCRATCH_MEMORY_AMDX:
5293          break;
5294       case VK_CMD_DISPATCH_GRAPH_INDIRECT_COUNT_AMDX:
5295          break;
5296       case VK_CMD_DISPATCH_GRAPH_INDIRECT_AMDX:
5297          break;
5298       case VK_CMD_DISPATCH_GRAPH_AMDX:
5299          handle_dispatch_graph(cmd, state);
5300          break;
5301 #endif
5302       case VK_CMD_SET_RENDERING_ATTACHMENT_LOCATIONS:
5303          handle_rendering_attachment_locations(cmd, state);
5304          break;
5305       case VK_CMD_SET_RENDERING_INPUT_ATTACHMENT_INDICES:
5306          handle_rendering_input_attachment_indices(cmd, state);
5307          break;
5308       case VK_CMD_COPY_ACCELERATION_STRUCTURE_KHR:
5309          handle_copy_acceleration_structure(cmd, state);
5310          break;
5311       case VK_CMD_COPY_MEMORY_TO_ACCELERATION_STRUCTURE_KHR:
5312          handle_copy_memory_to_acceleration_structure(cmd, state);
5313          break;
5314       case VK_CMD_COPY_ACCELERATION_STRUCTURE_TO_MEMORY_KHR:
5315          handle_copy_acceleration_structure_to_memory(cmd, state);
5316          break;
5317       case VK_CMD_BUILD_ACCELERATION_STRUCTURES_KHR:
5318          handle_build_acceleration_structures(cmd, state);
5319          break;
5320       case VK_CMD_BUILD_ACCELERATION_STRUCTURES_INDIRECT_KHR:
5321          break;
5322       case VK_CMD_WRITE_ACCELERATION_STRUCTURES_PROPERTIES_KHR:
5323          handle_write_acceleration_structures_properties(cmd, state);
5324          break;
5325       case VK_CMD_SET_RAY_TRACING_PIPELINE_STACK_SIZE_KHR:
5326          break;
5327       case VK_CMD_TRACE_RAYS_INDIRECT2_KHR:
5328          handle_trace_rays_indirect2(cmd, state);
5329          break;
5330       case VK_CMD_TRACE_RAYS_INDIRECT_KHR:
5331          handle_trace_rays_indirect(cmd, state);
5332          break;
5333       case VK_CMD_TRACE_RAYS_KHR:
5334          handle_trace_rays(cmd, state);
5335          break;
5336       default:
5337          fprintf(stderr, "Unsupported command %s\n", vk_cmd_queue_type_names[cmd->type]);
5338          unreachable("Unsupported command");
5339          break;
5340       }
5341       did_flush = false;
5342       if (!cmd->cmd_link.next)
5343          break;
5344    }
5345 }
5346 
lvp_execute_cmds(struct lvp_device * device,struct lvp_queue * queue,struct lvp_cmd_buffer * cmd_buffer)5347 VkResult lvp_execute_cmds(struct lvp_device *device,
5348                           struct lvp_queue *queue,
5349                           struct lvp_cmd_buffer *cmd_buffer)
5350 {
5351    struct rendering_state *state = queue->state;
5352    memset(state, 0, sizeof(*state));
5353    state->pctx = queue->ctx;
5354    state->device = device;
5355    state->uploader = queue->uploader;
5356    state->cso = queue->cso;
5357    state->blend_dirty = true;
5358    state->dsa_dirty = true;
5359    state->rs_dirty = true;
5360    state->vp_dirty = true;
5361    state->rs_state.point_line_tri_clip = true;
5362    state->rs_state.unclamped_fragment_depth_values = device->vk.enabled_extensions.EXT_depth_range_unrestricted;
5363    state->sample_mask_dirty = true;
5364    state->min_samples_dirty = true;
5365    state->sample_mask = UINT32_MAX;
5366    state->poison_mem = device->poison_mem;
5367    util_dynarray_init(&state->push_desc_sets, NULL);
5368    util_dynarray_init(&state->internal_buffers, NULL);
5369 
5370    /* default values */
5371    state->min_sample_shading = 1;
5372    state->num_viewports = 1;
5373    state->num_scissors = 1;
5374    state->rs_state.line_width = 1.0;
5375    state->rs_state.flatshade_first = true;
5376    state->rs_state.clip_halfz = true;
5377    state->rs_state.front_ccw = true;
5378    state->rs_state.point_size_per_vertex = true;
5379    state->rs_state.point_quad_rasterization = true;
5380    state->rs_state.half_pixel_center = true;
5381    state->rs_state.scissor = true;
5382    state->rs_state.no_ms_sample_mask_out = true;
5383    state->blend_state.independent_blend_enable = true;
5384 
5385    state->index_size = 4;
5386    state->index_buffer_size = sizeof(uint32_t);
5387    state->index_buffer = state->device->zero_buffer;
5388 
5389    /* create a gallium context */
5390    lvp_execute_cmd_buffer(&cmd_buffer->vk.cmd_queue.cmds, state, device->print_cmds);
5391 
5392    state->start_vb = -1;
5393    state->num_vb = 0;
5394    cso_unbind_context(queue->cso);
5395    for (unsigned i = 0; i < ARRAY_SIZE(state->so_targets); i++) {
5396       if (state->so_targets[i]) {
5397          state->pctx->stream_output_target_destroy(state->pctx, state->so_targets[i]);
5398       }
5399    }
5400 
5401    finish_fence(state);
5402 
5403    util_dynarray_foreach (&state->push_desc_sets, struct lvp_descriptor_set *, set)
5404       lvp_descriptor_set_destroy(device, *set);
5405 
5406    util_dynarray_fini(&state->push_desc_sets);
5407 
5408    util_dynarray_foreach (&state->internal_buffers, struct pipe_resource *, buffer)
5409       pipe_resource_reference(buffer, NULL);
5410 
5411    util_dynarray_fini(&state->internal_buffers);
5412 
5413    for (unsigned i = 0; i < ARRAY_SIZE(state->desc_buffers); i++)
5414       pipe_resource_reference(&state->desc_buffers[i], NULL);
5415 
5416    return VK_SUCCESS;
5417 }
5418 
5419 size_t
lvp_get_rendering_state_size(void)5420 lvp_get_rendering_state_size(void)
5421 {
5422    return sizeof(struct rendering_state);
5423 }
5424