• 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/format/u_format_zs.h"
42 
43 struct rendering_state {
44    struct pipe_context *pctx;
45 
46    bool blend_dirty;
47    bool rs_dirty;
48    bool dsa_dirty;
49    bool stencil_ref_dirty;
50    bool clip_state_dirty;
51    bool blend_color_dirty;
52    bool ve_dirty;
53    bool vb_dirty;
54    bool constbuf_dirty[PIPE_SHADER_TYPES];
55    bool pcbuf_dirty[PIPE_SHADER_TYPES];
56    bool vp_dirty;
57    bool scissor_dirty;
58    bool ib_dirty;
59    bool sample_mask_dirty;
60    bool min_samples_dirty;
61    struct pipe_draw_indirect_info indirect_info;
62    struct pipe_draw_info info;
63 
64    struct pipe_grid_info dispatch_info;
65    struct pipe_framebuffer_state framebuffer;
66 
67    struct pipe_blend_state blend_state;
68    void *blend_handle;
69    struct pipe_rasterizer_state rs_state;
70    void *rast_handle;
71    struct pipe_depth_stencil_alpha_state dsa_state;
72    void *dsa_handle;
73 
74    struct pipe_blend_color blend_color;
75    struct pipe_stencil_ref stencil_ref;
76    struct pipe_clip_state clip_state;
77 
78    int num_scissors;
79    struct pipe_scissor_state scissors[16];
80 
81    int num_viewports;
82    struct pipe_viewport_state viewports[16];
83 
84    ubyte index_size;
85    unsigned index_offset;
86    struct pipe_resource *index_buffer;
87    struct pipe_constant_buffer pc_buffer[PIPE_SHADER_TYPES];
88    struct pipe_constant_buffer const_buffer[PIPE_SHADER_TYPES][16];
89    int num_const_bufs[PIPE_SHADER_TYPES];
90    int num_vb;
91    unsigned start_vb;
92    struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];
93    int num_ve;
94    struct pipe_vertex_element ve[PIPE_MAX_ATTRIBS];
95 
96    struct pipe_sampler_view *sv[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
97    int num_sampler_views[PIPE_SHADER_TYPES];
98    struct pipe_sampler_state ss[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
99    int num_sampler_states[PIPE_SHADER_TYPES];
100    bool sv_dirty[PIPE_SHADER_TYPES];
101    bool ss_dirty[PIPE_SHADER_TYPES];
102 
103    struct pipe_image_view iv[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];
104    int num_shader_images[PIPE_SHADER_TYPES];
105    struct pipe_shader_buffer sb[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_BUFFERS];
106    int num_shader_buffers[PIPE_SHADER_TYPES];
107    bool iv_dirty[PIPE_SHADER_TYPES];
108    bool sb_dirty[PIPE_SHADER_TYPES];
109    void *ss_cso[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
110    void *velems_cso;
111 
112    uint8_t push_constants[128 * 4];
113 
114    const struct lvp_render_pass *pass;
115    uint32_t subpass;
116    const struct lvp_framebuffer *vk_framebuffer;
117    VkRect2D render_area;
118 
119    uint32_t sample_mask;
120    unsigned min_samples;
121 
122    const struct lvp_attachment_state *attachments;
123    VkImageAspectFlags *pending_clear_aspects;
124    int num_pending_aspects;
125 };
126 
emit_compute_state(struct rendering_state * state)127 static void emit_compute_state(struct rendering_state *state)
128 {
129    if (state->iv_dirty[PIPE_SHADER_COMPUTE]) {
130       state->pctx->set_shader_images(state->pctx, PIPE_SHADER_COMPUTE,
131                                      0, state->num_shader_images[PIPE_SHADER_COMPUTE],
132                                      state->iv[PIPE_SHADER_COMPUTE]);
133       state->iv_dirty[PIPE_SHADER_COMPUTE] = false;
134    }
135 
136    if (state->pcbuf_dirty[PIPE_SHADER_COMPUTE]) {
137       state->pctx->set_constant_buffer(state->pctx, PIPE_SHADER_COMPUTE,
138                                        0, &state->pc_buffer[PIPE_SHADER_COMPUTE]);
139       state->pcbuf_dirty[PIPE_SHADER_COMPUTE] = false;
140    }
141 
142    if (state->constbuf_dirty[PIPE_SHADER_COMPUTE]) {
143       for (unsigned i = 0; i < state->num_const_bufs[PIPE_SHADER_COMPUTE]; i++)
144          state->pctx->set_constant_buffer(state->pctx, PIPE_SHADER_COMPUTE,
145                                           i + 1, &state->const_buffer[PIPE_SHADER_COMPUTE][i]);
146       state->constbuf_dirty[PIPE_SHADER_COMPUTE] = false;
147    }
148 
149    if (state->sb_dirty[PIPE_SHADER_COMPUTE]) {
150       state->pctx->set_shader_buffers(state->pctx, PIPE_SHADER_COMPUTE,
151                                       0, state->num_shader_buffers[PIPE_SHADER_COMPUTE],
152                                       state->sb[PIPE_SHADER_COMPUTE], 0);
153       state->sb_dirty[PIPE_SHADER_COMPUTE] = false;
154    }
155 
156    if (state->sv_dirty[PIPE_SHADER_COMPUTE]) {
157       state->pctx->set_sampler_views(state->pctx, PIPE_SHADER_COMPUTE, 0, state->num_sampler_views[PIPE_SHADER_COMPUTE],
158                                      state->sv[PIPE_SHADER_COMPUTE]);
159       state->sv_dirty[PIPE_SHADER_COMPUTE] = false;
160    }
161 
162    if (state->ss_dirty[PIPE_SHADER_COMPUTE]) {
163       for (unsigned i = 0; i < state->num_sampler_states[PIPE_SHADER_COMPUTE]; i++) {
164          if (state->ss_cso[PIPE_SHADER_COMPUTE][i])
165             state->pctx->delete_sampler_state(state->pctx, state->ss_cso[PIPE_SHADER_COMPUTE][i]);
166          state->ss_cso[PIPE_SHADER_COMPUTE][i] = state->pctx->create_sampler_state(state->pctx, &state->ss[PIPE_SHADER_COMPUTE][i]);
167       }
168       state->pctx->bind_sampler_states(state->pctx, PIPE_SHADER_COMPUTE, 0, state->num_sampler_states[PIPE_SHADER_COMPUTE], state->ss_cso[PIPE_SHADER_COMPUTE]);
169       state->ss_dirty[PIPE_SHADER_COMPUTE] = false;
170    }
171 }
172 
emit_state(struct rendering_state * state)173 static void emit_state(struct rendering_state *state)
174 {
175    int sh;
176    if (state->blend_dirty) {
177       if (state->blend_handle) {
178          state->pctx->bind_blend_state(state->pctx, NULL);
179          state->pctx->delete_blend_state(state->pctx, state->blend_handle);
180       }
181       state->blend_handle = state->pctx->create_blend_state(state->pctx,
182                                                             &state->blend_state);
183       state->pctx->bind_blend_state(state->pctx, state->blend_handle);
184 
185       state->blend_dirty = false;
186    }
187 
188    if (state->rs_dirty) {
189       if (state->rast_handle) {
190          state->pctx->bind_rasterizer_state(state->pctx, NULL);
191          state->pctx->delete_rasterizer_state(state->pctx, state->rast_handle);
192       }
193       state->rast_handle = state->pctx->create_rasterizer_state(state->pctx,
194                                                                 &state->rs_state);
195       state->pctx->bind_rasterizer_state(state->pctx, state->rast_handle);
196       state->rs_dirty = false;
197    }
198 
199    if (state->dsa_dirty) {
200       if (state->dsa_handle) {
201          state->pctx->bind_depth_stencil_alpha_state(state->pctx, NULL);
202          state->pctx->delete_depth_stencil_alpha_state(state->pctx, state->dsa_handle);
203       }
204       state->dsa_handle = state->pctx->create_depth_stencil_alpha_state(state->pctx,
205                                                                         &state->dsa_state);
206       state->pctx->bind_depth_stencil_alpha_state(state->pctx, state->dsa_handle);
207 
208       state->dsa_dirty = false;
209    }
210 
211    if (state->sample_mask_dirty) {
212       state->pctx->set_sample_mask(state->pctx, state->sample_mask);
213       state->sample_mask_dirty = false;
214    }
215 
216    if (state->min_samples_dirty) {
217       state->pctx->set_min_samples(state->pctx, state->min_samples);
218       state->min_samples_dirty = false;
219    }
220 
221    if (state->blend_color_dirty) {
222       state->pctx->set_blend_color(state->pctx, &state->blend_color);
223       state->blend_color_dirty = false;
224    }
225 
226    if (state->stencil_ref_dirty) {
227       state->pctx->set_stencil_ref(state->pctx, &state->stencil_ref);
228       state->stencil_ref_dirty = false;
229    }
230 
231    if (state->vb_dirty) {
232       state->pctx->set_vertex_buffers(state->pctx, state->start_vb,
233                                       state->num_vb, state->vb);
234       state->vb_dirty = false;
235    }
236 
237    if (state->ve_dirty) {
238       void *ve = NULL;
239       if (state->velems_cso)
240          ve = state->velems_cso;
241 
242       state->velems_cso = state->pctx->create_vertex_elements_state(state->pctx, state->num_ve,
243                                                                     state->ve);
244       state->pctx->bind_vertex_elements_state(state->pctx, state->velems_cso);
245 
246       if (ve)
247          state->pctx->delete_vertex_elements_state(state->pctx, ve);
248    }
249 
250    for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
251       if (state->constbuf_dirty[sh]) {
252          for (unsigned idx = 0; idx < state->num_const_bufs[sh]; idx++)
253             state->pctx->set_constant_buffer(state->pctx, sh,
254                                              idx + 1, &state->const_buffer[sh][idx]);
255       }
256       state->constbuf_dirty[sh] = false;
257    }
258 
259    for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
260       if (state->pcbuf_dirty[sh]) {
261          state->pctx->set_constant_buffer(state->pctx, sh,
262                                           0, &state->pc_buffer[sh]);
263       }
264    }
265 
266    for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
267       if (state->sb_dirty[sh]) {
268          state->pctx->set_shader_buffers(state->pctx, sh,
269                                          0, state->num_shader_buffers[sh],
270                                          state->sb[sh], 0);
271       }
272    }
273 
274    for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
275       if (state->iv_dirty[sh]) {
276          state->pctx->set_shader_images(state->pctx, sh,
277                                         0, state->num_shader_images[sh],
278                                         state->iv[sh]);
279       }
280    }
281 
282    for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
283 
284       if (!state->sv_dirty[sh])
285          continue;
286 
287       state->pctx->set_sampler_views(state->pctx, sh, 0, state->num_sampler_views[sh],
288                                      state->sv[sh]);
289       state->sv_dirty[sh] = false;
290    }
291 
292    for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
293       int i;
294       if (!state->ss_dirty[sh])
295          continue;
296 
297       for (i = 0; i < state->num_sampler_states[sh]; i++) {
298          if (state->ss_cso[sh][i])
299             state->pctx->delete_sampler_state(state->pctx, state->ss_cso[sh][i]);
300          state->ss_cso[sh][i] = state->pctx->create_sampler_state(state->pctx, &state->ss[sh][i]);
301       }
302 
303       state->pctx->bind_sampler_states(state->pctx, sh, 0, state->num_sampler_states[sh], state->ss_cso[sh]);
304    }
305 
306    if (state->vp_dirty) {
307       state->pctx->set_viewport_states(state->pctx, 0, state->num_viewports, state->viewports);
308       state->vp_dirty = false;
309    }
310 
311    if (state->scissor_dirty) {
312       state->pctx->set_scissor_states(state->pctx, 0, state->num_scissors, state->scissors);
313       state->scissor_dirty = false;
314    }
315 }
316 
handle_compute_pipeline(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)317 static void handle_compute_pipeline(struct lvp_cmd_buffer_entry *cmd,
318                                     struct rendering_state *state)
319 {
320    struct lvp_pipeline *pipeline = cmd->u.pipeline.pipeline;
321 
322    state->dispatch_info.block[0] = pipeline->pipeline_nir[MESA_SHADER_COMPUTE]->info.cs.local_size[0];
323    state->dispatch_info.block[1] = pipeline->pipeline_nir[MESA_SHADER_COMPUTE]->info.cs.local_size[1];
324    state->dispatch_info.block[2] = pipeline->pipeline_nir[MESA_SHADER_COMPUTE]->info.cs.local_size[2];
325    state->pctx->bind_compute_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_COMPUTE]);
326 }
327 
328 static void
get_viewport_xform(const VkViewport * viewport,float scale[3],float translate[3])329 get_viewport_xform(const VkViewport *viewport,
330                    float scale[3], float translate[3])
331 {
332    float x = viewport->x;
333    float y = viewport->y;
334    float half_width = 0.5f * viewport->width;
335    float half_height = 0.5f * viewport->height;
336    double n = viewport->minDepth;
337    double f = viewport->maxDepth;
338 
339    scale[0] = half_width;
340    translate[0] = half_width + x;
341    scale[1] = half_height;
342    translate[1] = half_height + y;
343 
344    scale[2] = (f - n);
345    translate[2] = n;
346 }
347 
handle_graphics_pipeline(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)348 static void handle_graphics_pipeline(struct lvp_cmd_buffer_entry *cmd,
349                                      struct rendering_state *state)
350 {
351    struct lvp_pipeline *pipeline = cmd->u.pipeline.pipeline;
352    bool dynamic_states[VK_DYNAMIC_STATE_STENCIL_REFERENCE+1];
353    unsigned fb_samples = 0;
354 
355    memset(dynamic_states, 0, sizeof(dynamic_states));
356    if (pipeline->graphics_create_info.pDynamicState)
357    {
358       const VkPipelineDynamicStateCreateInfo *dyn = pipeline->graphics_create_info.pDynamicState;
359       int i;
360       for (i = 0; i < dyn->dynamicStateCount; i++) {
361          if (dyn->pDynamicStates[i] > VK_DYNAMIC_STATE_STENCIL_REFERENCE)
362             continue;
363          dynamic_states[dyn->pDynamicStates[i]] = true;
364       }
365    }
366 
367    bool has_stage[PIPE_SHADER_TYPES] = { false };
368 
369    state->pctx->bind_gs_state(state->pctx, NULL);
370    if (state->pctx->bind_tcs_state)
371       state->pctx->bind_tcs_state(state->pctx, NULL);
372    if (state->pctx->bind_tes_state)
373       state->pctx->bind_tes_state(state->pctx, NULL);
374    {
375       int i;
376       for (i = 0; i < pipeline->graphics_create_info.stageCount; i++) {
377          const VkPipelineShaderStageCreateInfo *sh = &pipeline->graphics_create_info.pStages[i];
378          switch (sh->stage) {
379          case VK_SHADER_STAGE_FRAGMENT_BIT:
380             state->pctx->bind_fs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_FRAGMENT]);
381             has_stage[PIPE_SHADER_FRAGMENT] = true;
382             break;
383          case VK_SHADER_STAGE_VERTEX_BIT:
384             state->pctx->bind_vs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_VERTEX]);
385             has_stage[PIPE_SHADER_VERTEX] = true;
386             break;
387          case VK_SHADER_STAGE_GEOMETRY_BIT:
388             state->pctx->bind_gs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_GEOMETRY]);
389             has_stage[PIPE_SHADER_GEOMETRY] = true;
390             break;
391          case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
392             state->pctx->bind_tcs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_TESS_CTRL]);
393             has_stage[PIPE_SHADER_TESS_CTRL] = true;
394             break;
395          case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
396             state->pctx->bind_tes_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_TESS_EVAL]);
397             has_stage[PIPE_SHADER_TESS_EVAL] = true;
398             break;
399          default:
400             assert(0);
401             break;
402          }
403       }
404    }
405 
406    /* there should always be a dummy fs. */
407    if (!has_stage[PIPE_SHADER_FRAGMENT])
408       state->pctx->bind_fs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_FRAGMENT]);
409    if (state->pctx->bind_gs_state && !has_stage[PIPE_SHADER_GEOMETRY])
410       state->pctx->bind_gs_state(state->pctx, NULL);
411    if (state->pctx->bind_tcs_state && !has_stage[PIPE_SHADER_TESS_CTRL])
412       state->pctx->bind_tcs_state(state->pctx, NULL);
413    if (state->pctx->bind_tes_state && !has_stage[PIPE_SHADER_TESS_EVAL])
414       state->pctx->bind_tes_state(state->pctx, NULL);
415 
416    /* rasterization state */
417    if (pipeline->graphics_create_info.pRasterizationState) {
418       const VkPipelineRasterizationStateCreateInfo *rsc = pipeline->graphics_create_info.pRasterizationState;
419       state->rs_state.depth_clip_near = state->rs_state.depth_clip_far = !rsc->depthClampEnable;
420       state->rs_state.rasterizer_discard = rsc->rasterizerDiscardEnable;
421       state->rs_state.front_ccw = (rsc->frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE);
422       state->rs_state.cull_face = vk_cull_to_pipe(rsc->cullMode);
423       state->rs_state.fill_front = vk_polygon_mode_to_pipe(rsc->polygonMode);
424       state->rs_state.fill_back = vk_polygon_mode_to_pipe(rsc->polygonMode);
425       state->rs_state.point_size_per_vertex = true;
426       state->rs_state.flatshade_first = true;
427       state->rs_state.point_quad_rasterization = true;
428       state->rs_state.clip_halfz = true;
429       state->rs_state.half_pixel_center = true;
430       state->rs_state.scissor = true;
431       state->rs_state.no_ms_sample_mask_out = true;
432 
433       if (!dynamic_states[VK_DYNAMIC_STATE_LINE_WIDTH])
434          state->rs_state.line_width = rsc->lineWidth;
435 
436       if (!dynamic_states[VK_DYNAMIC_STATE_DEPTH_BIAS]) {
437          state->rs_state.offset_units = rsc->depthBiasConstantFactor;
438          state->rs_state.offset_scale = rsc->depthBiasSlopeFactor;
439          state->rs_state.offset_clamp = rsc->depthBiasClamp;
440       }
441       state->rs_dirty = true;
442    }
443 
444    if (pipeline->graphics_create_info.pMultisampleState) {
445       const VkPipelineMultisampleStateCreateInfo *ms = pipeline->graphics_create_info.pMultisampleState;
446       state->rs_state.multisample = ms->rasterizationSamples > 1;
447       state->sample_mask = ms->pSampleMask ? ms->pSampleMask[0] : 0xffffffff;
448       state->blend_state.alpha_to_coverage = ms->alphaToCoverageEnable;
449       state->blend_state.alpha_to_one = ms->alphaToOneEnable;
450       state->blend_dirty = true;
451       state->rs_dirty = true;
452       state->min_samples = 1;
453       state->sample_mask_dirty = true;
454       fb_samples = ms->rasterizationSamples;
455       if (ms->sampleShadingEnable) {
456          state->min_samples = ceil(ms->rasterizationSamples * ms->minSampleShading);
457          if (state->min_samples > 1)
458             state->min_samples = ms->rasterizationSamples;
459          if (state->min_samples < 1)
460             state->min_samples = 1;
461       }
462       if (pipeline->force_min_sample)
463          state->min_samples = ms->rasterizationSamples;
464       state->min_samples_dirty = true;
465    } else {
466       state->rs_state.multisample = false;
467       state->blend_state.alpha_to_coverage = false;
468       state->blend_state.alpha_to_one = false;
469       state->rs_dirty = true;
470    }
471 
472    if (pipeline->graphics_create_info.pDepthStencilState) {
473       const VkPipelineDepthStencilStateCreateInfo *dsa = pipeline->graphics_create_info.pDepthStencilState;
474 
475       state->dsa_state.depth.enabled = dsa->depthTestEnable;
476       state->dsa_state.depth.writemask = dsa->depthWriteEnable;
477       state->dsa_state.depth.func = dsa->depthCompareOp;
478       state->dsa_state.depth.bounds_test = dsa->depthBoundsTestEnable;
479 
480       if (!dynamic_states[VK_DYNAMIC_STATE_DEPTH_BOUNDS]) {
481          state->dsa_state.depth.bounds_min = dsa->minDepthBounds;
482          state->dsa_state.depth.bounds_max = dsa->maxDepthBounds;
483       }
484 
485       state->dsa_state.stencil[0].enabled = dsa->stencilTestEnable;
486       state->dsa_state.stencil[0].func = dsa->front.compareOp;
487       state->dsa_state.stencil[0].fail_op = vk_conv_stencil_op(dsa->front.failOp);
488       state->dsa_state.stencil[0].zpass_op = vk_conv_stencil_op(dsa->front.passOp);
489       state->dsa_state.stencil[0].zfail_op = vk_conv_stencil_op(dsa->front.depthFailOp);
490 
491       state->dsa_state.stencil[1].enabled = dsa->stencilTestEnable;
492       state->dsa_state.stencil[1].func = dsa->back.compareOp;
493       state->dsa_state.stencil[1].fail_op = vk_conv_stencil_op(dsa->back.failOp);
494       state->dsa_state.stencil[1].zpass_op = vk_conv_stencil_op(dsa->back.passOp);
495       state->dsa_state.stencil[1].zfail_op = vk_conv_stencil_op(dsa->back.depthFailOp);
496 
497       if (!dynamic_states[VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK]) {
498          state->dsa_state.stencil[0].valuemask = dsa->front.compareMask;
499          state->dsa_state.stencil[1].valuemask = dsa->back.compareMask;
500       }
501 
502       if (!dynamic_states[VK_DYNAMIC_STATE_STENCIL_WRITE_MASK]) {
503          state->dsa_state.stencil[0].writemask = dsa->front.writeMask;
504          state->dsa_state.stencil[1].writemask = dsa->back.writeMask;
505       }
506 
507       if (dsa->stencilTestEnable) {
508          if (!dynamic_states[VK_DYNAMIC_STATE_STENCIL_REFERENCE]) {
509             state->stencil_ref.ref_value[0] = dsa->front.reference;
510             state->stencil_ref.ref_value[1] = dsa->back.reference;
511             state->stencil_ref_dirty = true;
512          }
513       }
514 
515       state->dsa_dirty = true;
516    }
517 
518    if (pipeline->graphics_create_info.pColorBlendState) {
519       const VkPipelineColorBlendStateCreateInfo *cb = pipeline->graphics_create_info.pColorBlendState;
520       int i;
521       if (cb->attachmentCount > 1)
522          state->blend_state.independent_blend_enable = true;
523       for (i = 0; i < cb->attachmentCount; i++) {
524          state->blend_state.rt[i].colormask = cb->pAttachments[i].colorWriteMask;
525          state->blend_state.rt[i].blend_enable = cb->pAttachments[i].blendEnable;
526          state->blend_state.rt[i].rgb_func = vk_conv_blend_func(cb->pAttachments[i].colorBlendOp);
527          state->blend_state.rt[i].rgb_src_factor = vk_conv_blend_factor(cb->pAttachments[i].srcColorBlendFactor);
528          state->blend_state.rt[i].rgb_dst_factor = vk_conv_blend_factor(cb->pAttachments[i].dstColorBlendFactor);
529          state->blend_state.rt[i].alpha_func = vk_conv_blend_func(cb->pAttachments[i].alphaBlendOp);
530          state->blend_state.rt[i].alpha_src_factor = vk_conv_blend_factor(cb->pAttachments[i].srcAlphaBlendFactor);
531          state->blend_state.rt[i].alpha_dst_factor = vk_conv_blend_factor(cb->pAttachments[i].dstAlphaBlendFactor);
532 
533          /* At least llvmpipe applies the blend factor prior to the blend function,
534           * regardless of what function is used. (like i965 hardware).
535           * It means for MIN/MAX the blend factor has to be stomped to ONE.
536           */
537          if (cb->pAttachments[i].colorBlendOp == VK_BLEND_OP_MIN ||
538              cb->pAttachments[i].colorBlendOp == VK_BLEND_OP_MAX) {
539             state->blend_state.rt[i].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
540             state->blend_state.rt[i].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
541          }
542 
543          if (cb->pAttachments[i].alphaBlendOp == VK_BLEND_OP_MIN ||
544              cb->pAttachments[i].alphaBlendOp == VK_BLEND_OP_MAX) {
545             state->blend_state.rt[i].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
546             state->blend_state.rt[i].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
547          }
548       }
549       state->blend_dirty = true;
550       if (!dynamic_states[VK_DYNAMIC_STATE_BLEND_CONSTANTS]) {
551          memcpy(state->blend_color.color, cb->blendConstants, 4 * sizeof(float));
552          state->blend_color_dirty = true;
553       }
554    }
555 
556    {
557       const VkPipelineVertexInputStateCreateInfo *vi = pipeline->graphics_create_info.pVertexInputState;
558       int i;
559 
560       for (i = 0; i < vi->vertexBindingDescriptionCount; i++) {
561          state->vb[i].stride = vi->pVertexBindingDescriptions[i].stride;
562       }
563 
564       int max_location = -1;
565       for (i = 0; i < vi->vertexAttributeDescriptionCount; i++) {
566          unsigned location = vi->pVertexAttributeDescriptions[i].location;
567          state->ve[location].src_offset = vi->pVertexAttributeDescriptions[i].offset;
568          state->ve[location].vertex_buffer_index = vi->pVertexAttributeDescriptions[i].binding;
569          state->ve[location].src_format = vk_format_to_pipe(vi->pVertexAttributeDescriptions[i].format);
570          state->ve[location].instance_divisor = vi->pVertexBindingDescriptions[vi->pVertexAttributeDescriptions[i].binding].inputRate;
571 
572          if ((int)location > max_location)
573             max_location = location;
574       }
575       state->num_ve = max_location + 1;
576       state->vb_dirty = true;
577       state->ve_dirty = true;
578    }
579 
580    {
581       const VkPipelineInputAssemblyStateCreateInfo *ia = pipeline->graphics_create_info.pInputAssemblyState;
582 
583       state->info.mode = vk_conv_topology(ia->topology);
584       state->info.primitive_restart = ia->primitiveRestartEnable;
585    }
586 
587    if (pipeline->graphics_create_info.pTessellationState) {
588       const VkPipelineTessellationStateCreateInfo *ts = pipeline->graphics_create_info.pTessellationState;
589       state->info.vertices_per_patch = ts->patchControlPoints;
590    } else
591       state->info.vertices_per_patch = 0;
592 
593    if (pipeline->graphics_create_info.pViewportState) {
594       const VkPipelineViewportStateCreateInfo *vpi= pipeline->graphics_create_info.pViewportState;
595       int i;
596 
597       state->num_viewports = vpi->viewportCount;
598       state->num_scissors = vpi->scissorCount;
599       state->vp_dirty = true;
600       if (!dynamic_states[VK_DYNAMIC_STATE_VIEWPORT]) {
601          for (i = 0; i < vpi->viewportCount; i++)
602             get_viewport_xform(&vpi->pViewports[i], state->viewports[i].scale, state->viewports[i].translate);
603          state->vp_dirty = true;
604       }
605       if (!dynamic_states[VK_DYNAMIC_STATE_SCISSOR]) {
606          for (i = 0; i < vpi->scissorCount; i++) {
607             const VkRect2D *ss = &vpi->pScissors[i];
608             state->scissors[i].minx = ss->offset.x;
609             state->scissors[i].miny = ss->offset.y;
610             state->scissors[i].maxx = ss->offset.x + ss->extent.width;
611             state->scissors[i].maxy = ss->offset.y + ss->extent.height;
612             state->scissor_dirty = true;
613          }
614 
615       }
616    }
617 
618    if (fb_samples != state->framebuffer.samples) {
619       state->framebuffer.samples = fb_samples;
620       state->pctx->set_framebuffer_state(state->pctx, &state->framebuffer);
621    }
622 }
623 
handle_pipeline(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)624 static void handle_pipeline(struct lvp_cmd_buffer_entry *cmd,
625                             struct rendering_state *state)
626 {
627    struct lvp_pipeline *pipeline = cmd->u.pipeline.pipeline;
628    if (pipeline->is_compute_pipeline)
629       handle_compute_pipeline(cmd, state);
630    else
631       handle_graphics_pipeline(cmd, state);
632 }
633 
handle_vertex_buffers(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)634 static void handle_vertex_buffers(struct lvp_cmd_buffer_entry *cmd,
635                                   struct rendering_state *state)
636 {
637    int i;
638    struct lvp_cmd_bind_vertex_buffers *vcb = &cmd->u.vertex_buffers;
639    for (i = 0; i < vcb->binding_count; i++) {
640       int idx = i + vcb->first;
641 
642       state->vb[idx].buffer_offset = vcb->offsets[i];
643       state->vb[idx].buffer.resource = vcb->buffers[i]->bo;
644    }
645    if (vcb->first < state->start_vb)
646       state->start_vb = vcb->first;
647    if (vcb->first + vcb->binding_count >= state->num_vb)
648       state->num_vb = vcb->first + vcb->binding_count;
649    state->vb_dirty = true;
650 }
651 
652 struct dyn_info {
653    struct {
654       uint16_t const_buffer_count;
655       uint16_t shader_buffer_count;
656       uint16_t sampler_count;
657       uint16_t sampler_view_count;
658       uint16_t image_count;
659    } stage[MESA_SHADER_STAGES];
660 
661    uint32_t dyn_index;
662    const uint32_t *dynamic_offsets;
663    uint32_t dynamic_offset_count;
664 };
665 
fill_sampler(struct pipe_sampler_state * ss,struct lvp_sampler * samp)666 static void fill_sampler(struct pipe_sampler_state *ss,
667                          struct lvp_sampler *samp)
668 {
669    ss->wrap_s = vk_conv_wrap_mode(samp->create_info.addressModeU);
670    ss->wrap_t = vk_conv_wrap_mode(samp->create_info.addressModeV);
671    ss->wrap_r = vk_conv_wrap_mode(samp->create_info.addressModeW);
672    ss->min_img_filter = samp->create_info.minFilter == VK_FILTER_LINEAR ? PIPE_TEX_FILTER_LINEAR : PIPE_TEX_FILTER_NEAREST;
673    ss->min_mip_filter = samp->create_info.mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR ? PIPE_TEX_MIPFILTER_LINEAR : PIPE_TEX_MIPFILTER_NEAREST;
674    ss->mag_img_filter = samp->create_info.magFilter == VK_FILTER_LINEAR ? PIPE_TEX_FILTER_LINEAR : PIPE_TEX_FILTER_NEAREST;
675    ss->min_lod = samp->create_info.minLod;
676    ss->max_lod = samp->create_info.maxLod;
677    ss->lod_bias = samp->create_info.mipLodBias;
678    ss->max_anisotropy = samp->create_info.maxAnisotropy;
679    ss->normalized_coords = !samp->create_info.unnormalizedCoordinates;
680    ss->compare_mode = samp->create_info.compareEnable ? PIPE_TEX_COMPARE_R_TO_TEXTURE : PIPE_TEX_COMPARE_NONE;
681    ss->compare_func = samp->create_info.compareOp;
682    ss->seamless_cube_map = true;
683 
684    switch (samp->create_info.borderColor) {
685    case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
686    case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK:
687    default:
688       memset(ss->border_color.f, 0, 4 * sizeof(float));
689       break;
690    case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
691       ss->border_color.f[0] = ss->border_color.f[1] = ss->border_color.f[2] = 0.0f;
692       ss->border_color.f[3] = 1.0f;
693       break;
694    case VK_BORDER_COLOR_INT_OPAQUE_BLACK:
695       ss->border_color.i[0] = ss->border_color.i[1] = ss->border_color.i[2] = 0;
696       ss->border_color.i[3] = 1;
697       break;
698    case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
699       ss->border_color.f[0] = ss->border_color.f[1] = ss->border_color.f[2] = 1.0f;
700       ss->border_color.f[3] = 1.0f;
701       break;
702    case VK_BORDER_COLOR_INT_OPAQUE_WHITE:
703       ss->border_color.i[0] = ss->border_color.i[1] = ss->border_color.i[2] = 1;
704       ss->border_color.i[3] = 1;
705       break;
706    }
707 }
708 
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 struct lvp_descriptor * descriptor,const struct lvp_descriptor_set_binding_layout * binding)709 static void fill_sampler_stage(struct rendering_state *state,
710                                struct dyn_info *dyn_info,
711                                gl_shader_stage stage,
712                                enum pipe_shader_type p_stage,
713                                int array_idx,
714                                const struct lvp_descriptor *descriptor,
715                                const struct lvp_descriptor_set_binding_layout *binding)
716 {
717    int ss_idx = binding->stage[stage].sampler_index;
718    if (ss_idx == -1)
719       return;
720    ss_idx += array_idx;
721    ss_idx += dyn_info->stage[stage].sampler_count;
722    fill_sampler(&state->ss[p_stage][ss_idx], descriptor->sampler);
723    if (state->num_sampler_states[p_stage] <= ss_idx)
724       state->num_sampler_states[p_stage] = ss_idx + 1;
725    state->ss_dirty[p_stage] = true;
726 }
727 
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 struct lvp_descriptor * descriptor,const struct lvp_descriptor_set_binding_layout * binding)728 static void fill_sampler_view_stage(struct rendering_state *state,
729                                     struct dyn_info *dyn_info,
730                                     gl_shader_stage stage,
731                                     enum pipe_shader_type p_stage,
732                                     int array_idx,
733                                     const struct lvp_descriptor *descriptor,
734                                     const struct lvp_descriptor_set_binding_layout *binding)
735 {
736    int sv_idx = binding->stage[stage].sampler_view_index;
737    if (sv_idx == -1)
738       return;
739    sv_idx += array_idx;
740    sv_idx += dyn_info->stage[stage].sampler_view_count;
741    struct lvp_image_view *iv = descriptor->image_view;
742    struct pipe_sampler_view templ;
743 
744    enum pipe_format pformat;
745    if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
746       pformat = vk_format_to_pipe(iv->format);
747    else if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
748       pformat = util_format_stencil_only(vk_format_to_pipe(iv->format));
749    else
750       pformat = vk_format_to_pipe(iv->format);
751    u_sampler_view_default_template(&templ,
752                                    iv->image->bo,
753                                    pformat);
754    if (iv->view_type == VK_IMAGE_VIEW_TYPE_1D)
755       templ.target = PIPE_TEXTURE_1D;
756    if (iv->view_type == VK_IMAGE_VIEW_TYPE_2D)
757       templ.target = PIPE_TEXTURE_2D;
758    if (iv->view_type == VK_IMAGE_VIEW_TYPE_CUBE)
759       templ.target = PIPE_TEXTURE_CUBE;
760    templ.u.tex.first_layer = iv->subresourceRange.baseArrayLayer;
761    templ.u.tex.last_layer = iv->subresourceRange.baseArrayLayer + lvp_get_layerCount(iv->image, &iv->subresourceRange) - 1;
762    templ.u.tex.first_level = iv->subresourceRange.baseMipLevel;
763    templ.u.tex.last_level = iv->subresourceRange.baseMipLevel + lvp_get_levelCount(iv->image, &iv->subresourceRange) - 1;
764    if (iv->components.r != VK_COMPONENT_SWIZZLE_IDENTITY)
765       templ.swizzle_r = vk_conv_swizzle(iv->components.r);
766    if (iv->components.g != VK_COMPONENT_SWIZZLE_IDENTITY)
767       templ.swizzle_g = vk_conv_swizzle(iv->components.g);
768    if (iv->components.b != VK_COMPONENT_SWIZZLE_IDENTITY)
769       templ.swizzle_b = vk_conv_swizzle(iv->components.b);
770    if (iv->components.a != VK_COMPONENT_SWIZZLE_IDENTITY)
771       templ.swizzle_a = vk_conv_swizzle(iv->components.a);
772 
773    if (util_format_is_depth_or_stencil(templ.format)) {
774       templ.swizzle_r = PIPE_SWIZZLE_X;
775       templ.swizzle_g = PIPE_SWIZZLE_0;
776       templ.swizzle_b = PIPE_SWIZZLE_0;
777    }
778 
779    if (state->sv[p_stage][sv_idx])
780       pipe_sampler_view_reference(&state->sv[p_stage][sv_idx], NULL);
781    state->sv[p_stage][sv_idx] = state->pctx->create_sampler_view(state->pctx, iv->image->bo, &templ);
782    if (state->num_sampler_views[p_stage] <= sv_idx)
783       state->num_sampler_views[p_stage] = sv_idx + 1;
784    state->sv_dirty[p_stage] = true;
785 }
786 
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 struct lvp_descriptor * descriptor,const struct lvp_descriptor_set_binding_layout * binding)787 static void fill_sampler_buffer_view_stage(struct rendering_state *state,
788                                            struct dyn_info *dyn_info,
789                                            gl_shader_stage stage,
790                                            enum pipe_shader_type p_stage,
791                                            int array_idx,
792                                            const struct lvp_descriptor *descriptor,
793                                            const struct lvp_descriptor_set_binding_layout *binding)
794 {
795    int sv_idx = binding->stage[stage].sampler_view_index;
796    if (sv_idx == -1)
797       return;
798    sv_idx += array_idx;
799    sv_idx += dyn_info->stage[stage].sampler_view_count;
800    struct lvp_buffer_view *bv = descriptor->buffer_view;
801    struct pipe_sampler_view templ;
802    memset(&templ, 0, sizeof(templ));
803    templ.target = PIPE_BUFFER;
804    templ.swizzle_r = PIPE_SWIZZLE_X;
805    templ.swizzle_g = PIPE_SWIZZLE_Y;
806    templ.swizzle_b = PIPE_SWIZZLE_Z;
807    templ.swizzle_a = PIPE_SWIZZLE_W;
808    templ.format = bv->pformat;
809    templ.u.buf.offset = bv->offset + bv->buffer->offset;
810    templ.u.buf.size = bv->range == VK_WHOLE_SIZE ? (bv->buffer->size - bv->offset) : bv->range;
811    templ.texture = bv->buffer->bo;
812    templ.context = state->pctx;
813 
814    if (state->sv[p_stage][sv_idx])
815       pipe_sampler_view_reference(&state->sv[p_stage][sv_idx], NULL);
816    state->sv[p_stage][sv_idx] = state->pctx->create_sampler_view(state->pctx, bv->buffer->bo, &templ);
817    if (state->num_sampler_views[p_stage] <= sv_idx)
818       state->num_sampler_views[p_stage] = sv_idx + 1;
819    state->sv_dirty[p_stage] = true;
820 }
821 
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 struct lvp_descriptor * descriptor,const struct lvp_descriptor_set_binding_layout * binding)822 static void fill_image_view_stage(struct rendering_state *state,
823                                   struct dyn_info *dyn_info,
824                                   gl_shader_stage stage,
825                                   enum pipe_shader_type p_stage,
826                                   int array_idx,
827                                   const struct lvp_descriptor *descriptor,
828                                   const struct lvp_descriptor_set_binding_layout *binding)
829 {
830    struct lvp_image_view *iv = descriptor->image_view;
831    int idx = binding->stage[stage].image_index;
832    if (idx == -1)
833       return;
834    idx += array_idx;
835    idx += dyn_info->stage[stage].image_count;
836    state->iv[p_stage][idx].resource = iv->image->bo;
837    if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
838       state->iv[p_stage][idx].format = vk_format_to_pipe(iv->format);
839    else if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
840       state->iv[p_stage][idx].format = util_format_stencil_only(vk_format_to_pipe(iv->format));
841    else
842       state->iv[p_stage][idx].format = vk_format_to_pipe(iv->format);
843 
844    if (iv->view_type == VK_IMAGE_VIEW_TYPE_3D) {
845       state->iv[p_stage][idx].u.tex.first_layer = 0;
846       state->iv[p_stage][idx].u.tex.last_layer = u_minify(iv->image->bo->depth0, iv->subresourceRange.baseMipLevel) - 1;
847    } else {
848       state->iv[p_stage][idx].u.tex.first_layer = iv->subresourceRange.baseArrayLayer;
849       state->iv[p_stage][idx].u.tex.last_layer = iv->subresourceRange.baseArrayLayer + lvp_get_layerCount(iv->image, &iv->subresourceRange) - 1;
850    }
851    state->iv[p_stage][idx].u.tex.level = iv->subresourceRange.baseMipLevel;
852    if (state->num_shader_images[p_stage] <= idx)
853       state->num_shader_images[p_stage] = idx + 1;
854    state->iv_dirty[p_stage] = true;
855 }
856 
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 struct lvp_descriptor * descriptor,const struct lvp_descriptor_set_binding_layout * binding)857 static void fill_image_buffer_view_stage(struct rendering_state *state,
858                                          struct dyn_info *dyn_info,
859                                          gl_shader_stage stage,
860                                          enum pipe_shader_type p_stage,
861                                          int array_idx,
862                                          const struct lvp_descriptor *descriptor,
863                                          const struct lvp_descriptor_set_binding_layout *binding)
864 {
865    struct lvp_buffer_view *bv = descriptor->buffer_view;
866    int idx = binding->stage[stage].image_index;
867    if (idx == -1)
868       return;
869    idx += array_idx;
870    idx += dyn_info->stage[stage].image_count;
871    state->iv[p_stage][idx].resource = bv->buffer->bo;
872    state->iv[p_stage][idx].format = bv->pformat;
873    state->iv[p_stage][idx].u.buf.offset = bv->offset + bv->buffer->offset;
874    state->iv[p_stage][idx].u.buf.size = bv->range == VK_WHOLE_SIZE ? (bv->buffer->size - bv->offset): bv->range;
875    if (state->num_shader_images[p_stage] <= idx)
876       state->num_shader_images[p_stage] = idx + 1;
877    state->iv_dirty[p_stage] = true;
878 }
879 
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,const struct lvp_descriptor * descriptor)880 static void handle_descriptor(struct rendering_state *state,
881                               struct dyn_info *dyn_info,
882                               const struct lvp_descriptor_set_binding_layout *binding,
883                               gl_shader_stage stage,
884                               enum pipe_shader_type p_stage,
885                               int array_idx,
886                               const struct lvp_descriptor *descriptor)
887 {
888    bool is_dynamic = descriptor->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
889       descriptor->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
890 
891    switch (descriptor->type) {
892    case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
893    case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
894       fill_image_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
895       break;
896    }
897    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
898    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: {
899       int idx = binding->stage[stage].const_buffer_index;
900       if (idx == -1)
901          return;
902       idx += array_idx;
903       idx += dyn_info->stage[stage].const_buffer_count;
904       state->const_buffer[p_stage][idx].buffer = descriptor->buf.buffer->bo;
905       state->const_buffer[p_stage][idx].buffer_offset = descriptor->buf.offset + descriptor->buf.buffer->offset;
906       if (is_dynamic) {
907          uint32_t offset = dyn_info->dynamic_offsets[dyn_info->dyn_index + binding->dynamic_index + array_idx];
908          state->const_buffer[p_stage][idx].buffer_offset += offset;
909       }
910       if (descriptor->buf.range == VK_WHOLE_SIZE)
911          state->const_buffer[p_stage][idx].buffer_size = descriptor->buf.buffer->bo->width0 - state->const_buffer[p_stage][idx].buffer_offset;
912       else
913          state->const_buffer[p_stage][idx].buffer_size = descriptor->buf.range;
914       if (state->num_const_bufs[p_stage] <= idx)
915          state->num_const_bufs[p_stage] = idx + 1;
916       state->constbuf_dirty[p_stage] = true;
917       break;
918    }
919    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
920    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
921       int idx = binding->stage[stage].shader_buffer_index;
922       if (idx == -1)
923          return;
924       idx += array_idx;
925       idx += dyn_info->stage[stage].shader_buffer_count;
926       state->sb[p_stage][idx].buffer = descriptor->buf.buffer->bo;
927       state->sb[p_stage][idx].buffer_offset = descriptor->buf.offset + descriptor->buf.buffer->offset;
928       if (is_dynamic) {
929          uint32_t offset = dyn_info->dynamic_offsets[dyn_info->dyn_index + binding->dynamic_index + array_idx];
930          state->sb[p_stage][idx].buffer_offset += offset;
931       }
932       if (descriptor->buf.range == VK_WHOLE_SIZE)
933          state->sb[p_stage][idx].buffer_size = descriptor->buf.buffer->bo->width0 - state->sb[p_stage][idx].buffer_offset;
934       else
935          state->sb[p_stage][idx].buffer_size = descriptor->buf.range;
936       if (state->num_shader_buffers[p_stage] <= idx)
937          state->num_shader_buffers[p_stage] = idx + 1;
938       state->sb_dirty[p_stage] = true;
939       break;
940    }
941    case VK_DESCRIPTOR_TYPE_SAMPLER:
942       if (!descriptor->sampler)
943          return;
944       fill_sampler_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
945       break;
946    case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
947       fill_sampler_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
948       break;
949    case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
950       fill_sampler_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
951       fill_sampler_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
952       break;
953    case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
954       fill_sampler_buffer_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
955       break;
956    case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
957       fill_image_buffer_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
958       break;
959    default:
960       fprintf(stderr, "Unhandled descriptor set %d\n", descriptor->type);
961       break;
962    }
963 }
964 
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)965 static void handle_set_stage(struct rendering_state *state,
966                              struct dyn_info *dyn_info,
967                              const struct lvp_descriptor_set *set,
968                              gl_shader_stage stage,
969                              enum pipe_shader_type p_stage)
970 {
971    int j;
972    for (j = 0; j < set->layout->binding_count; j++) {
973       const struct lvp_descriptor_set_binding_layout *binding;
974       const struct lvp_descriptor *descriptor;
975       binding = &set->layout->binding[j];
976 
977       if (binding->valid) {
978          for (int i = 0; i < binding->array_size; i++) {
979             descriptor = &set->descriptors[binding->descriptor_index + i];
980             handle_descriptor(state, dyn_info, binding, stage, p_stage, i, descriptor);
981          }
982       }
983    }
984 }
985 
increment_dyn_info(struct dyn_info * dyn_info,struct lvp_descriptor_set_layout * layout,bool inc_dyn)986 static void increment_dyn_info(struct dyn_info *dyn_info,
987                                struct lvp_descriptor_set_layout *layout, bool inc_dyn)
988 {
989    for (gl_shader_stage stage = MESA_SHADER_VERTEX; stage < MESA_SHADER_STAGES; stage++) {
990       dyn_info->stage[stage].const_buffer_count += layout->stage[stage].const_buffer_count;
991       dyn_info->stage[stage].shader_buffer_count += layout->stage[stage].shader_buffer_count;
992       dyn_info->stage[stage].sampler_count += layout->stage[stage].sampler_count;
993       dyn_info->stage[stage].sampler_view_count += layout->stage[stage].sampler_view_count;
994       dyn_info->stage[stage].image_count += layout->stage[stage].image_count;
995    }
996    if (inc_dyn)
997       dyn_info->dyn_index += layout->dynamic_offset_count;
998 }
999 
handle_compute_descriptor_sets(struct lvp_cmd_buffer_entry * cmd,struct dyn_info * dyn_info,struct rendering_state * state)1000 static void handle_compute_descriptor_sets(struct lvp_cmd_buffer_entry *cmd,
1001                                            struct dyn_info *dyn_info,
1002                                            struct rendering_state *state)
1003 {
1004    struct lvp_cmd_bind_descriptor_sets *bds = &cmd->u.descriptor_sets;
1005    int i;
1006 
1007    for (i = 0; i < bds->first; i++) {
1008       increment_dyn_info(dyn_info, bds->layout->set[i].layout, false);
1009    }
1010    for (i = 0; i < bds->count; i++) {
1011       const struct lvp_descriptor_set *set = bds->sets[i];
1012 
1013       if (set->layout->shader_stages & VK_SHADER_STAGE_COMPUTE_BIT)
1014          handle_set_stage(state, dyn_info, set, MESA_SHADER_COMPUTE, PIPE_SHADER_COMPUTE);
1015       increment_dyn_info(dyn_info, bds->layout->set[bds->first + i].layout, true);
1016    }
1017 }
1018 
handle_descriptor_sets(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1019 static void handle_descriptor_sets(struct lvp_cmd_buffer_entry *cmd,
1020                                    struct rendering_state *state)
1021 {
1022    struct lvp_cmd_bind_descriptor_sets *bds = &cmd->u.descriptor_sets;
1023    int i;
1024    struct dyn_info dyn_info;
1025 
1026    dyn_info.dyn_index = 0;
1027    dyn_info.dynamic_offsets = bds->dynamic_offsets;
1028    dyn_info.dynamic_offset_count = bds->dynamic_offset_count;
1029 
1030    memset(dyn_info.stage, 0, sizeof(dyn_info.stage));
1031    if (bds->bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
1032       handle_compute_descriptor_sets(cmd, &dyn_info, state);
1033       return;
1034    }
1035 
1036    for (i = 0; i < bds->first; i++) {
1037       increment_dyn_info(&dyn_info, bds->layout->set[i].layout, false);
1038    }
1039 
1040    for (i = 0; i < bds->count; i++) {
1041       const struct lvp_descriptor_set *set = bds->sets[i];
1042 
1043       if (set->layout->shader_stages & VK_SHADER_STAGE_VERTEX_BIT)
1044          handle_set_stage(state, &dyn_info, set, MESA_SHADER_VERTEX, PIPE_SHADER_VERTEX);
1045 
1046       if (set->layout->shader_stages & VK_SHADER_STAGE_FRAGMENT_BIT)
1047          handle_set_stage(state, &dyn_info, set, MESA_SHADER_FRAGMENT, PIPE_SHADER_FRAGMENT);
1048 
1049       if (set->layout->shader_stages & VK_SHADER_STAGE_GEOMETRY_BIT)
1050          handle_set_stage(state, &dyn_info, set, MESA_SHADER_GEOMETRY, PIPE_SHADER_GEOMETRY);
1051 
1052       if (set->layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
1053          handle_set_stage(state, &dyn_info, set, MESA_SHADER_TESS_CTRL, PIPE_SHADER_TESS_CTRL);
1054 
1055       if (set->layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
1056          handle_set_stage(state, &dyn_info, set, MESA_SHADER_TESS_EVAL, PIPE_SHADER_TESS_EVAL);
1057       increment_dyn_info(&dyn_info, bds->layout->set[bds->first + i].layout, true);
1058    }
1059 }
1060 
add_img_view_surface(struct rendering_state * state,struct lvp_image_view * imgv,VkFormat format,int width,int height)1061 static void add_img_view_surface(struct rendering_state *state,
1062                                  struct lvp_image_view *imgv, VkFormat format, int width, int height)
1063 {
1064    if (!imgv->surface) {
1065       struct pipe_surface template;
1066 
1067       memset(&template, 0, sizeof(struct pipe_surface));
1068 
1069       template.format = vk_format_to_pipe(format);
1070       template.width = width;
1071       template.height = height;
1072       template.u.tex.first_layer = imgv->subresourceRange.baseArrayLayer;
1073       template.u.tex.last_layer = imgv->subresourceRange.baseArrayLayer + lvp_get_layerCount(imgv->image, &imgv->subresourceRange) - 1;
1074       template.u.tex.level = imgv->subresourceRange.baseMipLevel;
1075 
1076       if (template.format == PIPE_FORMAT_NONE)
1077          return;
1078       imgv->surface = state->pctx->create_surface(state->pctx,
1079                                                   imgv->image->bo, &template);
1080    }
1081 }
1082 
1083 static inline bool
attachment_needs_clear(struct rendering_state * state,uint32_t a)1084 attachment_needs_clear(struct rendering_state *state,
1085                        uint32_t a)
1086 {
1087    return (a != VK_ATTACHMENT_UNUSED &&
1088            state->pending_clear_aspects[a]);
1089 }
1090 
1091 static bool
subpass_needs_clear(struct rendering_state * state)1092 subpass_needs_clear(struct rendering_state *state)
1093 {
1094    uint32_t a;
1095    const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
1096    for (uint32_t i = 0; i < subpass->color_count; i++) {
1097       a = subpass->color_attachments[i].attachment;
1098       if (attachment_needs_clear(state, a))
1099          return true;
1100    }
1101    if (subpass->depth_stencil_attachment) {
1102       a = subpass->depth_stencil_attachment->attachment;
1103       if (attachment_needs_clear(state, a))
1104          return true;
1105    }
1106    return false;
1107 }
1108 
render_subpass_clear(struct rendering_state * state)1109 static void render_subpass_clear(struct rendering_state *state)
1110 {
1111    const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
1112 
1113    if (!subpass_needs_clear(state))
1114       return;
1115 
1116    for (unsigned i = 0; i < subpass->color_count; i++) {
1117       uint32_t a = subpass->color_attachments[i].attachment;
1118 
1119       if (!attachment_needs_clear(state, a))
1120          continue;
1121 
1122       struct lvp_render_pass_attachment *att = &state->pass->attachments[a];
1123       struct lvp_image_view *imgv = state->vk_framebuffer->attachments[a];
1124 
1125       add_img_view_surface(state, imgv, att->format, state->framebuffer.width, state->framebuffer.height);
1126 
1127       union pipe_color_union color_clear_val = { 0 };
1128       const VkClearValue value = state->attachments[a].clear_value;
1129       color_clear_val.ui[0] = value.color.uint32[0];
1130       color_clear_val.ui[1] = value.color.uint32[1];
1131       color_clear_val.ui[2] = value.color.uint32[2];
1132       color_clear_val.ui[3] = value.color.uint32[3];
1133       state->pctx->clear_render_target(state->pctx,
1134                                        imgv->surface,
1135                                        &color_clear_val,
1136                                        state->render_area.offset.x, state->render_area.offset.y,
1137                                        state->render_area.extent.width, state->render_area.extent.height,
1138                                        false);
1139 
1140       state->pending_clear_aspects[a] = 0;
1141    }
1142 
1143    if (subpass->depth_stencil_attachment) {
1144       uint32_t ds = subpass->depth_stencil_attachment->attachment;
1145 
1146       if (!attachment_needs_clear(state, ds))
1147          return;
1148 
1149       struct lvp_render_pass_attachment *att = &state->pass->attachments[ds];
1150       struct lvp_image_view *imgv = state->vk_framebuffer->attachments[ds];
1151 
1152       add_img_view_surface(state, imgv, att->format, state->framebuffer.width, state->framebuffer.height);
1153 
1154       if (util_format_is_depth_or_stencil(imgv->surface->format)) {
1155          const struct util_format_description *desc = util_format_description(imgv->surface->format);
1156          double dclear_val = 0;
1157          uint32_t sclear_val = 0;
1158          uint32_t ds_clear_flags = 0;
1159 
1160          if (util_format_has_stencil(desc) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
1161             ds_clear_flags |= PIPE_CLEAR_STENCIL;
1162             sclear_val = state->attachments[ds].clear_value.depthStencil.stencil;
1163          }
1164          if (util_format_has_depth(desc) && att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
1165             ds_clear_flags |= PIPE_CLEAR_DEPTH;
1166             dclear_val = state->attachments[ds].clear_value.depthStencil.depth;
1167          }
1168 
1169          if (ds_clear_flags)
1170             state->pctx->clear_depth_stencil(state->pctx,
1171                                              imgv->surface,
1172                                              ds_clear_flags,
1173                                              dclear_val, sclear_val,
1174                                              state->render_area.offset.x, state->render_area.offset.y,
1175                                              state->render_area.extent.width, state->render_area.extent.height,
1176                                              false);
1177          state->pending_clear_aspects[ds] = 0;
1178       }
1179    }
1180 
1181 }
1182 
render_pass_resolve(struct rendering_state * state)1183 static void render_pass_resolve(struct rendering_state *state)
1184 {
1185    const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
1186    if (!subpass->has_color_resolve)
1187       return;
1188    for (uint32_t i = 0; i < subpass->color_count; i++) {
1189       struct lvp_subpass_attachment src_att = subpass->color_attachments[i];
1190       struct lvp_subpass_attachment dst_att = subpass->resolve_attachments[i];
1191 
1192       if (dst_att.attachment == VK_ATTACHMENT_UNUSED)
1193          continue;
1194 
1195       struct lvp_image_view *src_imgv = state->vk_framebuffer->attachments[src_att.attachment];
1196       struct lvp_image_view *dst_imgv = state->vk_framebuffer->attachments[dst_att.attachment];
1197 
1198       struct pipe_blit_info info;
1199       memset(&info, 0, sizeof(info));
1200 
1201       info.src.resource = src_imgv->image->bo;
1202       info.dst.resource = dst_imgv->image->bo;
1203       info.src.format = src_imgv->pformat;
1204       info.dst.format = dst_imgv->pformat;
1205       info.filter = PIPE_TEX_FILTER_NEAREST;
1206       info.mask = PIPE_MASK_RGBA;
1207       info.src.box.x = state->render_area.offset.x;
1208       info.src.box.y = state->render_area.offset.y;
1209       info.src.box.width = state->render_area.extent.width;
1210       info.src.box.height = state->render_area.extent.height;
1211       info.src.box.depth = state->vk_framebuffer->layers;
1212 
1213       info.dst.box = info.src.box;
1214 
1215       state->pctx->blit(state->pctx, &info);
1216    }
1217 }
1218 
begin_render_subpass(struct rendering_state * state,int subpass_idx)1219 static void begin_render_subpass(struct rendering_state *state,
1220                                  int subpass_idx)
1221 {
1222    state->subpass = subpass_idx;
1223 
1224    render_subpass_clear(state);
1225 
1226    state->framebuffer.nr_cbufs = 0;
1227 
1228    const struct lvp_subpass *subpass = &state->pass->subpasses[subpass_idx];
1229    for (unsigned i = 0; i < subpass->color_count; i++) {
1230       struct lvp_subpass_attachment *color_att = &subpass->color_attachments[i];
1231       if (color_att->attachment != VK_ATTACHMENT_UNUSED) {
1232          struct lvp_image_view *imgv = state->vk_framebuffer->attachments[color_att->attachment];
1233 
1234          add_img_view_surface(state, imgv, state->pass->attachments[color_att->attachment].format, state->framebuffer.width, state->framebuffer.height);
1235          state->framebuffer.cbufs[state->framebuffer.nr_cbufs] = imgv->surface;
1236       } else
1237          state->framebuffer.cbufs[state->framebuffer.nr_cbufs] = NULL;
1238       state->framebuffer.nr_cbufs++;
1239    }
1240 
1241    if (subpass->depth_stencil_attachment) {
1242       struct lvp_subpass_attachment *ds_att = subpass->depth_stencil_attachment;
1243 
1244       if (ds_att->attachment != VK_ATTACHMENT_UNUSED) {
1245          struct lvp_image_view *imgv = state->vk_framebuffer->attachments[ds_att->attachment];
1246          add_img_view_surface(state, imgv, state->pass->attachments[ds_att->attachment].format, state->framebuffer.width, state->framebuffer.height);
1247          state->framebuffer.zsbuf = imgv->surface;
1248       }
1249    }
1250 
1251    state->pctx->set_framebuffer_state(state->pctx,
1252                                       &state->framebuffer);
1253 }
1254 
handle_begin_render_pass(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1255 static void handle_begin_render_pass(struct lvp_cmd_buffer_entry *cmd,
1256                                      struct rendering_state *state)
1257 {
1258    state->pass = cmd->u.begin_render_pass.render_pass;
1259    state->vk_framebuffer = cmd->u.begin_render_pass.framebuffer;
1260    state->render_area = cmd->u.begin_render_pass.render_area;
1261 
1262    state->attachments = cmd->u.begin_render_pass.attachments;
1263 
1264    state->framebuffer.width = state->vk_framebuffer->width;
1265    state->framebuffer.height = state->vk_framebuffer->height;
1266    state->framebuffer.layers = state->vk_framebuffer->layers;
1267 
1268    if (state->num_pending_aspects < state->pass->attachment_count) {
1269       state->pending_clear_aspects = realloc(state->pending_clear_aspects, sizeof(VkImageAspectFlags) * state->pass->attachment_count);
1270       state->num_pending_aspects = state->pass->attachment_count;
1271    }
1272 
1273    for (unsigned a = 0; a < state->pass->attachment_count; a++) {
1274       state->pending_clear_aspects[a] = state->attachments[a].pending_clear_aspects;
1275    }
1276    begin_render_subpass(state, 0);
1277 }
1278 
handle_end_render_pass(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1279 static void handle_end_render_pass(struct lvp_cmd_buffer_entry *cmd,
1280                                    struct rendering_state *state)
1281 {
1282    state->pctx->flush(state->pctx, NULL, 0);
1283 
1284    render_pass_resolve(state);
1285 
1286    state->attachments = NULL;
1287    state->pass = NULL;
1288    state->subpass = 0;
1289 }
1290 
handle_next_subpass(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1291 static void handle_next_subpass(struct lvp_cmd_buffer_entry *cmd,
1292                                 struct rendering_state *state)
1293 {
1294    state->pctx->flush(state->pctx, NULL, 0);
1295    render_pass_resolve(state);
1296    state->subpass++;
1297    begin_render_subpass(state, state->subpass);
1298 }
1299 
handle_draw(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1300 static void handle_draw(struct lvp_cmd_buffer_entry *cmd,
1301                         struct rendering_state *state)
1302 {
1303    state->info.index_size = 0;
1304    state->info.indirect = NULL;
1305    state->info.index.resource = NULL;
1306    state->info.start = cmd->u.draw.first_vertex;
1307    state->info.count = cmd->u.draw.vertex_count;
1308    state->info.start_instance = cmd->u.draw.first_instance;
1309    state->info.instance_count = cmd->u.draw.instance_count;
1310    state->pctx->draw_vbo(state->pctx, &state->info);
1311 }
1312 
handle_set_viewport(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1313 static void handle_set_viewport(struct lvp_cmd_buffer_entry *cmd,
1314                                 struct rendering_state *state)
1315 {
1316    int i;
1317 
1318    for (i = 0; i < cmd->u.set_viewport.viewport_count; i++) {
1319       int idx = i + cmd->u.set_viewport.first_viewport;
1320       const VkViewport *vp = &cmd->u.set_viewport.viewports[i];
1321       get_viewport_xform(vp, state->viewports[idx].scale, state->viewports[idx].translate);
1322    }
1323    state->vp_dirty = true;
1324 }
1325 
handle_set_scissor(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1326 static void handle_set_scissor(struct lvp_cmd_buffer_entry *cmd,
1327                                struct rendering_state *state)
1328 {
1329    int i;
1330 
1331    for (i = 0; i < cmd->u.set_scissor.scissor_count; i++) {
1332       int idx = i + cmd->u.set_scissor.first_scissor;
1333       const VkRect2D *ss = &cmd->u.set_scissor.scissors[i];
1334       state->scissors[idx].minx = ss->offset.x;
1335       state->scissors[idx].miny = ss->offset.y;
1336       state->scissors[idx].maxx = ss->offset.x + ss->extent.width;
1337       state->scissors[idx].maxy = ss->offset.y + ss->extent.height;
1338    }
1339    state->scissor_dirty = true;
1340 }
1341 
handle_set_line_width(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1342 static void handle_set_line_width(struct lvp_cmd_buffer_entry *cmd,
1343                                   struct rendering_state *state)
1344 {
1345    state->rs_state.line_width = cmd->u.set_line_width.line_width;
1346    state->rs_dirty = true;
1347 }
1348 
handle_set_depth_bias(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1349 static void handle_set_depth_bias(struct lvp_cmd_buffer_entry *cmd,
1350                                   struct rendering_state *state)
1351 {
1352    state->rs_state.offset_units = cmd->u.set_depth_bias.constant_factor;
1353    state->rs_state.offset_scale = cmd->u.set_depth_bias.slope_factor;
1354    state->rs_state.offset_clamp = cmd->u.set_depth_bias.clamp;
1355    state->rs_dirty = true;
1356 }
1357 
handle_set_blend_constants(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1358 static void handle_set_blend_constants(struct lvp_cmd_buffer_entry *cmd,
1359                                        struct rendering_state *state)
1360 {
1361    memcpy(state->blend_color.color, cmd->u.set_blend_constants.blend_constants, 4 * sizeof(float));
1362    state->blend_color_dirty = true;
1363 }
1364 
handle_set_depth_bounds(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1365 static void handle_set_depth_bounds(struct lvp_cmd_buffer_entry *cmd,
1366                                     struct rendering_state *state)
1367 {
1368    state->dsa_state.depth.bounds_min = cmd->u.set_depth_bounds.min_depth;
1369    state->dsa_state.depth.bounds_max = cmd->u.set_depth_bounds.max_depth;
1370    state->dsa_dirty = true;
1371 }
1372 
handle_set_stencil_compare_mask(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1373 static void handle_set_stencil_compare_mask(struct lvp_cmd_buffer_entry *cmd,
1374                                             struct rendering_state *state)
1375 {
1376    if (cmd->u.stencil_vals.face_mask & VK_STENCIL_FACE_FRONT_BIT)
1377       state->dsa_state.stencil[0].valuemask = cmd->u.stencil_vals.value;
1378    if (cmd->u.stencil_vals.face_mask & VK_STENCIL_FACE_BACK_BIT)
1379       state->dsa_state.stencil[1].valuemask = cmd->u.stencil_vals.value;
1380    state->dsa_dirty = true;
1381 }
1382 
handle_set_stencil_write_mask(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1383 static void handle_set_stencil_write_mask(struct lvp_cmd_buffer_entry *cmd,
1384                                           struct rendering_state *state)
1385 {
1386    if (cmd->u.stencil_vals.face_mask & VK_STENCIL_FACE_FRONT_BIT)
1387       state->dsa_state.stencil[0].writemask = cmd->u.stencil_vals.value;
1388    if (cmd->u.stencil_vals.face_mask & VK_STENCIL_FACE_BACK_BIT)
1389       state->dsa_state.stencil[1].writemask = cmd->u.stencil_vals.value;
1390    state->dsa_dirty = true;
1391 }
1392 
handle_set_stencil_reference(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1393 static void handle_set_stencil_reference(struct lvp_cmd_buffer_entry *cmd,
1394                                          struct rendering_state *state)
1395 {
1396    if (cmd->u.stencil_vals.face_mask & VK_STENCIL_FACE_FRONT_BIT)
1397       state->stencil_ref.ref_value[0] = cmd->u.stencil_vals.value;
1398    if (cmd->u.stencil_vals.face_mask & VK_STENCIL_FACE_BACK_BIT)
1399       state->stencil_ref.ref_value[1] = cmd->u.stencil_vals.value;
1400    state->stencil_ref_dirty = true;
1401 }
1402 
1403 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)1404 copy_depth_rect(ubyte * dst,
1405                 enum pipe_format dst_format,
1406                 unsigned dst_stride,
1407                 unsigned dst_x,
1408                 unsigned dst_y,
1409                 unsigned width,
1410                 unsigned height,
1411                 const ubyte * src,
1412                 enum pipe_format src_format,
1413                 int src_stride,
1414                 unsigned src_x,
1415                 unsigned src_y)
1416 {
1417    int src_stride_pos = src_stride < 0 ? -src_stride : src_stride;
1418    int src_blocksize = util_format_get_blocksize(src_format);
1419    int src_blockwidth = util_format_get_blockwidth(src_format);
1420    int src_blockheight = util_format_get_blockheight(src_format);
1421    int dst_blocksize = util_format_get_blocksize(dst_format);
1422    int dst_blockwidth = util_format_get_blockwidth(dst_format);
1423    int dst_blockheight = util_format_get_blockheight(dst_format);
1424 
1425    assert(src_blocksize > 0);
1426    assert(src_blockwidth > 0);
1427    assert(src_blockheight > 0);
1428 
1429    dst_x /= dst_blockwidth;
1430    dst_y /= dst_blockheight;
1431    width = (width + src_blockwidth - 1)/src_blockwidth;
1432    height = (height + src_blockheight - 1)/src_blockheight;
1433    src_x /= src_blockwidth;
1434    src_y /= src_blockheight;
1435 
1436    dst += dst_x * dst_blocksize;
1437    src += src_x * src_blocksize;
1438    dst += dst_y * dst_stride;
1439    src += src_y * src_stride_pos;
1440 
1441    if (dst_format == PIPE_FORMAT_S8_UINT) {
1442       if (src_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
1443          util_format_z32_float_s8x24_uint_unpack_s_8uint(dst, dst_stride,
1444                                                          src, src_stride,
1445                                                          width, height);
1446       } else if (src_format == PIPE_FORMAT_Z24_UNORM_S8_UINT) {
1447          util_format_z24_unorm_s8_uint_unpack_s_8uint(dst, dst_stride,
1448                                                       src, src_stride,
1449                                                       width, height);
1450       } else {
1451       }
1452    } else if (dst_format == PIPE_FORMAT_Z24X8_UNORM) {
1453       util_format_z24_unorm_s8_uint_unpack_z24(dst, dst_stride,
1454                                                src, src_stride,
1455                                                width, height);
1456    } else if (dst_format == PIPE_FORMAT_Z32_FLOAT) {
1457       if (src_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
1458          util_format_z32_float_s8x24_uint_unpack_z_float((float *)dst, dst_stride,
1459                                                          src, src_stride,
1460                                                          width, height);
1461       }
1462    } else if (dst_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
1463       if (src_format == PIPE_FORMAT_Z32_FLOAT)
1464          util_format_z32_float_s8x24_uint_pack_z_float(dst, dst_stride,
1465                                                        (float *)src, src_stride,
1466                                                        width, height);
1467       else if (src_format == PIPE_FORMAT_S8_UINT)
1468          util_format_z32_float_s8x24_uint_pack_s_8uint(dst, dst_stride,
1469                                                        src, src_stride,
1470                                                        width, height);
1471    } else if (dst_format == PIPE_FORMAT_Z24_UNORM_S8_UINT) {
1472       if (src_format == PIPE_FORMAT_S8_UINT)
1473          util_format_z24_unorm_s8_uint_pack_s_8uint(dst, dst_stride,
1474                                                     src, src_stride,
1475                                                     width, height);
1476       if (src_format == PIPE_FORMAT_Z24X8_UNORM)
1477          util_format_z24_unorm_s8_uint_pack_z24(dst, dst_stride,
1478                                                 src, src_stride,
1479                                                 width, height);
1480    }
1481 }
1482 
1483 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)1484 copy_depth_box(ubyte *dst,
1485                enum pipe_format dst_format,
1486                unsigned dst_stride, unsigned dst_slice_stride,
1487                unsigned dst_x, unsigned dst_y, unsigned dst_z,
1488                unsigned width, unsigned height, unsigned depth,
1489                const ubyte * src,
1490                enum pipe_format src_format,
1491                int src_stride, unsigned src_slice_stride,
1492                unsigned src_x, unsigned src_y, unsigned src_z)
1493 {
1494    unsigned z;
1495    dst += dst_z * dst_slice_stride;
1496    src += src_z * src_slice_stride;
1497    for (z = 0; z < depth; ++z) {
1498       copy_depth_rect(dst,
1499                       dst_format,
1500                       dst_stride,
1501                       dst_x, dst_y,
1502                       width, height,
1503                       src,
1504                       src_format,
1505                       src_stride,
1506                       src_x, src_y);
1507 
1508       dst += dst_slice_stride;
1509       src += src_slice_stride;
1510    }
1511 }
1512 
handle_copy_image_to_buffer(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1513 static void handle_copy_image_to_buffer(struct lvp_cmd_buffer_entry *cmd,
1514                                         struct rendering_state *state)
1515 {
1516    int i;
1517    struct lvp_cmd_copy_image_to_buffer *copycmd = &cmd->u.img_to_buffer;
1518    struct pipe_box box, dbox;
1519    struct pipe_transfer *src_t, *dst_t;
1520    ubyte *src_data, *dst_data;
1521 
1522    state->pctx->flush(state->pctx, NULL, 0);
1523 
1524    for (i = 0; i < copycmd->region_count; i++) {
1525 
1526       box.x = copycmd->regions[i].imageOffset.x;
1527       box.y = copycmd->regions[i].imageOffset.y;
1528       box.z = copycmd->src->type == VK_IMAGE_TYPE_3D ? copycmd->regions[i].imageOffset.z : copycmd->regions[i].imageSubresource.baseArrayLayer;
1529       box.width = copycmd->regions[i].imageExtent.width;
1530       box.height = copycmd->regions[i].imageExtent.height;
1531       box.depth = copycmd->src->type == VK_IMAGE_TYPE_3D ? copycmd->regions[i].imageExtent.depth : copycmd->regions[i].imageSubresource.layerCount;
1532 
1533       src_data = state->pctx->transfer_map(state->pctx,
1534                                            copycmd->src->bo,
1535                                            copycmd->regions[i].imageSubresource.mipLevel,
1536                                            PIPE_MAP_READ,
1537                                            &box,
1538                                            &src_t);
1539 
1540       dbox.x = copycmd->regions[i].bufferOffset;
1541       dbox.y = 0;
1542       dbox.z = 0;
1543       dbox.width = copycmd->dst->bo->width0;
1544       dbox.height = 1;
1545       dbox.depth = 1;
1546       dst_data = state->pctx->transfer_map(state->pctx,
1547                                            copycmd->dst->bo,
1548                                            0,
1549                                            PIPE_MAP_WRITE,
1550                                            &dbox,
1551                                            &dst_t);
1552 
1553       enum pipe_format src_format = copycmd->src->bo->format;
1554       enum pipe_format dst_format = src_format;
1555       if (util_format_is_depth_or_stencil(src_format)) {
1556          if (copycmd->regions[i].imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) {
1557             dst_format = util_format_get_depth_only(src_format);
1558          } else if (copycmd->regions[i].imageSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {
1559             dst_format = PIPE_FORMAT_S8_UINT;
1560          }
1561       }
1562 
1563       unsigned buffer_row_len = util_format_get_stride(dst_format, copycmd->regions[i].bufferRowLength);
1564       if (buffer_row_len == 0)
1565          buffer_row_len = util_format_get_stride(dst_format, copycmd->regions[i].imageExtent.width);
1566       unsigned buffer_image_height = copycmd->regions[i].bufferImageHeight;
1567       if (buffer_image_height == 0)
1568          buffer_image_height = copycmd->regions[i].imageExtent.height;
1569 
1570       unsigned img_stride = util_format_get_2d_size(dst_format, buffer_row_len, buffer_image_height);
1571       if (src_format != dst_format) {
1572          copy_depth_box(dst_data, dst_format,
1573                         buffer_row_len, img_stride,
1574                         0, 0, 0,
1575                         copycmd->regions[i].imageExtent.width,
1576                         copycmd->regions[i].imageExtent.height,
1577                         box.depth,
1578                         src_data, src_format, src_t->stride, src_t->layer_stride, 0, 0, 0);
1579       } else {
1580          util_copy_box((ubyte *)dst_data, src_format,
1581                        buffer_row_len, img_stride,
1582                        0, 0, 0,
1583                        copycmd->regions[i].imageExtent.width,
1584                        copycmd->regions[i].imageExtent.height,
1585                        box.depth,
1586                        src_data, src_t->stride, src_t->layer_stride, 0, 0, 0);
1587       }
1588       state->pctx->transfer_unmap(state->pctx, src_t);
1589       state->pctx->transfer_unmap(state->pctx, dst_t);
1590    }
1591 }
1592 
handle_copy_buffer_to_image(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1593 static void handle_copy_buffer_to_image(struct lvp_cmd_buffer_entry *cmd,
1594                                         struct rendering_state *state)
1595 {
1596    int i;
1597    struct lvp_cmd_copy_buffer_to_image *copycmd = &cmd->u.buffer_to_img;
1598    struct pipe_box box, sbox;
1599    struct pipe_transfer *src_t, *dst_t;
1600    void *src_data, *dst_data;
1601 
1602    state->pctx->flush(state->pctx, NULL, 0);
1603 
1604    for (i = 0; i < copycmd->region_count; i++) {
1605 
1606       sbox.x = copycmd->regions[i].bufferOffset;
1607       sbox.y = 0;
1608       sbox.z = 0;
1609       sbox.width = copycmd->src->bo->width0;
1610       sbox.height = 1;
1611       sbox.depth = 1;
1612       src_data = state->pctx->transfer_map(state->pctx,
1613                                            copycmd->src->bo,
1614                                            0,
1615                                            PIPE_MAP_READ,
1616                                            &sbox,
1617                                            &src_t);
1618 
1619 
1620       box.x = copycmd->regions[i].imageOffset.x;
1621       box.y = copycmd->regions[i].imageOffset.y;
1622       box.z = copycmd->dst->type == VK_IMAGE_TYPE_3D ? copycmd->regions[i].imageOffset.z : copycmd->regions[i].imageSubresource.baseArrayLayer;
1623       box.width = copycmd->regions[i].imageExtent.width;
1624       box.height = copycmd->regions[i].imageExtent.height;
1625       box.depth = copycmd->dst->type == VK_IMAGE_TYPE_3D ? copycmd->regions[i].imageExtent.depth : copycmd->regions[i].imageSubresource.layerCount;
1626 
1627       dst_data = state->pctx->transfer_map(state->pctx,
1628                                            copycmd->dst->bo,
1629                                            copycmd->regions[i].imageSubresource.mipLevel,
1630                                            PIPE_MAP_WRITE,
1631                                            &box,
1632                                            &dst_t);
1633 
1634       enum pipe_format dst_format = copycmd->dst->bo->format;
1635       enum pipe_format src_format = dst_format;
1636       if (util_format_is_depth_or_stencil(dst_format)) {
1637          if (copycmd->regions[i].imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) {
1638             src_format = util_format_get_depth_only(copycmd->dst->bo->format);
1639          } else if (copycmd->regions[i].imageSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {
1640             src_format = PIPE_FORMAT_S8_UINT;
1641          }
1642       }
1643 
1644       unsigned buffer_row_len = util_format_get_stride(src_format, copycmd->regions[i].bufferRowLength);
1645       if (buffer_row_len == 0)
1646          buffer_row_len = util_format_get_stride(src_format, copycmd->regions[i].imageExtent.width);
1647       unsigned buffer_image_height = copycmd->regions[i].bufferImageHeight;
1648       if (buffer_image_height == 0)
1649          buffer_image_height = copycmd->regions[i].imageExtent.height;
1650 
1651       unsigned img_stride = util_format_get_2d_size(src_format, buffer_row_len, buffer_image_height);
1652       if (src_format != dst_format) {
1653          copy_depth_box(dst_data, dst_format,
1654                         dst_t->stride, dst_t->layer_stride,
1655                         0, 0, 0,
1656                         copycmd->regions[i].imageExtent.width,
1657                         copycmd->regions[i].imageExtent.height,
1658                         box.depth,
1659                         src_data, src_format,
1660                         buffer_row_len, img_stride, 0, 0, 0);
1661       } else {
1662          util_copy_box(dst_data, dst_format,
1663                        dst_t->stride, dst_t->layer_stride,
1664                        0, 0, 0,
1665                        copycmd->regions[i].imageExtent.width,
1666                        copycmd->regions[i].imageExtent.height,
1667                        box.depth,
1668                        src_data,
1669                        buffer_row_len, img_stride, 0, 0, 0);
1670       }
1671       state->pctx->transfer_unmap(state->pctx, src_t);
1672       state->pctx->transfer_unmap(state->pctx, dst_t);
1673    }
1674 }
1675 
handle_copy_image(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1676 static void handle_copy_image(struct lvp_cmd_buffer_entry *cmd,
1677                               struct rendering_state *state)
1678 {
1679    int i;
1680    struct lvp_cmd_copy_image *copycmd = &cmd->u.copy_image;
1681 
1682    state->pctx->flush(state->pctx, NULL, 0);
1683 
1684    for (i = 0; i < copycmd->region_count; i++) {
1685       struct pipe_box src_box;
1686       src_box.x = copycmd->regions[i].srcOffset.x;
1687       src_box.y = copycmd->regions[i].srcOffset.y;
1688       src_box.z = copycmd->regions[i].srcOffset.z + copycmd->regions[i].srcSubresource.baseArrayLayer;
1689       src_box.width = copycmd->regions[i].extent.width;
1690       src_box.height = copycmd->regions[i].extent.height;
1691       src_box.depth = copycmd->regions[i].extent.depth;
1692 
1693       state->pctx->resource_copy_region(state->pctx, copycmd->dst->bo,
1694                                         copycmd->regions[i].dstSubresource.mipLevel,
1695                                         copycmd->regions[i].dstOffset.x,
1696                                         copycmd->regions[i].dstOffset.y,
1697                                         copycmd->regions[i].dstOffset.z + copycmd->regions[i].dstSubresource.baseArrayLayer,
1698                                         copycmd->src->bo,
1699                                         copycmd->regions[i].srcSubresource.mipLevel,
1700                                         &src_box);
1701    }
1702 }
1703 
handle_copy_buffer(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1704 static void handle_copy_buffer(struct lvp_cmd_buffer_entry *cmd,
1705                                struct rendering_state *state)
1706 {
1707    int i;
1708    struct lvp_cmd_copy_buffer *copycmd = &cmd->u.copy_buffer;
1709 
1710    for (i = 0; i < copycmd->region_count; i++) {
1711       struct pipe_box box = { 0 };
1712       u_box_1d(copycmd->regions[i].srcOffset, copycmd->regions[i].size, &box);
1713       state->pctx->resource_copy_region(state->pctx, copycmd->dst->bo, 0,
1714                                         copycmd->regions[i].dstOffset, 0, 0,
1715                                         copycmd->src->bo, 0, &box);
1716    }
1717 }
1718 
handle_blit_image(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1719 static void handle_blit_image(struct lvp_cmd_buffer_entry *cmd,
1720                               struct rendering_state *state)
1721 {
1722    int i;
1723    struct lvp_cmd_blit_image *blitcmd = &cmd->u.blit_image;
1724    struct pipe_blit_info info;
1725 
1726    memset(&info, 0, sizeof(info));
1727 
1728    state->pctx->flush(state->pctx, NULL, 0);
1729    info.src.resource = blitcmd->src->bo;
1730    info.dst.resource = blitcmd->dst->bo;
1731    info.src.format = blitcmd->src->bo->format;
1732    info.dst.format = blitcmd->dst->bo->format;
1733    info.mask = util_format_is_depth_or_stencil(info.src.format) ? PIPE_MASK_ZS : PIPE_MASK_RGBA;
1734    info.filter = blitcmd->filter == VK_FILTER_NEAREST ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR;
1735    for (i = 0; i < blitcmd->region_count; i++) {
1736       int srcX0, srcX1, srcY0, srcY1, srcZ0, srcZ1;
1737       unsigned dstX0, dstX1, dstY0, dstY1, dstZ0, dstZ1;
1738 
1739       srcX0 = blitcmd->regions[i].srcOffsets[0].x;
1740       srcX1 = blitcmd->regions[i].srcOffsets[1].x;
1741       srcY0 = blitcmd->regions[i].srcOffsets[0].y;
1742       srcY1 = blitcmd->regions[i].srcOffsets[1].y;
1743       srcZ0 = blitcmd->regions[i].srcOffsets[0].z;
1744       srcZ1 = blitcmd->regions[i].srcOffsets[1].z;
1745 
1746       dstX0 = blitcmd->regions[i].dstOffsets[0].x;
1747       dstX1 = blitcmd->regions[i].dstOffsets[1].x;
1748       dstY0 = blitcmd->regions[i].dstOffsets[0].y;
1749       dstY1 = blitcmd->regions[i].dstOffsets[1].y;
1750       dstZ0 = blitcmd->regions[i].dstOffsets[0].z;
1751       dstZ1 = blitcmd->regions[i].dstOffsets[1].z;
1752 
1753       if (dstX0 < dstX1) {
1754          info.dst.box.x = dstX0;
1755          info.src.box.x = srcX0;
1756          info.dst.box.width = dstX1 - dstX0;
1757          info.src.box.width = srcX1 - srcX0;
1758       } else {
1759          info.dst.box.x = dstX1;
1760          info.src.box.x = srcX1;
1761          info.dst.box.width = dstX0 - dstX1;
1762          info.src.box.width = srcX0 - srcX1;
1763       }
1764 
1765       if (dstY0 < dstY1) {
1766          info.dst.box.y = dstY0;
1767          info.src.box.y = srcY0;
1768          info.dst.box.height = dstY1 - dstY0;
1769          info.src.box.height = srcY1 - srcY0;
1770       } else {
1771          info.dst.box.y = dstY1;
1772          info.src.box.y = srcY1;
1773          info.dst.box.height = dstY0 - dstY1;
1774          info.src.box.height = srcY0 - srcY1;
1775       }
1776 
1777       if (blitcmd->src->bo->target == PIPE_TEXTURE_3D) {
1778          if (dstZ0 < dstZ1) {
1779             info.dst.box.z = dstZ0;
1780             info.src.box.z = srcZ0;
1781             info.dst.box.depth = dstZ1 - dstZ0;
1782             info.src.box.depth = srcZ1 - srcZ0;
1783          } else {
1784             info.dst.box.z = dstZ1;
1785             info.src.box.z = srcZ1;
1786             info.dst.box.depth = dstZ0 - dstZ1;
1787             info.src.box.depth = srcZ0 - srcZ1;
1788          }
1789       } else {
1790          info.src.box.z = blitcmd->regions[i].srcSubresource.baseArrayLayer;
1791          info.dst.box.z = blitcmd->regions[i].dstSubresource.baseArrayLayer;
1792          info.src.box.depth = blitcmd->regions[i].srcSubresource.layerCount;
1793          info.dst.box.depth = blitcmd->regions[i].dstSubresource.layerCount;
1794       }
1795 
1796       info.src.level = blitcmd->regions[i].srcSubresource.mipLevel;
1797       info.dst.level = blitcmd->regions[i].dstSubresource.mipLevel;
1798       state->pctx->blit(state->pctx, &info);
1799    }
1800 }
1801 
handle_fill_buffer(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1802 static void handle_fill_buffer(struct lvp_cmd_buffer_entry *cmd,
1803                                struct rendering_state *state)
1804 {
1805    struct lvp_cmd_fill_buffer *fillcmd = &cmd->u.fill_buffer;
1806    uint32_t size = fillcmd->fill_size;
1807 
1808    if (fillcmd->fill_size == VK_WHOLE_SIZE) {
1809       size = fillcmd->buffer->bo->width0 - fillcmd->offset;
1810       size = ROUND_DOWN_TO(size, 4);
1811    }
1812 
1813    state->pctx->clear_buffer(state->pctx,
1814                              fillcmd->buffer->bo,
1815                              fillcmd->offset,
1816                              size,
1817                              &fillcmd->data,
1818                              4);
1819 }
1820 
handle_update_buffer(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1821 static void handle_update_buffer(struct lvp_cmd_buffer_entry *cmd,
1822                                  struct rendering_state *state)
1823 {
1824    struct lvp_cmd_update_buffer *updcmd = &cmd->u.update_buffer;
1825    uint32_t *dst;
1826    struct pipe_transfer *dst_t;
1827    struct pipe_box box;
1828 
1829    u_box_1d(updcmd->offset, updcmd->data_size, &box);
1830    dst = state->pctx->transfer_map(state->pctx,
1831                                    updcmd->buffer->bo,
1832                                    0,
1833                                    PIPE_MAP_WRITE,
1834                                    &box,
1835                                    &dst_t);
1836 
1837    memcpy(dst, updcmd->data, updcmd->data_size);
1838    state->pctx->transfer_unmap(state->pctx, dst_t);
1839 }
1840 
handle_draw_indexed(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1841 static void handle_draw_indexed(struct lvp_cmd_buffer_entry *cmd,
1842                                 struct rendering_state *state)
1843 {
1844    state->info.indirect = NULL;
1845    state->info.min_index = 0;
1846    state->info.max_index = ~0;
1847    state->info.index_size = state->index_size;
1848    state->info.index.resource = state->index_buffer;
1849    state->info.start = (state->index_offset / state->index_size) + cmd->u.draw_indexed.first_index;
1850    state->info.count = cmd->u.draw_indexed.index_count;
1851    state->info.start_instance = cmd->u.draw_indexed.first_instance;
1852    state->info.instance_count = cmd->u.draw_indexed.instance_count;
1853    state->info.index_bias = cmd->u.draw_indexed.vertex_offset;
1854 
1855    if (state->info.primitive_restart) {
1856       if (state->info.index_size == 4)
1857          state->info.restart_index = 0xffffffff;
1858       else
1859          state->info.restart_index = 0xffff;
1860    }
1861 
1862    state->pctx->draw_vbo(state->pctx, &state->info);
1863 }
1864 
handle_draw_indirect(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state,bool indexed)1865 static void handle_draw_indirect(struct lvp_cmd_buffer_entry *cmd,
1866                                  struct rendering_state *state, bool indexed)
1867 {
1868    if (indexed) {
1869       state->info.index_size = state->index_size;
1870       state->info.index.resource = state->index_buffer;
1871       state->info.max_index = ~0;
1872    } else
1873       state->info.index_size = 0;
1874    state->indirect_info.offset = cmd->u.draw_indirect.offset;
1875    state->indirect_info.stride = cmd->u.draw_indirect.stride;
1876    state->indirect_info.draw_count = cmd->u.draw_indirect.draw_count;
1877    state->indirect_info.buffer = cmd->u.draw_indirect.buffer->bo;
1878    state->info.indirect = &state->indirect_info;
1879    state->pctx->draw_vbo(state->pctx, &state->info);
1880 }
1881 
handle_index_buffer(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1882 static void handle_index_buffer(struct lvp_cmd_buffer_entry *cmd,
1883                                 struct rendering_state *state)
1884 {
1885    struct lvp_cmd_bind_index_buffer *ib = &cmd->u.index_buffer;
1886    switch (ib->index_type) {
1887    case VK_INDEX_TYPE_UINT16:
1888       state->index_size = 2;
1889       break;
1890    case VK_INDEX_TYPE_UINT32:
1891       state->index_size = 4;
1892       break;
1893    default:
1894       break;
1895    }
1896    state->index_offset = ib->offset;
1897    if (ib->buffer)
1898       state->index_buffer = ib->buffer->bo;
1899    else
1900       state->index_buffer = NULL;
1901 
1902    state->ib_dirty = true;
1903 }
1904 
handle_dispatch(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1905 static void handle_dispatch(struct lvp_cmd_buffer_entry *cmd,
1906                             struct rendering_state *state)
1907 {
1908    state->dispatch_info.grid[0] = cmd->u.dispatch.x;
1909    state->dispatch_info.grid[1] = cmd->u.dispatch.y;
1910    state->dispatch_info.grid[2] = cmd->u.dispatch.z;
1911    state->dispatch_info.indirect = NULL;
1912    state->pctx->launch_grid(state->pctx, &state->dispatch_info);
1913 }
1914 
handle_dispatch_indirect(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1915 static void handle_dispatch_indirect(struct lvp_cmd_buffer_entry *cmd,
1916                                      struct rendering_state *state)
1917 {
1918    state->dispatch_info.indirect = cmd->u.dispatch_indirect.buffer->bo;
1919    state->dispatch_info.indirect_offset = cmd->u.dispatch_indirect.offset;
1920    state->pctx->launch_grid(state->pctx, &state->dispatch_info);
1921 }
1922 
handle_push_constants(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1923 static void handle_push_constants(struct lvp_cmd_buffer_entry *cmd,
1924                                   struct rendering_state *state)
1925 {
1926    memcpy(state->push_constants + cmd->u.push_constants.offset, cmd->u.push_constants.val, cmd->u.push_constants.size);
1927 
1928    state->pc_buffer[PIPE_SHADER_VERTEX].buffer_size = 128 * 4;
1929    state->pc_buffer[PIPE_SHADER_VERTEX].buffer_offset = 0;
1930    state->pc_buffer[PIPE_SHADER_VERTEX].user_buffer = state->push_constants;
1931    state->pcbuf_dirty[PIPE_SHADER_VERTEX] = true;
1932    state->pc_buffer[PIPE_SHADER_FRAGMENT].buffer_size = 128 * 4;
1933    state->pc_buffer[PIPE_SHADER_FRAGMENT].buffer_offset = 0;
1934    state->pc_buffer[PIPE_SHADER_FRAGMENT].user_buffer = state->push_constants;
1935    state->pcbuf_dirty[PIPE_SHADER_FRAGMENT] = true;
1936    state->pc_buffer[PIPE_SHADER_GEOMETRY].buffer_size = 128 * 4;
1937    state->pc_buffer[PIPE_SHADER_GEOMETRY].buffer_offset = 0;
1938    state->pc_buffer[PIPE_SHADER_GEOMETRY].user_buffer = state->push_constants;
1939    state->pcbuf_dirty[PIPE_SHADER_GEOMETRY] = true;
1940    state->pc_buffer[PIPE_SHADER_TESS_CTRL].buffer_size = 128 * 4;
1941    state->pc_buffer[PIPE_SHADER_TESS_CTRL].buffer_offset = 0;
1942    state->pc_buffer[PIPE_SHADER_TESS_CTRL].user_buffer = state->push_constants;
1943    state->pcbuf_dirty[PIPE_SHADER_TESS_CTRL] = true;
1944    state->pc_buffer[PIPE_SHADER_TESS_EVAL].buffer_size = 128 * 4;
1945    state->pc_buffer[PIPE_SHADER_TESS_EVAL].buffer_offset = 0;
1946    state->pc_buffer[PIPE_SHADER_TESS_EVAL].user_buffer = state->push_constants;
1947    state->pcbuf_dirty[PIPE_SHADER_TESS_EVAL] = true;
1948    state->pc_buffer[PIPE_SHADER_COMPUTE].buffer_size = 128 * 4;
1949    state->pc_buffer[PIPE_SHADER_COMPUTE].buffer_offset = 0;
1950    state->pc_buffer[PIPE_SHADER_COMPUTE].user_buffer = state->push_constants;
1951    state->pcbuf_dirty[PIPE_SHADER_COMPUTE] = true;
1952 }
1953 
1954 static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer,
1955                                    struct rendering_state *state);
1956 
handle_execute_commands(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1957 static void handle_execute_commands(struct lvp_cmd_buffer_entry *cmd,
1958                                     struct rendering_state *state)
1959 {
1960    for (unsigned i = 0; i < cmd->u.execute_commands.command_buffer_count; i++) {
1961       struct lvp_cmd_buffer *secondary_buf = cmd->u.execute_commands.cmd_buffers[i];
1962       lvp_execute_cmd_buffer(secondary_buf, state);
1963    }
1964 }
1965 
handle_event_set(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1966 static void handle_event_set(struct lvp_cmd_buffer_entry *cmd,
1967                              struct rendering_state *state)
1968 {
1969    struct lvp_event *event = cmd->u.event_set.event;
1970 
1971    if (cmd->u.event_set.flush)
1972       state->pctx->flush(state->pctx, NULL, 0);
1973    event->event_storage = (cmd->u.event_set.value == true) ? 1 : 0;
1974 }
1975 
handle_wait_events(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1976 static void handle_wait_events(struct lvp_cmd_buffer_entry *cmd,
1977                                struct rendering_state *state)
1978 {
1979    for (unsigned i = 0; i < cmd->u.wait_events.event_count; i++) {
1980       struct lvp_event *event = cmd->u.wait_events.events[i];
1981 
1982       while (event->event_storage != true);
1983    }
1984 }
1985 
handle_pipeline_barrier(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1986 static void handle_pipeline_barrier(struct lvp_cmd_buffer_entry *cmd,
1987                                     struct rendering_state *state)
1988 {
1989    /* why hello nail, I'm a hammer. - TODO */
1990    state->pctx->flush(state->pctx, NULL, 0);
1991 }
1992 
handle_begin_query(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)1993 static void handle_begin_query(struct lvp_cmd_buffer_entry *cmd,
1994                                struct rendering_state *state)
1995 {
1996    struct lvp_cmd_query_cmd *qcmd = &cmd->u.query;
1997    struct lvp_query_pool *pool = qcmd->pool;
1998 
1999    if (!pool->queries[qcmd->query]) {
2000       enum pipe_query_type qtype = pool->base_type;
2001       if (qtype == PIPE_QUERY_OCCLUSION_COUNTER && !qcmd->precise)
2002          qtype = PIPE_QUERY_OCCLUSION_PREDICATE;
2003       pool->queries[qcmd->query] = state->pctx->create_query(state->pctx,
2004                                                              qtype, qcmd->index);
2005    }
2006 
2007    state->pctx->begin_query(state->pctx, pool->queries[qcmd->query]);
2008 }
2009 
handle_end_query(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)2010 static void handle_end_query(struct lvp_cmd_buffer_entry *cmd,
2011                              struct rendering_state *state)
2012 {
2013    struct lvp_cmd_query_cmd *qcmd = &cmd->u.query;
2014    struct lvp_query_pool *pool = qcmd->pool;
2015    assert(pool->queries[qcmd->query]);
2016 
2017    state->pctx->end_query(state->pctx, pool->queries[qcmd->query]);
2018 }
2019 
handle_reset_query_pool(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)2020 static void handle_reset_query_pool(struct lvp_cmd_buffer_entry *cmd,
2021                                     struct rendering_state *state)
2022 {
2023    struct lvp_cmd_query_cmd *qcmd = &cmd->u.query;
2024    struct lvp_query_pool *pool = qcmd->pool;
2025    for (unsigned i = qcmd->query; i < qcmd->query + qcmd->index; i++) {
2026       if (pool->queries[i]) {
2027          state->pctx->destroy_query(state->pctx, pool->queries[i]);
2028          pool->queries[i] = NULL;
2029       }
2030    }
2031 }
2032 
handle_write_timestamp(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)2033 static void handle_write_timestamp(struct lvp_cmd_buffer_entry *cmd,
2034                                    struct rendering_state *state)
2035 {
2036    struct lvp_cmd_query_cmd *qcmd = &cmd->u.query;
2037    struct lvp_query_pool *pool = qcmd->pool;
2038    if (!pool->queries[qcmd->query]) {
2039       pool->queries[qcmd->query] = state->pctx->create_query(state->pctx,
2040                                                              PIPE_QUERY_TIMESTAMP, 0);
2041    }
2042 
2043    if (qcmd->flush)
2044       state->pctx->flush(state->pctx, NULL, 0);
2045    state->pctx->end_query(state->pctx, pool->queries[qcmd->query]);
2046 
2047 }
2048 
handle_copy_query_pool_results(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)2049 static void handle_copy_query_pool_results(struct lvp_cmd_buffer_entry *cmd,
2050                                            struct rendering_state *state)
2051 {
2052    struct lvp_cmd_copy_query_pool_results *copycmd = &cmd->u.copy_query_pool_results;
2053    struct lvp_query_pool *pool = copycmd->pool;
2054 
2055    for (unsigned i = copycmd->first_query; i < copycmd->first_query + copycmd->query_count; i++) {
2056       unsigned offset = copycmd->dst->offset + (copycmd->stride * (i - copycmd->first_query));
2057       if (pool->queries[i]) {
2058          if (copycmd->flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)
2059             state->pctx->get_query_result_resource(state->pctx,
2060                                                    pool->queries[i],
2061                                                    copycmd->flags & VK_QUERY_RESULT_WAIT_BIT,
2062                                                    copycmd->flags & VK_QUERY_RESULT_64_BIT ? PIPE_QUERY_TYPE_U64 : PIPE_QUERY_TYPE_U32,
2063                                                    -1,
2064                                                    copycmd->dst->bo,
2065                                                    offset + (copycmd->flags & VK_QUERY_RESULT_64_BIT ? 8 : 4));
2066          state->pctx->get_query_result_resource(state->pctx,
2067                                                 pool->queries[i],
2068                                                 copycmd->flags & VK_QUERY_RESULT_WAIT_BIT,
2069                                                 copycmd->flags & VK_QUERY_RESULT_64_BIT ? PIPE_QUERY_TYPE_U64 : PIPE_QUERY_TYPE_U32,
2070                                                 0,
2071                                                 copycmd->dst->bo,
2072                                                 offset);
2073       } else {
2074          /* if no queries emitted yet, just reset the buffer to 0 so avail is reported correctly */
2075          if (copycmd->flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) {
2076             struct pipe_transfer *src_t;
2077             uint32_t *map;
2078 
2079             struct pipe_box box = {};
2080             box.width = copycmd->stride * copycmd->query_count;
2081             box.height = 1;
2082             box.depth = 1;
2083             map = state->pctx->transfer_map(state->pctx,
2084                                             copycmd->dst->bo, 0, PIPE_MAP_READ, &box,
2085                                             &src_t);
2086 
2087             memset(map, 0, box.width);
2088             state->pctx->transfer_unmap(state->pctx, src_t);
2089          }
2090       }
2091    }
2092 }
2093 
pack_clear_color(enum pipe_format pformat,VkClearColorValue * in_val,uint32_t col_val[4])2094 static void pack_clear_color(enum pipe_format pformat, VkClearColorValue *in_val, uint32_t col_val[4])
2095 {
2096    const struct util_format_description *desc = util_format_description(pformat);
2097    col_val[0] = col_val[1] = col_val[2] = col_val[3] = 0;
2098    for (unsigned c = 0; c < 4; c++) {
2099       if (desc->swizzle[c] >= 4)
2100          continue;
2101       const struct util_format_channel_description *channel = &desc->channel[desc->swizzle[c]];
2102       if (channel->size == 32) {
2103          col_val[c] = in_val->uint32[c];
2104          continue;
2105       }
2106       if (channel->pure_integer) {
2107          uint64_t v = in_val->uint32[c] & ((1u << channel->size) - 1);
2108          switch (channel->size) {
2109          case 2:
2110          case 8:
2111          case 10:
2112             col_val[0] |= (v << channel->shift);
2113             break;
2114          case 16:
2115             col_val[c / 2] |= (v << (16 * (c % 2)));
2116             break;
2117          }
2118       } else {
2119          util_pack_color(in_val->float32, pformat, (union util_color *)col_val);
2120          break;
2121       }
2122    }
2123 }
2124 
handle_clear_color_image(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)2125 static void handle_clear_color_image(struct lvp_cmd_buffer_entry *cmd,
2126                                      struct rendering_state *state)
2127 {
2128    struct lvp_image *image = cmd->u.clear_color_image.image;
2129    uint32_t col_val[4];
2130    pack_clear_color(image->bo->format, &cmd->u.clear_color_image.clear_val, col_val);
2131    for (unsigned i = 0; i < cmd->u.clear_color_image.range_count; i++) {
2132       VkImageSubresourceRange *range = &cmd->u.clear_color_image.ranges[i];
2133       struct pipe_box box;
2134       box.x = 0;
2135       box.y = 0;
2136       box.z = 0;
2137 
2138       uint32_t level_count = lvp_get_levelCount(image, range);
2139       for (unsigned j = range->baseMipLevel; j < range->baseMipLevel + level_count; j++) {
2140          box.width = u_minify(image->bo->width0, j);
2141          box.height = u_minify(image->bo->height0, j);
2142          box.depth = 1;
2143          if (image->bo->target == PIPE_TEXTURE_3D)
2144             box.depth = u_minify(image->bo->depth0, j);
2145          else if (image->bo->target == PIPE_TEXTURE_1D_ARRAY) {
2146             box.y = range->baseArrayLayer;
2147             box.height = lvp_get_layerCount(image, range);
2148             box.depth = 1;
2149          } else {
2150             box.z = range->baseArrayLayer;
2151             box.depth = lvp_get_layerCount(image, range);
2152          }
2153 
2154          state->pctx->clear_texture(state->pctx, image->bo,
2155                                     j, &box, (void *)col_val);
2156       }
2157    }
2158 }
2159 
handle_clear_ds_image(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)2160 static void handle_clear_ds_image(struct lvp_cmd_buffer_entry *cmd,
2161                                   struct rendering_state *state)
2162 {
2163    struct lvp_image *image = cmd->u.clear_ds_image.image;
2164    uint64_t col_val;
2165    col_val = util_pack64_z_stencil(image->bo->format, cmd->u.clear_ds_image.clear_val.depth, cmd->u.clear_ds_image.clear_val.stencil);
2166    for (unsigned i = 0; i < cmd->u.clear_ds_image.range_count; i++) {
2167       VkImageSubresourceRange *range = &cmd->u.clear_ds_image.ranges[i];
2168       struct pipe_box box;
2169       box.x = 0;
2170       box.y = 0;
2171       box.z = 0;
2172 
2173       uint32_t level_count = lvp_get_levelCount(image, range);
2174       for (unsigned j = range->baseMipLevel; j < range->baseMipLevel + level_count; j++) {
2175          box.width = u_minify(image->bo->width0, j);
2176          box.height = u_minify(image->bo->height0, j);
2177          box.depth = 1;
2178          if (image->bo->target == PIPE_TEXTURE_3D)
2179             box.depth = u_minify(image->bo->depth0, j);
2180          else if (image->bo->target == PIPE_TEXTURE_1D_ARRAY) {
2181             box.y = range->baseArrayLayer;
2182             box.height = lvp_get_layerCount(image, range);
2183             box.depth = 1;
2184          } else {
2185             box.z = range->baseArrayLayer;
2186             box.depth = lvp_get_layerCount(image, range);
2187          }
2188 
2189          state->pctx->clear_texture(state->pctx, image->bo,
2190                                     j, &box, (void *)&col_val);
2191       }
2192    }
2193 }
2194 
handle_clear_attachments(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)2195 static void handle_clear_attachments(struct lvp_cmd_buffer_entry *cmd,
2196                                      struct rendering_state *state)
2197 {
2198    for (uint32_t a = 0; a < cmd->u.clear_attachments.attachment_count; a++) {
2199       VkClearAttachment *att = &cmd->u.clear_attachments.attachments[a];
2200       const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
2201       struct lvp_image_view *imgv;
2202 
2203       if (att->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) {
2204          struct lvp_subpass_attachment *color_att = &subpass->color_attachments[att->colorAttachment];
2205          if (!color_att || color_att->attachment == VK_ATTACHMENT_UNUSED)
2206             continue;
2207          imgv = state->vk_framebuffer->attachments[color_att->attachment];
2208       } else {
2209          struct lvp_subpass_attachment *ds_att = subpass->depth_stencil_attachment;
2210          if (!ds_att || ds_att->attachment == VK_ATTACHMENT_UNUSED)
2211             continue;
2212          imgv = state->vk_framebuffer->attachments[ds_att->attachment];
2213       }
2214       uint32_t col_val[4];
2215       if (util_format_is_depth_or_stencil(imgv->pformat)) {
2216          int64_t val = util_pack64_z_stencil(imgv->pformat, att->clearValue.depthStencil.depth, att->clearValue.depthStencil.stencil);
2217          memcpy(col_val, &val, 8);
2218       } else
2219          pack_clear_color(imgv->pformat, &att->clearValue.color, col_val);
2220       for (uint32_t r = 0; r < cmd->u.clear_attachments.rect_count; r++) {
2221          struct pipe_box box;
2222          VkClearRect *rect = &cmd->u.clear_attachments.rects[r];
2223          box.x = rect->rect.offset.x;
2224          box.y = rect->rect.offset.y;
2225          box.z = imgv->subresourceRange.baseArrayLayer + rect->baseArrayLayer;
2226          box.width = rect->rect.extent.width;
2227          box.height = rect->rect.extent.height;
2228          box.depth = rect->layerCount;
2229 
2230          state->pctx->clear_texture(state->pctx, imgv->image->bo,
2231                                     imgv->subresourceRange.baseMipLevel,
2232                                     &box, col_val);
2233       }
2234    }
2235 }
2236 
handle_resolve_image(struct lvp_cmd_buffer_entry * cmd,struct rendering_state * state)2237 static void handle_resolve_image(struct lvp_cmd_buffer_entry *cmd,
2238                                  struct rendering_state *state)
2239 {
2240    int i;
2241    struct lvp_cmd_resolve_image *resolvecmd = &cmd->u.resolve_image;
2242    struct pipe_blit_info info;
2243 
2244    memset(&info, 0, sizeof(info));
2245 
2246    state->pctx->flush(state->pctx, NULL, 0);
2247    info.src.resource = resolvecmd->src->bo;
2248    info.dst.resource = resolvecmd->dst->bo;
2249    info.src.format = resolvecmd->src->bo->format;
2250    info.dst.format = resolvecmd->dst->bo->format;
2251    info.mask = util_format_is_depth_or_stencil(info.src.format) ? PIPE_MASK_ZS : PIPE_MASK_RGBA;
2252    info.filter = PIPE_TEX_FILTER_NEAREST;
2253    for (i = 0; i < resolvecmd->region_count; i++) {
2254       int srcX0, srcY0;
2255       unsigned dstX0, dstY0;
2256 
2257       srcX0 = resolvecmd->regions[i].srcOffset.x;
2258       srcY0 = resolvecmd->regions[i].srcOffset.y;
2259 
2260       dstX0 = resolvecmd->regions[i].dstOffset.x;
2261       dstY0 = resolvecmd->regions[i].dstOffset.y;
2262 
2263       info.dst.box.x = dstX0;
2264       info.dst.box.y = dstY0;
2265       info.src.box.x = srcX0;
2266       info.src.box.y = srcY0;
2267 
2268       info.dst.box.width = resolvecmd->regions[i].extent.width;
2269       info.src.box.width = resolvecmd->regions[i].extent.width;
2270       info.dst.box.height = resolvecmd->regions[i].extent.height;
2271       info.src.box.height = resolvecmd->regions[i].extent.height;
2272 
2273       info.dst.box.depth = resolvecmd->regions[i].dstSubresource.layerCount;
2274       info.src.box.depth = resolvecmd->regions[i].srcSubresource.layerCount;
2275 
2276       info.src.level = resolvecmd->regions[i].srcSubresource.mipLevel;
2277       info.src.box.z = resolvecmd->regions[i].srcOffset.z + resolvecmd->regions[i].srcSubresource.baseArrayLayer;
2278 
2279       info.dst.level = resolvecmd->regions[i].dstSubresource.mipLevel;
2280       info.dst.box.z = resolvecmd->regions[i].dstOffset.z + resolvecmd->regions[i].dstSubresource.baseArrayLayer;
2281 
2282       state->pctx->blit(state->pctx, &info);
2283    }
2284 }
2285 
lvp_execute_cmd_buffer(struct lvp_cmd_buffer * cmd_buffer,struct rendering_state * state)2286 static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer,
2287                                    struct rendering_state *state)
2288 {
2289    struct lvp_cmd_buffer_entry *cmd;
2290 
2291    LIST_FOR_EACH_ENTRY(cmd, &cmd_buffer->cmds, cmd_link) {
2292       switch (cmd->cmd_type) {
2293       case LVP_CMD_BIND_PIPELINE:
2294          handle_pipeline(cmd, state);
2295          break;
2296       case LVP_CMD_SET_VIEWPORT:
2297          handle_set_viewport(cmd, state);
2298          break;
2299       case LVP_CMD_SET_SCISSOR:
2300          handle_set_scissor(cmd, state);
2301          break;
2302       case LVP_CMD_SET_LINE_WIDTH:
2303          handle_set_line_width(cmd, state);
2304          break;
2305       case LVP_CMD_SET_DEPTH_BIAS:
2306          handle_set_depth_bias(cmd, state);
2307          break;
2308       case LVP_CMD_SET_BLEND_CONSTANTS:
2309          handle_set_blend_constants(cmd, state);
2310          break;
2311       case LVP_CMD_SET_DEPTH_BOUNDS:
2312          handle_set_depth_bounds(cmd, state);
2313          break;
2314       case LVP_CMD_SET_STENCIL_COMPARE_MASK:
2315          handle_set_stencil_compare_mask(cmd, state);
2316          break;
2317       case LVP_CMD_SET_STENCIL_WRITE_MASK:
2318          handle_set_stencil_write_mask(cmd, state);
2319          break;
2320       case LVP_CMD_SET_STENCIL_REFERENCE:
2321          handle_set_stencil_reference(cmd, state);
2322          break;
2323       case LVP_CMD_BIND_DESCRIPTOR_SETS:
2324          handle_descriptor_sets(cmd, state);
2325          break;
2326       case LVP_CMD_BIND_INDEX_BUFFER:
2327          handle_index_buffer(cmd, state);
2328          break;
2329       case LVP_CMD_BIND_VERTEX_BUFFERS:
2330          handle_vertex_buffers(cmd, state);
2331          break;
2332       case LVP_CMD_DRAW:
2333          emit_state(state);
2334          handle_draw(cmd, state);
2335          break;
2336       case LVP_CMD_DRAW_INDEXED:
2337          emit_state(state);
2338          handle_draw_indexed(cmd, state);
2339          break;
2340       case LVP_CMD_DRAW_INDIRECT:
2341          emit_state(state);
2342          handle_draw_indirect(cmd, state, false);
2343          break;
2344       case LVP_CMD_DRAW_INDEXED_INDIRECT:
2345          emit_state(state);
2346          handle_draw_indirect(cmd, state, true);
2347          break;
2348       case LVP_CMD_DISPATCH:
2349          emit_compute_state(state);
2350          handle_dispatch(cmd, state);
2351          break;
2352       case LVP_CMD_DISPATCH_INDIRECT:
2353          emit_compute_state(state);
2354          handle_dispatch_indirect(cmd, state);
2355          break;
2356       case LVP_CMD_COPY_BUFFER:
2357          handle_copy_buffer(cmd, state);
2358          break;
2359       case LVP_CMD_COPY_IMAGE:
2360          handle_copy_image(cmd, state);
2361          break;
2362       case LVP_CMD_BLIT_IMAGE:
2363          handle_blit_image(cmd, state);
2364          break;
2365       case LVP_CMD_COPY_BUFFER_TO_IMAGE:
2366          handle_copy_buffer_to_image(cmd, state);
2367          break;
2368       case LVP_CMD_COPY_IMAGE_TO_BUFFER:
2369          handle_copy_image_to_buffer(cmd, state);
2370          break;
2371       case LVP_CMD_UPDATE_BUFFER:
2372          handle_update_buffer(cmd, state);
2373          break;
2374       case LVP_CMD_FILL_BUFFER:
2375          handle_fill_buffer(cmd, state);
2376          break;
2377       case LVP_CMD_CLEAR_COLOR_IMAGE:
2378          handle_clear_color_image(cmd, state);
2379          break;
2380       case LVP_CMD_CLEAR_DEPTH_STENCIL_IMAGE:
2381          handle_clear_ds_image(cmd, state);
2382          break;
2383       case LVP_CMD_CLEAR_ATTACHMENTS:
2384          handle_clear_attachments(cmd, state);
2385          break;
2386       case LVP_CMD_RESOLVE_IMAGE:
2387          handle_resolve_image(cmd, state);
2388          break;
2389       case LVP_CMD_SET_EVENT:
2390       case LVP_CMD_RESET_EVENT:
2391          handle_event_set(cmd, state);
2392          break;
2393       case LVP_CMD_WAIT_EVENTS:
2394          handle_wait_events(cmd, state);
2395          break;
2396       case LVP_CMD_PIPELINE_BARRIER:
2397          handle_pipeline_barrier(cmd, state);
2398          break;
2399       case LVP_CMD_BEGIN_QUERY:
2400          handle_begin_query(cmd, state);
2401          break;
2402       case LVP_CMD_END_QUERY:
2403          handle_end_query(cmd, state);
2404          break;
2405       case LVP_CMD_RESET_QUERY_POOL:
2406          handle_reset_query_pool(cmd, state);
2407          break;
2408       case LVP_CMD_WRITE_TIMESTAMP:
2409          handle_write_timestamp(cmd, state);
2410          break;
2411       case LVP_CMD_COPY_QUERY_POOL_RESULTS:
2412          handle_copy_query_pool_results(cmd, state);
2413          break;
2414       case LVP_CMD_PUSH_CONSTANTS:
2415          handle_push_constants(cmd, state);
2416          break;
2417       case LVP_CMD_BEGIN_RENDER_PASS:
2418          handle_begin_render_pass(cmd, state);
2419          break;
2420       case LVP_CMD_NEXT_SUBPASS:
2421          handle_next_subpass(cmd, state);
2422          break;
2423       case LVP_CMD_END_RENDER_PASS:
2424          handle_end_render_pass(cmd, state);
2425          break;
2426       case LVP_CMD_EXECUTE_COMMANDS:
2427          handle_execute_commands(cmd, state);
2428          break;
2429       }
2430    }
2431 }
2432 
lvp_execute_cmds(struct lvp_device * device,struct lvp_queue * queue,struct lvp_fence * fence,struct lvp_cmd_buffer * cmd_buffer)2433 VkResult lvp_execute_cmds(struct lvp_device *device,
2434                           struct lvp_queue *queue,
2435                           struct lvp_fence *fence,
2436                           struct lvp_cmd_buffer *cmd_buffer)
2437 {
2438    struct rendering_state state;
2439    struct pipe_fence_handle *handle = NULL;
2440    memset(&state, 0, sizeof(state));
2441    state.pctx = queue->ctx;
2442    state.blend_dirty = true;
2443    state.dsa_dirty = true;
2444    state.rs_dirty = true;
2445    /* create a gallium context */
2446    lvp_execute_cmd_buffer(cmd_buffer, &state);
2447 
2448    state.pctx->flush(state.pctx, fence ? &handle : NULL, 0);
2449    if (fence) {
2450       mtx_lock(&device->fence_lock);
2451       fence->handle = handle;
2452       mtx_unlock(&device->fence_lock);
2453    }
2454    state.start_vb = -1;
2455    state.num_vb = 0;
2456    state.pctx->set_vertex_buffers(state.pctx, 0, PIPE_MAX_ATTRIBS, NULL);
2457    state.pctx->bind_vertex_elements_state(state.pctx, NULL);
2458    state.pctx->bind_vs_state(state.pctx, NULL);
2459    state.pctx->bind_fs_state(state.pctx, NULL);
2460    state.pctx->bind_gs_state(state.pctx, NULL);
2461    if (state.pctx->bind_tcs_state)
2462       state.pctx->bind_tcs_state(state.pctx, NULL);
2463    if (state.pctx->bind_tes_state)
2464       state.pctx->bind_tes_state(state.pctx, NULL);
2465    if (state.pctx->bind_compute_state)
2466       state.pctx->bind_compute_state(state.pctx, NULL);
2467    if (state.velems_cso)
2468       state.pctx->delete_vertex_elements_state(state.pctx, state.velems_cso);
2469 
2470    state.pctx->bind_rasterizer_state(state.pctx, NULL);
2471    state.pctx->delete_rasterizer_state(state.pctx, state.rast_handle);
2472    if (state.blend_handle) {
2473       state.pctx->bind_blend_state(state.pctx, NULL);
2474       state.pctx->delete_blend_state(state.pctx, state.blend_handle);
2475    }
2476 
2477    if (state.dsa_handle) {
2478       state.pctx->bind_depth_stencil_alpha_state(state.pctx, NULL);
2479       state.pctx->delete_depth_stencil_alpha_state(state.pctx, state.dsa_handle);
2480    }
2481 
2482    for (enum pipe_shader_type s = PIPE_SHADER_VERTEX; s < PIPE_SHADER_TYPES; s++) {
2483       for (unsigned i = 0; i < PIPE_MAX_SAMPLERS; i++) {
2484          if (state.sv[s][i])
2485             pipe_sampler_view_reference(&state.sv[s][i], NULL);
2486          if (state.ss_cso[s][i]) {
2487             state.pctx->delete_sampler_state(state.pctx, state.ss_cso[s][i]);
2488             state.ss_cso[s][i] = NULL;
2489          }
2490       }
2491       state.pctx->bind_sampler_states(state.pctx, s, 0, PIPE_MAX_SAMPLERS, state.ss_cso[s]);
2492 
2493       state.pctx->set_shader_images(state.pctx, s, 0, device->physical_device->max_images, NULL);
2494    }
2495 
2496    free(state.pending_clear_aspects);
2497    return VK_SUCCESS;
2498 }
2499