• 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_text.h"
34 #include "tgsi/tgsi_parse.h"
35 
36 #include "util/format/u_format.h"
37 #include "util/u_surface.h"
38 #include "util/u_sampler.h"
39 #include "util/u_box.h"
40 #include "util/u_inlines.h"
41 #include "util/u_prim.h"
42 #include "util/u_prim_restart.h"
43 #include "util/format/u_format_zs.h"
44 
45 #include "vk_util.h"
46 
47 #define VK_PROTOTYPES
48 #include <vulkan/vulkan.h>
49 
50 #define DOUBLE_EQ(a, b) (fabs((a) - (b)) < DBL_EPSILON)
51 
52 enum gs_output {
53   GS_OUTPUT_NONE,
54   GS_OUTPUT_NOT_LINES,
55   GS_OUTPUT_LINES,
56 };
57 
58 struct rendering_state {
59    struct pipe_context *pctx;
60    struct cso_context *cso;
61 
62    bool blend_dirty;
63    bool rs_dirty;
64    bool dsa_dirty;
65    bool stencil_ref_dirty;
66    bool clip_state_dirty;
67    bool blend_color_dirty;
68    bool ve_dirty;
69    bool vb_dirty;
70    bool constbuf_dirty[PIPE_SHADER_TYPES];
71    bool pcbuf_dirty[PIPE_SHADER_TYPES];
72    bool vp_dirty;
73    bool scissor_dirty;
74    bool ib_dirty;
75    bool sample_mask_dirty;
76    bool min_samples_dirty;
77    struct pipe_draw_indirect_info indirect_info;
78    struct pipe_draw_info info;
79 
80    struct pipe_grid_info dispatch_info;
81    struct pipe_framebuffer_state framebuffer;
82 
83    struct pipe_blend_state blend_state;
84    struct {
85       float offset_units;
86       float offset_scale;
87       float offset_clamp;
88       bool enabled;
89    } depth_bias;
90    struct pipe_rasterizer_state rs_state;
91    struct pipe_depth_stencil_alpha_state dsa_state;
92 
93    struct pipe_blend_color blend_color;
94    struct pipe_stencil_ref stencil_ref;
95    struct pipe_clip_state clip_state;
96 
97    int num_scissors;
98    struct pipe_scissor_state scissors[16];
99 
100    int num_viewports;
101    struct pipe_viewport_state viewports[16];
102 
103    uint8_t patch_vertices;
104    ubyte index_size;
105    unsigned index_offset;
106    struct pipe_resource *index_buffer;
107    struct pipe_constant_buffer pc_buffer[PIPE_SHADER_TYPES];
108    struct pipe_constant_buffer const_buffer[PIPE_SHADER_TYPES][16];
109    int num_const_bufs[PIPE_SHADER_TYPES];
110    int num_vb;
111    unsigned start_vb;
112    struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];
113    struct cso_velems_state velem;
114 
115    struct pipe_sampler_view *sv[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
116    int num_sampler_views[PIPE_SHADER_TYPES];
117    struct pipe_sampler_state ss[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
118    /* cso_context api is stupid */
119    const struct pipe_sampler_state *cso_ss_ptr[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
120    int num_sampler_states[PIPE_SHADER_TYPES];
121    bool sv_dirty[PIPE_SHADER_TYPES];
122    bool ss_dirty[PIPE_SHADER_TYPES];
123 
124    struct pipe_image_view iv[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];
125    int num_shader_images[PIPE_SHADER_TYPES];
126    struct pipe_shader_buffer sb[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_BUFFERS];
127    int num_shader_buffers[PIPE_SHADER_TYPES];
128    bool iv_dirty[PIPE_SHADER_TYPES];
129    bool sb_dirty[PIPE_SHADER_TYPES];
130    bool disable_multisample;
131    enum gs_output gs_output_lines : 2;
132 
133    uint32_t color_write_disables:8;
134    bool has_color_write_disables:1;
135    uint32_t pad:13;
136 
137    void *ss_cso[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
138    void *velems_cso;
139 
140    uint8_t push_constants[128 * 4];
141 
142    const struct lvp_render_pass *pass;
143    uint32_t subpass;
144    const struct lvp_framebuffer *vk_framebuffer;
145    VkRect2D render_area;
146 
147    uint32_t sample_mask;
148    unsigned min_samples;
149 
150    struct lvp_image_view **imageless_views;
151    struct lvp_attachment_state *attachments;
152    VkImageAspectFlags *pending_clear_aspects;
153    uint32_t *cleared_views;
154    int num_pending_aspects;
155 
156    uint32_t num_so_targets;
157    struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_BUFFERS];
158    uint32_t so_offsets[PIPE_MAX_SO_BUFFERS];
159 };
160 
161 ALWAYS_INLINE static void
assert_subresource_layers(const struct pipe_resource * pres,const VkImageSubresourceLayers * layers,const VkOffset3D * offsets)162 assert_subresource_layers(const struct pipe_resource *pres, const VkImageSubresourceLayers *layers, const VkOffset3D *offsets)
163 {
164 #ifndef NDEBUG
165    if (pres->target == PIPE_TEXTURE_3D) {
166       assert(layers->baseArrayLayer == 0);
167       assert(layers->layerCount == 1);
168       assert(offsets[0].z <= pres->depth0);
169       assert(offsets[1].z <= pres->depth0);
170    } else {
171       assert(layers->baseArrayLayer < pres->array_size);
172       assert(layers->baseArrayLayer + layers->layerCount <= pres->array_size);
173       assert(offsets[0].z == 0);
174       assert(offsets[1].z == 1);
175    }
176 #endif
177 }
178 
emit_compute_state(struct rendering_state * state)179 static void emit_compute_state(struct rendering_state *state)
180 {
181    if (state->iv_dirty[PIPE_SHADER_COMPUTE]) {
182       state->pctx->set_shader_images(state->pctx, PIPE_SHADER_COMPUTE,
183                                      0, state->num_shader_images[PIPE_SHADER_COMPUTE],
184                                      0, state->iv[PIPE_SHADER_COMPUTE]);
185       state->iv_dirty[PIPE_SHADER_COMPUTE] = false;
186    }
187 
188    if (state->pcbuf_dirty[PIPE_SHADER_COMPUTE]) {
189       state->pctx->set_constant_buffer(state->pctx, PIPE_SHADER_COMPUTE,
190                                        0, false, &state->pc_buffer[PIPE_SHADER_COMPUTE]);
191       state->pcbuf_dirty[PIPE_SHADER_COMPUTE] = false;
192    }
193 
194    if (state->constbuf_dirty[PIPE_SHADER_COMPUTE]) {
195       for (unsigned i = 0; i < state->num_const_bufs[PIPE_SHADER_COMPUTE]; i++)
196          state->pctx->set_constant_buffer(state->pctx, PIPE_SHADER_COMPUTE,
197                                           i + 1, false, &state->const_buffer[PIPE_SHADER_COMPUTE][i]);
198       state->constbuf_dirty[PIPE_SHADER_COMPUTE] = false;
199    }
200 
201    if (state->sb_dirty[PIPE_SHADER_COMPUTE]) {
202       state->pctx->set_shader_buffers(state->pctx, PIPE_SHADER_COMPUTE,
203                                       0, state->num_shader_buffers[PIPE_SHADER_COMPUTE],
204                                       state->sb[PIPE_SHADER_COMPUTE], 0);
205       state->sb_dirty[PIPE_SHADER_COMPUTE] = false;
206    }
207 
208    if (state->sv_dirty[PIPE_SHADER_COMPUTE]) {
209       state->pctx->set_sampler_views(state->pctx, PIPE_SHADER_COMPUTE, 0, state->num_sampler_views[PIPE_SHADER_COMPUTE],
210                                      0, false, state->sv[PIPE_SHADER_COMPUTE]);
211       state->sv_dirty[PIPE_SHADER_COMPUTE] = false;
212    }
213 
214    if (state->ss_dirty[PIPE_SHADER_COMPUTE]) {
215       for (unsigned i = 0; i < state->num_sampler_states[PIPE_SHADER_COMPUTE]; i++) {
216          if (state->ss_cso[PIPE_SHADER_COMPUTE][i])
217             state->pctx->delete_sampler_state(state->pctx, state->ss_cso[PIPE_SHADER_COMPUTE][i]);
218          state->ss_cso[PIPE_SHADER_COMPUTE][i] = state->pctx->create_sampler_state(state->pctx, &state->ss[PIPE_SHADER_COMPUTE][i]);
219       }
220       state->pctx->bind_sampler_states(state->pctx, PIPE_SHADER_COMPUTE, 0, state->num_sampler_states[PIPE_SHADER_COMPUTE], state->ss_cso[PIPE_SHADER_COMPUTE]);
221       state->ss_dirty[PIPE_SHADER_COMPUTE] = false;
222    }
223 }
224 
emit_state(struct rendering_state * state)225 static void emit_state(struct rendering_state *state)
226 {
227    int sh;
228    if (state->blend_dirty) {
229       uint32_t mask = 0;
230       /* zero out the colormask values for disabled attachments */
231       if (state->has_color_write_disables && state->color_write_disables) {
232          u_foreach_bit(att, state->color_write_disables) {
233             mask |= state->blend_state.rt[att].colormask << (att * 4);
234             state->blend_state.rt[att].colormask = 0;
235          }
236       }
237       cso_set_blend(state->cso, &state->blend_state);
238       /* reset colormasks using saved bitmask */
239       if (state->has_color_write_disables && state->color_write_disables) {
240          const uint32_t att_mask = BITFIELD_MASK(4);
241          u_foreach_bit(att, state->color_write_disables) {
242             state->blend_state.rt[att].colormask = (mask >> (att * 4)) & att_mask;
243          }
244       }
245       state->blend_dirty = false;
246    }
247 
248    if (state->rs_dirty) {
249       bool ms = state->rs_state.multisample;
250       if (state->disable_multisample &&
251           (state->gs_output_lines == GS_OUTPUT_LINES ||
252            (state->gs_output_lines == GS_OUTPUT_NONE && u_reduced_prim(state->info.mode) == PIPE_PRIM_LINES)))
253          state->rs_state.multisample = false;
254       assert(offsetof(struct pipe_rasterizer_state, offset_clamp) - offsetof(struct pipe_rasterizer_state, offset_units) == sizeof(float) * 2);
255       if (state->depth_bias.enabled) {
256          memcpy(&state->rs_state.offset_units, &state->depth_bias, sizeof(float) * 3);
257       } else {
258          memset(&state->rs_state.offset_units, 0, sizeof(float) * 3);
259       }
260       cso_set_rasterizer(state->cso, &state->rs_state);
261       state->rs_dirty = false;
262       state->rs_state.multisample = ms;
263    }
264 
265    if (state->dsa_dirty) {
266       cso_set_depth_stencil_alpha(state->cso, &state->dsa_state);
267       state->dsa_dirty = false;
268    }
269 
270    if (state->sample_mask_dirty) {
271       cso_set_sample_mask(state->cso, state->sample_mask);
272       state->sample_mask_dirty = false;
273    }
274 
275    if (state->min_samples_dirty) {
276       cso_set_min_samples(state->cso, state->min_samples);
277       state->min_samples_dirty = false;
278    }
279 
280    if (state->blend_color_dirty) {
281       state->pctx->set_blend_color(state->pctx, &state->blend_color);
282       state->blend_color_dirty = false;
283    }
284 
285    if (state->stencil_ref_dirty) {
286       cso_set_stencil_ref(state->cso, state->stencil_ref);
287       state->stencil_ref_dirty = false;
288    }
289 
290    if (state->vb_dirty) {
291       cso_set_vertex_buffers(state->cso, state->start_vb, state->num_vb, state->vb);
292       state->vb_dirty = false;
293    }
294 
295    if (state->ve_dirty) {
296       cso_set_vertex_elements(state->cso, &state->velem);
297       state->ve_dirty = false;
298    }
299 
300 
301    for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
302       if (state->constbuf_dirty[sh]) {
303          for (unsigned idx = 0; idx < state->num_const_bufs[sh]; idx++)
304             state->pctx->set_constant_buffer(state->pctx, sh,
305                                              idx + 1, false, &state->const_buffer[sh][idx]);
306       }
307       state->constbuf_dirty[sh] = false;
308    }
309 
310    for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
311       if (state->pcbuf_dirty[sh]) {
312          state->pctx->set_constant_buffer(state->pctx, sh,
313                                           0, false, &state->pc_buffer[sh]);
314       }
315    }
316 
317    for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
318       if (state->sb_dirty[sh]) {
319          state->pctx->set_shader_buffers(state->pctx, sh,
320                                          0, state->num_shader_buffers[sh],
321                                          state->sb[sh], 0);
322       }
323    }
324 
325    for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
326       if (state->iv_dirty[sh]) {
327          state->pctx->set_shader_images(state->pctx, sh,
328                                         0, state->num_shader_images[sh], 0,
329                                         state->iv[sh]);
330       }
331    }
332 
333    for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
334 
335       if (!state->sv_dirty[sh])
336          continue;
337 
338       state->pctx->set_sampler_views(state->pctx, sh, 0, state->num_sampler_views[sh],
339                                      0, false, state->sv[sh]);
340       state->sv_dirty[sh] = false;
341    }
342 
343    for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
344       if (!state->ss_dirty[sh])
345          continue;
346 
347       cso_set_samplers(state->cso, sh, state->num_sampler_states[sh], state->cso_ss_ptr[sh]);
348    }
349 
350    if (state->vp_dirty) {
351       state->pctx->set_viewport_states(state->pctx, 0, state->num_viewports, state->viewports);
352       state->vp_dirty = false;
353    }
354 
355    if (state->scissor_dirty) {
356       state->pctx->set_scissor_states(state->pctx, 0, state->num_scissors, state->scissors);
357       state->scissor_dirty = false;
358    }
359 }
360 
handle_compute_pipeline(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)361 static void handle_compute_pipeline(struct vk_cmd_queue_entry *cmd,
362                                     struct rendering_state *state)
363 {
364    LVP_FROM_HANDLE(lvp_pipeline, pipeline, cmd->u.bind_pipeline.pipeline);
365 
366    state->dispatch_info.block[0] = pipeline->pipeline_nir[MESA_SHADER_COMPUTE]->info.workgroup_size[0];
367    state->dispatch_info.block[1] = pipeline->pipeline_nir[MESA_SHADER_COMPUTE]->info.workgroup_size[1];
368    state->dispatch_info.block[2] = pipeline->pipeline_nir[MESA_SHADER_COMPUTE]->info.workgroup_size[2];
369    state->pctx->bind_compute_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_COMPUTE]);
370 }
371 
372 static void
get_viewport_xform(const VkViewport * viewport,float scale[3],float translate[3])373 get_viewport_xform(const VkViewport *viewport,
374                    float scale[3], float translate[3])
375 {
376    float x = viewport->x;
377    float y = viewport->y;
378    float half_width = 0.5f * viewport->width;
379    float half_height = 0.5f * viewport->height;
380    double n = viewport->minDepth;
381    double f = viewport->maxDepth;
382 
383    scale[0] = half_width;
384    translate[0] = half_width + x;
385    scale[1] = half_height;
386    translate[1] = half_height + y;
387 
388    scale[2] = (f - n);
389    translate[2] = n;
390 }
391 
392 /* enum re-indexing:
393 
394     VK_DYNAMIC_STATE_VIEWPORT
395     VK_DYNAMIC_STATE_SCISSOR
396     VK_DYNAMIC_STATE_LINE_WIDTH
397     VK_DYNAMIC_STATE_DEPTH_BIAS
398     VK_DYNAMIC_STATE_BLEND_CONSTANTS
399     VK_DYNAMIC_STATE_DEPTH_BOUNDS
400     VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK
401     VK_DYNAMIC_STATE_STENCIL_WRITE_MASK
402     VK_DYNAMIC_STATE_STENCIL_REFERENCE
403 
404     VK_DYNAMIC_STATE_LINE_STIPPLE_EXT
405 
406     VK_DYNAMIC_STATE_CULL_MODE_EXT
407     VK_DYNAMIC_STATE_FRONT_FACE_EXT
408     VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT
409     VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT
410     VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT
411     VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT
412     VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT
413     VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT
414     VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT
415     VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT
416     VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT
417     VK_DYNAMIC_STATE_STENCIL_OP_EXT
418 
419     VK_DYNAMIC_STATE_VERTEX_INPUT_EXT
420 
421     VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT
422     VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT
423     VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT
424     VK_DYNAMIC_STATE_LOGIC_OP_EXT
425     VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT
426 
427     VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT
428 */
conv_dynamic_state_idx(VkDynamicState dyn_state)429 static int conv_dynamic_state_idx(VkDynamicState dyn_state)
430 {
431    if (dyn_state <= VK_DYNAMIC_STATE_STENCIL_REFERENCE)
432       return dyn_state;
433    if (dyn_state == VK_DYNAMIC_STATE_LINE_STIPPLE_EXT)
434       /* this one has a weird id, map after the normal dynamic state ones */
435       return VK_DYNAMIC_STATE_STENCIL_REFERENCE + 1;
436    if (dyn_state >= VK_DYNAMIC_STATE_CULL_MODE_EXT &&
437        dyn_state <= VK_DYNAMIC_STATE_STENCIL_OP_EXT)
438       return dyn_state - VK_DYNAMIC_STATE_CULL_MODE_EXT + VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2;
439    if (dyn_state == VK_DYNAMIC_STATE_VERTEX_INPUT_EXT)
440       return (VK_DYNAMIC_STATE_STENCIL_OP_EXT - VK_DYNAMIC_STATE_CULL_MODE_EXT) + VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2 + 1;
441    if (dyn_state >= VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT &&
442        dyn_state <= VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT)
443       return dyn_state - VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT +
444              VK_DYNAMIC_STATE_STENCIL_OP_EXT - VK_DYNAMIC_STATE_CULL_MODE_EXT +
445              VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2 + 1 + 1;
446    if (dyn_state == VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT)
447       return VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT - VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT +
448              VK_DYNAMIC_STATE_STENCIL_OP_EXT - VK_DYNAMIC_STATE_CULL_MODE_EXT +
449              VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2 + 1 + 1 + 1;
450    assert(0);
451    return -1;
452 }
453 
handle_graphics_pipeline(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)454 static void handle_graphics_pipeline(struct vk_cmd_queue_entry *cmd,
455                                      struct rendering_state *state)
456 {
457    LVP_FROM_HANDLE(lvp_pipeline, pipeline, cmd->u.bind_pipeline.pipeline);
458    bool dynamic_states[VK_DYNAMIC_STATE_STENCIL_REFERENCE+32];
459    unsigned fb_samples = 0;
460 
461    memset(dynamic_states, 0, sizeof(dynamic_states));
462    if (pipeline->graphics_create_info.pDynamicState)
463    {
464       const VkPipelineDynamicStateCreateInfo *dyn = pipeline->graphics_create_info.pDynamicState;
465       int i;
466       for (i = 0; i < dyn->dynamicStateCount; i++) {
467          int idx = conv_dynamic_state_idx(dyn->pDynamicStates[i]);
468          if (idx == -1)
469             continue;
470          dynamic_states[idx] = true;
471       }
472    }
473    state->has_color_write_disables = dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT)];
474 
475    bool has_stage[PIPE_SHADER_TYPES] = { false };
476 
477    state->pctx->bind_gs_state(state->pctx, NULL);
478    if (state->pctx->bind_tcs_state)
479       state->pctx->bind_tcs_state(state->pctx, NULL);
480    if (state->pctx->bind_tes_state)
481       state->pctx->bind_tes_state(state->pctx, NULL);
482    state->gs_output_lines = GS_OUTPUT_NONE;
483    {
484       int i;
485       for (i = 0; i < pipeline->graphics_create_info.stageCount; i++) {
486          const VkPipelineShaderStageCreateInfo *sh = &pipeline->graphics_create_info.pStages[i];
487          switch (sh->stage) {
488          case VK_SHADER_STAGE_FRAGMENT_BIT:
489             state->pctx->bind_fs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_FRAGMENT]);
490             has_stage[PIPE_SHADER_FRAGMENT] = true;
491             break;
492          case VK_SHADER_STAGE_VERTEX_BIT:
493             state->pctx->bind_vs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_VERTEX]);
494             has_stage[PIPE_SHADER_VERTEX] = true;
495             break;
496          case VK_SHADER_STAGE_GEOMETRY_BIT:
497             state->pctx->bind_gs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_GEOMETRY]);
498             state->gs_output_lines = pipeline->gs_output_lines ? GS_OUTPUT_LINES : GS_OUTPUT_NOT_LINES;
499             has_stage[PIPE_SHADER_GEOMETRY] = true;
500             break;
501          case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
502             state->pctx->bind_tcs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_TESS_CTRL]);
503             has_stage[PIPE_SHADER_TESS_CTRL] = true;
504             break;
505          case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
506             state->pctx->bind_tes_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_TESS_EVAL]);
507             has_stage[PIPE_SHADER_TESS_EVAL] = true;
508             break;
509          default:
510             assert(0);
511             break;
512          }
513       }
514    }
515 
516    /* there should always be a dummy fs. */
517    if (!has_stage[PIPE_SHADER_FRAGMENT])
518       state->pctx->bind_fs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_FRAGMENT]);
519    if (state->pctx->bind_gs_state && !has_stage[PIPE_SHADER_GEOMETRY])
520       state->pctx->bind_gs_state(state->pctx, NULL);
521    if (state->pctx->bind_tcs_state && !has_stage[PIPE_SHADER_TESS_CTRL])
522       state->pctx->bind_tcs_state(state->pctx, NULL);
523    if (state->pctx->bind_tes_state && !has_stage[PIPE_SHADER_TESS_EVAL])
524       state->pctx->bind_tes_state(state->pctx, NULL);
525 
526    /* rasterization state */
527    if (pipeline->graphics_create_info.pRasterizationState) {
528       const VkPipelineRasterizationStateCreateInfo *rsc = pipeline->graphics_create_info.pRasterizationState;
529       const VkPipelineRasterizationDepthClipStateCreateInfoEXT *depth_clip_state =
530          vk_find_struct_const(rsc->pNext, PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT);
531       state->rs_state.depth_clamp = rsc->depthClampEnable;
532       if (!depth_clip_state)
533          state->rs_state.depth_clip_near = state->rs_state.depth_clip_far = !rsc->depthClampEnable;
534       else
535          state->rs_state.depth_clip_near = state->rs_state.depth_clip_far = depth_clip_state->depthClipEnable;
536 
537       if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT)])
538          state->rs_state.rasterizer_discard = rsc->rasterizerDiscardEnable;
539 
540       state->rs_state.line_smooth = pipeline->line_smooth;
541       state->rs_state.line_stipple_enable = pipeline->line_stipple_enable;
542       state->rs_state.fill_front = vk_polygon_mode_to_pipe(rsc->polygonMode);
543       state->rs_state.fill_back = vk_polygon_mode_to_pipe(rsc->polygonMode);
544       state->rs_state.point_size_per_vertex = true;
545       state->rs_state.flatshade_first = !pipeline->provoking_vertex_last;
546       state->rs_state.point_quad_rasterization = true;
547       state->rs_state.clip_halfz = true;
548       state->rs_state.half_pixel_center = true;
549       state->rs_state.scissor = true;
550       state->rs_state.no_ms_sample_mask_out = true;
551       state->rs_state.line_rectangular = pipeline->line_rectangular;
552 
553       if (!dynamic_states[VK_DYNAMIC_STATE_LINE_WIDTH])
554          state->rs_state.line_width = rsc->lineWidth;
555       if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_LINE_STIPPLE_EXT)]) {
556          state->rs_state.line_stipple_factor = pipeline->line_stipple_factor;
557          state->rs_state.line_stipple_pattern = pipeline->line_stipple_pattern;
558       }
559 
560       if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT)])
561          state->depth_bias.enabled = pipeline->graphics_create_info.pRasterizationState->depthBiasEnable;
562       if (!dynamic_states[VK_DYNAMIC_STATE_DEPTH_BIAS]) {
563          state->depth_bias.offset_units = rsc->depthBiasConstantFactor;
564          state->depth_bias.offset_scale = rsc->depthBiasSlopeFactor;
565          state->depth_bias.offset_clamp = rsc->depthBiasClamp;
566       }
567 
568       if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_CULL_MODE_EXT)])
569          state->rs_state.cull_face = vk_cull_to_pipe(rsc->cullMode);
570 
571       if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_FRONT_FACE_EXT)])
572          state->rs_state.front_ccw = (rsc->frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE);
573       state->rs_dirty = true;
574    }
575 
576    state->disable_multisample = pipeline->disable_multisample;
577    if (pipeline->graphics_create_info.pMultisampleState) {
578       const VkPipelineMultisampleStateCreateInfo *ms = pipeline->graphics_create_info.pMultisampleState;
579       state->rs_state.multisample = ms->rasterizationSamples > 1;
580       state->sample_mask = ms->pSampleMask ? ms->pSampleMask[0] : 0xffffffff;
581       state->blend_state.alpha_to_coverage = ms->alphaToCoverageEnable;
582       state->blend_state.alpha_to_one = ms->alphaToOneEnable;
583       state->blend_dirty = true;
584       state->rs_dirty = true;
585       state->min_samples = 1;
586       state->sample_mask_dirty = true;
587       fb_samples = ms->rasterizationSamples;
588       if (ms->sampleShadingEnable) {
589          state->min_samples = ceil(ms->rasterizationSamples * ms->minSampleShading);
590          if (state->min_samples > 1)
591             state->min_samples = ms->rasterizationSamples;
592          if (state->min_samples < 1)
593             state->min_samples = 1;
594       }
595       if (pipeline->force_min_sample)
596          state->min_samples = ms->rasterizationSamples;
597       state->min_samples_dirty = true;
598    } else {
599       state->rs_state.multisample = false;
600       state->sample_mask_dirty = state->sample_mask != 0xffffffff;
601       state->sample_mask = 0xffffffff;
602       state->min_samples_dirty = state->min_samples;
603       state->min_samples = 0;
604       state->blend_dirty |= state->blend_state.alpha_to_coverage || state->blend_state.alpha_to_one;
605       state->blend_state.alpha_to_coverage = false;
606       state->blend_state.alpha_to_one = false;
607       state->rs_dirty = true;
608    }
609 
610    if (pipeline->graphics_create_info.pDepthStencilState) {
611       const VkPipelineDepthStencilStateCreateInfo *dsa = pipeline->graphics_create_info.pDepthStencilState;
612 
613       if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT)])
614          state->dsa_state.depth_enabled = dsa->depthTestEnable;
615       if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT)])
616          state->dsa_state.depth_writemask = dsa->depthWriteEnable;
617       if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT)])
618          state->dsa_state.depth_func = dsa->depthCompareOp;
619       if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT)])
620          state->dsa_state.depth_bounds_test = dsa->depthBoundsTestEnable;
621 
622       if (!dynamic_states[VK_DYNAMIC_STATE_DEPTH_BOUNDS]) {
623          state->dsa_state.depth_bounds_min = dsa->minDepthBounds;
624          state->dsa_state.depth_bounds_max = dsa->maxDepthBounds;
625       }
626 
627       if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT)]) {
628          state->dsa_state.stencil[0].enabled = dsa->stencilTestEnable;
629          state->dsa_state.stencil[1].enabled = dsa->stencilTestEnable;
630       }
631 
632       if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_STENCIL_OP_EXT)]) {
633          state->dsa_state.stencil[0].func = dsa->front.compareOp;
634          state->dsa_state.stencil[0].fail_op = vk_conv_stencil_op(dsa->front.failOp);
635          state->dsa_state.stencil[0].zpass_op = vk_conv_stencil_op(dsa->front.passOp);
636          state->dsa_state.stencil[0].zfail_op = vk_conv_stencil_op(dsa->front.depthFailOp);
637 
638          state->dsa_state.stencil[1].func = dsa->back.compareOp;
639          state->dsa_state.stencil[1].fail_op = vk_conv_stencil_op(dsa->back.failOp);
640          state->dsa_state.stencil[1].zpass_op = vk_conv_stencil_op(dsa->back.passOp);
641          state->dsa_state.stencil[1].zfail_op = vk_conv_stencil_op(dsa->back.depthFailOp);
642       }
643 
644       if (!dynamic_states[VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK]) {
645          state->dsa_state.stencil[0].valuemask = dsa->front.compareMask;
646          state->dsa_state.stencil[1].valuemask = dsa->back.compareMask;
647       }
648 
649       if (!dynamic_states[VK_DYNAMIC_STATE_STENCIL_WRITE_MASK]) {
650          state->dsa_state.stencil[0].writemask = dsa->front.writeMask;
651          state->dsa_state.stencil[1].writemask = dsa->back.writeMask;
652       }
653 
654       if (dsa->stencilTestEnable) {
655          if (!dynamic_states[VK_DYNAMIC_STATE_STENCIL_REFERENCE]) {
656             state->stencil_ref.ref_value[0] = dsa->front.reference;
657             state->stencil_ref.ref_value[1] = dsa->back.reference;
658             state->stencil_ref_dirty = true;
659          }
660       }
661    } else
662       memset(&state->dsa_state, 0, sizeof(state->dsa_state));
663    state->dsa_dirty = true;
664 
665    if (pipeline->graphics_create_info.pColorBlendState) {
666       const VkPipelineColorBlendStateCreateInfo *cb = pipeline->graphics_create_info.pColorBlendState;
667       int i;
668 
669       if (cb->logicOpEnable) {
670          state->blend_state.logicop_enable = VK_TRUE;
671          if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_LOGIC_OP_EXT)])
672             state->blend_state.logicop_func = vk_conv_logic_op(cb->logicOp);
673       }
674 
675       if (cb->attachmentCount > 1)
676          state->blend_state.independent_blend_enable = true;
677       for (i = 0; i < cb->attachmentCount; i++) {
678          state->blend_state.rt[i].colormask = cb->pAttachments[i].colorWriteMask;
679          state->blend_state.rt[i].blend_enable = cb->pAttachments[i].blendEnable;
680          state->blend_state.rt[i].rgb_func = vk_conv_blend_func(cb->pAttachments[i].colorBlendOp);
681          state->blend_state.rt[i].rgb_src_factor = vk_conv_blend_factor(cb->pAttachments[i].srcColorBlendFactor);
682          state->blend_state.rt[i].rgb_dst_factor = vk_conv_blend_factor(cb->pAttachments[i].dstColorBlendFactor);
683          state->blend_state.rt[i].alpha_func = vk_conv_blend_func(cb->pAttachments[i].alphaBlendOp);
684          state->blend_state.rt[i].alpha_src_factor = vk_conv_blend_factor(cb->pAttachments[i].srcAlphaBlendFactor);
685          state->blend_state.rt[i].alpha_dst_factor = vk_conv_blend_factor(cb->pAttachments[i].dstAlphaBlendFactor);
686 
687          /* At least llvmpipe applies the blend factor prior to the blend function,
688           * regardless of what function is used. (like i965 hardware).
689           * It means for MIN/MAX the blend factor has to be stomped to ONE.
690           */
691          if (cb->pAttachments[i].colorBlendOp == VK_BLEND_OP_MIN ||
692              cb->pAttachments[i].colorBlendOp == VK_BLEND_OP_MAX) {
693             state->blend_state.rt[i].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
694             state->blend_state.rt[i].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
695          }
696 
697          if (cb->pAttachments[i].alphaBlendOp == VK_BLEND_OP_MIN ||
698              cb->pAttachments[i].alphaBlendOp == VK_BLEND_OP_MAX) {
699             state->blend_state.rt[i].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
700             state->blend_state.rt[i].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
701          }
702       }
703       state->blend_dirty = true;
704       if (!dynamic_states[VK_DYNAMIC_STATE_BLEND_CONSTANTS]) {
705          memcpy(state->blend_color.color, cb->blendConstants, 4 * sizeof(float));
706          state->blend_color_dirty = true;
707       }
708    } else {
709       memset(&state->blend_state, 0, sizeof(state->blend_state));
710       state->blend_dirty = true;
711    }
712 
713    if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_VERTEX_INPUT_EXT)]) {
714       const VkPipelineVertexInputStateCreateInfo *vi = pipeline->graphics_create_info.pVertexInputState;
715       int i;
716       const VkPipelineVertexInputDivisorStateCreateInfoEXT *div_state =
717          vk_find_struct_const(vi->pNext,
718                               PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT);
719 
720       if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT)]) {
721          for (i = 0; i < vi->vertexBindingDescriptionCount; i++) {
722             state->vb[vi->pVertexBindingDescriptions[i].binding].stride = vi->pVertexBindingDescriptions[i].stride;
723          }
724       }
725 
726       int max_location = -1;
727       for (i = 0; i < vi->vertexAttributeDescriptionCount; i++) {
728          unsigned location = vi->pVertexAttributeDescriptions[i].location;
729          unsigned binding = vi->pVertexAttributeDescriptions[i].binding;
730          const struct VkVertexInputBindingDescription *desc_binding = NULL;
731          for (unsigned j = 0; j < vi->vertexBindingDescriptionCount; j++) {
732             const struct VkVertexInputBindingDescription *b = &vi->pVertexBindingDescriptions[j];
733             if (b->binding == binding) {
734                desc_binding = b;
735                break;
736             }
737          }
738          assert(desc_binding);
739          state->velem.velems[location].src_offset = vi->pVertexAttributeDescriptions[i].offset;
740          state->velem.velems[location].vertex_buffer_index = binding;
741          state->velem.velems[location].src_format = lvp_vk_format_to_pipe_format(vi->pVertexAttributeDescriptions[i].format);
742          state->velem.velems[location].dual_slot = false;
743 
744          switch (desc_binding->inputRate) {
745          case VK_VERTEX_INPUT_RATE_VERTEX:
746             state->velem.velems[location].instance_divisor = 0;
747             break;
748          case VK_VERTEX_INPUT_RATE_INSTANCE:
749             if (div_state) {
750                for (unsigned j = 0; j < div_state->vertexBindingDivisorCount; j++) {
751                   const VkVertexInputBindingDivisorDescriptionEXT *desc =
752                      &div_state->pVertexBindingDivisors[j];
753                   if (desc->binding == state->velem.velems[location].vertex_buffer_index) {
754                      state->velem.velems[location].instance_divisor = desc->divisor;
755                      break;
756                   }
757                }
758             } else
759                state->velem.velems[location].instance_divisor = 1;
760             break;
761          default:
762             assert(0);
763             break;
764          }
765 
766          if ((int)location > max_location)
767             max_location = location;
768       }
769       state->velem.count = max_location + 1;
770       state->vb_dirty = true;
771       state->ve_dirty = true;
772    }
773 
774    {
775       const VkPipelineInputAssemblyStateCreateInfo *ia = pipeline->graphics_create_info.pInputAssemblyState;
776 
777       if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT)]) {
778          state->info.mode = vk_conv_topology(ia->topology);
779          state->rs_dirty = true;
780       }
781       if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT)])
782          state->info.primitive_restart = ia->primitiveRestartEnable;
783    }
784 
785    if (pipeline->graphics_create_info.pTessellationState) {
786       if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT)]) {
787          const VkPipelineTessellationStateCreateInfo *ts = pipeline->graphics_create_info.pTessellationState;
788          state->patch_vertices = ts->patchControlPoints;
789       }
790    } else
791       state->patch_vertices = 0;
792 
793    if (pipeline->graphics_create_info.pViewportState) {
794       const VkPipelineViewportStateCreateInfo *vpi= pipeline->graphics_create_info.pViewportState;
795       int i;
796 
797       if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT)]) {
798          state->num_viewports = vpi->viewportCount;
799          state->vp_dirty = true;
800       }
801       if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT)]) {
802          state->num_scissors = vpi->scissorCount;
803          state->scissor_dirty = true;
804       }
805 
806       if (!dynamic_states[VK_DYNAMIC_STATE_VIEWPORT] &&
807           !dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT)]) {
808          for (i = 0; i < vpi->viewportCount; i++)
809             get_viewport_xform(&vpi->pViewports[i], state->viewports[i].scale, state->viewports[i].translate);
810          state->vp_dirty = true;
811       }
812       if (!dynamic_states[VK_DYNAMIC_STATE_SCISSOR] &&
813           !dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT)]) {
814          for (i = 0; i < vpi->scissorCount; i++) {
815             const VkRect2D *ss = &vpi->pScissors[i];
816             state->scissors[i].minx = ss->offset.x;
817             state->scissors[i].miny = ss->offset.y;
818             state->scissors[i].maxx = ss->offset.x + ss->extent.width;
819             state->scissors[i].maxy = ss->offset.y + ss->extent.height;
820             state->scissor_dirty = true;
821          }
822 
823       }
824    }
825 
826    if (fb_samples != state->framebuffer.samples) {
827       state->framebuffer.samples = fb_samples;
828       state->pctx->set_framebuffer_state(state->pctx, &state->framebuffer);
829    }
830 }
831 
handle_pipeline(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)832 static void handle_pipeline(struct vk_cmd_queue_entry *cmd,
833                             struct rendering_state *state)
834 {
835    LVP_FROM_HANDLE(lvp_pipeline, pipeline, cmd->u.bind_pipeline.pipeline);
836    if (pipeline->is_compute_pipeline)
837       handle_compute_pipeline(cmd, state);
838    else
839       handle_graphics_pipeline(cmd, state);
840 }
841 
vertex_buffers(uint32_t first_binding,uint32_t binding_count,const VkBuffer * buffers,const VkDeviceSize * offsets,const VkDeviceSize * strides,struct rendering_state * state)842 static void vertex_buffers(uint32_t first_binding,
843                            uint32_t binding_count,
844                            const VkBuffer *buffers,
845                            const VkDeviceSize *offsets,
846                            const VkDeviceSize *strides,
847                            struct rendering_state *state)
848 {
849    int i;
850    for (i = 0; i < binding_count; i++) {
851       int idx = i + first_binding;
852 
853       state->vb[idx].buffer_offset = offsets[i];
854       state->vb[idx].buffer.resource = buffers[i] ? lvp_buffer_from_handle(buffers[i])->bo : NULL;
855 
856       if (strides)
857          state->vb[idx].stride = strides[i];
858    }
859    if (first_binding < state->start_vb)
860       state->start_vb = first_binding;
861    if (first_binding + binding_count >= state->num_vb)
862       state->num_vb = first_binding + binding_count;
863    state->vb_dirty = true;
864 }
865 
handle_vertex_buffers(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)866 static void handle_vertex_buffers(struct vk_cmd_queue_entry *cmd,
867                                   struct rendering_state *state)
868 {
869    struct vk_cmd_bind_vertex_buffers *vcb = &cmd->u.bind_vertex_buffers;
870 
871    vertex_buffers(vcb->first_binding,
872                   vcb->binding_count,
873                   vcb->buffers,
874                   vcb->offsets,
875                   NULL,
876                   state);
877 }
878 
handle_vertex_buffers2(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)879 static void handle_vertex_buffers2(struct vk_cmd_queue_entry *cmd,
880                                    struct rendering_state *state)
881 {
882    struct vk_cmd_bind_vertex_buffers2_ext *vcb = &cmd->u.bind_vertex_buffers2_ext;
883 
884    vertex_buffers(vcb->first_binding,
885                   vcb->binding_count,
886                   vcb->buffers,
887                   vcb->offsets,
888                   vcb->strides,
889                   state);
890 }
891 
892 struct dyn_info {
893    struct {
894       uint16_t const_buffer_count;
895       uint16_t shader_buffer_count;
896       uint16_t sampler_count;
897       uint16_t sampler_view_count;
898       uint16_t image_count;
899    } stage[MESA_SHADER_STAGES];
900 
901    uint32_t dyn_index;
902    const uint32_t *dynamic_offsets;
903    uint32_t dynamic_offset_count;
904 };
905 
fill_sampler(struct pipe_sampler_state * ss,struct lvp_sampler * samp)906 static void fill_sampler(struct pipe_sampler_state *ss,
907                          struct lvp_sampler *samp)
908 {
909    ss->wrap_s = vk_conv_wrap_mode(samp->create_info.addressModeU);
910    ss->wrap_t = vk_conv_wrap_mode(samp->create_info.addressModeV);
911    ss->wrap_r = vk_conv_wrap_mode(samp->create_info.addressModeW);
912    ss->min_img_filter = samp->create_info.minFilter == VK_FILTER_LINEAR ? PIPE_TEX_FILTER_LINEAR : PIPE_TEX_FILTER_NEAREST;
913    ss->min_mip_filter = samp->create_info.mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR ? PIPE_TEX_MIPFILTER_LINEAR : PIPE_TEX_MIPFILTER_NEAREST;
914    ss->mag_img_filter = samp->create_info.magFilter == VK_FILTER_LINEAR ? PIPE_TEX_FILTER_LINEAR : PIPE_TEX_FILTER_NEAREST;
915    ss->min_lod = samp->create_info.minLod;
916    ss->max_lod = samp->create_info.maxLod;
917    ss->lod_bias = samp->create_info.mipLodBias;
918    if (samp->create_info.anisotropyEnable)
919       ss->max_anisotropy = samp->create_info.maxAnisotropy;
920    else
921       ss->max_anisotropy = 1;
922    ss->normalized_coords = !samp->create_info.unnormalizedCoordinates;
923    ss->compare_mode = samp->create_info.compareEnable ? PIPE_TEX_COMPARE_R_TO_TEXTURE : PIPE_TEX_COMPARE_NONE;
924    ss->compare_func = samp->create_info.compareOp;
925    ss->seamless_cube_map = true;
926    ss->reduction_mode = samp->reduction_mode;
927    memcpy(&ss->border_color, &samp->border_color,
928           sizeof(union pipe_color_union));
929 }
930 
fill_sampler_stage(struct rendering_state * state,struct dyn_info * dyn_info,gl_shader_stage stage,enum pipe_shader_type p_stage,int array_idx,const union lvp_descriptor_info * descriptor,const struct lvp_descriptor_set_binding_layout * binding)931 static void fill_sampler_stage(struct rendering_state *state,
932                                struct dyn_info *dyn_info,
933                                gl_shader_stage stage,
934                                enum pipe_shader_type p_stage,
935                                int array_idx,
936                                const union lvp_descriptor_info *descriptor,
937                                const struct lvp_descriptor_set_binding_layout *binding)
938 {
939    int ss_idx = binding->stage[stage].sampler_index;
940    if (ss_idx == -1)
941       return;
942    ss_idx += array_idx;
943    ss_idx += dyn_info->stage[stage].sampler_count;
944    fill_sampler(&state->ss[p_stage][ss_idx], binding->immutable_samplers ? binding->immutable_samplers[array_idx] : descriptor->sampler);
945    if (state->num_sampler_states[p_stage] <= ss_idx)
946       state->num_sampler_states[p_stage] = ss_idx + 1;
947    state->ss_dirty[p_stage] = true;
948 }
949 
950 #define fix_depth_swizzle(x) do { \
951   if (x > PIPE_SWIZZLE_X && x < PIPE_SWIZZLE_0) \
952     x = PIPE_SWIZZLE_0;				\
953   } while (0)
954 #define fix_depth_swizzle_a(x) do { \
955   if (x > PIPE_SWIZZLE_X && x < PIPE_SWIZZLE_0) \
956     x = PIPE_SWIZZLE_1;				\
957   } while (0)
958 
fill_sampler_view_stage(struct rendering_state * state,struct dyn_info * dyn_info,gl_shader_stage stage,enum pipe_shader_type p_stage,int array_idx,const union lvp_descriptor_info * descriptor,const struct lvp_descriptor_set_binding_layout * binding)959 static void fill_sampler_view_stage(struct rendering_state *state,
960                                     struct dyn_info *dyn_info,
961                                     gl_shader_stage stage,
962                                     enum pipe_shader_type p_stage,
963                                     int array_idx,
964                                     const union lvp_descriptor_info *descriptor,
965                                     const struct lvp_descriptor_set_binding_layout *binding)
966 {
967    int sv_idx = binding->stage[stage].sampler_view_index;
968    if (sv_idx == -1)
969       return;
970    sv_idx += array_idx;
971    sv_idx += dyn_info->stage[stage].sampler_view_count;
972    struct lvp_image_view *iv = descriptor->iview;
973    struct pipe_sampler_view templ;
974 
975    enum pipe_format pformat;
976    if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
977       pformat = lvp_vk_format_to_pipe_format(iv->format);
978    else if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
979       pformat = util_format_stencil_only(lvp_vk_format_to_pipe_format(iv->format));
980    else
981       pformat = lvp_vk_format_to_pipe_format(iv->format);
982    u_sampler_view_default_template(&templ,
983                                    iv->image->bo,
984                                    pformat);
985    if (iv->view_type == VK_IMAGE_VIEW_TYPE_1D)
986       templ.target = PIPE_TEXTURE_1D;
987    if (iv->view_type == VK_IMAGE_VIEW_TYPE_2D)
988       templ.target = PIPE_TEXTURE_2D;
989    if (iv->view_type == VK_IMAGE_VIEW_TYPE_CUBE)
990       templ.target = PIPE_TEXTURE_CUBE;
991    if (iv->view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
992       templ.target = PIPE_TEXTURE_CUBE_ARRAY;
993    templ.u.tex.first_layer = iv->subresourceRange.baseArrayLayer;
994    templ.u.tex.last_layer = iv->subresourceRange.baseArrayLayer + lvp_get_layerCount(iv->image, &iv->subresourceRange) - 1;
995    templ.u.tex.first_level = iv->subresourceRange.baseMipLevel;
996    templ.u.tex.last_level = iv->subresourceRange.baseMipLevel + lvp_get_levelCount(iv->image, &iv->subresourceRange) - 1;
997    if (iv->components.r != VK_COMPONENT_SWIZZLE_IDENTITY)
998       templ.swizzle_r = vk_conv_swizzle(iv->components.r);
999    if (iv->components.g != VK_COMPONENT_SWIZZLE_IDENTITY)
1000       templ.swizzle_g = vk_conv_swizzle(iv->components.g);
1001    if (iv->components.b != VK_COMPONENT_SWIZZLE_IDENTITY)
1002       templ.swizzle_b = vk_conv_swizzle(iv->components.b);
1003    if (iv->components.a != VK_COMPONENT_SWIZZLE_IDENTITY)
1004       templ.swizzle_a = vk_conv_swizzle(iv->components.a);
1005 
1006    /* depth stencil swizzles need special handling to pass VK CTS
1007     * but also for zink GL tests.
1008     * piping A swizzle into R fixes GL_ALPHA depth texture mode
1009     * only swizzling from R/0/1 (for alpha) fixes VK CTS tests
1010     * and a bunch of zink tests.
1011    */
1012    if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT ||
1013        iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {
1014       if (templ.swizzle_a == PIPE_SWIZZLE_X)
1015          templ.swizzle_r = PIPE_SWIZZLE_X;
1016       fix_depth_swizzle(templ.swizzle_r);
1017       fix_depth_swizzle(templ.swizzle_g);
1018       fix_depth_swizzle(templ.swizzle_b);
1019       fix_depth_swizzle_a(templ.swizzle_a);
1020    }
1021 
1022    if (state->sv[p_stage][sv_idx])
1023       pipe_sampler_view_reference(&state->sv[p_stage][sv_idx], NULL);
1024    state->sv[p_stage][sv_idx] = state->pctx->create_sampler_view(state->pctx, iv->image->bo, &templ);
1025    if (state->num_sampler_views[p_stage] <= sv_idx)
1026       state->num_sampler_views[p_stage] = sv_idx + 1;
1027    state->sv_dirty[p_stage] = true;
1028 }
1029 
fill_sampler_buffer_view_stage(struct rendering_state * state,struct dyn_info * dyn_info,gl_shader_stage stage,enum pipe_shader_type p_stage,int array_idx,const union lvp_descriptor_info * descriptor,const struct lvp_descriptor_set_binding_layout * binding)1030 static void fill_sampler_buffer_view_stage(struct rendering_state *state,
1031                                            struct dyn_info *dyn_info,
1032                                            gl_shader_stage stage,
1033                                            enum pipe_shader_type p_stage,
1034                                            int array_idx,
1035                                            const union lvp_descriptor_info *descriptor,
1036                                            const struct lvp_descriptor_set_binding_layout *binding)
1037 {
1038    int sv_idx = binding->stage[stage].sampler_view_index;
1039    if (sv_idx == -1)
1040       return;
1041    sv_idx += array_idx;
1042    sv_idx += dyn_info->stage[stage].sampler_view_count;
1043    struct lvp_buffer_view *bv = descriptor->buffer_view;
1044    struct pipe_sampler_view templ;
1045    memset(&templ, 0, sizeof(templ));
1046    templ.target = PIPE_BUFFER;
1047    templ.swizzle_r = PIPE_SWIZZLE_X;
1048    templ.swizzle_g = PIPE_SWIZZLE_Y;
1049    templ.swizzle_b = PIPE_SWIZZLE_Z;
1050    templ.swizzle_a = PIPE_SWIZZLE_W;
1051    templ.format = bv->pformat;
1052    templ.u.buf.offset = bv->offset + bv->buffer->offset;
1053    templ.u.buf.size = bv->range == VK_WHOLE_SIZE ? (bv->buffer->size - bv->offset) : bv->range;
1054    templ.texture = bv->buffer->bo;
1055    templ.context = state->pctx;
1056 
1057    if (state->sv[p_stage][sv_idx])
1058       pipe_sampler_view_reference(&state->sv[p_stage][sv_idx], NULL);
1059    state->sv[p_stage][sv_idx] = state->pctx->create_sampler_view(state->pctx, bv->buffer->bo, &templ);
1060    if (state->num_sampler_views[p_stage] <= sv_idx)
1061       state->num_sampler_views[p_stage] = sv_idx + 1;
1062    state->sv_dirty[p_stage] = true;
1063 }
1064 
fill_image_view_stage(struct rendering_state * state,struct dyn_info * dyn_info,gl_shader_stage stage,enum pipe_shader_type p_stage,int array_idx,const union lvp_descriptor_info * descriptor,const struct lvp_descriptor_set_binding_layout * binding)1065 static void fill_image_view_stage(struct rendering_state *state,
1066                                   struct dyn_info *dyn_info,
1067                                   gl_shader_stage stage,
1068                                   enum pipe_shader_type p_stage,
1069                                   int array_idx,
1070                                   const union lvp_descriptor_info *descriptor,
1071                                   const struct lvp_descriptor_set_binding_layout *binding)
1072 {
1073    struct lvp_image_view *iv = descriptor->iview;
1074    int idx = binding->stage[stage].image_index;
1075    if (idx == -1)
1076       return;
1077    idx += array_idx;
1078    idx += dyn_info->stage[stage].image_count;
1079    state->iv[p_stage][idx].resource = iv->image->bo;
1080    if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
1081       state->iv[p_stage][idx].format = lvp_vk_format_to_pipe_format(iv->format);
1082    else if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
1083       state->iv[p_stage][idx].format = util_format_stencil_only(lvp_vk_format_to_pipe_format(iv->format));
1084    else
1085       state->iv[p_stage][idx].format = lvp_vk_format_to_pipe_format(iv->format);
1086 
1087    if (iv->view_type == VK_IMAGE_VIEW_TYPE_3D) {
1088       state->iv[p_stage][idx].u.tex.first_layer = 0;
1089       state->iv[p_stage][idx].u.tex.last_layer = u_minify(iv->image->bo->depth0, iv->subresourceRange.baseMipLevel) - 1;
1090    } else {
1091       state->iv[p_stage][idx].u.tex.first_layer = iv->subresourceRange.baseArrayLayer;
1092       state->iv[p_stage][idx].u.tex.last_layer = iv->subresourceRange.baseArrayLayer + lvp_get_layerCount(iv->image, &iv->subresourceRange) - 1;
1093    }
1094    state->iv[p_stage][idx].u.tex.level = iv->subresourceRange.baseMipLevel;
1095    if (state->num_shader_images[p_stage] <= idx)
1096       state->num_shader_images[p_stage] = idx + 1;
1097    state->iv_dirty[p_stage] = true;
1098 }
1099 
fill_image_buffer_view_stage(struct rendering_state * state,struct dyn_info * dyn_info,gl_shader_stage stage,enum pipe_shader_type p_stage,int array_idx,const union lvp_descriptor_info * descriptor,const struct lvp_descriptor_set_binding_layout * binding)1100 static void fill_image_buffer_view_stage(struct rendering_state *state,
1101                                          struct dyn_info *dyn_info,
1102                                          gl_shader_stage stage,
1103                                          enum pipe_shader_type p_stage,
1104                                          int array_idx,
1105                                          const union lvp_descriptor_info *descriptor,
1106                                          const struct lvp_descriptor_set_binding_layout *binding)
1107 {
1108    struct lvp_buffer_view *bv = descriptor->buffer_view;
1109    int idx = binding->stage[stage].image_index;
1110    if (idx == -1)
1111       return;
1112    idx += array_idx;
1113    idx += dyn_info->stage[stage].image_count;
1114    state->iv[p_stage][idx].resource = bv->buffer->bo;
1115    state->iv[p_stage][idx].format = bv->pformat;
1116    state->iv[p_stage][idx].u.buf.offset = bv->offset + bv->buffer->offset;
1117    state->iv[p_stage][idx].u.buf.size = bv->range == VK_WHOLE_SIZE ? (bv->buffer->size - bv->offset): bv->range;
1118    if (state->num_shader_images[p_stage] <= idx)
1119       state->num_shader_images[p_stage] = idx + 1;
1120    state->iv_dirty[p_stage] = true;
1121 }
1122 
handle_descriptor(struct rendering_state * state,struct dyn_info * dyn_info,const struct lvp_descriptor_set_binding_layout * binding,gl_shader_stage stage,enum pipe_shader_type p_stage,int array_idx,VkDescriptorType type,const union lvp_descriptor_info * descriptor)1123 static void handle_descriptor(struct rendering_state *state,
1124                               struct dyn_info *dyn_info,
1125                               const struct lvp_descriptor_set_binding_layout *binding,
1126                               gl_shader_stage stage,
1127                               enum pipe_shader_type p_stage,
1128                               int array_idx,
1129                               VkDescriptorType type,
1130                               const union lvp_descriptor_info *descriptor)
1131 {
1132    bool is_dynamic = type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
1133       type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
1134 
1135    switch (type) {
1136    case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1137    case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
1138       fill_image_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
1139       break;
1140    }
1141    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1142    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: {
1143       int idx = binding->stage[stage].const_buffer_index;
1144       if (idx == -1)
1145          return;
1146       idx += array_idx;
1147       idx += dyn_info->stage[stage].const_buffer_count;
1148       state->const_buffer[p_stage][idx].buffer = descriptor->buffer->bo;
1149       state->const_buffer[p_stage][idx].buffer_offset = descriptor->offset + descriptor->buffer->offset;
1150       if (is_dynamic) {
1151          uint32_t offset = dyn_info->dynamic_offsets[dyn_info->dyn_index + binding->dynamic_index + array_idx];
1152          state->const_buffer[p_stage][idx].buffer_offset += offset;
1153       }
1154       if (descriptor->range == VK_WHOLE_SIZE)
1155          state->const_buffer[p_stage][idx].buffer_size = descriptor->buffer->bo->width0 - state->const_buffer[p_stage][idx].buffer_offset;
1156       else
1157          state->const_buffer[p_stage][idx].buffer_size = descriptor->range;
1158       if (state->num_const_bufs[p_stage] <= idx)
1159          state->num_const_bufs[p_stage] = idx + 1;
1160       state->constbuf_dirty[p_stage] = true;
1161       break;
1162    }
1163    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1164    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
1165       int idx = binding->stage[stage].shader_buffer_index;
1166       if (idx == -1)
1167          return;
1168       idx += array_idx;
1169       idx += dyn_info->stage[stage].shader_buffer_count;
1170       state->sb[p_stage][idx].buffer = descriptor->buffer->bo;
1171       state->sb[p_stage][idx].buffer_offset = descriptor->offset + descriptor->buffer->offset;
1172       if (is_dynamic) {
1173          uint32_t offset = dyn_info->dynamic_offsets[dyn_info->dyn_index + binding->dynamic_index + array_idx];
1174          state->sb[p_stage][idx].buffer_offset += offset;
1175       }
1176       if (descriptor->range == VK_WHOLE_SIZE)
1177          state->sb[p_stage][idx].buffer_size = descriptor->buffer->bo->width0 - state->sb[p_stage][idx].buffer_offset;
1178       else
1179          state->sb[p_stage][idx].buffer_size = descriptor->range;
1180       if (state->num_shader_buffers[p_stage] <= idx)
1181          state->num_shader_buffers[p_stage] = idx + 1;
1182       state->sb_dirty[p_stage] = true;
1183       break;
1184    }
1185    case VK_DESCRIPTOR_TYPE_SAMPLER:
1186       if (!descriptor->sampler)
1187          return;
1188       fill_sampler_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
1189       break;
1190    case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1191       fill_sampler_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
1192       break;
1193    case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1194       fill_sampler_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
1195       fill_sampler_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
1196       break;
1197    case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1198       fill_sampler_buffer_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
1199       break;
1200    case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1201       fill_image_buffer_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
1202       break;
1203    default:
1204       fprintf(stderr, "Unhandled descriptor set %d\n", type);
1205       break;
1206    }
1207 }
1208 
handle_set_stage(struct rendering_state * state,struct dyn_info * dyn_info,const struct lvp_descriptor_set * set,gl_shader_stage stage,enum pipe_shader_type p_stage)1209 static void handle_set_stage(struct rendering_state *state,
1210                              struct dyn_info *dyn_info,
1211                              const struct lvp_descriptor_set *set,
1212                              gl_shader_stage stage,
1213                              enum pipe_shader_type p_stage)
1214 {
1215    int j;
1216    for (j = 0; j < set->layout->binding_count; j++) {
1217       const struct lvp_descriptor_set_binding_layout *binding;
1218       const struct lvp_descriptor *descriptor;
1219       binding = &set->layout->binding[j];
1220 
1221       if (binding->valid) {
1222          for (int i = 0; i < binding->array_size; i++) {
1223             descriptor = &set->descriptors[binding->descriptor_index + i];
1224             handle_descriptor(state, dyn_info, binding, stage, p_stage, i, descriptor->type, &descriptor->info);
1225          }
1226       }
1227    }
1228 }
1229 
increment_dyn_info(struct dyn_info * dyn_info,struct lvp_descriptor_set_layout * layout,bool inc_dyn)1230 static void increment_dyn_info(struct dyn_info *dyn_info,
1231                                struct lvp_descriptor_set_layout *layout, bool inc_dyn)
1232 {
1233    for (gl_shader_stage stage = MESA_SHADER_VERTEX; stage < MESA_SHADER_STAGES; stage++) {
1234       dyn_info->stage[stage].const_buffer_count += layout->stage[stage].const_buffer_count;
1235       dyn_info->stage[stage].shader_buffer_count += layout->stage[stage].shader_buffer_count;
1236       dyn_info->stage[stage].sampler_count += layout->stage[stage].sampler_count;
1237       dyn_info->stage[stage].sampler_view_count += layout->stage[stage].sampler_view_count;
1238       dyn_info->stage[stage].image_count += layout->stage[stage].image_count;
1239    }
1240    if (inc_dyn)
1241       dyn_info->dyn_index += layout->dynamic_offset_count;
1242 }
1243 
handle_compute_descriptor_sets(struct vk_cmd_queue_entry * cmd,struct dyn_info * dyn_info,struct rendering_state * state)1244 static void handle_compute_descriptor_sets(struct vk_cmd_queue_entry *cmd,
1245                                            struct dyn_info *dyn_info,
1246                                            struct rendering_state *state)
1247 {
1248    struct vk_cmd_bind_descriptor_sets *bds = &cmd->u.bind_descriptor_sets;
1249    struct lvp_descriptor_set_layout **set_layout = cmd->driver_data;
1250    int i;
1251 
1252    for (i = 0; i < bds->first_set; i++) {
1253       increment_dyn_info(dyn_info, set_layout[i], false);
1254    }
1255    for (i = 0; i < bds->descriptor_set_count; i++) {
1256       const struct lvp_descriptor_set *set = lvp_descriptor_set_from_handle(bds->descriptor_sets[i]);
1257 
1258       if (set->layout->shader_stages & VK_SHADER_STAGE_COMPUTE_BIT)
1259          handle_set_stage(state, dyn_info, set, MESA_SHADER_COMPUTE, PIPE_SHADER_COMPUTE);
1260       increment_dyn_info(dyn_info, set_layout[bds->first_set + i], true);
1261    }
1262 }
1263 
handle_descriptor_sets(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1264 static void handle_descriptor_sets(struct vk_cmd_queue_entry *cmd,
1265                                    struct rendering_state *state)
1266 {
1267    struct vk_cmd_bind_descriptor_sets *bds = &cmd->u.bind_descriptor_sets;
1268    struct lvp_descriptor_set_layout **set_layout = cmd->driver_data;
1269    int i;
1270    struct dyn_info dyn_info;
1271 
1272    dyn_info.dyn_index = 0;
1273    dyn_info.dynamic_offsets = bds->dynamic_offsets;
1274    dyn_info.dynamic_offset_count = bds->dynamic_offset_count;
1275 
1276    memset(dyn_info.stage, 0, sizeof(dyn_info.stage));
1277    if (bds->pipeline_bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
1278       handle_compute_descriptor_sets(cmd, &dyn_info, state);
1279       return;
1280    }
1281 
1282    for (i = 0; i < bds->first_set; i++) {
1283       increment_dyn_info(&dyn_info, set_layout[i], false);
1284    }
1285 
1286    for (i = 0; i < bds->descriptor_set_count; i++) {
1287       const struct lvp_descriptor_set *set = lvp_descriptor_set_from_handle(bds->descriptor_sets[i]);
1288 
1289       if (set->layout->shader_stages & VK_SHADER_STAGE_VERTEX_BIT)
1290          handle_set_stage(state, &dyn_info, set, MESA_SHADER_VERTEX, PIPE_SHADER_VERTEX);
1291 
1292       if (set->layout->shader_stages & VK_SHADER_STAGE_GEOMETRY_BIT)
1293          handle_set_stage(state, &dyn_info, set, MESA_SHADER_GEOMETRY, PIPE_SHADER_GEOMETRY);
1294 
1295       if (set->layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
1296          handle_set_stage(state, &dyn_info, set, MESA_SHADER_TESS_CTRL, PIPE_SHADER_TESS_CTRL);
1297 
1298       if (set->layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
1299          handle_set_stage(state, &dyn_info, set, MESA_SHADER_TESS_EVAL, PIPE_SHADER_TESS_EVAL);
1300 
1301       if (set->layout->shader_stages & VK_SHADER_STAGE_FRAGMENT_BIT)
1302          handle_set_stage(state, &dyn_info, set, MESA_SHADER_FRAGMENT, PIPE_SHADER_FRAGMENT);
1303 
1304       increment_dyn_info(&dyn_info, set_layout[bds->first_set + i], true);
1305    }
1306 }
1307 
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)1308 static struct pipe_surface *create_img_surface_bo(struct rendering_state *state,
1309                                                   VkImageSubresourceRange *range,
1310                                                   struct pipe_resource *bo,
1311                                                   enum pipe_format pformat,
1312                                                   int width,
1313                                                   int height,
1314                                                   int base_layer, int layer_count,
1315                                                   int level)
1316 {
1317    struct pipe_surface template;
1318 
1319    memset(&template, 0, sizeof(struct pipe_surface));
1320 
1321    template.format = pformat;
1322    template.width = width;
1323    template.height = height;
1324    template.u.tex.first_layer = range->baseArrayLayer + base_layer;
1325    template.u.tex.last_layer = range->baseArrayLayer + layer_count;
1326    template.u.tex.level = range->baseMipLevel + level;
1327 
1328    if (template.format == PIPE_FORMAT_NONE)
1329       return NULL;
1330    return state->pctx->create_surface(state->pctx,
1331                                       bo, &template);
1332 
1333 }
create_img_surface(struct rendering_state * state,struct lvp_image_view * imgv,VkFormat format,int width,int height,int base_layer,int layer_count)1334 static struct pipe_surface *create_img_surface(struct rendering_state *state,
1335                                                struct lvp_image_view *imgv,
1336                                                VkFormat format, int width,
1337                                                int height,
1338                                                int base_layer, int layer_count)
1339 {
1340    return create_img_surface_bo(state, &imgv->subresourceRange, imgv->image->bo,
1341                                 lvp_vk_format_to_pipe_format(format), width, height, base_layer, layer_count, 0);
1342 }
1343 
add_img_view_surface(struct rendering_state * state,struct lvp_image_view * imgv,VkFormat format,int width,int height)1344 static void add_img_view_surface(struct rendering_state *state,
1345                                  struct lvp_image_view *imgv, VkFormat format, int width, int height)
1346 {
1347    if (!imgv->surface) {
1348       imgv->surface = create_img_surface(state, imgv, format,
1349                                          width, height,
1350                                          0, lvp_get_layerCount(imgv->image, &imgv->subresourceRange) - 1);
1351    }
1352 }
1353 
1354 static inline bool
attachment_needs_clear(struct rendering_state * state,uint32_t a)1355 attachment_needs_clear(struct rendering_state *state,
1356                        uint32_t a)
1357 {
1358    const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
1359    uint32_t view_mask = subpass->view_mask;
1360    return (a != VK_ATTACHMENT_UNUSED &&
1361            state->pending_clear_aspects[a] &&
1362            (!view_mask || (view_mask & ~state->cleared_views[a])));
1363 }
1364 
1365 static bool
subpass_needs_clear(struct rendering_state * state)1366 subpass_needs_clear(struct rendering_state *state)
1367 {
1368    uint32_t a;
1369    const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
1370    for (uint32_t i = 0; i < subpass->color_count; i++) {
1371       a = subpass->color_attachments[i].attachment;
1372       if (attachment_needs_clear(state, a))
1373          return true;
1374    }
1375    if (subpass->depth_stencil_attachment) {
1376       a = subpass->depth_stencil_attachment->attachment;
1377       if (attachment_needs_clear(state, a))
1378          return true;
1379    }
1380    return false;
1381 }
1382 
clear_attachment_layers(struct rendering_state * state,struct lvp_image_view * imgv,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)1383 static void clear_attachment_layers(struct rendering_state *state,
1384                                     struct lvp_image_view *imgv,
1385                                     VkRect2D *rect,
1386                                     unsigned base_layer, unsigned layer_count,
1387                                     unsigned ds_clear_flags, double dclear_val,
1388                                     uint32_t sclear_val,
1389                                     union pipe_color_union *col_val)
1390 {
1391    struct pipe_surface *clear_surf = create_img_surface(state,
1392                                                         imgv,
1393                                                         imgv->format,
1394                                                         state->framebuffer.width,
1395                                                         state->framebuffer.height,
1396                                                         base_layer,
1397                                                         base_layer + layer_count - 1);
1398 
1399    if (ds_clear_flags) {
1400       state->pctx->clear_depth_stencil(state->pctx,
1401                                        clear_surf,
1402                                        ds_clear_flags,
1403                                        dclear_val, sclear_val,
1404                                        rect->offset.x, rect->offset.y,
1405                                        rect->extent.width, rect->extent.height,
1406                                        true);
1407    } else {
1408       state->pctx->clear_render_target(state->pctx, clear_surf,
1409                                        col_val,
1410                                        rect->offset.x, rect->offset.y,
1411                                        rect->extent.width, rect->extent.height,
1412                                        true);
1413    }
1414    state->pctx->surface_destroy(state->pctx, clear_surf);
1415 }
1416 
1417 static struct lvp_image_view *
get_attachment(struct rendering_state * state,unsigned idx)1418 get_attachment(struct rendering_state *state,
1419                unsigned idx)
1420 {
1421    if (state->imageless_views)
1422       return state->imageless_views[idx];
1423    else
1424       return state->vk_framebuffer->attachments[idx];
1425 }
1426 
render_subpass_clear(struct rendering_state * state)1427 static void render_subpass_clear(struct rendering_state *state)
1428 {
1429    const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
1430 
1431    for (unsigned i = 0; i < subpass->color_count; i++) {
1432       uint32_t a = subpass->color_attachments[i].attachment;
1433 
1434       if (!attachment_needs_clear(state, a))
1435          continue;
1436 
1437       union pipe_color_union color_clear_val = { 0 };
1438       const VkClearValue value = state->attachments[a].clear_value;
1439       color_clear_val.ui[0] = value.color.uint32[0];
1440       color_clear_val.ui[1] = value.color.uint32[1];
1441       color_clear_val.ui[2] = value.color.uint32[2];
1442       color_clear_val.ui[3] = value.color.uint32[3];
1443 
1444       struct lvp_image_view *imgv = get_attachment(state, a);
1445 
1446       assert(imgv->surface);
1447 
1448       if (subpass->view_mask) {
1449          u_foreach_bit(i, subpass->view_mask)
1450             clear_attachment_layers(state, imgv, &state->render_area,
1451                                     i, 1, 0, 0, 0, &color_clear_val);
1452          state->cleared_views[a] |= subpass->view_mask;
1453       } else {
1454          state->pctx->clear_render_target(state->pctx,
1455                                           imgv->surface,
1456                                           &color_clear_val,
1457                                           state->render_area.offset.x, state->render_area.offset.y,
1458                                           state->render_area.extent.width, state->render_area.extent.height,
1459                                           false);
1460          state->pending_clear_aspects[a] = 0;
1461       }
1462    }
1463 
1464    if (subpass->depth_stencil_attachment) {
1465       uint32_t ds = subpass->depth_stencil_attachment->attachment;
1466 
1467       if (!attachment_needs_clear(state, ds))
1468          return;
1469 
1470       struct lvp_render_pass_attachment *att = &state->pass->attachments[ds];
1471       struct lvp_image_view *imgv = get_attachment(state, ds);
1472 
1473       assert (util_format_is_depth_or_stencil(imgv->surface->format));
1474 
1475       const struct util_format_description *desc = util_format_description(imgv->surface->format);
1476       double dclear_val = 0;
1477       uint32_t sclear_val = 0;
1478       uint32_t ds_clear_flags = 0;
1479 
1480       if ((util_format_has_stencil(desc) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) ||
1481           (util_format_is_depth_and_stencil(imgv->surface->format) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE)) {
1482          ds_clear_flags |= PIPE_CLEAR_STENCIL;
1483          if (att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
1484             sclear_val = state->attachments[ds].clear_value.depthStencil.stencil;
1485       }
1486       if ((util_format_has_depth(desc) && att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) ||
1487           (util_format_is_depth_and_stencil(imgv->surface->format) && att->load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE)) {
1488          ds_clear_flags |= PIPE_CLEAR_DEPTH;
1489          if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
1490             dclear_val = state->attachments[ds].clear_value.depthStencil.depth;
1491       }
1492 
1493       assert(imgv->surface);
1494       if (ds_clear_flags) {
1495          if (subpass->view_mask) {
1496             u_foreach_bit(i, subpass->view_mask)
1497                clear_attachment_layers(state, imgv, &state->render_area,
1498                                        i, 1, ds_clear_flags, dclear_val, sclear_val, NULL);
1499             state->cleared_views[ds] |= subpass->view_mask;
1500          } else {
1501             state->pctx->clear_depth_stencil(state->pctx,
1502                                              imgv->surface,
1503                                              ds_clear_flags,
1504                                              dclear_val, sclear_val,
1505                                              state->render_area.offset.x, state->render_area.offset.y,
1506                                              state->render_area.extent.width, state->render_area.extent.height,
1507                                              false);
1508             state->pending_clear_aspects[ds] = 0;
1509          }
1510       }
1511 
1512    }
1513 
1514 }
1515 
render_subpass_clear_fast(struct rendering_state * state)1516 static void render_subpass_clear_fast(struct rendering_state *state)
1517 {
1518    /* attempt to use the clear interface first, then fallback to per-attchment clears */
1519    const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
1520    bool has_color_value = false;
1521    uint32_t buffers = 0;
1522    VkClearValue color_value = {0};
1523    double dclear_val = 0;
1524    uint32_t sclear_val = 0;
1525 
1526    /*
1527     * the state tracker clear interface only works if all the attachments have the same
1528     * clear color.
1529     */
1530    /* llvmpipe doesn't support scissored clears yet */
1531    if (state->render_area.offset.x || state->render_area.offset.y)
1532       goto slow_clear;
1533 
1534    if (state->render_area.extent.width != state->framebuffer.width ||
1535        state->render_area.extent.height != state->framebuffer.height)
1536       goto slow_clear;
1537 
1538    if (subpass->view_mask)
1539       goto slow_clear;
1540    for (unsigned i = 0; i < subpass->color_count; i++) {
1541       uint32_t a = subpass->color_attachments[i].attachment;
1542 
1543       if (!attachment_needs_clear(state, a))
1544          continue;
1545 
1546       if (has_color_value) {
1547          if (memcmp(&color_value, &state->attachments[a].clear_value, sizeof(VkClearValue)))
1548             goto slow_clear;
1549       } else {
1550          memcpy(&color_value, &state->attachments[a].clear_value, sizeof(VkClearValue));
1551          has_color_value = true;
1552       }
1553    }
1554 
1555    for (unsigned i = 0; i < subpass->color_count; i++) {
1556       uint32_t a = subpass->color_attachments[i].attachment;
1557 
1558       if (!attachment_needs_clear(state, a))
1559          continue;
1560       buffers |= (PIPE_CLEAR_COLOR0 << i);
1561       state->pending_clear_aspects[a] = 0;
1562    }
1563 
1564    if (subpass->depth_stencil_attachment &&
1565        attachment_needs_clear(state, subpass->depth_stencil_attachment->attachment)) {
1566       uint32_t ds = subpass->depth_stencil_attachment->attachment;
1567 
1568       struct lvp_render_pass_attachment *att = &state->pass->attachments[ds];
1569       struct lvp_image_view *imgv = get_attachment(state, ds);
1570       const struct util_format_description *desc = util_format_description(imgv->surface->format);
1571 
1572       /* also clear stencil for don't care to avoid RMW */
1573       if ((util_format_has_stencil(desc) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) ||
1574           (util_format_is_depth_and_stencil(imgv->surface->format) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE))
1575          buffers |= PIPE_CLEAR_STENCIL;
1576       if (util_format_has_depth(desc) && att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
1577          buffers |= PIPE_CLEAR_DEPTH;
1578 
1579       dclear_val = state->attachments[ds].clear_value.depthStencil.depth;
1580       sclear_val = state->attachments[ds].clear_value.depthStencil.stencil;
1581       state->pending_clear_aspects[ds] = 0;
1582    }
1583 
1584    union pipe_color_union col_val;
1585    for (unsigned i = 0; i < 4; i++)
1586       col_val.ui[i] = color_value.color.uint32[i];
1587 
1588    state->pctx->clear(state->pctx, buffers,
1589                       NULL, &col_val,
1590                       dclear_val, sclear_val);
1591    return;
1592 slow_clear:
1593    render_subpass_clear(state);
1594 }
1595 
render_pass_resolve(struct rendering_state * state)1596 static void render_pass_resolve(struct rendering_state *state)
1597 {
1598    const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
1599 
1600    if (subpass->depth_stencil_attachment && subpass->ds_resolve_attachment) {
1601       struct lvp_subpass_attachment src_att = *subpass->depth_stencil_attachment;
1602       struct lvp_subpass_attachment dst_att = *subpass->ds_resolve_attachment;
1603       if (dst_att.attachment != VK_ATTACHMENT_UNUSED) {
1604          int num_blits = 1;
1605          if (subpass->depth_resolve_mode != subpass->stencil_resolve_mode)
1606             num_blits = 2;
1607 
1608          for (unsigned i = 0; i < num_blits; i++) {
1609 
1610             if (i == 0 && subpass->depth_resolve_mode == VK_RESOLVE_MODE_NONE)
1611                continue;
1612 
1613             if (i == 1 && subpass->stencil_resolve_mode == VK_RESOLVE_MODE_NONE)
1614                continue;
1615 
1616             struct lvp_image_view *src_imgv = get_attachment(state, src_att.attachment);
1617             struct lvp_image_view *dst_imgv = get_attachment(state, dst_att.attachment);
1618 
1619             struct pipe_blit_info info;
1620             memset(&info, 0, sizeof(info));
1621 
1622             info.src.resource = src_imgv->image->bo;
1623             info.dst.resource = dst_imgv->image->bo;
1624             info.src.format = src_imgv->pformat;
1625             info.dst.format = dst_imgv->pformat;
1626             info.filter = PIPE_TEX_FILTER_NEAREST;
1627 
1628             if (num_blits == 1)
1629                info.mask = PIPE_MASK_ZS;
1630             else if (i == 0)
1631                info.mask = PIPE_MASK_Z;
1632             else
1633                info.mask = PIPE_MASK_S;
1634 
1635             if (i == 0 && subpass->depth_resolve_mode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT)
1636                info.sample0_only = true;
1637             if (i == 1 && subpass->stencil_resolve_mode == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT)
1638                info.sample0_only = true;
1639 
1640             info.src.box.x = state->render_area.offset.x;
1641             info.src.box.y = state->render_area.offset.y;
1642             info.src.box.width = state->render_area.extent.width;
1643             info.src.box.height = state->render_area.extent.height;
1644             info.src.box.depth = state->vk_framebuffer->layers;
1645 
1646             info.dst.box = info.src.box;
1647 
1648             state->pctx->blit(state->pctx, &info);
1649          }
1650       }
1651    }
1652 
1653    if (!subpass->has_color_resolve)
1654       return;
1655    for (uint32_t i = 0; i < subpass->color_count; i++) {
1656       struct lvp_subpass_attachment src_att = subpass->color_attachments[i];
1657       struct lvp_subpass_attachment dst_att = subpass->resolve_attachments[i];
1658 
1659       if (dst_att.attachment == VK_ATTACHMENT_UNUSED)
1660          continue;
1661 
1662       struct lvp_image_view *src_imgv = get_attachment(state, src_att.attachment);
1663       struct lvp_image_view *dst_imgv = get_attachment(state, dst_att.attachment);
1664 
1665       struct pipe_blit_info info;
1666       memset(&info, 0, sizeof(info));
1667 
1668       info.src.resource = src_imgv->image->bo;
1669       info.dst.resource = dst_imgv->image->bo;
1670       info.src.format = src_imgv->pformat;
1671       info.dst.format = dst_imgv->pformat;
1672       info.filter = PIPE_TEX_FILTER_NEAREST;
1673       info.mask = PIPE_MASK_RGBA;
1674       info.src.box.x = state->render_area.offset.x;
1675       info.src.box.y = state->render_area.offset.y;
1676       info.src.box.width = state->render_area.extent.width;
1677       info.src.box.height = state->render_area.extent.height;
1678       info.src.box.depth = state->vk_framebuffer->layers;
1679 
1680       info.dst.box = info.src.box;
1681 
1682       info.src.level = src_imgv->subresourceRange.baseMipLevel;
1683       info.dst.level = dst_imgv->subresourceRange.baseMipLevel;
1684 
1685       state->pctx->blit(state->pctx, &info);
1686    }
1687 }
1688 
begin_render_subpass(struct rendering_state * state,int subpass_idx)1689 static void begin_render_subpass(struct rendering_state *state,
1690                                  int subpass_idx)
1691 {
1692    state->subpass = subpass_idx;
1693 
1694    state->framebuffer.nr_cbufs = 0;
1695 
1696    const struct lvp_subpass *subpass = &state->pass->subpasses[subpass_idx];
1697    for (unsigned i = 0; i < subpass->color_count; i++) {
1698       struct lvp_subpass_attachment *color_att = &subpass->color_attachments[i];
1699       if (color_att->attachment != VK_ATTACHMENT_UNUSED) {
1700          struct lvp_image_view *imgv = get_attachment(state, color_att->attachment);
1701          add_img_view_surface(state, imgv, state->pass->attachments[color_att->attachment].format, state->framebuffer.width, state->framebuffer.height);
1702          state->framebuffer.cbufs[state->framebuffer.nr_cbufs] = imgv->surface;
1703       } else
1704          state->framebuffer.cbufs[state->framebuffer.nr_cbufs] = NULL;
1705       state->framebuffer.nr_cbufs++;
1706    }
1707 
1708    if (subpass->depth_stencil_attachment) {
1709       struct lvp_subpass_attachment *ds_att = subpass->depth_stencil_attachment;
1710 
1711       if (ds_att->attachment != VK_ATTACHMENT_UNUSED) {
1712          struct lvp_image_view *imgv = get_attachment(state, ds_att->attachment);
1713          add_img_view_surface(state, imgv, state->pass->attachments[ds_att->attachment].format, state->framebuffer.width, state->framebuffer.height);
1714          state->framebuffer.zsbuf = imgv->surface;
1715       }
1716    }
1717 
1718    state->pctx->set_framebuffer_state(state->pctx,
1719                                       &state->framebuffer);
1720 
1721    if (subpass_needs_clear(state))
1722       render_subpass_clear_fast(state);
1723 }
1724 
begin_render_pass(const VkRenderPassBeginInfo * render_pass_begin,struct rendering_state * state)1725 static void begin_render_pass(const VkRenderPassBeginInfo *render_pass_begin,
1726                               struct rendering_state *state)
1727 {
1728    LVP_FROM_HANDLE(lvp_render_pass, pass, render_pass_begin->renderPass);
1729    LVP_FROM_HANDLE(lvp_framebuffer, framebuffer, render_pass_begin->framebuffer);
1730    const struct VkRenderPassAttachmentBeginInfo *attachment_info =
1731       vk_find_struct_const(render_pass_begin->pNext,
1732                            RENDER_PASS_ATTACHMENT_BEGIN_INFO);
1733 
1734    state->pass = pass;
1735    state->vk_framebuffer = framebuffer;
1736    state->render_area = render_pass_begin->renderArea;
1737 
1738    if (attachment_info) {
1739       state->imageless_views = realloc(state->imageless_views, sizeof(*state->imageless_views) * attachment_info->attachmentCount);
1740       for (unsigned i = 0; i < attachment_info->attachmentCount; i++)
1741          state->imageless_views[i] = lvp_image_view_from_handle(attachment_info->pAttachments[i]);
1742    }
1743 
1744    state->framebuffer.width = state->vk_framebuffer->width;
1745    state->framebuffer.height = state->vk_framebuffer->height;
1746    state->framebuffer.layers = state->vk_framebuffer->layers;
1747 
1748    if (state->num_pending_aspects < state->pass->attachment_count) {
1749       state->pending_clear_aspects = realloc(state->pending_clear_aspects, sizeof(VkImageAspectFlags) * state->pass->attachment_count);
1750       state->cleared_views = realloc(state->cleared_views, sizeof(uint32_t) * state->pass->attachment_count);
1751       state->num_pending_aspects = state->pass->attachment_count;
1752    }
1753 
1754    state->attachments = realloc(state->attachments, sizeof(*state->attachments) * pass->attachment_count);
1755    for (unsigned i = 0; i < state->pass->attachment_count; i++) {
1756       struct lvp_render_pass_attachment *att = &pass->attachments[i];
1757       VkImageAspectFlags att_aspects = vk_format_aspects(att->format);
1758       VkImageAspectFlags clear_aspects = 0;
1759       if (att_aspects == VK_IMAGE_ASPECT_COLOR_BIT) {
1760          /* color attachment */
1761          if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
1762             clear_aspects |= VK_IMAGE_ASPECT_COLOR_BIT;
1763          }
1764       } else {
1765          /* depthstencil attachment */
1766          if ((att_aspects & VK_IMAGE_ASPECT_DEPTH_BIT) &&
1767              att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
1768             clear_aspects |= VK_IMAGE_ASPECT_DEPTH_BIT;
1769             if ((att_aspects & VK_IMAGE_ASPECT_STENCIL_BIT) &&
1770                 att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
1771                clear_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
1772          }
1773          if ((att_aspects & VK_IMAGE_ASPECT_STENCIL_BIT) &&
1774              att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
1775             clear_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
1776          }
1777       }
1778       state->attachments[i].pending_clear_aspects = clear_aspects;
1779       if (clear_aspects)
1780          state->attachments[i].clear_value = render_pass_begin->pClearValues[i];
1781 
1782       state->pending_clear_aspects[i] = state->attachments[i].pending_clear_aspects;
1783       state->cleared_views[i] = 0;
1784    }
1785    begin_render_subpass(state, 0);
1786 }
1787 
1788 
handle_begin_render_pass(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1789 static void handle_begin_render_pass(struct vk_cmd_queue_entry *cmd,
1790                                      struct rendering_state *state)
1791 {
1792    begin_render_pass(cmd->u.begin_render_pass.render_pass_begin, state);
1793 }
1794 
handle_begin_render_pass2(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1795 static void handle_begin_render_pass2(struct vk_cmd_queue_entry *cmd,
1796                                       struct rendering_state *state)
1797 {
1798    begin_render_pass(cmd->u.begin_render_pass2.render_pass_begin, state);
1799 }
1800 
handle_end_render_pass2(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1801 static void handle_end_render_pass2(struct vk_cmd_queue_entry *cmd,
1802                                     struct rendering_state *state)
1803 {
1804    state->pctx->flush(state->pctx, NULL, 0);
1805 
1806    render_pass_resolve(state);
1807 
1808    free(state->attachments);
1809    state->attachments = NULL;
1810    state->pass = NULL;
1811    state->subpass = 0;
1812 }
1813 
handle_next_subpass2(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1814 static void handle_next_subpass2(struct vk_cmd_queue_entry *cmd,
1815                                 struct rendering_state *state)
1816 {
1817    state->pctx->flush(state->pctx, NULL, 0);
1818    render_pass_resolve(state);
1819    state->subpass++;
1820    begin_render_subpass(state, state->subpass);
1821 }
1822 
handle_draw(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1823 static void handle_draw(struct vk_cmd_queue_entry *cmd,
1824                         struct rendering_state *state)
1825 {
1826    const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
1827    struct pipe_draw_start_count_bias draw;
1828 
1829    state->info.index_size = 0;
1830    state->info.index.resource = NULL;
1831    state->info.start_instance = cmd->u.draw.first_instance;
1832    state->info.instance_count = cmd->u.draw.instance_count;
1833    state->info.view_mask = subpass->view_mask;
1834 
1835    draw.start = cmd->u.draw.first_vertex;
1836    draw.count = cmd->u.draw.vertex_count;
1837 
1838    state->pctx->set_patch_vertices(state->pctx, state->patch_vertices);
1839    state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, &draw, 1);
1840 }
1841 
handle_draw_multi(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1842 static void handle_draw_multi(struct vk_cmd_queue_entry *cmd,
1843                               struct rendering_state *state)
1844 {
1845    const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
1846    struct pipe_draw_start_count_bias *draws = calloc(cmd->u.draw_multi_ext.draw_count,
1847                                                      sizeof(*draws));
1848 
1849    state->info.index_size = 0;
1850    state->info.index.resource = NULL;
1851    state->info.start_instance = cmd->u.draw_multi_ext.first_instance;
1852    state->info.instance_count = cmd->u.draw_multi_ext.instance_count;
1853    state->info.view_mask = subpass->view_mask;
1854    if (cmd->u.draw_multi_ext.draw_count > 1)
1855       state->info.increment_draw_id = true;
1856 
1857    for(unsigned i = 0; i < cmd->u.draw_multi_ext.draw_count; i++) {
1858       draws[i].start = cmd->u.draw_multi_ext.vertex_info[i].firstVertex;
1859       draws[i].count = cmd->u.draw_multi_ext.vertex_info[i].vertexCount;
1860       draws[i].index_bias = 0;
1861    }
1862 
1863    state->pctx->set_patch_vertices(state->pctx, state->patch_vertices);
1864 
1865    if (cmd->u.draw_multi_indexed_ext.draw_count)
1866       state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, draws, cmd->u.draw_multi_ext.draw_count);
1867 
1868    free(draws);
1869 }
1870 
set_viewport(unsigned first_viewport,unsigned viewport_count,const VkViewport * viewports,struct rendering_state * state)1871 static void set_viewport(unsigned first_viewport, unsigned viewport_count,
1872                          const VkViewport* viewports,
1873                          struct rendering_state *state)
1874 {
1875    int i;
1876    unsigned base = 0;
1877    if (first_viewport == UINT32_MAX)
1878       state->num_viewports = viewport_count;
1879    else
1880       base = first_viewport;
1881 
1882    for (i = 0; i < viewport_count; i++) {
1883       int idx = i + base;
1884       const VkViewport *vp = &viewports[i];
1885       get_viewport_xform(vp, state->viewports[idx].scale, state->viewports[idx].translate);
1886    }
1887    state->vp_dirty = true;
1888 }
1889 
handle_set_viewport(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1890 static void handle_set_viewport(struct vk_cmd_queue_entry *cmd,
1891                                 struct rendering_state *state)
1892 {
1893    set_viewport(cmd->u.set_viewport.first_viewport,
1894                 cmd->u.set_viewport.viewport_count,
1895                 cmd->u.set_viewport.viewports,
1896                 state);
1897 }
1898 
handle_set_viewport_with_count(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1899 static void handle_set_viewport_with_count(struct vk_cmd_queue_entry *cmd,
1900                                            struct rendering_state *state)
1901 {
1902    set_viewport(UINT32_MAX,
1903                 cmd->u.set_viewport_with_count_ext.viewport_count,
1904                 cmd->u.set_viewport_with_count_ext.viewports,
1905                 state);
1906 }
1907 
set_scissor(unsigned first_scissor,unsigned scissor_count,const VkRect2D * scissors,struct rendering_state * state)1908 static void set_scissor(unsigned first_scissor,
1909                         unsigned scissor_count,
1910                         const VkRect2D *scissors,
1911                         struct rendering_state *state)
1912 {
1913    int i;
1914    unsigned base = 0;
1915    if (first_scissor == UINT32_MAX)
1916       state->num_scissors = scissor_count;
1917    else
1918       base = first_scissor;
1919 
1920    for (i = 0; i < scissor_count; i++) {
1921       int idx = i + base;
1922       const VkRect2D *ss = &scissors[i];
1923       state->scissors[idx].minx = ss->offset.x;
1924       state->scissors[idx].miny = ss->offset.y;
1925       state->scissors[idx].maxx = ss->offset.x + ss->extent.width;
1926       state->scissors[idx].maxy = ss->offset.y + ss->extent.height;
1927    }
1928    state->scissor_dirty = true;
1929 }
1930 
handle_set_scissor(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1931 static void handle_set_scissor(struct vk_cmd_queue_entry *cmd,
1932                                struct rendering_state *state)
1933 {
1934    set_scissor(cmd->u.set_scissor.first_scissor,
1935                cmd->u.set_scissor.scissor_count,
1936                cmd->u.set_scissor.scissors,
1937                state);
1938 }
1939 
handle_set_scissor_with_count(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1940 static void handle_set_scissor_with_count(struct vk_cmd_queue_entry *cmd,
1941                                           struct rendering_state *state)
1942 {
1943    set_scissor(UINT32_MAX,
1944                cmd->u.set_scissor_with_count_ext.scissor_count,
1945                cmd->u.set_scissor_with_count_ext.scissors,
1946                state);
1947 }
1948 
handle_set_line_width(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1949 static void handle_set_line_width(struct vk_cmd_queue_entry *cmd,
1950                                   struct rendering_state *state)
1951 {
1952    state->rs_state.line_width = cmd->u.set_line_width.line_width;
1953    state->rs_dirty = true;
1954 }
1955 
handle_set_depth_bias(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1956 static void handle_set_depth_bias(struct vk_cmd_queue_entry *cmd,
1957                                   struct rendering_state *state)
1958 {
1959    state->depth_bias.offset_units = cmd->u.set_depth_bias.depth_bias_constant_factor;
1960    state->depth_bias.offset_scale = cmd->u.set_depth_bias.depth_bias_slope_factor;
1961    state->depth_bias.offset_clamp = cmd->u.set_depth_bias.depth_bias_clamp;
1962    state->rs_dirty = true;
1963 }
1964 
handle_set_blend_constants(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1965 static void handle_set_blend_constants(struct vk_cmd_queue_entry *cmd,
1966                                        struct rendering_state *state)
1967 {
1968    memcpy(state->blend_color.color, cmd->u.set_blend_constants.blend_constants, 4 * sizeof(float));
1969    state->blend_color_dirty = true;
1970 }
1971 
handle_set_depth_bounds(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1972 static void handle_set_depth_bounds(struct vk_cmd_queue_entry *cmd,
1973                                     struct rendering_state *state)
1974 {
1975    state->dsa_dirty |= !DOUBLE_EQ(state->dsa_state.depth_bounds_min, cmd->u.set_depth_bounds.min_depth_bounds);
1976    state->dsa_dirty |= !DOUBLE_EQ(state->dsa_state.depth_bounds_max, cmd->u.set_depth_bounds.max_depth_bounds);
1977    state->dsa_state.depth_bounds_min = cmd->u.set_depth_bounds.min_depth_bounds;
1978    state->dsa_state.depth_bounds_max = cmd->u.set_depth_bounds.max_depth_bounds;
1979 }
1980 
handle_set_stencil_compare_mask(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1981 static void handle_set_stencil_compare_mask(struct vk_cmd_queue_entry *cmd,
1982                                             struct rendering_state *state)
1983 {
1984    if (cmd->u.set_stencil_compare_mask.face_mask & VK_STENCIL_FACE_FRONT_BIT)
1985       state->dsa_state.stencil[0].valuemask = cmd->u.set_stencil_compare_mask.compare_mask;
1986    if (cmd->u.set_stencil_compare_mask.face_mask & VK_STENCIL_FACE_BACK_BIT)
1987       state->dsa_state.stencil[1].valuemask = cmd->u.set_stencil_compare_mask.compare_mask;
1988    state->dsa_dirty = true;
1989 }
1990 
handle_set_stencil_write_mask(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)1991 static void handle_set_stencil_write_mask(struct vk_cmd_queue_entry *cmd,
1992                                           struct rendering_state *state)
1993 {
1994    if (cmd->u.set_stencil_write_mask.face_mask & VK_STENCIL_FACE_FRONT_BIT)
1995       state->dsa_state.stencil[0].writemask = cmd->u.set_stencil_write_mask.write_mask;
1996    if (cmd->u.set_stencil_write_mask.face_mask & VK_STENCIL_FACE_BACK_BIT)
1997       state->dsa_state.stencil[1].writemask = cmd->u.set_stencil_write_mask.write_mask;
1998    state->dsa_dirty = true;
1999 }
2000 
handle_set_stencil_reference(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2001 static void handle_set_stencil_reference(struct vk_cmd_queue_entry *cmd,
2002                                          struct rendering_state *state)
2003 {
2004    if (cmd->u.set_stencil_reference.face_mask & VK_STENCIL_FACE_FRONT_BIT)
2005       state->stencil_ref.ref_value[0] = cmd->u.set_stencil_reference.reference;
2006    if (cmd->u.set_stencil_reference.face_mask & VK_STENCIL_FACE_BACK_BIT)
2007       state->stencil_ref.ref_value[1] = cmd->u.set_stencil_reference.reference;
2008    state->stencil_ref_dirty = true;
2009 }
2010 
2011 static void
copy_depth_rect(ubyte * dst,enum pipe_format dst_format,unsigned dst_stride,unsigned dst_x,unsigned dst_y,unsigned width,unsigned height,const ubyte * src,enum pipe_format src_format,int src_stride,unsigned src_x,unsigned src_y)2012 copy_depth_rect(ubyte * dst,
2013                 enum pipe_format dst_format,
2014                 unsigned dst_stride,
2015                 unsigned dst_x,
2016                 unsigned dst_y,
2017                 unsigned width,
2018                 unsigned height,
2019                 const ubyte * src,
2020                 enum pipe_format src_format,
2021                 int src_stride,
2022                 unsigned src_x,
2023                 unsigned src_y)
2024 {
2025    int src_stride_pos = src_stride < 0 ? -src_stride : src_stride;
2026    int src_blocksize = util_format_get_blocksize(src_format);
2027    int src_blockwidth = util_format_get_blockwidth(src_format);
2028    int src_blockheight = util_format_get_blockheight(src_format);
2029    int dst_blocksize = util_format_get_blocksize(dst_format);
2030    int dst_blockwidth = util_format_get_blockwidth(dst_format);
2031    int dst_blockheight = util_format_get_blockheight(dst_format);
2032 
2033    assert(src_blocksize > 0);
2034    assert(src_blockwidth > 0);
2035    assert(src_blockheight > 0);
2036 
2037    dst_x /= dst_blockwidth;
2038    dst_y /= dst_blockheight;
2039    width = (width + src_blockwidth - 1)/src_blockwidth;
2040    height = (height + src_blockheight - 1)/src_blockheight;
2041    src_x /= src_blockwidth;
2042    src_y /= src_blockheight;
2043 
2044    dst += dst_x * dst_blocksize;
2045    src += src_x * src_blocksize;
2046    dst += dst_y * dst_stride;
2047    src += src_y * src_stride_pos;
2048 
2049    if (dst_format == PIPE_FORMAT_S8_UINT) {
2050       if (src_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
2051          util_format_z32_float_s8x24_uint_unpack_s_8uint(dst, dst_stride,
2052                                                          src, src_stride,
2053                                                          width, height);
2054       } else if (src_format == PIPE_FORMAT_Z24_UNORM_S8_UINT) {
2055          util_format_z24_unorm_s8_uint_unpack_s_8uint(dst, dst_stride,
2056                                                       src, src_stride,
2057                                                       width, height);
2058       } else {
2059       }
2060    } else if (dst_format == PIPE_FORMAT_Z24X8_UNORM) {
2061       util_format_z24_unorm_s8_uint_unpack_z24(dst, dst_stride,
2062                                                src, src_stride,
2063                                                width, height);
2064    } else if (dst_format == PIPE_FORMAT_Z32_FLOAT) {
2065       if (src_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
2066          util_format_z32_float_s8x24_uint_unpack_z_float((float *)dst, dst_stride,
2067                                                          src, src_stride,
2068                                                          width, height);
2069       }
2070    } else if (dst_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
2071       if (src_format == PIPE_FORMAT_Z32_FLOAT)
2072          util_format_z32_float_s8x24_uint_pack_z_float(dst, dst_stride,
2073                                                        (float *)src, src_stride,
2074                                                        width, height);
2075       else if (src_format == PIPE_FORMAT_S8_UINT)
2076          util_format_z32_float_s8x24_uint_pack_s_8uint(dst, dst_stride,
2077                                                        src, src_stride,
2078                                                        width, height);
2079    } else if (dst_format == PIPE_FORMAT_Z24_UNORM_S8_UINT) {
2080       if (src_format == PIPE_FORMAT_S8_UINT)
2081          util_format_z24_unorm_s8_uint_pack_s_8uint(dst, dst_stride,
2082                                                     src, src_stride,
2083                                                     width, height);
2084       if (src_format == PIPE_FORMAT_Z24X8_UNORM)
2085          util_format_z24_unorm_s8_uint_pack_z24(dst, dst_stride,
2086                                                 src, src_stride,
2087                                                 width, height);
2088    }
2089 }
2090 
2091 static void
copy_depth_box(ubyte * dst,enum pipe_format dst_format,unsigned dst_stride,unsigned dst_slice_stride,unsigned dst_x,unsigned dst_y,unsigned dst_z,unsigned width,unsigned height,unsigned depth,const ubyte * src,enum pipe_format src_format,int src_stride,unsigned src_slice_stride,unsigned src_x,unsigned src_y,unsigned src_z)2092 copy_depth_box(ubyte *dst,
2093                enum pipe_format dst_format,
2094                unsigned dst_stride, unsigned dst_slice_stride,
2095                unsigned dst_x, unsigned dst_y, unsigned dst_z,
2096                unsigned width, unsigned height, unsigned depth,
2097                const ubyte * src,
2098                enum pipe_format src_format,
2099                int src_stride, unsigned src_slice_stride,
2100                unsigned src_x, unsigned src_y, unsigned src_z)
2101 {
2102    unsigned z;
2103    dst += dst_z * dst_slice_stride;
2104    src += src_z * src_slice_stride;
2105    for (z = 0; z < depth; ++z) {
2106       copy_depth_rect(dst,
2107                       dst_format,
2108                       dst_stride,
2109                       dst_x, dst_y,
2110                       width, height,
2111                       src,
2112                       src_format,
2113                       src_stride,
2114                       src_x, src_y);
2115 
2116       dst += dst_slice_stride;
2117       src += src_slice_stride;
2118    }
2119 }
2120 
handle_copy_image_to_buffer2_khr(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2121 static void handle_copy_image_to_buffer2_khr(struct vk_cmd_queue_entry *cmd,
2122                                              struct rendering_state *state)
2123 {
2124    int i;
2125    struct VkCopyImageToBufferInfo2KHR *copycmd = cmd->u.copy_image_to_buffer2_khr.copy_image_to_buffer_info;
2126    LVP_FROM_HANDLE(lvp_image, src_image, copycmd->srcImage);
2127    struct pipe_box box, dbox;
2128    struct pipe_transfer *src_t, *dst_t;
2129    ubyte *src_data, *dst_data;
2130 
2131    state->pctx->flush(state->pctx, NULL, 0);
2132 
2133    for (i = 0; i < copycmd->regionCount; i++) {
2134 
2135       box.x = copycmd->pRegions[i].imageOffset.x;
2136       box.y = copycmd->pRegions[i].imageOffset.y;
2137       box.z = src_image->vk.image_type == VK_IMAGE_TYPE_3D ? copycmd->pRegions[i].imageOffset.z : copycmd->pRegions[i].imageSubresource.baseArrayLayer;
2138       box.width = copycmd->pRegions[i].imageExtent.width;
2139       box.height = copycmd->pRegions[i].imageExtent.height;
2140       box.depth = src_image->vk.image_type == VK_IMAGE_TYPE_3D ? copycmd->pRegions[i].imageExtent.depth : copycmd->pRegions[i].imageSubresource.layerCount;
2141 
2142       src_data = state->pctx->texture_map(state->pctx,
2143                                            src_image->bo,
2144                                            copycmd->pRegions[i].imageSubresource.mipLevel,
2145                                            PIPE_MAP_READ,
2146                                            &box,
2147                                            &src_t);
2148 
2149       dbox.x = copycmd->pRegions[i].bufferOffset;
2150       dbox.y = 0;
2151       dbox.z = 0;
2152       dbox.width = lvp_buffer_from_handle(copycmd->dstBuffer)->bo->width0;
2153       dbox.height = 1;
2154       dbox.depth = 1;
2155       dst_data = state->pctx->buffer_map(state->pctx,
2156                                            lvp_buffer_from_handle(copycmd->dstBuffer)->bo,
2157                                            0,
2158                                            PIPE_MAP_WRITE,
2159                                            &dbox,
2160                                            &dst_t);
2161 
2162       enum pipe_format src_format = src_image->bo->format;
2163       enum pipe_format dst_format = src_format;
2164       if (util_format_is_depth_or_stencil(src_format)) {
2165          if (copycmd->pRegions[i].imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) {
2166             dst_format = util_format_get_depth_only(src_format);
2167          } else if (copycmd->pRegions[i].imageSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {
2168             dst_format = PIPE_FORMAT_S8_UINT;
2169          }
2170       }
2171 
2172       unsigned buffer_row_len = util_format_get_stride(dst_format, copycmd->pRegions[i].bufferRowLength);
2173       if (buffer_row_len == 0)
2174          buffer_row_len = util_format_get_stride(dst_format, copycmd->pRegions[i].imageExtent.width);
2175       unsigned buffer_image_height = copycmd->pRegions[i].bufferImageHeight;
2176       if (buffer_image_height == 0)
2177          buffer_image_height = copycmd->pRegions[i].imageExtent.height;
2178 
2179       unsigned img_stride = util_format_get_2d_size(dst_format, buffer_row_len, buffer_image_height);
2180       if (src_format != dst_format) {
2181          copy_depth_box(dst_data, dst_format,
2182                         buffer_row_len, img_stride,
2183                         0, 0, 0,
2184                         copycmd->pRegions[i].imageExtent.width,
2185                         copycmd->pRegions[i].imageExtent.height,
2186                         box.depth,
2187                         src_data, src_format, src_t->stride, src_t->layer_stride, 0, 0, 0);
2188       } else {
2189          util_copy_box((ubyte *)dst_data, src_format,
2190                        buffer_row_len, img_stride,
2191                        0, 0, 0,
2192                        copycmd->pRegions[i].imageExtent.width,
2193                        copycmd->pRegions[i].imageExtent.height,
2194                        box.depth,
2195                        src_data, src_t->stride, src_t->layer_stride, 0, 0, 0);
2196       }
2197       state->pctx->texture_unmap(state->pctx, src_t);
2198       state->pctx->buffer_unmap(state->pctx, dst_t);
2199    }
2200 }
2201 
handle_copy_buffer_to_image(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2202 static void handle_copy_buffer_to_image(struct vk_cmd_queue_entry *cmd,
2203                                         struct rendering_state *state)
2204 {
2205    int i;
2206    struct VkCopyBufferToImageInfo2KHR *copycmd = cmd->u.copy_buffer_to_image2_khr.copy_buffer_to_image_info;
2207    LVP_FROM_HANDLE(lvp_image, dst_image, copycmd->dstImage);
2208    struct pipe_box box, sbox;
2209    struct pipe_transfer *src_t, *dst_t;
2210    void *src_data, *dst_data;
2211 
2212    state->pctx->flush(state->pctx, NULL, 0);
2213 
2214    for (i = 0; i < copycmd->regionCount; i++) {
2215 
2216       sbox.x = copycmd->pRegions[i].bufferOffset;
2217       sbox.y = 0;
2218       sbox.z = 0;
2219       sbox.width = lvp_buffer_from_handle(copycmd->srcBuffer)->bo->width0;
2220       sbox.height = 1;
2221       sbox.depth = 1;
2222       src_data = state->pctx->buffer_map(state->pctx,
2223                                            lvp_buffer_from_handle(copycmd->srcBuffer)->bo,
2224                                            0,
2225                                            PIPE_MAP_READ,
2226                                            &sbox,
2227                                            &src_t);
2228 
2229 
2230       box.x = copycmd->pRegions[i].imageOffset.x;
2231       box.y = copycmd->pRegions[i].imageOffset.y;
2232       box.z = dst_image->vk.image_type == VK_IMAGE_TYPE_3D ? copycmd->pRegions[i].imageOffset.z : copycmd->pRegions[i].imageSubresource.baseArrayLayer;
2233       box.width = copycmd->pRegions[i].imageExtent.width;
2234       box.height = copycmd->pRegions[i].imageExtent.height;
2235       box.depth = dst_image->vk.image_type == VK_IMAGE_TYPE_3D ? copycmd->pRegions[i].imageExtent.depth : copycmd->pRegions[i].imageSubresource.layerCount;
2236 
2237       dst_data = state->pctx->texture_map(state->pctx,
2238                                            dst_image->bo,
2239                                            copycmd->pRegions[i].imageSubresource.mipLevel,
2240                                            PIPE_MAP_WRITE,
2241                                            &box,
2242                                            &dst_t);
2243 
2244       enum pipe_format dst_format = dst_image->bo->format;
2245       enum pipe_format src_format = dst_format;
2246       if (util_format_is_depth_or_stencil(dst_format)) {
2247          if (copycmd->pRegions[i].imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) {
2248             src_format = util_format_get_depth_only(dst_image->bo->format);
2249          } else if (copycmd->pRegions[i].imageSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {
2250             src_format = PIPE_FORMAT_S8_UINT;
2251          }
2252       }
2253 
2254       unsigned buffer_row_len = util_format_get_stride(src_format, copycmd->pRegions[i].bufferRowLength);
2255       if (buffer_row_len == 0)
2256          buffer_row_len = util_format_get_stride(src_format, copycmd->pRegions[i].imageExtent.width);
2257       unsigned buffer_image_height = copycmd->pRegions[i].bufferImageHeight;
2258       if (buffer_image_height == 0)
2259          buffer_image_height = copycmd->pRegions[i].imageExtent.height;
2260 
2261       unsigned img_stride = util_format_get_2d_size(src_format, buffer_row_len, buffer_image_height);
2262       if (src_format != dst_format) {
2263          copy_depth_box(dst_data, dst_format,
2264                         dst_t->stride, dst_t->layer_stride,
2265                         0, 0, 0,
2266                         copycmd->pRegions[i].imageExtent.width,
2267                         copycmd->pRegions[i].imageExtent.height,
2268                         box.depth,
2269                         src_data, src_format,
2270                         buffer_row_len, img_stride, 0, 0, 0);
2271       } else {
2272          util_copy_box(dst_data, dst_format,
2273                        dst_t->stride, dst_t->layer_stride,
2274                        0, 0, 0,
2275                        copycmd->pRegions[i].imageExtent.width,
2276                        copycmd->pRegions[i].imageExtent.height,
2277                        box.depth,
2278                        src_data,
2279                        buffer_row_len, img_stride, 0, 0, 0);
2280       }
2281       state->pctx->buffer_unmap(state->pctx, src_t);
2282       state->pctx->texture_unmap(state->pctx, dst_t);
2283    }
2284 }
2285 
handle_copy_image(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2286 static void handle_copy_image(struct vk_cmd_queue_entry *cmd,
2287                               struct rendering_state *state)
2288 {
2289    int i;
2290    struct VkCopyImageInfo2KHR *copycmd = cmd->u.copy_image2_khr.copy_image_info;
2291    LVP_FROM_HANDLE(lvp_image, src_image, copycmd->srcImage);
2292    LVP_FROM_HANDLE(lvp_image, dst_image, copycmd->dstImage);
2293 
2294    state->pctx->flush(state->pctx, NULL, 0);
2295 
2296    for (i = 0; i < copycmd->regionCount; i++) {
2297       struct pipe_box src_box;
2298       src_box.x = copycmd->pRegions[i].srcOffset.x;
2299       src_box.y = copycmd->pRegions[i].srcOffset.y;
2300       src_box.width = copycmd->pRegions[i].extent.width;
2301       src_box.height = copycmd->pRegions[i].extent.height;
2302       if (src_image->bo->target == PIPE_TEXTURE_3D) {
2303          src_box.depth = copycmd->pRegions[i].extent.depth;
2304          src_box.z = copycmd->pRegions[i].srcOffset.z;
2305       } else {
2306          src_box.depth = copycmd->pRegions[i].srcSubresource.layerCount;
2307          src_box.z = copycmd->pRegions[i].srcSubresource.baseArrayLayer;
2308       }
2309 
2310       unsigned dstz = dst_image->bo->target == PIPE_TEXTURE_3D ?
2311                       copycmd->pRegions[i].dstOffset.z :
2312                       copycmd->pRegions[i].dstSubresource.baseArrayLayer;
2313       state->pctx->resource_copy_region(state->pctx, dst_image->bo,
2314                                         copycmd->pRegions[i].dstSubresource.mipLevel,
2315                                         copycmd->pRegions[i].dstOffset.x,
2316                                         copycmd->pRegions[i].dstOffset.y,
2317                                         dstz,
2318                                         src_image->bo,
2319                                         copycmd->pRegions[i].srcSubresource.mipLevel,
2320                                         &src_box);
2321    }
2322 }
2323 
handle_copy_buffer(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2324 static void handle_copy_buffer(struct vk_cmd_queue_entry *cmd,
2325                                struct rendering_state *state)
2326 {
2327    int i;
2328    struct VkCopyBufferInfo2KHR *copycmd = cmd->u.copy_buffer2_khr.copy_buffer_info;
2329 
2330    for (i = 0; i < copycmd->regionCount; i++) {
2331       struct pipe_box box = { 0 };
2332       u_box_1d(copycmd->pRegions[i].srcOffset, copycmd->pRegions[i].size, &box);
2333       state->pctx->resource_copy_region(state->pctx, lvp_buffer_from_handle(copycmd->dstBuffer)->bo, 0,
2334                                         copycmd->pRegions[i].dstOffset, 0, 0,
2335                                         lvp_buffer_from_handle(copycmd->srcBuffer)->bo, 0, &box);
2336    }
2337 }
2338 
handle_blit_image(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2339 static void handle_blit_image(struct vk_cmd_queue_entry *cmd,
2340                               struct rendering_state *state)
2341 {
2342    int i;
2343    struct VkBlitImageInfo2KHR *blitcmd = cmd->u.blit_image2_khr.blit_image_info;
2344    LVP_FROM_HANDLE(lvp_image, src_image, blitcmd->srcImage);
2345    LVP_FROM_HANDLE(lvp_image, dst_image, blitcmd->dstImage);
2346    struct pipe_blit_info info;
2347 
2348    memset(&info, 0, sizeof(info));
2349 
2350    state->pctx->flush(state->pctx, NULL, 0);
2351    info.src.resource = src_image->bo;
2352    info.dst.resource = dst_image->bo;
2353    info.src.format = src_image->bo->format;
2354    info.dst.format = dst_image->bo->format;
2355    info.mask = util_format_is_depth_or_stencil(info.src.format) ? PIPE_MASK_ZS : PIPE_MASK_RGBA;
2356    info.filter = blitcmd->filter == VK_FILTER_NEAREST ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR;
2357    for (i = 0; i < blitcmd->regionCount; i++) {
2358       int srcX0, srcX1, srcY0, srcY1, srcZ0, srcZ1;
2359       unsigned dstX0, dstX1, dstY0, dstY1, dstZ0, dstZ1;
2360 
2361       srcX0 = blitcmd->pRegions[i].srcOffsets[0].x;
2362       srcX1 = blitcmd->pRegions[i].srcOffsets[1].x;
2363       srcY0 = blitcmd->pRegions[i].srcOffsets[0].y;
2364       srcY1 = blitcmd->pRegions[i].srcOffsets[1].y;
2365       srcZ0 = blitcmd->pRegions[i].srcOffsets[0].z;
2366       srcZ1 = blitcmd->pRegions[i].srcOffsets[1].z;
2367 
2368       dstX0 = blitcmd->pRegions[i].dstOffsets[0].x;
2369       dstX1 = blitcmd->pRegions[i].dstOffsets[1].x;
2370       dstY0 = blitcmd->pRegions[i].dstOffsets[0].y;
2371       dstY1 = blitcmd->pRegions[i].dstOffsets[1].y;
2372       dstZ0 = blitcmd->pRegions[i].dstOffsets[0].z;
2373       dstZ1 = blitcmd->pRegions[i].dstOffsets[1].z;
2374 
2375       if (dstX0 < dstX1) {
2376          info.dst.box.x = dstX0;
2377          info.src.box.x = srcX0;
2378          info.dst.box.width = dstX1 - dstX0;
2379          info.src.box.width = srcX1 - srcX0;
2380       } else {
2381          info.dst.box.x = dstX1;
2382          info.src.box.x = srcX1;
2383          info.dst.box.width = dstX0 - dstX1;
2384          info.src.box.width = srcX0 - srcX1;
2385       }
2386 
2387       if (dstY0 < dstY1) {
2388          info.dst.box.y = dstY0;
2389          info.src.box.y = srcY0;
2390          info.dst.box.height = dstY1 - dstY0;
2391          info.src.box.height = srcY1 - srcY0;
2392       } else {
2393          info.dst.box.y = dstY1;
2394          info.src.box.y = srcY1;
2395          info.dst.box.height = dstY0 - dstY1;
2396          info.src.box.height = srcY0 - srcY1;
2397       }
2398 
2399       assert_subresource_layers(info.src.resource, &blitcmd->pRegions[i].srcSubresource, blitcmd->pRegions[i].srcOffsets);
2400       assert_subresource_layers(info.dst.resource, &blitcmd->pRegions[i].dstSubresource, blitcmd->pRegions[i].dstOffsets);
2401       if (src_image->bo->target == PIPE_TEXTURE_3D) {
2402          if (dstZ0 < dstZ1) {
2403             info.dst.box.z = dstZ0;
2404             info.src.box.z = srcZ0;
2405             info.dst.box.depth = dstZ1 - dstZ0;
2406             info.src.box.depth = srcZ1 - srcZ0;
2407          } else {
2408             info.dst.box.z = dstZ1;
2409             info.src.box.z = srcZ1;
2410             info.dst.box.depth = dstZ0 - dstZ1;
2411             info.src.box.depth = srcZ0 - srcZ1;
2412          }
2413       } else {
2414          info.src.box.z = blitcmd->pRegions[i].srcSubresource.baseArrayLayer;
2415          info.dst.box.z = blitcmd->pRegions[i].dstSubresource.baseArrayLayer;
2416          info.src.box.depth = blitcmd->pRegions[i].srcSubresource.layerCount;
2417          info.dst.box.depth = blitcmd->pRegions[i].dstSubresource.layerCount;
2418       }
2419 
2420       info.src.level = blitcmd->pRegions[i].srcSubresource.mipLevel;
2421       info.dst.level = blitcmd->pRegions[i].dstSubresource.mipLevel;
2422       state->pctx->blit(state->pctx, &info);
2423    }
2424 }
2425 
handle_fill_buffer(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2426 static void handle_fill_buffer(struct vk_cmd_queue_entry *cmd,
2427                                struct rendering_state *state)
2428 {
2429    struct vk_cmd_fill_buffer *fillcmd = &cmd->u.fill_buffer;
2430    uint32_t size = fillcmd->size;
2431 
2432    if (fillcmd->size == VK_WHOLE_SIZE) {
2433       size = lvp_buffer_from_handle(fillcmd->dst_buffer)->bo->width0 - fillcmd->dst_offset;
2434       size = ROUND_DOWN_TO(size, 4);
2435    }
2436 
2437    state->pctx->clear_buffer(state->pctx,
2438                              lvp_buffer_from_handle(fillcmd->dst_buffer)->bo,
2439                              fillcmd->dst_offset,
2440                              size,
2441                              &fillcmd->data,
2442                              4);
2443 }
2444 
handle_update_buffer(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2445 static void handle_update_buffer(struct vk_cmd_queue_entry *cmd,
2446                                  struct rendering_state *state)
2447 {
2448    struct vk_cmd_update_buffer *updcmd = &cmd->u.update_buffer;
2449    uint32_t *dst;
2450    struct pipe_transfer *dst_t;
2451    struct pipe_box box;
2452 
2453    u_box_1d(updcmd->dst_offset, updcmd->data_size, &box);
2454    dst = state->pctx->buffer_map(state->pctx,
2455                                    lvp_buffer_from_handle(updcmd->dst_buffer)->bo,
2456                                    0,
2457                                    PIPE_MAP_WRITE,
2458                                    &box,
2459                                    &dst_t);
2460 
2461    memcpy(dst, updcmd->data, updcmd->data_size);
2462    state->pctx->buffer_unmap(state->pctx, dst_t);
2463 }
2464 
handle_draw_indexed(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2465 static void handle_draw_indexed(struct vk_cmd_queue_entry *cmd,
2466                                 struct rendering_state *state)
2467 {
2468    const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
2469    struct pipe_draw_start_count_bias draw = {0};
2470 
2471    state->info.index_bounds_valid = false;
2472    state->info.min_index = 0;
2473    state->info.max_index = ~0;
2474    state->info.index_size = state->index_size;
2475    state->info.index.resource = state->index_buffer;
2476    state->info.start_instance = cmd->u.draw_indexed.first_instance;
2477    state->info.instance_count = cmd->u.draw_indexed.instance_count;
2478    state->info.view_mask = subpass->view_mask;
2479 
2480    if (state->info.primitive_restart)
2481       state->info.restart_index = util_prim_restart_index_from_size(state->info.index_size);
2482 
2483    draw.count = cmd->u.draw_indexed.index_count;
2484    draw.index_bias = cmd->u.draw_indexed.vertex_offset;
2485    /* TODO: avoid calculating multiple times if cmdbuf is submitted again */
2486    draw.start = (state->index_offset / state->index_size) + cmd->u.draw_indexed.first_index;
2487 
2488    state->info.index_bias_varies = !cmd->u.draw_indexed.vertex_offset;
2489    state->pctx->set_patch_vertices(state->pctx, state->patch_vertices);
2490    state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, &draw, 1);
2491 }
2492 
handle_draw_multi_indexed(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2493 static void handle_draw_multi_indexed(struct vk_cmd_queue_entry *cmd,
2494                                       struct rendering_state *state)
2495 {
2496    const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
2497    struct pipe_draw_start_count_bias *draws = calloc(cmd->u.draw_multi_indexed_ext.draw_count,
2498                                                      sizeof(*draws));
2499 
2500    state->info.index_bounds_valid = false;
2501    state->info.min_index = 0;
2502    state->info.max_index = ~0;
2503    state->info.index_size = state->index_size;
2504    state->info.index.resource = state->index_buffer;
2505    state->info.start_instance = cmd->u.draw_multi_indexed_ext.first_instance;
2506    state->info.instance_count = cmd->u.draw_multi_indexed_ext.instance_count;
2507    state->info.view_mask = subpass->view_mask;
2508    if (cmd->u.draw_multi_indexed_ext.draw_count > 1)
2509       state->info.increment_draw_id = true;
2510 
2511    if (state->info.primitive_restart)
2512       state->info.restart_index = util_prim_restart_index_from_size(state->info.index_size);
2513 
2514    unsigned size = cmd->u.draw_multi_indexed_ext.draw_count * sizeof(struct pipe_draw_start_count_bias);
2515    memcpy(draws, cmd->u.draw_multi_indexed_ext.index_info, size);
2516 
2517    /* only the first member is read if index_bias_varies is true */
2518    if (cmd->u.draw_multi_indexed_ext.draw_count &&
2519        cmd->u.draw_multi_indexed_ext.vertex_offset)
2520       draws[0].index_bias = *cmd->u.draw_multi_indexed_ext.vertex_offset;
2521 
2522    /* TODO: avoid calculating multiple times if cmdbuf is submitted again */
2523    for (unsigned i = 0; i < cmd->u.draw_multi_indexed_ext.draw_count; i++)
2524       draws[i].start = (state->index_offset / state->index_size) + draws[i].start;
2525 
2526    state->info.index_bias_varies = !cmd->u.draw_multi_indexed_ext.vertex_offset;
2527    state->pctx->set_patch_vertices(state->pctx, state->patch_vertices);
2528 
2529    if (cmd->u.draw_multi_indexed_ext.draw_count)
2530       state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, draws, cmd->u.draw_multi_indexed_ext.draw_count);
2531 
2532    free(draws);
2533 }
2534 
handle_draw_indirect(struct vk_cmd_queue_entry * cmd,struct rendering_state * state,bool indexed)2535 static void handle_draw_indirect(struct vk_cmd_queue_entry *cmd,
2536                                  struct rendering_state *state, bool indexed)
2537 {
2538    const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
2539    struct pipe_draw_start_count_bias draw = {0};
2540    if (indexed) {
2541       state->info.index_bounds_valid = false;
2542       state->info.index_size = state->index_size;
2543       state->info.index.resource = state->index_buffer;
2544       state->info.max_index = ~0;
2545       if (state->info.primitive_restart)
2546          state->info.restart_index = util_prim_restart_index_from_size(state->info.index_size);
2547    } else
2548       state->info.index_size = 0;
2549    state->indirect_info.offset = cmd->u.draw_indirect.offset;
2550    state->indirect_info.stride = cmd->u.draw_indirect.stride;
2551    state->indirect_info.draw_count = cmd->u.draw_indirect.draw_count;
2552    state->indirect_info.buffer = lvp_buffer_from_handle(cmd->u.draw_indirect.buffer)->bo;
2553    state->info.view_mask = subpass->view_mask;
2554 
2555    state->pctx->set_patch_vertices(state->pctx, state->patch_vertices);
2556    state->pctx->draw_vbo(state->pctx, &state->info, 0, &state->indirect_info, &draw, 1);
2557 }
2558 
handle_index_buffer(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2559 static void handle_index_buffer(struct vk_cmd_queue_entry *cmd,
2560                                 struct rendering_state *state)
2561 {
2562    struct vk_cmd_bind_index_buffer *ib = &cmd->u.bind_index_buffer;
2563    switch (ib->index_type) {
2564    case VK_INDEX_TYPE_UINT8_EXT:
2565       state->index_size = 1;
2566       break;
2567    case VK_INDEX_TYPE_UINT16:
2568       state->index_size = 2;
2569       break;
2570    case VK_INDEX_TYPE_UINT32:
2571       state->index_size = 4;
2572       break;
2573    default:
2574       break;
2575    }
2576    state->index_offset = ib->offset;
2577    if (ib->buffer)
2578       state->index_buffer = lvp_buffer_from_handle(ib->buffer)->bo;
2579    else
2580       state->index_buffer = NULL;
2581 
2582    state->ib_dirty = true;
2583 }
2584 
handle_dispatch(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2585 static void handle_dispatch(struct vk_cmd_queue_entry *cmd,
2586                             struct rendering_state *state)
2587 {
2588    state->dispatch_info.grid[0] = cmd->u.dispatch.group_count_x;
2589    state->dispatch_info.grid[1] = cmd->u.dispatch.group_count_y;
2590    state->dispatch_info.grid[2] = cmd->u.dispatch.group_count_z;
2591    state->dispatch_info.grid_base[0] = 0;
2592    state->dispatch_info.grid_base[1] = 0;
2593    state->dispatch_info.grid_base[2] = 0;
2594    state->dispatch_info.indirect = NULL;
2595    state->pctx->launch_grid(state->pctx, &state->dispatch_info);
2596 }
2597 
handle_dispatch_base(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2598 static void handle_dispatch_base(struct vk_cmd_queue_entry *cmd,
2599                                  struct rendering_state *state)
2600 {
2601    state->dispatch_info.grid[0] = cmd->u.dispatch_base.group_count_x;
2602    state->dispatch_info.grid[1] = cmd->u.dispatch_base.group_count_y;
2603    state->dispatch_info.grid[2] = cmd->u.dispatch_base.group_count_z;
2604    state->dispatch_info.grid_base[0] = cmd->u.dispatch_base.base_group_x;
2605    state->dispatch_info.grid_base[1] = cmd->u.dispatch_base.base_group_y;
2606    state->dispatch_info.grid_base[2] = cmd->u.dispatch_base.base_group_z;
2607    state->dispatch_info.indirect = NULL;
2608    state->pctx->launch_grid(state->pctx, &state->dispatch_info);
2609 }
2610 
handle_dispatch_indirect(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2611 static void handle_dispatch_indirect(struct vk_cmd_queue_entry *cmd,
2612                                      struct rendering_state *state)
2613 {
2614    state->dispatch_info.indirect = lvp_buffer_from_handle(cmd->u.dispatch_indirect.buffer)->bo;
2615    state->dispatch_info.indirect_offset = cmd->u.dispatch_indirect.offset;
2616    state->pctx->launch_grid(state->pctx, &state->dispatch_info);
2617 }
2618 
handle_push_constants(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2619 static void handle_push_constants(struct vk_cmd_queue_entry *cmd,
2620                                   struct rendering_state *state)
2621 {
2622    memcpy(state->push_constants + cmd->u.push_constants.offset, cmd->u.push_constants.values, cmd->u.push_constants.size);
2623 
2624    state->pc_buffer[PIPE_SHADER_VERTEX].buffer_size = 128 * 4;
2625    state->pc_buffer[PIPE_SHADER_VERTEX].buffer_offset = 0;
2626    state->pc_buffer[PIPE_SHADER_VERTEX].user_buffer = state->push_constants;
2627    state->pcbuf_dirty[PIPE_SHADER_VERTEX] = true;
2628    state->pc_buffer[PIPE_SHADER_FRAGMENT].buffer_size = 128 * 4;
2629    state->pc_buffer[PIPE_SHADER_FRAGMENT].buffer_offset = 0;
2630    state->pc_buffer[PIPE_SHADER_FRAGMENT].user_buffer = state->push_constants;
2631    state->pcbuf_dirty[PIPE_SHADER_FRAGMENT] = true;
2632    state->pc_buffer[PIPE_SHADER_GEOMETRY].buffer_size = 128 * 4;
2633    state->pc_buffer[PIPE_SHADER_GEOMETRY].buffer_offset = 0;
2634    state->pc_buffer[PIPE_SHADER_GEOMETRY].user_buffer = state->push_constants;
2635    state->pcbuf_dirty[PIPE_SHADER_GEOMETRY] = true;
2636    state->pc_buffer[PIPE_SHADER_TESS_CTRL].buffer_size = 128 * 4;
2637    state->pc_buffer[PIPE_SHADER_TESS_CTRL].buffer_offset = 0;
2638    state->pc_buffer[PIPE_SHADER_TESS_CTRL].user_buffer = state->push_constants;
2639    state->pcbuf_dirty[PIPE_SHADER_TESS_CTRL] = true;
2640    state->pc_buffer[PIPE_SHADER_TESS_EVAL].buffer_size = 128 * 4;
2641    state->pc_buffer[PIPE_SHADER_TESS_EVAL].buffer_offset = 0;
2642    state->pc_buffer[PIPE_SHADER_TESS_EVAL].user_buffer = state->push_constants;
2643    state->pcbuf_dirty[PIPE_SHADER_TESS_EVAL] = true;
2644    state->pc_buffer[PIPE_SHADER_COMPUTE].buffer_size = 128 * 4;
2645    state->pc_buffer[PIPE_SHADER_COMPUTE].buffer_offset = 0;
2646    state->pc_buffer[PIPE_SHADER_COMPUTE].user_buffer = state->push_constants;
2647    state->pcbuf_dirty[PIPE_SHADER_COMPUTE] = true;
2648 }
2649 
2650 static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer,
2651                                    struct rendering_state *state);
2652 
handle_execute_commands(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2653 static void handle_execute_commands(struct vk_cmd_queue_entry *cmd,
2654                                     struct rendering_state *state)
2655 {
2656    for (unsigned i = 0; i < cmd->u.execute_commands.command_buffer_count; i++) {
2657       LVP_FROM_HANDLE(lvp_cmd_buffer, secondary_buf, cmd->u.execute_commands.command_buffers[i]);
2658       lvp_execute_cmd_buffer(secondary_buf, state);
2659    }
2660 }
2661 
handle_event_set(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2662 static void handle_event_set(struct vk_cmd_queue_entry *cmd,
2663                              struct rendering_state *state)
2664 {
2665    LVP_FROM_HANDLE(lvp_event, event, cmd->u.set_event.event);
2666 
2667    if (cmd->u.reset_event.stage_mask == VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
2668       state->pctx->flush(state->pctx, NULL, 0);
2669    event->event_storage = 1;
2670 }
2671 
handle_event_reset(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2672 static void handle_event_reset(struct vk_cmd_queue_entry *cmd,
2673                                struct rendering_state *state)
2674 {
2675    LVP_FROM_HANDLE(lvp_event, event, cmd->u.reset_event.event);
2676 
2677    if (cmd->u.reset_event.stage_mask == VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
2678       state->pctx->flush(state->pctx, NULL, 0);
2679    event->event_storage = 0;
2680 }
2681 
handle_wait_events(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2682 static void handle_wait_events(struct vk_cmd_queue_entry *cmd,
2683                                struct rendering_state *state)
2684 {
2685    for (unsigned i = 0; i < cmd->u.wait_events.event_count; i++) {
2686       LVP_FROM_HANDLE(lvp_event, event, cmd->u.wait_events.events[i]);
2687 
2688       while (event->event_storage != true);
2689    }
2690 }
2691 
handle_pipeline_barrier(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2692 static void handle_pipeline_barrier(struct vk_cmd_queue_entry *cmd,
2693                                     struct rendering_state *state)
2694 {
2695    /* why hello nail, I'm a hammer. - TODO */
2696    state->pctx->flush(state->pctx, NULL, 0);
2697 }
2698 
handle_begin_query(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2699 static void handle_begin_query(struct vk_cmd_queue_entry *cmd,
2700                                struct rendering_state *state)
2701 {
2702    struct vk_cmd_begin_query *qcmd = &cmd->u.begin_query;
2703    LVP_FROM_HANDLE(lvp_query_pool, pool, qcmd->query_pool);
2704 
2705    if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS &&
2706        pool->pipeline_stats & VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT)
2707       emit_compute_state(state);
2708 
2709    emit_state(state);
2710 
2711    if (!pool->queries[qcmd->query]) {
2712       enum pipe_query_type qtype = pool->base_type;
2713       pool->queries[qcmd->query] = state->pctx->create_query(state->pctx,
2714                                                              qtype, 0);
2715    }
2716 
2717    state->pctx->begin_query(state->pctx, pool->queries[qcmd->query]);
2718 }
2719 
handle_end_query(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2720 static void handle_end_query(struct vk_cmd_queue_entry *cmd,
2721                              struct rendering_state *state)
2722 {
2723    struct vk_cmd_end_query *qcmd = &cmd->u.end_query;
2724    LVP_FROM_HANDLE(lvp_query_pool, pool, qcmd->query_pool);
2725    assert(pool->queries[qcmd->query]);
2726 
2727    state->pctx->end_query(state->pctx, pool->queries[qcmd->query]);
2728 }
2729 
2730 
handle_begin_query_indexed_ext(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2731 static void handle_begin_query_indexed_ext(struct vk_cmd_queue_entry *cmd,
2732                                            struct rendering_state *state)
2733 {
2734    struct vk_cmd_begin_query_indexed_ext *qcmd = &cmd->u.begin_query_indexed_ext;
2735    LVP_FROM_HANDLE(lvp_query_pool, pool, qcmd->query_pool);
2736 
2737    if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS &&
2738        pool->pipeline_stats & VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT)
2739       emit_compute_state(state);
2740 
2741    emit_state(state);
2742 
2743    if (!pool->queries[qcmd->query]) {
2744       enum pipe_query_type qtype = pool->base_type;
2745       pool->queries[qcmd->query] = state->pctx->create_query(state->pctx,
2746                                                              qtype, qcmd->index);
2747    }
2748 
2749    state->pctx->begin_query(state->pctx, pool->queries[qcmd->query]);
2750 }
2751 
handle_end_query_indexed_ext(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2752 static void handle_end_query_indexed_ext(struct vk_cmd_queue_entry *cmd,
2753                                          struct rendering_state *state)
2754 {
2755    struct vk_cmd_end_query_indexed_ext *qcmd = &cmd->u.end_query_indexed_ext;
2756    LVP_FROM_HANDLE(lvp_query_pool, pool, qcmd->query_pool);
2757    assert(pool->queries[qcmd->query]);
2758 
2759    state->pctx->end_query(state->pctx, pool->queries[qcmd->query]);
2760 }
2761 
handle_reset_query_pool(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2762 static void handle_reset_query_pool(struct vk_cmd_queue_entry *cmd,
2763                                     struct rendering_state *state)
2764 {
2765    struct vk_cmd_reset_query_pool *qcmd = &cmd->u.reset_query_pool;
2766    LVP_FROM_HANDLE(lvp_query_pool, pool, qcmd->query_pool);
2767    for (unsigned i = qcmd->first_query; i < qcmd->first_query + qcmd->query_count; i++) {
2768       if (pool->queries[i]) {
2769          state->pctx->destroy_query(state->pctx, pool->queries[i]);
2770          pool->queries[i] = NULL;
2771       }
2772    }
2773 }
2774 
handle_write_timestamp(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2775 static void handle_write_timestamp(struct vk_cmd_queue_entry *cmd,
2776                                    struct rendering_state *state)
2777 {
2778    struct vk_cmd_write_timestamp *qcmd = &cmd->u.write_timestamp;
2779    LVP_FROM_HANDLE(lvp_query_pool, pool, qcmd->query_pool);
2780    if (!pool->queries[qcmd->query]) {
2781       pool->queries[qcmd->query] = state->pctx->create_query(state->pctx,
2782                                                              PIPE_QUERY_TIMESTAMP, 0);
2783    }
2784 
2785    if (!(qcmd->pipeline_stage == VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT))
2786       state->pctx->flush(state->pctx, NULL, 0);
2787    state->pctx->end_query(state->pctx, pool->queries[qcmd->query]);
2788 
2789 }
2790 
handle_copy_query_pool_results(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2791 static void handle_copy_query_pool_results(struct vk_cmd_queue_entry *cmd,
2792                                            struct rendering_state *state)
2793 {
2794    struct vk_cmd_copy_query_pool_results *copycmd = &cmd->u.copy_query_pool_results;
2795    LVP_FROM_HANDLE(lvp_query_pool, pool, copycmd->query_pool);
2796 
2797    for (unsigned i = copycmd->first_query; i < copycmd->first_query + copycmd->query_count; i++) {
2798       unsigned offset = copycmd->dst_offset + lvp_buffer_from_handle(copycmd->dst_buffer)->offset + (copycmd->stride * (i - copycmd->first_query));
2799       if (pool->queries[i]) {
2800          if (copycmd->flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)
2801             state->pctx->get_query_result_resource(state->pctx,
2802                                                    pool->queries[i],
2803                                                    copycmd->flags & VK_QUERY_RESULT_WAIT_BIT,
2804                                                    copycmd->flags & VK_QUERY_RESULT_64_BIT ? PIPE_QUERY_TYPE_U64 : PIPE_QUERY_TYPE_U32,
2805                                                    -1,
2806                                                    lvp_buffer_from_handle(copycmd->dst_buffer)->bo,
2807                                                    offset + (copycmd->flags & VK_QUERY_RESULT_64_BIT ? 8 : 4));
2808          if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS) {
2809             unsigned num_results = 0;
2810             unsigned result_size = copycmd->flags & VK_QUERY_RESULT_64_BIT ? 8 : 4;
2811             u_foreach_bit(bit, pool->pipeline_stats)
2812                state->pctx->get_query_result_resource(state->pctx,
2813                                                       pool->queries[i],
2814                                                       copycmd->flags & VK_QUERY_RESULT_WAIT_BIT,
2815                                                       copycmd->flags & VK_QUERY_RESULT_64_BIT ? PIPE_QUERY_TYPE_U64 : PIPE_QUERY_TYPE_U32,
2816                                                       bit,
2817                                                       lvp_buffer_from_handle(copycmd->dst_buffer)->bo,
2818                                                       offset + num_results++ * result_size);
2819          } else {
2820             state->pctx->get_query_result_resource(state->pctx,
2821                                                    pool->queries[i],
2822                                                    copycmd->flags & VK_QUERY_RESULT_WAIT_BIT,
2823                                                    copycmd->flags & VK_QUERY_RESULT_64_BIT ? PIPE_QUERY_TYPE_U64 : PIPE_QUERY_TYPE_U32,
2824                                                    0,
2825                                                    lvp_buffer_from_handle(copycmd->dst_buffer)->bo,
2826                                                    offset);
2827          }
2828       } else {
2829          /* if no queries emitted yet, just reset the buffer to 0 so avail is reported correctly */
2830          if (copycmd->flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) {
2831             struct pipe_transfer *src_t;
2832             uint32_t *map;
2833 
2834             struct pipe_box box = {0};
2835             box.x = offset;
2836             box.width = copycmd->stride;
2837             box.height = 1;
2838             box.depth = 1;
2839             map = state->pctx->buffer_map(state->pctx,
2840                                             lvp_buffer_from_handle(copycmd->dst_buffer)->bo, 0, PIPE_MAP_READ, &box,
2841                                             &src_t);
2842 
2843             memset(map, 0, box.width);
2844             state->pctx->buffer_unmap(state->pctx, src_t);
2845          }
2846       }
2847    }
2848 }
2849 
pack_clear_color(enum pipe_format pformat,VkClearColorValue * in_val,uint32_t col_val[4])2850 static void pack_clear_color(enum pipe_format pformat, VkClearColorValue *in_val, uint32_t col_val[4])
2851 {
2852    const struct util_format_description *desc = util_format_description(pformat);
2853    col_val[0] = col_val[1] = col_val[2] = col_val[3] = 0;
2854    for (unsigned c = 0; c < 4; c++) {
2855       if (desc->swizzle[c] >= 4)
2856          continue;
2857       const struct util_format_channel_description *channel = &desc->channel[desc->swizzle[c]];
2858       if (channel->size == 32) {
2859          col_val[c] = in_val->uint32[c];
2860          continue;
2861       }
2862       if (channel->pure_integer) {
2863          uint64_t v = in_val->uint32[c] & ((1u << channel->size) - 1);
2864          switch (channel->size) {
2865          case 2:
2866          case 8:
2867          case 10:
2868             col_val[0] |= (v << channel->shift);
2869             break;
2870          case 16:
2871             col_val[c / 2] |= (v << (16 * (c % 2)));
2872             break;
2873          }
2874       } else {
2875          util_pack_color(in_val->float32, pformat, (union util_color *)col_val);
2876          break;
2877       }
2878    }
2879 }
2880 
handle_clear_color_image(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2881 static void handle_clear_color_image(struct vk_cmd_queue_entry *cmd,
2882                                      struct rendering_state *state)
2883 {
2884    LVP_FROM_HANDLE(lvp_image, image, cmd->u.clear_color_image.image);
2885    uint32_t col_val[4];
2886    pack_clear_color(image->bo->format, cmd->u.clear_color_image.color, col_val);
2887    for (unsigned i = 0; i < cmd->u.clear_color_image.range_count; i++) {
2888       VkImageSubresourceRange *range = &cmd->u.clear_color_image.ranges[i];
2889       struct pipe_box box;
2890       box.x = 0;
2891       box.y = 0;
2892       box.z = 0;
2893 
2894       uint32_t level_count = lvp_get_levelCount(image, range);
2895       for (unsigned j = range->baseMipLevel; j < range->baseMipLevel + level_count; j++) {
2896          box.width = u_minify(image->bo->width0, j);
2897          box.height = u_minify(image->bo->height0, j);
2898          box.depth = 1;
2899          if (image->bo->target == PIPE_TEXTURE_3D)
2900             box.depth = u_minify(image->bo->depth0, j);
2901          else if (image->bo->target == PIPE_TEXTURE_1D_ARRAY) {
2902             box.y = range->baseArrayLayer;
2903             box.height = lvp_get_layerCount(image, range);
2904             box.depth = 1;
2905          } else {
2906             box.z = range->baseArrayLayer;
2907             box.depth = lvp_get_layerCount(image, range);
2908          }
2909 
2910          state->pctx->clear_texture(state->pctx, image->bo,
2911                                     j, &box, (void *)col_val);
2912       }
2913    }
2914 }
2915 
handle_clear_ds_image(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2916 static void handle_clear_ds_image(struct vk_cmd_queue_entry *cmd,
2917                                   struct rendering_state *state)
2918 {
2919    LVP_FROM_HANDLE(lvp_image, image, cmd->u.clear_depth_stencil_image.image);
2920    for (unsigned i = 0; i < cmd->u.clear_depth_stencil_image.range_count; i++) {
2921       VkImageSubresourceRange *range = &cmd->u.clear_depth_stencil_image.ranges[i];
2922       uint32_t ds_clear_flags = 0;
2923       if (range->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)
2924          ds_clear_flags |= PIPE_CLEAR_DEPTH;
2925       if (range->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)
2926          ds_clear_flags |= PIPE_CLEAR_STENCIL;
2927 
2928       uint32_t level_count = lvp_get_levelCount(image, range);
2929       for (unsigned j = 0; j < level_count; j++) {
2930          struct pipe_surface *surf;
2931          unsigned width, height;
2932 
2933          width = u_minify(image->bo->width0, range->baseMipLevel + j);
2934          height = u_minify(image->bo->height0, range->baseMipLevel + j);
2935 
2936          surf = create_img_surface_bo(state, range,
2937                                       image->bo, image->bo->format,
2938                                       width, height,
2939                                       0, lvp_get_layerCount(image, range) - 1, j);
2940 
2941          state->pctx->clear_depth_stencil(state->pctx,
2942                                           surf,
2943                                           ds_clear_flags,
2944                                           cmd->u.clear_depth_stencil_image.depth_stencil->depth,
2945                                           cmd->u.clear_depth_stencil_image.depth_stencil->stencil,
2946                                           0, 0,
2947                                           width, height, true);
2948          state->pctx->surface_destroy(state->pctx, surf);
2949       }
2950    }
2951 }
2952 
handle_clear_attachments(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)2953 static void handle_clear_attachments(struct vk_cmd_queue_entry *cmd,
2954                                      struct rendering_state *state)
2955 {
2956    for (uint32_t a = 0; a < cmd->u.clear_attachments.attachment_count; a++) {
2957       VkClearAttachment *att = &cmd->u.clear_attachments.attachments[a];
2958       const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
2959       struct lvp_image_view *imgv;
2960 
2961       if (att->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) {
2962          struct lvp_subpass_attachment *color_att = &subpass->color_attachments[att->colorAttachment];
2963          if (!color_att || color_att->attachment == VK_ATTACHMENT_UNUSED)
2964             continue;
2965          imgv = get_attachment(state, color_att->attachment);
2966       } else {
2967          struct lvp_subpass_attachment *ds_att = subpass->depth_stencil_attachment;
2968          if (!ds_att || ds_att->attachment == VK_ATTACHMENT_UNUSED)
2969             continue;
2970          imgv = get_attachment(state, ds_att->attachment);
2971       }
2972       union pipe_color_union col_val;
2973       double dclear_val = 0;
2974       uint32_t sclear_val = 0;
2975       uint32_t ds_clear_flags = 0;
2976       if (att->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) {
2977          ds_clear_flags |= PIPE_CLEAR_DEPTH;
2978          dclear_val = att->clearValue.depthStencil.depth;
2979       }
2980       if (att->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) {
2981          ds_clear_flags |= PIPE_CLEAR_STENCIL;
2982          sclear_val = att->clearValue.depthStencil.stencil;
2983       }
2984       if (att->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
2985          for (unsigned i = 0; i < 4; i++)
2986             col_val.ui[i] = att->clearValue.color.uint32[i];
2987       }
2988 
2989       for (uint32_t r = 0; r < cmd->u.clear_attachments.rect_count; r++) {
2990 
2991          VkClearRect *rect = &cmd->u.clear_attachments.rects[r];
2992          if (subpass->view_mask) {
2993             u_foreach_bit(i, subpass->view_mask)
2994                clear_attachment_layers(state, imgv, &rect->rect,
2995                                        i, 1,
2996                                        ds_clear_flags, dclear_val, sclear_val,
2997                                        &col_val);
2998          } else
2999             clear_attachment_layers(state, imgv, &rect->rect,
3000                                     rect->baseArrayLayer, rect->layerCount,
3001                                     ds_clear_flags, dclear_val, sclear_val,
3002                                     &col_val);
3003       }
3004    }
3005 }
3006 
handle_resolve_image(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3007 static void handle_resolve_image(struct vk_cmd_queue_entry *cmd,
3008                                  struct rendering_state *state)
3009 {
3010    int i;
3011    struct VkResolveImageInfo2KHR *resolvecmd = cmd->u.resolve_image2_khr.resolve_image_info;
3012    LVP_FROM_HANDLE(lvp_image, src_image, resolvecmd->srcImage);
3013    LVP_FROM_HANDLE(lvp_image, dst_image, resolvecmd->dstImage);
3014    struct pipe_blit_info info;
3015 
3016    memset(&info, 0, sizeof(info));
3017 
3018    state->pctx->flush(state->pctx, NULL, 0);
3019    info.src.resource = src_image->bo;
3020    info.dst.resource = dst_image->bo;
3021    info.src.format = src_image->bo->format;
3022    info.dst.format = dst_image->bo->format;
3023    info.mask = util_format_is_depth_or_stencil(info.src.format) ? PIPE_MASK_ZS : PIPE_MASK_RGBA;
3024    info.filter = PIPE_TEX_FILTER_NEAREST;
3025    for (i = 0; i < resolvecmd->regionCount; i++) {
3026       int srcX0, srcY0;
3027       unsigned dstX0, dstY0;
3028 
3029       srcX0 = resolvecmd->pRegions[i].srcOffset.x;
3030       srcY0 = resolvecmd->pRegions[i].srcOffset.y;
3031 
3032       dstX0 = resolvecmd->pRegions[i].dstOffset.x;
3033       dstY0 = resolvecmd->pRegions[i].dstOffset.y;
3034 
3035       info.dst.box.x = dstX0;
3036       info.dst.box.y = dstY0;
3037       info.src.box.x = srcX0;
3038       info.src.box.y = srcY0;
3039 
3040       info.dst.box.width = resolvecmd->pRegions[i].extent.width;
3041       info.src.box.width = resolvecmd->pRegions[i].extent.width;
3042       info.dst.box.height = resolvecmd->pRegions[i].extent.height;
3043       info.src.box.height = resolvecmd->pRegions[i].extent.height;
3044 
3045       info.dst.box.depth = resolvecmd->pRegions[i].dstSubresource.layerCount;
3046       info.src.box.depth = resolvecmd->pRegions[i].srcSubresource.layerCount;
3047 
3048       info.src.level = resolvecmd->pRegions[i].srcSubresource.mipLevel;
3049       info.src.box.z = resolvecmd->pRegions[i].srcOffset.z + resolvecmd->pRegions[i].srcSubresource.baseArrayLayer;
3050 
3051       info.dst.level = resolvecmd->pRegions[i].dstSubresource.mipLevel;
3052       info.dst.box.z = resolvecmd->pRegions[i].dstOffset.z + resolvecmd->pRegions[i].dstSubresource.baseArrayLayer;
3053 
3054       state->pctx->blit(state->pctx, &info);
3055    }
3056 }
3057 
handle_draw_indirect_count(struct vk_cmd_queue_entry * cmd,struct rendering_state * state,bool indexed)3058 static void handle_draw_indirect_count(struct vk_cmd_queue_entry *cmd,
3059                                        struct rendering_state *state, bool indexed)
3060 {
3061    const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
3062    struct pipe_draw_start_count_bias draw = {0};
3063    if (indexed) {
3064       state->info.index_bounds_valid = false;
3065       state->info.index_size = state->index_size;
3066       state->info.index.resource = state->index_buffer;
3067       state->info.max_index = ~0;
3068    } else
3069       state->info.index_size = 0;
3070    state->indirect_info.offset = cmd->u.draw_indirect_count.offset;
3071    state->indirect_info.stride = cmd->u.draw_indirect_count.stride;
3072    state->indirect_info.draw_count = cmd->u.draw_indirect_count.max_draw_count;
3073    state->indirect_info.buffer = lvp_buffer_from_handle(cmd->u.draw_indirect_count.buffer)->bo;
3074    state->indirect_info.indirect_draw_count_offset = cmd->u.draw_indirect_count.count_buffer_offset;
3075    state->indirect_info.indirect_draw_count = lvp_buffer_from_handle(cmd->u.draw_indirect_count.count_buffer)->bo;
3076    state->info.view_mask = subpass->view_mask;
3077 
3078    state->pctx->set_patch_vertices(state->pctx, state->patch_vertices);
3079    state->pctx->draw_vbo(state->pctx, &state->info, 0, &state->indirect_info, &draw, 1);
3080 }
3081 
handle_compute_push_descriptor_set(struct lvp_cmd_push_descriptor_set * pds,struct dyn_info * dyn_info,struct rendering_state * state)3082 static void handle_compute_push_descriptor_set(struct lvp_cmd_push_descriptor_set *pds,
3083                                                struct dyn_info *dyn_info,
3084                                                struct rendering_state *state)
3085 {
3086    struct lvp_descriptor_set_layout *layout = pds->layout->set[pds->set].layout;
3087 
3088    if (!(layout->shader_stages & VK_SHADER_STAGE_COMPUTE_BIT))
3089       return;
3090    for (unsigned i = 0; i < pds->set; i++) {
3091       increment_dyn_info(dyn_info, pds->layout->set[i].layout, false);
3092    }
3093    unsigned info_idx = 0;
3094    for (unsigned i = 0; i < pds->descriptor_write_count; i++) {
3095       struct lvp_write_descriptor *desc = &pds->descriptors[i];
3096       struct lvp_descriptor_set_binding_layout *binding = &layout->binding[desc->dst_binding];
3097 
3098       if (!binding->valid)
3099          continue;
3100 
3101       for (unsigned j = 0; j < desc->descriptor_count; j++) {
3102          union lvp_descriptor_info *info = &pds->infos[info_idx + j];
3103 
3104          handle_descriptor(state, dyn_info, binding,
3105                            MESA_SHADER_COMPUTE, PIPE_SHADER_COMPUTE,
3106                            j, desc->descriptor_type,
3107                            info);
3108       }
3109       info_idx += desc->descriptor_count;
3110    }
3111 }
3112 
create_push_descriptor_set(struct vk_cmd_push_descriptor_set_khr * in_cmd)3113 static struct lvp_cmd_push_descriptor_set *create_push_descriptor_set(struct vk_cmd_push_descriptor_set_khr *in_cmd)
3114 {
3115    LVP_FROM_HANDLE(lvp_pipeline_layout, layout, in_cmd->layout);
3116    struct lvp_cmd_push_descriptor_set *out_cmd;
3117    int count_descriptors = 0;
3118    int cmd_size = sizeof(*out_cmd);
3119 
3120    for (unsigned i = 0; i < in_cmd->descriptor_write_count; i++) {
3121       count_descriptors += in_cmd->descriptor_writes[i].descriptorCount;
3122    }
3123    cmd_size += count_descriptors * sizeof(union lvp_descriptor_info);
3124 
3125    cmd_size += in_cmd->descriptor_write_count * sizeof(struct lvp_write_descriptor);
3126 
3127    out_cmd = calloc(1, cmd_size);
3128    if (!out_cmd)
3129       return NULL;
3130 
3131    out_cmd->bind_point = in_cmd->pipeline_bind_point;
3132    out_cmd->layout = layout;
3133    out_cmd->set = in_cmd->set;
3134    out_cmd->descriptor_write_count = in_cmd->descriptor_write_count;
3135    out_cmd->descriptors = (struct lvp_write_descriptor *)(out_cmd + 1);
3136    out_cmd->infos = (union lvp_descriptor_info *)(out_cmd->descriptors + in_cmd->descriptor_write_count);
3137 
3138    unsigned descriptor_index = 0;
3139 
3140    for (unsigned i = 0; i < in_cmd->descriptor_write_count; i++) {
3141       struct lvp_write_descriptor *desc = &out_cmd->descriptors[i];
3142 
3143       /* dstSet is ignored */
3144       desc->dst_binding = in_cmd->descriptor_writes[i].dstBinding;
3145       desc->dst_array_element = in_cmd->descriptor_writes[i].dstArrayElement;
3146       desc->descriptor_count = in_cmd->descriptor_writes[i].descriptorCount;
3147       desc->descriptor_type = in_cmd->descriptor_writes[i].descriptorType;
3148 
3149       for (unsigned j = 0; j < desc->descriptor_count; j++) {
3150          union lvp_descriptor_info *info = &out_cmd->infos[descriptor_index + j];
3151          switch (desc->descriptor_type) {
3152          case VK_DESCRIPTOR_TYPE_SAMPLER:
3153             info->sampler = lvp_sampler_from_handle(in_cmd->descriptor_writes[i].pImageInfo[j].sampler);
3154             break;
3155          case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
3156             info->sampler = lvp_sampler_from_handle(in_cmd->descriptor_writes[i].pImageInfo[j].sampler);
3157             info->iview = lvp_image_view_from_handle(in_cmd->descriptor_writes[i].pImageInfo[j].imageView);
3158             info->image_layout = in_cmd->descriptor_writes[i].pImageInfo[j].imageLayout;
3159             break;
3160          case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
3161          case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
3162          case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
3163             info->iview = lvp_image_view_from_handle(in_cmd->descriptor_writes[i].pImageInfo[j].imageView);
3164             info->image_layout = in_cmd->descriptor_writes[i].pImageInfo[j].imageLayout;
3165             break;
3166          case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
3167          case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
3168             info->buffer_view = lvp_buffer_view_from_handle(in_cmd->descriptor_writes[i].pTexelBufferView[j]);
3169             break;
3170          case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
3171          case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
3172          case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
3173          case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
3174          default:
3175             info->buffer = lvp_buffer_from_handle(in_cmd->descriptor_writes[i].pBufferInfo[j].buffer);
3176             info->offset = in_cmd->descriptor_writes[i].pBufferInfo[j].offset;
3177             info->range = in_cmd->descriptor_writes[i].pBufferInfo[j].range;
3178             break;
3179          }
3180       }
3181       descriptor_index += desc->descriptor_count;
3182    }
3183 
3184    return out_cmd;
3185 }
3186 
handle_push_descriptor_set_generic(struct vk_cmd_push_descriptor_set_khr * _pds,struct rendering_state * state)3187 static void handle_push_descriptor_set_generic(struct vk_cmd_push_descriptor_set_khr *_pds,
3188                                                struct rendering_state *state)
3189 {
3190    struct lvp_cmd_push_descriptor_set *pds;
3191    struct lvp_descriptor_set_layout *layout;
3192    struct dyn_info dyn_info;
3193 
3194    pds = create_push_descriptor_set(_pds);
3195    layout = pds->layout->set[pds->set].layout;
3196 
3197    memset(&dyn_info.stage, 0, sizeof(dyn_info.stage));
3198    dyn_info.dyn_index = 0;
3199    if (pds->bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
3200       handle_compute_push_descriptor_set(pds, &dyn_info, state);
3201    }
3202 
3203    for (unsigned i = 0; i < pds->set; i++) {
3204       increment_dyn_info(&dyn_info, pds->layout->set[i].layout, false);
3205    }
3206 
3207    unsigned info_idx = 0;
3208    for (unsigned i = 0; i < pds->descriptor_write_count; i++) {
3209       struct lvp_write_descriptor *desc = &pds->descriptors[i];
3210       struct lvp_descriptor_set_binding_layout *binding = &layout->binding[desc->dst_binding];
3211 
3212       if (!binding->valid)
3213          continue;
3214 
3215       for (unsigned j = 0; j < desc->descriptor_count; j++) {
3216          union lvp_descriptor_info *info = &pds->infos[info_idx + j];
3217 
3218          if (layout->shader_stages & VK_SHADER_STAGE_VERTEX_BIT)
3219             handle_descriptor(state, &dyn_info, binding,
3220                               MESA_SHADER_VERTEX, PIPE_SHADER_VERTEX,
3221                               j, desc->descriptor_type,
3222                               info);
3223          if (layout->shader_stages & VK_SHADER_STAGE_FRAGMENT_BIT)
3224             handle_descriptor(state, &dyn_info, binding,
3225                               MESA_SHADER_FRAGMENT, PIPE_SHADER_FRAGMENT,
3226                               j, desc->descriptor_type,
3227                               info);
3228          if (layout->shader_stages & VK_SHADER_STAGE_GEOMETRY_BIT)
3229             handle_descriptor(state, &dyn_info, binding,
3230                               MESA_SHADER_GEOMETRY, PIPE_SHADER_GEOMETRY,
3231                               j, desc->descriptor_type,
3232                               info);
3233          if (layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
3234             handle_descriptor(state, &dyn_info, binding,
3235                               MESA_SHADER_TESS_CTRL, PIPE_SHADER_TESS_CTRL,
3236                               j, desc->descriptor_type,
3237                               info);
3238          if (layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
3239             handle_descriptor(state, &dyn_info, binding,
3240                               MESA_SHADER_TESS_EVAL, PIPE_SHADER_TESS_EVAL,
3241                               j, desc->descriptor_type,
3242                               info);
3243       }
3244       info_idx += desc->descriptor_count;
3245    }
3246    free(pds);
3247 }
3248 
handle_push_descriptor_set(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3249 static void handle_push_descriptor_set(struct vk_cmd_queue_entry *cmd,
3250                                        struct rendering_state *state)
3251 {
3252    handle_push_descriptor_set_generic(&cmd->u.push_descriptor_set_khr, state);
3253 }
3254 
handle_push_descriptor_set_with_template(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3255 static void handle_push_descriptor_set_with_template(struct vk_cmd_queue_entry *cmd,
3256                                                      struct rendering_state *state)
3257 {
3258    LVP_FROM_HANDLE(lvp_descriptor_update_template, templ, cmd->u.push_descriptor_set_with_template_khr.descriptor_update_template);
3259    struct vk_cmd_push_descriptor_set_khr *pds;
3260    int pds_size = sizeof(*pds);
3261 
3262    pds_size += templ->entry_count * sizeof(struct VkWriteDescriptorSet);
3263 
3264    for (unsigned i = 0; i < templ->entry_count; i++) {
3265       VkDescriptorUpdateTemplateEntry *entry = &templ->entry[i];
3266       switch (entry->descriptorType) {
3267       case VK_DESCRIPTOR_TYPE_SAMPLER:
3268       case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
3269       case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
3270       case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
3271       case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
3272          pds_size += sizeof(VkDescriptorImageInfo) * entry->descriptorCount;
3273          break;
3274       case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
3275       case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
3276          pds_size += sizeof(VkBufferView) * entry->descriptorCount;
3277          break;
3278       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
3279       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
3280       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
3281       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
3282       default:
3283          pds_size += sizeof(VkDescriptorBufferInfo) * entry->descriptorCount;
3284          break;
3285       }
3286    }
3287 
3288    pds = calloc(1, pds_size);
3289    if (!pds)
3290       return;
3291 
3292    pds->pipeline_bind_point = templ->bind_point;
3293    pds->layout = lvp_pipeline_layout_to_handle(templ->pipeline_layout);
3294    pds->set = templ->set;
3295    pds->descriptor_write_count = templ->entry_count;
3296    pds->descriptor_writes = (struct VkWriteDescriptorSet *)(pds + 1);
3297    const uint8_t *next_info = (const uint8_t *) (pds->descriptor_writes + templ->entry_count);
3298 
3299    const uint8_t *pSrc = cmd->u.push_descriptor_set_with_template_khr.data;
3300    for (unsigned i = 0; i < templ->entry_count; i++) {
3301       struct VkWriteDescriptorSet *desc = &pds->descriptor_writes[i];
3302       struct VkDescriptorUpdateTemplateEntry *entry = &templ->entry[i];
3303 
3304       /* dstSet is ignored */
3305       desc->dstBinding = entry->dstBinding;
3306       desc->dstArrayElement = entry->dstArrayElement;
3307       desc->descriptorCount = entry->descriptorCount;
3308       desc->descriptorType = entry->descriptorType;
3309       desc->pImageInfo = (const VkDescriptorImageInfo *) next_info;
3310       desc->pTexelBufferView = (const VkBufferView *) next_info;
3311       desc->pBufferInfo = (const VkDescriptorBufferInfo *) next_info;
3312 
3313       for (unsigned j = 0; j < desc->descriptorCount; j++) {
3314          switch (desc->descriptorType) {
3315          case VK_DESCRIPTOR_TYPE_SAMPLER:
3316          case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
3317          case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
3318          case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
3319          case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
3320             memcpy((VkDescriptorImageInfo*)&desc->pImageInfo[j], pSrc, sizeof(VkDescriptorImageInfo));
3321             next_info += sizeof(VkDescriptorImageInfo);
3322             pSrc += sizeof(VkDescriptorImageInfo);
3323             break;
3324          case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
3325          case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
3326             memcpy((VkBufferView*)&desc->pTexelBufferView[j], pSrc, sizeof(VkBufferView));
3327             next_info += sizeof(VkBufferView);
3328             pSrc += sizeof(VkBufferView);
3329             break;
3330          case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
3331          case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
3332          case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
3333          case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
3334          default:
3335             memcpy((VkDescriptorBufferInfo*)&desc->pBufferInfo[j], pSrc, sizeof(VkDescriptorBufferInfo));
3336             next_info += sizeof(VkDescriptorBufferInfo);
3337             pSrc += sizeof(VkDescriptorBufferInfo);
3338             break;
3339          }
3340       }
3341    }
3342    handle_push_descriptor_set_generic(pds, state);
3343    free(pds);
3344 }
3345 
handle_bind_transform_feedback_buffers(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3346 static void handle_bind_transform_feedback_buffers(struct vk_cmd_queue_entry *cmd,
3347                                                    struct rendering_state *state)
3348 {
3349    struct vk_cmd_bind_transform_feedback_buffers_ext *btfb = &cmd->u.bind_transform_feedback_buffers_ext;
3350 
3351    for (unsigned i = 0; i < btfb->binding_count; i++) {
3352       int idx = i + btfb->first_binding;
3353       uint32_t size;
3354       if (btfb->sizes && btfb->sizes[i] != VK_WHOLE_SIZE)
3355          size = btfb->sizes[i];
3356       else
3357          size = lvp_buffer_from_handle(btfb->buffers[i])->size - btfb->offsets[i];
3358 
3359       if (state->so_targets[idx])
3360          state->pctx->stream_output_target_destroy(state->pctx, state->so_targets[idx]);
3361 
3362       state->so_targets[idx] = state->pctx->create_stream_output_target(state->pctx,
3363                                                                         lvp_buffer_from_handle(btfb->buffers[i])->bo,
3364                                                                         btfb->offsets[i],
3365                                                                         size);
3366    }
3367    state->num_so_targets = btfb->first_binding + btfb->binding_count;
3368 }
3369 
handle_begin_transform_feedback(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3370 static void handle_begin_transform_feedback(struct vk_cmd_queue_entry *cmd,
3371                                             struct rendering_state *state)
3372 {
3373    struct vk_cmd_begin_transform_feedback_ext *btf = &cmd->u.begin_transform_feedback_ext;
3374    uint32_t offsets[4];
3375 
3376    memset(offsets, 0, sizeof(uint32_t)*4);
3377 
3378    for (unsigned i = 0; i < btf->counter_buffer_count; i++) {
3379       if (!btf->counter_buffers[i])
3380          continue;
3381 
3382       pipe_buffer_read(state->pctx,
3383                        btf->counter_buffers ? lvp_buffer_from_handle(btf->counter_buffers[i])->bo : NULL,
3384                        btf->counter_buffer_offsets ? btf->counter_buffer_offsets[i] : 0,
3385                        4,
3386                        &offsets[i]);
3387    }
3388    state->pctx->set_stream_output_targets(state->pctx, state->num_so_targets,
3389                                           state->so_targets, offsets);
3390 }
3391 
handle_end_transform_feedback(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3392 static void handle_end_transform_feedback(struct vk_cmd_queue_entry *cmd,
3393                                           struct rendering_state *state)
3394 {
3395    struct vk_cmd_end_transform_feedback_ext *etf = &cmd->u.end_transform_feedback_ext;
3396 
3397    if (etf->counter_buffer_count) {
3398       for (unsigned i = 0; i < etf->counter_buffer_count; i++) {
3399          if (!etf->counter_buffers[i])
3400             continue;
3401 
3402          uint32_t offset;
3403          offset = state->pctx->stream_output_target_offset(state->so_targets[i]);
3404 
3405          pipe_buffer_write(state->pctx,
3406                            etf->counter_buffers ? lvp_buffer_from_handle(etf->counter_buffers[i])->bo : NULL,
3407                            etf->counter_buffer_offsets ? etf->counter_buffer_offsets[i] : 0,
3408                            4,
3409                            &offset);
3410       }
3411    }
3412    state->pctx->set_stream_output_targets(state->pctx, 0, NULL, NULL);
3413 }
3414 
handle_draw_indirect_byte_count(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3415 static void handle_draw_indirect_byte_count(struct vk_cmd_queue_entry *cmd,
3416                                             struct rendering_state *state)
3417 {
3418    struct vk_cmd_draw_indirect_byte_count_ext *dibc = &cmd->u.draw_indirect_byte_count_ext;
3419    const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
3420    struct pipe_draw_start_count_bias draw = {0};
3421 
3422    pipe_buffer_read(state->pctx,
3423                     lvp_buffer_from_handle(dibc->counter_buffer)->bo,
3424                     lvp_buffer_from_handle(dibc->counter_buffer)->offset + dibc->counter_buffer_offset,
3425                     4, &draw.count);
3426 
3427    state->info.start_instance = cmd->u.draw_indirect_byte_count_ext.first_instance;
3428    state->info.instance_count = cmd->u.draw_indirect_byte_count_ext.instance_count;
3429    state->info.index_size = 0;
3430 
3431    draw.count /= cmd->u.draw_indirect_byte_count_ext.vertex_stride;
3432    state->info.view_mask = subpass->view_mask;
3433    state->pctx->set_patch_vertices(state->pctx, state->patch_vertices);
3434    state->pctx->draw_vbo(state->pctx, &state->info, 0, &state->indirect_info, &draw, 1);
3435 }
3436 
handle_begin_conditional_rendering(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3437 static void handle_begin_conditional_rendering(struct vk_cmd_queue_entry *cmd,
3438                                                struct rendering_state *state)
3439 {
3440    struct VkConditionalRenderingBeginInfoEXT *bcr = cmd->u.begin_conditional_rendering_ext.conditional_rendering_begin;
3441    state->pctx->render_condition_mem(state->pctx,
3442                                      lvp_buffer_from_handle(bcr->buffer)->bo,
3443                                      lvp_buffer_from_handle(bcr->buffer)->offset + bcr->offset,
3444                                      bcr->flags & VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT);
3445 }
3446 
handle_end_conditional_rendering(struct rendering_state * state)3447 static void handle_end_conditional_rendering(struct rendering_state *state)
3448 {
3449    state->pctx->render_condition_mem(state->pctx, NULL, 0, false);
3450 }
3451 
handle_set_vertex_input(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3452 static void handle_set_vertex_input(struct vk_cmd_queue_entry *cmd,
3453                                     struct rendering_state *state)
3454 {
3455    const struct vk_cmd_set_vertex_input_ext *vertex_input = &cmd->u.set_vertex_input_ext;
3456    const struct VkVertexInputBindingDescription2EXT *bindings = vertex_input->vertex_binding_descriptions;
3457    const struct VkVertexInputAttributeDescription2EXT *attrs = vertex_input->vertex_attribute_descriptions;
3458    int max_location = -1;
3459    for (unsigned i = 0; i < vertex_input->vertex_attribute_description_count; i++) {
3460       const struct VkVertexInputBindingDescription2EXT *binding = NULL;
3461       unsigned location = attrs[i].location;
3462 
3463       for (unsigned j = 0; j < vertex_input->vertex_binding_description_count; j++) {
3464          const struct VkVertexInputBindingDescription2EXT *b = &bindings[j];
3465          if (b->binding == attrs[i].binding) {
3466             binding = b;
3467             break;
3468          }
3469       }
3470       assert(binding);
3471       state->velem.velems[location].src_offset = attrs[i].offset;
3472       state->velem.velems[location].vertex_buffer_index = attrs[i].binding;
3473       state->velem.velems[location].src_format = lvp_vk_format_to_pipe_format(attrs[i].format);
3474       state->vb[attrs[i].binding].stride = binding->stride;
3475 
3476       switch (binding->inputRate) {
3477       case VK_VERTEX_INPUT_RATE_VERTEX:
3478          state->velem.velems[location].instance_divisor = 0;
3479          break;
3480       case VK_VERTEX_INPUT_RATE_INSTANCE:
3481          state->velem.velems[location].instance_divisor = binding->divisor;
3482          break;
3483       default:
3484          assert(0);
3485          break;
3486       }
3487 
3488       if ((int)location > max_location)
3489          max_location = location;
3490    }
3491    state->velem.count = max_location + 1;
3492    state->vb_dirty = true;
3493    state->ve_dirty = true;
3494 }
3495 
handle_set_cull_mode(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3496 static void handle_set_cull_mode(struct vk_cmd_queue_entry *cmd,
3497                                  struct rendering_state *state)
3498 {
3499    state->rs_state.cull_face = vk_cull_to_pipe(cmd->u.set_cull_mode_ext.cull_mode);
3500    state->rs_dirty = true;
3501 }
3502 
handle_set_front_face(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3503 static void handle_set_front_face(struct vk_cmd_queue_entry *cmd,
3504                                   struct rendering_state *state)
3505 {
3506    state->rs_state.front_ccw = (cmd->u.set_front_face_ext.front_face == VK_FRONT_FACE_COUNTER_CLOCKWISE);
3507    state->rs_dirty = true;
3508 }
3509 
handle_set_primitive_topology(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3510 static void handle_set_primitive_topology(struct vk_cmd_queue_entry *cmd,
3511                                           struct rendering_state *state)
3512 {
3513    state->info.mode = vk_conv_topology(cmd->u.set_primitive_topology_ext.primitive_topology);
3514    state->rs_dirty = true;
3515 }
3516 
3517 
handle_set_depth_test_enable(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3518 static void handle_set_depth_test_enable(struct vk_cmd_queue_entry *cmd,
3519                                          struct rendering_state *state)
3520 {
3521    state->dsa_dirty |= state->dsa_state.depth_enabled != cmd->u.set_depth_test_enable_ext.depth_test_enable;
3522    state->dsa_state.depth_enabled = cmd->u.set_depth_test_enable_ext.depth_test_enable;
3523 }
3524 
handle_set_depth_write_enable(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3525 static void handle_set_depth_write_enable(struct vk_cmd_queue_entry *cmd,
3526                                           struct rendering_state *state)
3527 {
3528    state->dsa_dirty |= state->dsa_state.depth_writemask != cmd->u.set_depth_write_enable_ext.depth_write_enable;
3529    state->dsa_state.depth_writemask = cmd->u.set_depth_write_enable_ext.depth_write_enable;
3530 }
3531 
handle_set_depth_compare_op(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3532 static void handle_set_depth_compare_op(struct vk_cmd_queue_entry *cmd,
3533                                         struct rendering_state *state)
3534 {
3535    state->dsa_dirty |= state->dsa_state.depth_func != cmd->u.set_depth_compare_op_ext.depth_compare_op;
3536    state->dsa_state.depth_func = cmd->u.set_depth_compare_op_ext.depth_compare_op;
3537 }
3538 
handle_set_depth_bounds_test_enable(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3539 static void handle_set_depth_bounds_test_enable(struct vk_cmd_queue_entry *cmd,
3540                                                 struct rendering_state *state)
3541 {
3542    state->dsa_dirty |= state->dsa_state.depth_bounds_test != cmd->u.set_depth_bounds_test_enable_ext.depth_bounds_test_enable;
3543    state->dsa_state.depth_bounds_test = cmd->u.set_depth_bounds_test_enable_ext.depth_bounds_test_enable;
3544 }
3545 
handle_set_stencil_test_enable(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3546 static void handle_set_stencil_test_enable(struct vk_cmd_queue_entry *cmd,
3547                                            struct rendering_state *state)
3548 {
3549    state->dsa_dirty |= state->dsa_state.stencil[0].enabled != cmd->u.set_stencil_test_enable_ext.stencil_test_enable ||
3550                        state->dsa_state.stencil[1].enabled != cmd->u.set_stencil_test_enable_ext.stencil_test_enable;
3551    state->dsa_state.stencil[0].enabled = cmd->u.set_stencil_test_enable_ext.stencil_test_enable;
3552    state->dsa_state.stencil[1].enabled = cmd->u.set_stencil_test_enable_ext.stencil_test_enable;
3553 }
3554 
handle_set_stencil_op(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3555 static void handle_set_stencil_op(struct vk_cmd_queue_entry *cmd,
3556                                   struct rendering_state *state)
3557 {
3558    if (cmd->u.set_stencil_op_ext.face_mask & VK_STENCIL_FACE_FRONT_BIT) {
3559       state->dsa_state.stencil[0].func = cmd->u.set_stencil_op_ext.compare_op;
3560       state->dsa_state.stencil[0].fail_op = vk_conv_stencil_op(cmd->u.set_stencil_op_ext.fail_op);
3561       state->dsa_state.stencil[0].zpass_op = vk_conv_stencil_op(cmd->u.set_stencil_op_ext.pass_op);
3562       state->dsa_state.stencil[0].zfail_op = vk_conv_stencil_op(cmd->u.set_stencil_op_ext.depth_fail_op);
3563    }
3564 
3565    if (cmd->u.set_stencil_op_ext.face_mask & VK_STENCIL_FACE_BACK_BIT) {
3566       state->dsa_state.stencil[1].func = cmd->u.set_stencil_op_ext.compare_op;
3567       state->dsa_state.stencil[1].fail_op = vk_conv_stencil_op(cmd->u.set_stencil_op_ext.fail_op);
3568       state->dsa_state.stencil[1].zpass_op = vk_conv_stencil_op(cmd->u.set_stencil_op_ext.pass_op);
3569       state->dsa_state.stencil[1].zfail_op = vk_conv_stencil_op(cmd->u.set_stencil_op_ext.depth_fail_op);
3570    }
3571    state->dsa_dirty = true;
3572 }
3573 
handle_set_line_stipple(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3574 static void handle_set_line_stipple(struct vk_cmd_queue_entry *cmd,
3575                                     struct rendering_state *state)
3576 {
3577    state->rs_state.line_stipple_factor = cmd->u.set_line_stipple_ext.line_stipple_factor - 1;
3578    state->rs_state.line_stipple_pattern = cmd->u.set_line_stipple_ext.line_stipple_pattern;
3579    state->rs_dirty = true;
3580 }
3581 
handle_set_depth_bias_enable(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3582 static void handle_set_depth_bias_enable(struct vk_cmd_queue_entry *cmd,
3583                                          struct rendering_state *state)
3584 {
3585    state->rs_dirty |= state->depth_bias.enabled != cmd->u.set_depth_bias_enable_ext.depth_bias_enable;
3586    state->depth_bias.enabled = cmd->u.set_depth_bias_enable_ext.depth_bias_enable;
3587 }
3588 
handle_set_logic_op(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3589 static void handle_set_logic_op(struct vk_cmd_queue_entry *cmd,
3590                                 struct rendering_state *state)
3591 {
3592    unsigned op = vk_conv_logic_op(cmd->u.set_logic_op_ext.logic_op);
3593    state->rs_dirty |= state->blend_state.logicop_func != op;
3594    state->blend_state.logicop_func = op;
3595 }
3596 
handle_set_patch_control_points(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3597 static void handle_set_patch_control_points(struct vk_cmd_queue_entry *cmd,
3598                                             struct rendering_state *state)
3599 {
3600    state->patch_vertices = cmd->u.set_patch_control_points_ext.patch_control_points;
3601 }
3602 
handle_set_primitive_restart_enable(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3603 static void handle_set_primitive_restart_enable(struct vk_cmd_queue_entry *cmd,
3604                                                 struct rendering_state *state)
3605 {
3606    state->info.primitive_restart = cmd->u.set_primitive_restart_enable_ext.primitive_restart_enable;
3607 }
3608 
handle_set_rasterizer_discard_enable(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3609 static void handle_set_rasterizer_discard_enable(struct vk_cmd_queue_entry *cmd,
3610                                                  struct rendering_state *state)
3611 {
3612    state->rs_dirty |= state->rs_state.rasterizer_discard != cmd->u.set_rasterizer_discard_enable_ext.rasterizer_discard_enable;
3613    state->rs_state.rasterizer_discard = cmd->u.set_rasterizer_discard_enable_ext.rasterizer_discard_enable;
3614 }
3615 
handle_set_color_write_enable(struct vk_cmd_queue_entry * cmd,struct rendering_state * state)3616 static void handle_set_color_write_enable(struct vk_cmd_queue_entry *cmd,
3617                                           struct rendering_state *state)
3618 {
3619    uint8_t disable_mask = 0; //PIPE_MAX_COLOR_BUFS is max attachment count
3620 
3621    for (unsigned i = 0; i < cmd->u.set_color_write_enable_ext.attachment_count; i++) {
3622       /* this is inverted because cmdbufs are zero-initialized, meaning only 'true'
3623        * can be detected with a bool, and the default is to enable color writes
3624        */
3625       if (cmd->u.set_color_write_enable_ext.color_write_enables[i] != VK_TRUE)
3626          disable_mask |= BITFIELD_BIT(i);
3627    }
3628 
3629    state->blend_dirty |= state->color_write_disables != disable_mask;
3630    state->color_write_disables = disable_mask;
3631 }
3632 
lvp_execute_cmd_buffer(struct lvp_cmd_buffer * cmd_buffer,struct rendering_state * state)3633 static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer,
3634                                    struct rendering_state *state)
3635 {
3636    struct vk_cmd_queue_entry *cmd;
3637    bool first = true;
3638    bool did_flush = false;
3639 
3640    LIST_FOR_EACH_ENTRY(cmd, &cmd_buffer->queue.cmds, cmd_link) {
3641       switch (cmd->type) {
3642       case VK_CMD_BIND_PIPELINE:
3643          handle_pipeline(cmd, state);
3644          break;
3645       case VK_CMD_SET_VIEWPORT:
3646          handle_set_viewport(cmd, state);
3647          break;
3648       case VK_CMD_SET_VIEWPORT_WITH_COUNT_EXT:
3649          handle_set_viewport_with_count(cmd, state);
3650          break;
3651       case VK_CMD_SET_SCISSOR:
3652          handle_set_scissor(cmd, state);
3653          break;
3654       case VK_CMD_SET_SCISSOR_WITH_COUNT_EXT:
3655          handle_set_scissor_with_count(cmd, state);
3656          break;
3657       case VK_CMD_SET_LINE_WIDTH:
3658          handle_set_line_width(cmd, state);
3659          break;
3660       case VK_CMD_SET_DEPTH_BIAS:
3661          handle_set_depth_bias(cmd, state);
3662          break;
3663       case VK_CMD_SET_BLEND_CONSTANTS:
3664          handle_set_blend_constants(cmd, state);
3665          break;
3666       case VK_CMD_SET_DEPTH_BOUNDS:
3667          handle_set_depth_bounds(cmd, state);
3668          break;
3669       case VK_CMD_SET_STENCIL_COMPARE_MASK:
3670          handle_set_stencil_compare_mask(cmd, state);
3671          break;
3672       case VK_CMD_SET_STENCIL_WRITE_MASK:
3673          handle_set_stencil_write_mask(cmd, state);
3674          break;
3675       case VK_CMD_SET_STENCIL_REFERENCE:
3676          handle_set_stencil_reference(cmd, state);
3677          break;
3678       case VK_CMD_BIND_DESCRIPTOR_SETS:
3679          handle_descriptor_sets(cmd, state);
3680          break;
3681       case VK_CMD_BIND_INDEX_BUFFER:
3682          handle_index_buffer(cmd, state);
3683          break;
3684       case VK_CMD_BIND_VERTEX_BUFFERS:
3685          handle_vertex_buffers(cmd, state);
3686          break;
3687       case VK_CMD_BIND_VERTEX_BUFFERS2_EXT:
3688          handle_vertex_buffers2(cmd, state);
3689          break;
3690       case VK_CMD_DRAW:
3691          emit_state(state);
3692          handle_draw(cmd, state);
3693          break;
3694       case VK_CMD_DRAW_MULTI_EXT:
3695          emit_state(state);
3696          handle_draw_multi(cmd, state);
3697          break;
3698       case VK_CMD_DRAW_INDEXED:
3699          emit_state(state);
3700          handle_draw_indexed(cmd, state);
3701          break;
3702       case VK_CMD_DRAW_INDIRECT:
3703          emit_state(state);
3704          handle_draw_indirect(cmd, state, false);
3705          break;
3706       case VK_CMD_DRAW_INDEXED_INDIRECT:
3707          emit_state(state);
3708          handle_draw_indirect(cmd, state, true);
3709          break;
3710       case VK_CMD_DRAW_MULTI_INDEXED_EXT:
3711          emit_state(state);
3712          handle_draw_multi_indexed(cmd, state);
3713          break;
3714       case VK_CMD_DISPATCH:
3715          emit_compute_state(state);
3716          handle_dispatch(cmd, state);
3717          break;
3718       case VK_CMD_DISPATCH_BASE:
3719          emit_compute_state(state);
3720          handle_dispatch_base(cmd, state);
3721          break;
3722       case VK_CMD_DISPATCH_INDIRECT:
3723          emit_compute_state(state);
3724          handle_dispatch_indirect(cmd, state);
3725          break;
3726       case VK_CMD_COPY_BUFFER2_KHR:
3727          handle_copy_buffer(cmd, state);
3728          break;
3729       case VK_CMD_COPY_IMAGE2_KHR:
3730          handle_copy_image(cmd, state);
3731          break;
3732       case VK_CMD_BLIT_IMAGE2_KHR:
3733          handle_blit_image(cmd, state);
3734          break;
3735       case VK_CMD_COPY_BUFFER_TO_IMAGE2_KHR:
3736          handle_copy_buffer_to_image(cmd, state);
3737          break;
3738       case VK_CMD_COPY_IMAGE_TO_BUFFER2_KHR:
3739          handle_copy_image_to_buffer2_khr(cmd, state);
3740          break;
3741       case VK_CMD_UPDATE_BUFFER:
3742          handle_update_buffer(cmd, state);
3743          break;
3744       case VK_CMD_FILL_BUFFER:
3745          handle_fill_buffer(cmd, state);
3746          break;
3747       case VK_CMD_CLEAR_COLOR_IMAGE:
3748          handle_clear_color_image(cmd, state);
3749          break;
3750       case VK_CMD_CLEAR_DEPTH_STENCIL_IMAGE:
3751          handle_clear_ds_image(cmd, state);
3752          break;
3753       case VK_CMD_CLEAR_ATTACHMENTS:
3754          handle_clear_attachments(cmd, state);
3755          break;
3756       case VK_CMD_RESOLVE_IMAGE2_KHR:
3757          handle_resolve_image(cmd, state);
3758          break;
3759       case VK_CMD_SET_EVENT:
3760          handle_event_set(cmd, state);
3761          break;
3762       case VK_CMD_RESET_EVENT:
3763          handle_event_reset(cmd, state);
3764          break;
3765       case VK_CMD_WAIT_EVENTS:
3766          handle_wait_events(cmd, state);
3767          break;
3768       case VK_CMD_PIPELINE_BARRIER:
3769          /* skip flushes since every cmdbuf does a flush
3770             after iterating its cmds and so this is redundant
3771           */
3772          if (first || did_flush || cmd->cmd_link.next == &cmd_buffer->queue.cmds)
3773             continue;
3774          handle_pipeline_barrier(cmd, state);
3775          did_flush = true;
3776          continue;
3777       case VK_CMD_BEGIN_QUERY_INDEXED_EXT:
3778          handle_begin_query_indexed_ext(cmd, state);
3779          break;
3780       case VK_CMD_END_QUERY_INDEXED_EXT:
3781          handle_end_query_indexed_ext(cmd, state);
3782          break;
3783       case VK_CMD_BEGIN_QUERY:
3784          handle_begin_query(cmd, state);
3785          break;
3786       case VK_CMD_END_QUERY:
3787          handle_end_query(cmd, state);
3788          break;
3789       case VK_CMD_RESET_QUERY_POOL:
3790          handle_reset_query_pool(cmd, state);
3791          break;
3792       case VK_CMD_WRITE_TIMESTAMP:
3793          handle_write_timestamp(cmd, state);
3794          break;
3795       case VK_CMD_COPY_QUERY_POOL_RESULTS:
3796          handle_copy_query_pool_results(cmd, state);
3797          break;
3798       case VK_CMD_PUSH_CONSTANTS:
3799          handle_push_constants(cmd, state);
3800          break;
3801       case VK_CMD_BEGIN_RENDER_PASS:
3802          handle_begin_render_pass(cmd, state);
3803          break;
3804       case VK_CMD_BEGIN_RENDER_PASS2:
3805          handle_begin_render_pass2(cmd, state);
3806          break;
3807       case VK_CMD_NEXT_SUBPASS:
3808       case VK_CMD_NEXT_SUBPASS2:
3809          handle_next_subpass2(cmd, state);
3810          break;
3811       case VK_CMD_END_RENDER_PASS:
3812       case VK_CMD_END_RENDER_PASS2:
3813          handle_end_render_pass2(cmd, state);
3814          break;
3815       case VK_CMD_EXECUTE_COMMANDS:
3816          handle_execute_commands(cmd, state);
3817          break;
3818       case VK_CMD_DRAW_INDIRECT_COUNT:
3819          emit_state(state);
3820          handle_draw_indirect_count(cmd, state, false);
3821          break;
3822       case VK_CMD_DRAW_INDEXED_INDIRECT_COUNT:
3823          emit_state(state);
3824          handle_draw_indirect_count(cmd, state, true);
3825          break;
3826       case VK_CMD_PUSH_DESCRIPTOR_SET_KHR:
3827          handle_push_descriptor_set(cmd, state);
3828          break;
3829       case VK_CMD_PUSH_DESCRIPTOR_SET_WITH_TEMPLATE_KHR:
3830          handle_push_descriptor_set_with_template(cmd, state);
3831          break;
3832       case VK_CMD_BIND_TRANSFORM_FEEDBACK_BUFFERS_EXT:
3833          handle_bind_transform_feedback_buffers(cmd, state);
3834          break;
3835       case VK_CMD_BEGIN_TRANSFORM_FEEDBACK_EXT:
3836          handle_begin_transform_feedback(cmd, state);
3837          break;
3838       case VK_CMD_END_TRANSFORM_FEEDBACK_EXT:
3839          handle_end_transform_feedback(cmd, state);
3840          break;
3841       case VK_CMD_DRAW_INDIRECT_BYTE_COUNT_EXT:
3842          emit_state(state);
3843          handle_draw_indirect_byte_count(cmd, state);
3844          break;
3845       case VK_CMD_BEGIN_CONDITIONAL_RENDERING_EXT:
3846          handle_begin_conditional_rendering(cmd, state);
3847          break;
3848       case VK_CMD_END_CONDITIONAL_RENDERING_EXT:
3849          handle_end_conditional_rendering(state);
3850          break;
3851       case VK_CMD_SET_VERTEX_INPUT_EXT:
3852          handle_set_vertex_input(cmd, state);
3853          break;
3854       case VK_CMD_SET_CULL_MODE_EXT:
3855          handle_set_cull_mode(cmd, state);
3856          break;
3857       case VK_CMD_SET_FRONT_FACE_EXT:
3858          handle_set_front_face(cmd, state);
3859          break;
3860       case VK_CMD_SET_PRIMITIVE_TOPOLOGY_EXT:
3861          handle_set_primitive_topology(cmd, state);
3862          break;
3863       case VK_CMD_SET_DEPTH_TEST_ENABLE_EXT:
3864          handle_set_depth_test_enable(cmd, state);
3865          break;
3866       case VK_CMD_SET_DEPTH_WRITE_ENABLE_EXT:
3867          handle_set_depth_write_enable(cmd, state);
3868          break;
3869       case VK_CMD_SET_DEPTH_COMPARE_OP_EXT:
3870          handle_set_depth_compare_op(cmd, state);
3871          break;
3872       case VK_CMD_SET_DEPTH_BOUNDS_TEST_ENABLE_EXT:
3873          handle_set_depth_bounds_test_enable(cmd, state);
3874          break;
3875       case VK_CMD_SET_STENCIL_TEST_ENABLE_EXT:
3876          handle_set_stencil_test_enable(cmd, state);
3877          break;
3878       case VK_CMD_SET_STENCIL_OP_EXT:
3879          handle_set_stencil_op(cmd, state);
3880          break;
3881       case VK_CMD_SET_LINE_STIPPLE_EXT:
3882          handle_set_line_stipple(cmd, state);
3883          break;
3884       case VK_CMD_SET_DEPTH_BIAS_ENABLE_EXT:
3885          handle_set_depth_bias_enable(cmd, state);
3886          break;
3887       case VK_CMD_SET_LOGIC_OP_EXT:
3888          handle_set_logic_op(cmd, state);
3889          break;
3890       case VK_CMD_SET_PATCH_CONTROL_POINTS_EXT:
3891          handle_set_patch_control_points(cmd, state);
3892          break;
3893       case VK_CMD_SET_PRIMITIVE_RESTART_ENABLE_EXT:
3894          handle_set_primitive_restart_enable(cmd, state);
3895          break;
3896       case VK_CMD_SET_RASTERIZER_DISCARD_ENABLE_EXT:
3897          handle_set_rasterizer_discard_enable(cmd, state);
3898          break;
3899       case VK_CMD_SET_COLOR_WRITE_ENABLE_EXT:
3900          handle_set_color_write_enable(cmd, state);
3901          break;
3902       case VK_CMD_SET_DEVICE_MASK:
3903          /* no-op */
3904          break;
3905       default:
3906          fprintf(stderr, "Unsupported command %s\n", vk_cmd_queue_type_names[cmd->type]);
3907          unreachable("Unsupported command");
3908          break;
3909       }
3910       first = false;
3911       did_flush = false;
3912    }
3913 }
3914 
lvp_execute_cmds(struct lvp_device * device,struct lvp_queue * queue,struct lvp_cmd_buffer * cmd_buffer)3915 VkResult lvp_execute_cmds(struct lvp_device *device,
3916                           struct lvp_queue *queue,
3917                           struct lvp_cmd_buffer *cmd_buffer)
3918 {
3919    struct rendering_state state;
3920    memset(&state, 0, sizeof(state));
3921    state.pctx = queue->ctx;
3922    state.cso = queue->cso;
3923    state.blend_dirty = true;
3924    state.dsa_dirty = true;
3925    state.rs_dirty = true;
3926    state.vp_dirty = true;
3927    for (enum pipe_shader_type s = PIPE_SHADER_VERTEX; s < PIPE_SHADER_TYPES; s++) {
3928       for (unsigned i = 0; i < PIPE_MAX_SAMPLERS; i++)
3929          state.cso_ss_ptr[s][i] = &state.ss[s][i];
3930    }
3931    /* create a gallium context */
3932    lvp_execute_cmd_buffer(cmd_buffer, &state);
3933 
3934    state.start_vb = -1;
3935    state.num_vb = 0;
3936    cso_unbind_context(queue->cso);
3937    for (unsigned i = 0; i < PIPE_MAX_SO_BUFFERS; i++) {
3938       if (state.so_targets[i]) {
3939          state.pctx->stream_output_target_destroy(state.pctx, state.so_targets[i]);
3940       }
3941    }
3942 
3943    free(state.imageless_views);
3944    free(state.pending_clear_aspects);
3945    free(state.cleared_views);
3946    free(state.attachments);
3947    return VK_SUCCESS;
3948 }
3949