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