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