Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/frontends/lavapipe/lvp_execute.c
4565 views
1
/*
2
* Copyright © 2019 Red Hat.
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
10
*
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
13
* Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
* IN THE SOFTWARE.
22
*/
23
24
/* use a gallium context to execute a command buffer */
25
26
#include "lvp_private.h"
27
28
#include "pipe/p_context.h"
29
#include "pipe/p_state.h"
30
#include "lvp_conv.h"
31
32
#include "pipe/p_shader_tokens.h"
33
#include "tgsi/tgsi_text.h"
34
#include "tgsi/tgsi_parse.h"
35
36
#include "util/format/u_format.h"
37
#include "util/u_surface.h"
38
#include "util/u_sampler.h"
39
#include "util/u_box.h"
40
#include "util/u_inlines.h"
41
#include "util/u_prim.h"
42
#include "util/u_prim_restart.h"
43
#include "util/format/u_format_zs.h"
44
45
#include "vk_util.h"
46
47
#define DOUBLE_EQ(a, b) (fabs((a) - (b)) < DBL_EPSILON)
48
49
enum gs_output {
50
GS_OUTPUT_NONE,
51
GS_OUTPUT_NOT_LINES,
52
GS_OUTPUT_LINES,
53
};
54
55
struct rendering_state {
56
struct pipe_context *pctx;
57
struct cso_context *cso;
58
59
bool blend_dirty;
60
bool rs_dirty;
61
bool dsa_dirty;
62
bool stencil_ref_dirty;
63
bool clip_state_dirty;
64
bool blend_color_dirty;
65
bool ve_dirty;
66
bool vb_dirty;
67
bool constbuf_dirty[PIPE_SHADER_TYPES];
68
bool pcbuf_dirty[PIPE_SHADER_TYPES];
69
bool vp_dirty;
70
bool scissor_dirty;
71
bool ib_dirty;
72
bool sample_mask_dirty;
73
bool min_samples_dirty;
74
struct pipe_draw_indirect_info indirect_info;
75
struct pipe_draw_info info;
76
77
struct pipe_grid_info dispatch_info;
78
struct pipe_framebuffer_state framebuffer;
79
80
struct pipe_blend_state blend_state;
81
struct {
82
float offset_units;
83
float offset_scale;
84
float offset_clamp;
85
bool enabled;
86
} depth_bias;
87
struct pipe_rasterizer_state rs_state;
88
struct pipe_depth_stencil_alpha_state dsa_state;
89
90
struct pipe_blend_color blend_color;
91
struct pipe_stencil_ref stencil_ref;
92
struct pipe_clip_state clip_state;
93
94
int num_scissors;
95
struct pipe_scissor_state scissors[16];
96
97
int num_viewports;
98
struct pipe_viewport_state viewports[16];
99
100
ubyte index_size;
101
unsigned index_offset;
102
struct pipe_resource *index_buffer;
103
struct pipe_constant_buffer pc_buffer[PIPE_SHADER_TYPES];
104
struct pipe_constant_buffer const_buffer[PIPE_SHADER_TYPES][16];
105
int num_const_bufs[PIPE_SHADER_TYPES];
106
int num_vb;
107
unsigned start_vb;
108
struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];
109
struct cso_velems_state velem;
110
111
struct pipe_sampler_view *sv[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
112
int num_sampler_views[PIPE_SHADER_TYPES];
113
struct pipe_sampler_state ss[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
114
/* cso_context api is stupid */
115
const struct pipe_sampler_state *cso_ss_ptr[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
116
int num_sampler_states[PIPE_SHADER_TYPES];
117
bool sv_dirty[PIPE_SHADER_TYPES];
118
bool ss_dirty[PIPE_SHADER_TYPES];
119
120
struct pipe_image_view iv[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];
121
int num_shader_images[PIPE_SHADER_TYPES];
122
struct pipe_shader_buffer sb[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_BUFFERS];
123
int num_shader_buffers[PIPE_SHADER_TYPES];
124
bool iv_dirty[PIPE_SHADER_TYPES];
125
bool sb_dirty[PIPE_SHADER_TYPES];
126
bool disable_multisample;
127
enum gs_output gs_output_lines : 2;
128
void *ss_cso[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
129
void *velems_cso;
130
131
uint8_t push_constants[128 * 4];
132
133
const struct lvp_render_pass *pass;
134
uint32_t subpass;
135
const struct lvp_framebuffer *vk_framebuffer;
136
VkRect2D render_area;
137
138
uint32_t sample_mask;
139
unsigned min_samples;
140
141
struct lvp_image_view **imageless_views;
142
const struct lvp_attachment_state *attachments;
143
VkImageAspectFlags *pending_clear_aspects;
144
uint32_t *cleared_views;
145
int num_pending_aspects;
146
147
uint32_t num_so_targets;
148
struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_BUFFERS];
149
uint32_t so_offsets[PIPE_MAX_SO_BUFFERS];
150
};
151
152
ALWAYS_INLINE static void
153
assert_subresource_layers(const struct pipe_resource *pres, const VkImageSubresourceLayers *layers, const VkOffset3D *offsets)
154
{
155
#ifndef NDEBUG
156
if (pres->target == PIPE_TEXTURE_3D) {
157
assert(layers->baseArrayLayer == 0);
158
assert(layers->layerCount == 1);
159
assert(offsets[0].z <= pres->depth0);
160
assert(offsets[1].z <= pres->depth0);
161
} else {
162
assert(layers->baseArrayLayer < pres->array_size);
163
assert(layers->baseArrayLayer + layers->layerCount <= pres->array_size);
164
assert(offsets[0].z == 0);
165
assert(offsets[1].z == 1);
166
}
167
#endif
168
}
169
170
static void emit_compute_state(struct rendering_state *state)
171
{
172
if (state->iv_dirty[PIPE_SHADER_COMPUTE]) {
173
state->pctx->set_shader_images(state->pctx, PIPE_SHADER_COMPUTE,
174
0, state->num_shader_images[PIPE_SHADER_COMPUTE],
175
0, state->iv[PIPE_SHADER_COMPUTE]);
176
state->iv_dirty[PIPE_SHADER_COMPUTE] = false;
177
}
178
179
if (state->pcbuf_dirty[PIPE_SHADER_COMPUTE]) {
180
state->pctx->set_constant_buffer(state->pctx, PIPE_SHADER_COMPUTE,
181
0, false, &state->pc_buffer[PIPE_SHADER_COMPUTE]);
182
state->pcbuf_dirty[PIPE_SHADER_COMPUTE] = false;
183
}
184
185
if (state->constbuf_dirty[PIPE_SHADER_COMPUTE]) {
186
for (unsigned i = 0; i < state->num_const_bufs[PIPE_SHADER_COMPUTE]; i++)
187
state->pctx->set_constant_buffer(state->pctx, PIPE_SHADER_COMPUTE,
188
i + 1, false, &state->const_buffer[PIPE_SHADER_COMPUTE][i]);
189
state->constbuf_dirty[PIPE_SHADER_COMPUTE] = false;
190
}
191
192
if (state->sb_dirty[PIPE_SHADER_COMPUTE]) {
193
state->pctx->set_shader_buffers(state->pctx, PIPE_SHADER_COMPUTE,
194
0, state->num_shader_buffers[PIPE_SHADER_COMPUTE],
195
state->sb[PIPE_SHADER_COMPUTE], 0);
196
state->sb_dirty[PIPE_SHADER_COMPUTE] = false;
197
}
198
199
if (state->sv_dirty[PIPE_SHADER_COMPUTE]) {
200
state->pctx->set_sampler_views(state->pctx, PIPE_SHADER_COMPUTE, 0, state->num_sampler_views[PIPE_SHADER_COMPUTE],
201
0, state->sv[PIPE_SHADER_COMPUTE]);
202
state->sv_dirty[PIPE_SHADER_COMPUTE] = false;
203
}
204
205
if (state->ss_dirty[PIPE_SHADER_COMPUTE]) {
206
for (unsigned i = 0; i < state->num_sampler_states[PIPE_SHADER_COMPUTE]; i++) {
207
if (state->ss_cso[PIPE_SHADER_COMPUTE][i])
208
state->pctx->delete_sampler_state(state->pctx, state->ss_cso[PIPE_SHADER_COMPUTE][i]);
209
state->ss_cso[PIPE_SHADER_COMPUTE][i] = state->pctx->create_sampler_state(state->pctx, &state->ss[PIPE_SHADER_COMPUTE][i]);
210
}
211
state->pctx->bind_sampler_states(state->pctx, PIPE_SHADER_COMPUTE, 0, state->num_sampler_states[PIPE_SHADER_COMPUTE], state->ss_cso[PIPE_SHADER_COMPUTE]);
212
state->ss_dirty[PIPE_SHADER_COMPUTE] = false;
213
}
214
}
215
216
static void emit_state(struct rendering_state *state)
217
{
218
int sh;
219
if (state->blend_dirty) {
220
cso_set_blend(state->cso, &state->blend_state);
221
state->blend_dirty = false;
222
}
223
224
if (state->rs_dirty) {
225
bool ms = state->rs_state.multisample;
226
if (state->disable_multisample &&
227
(state->gs_output_lines == GS_OUTPUT_LINES ||
228
(state->gs_output_lines == GS_OUTPUT_NONE && u_reduced_prim(state->info.mode) == PIPE_PRIM_LINES)))
229
state->rs_state.multisample = false;
230
assert(offsetof(struct pipe_rasterizer_state, offset_clamp) - offsetof(struct pipe_rasterizer_state, offset_units) == sizeof(float) * 2);
231
if (state->depth_bias.enabled) {
232
memcpy(&state->rs_state.offset_units, &state->depth_bias, sizeof(float) * 3);
233
} else {
234
memset(&state->rs_state.offset_units, 0, sizeof(float) * 3);
235
}
236
cso_set_rasterizer(state->cso, &state->rs_state);
237
state->rs_dirty = false;
238
state->rs_state.multisample = ms;
239
}
240
241
if (state->dsa_dirty) {
242
cso_set_depth_stencil_alpha(state->cso, &state->dsa_state);
243
state->dsa_dirty = false;
244
}
245
246
if (state->sample_mask_dirty) {
247
cso_set_sample_mask(state->cso, state->sample_mask);
248
state->sample_mask_dirty = false;
249
}
250
251
if (state->min_samples_dirty) {
252
cso_set_min_samples(state->cso, state->min_samples);
253
state->min_samples_dirty = false;
254
}
255
256
if (state->blend_color_dirty) {
257
state->pctx->set_blend_color(state->pctx, &state->blend_color);
258
state->blend_color_dirty = false;
259
}
260
261
if (state->stencil_ref_dirty) {
262
cso_set_stencil_ref(state->cso, state->stencil_ref);
263
state->stencil_ref_dirty = false;
264
}
265
266
if (state->vb_dirty) {
267
cso_set_vertex_buffers(state->cso, state->start_vb, state->num_vb, state->vb);
268
state->vb_dirty = false;
269
}
270
271
if (state->ve_dirty) {
272
cso_set_vertex_elements(state->cso, &state->velem);
273
state->ve_dirty = false;
274
}
275
276
277
for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
278
if (state->constbuf_dirty[sh]) {
279
for (unsigned idx = 0; idx < state->num_const_bufs[sh]; idx++)
280
state->pctx->set_constant_buffer(state->pctx, sh,
281
idx + 1, false, &state->const_buffer[sh][idx]);
282
}
283
state->constbuf_dirty[sh] = false;
284
}
285
286
for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
287
if (state->pcbuf_dirty[sh]) {
288
state->pctx->set_constant_buffer(state->pctx, sh,
289
0, false, &state->pc_buffer[sh]);
290
}
291
}
292
293
for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
294
if (state->sb_dirty[sh]) {
295
state->pctx->set_shader_buffers(state->pctx, sh,
296
0, state->num_shader_buffers[sh],
297
state->sb[sh], 0);
298
}
299
}
300
301
for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
302
if (state->iv_dirty[sh]) {
303
state->pctx->set_shader_images(state->pctx, sh,
304
0, state->num_shader_images[sh], 0,
305
state->iv[sh]);
306
}
307
}
308
309
for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
310
311
if (!state->sv_dirty[sh])
312
continue;
313
314
state->pctx->set_sampler_views(state->pctx, sh, 0, state->num_sampler_views[sh],
315
0, state->sv[sh]);
316
state->sv_dirty[sh] = false;
317
}
318
319
for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
320
if (!state->ss_dirty[sh])
321
continue;
322
323
cso_set_samplers(state->cso, sh, state->num_sampler_states[sh], state->cso_ss_ptr[sh]);
324
}
325
326
if (state->vp_dirty) {
327
state->pctx->set_viewport_states(state->pctx, 0, state->num_viewports, state->viewports);
328
state->vp_dirty = false;
329
}
330
331
if (state->scissor_dirty) {
332
state->pctx->set_scissor_states(state->pctx, 0, state->num_scissors, state->scissors);
333
state->scissor_dirty = false;
334
}
335
}
336
337
static void handle_compute_pipeline(struct lvp_cmd_buffer_entry *cmd,
338
struct rendering_state *state)
339
{
340
struct lvp_pipeline *pipeline = cmd->u.pipeline.pipeline;
341
342
state->dispatch_info.block[0] = pipeline->pipeline_nir[MESA_SHADER_COMPUTE]->info.workgroup_size[0];
343
state->dispatch_info.block[1] = pipeline->pipeline_nir[MESA_SHADER_COMPUTE]->info.workgroup_size[1];
344
state->dispatch_info.block[2] = pipeline->pipeline_nir[MESA_SHADER_COMPUTE]->info.workgroup_size[2];
345
state->pctx->bind_compute_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_COMPUTE]);
346
}
347
348
static void
349
get_viewport_xform(const VkViewport *viewport,
350
float scale[3], float translate[3])
351
{
352
float x = viewport->x;
353
float y = viewport->y;
354
float half_width = 0.5f * viewport->width;
355
float half_height = 0.5f * viewport->height;
356
double n = viewport->minDepth;
357
double f = viewport->maxDepth;
358
359
scale[0] = half_width;
360
translate[0] = half_width + x;
361
scale[1] = half_height;
362
translate[1] = half_height + y;
363
364
scale[2] = (f - n);
365
translate[2] = n;
366
}
367
368
/* enum re-indexing:
369
370
VK_DYNAMIC_STATE_VIEWPORT
371
VK_DYNAMIC_STATE_SCISSOR
372
VK_DYNAMIC_STATE_LINE_WIDTH
373
VK_DYNAMIC_STATE_DEPTH_BIAS
374
VK_DYNAMIC_STATE_BLEND_CONSTANTS
375
VK_DYNAMIC_STATE_DEPTH_BOUNDS
376
VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK
377
VK_DYNAMIC_STATE_STENCIL_WRITE_MASK
378
VK_DYNAMIC_STATE_STENCIL_REFERENCE
379
380
VK_DYNAMIC_STATE_LINE_STIPPLE_EXT
381
382
VK_DYNAMIC_STATE_CULL_MODE_EXT
383
VK_DYNAMIC_STATE_FRONT_FACE_EXT
384
VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT
385
VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT
386
VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT
387
VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT
388
VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT
389
VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT
390
VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT
391
VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT
392
VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT
393
VK_DYNAMIC_STATE_STENCIL_OP_EXT
394
395
VK_DYNAMIC_STATE_VERTEX_INPUT_EXT
396
397
VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT
398
VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT
399
VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT
400
VK_DYNAMIC_STATE_LOGIC_OP_EXT
401
VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT
402
*/
403
static int conv_dynamic_state_idx(VkDynamicState dyn_state)
404
{
405
if (dyn_state <= VK_DYNAMIC_STATE_STENCIL_REFERENCE)
406
return dyn_state;
407
if (dyn_state == VK_DYNAMIC_STATE_LINE_STIPPLE_EXT)
408
/* this one has a weird id, map after the normal dynamic state ones */
409
return VK_DYNAMIC_STATE_STENCIL_REFERENCE + 1;
410
if (dyn_state >= VK_DYNAMIC_STATE_CULL_MODE_EXT &&
411
dyn_state <= VK_DYNAMIC_STATE_STENCIL_OP_EXT)
412
return dyn_state - VK_DYNAMIC_STATE_CULL_MODE_EXT + VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2;
413
if (dyn_state == VK_DYNAMIC_STATE_VERTEX_INPUT_EXT)
414
return (VK_DYNAMIC_STATE_STENCIL_OP_EXT - VK_DYNAMIC_STATE_CULL_MODE_EXT) + VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2 + 1;
415
if (dyn_state >= VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT &&
416
dyn_state <= VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT)
417
return dyn_state - VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT +
418
VK_DYNAMIC_STATE_STENCIL_OP_EXT - VK_DYNAMIC_STATE_CULL_MODE_EXT +
419
VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2 + 1 + 1;
420
assert(0);
421
return -1;
422
}
423
424
static void handle_graphics_pipeline(struct lvp_cmd_buffer_entry *cmd,
425
struct rendering_state *state)
426
{
427
struct lvp_pipeline *pipeline = cmd->u.pipeline.pipeline;
428
bool dynamic_states[VK_DYNAMIC_STATE_STENCIL_REFERENCE+32];
429
unsigned fb_samples = 0;
430
431
memset(dynamic_states, 0, sizeof(dynamic_states));
432
if (pipeline->graphics_create_info.pDynamicState)
433
{
434
const VkPipelineDynamicStateCreateInfo *dyn = pipeline->graphics_create_info.pDynamicState;
435
int i;
436
for (i = 0; i < dyn->dynamicStateCount; i++) {
437
int idx = conv_dynamic_state_idx(dyn->pDynamicStates[i]);
438
if (idx == -1)
439
continue;
440
dynamic_states[idx] = true;
441
}
442
}
443
444
bool has_stage[PIPE_SHADER_TYPES] = { false };
445
446
state->pctx->bind_gs_state(state->pctx, NULL);
447
if (state->pctx->bind_tcs_state)
448
state->pctx->bind_tcs_state(state->pctx, NULL);
449
if (state->pctx->bind_tes_state)
450
state->pctx->bind_tes_state(state->pctx, NULL);
451
state->gs_output_lines = GS_OUTPUT_NONE;
452
{
453
int i;
454
for (i = 0; i < pipeline->graphics_create_info.stageCount; i++) {
455
const VkPipelineShaderStageCreateInfo *sh = &pipeline->graphics_create_info.pStages[i];
456
switch (sh->stage) {
457
case VK_SHADER_STAGE_FRAGMENT_BIT:
458
state->pctx->bind_fs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_FRAGMENT]);
459
has_stage[PIPE_SHADER_FRAGMENT] = true;
460
break;
461
case VK_SHADER_STAGE_VERTEX_BIT:
462
state->pctx->bind_vs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_VERTEX]);
463
has_stage[PIPE_SHADER_VERTEX] = true;
464
break;
465
case VK_SHADER_STAGE_GEOMETRY_BIT:
466
state->pctx->bind_gs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_GEOMETRY]);
467
state->gs_output_lines = pipeline->gs_output_lines ? GS_OUTPUT_LINES : GS_OUTPUT_NOT_LINES;
468
has_stage[PIPE_SHADER_GEOMETRY] = true;
469
break;
470
case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
471
state->pctx->bind_tcs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_TESS_CTRL]);
472
has_stage[PIPE_SHADER_TESS_CTRL] = true;
473
break;
474
case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
475
state->pctx->bind_tes_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_TESS_EVAL]);
476
has_stage[PIPE_SHADER_TESS_EVAL] = true;
477
break;
478
default:
479
assert(0);
480
break;
481
}
482
}
483
}
484
485
/* there should always be a dummy fs. */
486
if (!has_stage[PIPE_SHADER_FRAGMENT])
487
state->pctx->bind_fs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_FRAGMENT]);
488
if (state->pctx->bind_gs_state && !has_stage[PIPE_SHADER_GEOMETRY])
489
state->pctx->bind_gs_state(state->pctx, NULL);
490
if (state->pctx->bind_tcs_state && !has_stage[PIPE_SHADER_TESS_CTRL])
491
state->pctx->bind_tcs_state(state->pctx, NULL);
492
if (state->pctx->bind_tes_state && !has_stage[PIPE_SHADER_TESS_EVAL])
493
state->pctx->bind_tes_state(state->pctx, NULL);
494
495
/* rasterization state */
496
if (pipeline->graphics_create_info.pRasterizationState) {
497
const VkPipelineRasterizationStateCreateInfo *rsc = pipeline->graphics_create_info.pRasterizationState;
498
state->rs_state.depth_clip_near = state->rs_state.depth_clip_far = !rsc->depthClampEnable;
499
if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT)])
500
state->rs_state.rasterizer_discard = rsc->rasterizerDiscardEnable;
501
502
state->rs_state.line_smooth = pipeline->line_smooth;
503
state->rs_state.line_stipple_enable = pipeline->line_stipple_enable;
504
state->rs_state.fill_front = vk_polygon_mode_to_pipe(rsc->polygonMode);
505
state->rs_state.fill_back = vk_polygon_mode_to_pipe(rsc->polygonMode);
506
state->rs_state.point_size_per_vertex = true;
507
state->rs_state.flatshade_first = !pipeline->provoking_vertex_last;
508
state->rs_state.point_quad_rasterization = true;
509
state->rs_state.clip_halfz = true;
510
state->rs_state.half_pixel_center = true;
511
state->rs_state.scissor = true;
512
state->rs_state.no_ms_sample_mask_out = true;
513
state->rs_state.line_rectangular = pipeline->line_rectangular;
514
515
if (!dynamic_states[VK_DYNAMIC_STATE_LINE_WIDTH])
516
state->rs_state.line_width = rsc->lineWidth;
517
if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_LINE_STIPPLE_EXT)]) {
518
state->rs_state.line_stipple_factor = pipeline->line_stipple_factor;
519
state->rs_state.line_stipple_pattern = pipeline->line_stipple_pattern;
520
}
521
522
if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT)])
523
state->depth_bias.enabled = pipeline->graphics_create_info.pRasterizationState->depthBiasEnable;
524
if (!dynamic_states[VK_DYNAMIC_STATE_DEPTH_BIAS]) {
525
state->depth_bias.offset_units = rsc->depthBiasConstantFactor;
526
state->depth_bias.offset_scale = rsc->depthBiasSlopeFactor;
527
state->depth_bias.offset_clamp = rsc->depthBiasClamp;
528
}
529
530
if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_CULL_MODE_EXT)])
531
state->rs_state.cull_face = vk_cull_to_pipe(rsc->cullMode);
532
533
if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_FRONT_FACE_EXT)])
534
state->rs_state.front_ccw = (rsc->frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE);
535
state->rs_dirty = true;
536
}
537
538
state->disable_multisample = pipeline->disable_multisample;
539
if (pipeline->graphics_create_info.pMultisampleState) {
540
const VkPipelineMultisampleStateCreateInfo *ms = pipeline->graphics_create_info.pMultisampleState;
541
state->rs_state.multisample = ms->rasterizationSamples > 1;
542
state->sample_mask = ms->pSampleMask ? ms->pSampleMask[0] : 0xffffffff;
543
state->blend_state.alpha_to_coverage = ms->alphaToCoverageEnable;
544
state->blend_state.alpha_to_one = ms->alphaToOneEnable;
545
state->blend_dirty = true;
546
state->rs_dirty = true;
547
state->min_samples = 1;
548
state->sample_mask_dirty = true;
549
fb_samples = ms->rasterizationSamples;
550
if (ms->sampleShadingEnable) {
551
state->min_samples = ceil(ms->rasterizationSamples * ms->minSampleShading);
552
if (state->min_samples > 1)
553
state->min_samples = ms->rasterizationSamples;
554
if (state->min_samples < 1)
555
state->min_samples = 1;
556
}
557
if (pipeline->force_min_sample)
558
state->min_samples = ms->rasterizationSamples;
559
state->min_samples_dirty = true;
560
} else {
561
state->rs_state.multisample = false;
562
state->sample_mask_dirty = state->sample_mask != 0xffffffff;
563
state->sample_mask = 0xffffffff;
564
state->min_samples_dirty = state->min_samples;
565
state->min_samples = 0;
566
state->blend_dirty |= state->blend_state.alpha_to_coverage || state->blend_state.alpha_to_one;
567
state->blend_state.alpha_to_coverage = false;
568
state->blend_state.alpha_to_one = false;
569
state->rs_dirty = true;
570
}
571
572
if (pipeline->graphics_create_info.pDepthStencilState) {
573
const VkPipelineDepthStencilStateCreateInfo *dsa = pipeline->graphics_create_info.pDepthStencilState;
574
575
if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT)])
576
state->dsa_state.depth_enabled = dsa->depthTestEnable;
577
if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT)])
578
state->dsa_state.depth_writemask = dsa->depthWriteEnable;
579
if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT)])
580
state->dsa_state.depth_func = dsa->depthCompareOp;
581
if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT)])
582
state->dsa_state.depth_bounds_test = dsa->depthBoundsTestEnable;
583
584
if (!dynamic_states[VK_DYNAMIC_STATE_DEPTH_BOUNDS]) {
585
state->dsa_state.depth_bounds_min = dsa->minDepthBounds;
586
state->dsa_state.depth_bounds_max = dsa->maxDepthBounds;
587
}
588
589
if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT)]) {
590
state->dsa_state.stencil[0].enabled = dsa->stencilTestEnable;
591
state->dsa_state.stencil[1].enabled = dsa->stencilTestEnable;
592
}
593
594
if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_STENCIL_OP_EXT)]) {
595
state->dsa_state.stencil[0].func = dsa->front.compareOp;
596
state->dsa_state.stencil[0].fail_op = vk_conv_stencil_op(dsa->front.failOp);
597
state->dsa_state.stencil[0].zpass_op = vk_conv_stencil_op(dsa->front.passOp);
598
state->dsa_state.stencil[0].zfail_op = vk_conv_stencil_op(dsa->front.depthFailOp);
599
600
state->dsa_state.stencil[1].func = dsa->back.compareOp;
601
state->dsa_state.stencil[1].fail_op = vk_conv_stencil_op(dsa->back.failOp);
602
state->dsa_state.stencil[1].zpass_op = vk_conv_stencil_op(dsa->back.passOp);
603
state->dsa_state.stencil[1].zfail_op = vk_conv_stencil_op(dsa->back.depthFailOp);
604
}
605
606
if (!dynamic_states[VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK]) {
607
state->dsa_state.stencil[0].valuemask = dsa->front.compareMask;
608
state->dsa_state.stencil[1].valuemask = dsa->back.compareMask;
609
}
610
611
if (!dynamic_states[VK_DYNAMIC_STATE_STENCIL_WRITE_MASK]) {
612
state->dsa_state.stencil[0].writemask = dsa->front.writeMask;
613
state->dsa_state.stencil[1].writemask = dsa->back.writeMask;
614
}
615
616
if (dsa->stencilTestEnable) {
617
if (!dynamic_states[VK_DYNAMIC_STATE_STENCIL_REFERENCE]) {
618
state->stencil_ref.ref_value[0] = dsa->front.reference;
619
state->stencil_ref.ref_value[1] = dsa->back.reference;
620
state->stencil_ref_dirty = true;
621
}
622
}
623
} else
624
memset(&state->dsa_state, 0, sizeof(state->dsa_state));
625
state->dsa_dirty = true;
626
627
if (pipeline->graphics_create_info.pColorBlendState) {
628
const VkPipelineColorBlendStateCreateInfo *cb = pipeline->graphics_create_info.pColorBlendState;
629
int i;
630
631
if (cb->logicOpEnable) {
632
state->blend_state.logicop_enable = VK_TRUE;
633
if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_LOGIC_OP_EXT)])
634
state->blend_state.logicop_func = vk_conv_logic_op(cb->logicOp);
635
}
636
637
if (cb->attachmentCount > 1)
638
state->blend_state.independent_blend_enable = true;
639
for (i = 0; i < cb->attachmentCount; i++) {
640
state->blend_state.rt[i].colormask = cb->pAttachments[i].colorWriteMask;
641
state->blend_state.rt[i].blend_enable = cb->pAttachments[i].blendEnable;
642
state->blend_state.rt[i].rgb_func = vk_conv_blend_func(cb->pAttachments[i].colorBlendOp);
643
state->blend_state.rt[i].rgb_src_factor = vk_conv_blend_factor(cb->pAttachments[i].srcColorBlendFactor);
644
state->blend_state.rt[i].rgb_dst_factor = vk_conv_blend_factor(cb->pAttachments[i].dstColorBlendFactor);
645
state->blend_state.rt[i].alpha_func = vk_conv_blend_func(cb->pAttachments[i].alphaBlendOp);
646
state->blend_state.rt[i].alpha_src_factor = vk_conv_blend_factor(cb->pAttachments[i].srcAlphaBlendFactor);
647
state->blend_state.rt[i].alpha_dst_factor = vk_conv_blend_factor(cb->pAttachments[i].dstAlphaBlendFactor);
648
649
/* At least llvmpipe applies the blend factor prior to the blend function,
650
* regardless of what function is used. (like i965 hardware).
651
* It means for MIN/MAX the blend factor has to be stomped to ONE.
652
*/
653
if (cb->pAttachments[i].colorBlendOp == VK_BLEND_OP_MIN ||
654
cb->pAttachments[i].colorBlendOp == VK_BLEND_OP_MAX) {
655
state->blend_state.rt[i].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
656
state->blend_state.rt[i].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
657
}
658
659
if (cb->pAttachments[i].alphaBlendOp == VK_BLEND_OP_MIN ||
660
cb->pAttachments[i].alphaBlendOp == VK_BLEND_OP_MAX) {
661
state->blend_state.rt[i].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
662
state->blend_state.rt[i].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
663
}
664
}
665
state->blend_dirty = true;
666
if (!dynamic_states[VK_DYNAMIC_STATE_BLEND_CONSTANTS]) {
667
memcpy(state->blend_color.color, cb->blendConstants, 4 * sizeof(float));
668
state->blend_color_dirty = true;
669
}
670
} else {
671
memset(&state->blend_state, 0, sizeof(state->blend_state));
672
state->blend_dirty = true;
673
}
674
675
if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_VERTEX_INPUT_EXT)]) {
676
const VkPipelineVertexInputStateCreateInfo *vi = pipeline->graphics_create_info.pVertexInputState;
677
int i;
678
const VkPipelineVertexInputDivisorStateCreateInfoEXT *div_state =
679
vk_find_struct_const(vi->pNext,
680
PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT);
681
682
if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT)]) {
683
for (i = 0; i < vi->vertexBindingDescriptionCount; i++) {
684
state->vb[i].stride = vi->pVertexBindingDescriptions[i].stride;
685
}
686
}
687
688
int max_location = -1;
689
for (i = 0; i < vi->vertexAttributeDescriptionCount; i++) {
690
unsigned location = vi->pVertexAttributeDescriptions[i].location;
691
state->velem.velems[location].src_offset = vi->pVertexAttributeDescriptions[i].offset;
692
state->velem.velems[location].vertex_buffer_index = vi->pVertexAttributeDescriptions[i].binding;
693
state->velem.velems[location].src_format = lvp_vk_format_to_pipe_format(vi->pVertexAttributeDescriptions[i].format);
694
695
switch (vi->pVertexBindingDescriptions[vi->pVertexAttributeDescriptions[i].binding].inputRate) {
696
case VK_VERTEX_INPUT_RATE_VERTEX:
697
state->velem.velems[location].instance_divisor = 0;
698
break;
699
case VK_VERTEX_INPUT_RATE_INSTANCE:
700
if (div_state) {
701
for (unsigned j = 0; j < div_state->vertexBindingDivisorCount; j++) {
702
const VkVertexInputBindingDivisorDescriptionEXT *desc =
703
&div_state->pVertexBindingDivisors[j];
704
if (desc->binding == state->velem.velems[location].vertex_buffer_index) {
705
state->velem.velems[location].instance_divisor = desc->divisor;
706
break;
707
}
708
}
709
} else
710
state->velem.velems[location].instance_divisor = 1;
711
break;
712
default:
713
assert(0);
714
break;
715
}
716
717
if ((int)location > max_location)
718
max_location = location;
719
}
720
state->velem.count = max_location + 1;
721
state->vb_dirty = true;
722
state->ve_dirty = true;
723
}
724
725
{
726
const VkPipelineInputAssemblyStateCreateInfo *ia = pipeline->graphics_create_info.pInputAssemblyState;
727
728
if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT)]) {
729
state->info.mode = vk_conv_topology(ia->topology);
730
state->rs_dirty = true;
731
}
732
if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT)])
733
state->info.primitive_restart = ia->primitiveRestartEnable;
734
}
735
736
if (pipeline->graphics_create_info.pTessellationState) {
737
if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT)]) {
738
const VkPipelineTessellationStateCreateInfo *ts = pipeline->graphics_create_info.pTessellationState;
739
state->info.vertices_per_patch = ts->patchControlPoints;
740
}
741
} else
742
state->info.vertices_per_patch = 0;
743
744
if (pipeline->graphics_create_info.pViewportState) {
745
const VkPipelineViewportStateCreateInfo *vpi= pipeline->graphics_create_info.pViewportState;
746
int i;
747
748
if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT)]) {
749
state->num_viewports = vpi->viewportCount;
750
state->vp_dirty = true;
751
}
752
if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT)]) {
753
state->num_scissors = vpi->scissorCount;
754
state->scissor_dirty = true;
755
}
756
757
if (!dynamic_states[VK_DYNAMIC_STATE_VIEWPORT] &&
758
!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT)]) {
759
for (i = 0; i < vpi->viewportCount; i++)
760
get_viewport_xform(&vpi->pViewports[i], state->viewports[i].scale, state->viewports[i].translate);
761
state->vp_dirty = true;
762
}
763
if (!dynamic_states[VK_DYNAMIC_STATE_SCISSOR] &&
764
!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT)]) {
765
for (i = 0; i < vpi->scissorCount; i++) {
766
const VkRect2D *ss = &vpi->pScissors[i];
767
state->scissors[i].minx = ss->offset.x;
768
state->scissors[i].miny = ss->offset.y;
769
state->scissors[i].maxx = ss->offset.x + ss->extent.width;
770
state->scissors[i].maxy = ss->offset.y + ss->extent.height;
771
state->scissor_dirty = true;
772
}
773
774
}
775
}
776
777
if (fb_samples != state->framebuffer.samples) {
778
state->framebuffer.samples = fb_samples;
779
state->pctx->set_framebuffer_state(state->pctx, &state->framebuffer);
780
}
781
}
782
783
static void handle_pipeline(struct lvp_cmd_buffer_entry *cmd,
784
struct rendering_state *state)
785
{
786
struct lvp_pipeline *pipeline = cmd->u.pipeline.pipeline;
787
if (pipeline->is_compute_pipeline)
788
handle_compute_pipeline(cmd, state);
789
else
790
handle_graphics_pipeline(cmd, state);
791
}
792
793
static void handle_vertex_buffers(struct lvp_cmd_buffer_entry *cmd,
794
struct rendering_state *state)
795
{
796
int i;
797
struct lvp_cmd_bind_vertex_buffers *vcb = &cmd->u.vertex_buffers;
798
for (i = 0; i < vcb->binding_count; i++) {
799
int idx = i + vcb->first;
800
801
state->vb[idx].buffer_offset = vcb->offsets[i];
802
state->vb[idx].buffer.resource = vcb->buffers[i] ? vcb->buffers[i]->bo : NULL;
803
804
if (vcb->strides) {
805
state->vb[idx].stride = vcb->strides[i];
806
}
807
}
808
if (vcb->first < state->start_vb)
809
state->start_vb = vcb->first;
810
if (vcb->first + vcb->binding_count >= state->num_vb)
811
state->num_vb = vcb->first + vcb->binding_count;
812
state->vb_dirty = true;
813
}
814
815
struct dyn_info {
816
struct {
817
uint16_t const_buffer_count;
818
uint16_t shader_buffer_count;
819
uint16_t sampler_count;
820
uint16_t sampler_view_count;
821
uint16_t image_count;
822
} stage[MESA_SHADER_STAGES];
823
824
uint32_t dyn_index;
825
const uint32_t *dynamic_offsets;
826
uint32_t dynamic_offset_count;
827
};
828
829
static void fill_sampler(struct pipe_sampler_state *ss,
830
struct lvp_sampler *samp)
831
{
832
ss->wrap_s = vk_conv_wrap_mode(samp->create_info.addressModeU);
833
ss->wrap_t = vk_conv_wrap_mode(samp->create_info.addressModeV);
834
ss->wrap_r = vk_conv_wrap_mode(samp->create_info.addressModeW);
835
ss->min_img_filter = samp->create_info.minFilter == VK_FILTER_LINEAR ? PIPE_TEX_FILTER_LINEAR : PIPE_TEX_FILTER_NEAREST;
836
ss->min_mip_filter = samp->create_info.mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR ? PIPE_TEX_MIPFILTER_LINEAR : PIPE_TEX_MIPFILTER_NEAREST;
837
ss->mag_img_filter = samp->create_info.magFilter == VK_FILTER_LINEAR ? PIPE_TEX_FILTER_LINEAR : PIPE_TEX_FILTER_NEAREST;
838
ss->min_lod = samp->create_info.minLod;
839
ss->max_lod = samp->create_info.maxLod;
840
ss->lod_bias = samp->create_info.mipLodBias;
841
ss->max_anisotropy = samp->create_info.maxAnisotropy;
842
ss->normalized_coords = !samp->create_info.unnormalizedCoordinates;
843
ss->compare_mode = samp->create_info.compareEnable ? PIPE_TEX_COMPARE_R_TO_TEXTURE : PIPE_TEX_COMPARE_NONE;
844
ss->compare_func = samp->create_info.compareOp;
845
ss->seamless_cube_map = true;
846
ss->reduction_mode = samp->reduction_mode;
847
memcpy(&ss->border_color, &samp->border_color,
848
sizeof(union pipe_color_union));
849
}
850
851
static void fill_sampler_stage(struct rendering_state *state,
852
struct dyn_info *dyn_info,
853
gl_shader_stage stage,
854
enum pipe_shader_type p_stage,
855
int array_idx,
856
const union lvp_descriptor_info *descriptor,
857
const struct lvp_descriptor_set_binding_layout *binding)
858
{
859
int ss_idx = binding->stage[stage].sampler_index;
860
if (ss_idx == -1)
861
return;
862
ss_idx += array_idx;
863
ss_idx += dyn_info->stage[stage].sampler_count;
864
fill_sampler(&state->ss[p_stage][ss_idx], binding->immutable_samplers ? binding->immutable_samplers[array_idx] : descriptor->sampler);
865
if (state->num_sampler_states[p_stage] <= ss_idx)
866
state->num_sampler_states[p_stage] = ss_idx + 1;
867
state->ss_dirty[p_stage] = true;
868
}
869
870
#define fix_depth_swizzle(x) do { \
871
if (x > PIPE_SWIZZLE_X && x < PIPE_SWIZZLE_0) \
872
x = PIPE_SWIZZLE_0; \
873
} while (0)
874
#define fix_depth_swizzle_a(x) do { \
875
if (x > PIPE_SWIZZLE_X && x < PIPE_SWIZZLE_0) \
876
x = PIPE_SWIZZLE_1; \
877
} while (0)
878
879
static void fill_sampler_view_stage(struct rendering_state *state,
880
struct dyn_info *dyn_info,
881
gl_shader_stage stage,
882
enum pipe_shader_type p_stage,
883
int array_idx,
884
const union lvp_descriptor_info *descriptor,
885
const struct lvp_descriptor_set_binding_layout *binding)
886
{
887
int sv_idx = binding->stage[stage].sampler_view_index;
888
if (sv_idx == -1)
889
return;
890
sv_idx += array_idx;
891
sv_idx += dyn_info->stage[stage].sampler_view_count;
892
struct lvp_image_view *iv = descriptor->iview;
893
struct pipe_sampler_view templ;
894
895
enum pipe_format pformat;
896
if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
897
pformat = lvp_vk_format_to_pipe_format(iv->format);
898
else if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
899
pformat = util_format_stencil_only(lvp_vk_format_to_pipe_format(iv->format));
900
else
901
pformat = lvp_vk_format_to_pipe_format(iv->format);
902
u_sampler_view_default_template(&templ,
903
iv->image->bo,
904
pformat);
905
if (iv->view_type == VK_IMAGE_VIEW_TYPE_1D)
906
templ.target = PIPE_TEXTURE_1D;
907
if (iv->view_type == VK_IMAGE_VIEW_TYPE_2D)
908
templ.target = PIPE_TEXTURE_2D;
909
if (iv->view_type == VK_IMAGE_VIEW_TYPE_CUBE)
910
templ.target = PIPE_TEXTURE_CUBE;
911
if (iv->view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
912
templ.target = PIPE_TEXTURE_CUBE_ARRAY;
913
templ.u.tex.first_layer = iv->subresourceRange.baseArrayLayer;
914
templ.u.tex.last_layer = iv->subresourceRange.baseArrayLayer + lvp_get_layerCount(iv->image, &iv->subresourceRange) - 1;
915
templ.u.tex.first_level = iv->subresourceRange.baseMipLevel;
916
templ.u.tex.last_level = iv->subresourceRange.baseMipLevel + lvp_get_levelCount(iv->image, &iv->subresourceRange) - 1;
917
if (iv->components.r != VK_COMPONENT_SWIZZLE_IDENTITY)
918
templ.swizzle_r = vk_conv_swizzle(iv->components.r);
919
if (iv->components.g != VK_COMPONENT_SWIZZLE_IDENTITY)
920
templ.swizzle_g = vk_conv_swizzle(iv->components.g);
921
if (iv->components.b != VK_COMPONENT_SWIZZLE_IDENTITY)
922
templ.swizzle_b = vk_conv_swizzle(iv->components.b);
923
if (iv->components.a != VK_COMPONENT_SWIZZLE_IDENTITY)
924
templ.swizzle_a = vk_conv_swizzle(iv->components.a);
925
926
/* depth stencil swizzles need special handling to pass VK CTS
927
* but also for zink GL tests.
928
* piping A swizzle into R fixes GL_ALPHA depth texture mode
929
* only swizzling from R/0/1 (for alpha) fixes VK CTS tests
930
* and a bunch of zink tests.
931
*/
932
if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT ||
933
iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {
934
if (templ.swizzle_a == PIPE_SWIZZLE_X)
935
templ.swizzle_r = PIPE_SWIZZLE_X;
936
fix_depth_swizzle(templ.swizzle_r);
937
fix_depth_swizzle(templ.swizzle_g);
938
fix_depth_swizzle(templ.swizzle_b);
939
fix_depth_swizzle_a(templ.swizzle_a);
940
}
941
942
if (state->sv[p_stage][sv_idx])
943
pipe_sampler_view_reference(&state->sv[p_stage][sv_idx], NULL);
944
state->sv[p_stage][sv_idx] = state->pctx->create_sampler_view(state->pctx, iv->image->bo, &templ);
945
if (state->num_sampler_views[p_stage] <= sv_idx)
946
state->num_sampler_views[p_stage] = sv_idx + 1;
947
state->sv_dirty[p_stage] = true;
948
}
949
950
static void fill_sampler_buffer_view_stage(struct rendering_state *state,
951
struct dyn_info *dyn_info,
952
gl_shader_stage stage,
953
enum pipe_shader_type p_stage,
954
int array_idx,
955
const union lvp_descriptor_info *descriptor,
956
const struct lvp_descriptor_set_binding_layout *binding)
957
{
958
int sv_idx = binding->stage[stage].sampler_view_index;
959
if (sv_idx == -1)
960
return;
961
sv_idx += array_idx;
962
sv_idx += dyn_info->stage[stage].sampler_view_count;
963
struct lvp_buffer_view *bv = descriptor->buffer_view;
964
struct pipe_sampler_view templ;
965
memset(&templ, 0, sizeof(templ));
966
templ.target = PIPE_BUFFER;
967
templ.swizzle_r = PIPE_SWIZZLE_X;
968
templ.swizzle_g = PIPE_SWIZZLE_Y;
969
templ.swizzle_b = PIPE_SWIZZLE_Z;
970
templ.swizzle_a = PIPE_SWIZZLE_W;
971
templ.format = bv->pformat;
972
templ.u.buf.offset = bv->offset + bv->buffer->offset;
973
templ.u.buf.size = bv->range == VK_WHOLE_SIZE ? (bv->buffer->size - bv->offset) : bv->range;
974
templ.texture = bv->buffer->bo;
975
templ.context = state->pctx;
976
977
if (state->sv[p_stage][sv_idx])
978
pipe_sampler_view_reference(&state->sv[p_stage][sv_idx], NULL);
979
state->sv[p_stage][sv_idx] = state->pctx->create_sampler_view(state->pctx, bv->buffer->bo, &templ);
980
if (state->num_sampler_views[p_stage] <= sv_idx)
981
state->num_sampler_views[p_stage] = sv_idx + 1;
982
state->sv_dirty[p_stage] = true;
983
}
984
985
static void fill_image_view_stage(struct rendering_state *state,
986
struct dyn_info *dyn_info,
987
gl_shader_stage stage,
988
enum pipe_shader_type p_stage,
989
int array_idx,
990
const union lvp_descriptor_info *descriptor,
991
const struct lvp_descriptor_set_binding_layout *binding)
992
{
993
struct lvp_image_view *iv = descriptor->iview;
994
int idx = binding->stage[stage].image_index;
995
if (idx == -1)
996
return;
997
idx += array_idx;
998
idx += dyn_info->stage[stage].image_count;
999
state->iv[p_stage][idx].resource = iv->image->bo;
1000
if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
1001
state->iv[p_stage][idx].format = lvp_vk_format_to_pipe_format(iv->format);
1002
else if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
1003
state->iv[p_stage][idx].format = util_format_stencil_only(lvp_vk_format_to_pipe_format(iv->format));
1004
else
1005
state->iv[p_stage][idx].format = lvp_vk_format_to_pipe_format(iv->format);
1006
1007
if (iv->view_type == VK_IMAGE_VIEW_TYPE_3D) {
1008
state->iv[p_stage][idx].u.tex.first_layer = 0;
1009
state->iv[p_stage][idx].u.tex.last_layer = u_minify(iv->image->bo->depth0, iv->subresourceRange.baseMipLevel) - 1;
1010
} else {
1011
state->iv[p_stage][idx].u.tex.first_layer = iv->subresourceRange.baseArrayLayer;
1012
state->iv[p_stage][idx].u.tex.last_layer = iv->subresourceRange.baseArrayLayer + lvp_get_layerCount(iv->image, &iv->subresourceRange) - 1;
1013
}
1014
state->iv[p_stage][idx].u.tex.level = iv->subresourceRange.baseMipLevel;
1015
if (state->num_shader_images[p_stage] <= idx)
1016
state->num_shader_images[p_stage] = idx + 1;
1017
state->iv_dirty[p_stage] = true;
1018
}
1019
1020
static void fill_image_buffer_view_stage(struct rendering_state *state,
1021
struct dyn_info *dyn_info,
1022
gl_shader_stage stage,
1023
enum pipe_shader_type p_stage,
1024
int array_idx,
1025
const union lvp_descriptor_info *descriptor,
1026
const struct lvp_descriptor_set_binding_layout *binding)
1027
{
1028
struct lvp_buffer_view *bv = descriptor->buffer_view;
1029
int idx = binding->stage[stage].image_index;
1030
if (idx == -1)
1031
return;
1032
idx += array_idx;
1033
idx += dyn_info->stage[stage].image_count;
1034
state->iv[p_stage][idx].resource = bv->buffer->bo;
1035
state->iv[p_stage][idx].format = bv->pformat;
1036
state->iv[p_stage][idx].u.buf.offset = bv->offset + bv->buffer->offset;
1037
state->iv[p_stage][idx].u.buf.size = bv->range == VK_WHOLE_SIZE ? (bv->buffer->size - bv->offset): bv->range;
1038
if (state->num_shader_images[p_stage] <= idx)
1039
state->num_shader_images[p_stage] = idx + 1;
1040
state->iv_dirty[p_stage] = true;
1041
}
1042
1043
static void handle_descriptor(struct rendering_state *state,
1044
struct dyn_info *dyn_info,
1045
const struct lvp_descriptor_set_binding_layout *binding,
1046
gl_shader_stage stage,
1047
enum pipe_shader_type p_stage,
1048
int array_idx,
1049
VkDescriptorType type,
1050
const union lvp_descriptor_info *descriptor)
1051
{
1052
bool is_dynamic = type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
1053
type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
1054
1055
switch (type) {
1056
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1057
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
1058
fill_image_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
1059
break;
1060
}
1061
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1062
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: {
1063
int idx = binding->stage[stage].const_buffer_index;
1064
if (idx == -1)
1065
return;
1066
idx += array_idx;
1067
idx += dyn_info->stage[stage].const_buffer_count;
1068
state->const_buffer[p_stage][idx].buffer = descriptor->buffer->bo;
1069
state->const_buffer[p_stage][idx].buffer_offset = descriptor->offset + descriptor->buffer->offset;
1070
if (is_dynamic) {
1071
uint32_t offset = dyn_info->dynamic_offsets[dyn_info->dyn_index + binding->dynamic_index + array_idx];
1072
state->const_buffer[p_stage][idx].buffer_offset += offset;
1073
}
1074
if (descriptor->range == VK_WHOLE_SIZE)
1075
state->const_buffer[p_stage][idx].buffer_size = descriptor->buffer->bo->width0 - state->const_buffer[p_stage][idx].buffer_offset;
1076
else
1077
state->const_buffer[p_stage][idx].buffer_size = descriptor->range;
1078
if (state->num_const_bufs[p_stage] <= idx)
1079
state->num_const_bufs[p_stage] = idx + 1;
1080
state->constbuf_dirty[p_stage] = true;
1081
break;
1082
}
1083
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1084
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
1085
int idx = binding->stage[stage].shader_buffer_index;
1086
if (idx == -1)
1087
return;
1088
idx += array_idx;
1089
idx += dyn_info->stage[stage].shader_buffer_count;
1090
state->sb[p_stage][idx].buffer = descriptor->buffer->bo;
1091
state->sb[p_stage][idx].buffer_offset = descriptor->offset + descriptor->buffer->offset;
1092
if (is_dynamic) {
1093
uint32_t offset = dyn_info->dynamic_offsets[dyn_info->dyn_index + binding->dynamic_index + array_idx];
1094
state->sb[p_stage][idx].buffer_offset += offset;
1095
}
1096
if (descriptor->range == VK_WHOLE_SIZE)
1097
state->sb[p_stage][idx].buffer_size = descriptor->buffer->bo->width0 - state->sb[p_stage][idx].buffer_offset;
1098
else
1099
state->sb[p_stage][idx].buffer_size = descriptor->range;
1100
if (state->num_shader_buffers[p_stage] <= idx)
1101
state->num_shader_buffers[p_stage] = idx + 1;
1102
state->sb_dirty[p_stage] = true;
1103
break;
1104
}
1105
case VK_DESCRIPTOR_TYPE_SAMPLER:
1106
if (!descriptor->sampler)
1107
return;
1108
fill_sampler_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
1109
break;
1110
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1111
fill_sampler_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
1112
break;
1113
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1114
fill_sampler_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
1115
fill_sampler_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
1116
break;
1117
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1118
fill_sampler_buffer_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
1119
break;
1120
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1121
fill_image_buffer_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);
1122
break;
1123
default:
1124
fprintf(stderr, "Unhandled descriptor set %d\n", type);
1125
break;
1126
}
1127
}
1128
1129
static void handle_set_stage(struct rendering_state *state,
1130
struct dyn_info *dyn_info,
1131
const struct lvp_descriptor_set *set,
1132
gl_shader_stage stage,
1133
enum pipe_shader_type p_stage)
1134
{
1135
int j;
1136
for (j = 0; j < set->layout->binding_count; j++) {
1137
const struct lvp_descriptor_set_binding_layout *binding;
1138
const struct lvp_descriptor *descriptor;
1139
binding = &set->layout->binding[j];
1140
1141
if (binding->valid) {
1142
for (int i = 0; i < binding->array_size; i++) {
1143
descriptor = &set->descriptors[binding->descriptor_index + i];
1144
handle_descriptor(state, dyn_info, binding, stage, p_stage, i, descriptor->type, &descriptor->info);
1145
}
1146
}
1147
}
1148
}
1149
1150
static void increment_dyn_info(struct dyn_info *dyn_info,
1151
struct lvp_descriptor_set_layout *layout, bool inc_dyn)
1152
{
1153
for (gl_shader_stage stage = MESA_SHADER_VERTEX; stage < MESA_SHADER_STAGES; stage++) {
1154
dyn_info->stage[stage].const_buffer_count += layout->stage[stage].const_buffer_count;
1155
dyn_info->stage[stage].shader_buffer_count += layout->stage[stage].shader_buffer_count;
1156
dyn_info->stage[stage].sampler_count += layout->stage[stage].sampler_count;
1157
dyn_info->stage[stage].sampler_view_count += layout->stage[stage].sampler_view_count;
1158
dyn_info->stage[stage].image_count += layout->stage[stage].image_count;
1159
}
1160
if (inc_dyn)
1161
dyn_info->dyn_index += layout->dynamic_offset_count;
1162
}
1163
1164
static void handle_compute_descriptor_sets(struct lvp_cmd_buffer_entry *cmd,
1165
struct dyn_info *dyn_info,
1166
struct rendering_state *state)
1167
{
1168
struct lvp_cmd_bind_descriptor_sets *bds = &cmd->u.descriptor_sets;
1169
int i;
1170
1171
for (i = 0; i < bds->first; i++) {
1172
increment_dyn_info(dyn_info, bds->set_layout[i], false);
1173
}
1174
for (i = 0; i < bds->count; i++) {
1175
const struct lvp_descriptor_set *set = bds->sets[i];
1176
1177
if (set->layout->shader_stages & VK_SHADER_STAGE_COMPUTE_BIT)
1178
handle_set_stage(state, dyn_info, set, MESA_SHADER_COMPUTE, PIPE_SHADER_COMPUTE);
1179
increment_dyn_info(dyn_info, bds->set_layout[bds->first + i], true);
1180
}
1181
}
1182
1183
static void handle_descriptor_sets(struct lvp_cmd_buffer_entry *cmd,
1184
struct rendering_state *state)
1185
{
1186
struct lvp_cmd_bind_descriptor_sets *bds = &cmd->u.descriptor_sets;
1187
int i;
1188
struct dyn_info dyn_info;
1189
1190
dyn_info.dyn_index = 0;
1191
dyn_info.dynamic_offsets = bds->dynamic_offsets;
1192
dyn_info.dynamic_offset_count = bds->dynamic_offset_count;
1193
1194
memset(dyn_info.stage, 0, sizeof(dyn_info.stage));
1195
if (bds->bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
1196
handle_compute_descriptor_sets(cmd, &dyn_info, state);
1197
return;
1198
}
1199
1200
for (i = 0; i < bds->first; i++) {
1201
increment_dyn_info(&dyn_info, bds->set_layout[i], false);
1202
}
1203
1204
for (i = 0; i < bds->count; i++) {
1205
const struct lvp_descriptor_set *set = bds->sets[i];
1206
1207
if (set->layout->shader_stages & VK_SHADER_STAGE_VERTEX_BIT)
1208
handle_set_stage(state, &dyn_info, set, MESA_SHADER_VERTEX, PIPE_SHADER_VERTEX);
1209
1210
if (set->layout->shader_stages & VK_SHADER_STAGE_GEOMETRY_BIT)
1211
handle_set_stage(state, &dyn_info, set, MESA_SHADER_GEOMETRY, PIPE_SHADER_GEOMETRY);
1212
1213
if (set->layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
1214
handle_set_stage(state, &dyn_info, set, MESA_SHADER_TESS_CTRL, PIPE_SHADER_TESS_CTRL);
1215
1216
if (set->layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
1217
handle_set_stage(state, &dyn_info, set, MESA_SHADER_TESS_EVAL, PIPE_SHADER_TESS_EVAL);
1218
1219
if (set->layout->shader_stages & VK_SHADER_STAGE_FRAGMENT_BIT)
1220
handle_set_stage(state, &dyn_info, set, MESA_SHADER_FRAGMENT, PIPE_SHADER_FRAGMENT);
1221
increment_dyn_info(&dyn_info, bds->set_layout[bds->first + i], true);
1222
}
1223
}
1224
1225
static struct pipe_surface *create_img_surface_bo(struct rendering_state *state,
1226
VkImageSubresourceRange *range,
1227
struct pipe_resource *bo,
1228
enum pipe_format pformat,
1229
int width,
1230
int height,
1231
int base_layer, int layer_count,
1232
int level)
1233
{
1234
struct pipe_surface template;
1235
1236
memset(&template, 0, sizeof(struct pipe_surface));
1237
1238
template.format = pformat;
1239
template.width = width;
1240
template.height = height;
1241
template.u.tex.first_layer = range->baseArrayLayer + base_layer;
1242
template.u.tex.last_layer = range->baseArrayLayer + layer_count;
1243
template.u.tex.level = range->baseMipLevel + level;
1244
1245
if (template.format == PIPE_FORMAT_NONE)
1246
return NULL;
1247
return state->pctx->create_surface(state->pctx,
1248
bo, &template);
1249
1250
}
1251
static struct pipe_surface *create_img_surface(struct rendering_state *state,
1252
struct lvp_image_view *imgv,
1253
VkFormat format, int width,
1254
int height,
1255
int base_layer, int layer_count)
1256
{
1257
return create_img_surface_bo(state, &imgv->subresourceRange, imgv->image->bo,
1258
lvp_vk_format_to_pipe_format(format), width, height, base_layer, layer_count, 0);
1259
}
1260
1261
static void add_img_view_surface(struct rendering_state *state,
1262
struct lvp_image_view *imgv, VkFormat format, int width, int height)
1263
{
1264
if (!imgv->surface) {
1265
imgv->surface = create_img_surface(state, imgv, format,
1266
width, height,
1267
0, lvp_get_layerCount(imgv->image, &imgv->subresourceRange) - 1);
1268
}
1269
}
1270
1271
static inline bool
1272
attachment_needs_clear(struct rendering_state *state,
1273
uint32_t a)
1274
{
1275
const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
1276
uint32_t view_mask = subpass->view_mask;
1277
return (a != VK_ATTACHMENT_UNUSED &&
1278
state->pending_clear_aspects[a] &&
1279
(!view_mask || (view_mask & ~state->cleared_views[a])));
1280
}
1281
1282
static bool
1283
subpass_needs_clear(struct rendering_state *state)
1284
{
1285
uint32_t a;
1286
const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
1287
for (uint32_t i = 0; i < subpass->color_count; i++) {
1288
a = subpass->color_attachments[i].attachment;
1289
if (attachment_needs_clear(state, a))
1290
return true;
1291
}
1292
if (subpass->depth_stencil_attachment) {
1293
a = subpass->depth_stencil_attachment->attachment;
1294
if (attachment_needs_clear(state, a))
1295
return true;
1296
}
1297
return false;
1298
}
1299
1300
static void clear_attachment_layers(struct rendering_state *state,
1301
struct lvp_image_view *imgv,
1302
VkRect2D *rect,
1303
unsigned base_layer, unsigned layer_count,
1304
unsigned ds_clear_flags, double dclear_val,
1305
uint32_t sclear_val,
1306
union pipe_color_union *col_val)
1307
{
1308
struct pipe_surface *clear_surf = create_img_surface(state,
1309
imgv,
1310
imgv->format,
1311
state->framebuffer.width,
1312
state->framebuffer.height,
1313
base_layer,
1314
base_layer + layer_count - 1);
1315
1316
if (ds_clear_flags) {
1317
state->pctx->clear_depth_stencil(state->pctx,
1318
clear_surf,
1319
ds_clear_flags,
1320
dclear_val, sclear_val,
1321
rect->offset.x, rect->offset.y,
1322
rect->extent.width, rect->extent.height,
1323
true);
1324
} else {
1325
state->pctx->clear_render_target(state->pctx, clear_surf,
1326
col_val,
1327
rect->offset.x, rect->offset.y,
1328
rect->extent.width, rect->extent.height,
1329
true);
1330
}
1331
state->pctx->surface_destroy(state->pctx, clear_surf);
1332
}
1333
1334
static struct lvp_image_view *
1335
get_attachment(struct rendering_state *state,
1336
unsigned idx)
1337
{
1338
if (state->imageless_views)
1339
return state->imageless_views[idx];
1340
else
1341
return state->vk_framebuffer->attachments[idx];
1342
}
1343
1344
static void render_subpass_clear(struct rendering_state *state)
1345
{
1346
const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
1347
1348
for (unsigned i = 0; i < subpass->color_count; i++) {
1349
uint32_t a = subpass->color_attachments[i].attachment;
1350
1351
if (!attachment_needs_clear(state, a))
1352
continue;
1353
1354
union pipe_color_union color_clear_val = { 0 };
1355
const VkClearValue value = state->attachments[a].clear_value;
1356
color_clear_val.ui[0] = value.color.uint32[0];
1357
color_clear_val.ui[1] = value.color.uint32[1];
1358
color_clear_val.ui[2] = value.color.uint32[2];
1359
color_clear_val.ui[3] = value.color.uint32[3];
1360
1361
struct lvp_image_view *imgv = get_attachment(state, a);
1362
1363
assert(imgv->surface);
1364
1365
if (subpass->view_mask) {
1366
u_foreach_bit(i, subpass->view_mask)
1367
clear_attachment_layers(state, imgv, &state->render_area,
1368
i, 1, 0, 0, 0, &color_clear_val);
1369
state->cleared_views[a] |= subpass->view_mask;
1370
} else {
1371
state->pctx->clear_render_target(state->pctx,
1372
imgv->surface,
1373
&color_clear_val,
1374
state->render_area.offset.x, state->render_area.offset.y,
1375
state->render_area.extent.width, state->render_area.extent.height,
1376
false);
1377
state->pending_clear_aspects[a] = 0;
1378
}
1379
}
1380
1381
if (subpass->depth_stencil_attachment) {
1382
uint32_t ds = subpass->depth_stencil_attachment->attachment;
1383
1384
if (!attachment_needs_clear(state, ds))
1385
return;
1386
1387
struct lvp_render_pass_attachment *att = &state->pass->attachments[ds];
1388
struct lvp_image_view *imgv = get_attachment(state, ds);
1389
1390
assert (util_format_is_depth_or_stencil(imgv->surface->format));
1391
1392
const struct util_format_description *desc = util_format_description(imgv->surface->format);
1393
double dclear_val = 0;
1394
uint32_t sclear_val = 0;
1395
uint32_t ds_clear_flags = 0;
1396
1397
if ((util_format_has_stencil(desc) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) ||
1398
(util_format_is_depth_and_stencil(imgv->surface->format) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE)) {
1399
ds_clear_flags |= PIPE_CLEAR_STENCIL;
1400
if (att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
1401
sclear_val = state->attachments[ds].clear_value.depthStencil.stencil;
1402
}
1403
if ((util_format_has_depth(desc) && att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) ||
1404
(util_format_is_depth_and_stencil(imgv->surface->format) && att->load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE)) {
1405
ds_clear_flags |= PIPE_CLEAR_DEPTH;
1406
if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
1407
dclear_val = state->attachments[ds].clear_value.depthStencil.depth;
1408
}
1409
1410
assert(imgv->surface);
1411
if (ds_clear_flags) {
1412
if (subpass->view_mask) {
1413
u_foreach_bit(i, subpass->view_mask)
1414
clear_attachment_layers(state, imgv, &state->render_area,
1415
i, 1, ds_clear_flags, dclear_val, sclear_val, NULL);
1416
state->cleared_views[ds] |= subpass->view_mask;
1417
} else {
1418
state->pctx->clear_depth_stencil(state->pctx,
1419
imgv->surface,
1420
ds_clear_flags,
1421
dclear_val, sclear_val,
1422
state->render_area.offset.x, state->render_area.offset.y,
1423
state->render_area.extent.width, state->render_area.extent.height,
1424
false);
1425
state->pending_clear_aspects[ds] = 0;
1426
}
1427
}
1428
1429
}
1430
1431
}
1432
1433
static void render_subpass_clear_fast(struct rendering_state *state)
1434
{
1435
/* attempt to use the clear interface first, then fallback to per-attchment clears */
1436
const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
1437
bool has_color_value = false;
1438
uint32_t buffers = 0;
1439
VkClearValue color_value = {0};
1440
double dclear_val = 0;
1441
uint32_t sclear_val = 0;
1442
1443
/*
1444
* the state tracker clear interface only works if all the attachments have the same
1445
* clear color.
1446
*/
1447
/* llvmpipe doesn't support scissored clears yet */
1448
if (state->render_area.offset.x || state->render_area.offset.y)
1449
goto slow_clear;
1450
1451
if (state->render_area.extent.width != state->framebuffer.width ||
1452
state->render_area.extent.height != state->framebuffer.height)
1453
goto slow_clear;
1454
1455
if (subpass->view_mask)
1456
goto slow_clear;
1457
for (unsigned i = 0; i < subpass->color_count; i++) {
1458
uint32_t a = subpass->color_attachments[i].attachment;
1459
1460
if (!attachment_needs_clear(state, a))
1461
continue;
1462
1463
if (has_color_value) {
1464
if (memcmp(&color_value, &state->attachments[a].clear_value, sizeof(VkClearValue)))
1465
goto slow_clear;
1466
} else {
1467
memcpy(&color_value, &state->attachments[a].clear_value, sizeof(VkClearValue));
1468
has_color_value = true;
1469
}
1470
}
1471
1472
for (unsigned i = 0; i < subpass->color_count; i++) {
1473
uint32_t a = subpass->color_attachments[i].attachment;
1474
1475
if (!attachment_needs_clear(state, a))
1476
continue;
1477
buffers |= (PIPE_CLEAR_COLOR0 << i);
1478
state->pending_clear_aspects[a] = 0;
1479
}
1480
1481
if (subpass->depth_stencil_attachment &&
1482
attachment_needs_clear(state, subpass->depth_stencil_attachment->attachment)) {
1483
uint32_t ds = subpass->depth_stencil_attachment->attachment;
1484
1485
struct lvp_render_pass_attachment *att = &state->pass->attachments[ds];
1486
struct lvp_image_view *imgv = get_attachment(state, ds);
1487
const struct util_format_description *desc = util_format_description(imgv->surface->format);
1488
1489
/* also clear stencil for don't care to avoid RMW */
1490
if ((util_format_has_stencil(desc) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) ||
1491
(util_format_is_depth_and_stencil(imgv->surface->format) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE))
1492
buffers |= PIPE_CLEAR_STENCIL;
1493
if (util_format_has_depth(desc) && att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
1494
buffers |= PIPE_CLEAR_DEPTH;
1495
1496
dclear_val = state->attachments[ds].clear_value.depthStencil.depth;
1497
sclear_val = state->attachments[ds].clear_value.depthStencil.stencil;
1498
state->pending_clear_aspects[ds] = 0;
1499
}
1500
1501
union pipe_color_union col_val;
1502
for (unsigned i = 0; i < 4; i++)
1503
col_val.ui[i] = color_value.color.uint32[i];
1504
1505
state->pctx->clear(state->pctx, buffers,
1506
NULL, &col_val,
1507
dclear_val, sclear_val);
1508
return;
1509
slow_clear:
1510
render_subpass_clear(state);
1511
}
1512
1513
static void render_pass_resolve(struct rendering_state *state)
1514
{
1515
const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
1516
if (!subpass->has_color_resolve)
1517
return;
1518
for (uint32_t i = 0; i < subpass->color_count; i++) {
1519
struct lvp_subpass_attachment src_att = subpass->color_attachments[i];
1520
struct lvp_subpass_attachment dst_att = subpass->resolve_attachments[i];
1521
1522
if (dst_att.attachment == VK_ATTACHMENT_UNUSED)
1523
continue;
1524
1525
struct lvp_image_view *src_imgv = get_attachment(state, src_att.attachment);
1526
struct lvp_image_view *dst_imgv = get_attachment(state, dst_att.attachment);
1527
1528
struct pipe_blit_info info;
1529
memset(&info, 0, sizeof(info));
1530
1531
info.src.resource = src_imgv->image->bo;
1532
info.dst.resource = dst_imgv->image->bo;
1533
info.src.format = src_imgv->pformat;
1534
info.dst.format = dst_imgv->pformat;
1535
info.filter = PIPE_TEX_FILTER_NEAREST;
1536
info.mask = PIPE_MASK_RGBA;
1537
info.src.box.x = state->render_area.offset.x;
1538
info.src.box.y = state->render_area.offset.y;
1539
info.src.box.width = state->render_area.extent.width;
1540
info.src.box.height = state->render_area.extent.height;
1541
info.src.box.depth = state->vk_framebuffer->layers;
1542
1543
info.dst.box = info.src.box;
1544
1545
info.src.level = src_imgv->subresourceRange.baseMipLevel;
1546
info.dst.level = dst_imgv->subresourceRange.baseMipLevel;
1547
1548
state->pctx->blit(state->pctx, &info);
1549
}
1550
}
1551
1552
static void begin_render_subpass(struct rendering_state *state,
1553
int subpass_idx)
1554
{
1555
state->subpass = subpass_idx;
1556
1557
state->framebuffer.nr_cbufs = 0;
1558
1559
const struct lvp_subpass *subpass = &state->pass->subpasses[subpass_idx];
1560
for (unsigned i = 0; i < subpass->color_count; i++) {
1561
struct lvp_subpass_attachment *color_att = &subpass->color_attachments[i];
1562
if (color_att->attachment != VK_ATTACHMENT_UNUSED) {
1563
struct lvp_image_view *imgv = get_attachment(state, color_att->attachment);
1564
add_img_view_surface(state, imgv, state->pass->attachments[color_att->attachment].format, state->framebuffer.width, state->framebuffer.height);
1565
state->framebuffer.cbufs[state->framebuffer.nr_cbufs] = imgv->surface;
1566
} else
1567
state->framebuffer.cbufs[state->framebuffer.nr_cbufs] = NULL;
1568
state->framebuffer.nr_cbufs++;
1569
}
1570
1571
if (subpass->depth_stencil_attachment) {
1572
struct lvp_subpass_attachment *ds_att = subpass->depth_stencil_attachment;
1573
1574
if (ds_att->attachment != VK_ATTACHMENT_UNUSED) {
1575
struct lvp_image_view *imgv = get_attachment(state, ds_att->attachment);
1576
add_img_view_surface(state, imgv, state->pass->attachments[ds_att->attachment].format, state->framebuffer.width, state->framebuffer.height);
1577
state->framebuffer.zsbuf = imgv->surface;
1578
}
1579
}
1580
1581
state->pctx->set_framebuffer_state(state->pctx,
1582
&state->framebuffer);
1583
1584
if (subpass_needs_clear(state))
1585
render_subpass_clear_fast(state);
1586
}
1587
1588
static void handle_begin_render_pass(struct lvp_cmd_buffer_entry *cmd,
1589
struct rendering_state *state)
1590
{
1591
state->pass = cmd->u.begin_render_pass.render_pass;
1592
state->vk_framebuffer = cmd->u.begin_render_pass.framebuffer;
1593
state->render_area = cmd->u.begin_render_pass.render_area;
1594
1595
state->attachments = cmd->u.begin_render_pass.attachments;
1596
1597
state->imageless_views = cmd->u.begin_render_pass.imageless_views;
1598
state->framebuffer.width = state->vk_framebuffer->width;
1599
state->framebuffer.height = state->vk_framebuffer->height;
1600
state->framebuffer.layers = state->vk_framebuffer->layers;
1601
1602
if (state->num_pending_aspects < state->pass->attachment_count) {
1603
state->pending_clear_aspects = realloc(state->pending_clear_aspects, sizeof(VkImageAspectFlags) * state->pass->attachment_count);
1604
state->cleared_views = realloc(state->cleared_views, sizeof(uint32_t) * state->pass->attachment_count);
1605
state->num_pending_aspects = state->pass->attachment_count;
1606
}
1607
1608
for (unsigned a = 0; a < state->pass->attachment_count; a++) {
1609
state->pending_clear_aspects[a] = state->attachments[a].pending_clear_aspects;
1610
state->cleared_views[a] = 0;
1611
}
1612
begin_render_subpass(state, 0);
1613
}
1614
1615
static void handle_end_render_pass(struct lvp_cmd_buffer_entry *cmd,
1616
struct rendering_state *state)
1617
{
1618
state->pctx->flush(state->pctx, NULL, 0);
1619
1620
render_pass_resolve(state);
1621
1622
state->attachments = NULL;
1623
state->pass = NULL;
1624
state->subpass = 0;
1625
}
1626
1627
static void handle_next_subpass(struct lvp_cmd_buffer_entry *cmd,
1628
struct rendering_state *state)
1629
{
1630
state->pctx->flush(state->pctx, NULL, 0);
1631
render_pass_resolve(state);
1632
state->subpass++;
1633
begin_render_subpass(state, state->subpass);
1634
}
1635
1636
static void handle_draw(struct lvp_cmd_buffer_entry *cmd,
1637
struct rendering_state *state)
1638
{
1639
const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
1640
state->info.index_size = 0;
1641
state->info.index.resource = NULL;
1642
state->info.start_instance = cmd->u.draw.first_instance;
1643
state->info.instance_count = cmd->u.draw.instance_count;
1644
state->info.view_mask = subpass->view_mask;
1645
state->info.increment_draw_id = true;
1646
1647
state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, cmd->u.draw.draws, cmd->u.draw.draw_count);
1648
}
1649
1650
static void handle_set_viewport(struct lvp_cmd_buffer_entry *cmd,
1651
struct rendering_state *state)
1652
{
1653
int i;
1654
unsigned base = 0;
1655
if (cmd->u.set_viewport.first_viewport == UINT32_MAX)
1656
state->num_viewports = cmd->u.set_viewport.viewport_count;
1657
else
1658
base = cmd->u.set_viewport.first_viewport;
1659
1660
for (i = 0; i < cmd->u.set_viewport.viewport_count; i++) {
1661
int idx = i + base;
1662
const VkViewport *vp = &cmd->u.set_viewport.viewports[i];
1663
get_viewport_xform(vp, state->viewports[idx].scale, state->viewports[idx].translate);
1664
}
1665
state->vp_dirty = true;
1666
}
1667
1668
static void handle_set_scissor(struct lvp_cmd_buffer_entry *cmd,
1669
struct rendering_state *state)
1670
{
1671
int i;
1672
unsigned base = 0;
1673
if (cmd->u.set_scissor.first_scissor == UINT32_MAX)
1674
state->num_scissors = cmd->u.set_scissor.scissor_count;
1675
else
1676
base = cmd->u.set_scissor.first_scissor;
1677
1678
for (i = 0; i < cmd->u.set_scissor.scissor_count; i++) {
1679
int idx = i + base;
1680
const VkRect2D *ss = &cmd->u.set_scissor.scissors[i];
1681
state->scissors[idx].minx = ss->offset.x;
1682
state->scissors[idx].miny = ss->offset.y;
1683
state->scissors[idx].maxx = ss->offset.x + ss->extent.width;
1684
state->scissors[idx].maxy = ss->offset.y + ss->extent.height;
1685
}
1686
state->scissor_dirty = true;
1687
}
1688
1689
static void handle_set_line_width(struct lvp_cmd_buffer_entry *cmd,
1690
struct rendering_state *state)
1691
{
1692
state->rs_state.line_width = cmd->u.set_line_width.line_width;
1693
state->rs_dirty = true;
1694
}
1695
1696
static void handle_set_depth_bias(struct lvp_cmd_buffer_entry *cmd,
1697
struct rendering_state *state)
1698
{
1699
state->depth_bias.offset_units = cmd->u.set_depth_bias.constant_factor;
1700
state->depth_bias.offset_scale = cmd->u.set_depth_bias.slope_factor;
1701
state->depth_bias.offset_clamp = cmd->u.set_depth_bias.clamp;
1702
state->rs_dirty = true;
1703
}
1704
1705
static void handle_set_blend_constants(struct lvp_cmd_buffer_entry *cmd,
1706
struct rendering_state *state)
1707
{
1708
memcpy(state->blend_color.color, cmd->u.set_blend_constants.blend_constants, 4 * sizeof(float));
1709
state->blend_color_dirty = true;
1710
}
1711
1712
static void handle_set_depth_bounds(struct lvp_cmd_buffer_entry *cmd,
1713
struct rendering_state *state)
1714
{
1715
state->dsa_dirty |= !DOUBLE_EQ(state->dsa_state.depth_bounds_min, cmd->u.set_depth_bounds.min_depth);
1716
state->dsa_dirty |= !DOUBLE_EQ(state->dsa_state.depth_bounds_max, cmd->u.set_depth_bounds.max_depth);
1717
state->dsa_state.depth_bounds_min = cmd->u.set_depth_bounds.min_depth;
1718
state->dsa_state.depth_bounds_max = cmd->u.set_depth_bounds.max_depth;
1719
}
1720
1721
static void handle_set_stencil_compare_mask(struct lvp_cmd_buffer_entry *cmd,
1722
struct rendering_state *state)
1723
{
1724
if (cmd->u.stencil_vals.face_mask & VK_STENCIL_FACE_FRONT_BIT)
1725
state->dsa_state.stencil[0].valuemask = cmd->u.stencil_vals.value;
1726
if (cmd->u.stencil_vals.face_mask & VK_STENCIL_FACE_BACK_BIT)
1727
state->dsa_state.stencil[1].valuemask = cmd->u.stencil_vals.value;
1728
state->dsa_dirty = true;
1729
}
1730
1731
static void handle_set_stencil_write_mask(struct lvp_cmd_buffer_entry *cmd,
1732
struct rendering_state *state)
1733
{
1734
if (cmd->u.stencil_vals.face_mask & VK_STENCIL_FACE_FRONT_BIT)
1735
state->dsa_state.stencil[0].writemask = cmd->u.stencil_vals.value;
1736
if (cmd->u.stencil_vals.face_mask & VK_STENCIL_FACE_BACK_BIT)
1737
state->dsa_state.stencil[1].writemask = cmd->u.stencil_vals.value;
1738
state->dsa_dirty = true;
1739
}
1740
1741
static void handle_set_stencil_reference(struct lvp_cmd_buffer_entry *cmd,
1742
struct rendering_state *state)
1743
{
1744
if (cmd->u.stencil_vals.face_mask & VK_STENCIL_FACE_FRONT_BIT)
1745
state->stencil_ref.ref_value[0] = cmd->u.stencil_vals.value;
1746
if (cmd->u.stencil_vals.face_mask & VK_STENCIL_FACE_BACK_BIT)
1747
state->stencil_ref.ref_value[1] = cmd->u.stencil_vals.value;
1748
state->stencil_ref_dirty = true;
1749
}
1750
1751
static void
1752
copy_depth_rect(ubyte * dst,
1753
enum pipe_format dst_format,
1754
unsigned dst_stride,
1755
unsigned dst_x,
1756
unsigned dst_y,
1757
unsigned width,
1758
unsigned height,
1759
const ubyte * src,
1760
enum pipe_format src_format,
1761
int src_stride,
1762
unsigned src_x,
1763
unsigned src_y)
1764
{
1765
int src_stride_pos = src_stride < 0 ? -src_stride : src_stride;
1766
int src_blocksize = util_format_get_blocksize(src_format);
1767
int src_blockwidth = util_format_get_blockwidth(src_format);
1768
int src_blockheight = util_format_get_blockheight(src_format);
1769
int dst_blocksize = util_format_get_blocksize(dst_format);
1770
int dst_blockwidth = util_format_get_blockwidth(dst_format);
1771
int dst_blockheight = util_format_get_blockheight(dst_format);
1772
1773
assert(src_blocksize > 0);
1774
assert(src_blockwidth > 0);
1775
assert(src_blockheight > 0);
1776
1777
dst_x /= dst_blockwidth;
1778
dst_y /= dst_blockheight;
1779
width = (width + src_blockwidth - 1)/src_blockwidth;
1780
height = (height + src_blockheight - 1)/src_blockheight;
1781
src_x /= src_blockwidth;
1782
src_y /= src_blockheight;
1783
1784
dst += dst_x * dst_blocksize;
1785
src += src_x * src_blocksize;
1786
dst += dst_y * dst_stride;
1787
src += src_y * src_stride_pos;
1788
1789
if (dst_format == PIPE_FORMAT_S8_UINT) {
1790
if (src_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
1791
util_format_z32_float_s8x24_uint_unpack_s_8uint(dst, dst_stride,
1792
src, src_stride,
1793
width, height);
1794
} else if (src_format == PIPE_FORMAT_Z24_UNORM_S8_UINT) {
1795
util_format_z24_unorm_s8_uint_unpack_s_8uint(dst, dst_stride,
1796
src, src_stride,
1797
width, height);
1798
} else {
1799
}
1800
} else if (dst_format == PIPE_FORMAT_Z24X8_UNORM) {
1801
util_format_z24_unorm_s8_uint_unpack_z24(dst, dst_stride,
1802
src, src_stride,
1803
width, height);
1804
} else if (dst_format == PIPE_FORMAT_Z32_FLOAT) {
1805
if (src_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
1806
util_format_z32_float_s8x24_uint_unpack_z_float((float *)dst, dst_stride,
1807
src, src_stride,
1808
width, height);
1809
}
1810
} else if (dst_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {
1811
if (src_format == PIPE_FORMAT_Z32_FLOAT)
1812
util_format_z32_float_s8x24_uint_pack_z_float(dst, dst_stride,
1813
(float *)src, src_stride,
1814
width, height);
1815
else if (src_format == PIPE_FORMAT_S8_UINT)
1816
util_format_z32_float_s8x24_uint_pack_s_8uint(dst, dst_stride,
1817
src, src_stride,
1818
width, height);
1819
} else if (dst_format == PIPE_FORMAT_Z24_UNORM_S8_UINT) {
1820
if (src_format == PIPE_FORMAT_S8_UINT)
1821
util_format_z24_unorm_s8_uint_pack_s_8uint(dst, dst_stride,
1822
src, src_stride,
1823
width, height);
1824
if (src_format == PIPE_FORMAT_Z24X8_UNORM)
1825
util_format_z24_unorm_s8_uint_pack_z24(dst, dst_stride,
1826
src, src_stride,
1827
width, height);
1828
}
1829
}
1830
1831
static void
1832
copy_depth_box(ubyte *dst,
1833
enum pipe_format dst_format,
1834
unsigned dst_stride, unsigned dst_slice_stride,
1835
unsigned dst_x, unsigned dst_y, unsigned dst_z,
1836
unsigned width, unsigned height, unsigned depth,
1837
const ubyte * src,
1838
enum pipe_format src_format,
1839
int src_stride, unsigned src_slice_stride,
1840
unsigned src_x, unsigned src_y, unsigned src_z)
1841
{
1842
unsigned z;
1843
dst += dst_z * dst_slice_stride;
1844
src += src_z * src_slice_stride;
1845
for (z = 0; z < depth; ++z) {
1846
copy_depth_rect(dst,
1847
dst_format,
1848
dst_stride,
1849
dst_x, dst_y,
1850
width, height,
1851
src,
1852
src_format,
1853
src_stride,
1854
src_x, src_y);
1855
1856
dst += dst_slice_stride;
1857
src += src_slice_stride;
1858
}
1859
}
1860
1861
static void handle_copy_image_to_buffer(struct lvp_cmd_buffer_entry *cmd,
1862
struct rendering_state *state)
1863
{
1864
int i;
1865
struct lvp_cmd_copy_image_to_buffer *copycmd = &cmd->u.img_to_buffer;
1866
struct pipe_box box, dbox;
1867
struct pipe_transfer *src_t, *dst_t;
1868
ubyte *src_data, *dst_data;
1869
1870
state->pctx->flush(state->pctx, NULL, 0);
1871
1872
for (i = 0; i < copycmd->region_count; i++) {
1873
1874
box.x = copycmd->regions[i].imageOffset.x;
1875
box.y = copycmd->regions[i].imageOffset.y;
1876
box.z = copycmd->src->type == VK_IMAGE_TYPE_3D ? copycmd->regions[i].imageOffset.z : copycmd->regions[i].imageSubresource.baseArrayLayer;
1877
box.width = copycmd->regions[i].imageExtent.width;
1878
box.height = copycmd->regions[i].imageExtent.height;
1879
box.depth = copycmd->src->type == VK_IMAGE_TYPE_3D ? copycmd->regions[i].imageExtent.depth : copycmd->regions[i].imageSubresource.layerCount;
1880
1881
src_data = state->pctx->texture_map(state->pctx,
1882
copycmd->src->bo,
1883
copycmd->regions[i].imageSubresource.mipLevel,
1884
PIPE_MAP_READ,
1885
&box,
1886
&src_t);
1887
1888
dbox.x = copycmd->regions[i].bufferOffset;
1889
dbox.y = 0;
1890
dbox.z = 0;
1891
dbox.width = copycmd->dst->bo->width0;
1892
dbox.height = 1;
1893
dbox.depth = 1;
1894
dst_data = state->pctx->buffer_map(state->pctx,
1895
copycmd->dst->bo,
1896
0,
1897
PIPE_MAP_WRITE,
1898
&dbox,
1899
&dst_t);
1900
1901
enum pipe_format src_format = copycmd->src->bo->format;
1902
enum pipe_format dst_format = src_format;
1903
if (util_format_is_depth_or_stencil(src_format)) {
1904
if (copycmd->regions[i].imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) {
1905
dst_format = util_format_get_depth_only(src_format);
1906
} else if (copycmd->regions[i].imageSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {
1907
dst_format = PIPE_FORMAT_S8_UINT;
1908
}
1909
}
1910
1911
unsigned buffer_row_len = util_format_get_stride(dst_format, copycmd->regions[i].bufferRowLength);
1912
if (buffer_row_len == 0)
1913
buffer_row_len = util_format_get_stride(dst_format, copycmd->regions[i].imageExtent.width);
1914
unsigned buffer_image_height = copycmd->regions[i].bufferImageHeight;
1915
if (buffer_image_height == 0)
1916
buffer_image_height = copycmd->regions[i].imageExtent.height;
1917
1918
unsigned img_stride = util_format_get_2d_size(dst_format, buffer_row_len, buffer_image_height);
1919
if (src_format != dst_format) {
1920
copy_depth_box(dst_data, dst_format,
1921
buffer_row_len, img_stride,
1922
0, 0, 0,
1923
copycmd->regions[i].imageExtent.width,
1924
copycmd->regions[i].imageExtent.height,
1925
box.depth,
1926
src_data, src_format, src_t->stride, src_t->layer_stride, 0, 0, 0);
1927
} else {
1928
util_copy_box((ubyte *)dst_data, src_format,
1929
buffer_row_len, img_stride,
1930
0, 0, 0,
1931
copycmd->regions[i].imageExtent.width,
1932
copycmd->regions[i].imageExtent.height,
1933
box.depth,
1934
src_data, src_t->stride, src_t->layer_stride, 0, 0, 0);
1935
}
1936
state->pctx->texture_unmap(state->pctx, src_t);
1937
state->pctx->buffer_unmap(state->pctx, dst_t);
1938
}
1939
}
1940
1941
static void handle_copy_buffer_to_image(struct lvp_cmd_buffer_entry *cmd,
1942
struct rendering_state *state)
1943
{
1944
int i;
1945
struct lvp_cmd_copy_buffer_to_image *copycmd = &cmd->u.buffer_to_img;
1946
struct pipe_box box, sbox;
1947
struct pipe_transfer *src_t, *dst_t;
1948
void *src_data, *dst_data;
1949
1950
state->pctx->flush(state->pctx, NULL, 0);
1951
1952
for (i = 0; i < copycmd->region_count; i++) {
1953
1954
sbox.x = copycmd->regions[i].bufferOffset;
1955
sbox.y = 0;
1956
sbox.z = 0;
1957
sbox.width = copycmd->src->bo->width0;
1958
sbox.height = 1;
1959
sbox.depth = 1;
1960
src_data = state->pctx->buffer_map(state->pctx,
1961
copycmd->src->bo,
1962
0,
1963
PIPE_MAP_READ,
1964
&sbox,
1965
&src_t);
1966
1967
1968
box.x = copycmd->regions[i].imageOffset.x;
1969
box.y = copycmd->regions[i].imageOffset.y;
1970
box.z = copycmd->dst->type == VK_IMAGE_TYPE_3D ? copycmd->regions[i].imageOffset.z : copycmd->regions[i].imageSubresource.baseArrayLayer;
1971
box.width = copycmd->regions[i].imageExtent.width;
1972
box.height = copycmd->regions[i].imageExtent.height;
1973
box.depth = copycmd->dst->type == VK_IMAGE_TYPE_3D ? copycmd->regions[i].imageExtent.depth : copycmd->regions[i].imageSubresource.layerCount;
1974
1975
dst_data = state->pctx->texture_map(state->pctx,
1976
copycmd->dst->bo,
1977
copycmd->regions[i].imageSubresource.mipLevel,
1978
PIPE_MAP_WRITE,
1979
&box,
1980
&dst_t);
1981
1982
enum pipe_format dst_format = copycmd->dst->bo->format;
1983
enum pipe_format src_format = dst_format;
1984
if (util_format_is_depth_or_stencil(dst_format)) {
1985
if (copycmd->regions[i].imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) {
1986
src_format = util_format_get_depth_only(copycmd->dst->bo->format);
1987
} else if (copycmd->regions[i].imageSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {
1988
src_format = PIPE_FORMAT_S8_UINT;
1989
}
1990
}
1991
1992
unsigned buffer_row_len = util_format_get_stride(src_format, copycmd->regions[i].bufferRowLength);
1993
if (buffer_row_len == 0)
1994
buffer_row_len = util_format_get_stride(src_format, copycmd->regions[i].imageExtent.width);
1995
unsigned buffer_image_height = copycmd->regions[i].bufferImageHeight;
1996
if (buffer_image_height == 0)
1997
buffer_image_height = copycmd->regions[i].imageExtent.height;
1998
1999
unsigned img_stride = util_format_get_2d_size(src_format, buffer_row_len, buffer_image_height);
2000
if (src_format != dst_format) {
2001
copy_depth_box(dst_data, dst_format,
2002
dst_t->stride, dst_t->layer_stride,
2003
0, 0, 0,
2004
copycmd->regions[i].imageExtent.width,
2005
copycmd->regions[i].imageExtent.height,
2006
box.depth,
2007
src_data, src_format,
2008
buffer_row_len, img_stride, 0, 0, 0);
2009
} else {
2010
util_copy_box(dst_data, dst_format,
2011
dst_t->stride, dst_t->layer_stride,
2012
0, 0, 0,
2013
copycmd->regions[i].imageExtent.width,
2014
copycmd->regions[i].imageExtent.height,
2015
box.depth,
2016
src_data,
2017
buffer_row_len, img_stride, 0, 0, 0);
2018
}
2019
state->pctx->buffer_unmap(state->pctx, src_t);
2020
state->pctx->texture_unmap(state->pctx, dst_t);
2021
}
2022
}
2023
2024
static void handle_copy_image(struct lvp_cmd_buffer_entry *cmd,
2025
struct rendering_state *state)
2026
{
2027
int i;
2028
struct lvp_cmd_copy_image *copycmd = &cmd->u.copy_image;
2029
2030
state->pctx->flush(state->pctx, NULL, 0);
2031
2032
for (i = 0; i < copycmd->region_count; i++) {
2033
struct pipe_box src_box;
2034
src_box.x = copycmd->regions[i].srcOffset.x;
2035
src_box.y = copycmd->regions[i].srcOffset.y;
2036
src_box.width = copycmd->regions[i].extent.width;
2037
src_box.height = copycmd->regions[i].extent.height;
2038
if (copycmd->src->bo->target == PIPE_TEXTURE_3D) {
2039
src_box.depth = copycmd->regions[i].extent.depth;
2040
src_box.z = copycmd->regions[i].srcOffset.z;
2041
} else {
2042
src_box.depth = copycmd->regions[i].srcSubresource.layerCount;
2043
src_box.z = copycmd->regions[i].srcSubresource.baseArrayLayer;
2044
}
2045
2046
unsigned dstz = copycmd->dst->bo->target == PIPE_TEXTURE_3D ?
2047
copycmd->regions[i].dstOffset.z :
2048
copycmd->regions[i].dstSubresource.baseArrayLayer;
2049
state->pctx->resource_copy_region(state->pctx, copycmd->dst->bo,
2050
copycmd->regions[i].dstSubresource.mipLevel,
2051
copycmd->regions[i].dstOffset.x,
2052
copycmd->regions[i].dstOffset.y,
2053
dstz,
2054
copycmd->src->bo,
2055
copycmd->regions[i].srcSubresource.mipLevel,
2056
&src_box);
2057
}
2058
}
2059
2060
static void handle_copy_buffer(struct lvp_cmd_buffer_entry *cmd,
2061
struct rendering_state *state)
2062
{
2063
int i;
2064
struct lvp_cmd_copy_buffer *copycmd = &cmd->u.copy_buffer;
2065
2066
for (i = 0; i < copycmd->region_count; i++) {
2067
struct pipe_box box = { 0 };
2068
u_box_1d(copycmd->regions[i].srcOffset, copycmd->regions[i].size, &box);
2069
state->pctx->resource_copy_region(state->pctx, copycmd->dst->bo, 0,
2070
copycmd->regions[i].dstOffset, 0, 0,
2071
copycmd->src->bo, 0, &box);
2072
}
2073
}
2074
2075
static void handle_blit_image(struct lvp_cmd_buffer_entry *cmd,
2076
struct rendering_state *state)
2077
{
2078
int i;
2079
struct lvp_cmd_blit_image *blitcmd = &cmd->u.blit_image;
2080
struct pipe_blit_info info;
2081
2082
memset(&info, 0, sizeof(info));
2083
2084
state->pctx->flush(state->pctx, NULL, 0);
2085
info.src.resource = blitcmd->src->bo;
2086
info.dst.resource = blitcmd->dst->bo;
2087
info.src.format = blitcmd->src->bo->format;
2088
info.dst.format = blitcmd->dst->bo->format;
2089
info.mask = util_format_is_depth_or_stencil(info.src.format) ? PIPE_MASK_ZS : PIPE_MASK_RGBA;
2090
info.filter = blitcmd->filter == VK_FILTER_NEAREST ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR;
2091
for (i = 0; i < blitcmd->region_count; i++) {
2092
int srcX0, srcX1, srcY0, srcY1, srcZ0, srcZ1;
2093
unsigned dstX0, dstX1, dstY0, dstY1, dstZ0, dstZ1;
2094
2095
srcX0 = blitcmd->regions[i].srcOffsets[0].x;
2096
srcX1 = blitcmd->regions[i].srcOffsets[1].x;
2097
srcY0 = blitcmd->regions[i].srcOffsets[0].y;
2098
srcY1 = blitcmd->regions[i].srcOffsets[1].y;
2099
srcZ0 = blitcmd->regions[i].srcOffsets[0].z;
2100
srcZ1 = blitcmd->regions[i].srcOffsets[1].z;
2101
2102
dstX0 = blitcmd->regions[i].dstOffsets[0].x;
2103
dstX1 = blitcmd->regions[i].dstOffsets[1].x;
2104
dstY0 = blitcmd->regions[i].dstOffsets[0].y;
2105
dstY1 = blitcmd->regions[i].dstOffsets[1].y;
2106
dstZ0 = blitcmd->regions[i].dstOffsets[0].z;
2107
dstZ1 = blitcmd->regions[i].dstOffsets[1].z;
2108
2109
if (dstX0 < dstX1) {
2110
info.dst.box.x = dstX0;
2111
info.src.box.x = srcX0;
2112
info.dst.box.width = dstX1 - dstX0;
2113
info.src.box.width = srcX1 - srcX0;
2114
} else {
2115
info.dst.box.x = dstX1;
2116
info.src.box.x = srcX1;
2117
info.dst.box.width = dstX0 - dstX1;
2118
info.src.box.width = srcX0 - srcX1;
2119
}
2120
2121
if (dstY0 < dstY1) {
2122
info.dst.box.y = dstY0;
2123
info.src.box.y = srcY0;
2124
info.dst.box.height = dstY1 - dstY0;
2125
info.src.box.height = srcY1 - srcY0;
2126
} else {
2127
info.dst.box.y = dstY1;
2128
info.src.box.y = srcY1;
2129
info.dst.box.height = dstY0 - dstY1;
2130
info.src.box.height = srcY0 - srcY1;
2131
}
2132
2133
assert_subresource_layers(info.src.resource, &blitcmd->regions[i].srcSubresource, blitcmd->regions[i].srcOffsets);
2134
assert_subresource_layers(info.dst.resource, &blitcmd->regions[i].dstSubresource, blitcmd->regions[i].dstOffsets);
2135
if (blitcmd->src->bo->target == PIPE_TEXTURE_3D) {
2136
if (dstZ0 < dstZ1) {
2137
info.dst.box.z = dstZ0;
2138
info.src.box.z = srcZ0;
2139
info.dst.box.depth = dstZ1 - dstZ0;
2140
info.src.box.depth = srcZ1 - srcZ0;
2141
} else {
2142
info.dst.box.z = dstZ1;
2143
info.src.box.z = srcZ1;
2144
info.dst.box.depth = dstZ0 - dstZ1;
2145
info.src.box.depth = srcZ0 - srcZ1;
2146
}
2147
} else {
2148
info.src.box.z = blitcmd->regions[i].srcSubresource.baseArrayLayer;
2149
info.dst.box.z = blitcmd->regions[i].dstSubresource.baseArrayLayer;
2150
info.src.box.depth = blitcmd->regions[i].srcSubresource.layerCount;
2151
info.dst.box.depth = blitcmd->regions[i].dstSubresource.layerCount;
2152
}
2153
2154
info.src.level = blitcmd->regions[i].srcSubresource.mipLevel;
2155
info.dst.level = blitcmd->regions[i].dstSubresource.mipLevel;
2156
state->pctx->blit(state->pctx, &info);
2157
}
2158
}
2159
2160
static void handle_fill_buffer(struct lvp_cmd_buffer_entry *cmd,
2161
struct rendering_state *state)
2162
{
2163
struct lvp_cmd_fill_buffer *fillcmd = &cmd->u.fill_buffer;
2164
uint32_t size = fillcmd->fill_size;
2165
2166
if (fillcmd->fill_size == VK_WHOLE_SIZE) {
2167
size = fillcmd->buffer->bo->width0 - fillcmd->offset;
2168
size = ROUND_DOWN_TO(size, 4);
2169
}
2170
2171
state->pctx->clear_buffer(state->pctx,
2172
fillcmd->buffer->bo,
2173
fillcmd->offset,
2174
size,
2175
&fillcmd->data,
2176
4);
2177
}
2178
2179
static void handle_update_buffer(struct lvp_cmd_buffer_entry *cmd,
2180
struct rendering_state *state)
2181
{
2182
struct lvp_cmd_update_buffer *updcmd = &cmd->u.update_buffer;
2183
uint32_t *dst;
2184
struct pipe_transfer *dst_t;
2185
struct pipe_box box;
2186
2187
u_box_1d(updcmd->offset, updcmd->data_size, &box);
2188
dst = state->pctx->buffer_map(state->pctx,
2189
updcmd->buffer->bo,
2190
0,
2191
PIPE_MAP_WRITE,
2192
&box,
2193
&dst_t);
2194
2195
memcpy(dst, updcmd->data, updcmd->data_size);
2196
state->pctx->buffer_unmap(state->pctx, dst_t);
2197
}
2198
2199
static void handle_draw_indexed(struct lvp_cmd_buffer_entry *cmd,
2200
struct rendering_state *state)
2201
{
2202
const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
2203
state->info.index_bounds_valid = false;
2204
state->info.min_index = 0;
2205
state->info.max_index = ~0;
2206
state->info.index_size = state->index_size;
2207
state->info.index.resource = state->index_buffer;
2208
state->info.start_instance = cmd->u.draw_indexed.first_instance;
2209
state->info.instance_count = cmd->u.draw_indexed.instance_count;
2210
state->info.view_mask = subpass->view_mask;
2211
state->info.increment_draw_id = true;
2212
2213
if (state->info.primitive_restart)
2214
state->info.restart_index = util_prim_restart_index_from_size(state->info.index_size);
2215
/* avoid calculating multiple times if cmdbuf is submitted again */
2216
if (cmd->u.draw_indexed.calc_start) {
2217
for (unsigned i = 0; i < cmd->u.draw_indexed.draw_count; i++)
2218
cmd->u.draw_indexed.draws[i].start = (state->index_offset / state->index_size) + cmd->u.draw_indexed.draws[i].start;
2219
cmd->u.draw_indexed.calc_start = false;
2220
}
2221
state->info.index_bias_varies = cmd->u.draw_indexed.vertex_offset_changes;
2222
state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, cmd->u.draw_indexed.draws, cmd->u.draw_indexed.draw_count);
2223
}
2224
2225
static void handle_draw_indirect(struct lvp_cmd_buffer_entry *cmd,
2226
struct rendering_state *state, bool indexed)
2227
{
2228
const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
2229
struct pipe_draw_start_count_bias draw = {0};
2230
if (indexed) {
2231
state->info.index_bounds_valid = false;
2232
state->info.index_size = state->index_size;
2233
state->info.index.resource = state->index_buffer;
2234
state->info.max_index = ~0;
2235
} else
2236
state->info.index_size = 0;
2237
state->indirect_info.offset = cmd->u.draw_indirect.offset;
2238
state->indirect_info.stride = cmd->u.draw_indirect.stride;
2239
state->indirect_info.draw_count = cmd->u.draw_indirect.draw_count;
2240
state->indirect_info.buffer = cmd->u.draw_indirect.buffer->bo;
2241
state->info.view_mask = subpass->view_mask;
2242
2243
state->pctx->draw_vbo(state->pctx, &state->info, 0, &state->indirect_info, &draw, 1);
2244
}
2245
2246
static void handle_index_buffer(struct lvp_cmd_buffer_entry *cmd,
2247
struct rendering_state *state)
2248
{
2249
struct lvp_cmd_bind_index_buffer *ib = &cmd->u.index_buffer;
2250
switch (ib->index_type) {
2251
case VK_INDEX_TYPE_UINT8_EXT:
2252
state->index_size = 1;
2253
break;
2254
case VK_INDEX_TYPE_UINT16:
2255
state->index_size = 2;
2256
break;
2257
case VK_INDEX_TYPE_UINT32:
2258
state->index_size = 4;
2259
break;
2260
default:
2261
break;
2262
}
2263
state->index_offset = ib->offset;
2264
if (ib->buffer)
2265
state->index_buffer = ib->buffer->bo;
2266
else
2267
state->index_buffer = NULL;
2268
2269
state->ib_dirty = true;
2270
}
2271
2272
static void handle_dispatch(struct lvp_cmd_buffer_entry *cmd,
2273
struct rendering_state *state)
2274
{
2275
state->dispatch_info.grid[0] = cmd->u.dispatch.x;
2276
state->dispatch_info.grid[1] = cmd->u.dispatch.y;
2277
state->dispatch_info.grid[2] = cmd->u.dispatch.z;
2278
state->dispatch_info.grid_base[0] = cmd->u.dispatch.base_x;
2279
state->dispatch_info.grid_base[1] = cmd->u.dispatch.base_y;
2280
state->dispatch_info.grid_base[2] = cmd->u.dispatch.base_z;
2281
state->dispatch_info.indirect = NULL;
2282
state->pctx->launch_grid(state->pctx, &state->dispatch_info);
2283
}
2284
2285
static void handle_dispatch_indirect(struct lvp_cmd_buffer_entry *cmd,
2286
struct rendering_state *state)
2287
{
2288
state->dispatch_info.indirect = cmd->u.dispatch_indirect.buffer->bo;
2289
state->dispatch_info.indirect_offset = cmd->u.dispatch_indirect.offset;
2290
state->pctx->launch_grid(state->pctx, &state->dispatch_info);
2291
}
2292
2293
static void handle_push_constants(struct lvp_cmd_buffer_entry *cmd,
2294
struct rendering_state *state)
2295
{
2296
memcpy(state->push_constants + cmd->u.push_constants.offset, cmd->u.push_constants.val, cmd->u.push_constants.size);
2297
2298
state->pc_buffer[PIPE_SHADER_VERTEX].buffer_size = 128 * 4;
2299
state->pc_buffer[PIPE_SHADER_VERTEX].buffer_offset = 0;
2300
state->pc_buffer[PIPE_SHADER_VERTEX].user_buffer = state->push_constants;
2301
state->pcbuf_dirty[PIPE_SHADER_VERTEX] = true;
2302
state->pc_buffer[PIPE_SHADER_FRAGMENT].buffer_size = 128 * 4;
2303
state->pc_buffer[PIPE_SHADER_FRAGMENT].buffer_offset = 0;
2304
state->pc_buffer[PIPE_SHADER_FRAGMENT].user_buffer = state->push_constants;
2305
state->pcbuf_dirty[PIPE_SHADER_FRAGMENT] = true;
2306
state->pc_buffer[PIPE_SHADER_GEOMETRY].buffer_size = 128 * 4;
2307
state->pc_buffer[PIPE_SHADER_GEOMETRY].buffer_offset = 0;
2308
state->pc_buffer[PIPE_SHADER_GEOMETRY].user_buffer = state->push_constants;
2309
state->pcbuf_dirty[PIPE_SHADER_GEOMETRY] = true;
2310
state->pc_buffer[PIPE_SHADER_TESS_CTRL].buffer_size = 128 * 4;
2311
state->pc_buffer[PIPE_SHADER_TESS_CTRL].buffer_offset = 0;
2312
state->pc_buffer[PIPE_SHADER_TESS_CTRL].user_buffer = state->push_constants;
2313
state->pcbuf_dirty[PIPE_SHADER_TESS_CTRL] = true;
2314
state->pc_buffer[PIPE_SHADER_TESS_EVAL].buffer_size = 128 * 4;
2315
state->pc_buffer[PIPE_SHADER_TESS_EVAL].buffer_offset = 0;
2316
state->pc_buffer[PIPE_SHADER_TESS_EVAL].user_buffer = state->push_constants;
2317
state->pcbuf_dirty[PIPE_SHADER_TESS_EVAL] = true;
2318
state->pc_buffer[PIPE_SHADER_COMPUTE].buffer_size = 128 * 4;
2319
state->pc_buffer[PIPE_SHADER_COMPUTE].buffer_offset = 0;
2320
state->pc_buffer[PIPE_SHADER_COMPUTE].user_buffer = state->push_constants;
2321
state->pcbuf_dirty[PIPE_SHADER_COMPUTE] = true;
2322
}
2323
2324
static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer,
2325
struct rendering_state *state);
2326
2327
static void handle_execute_commands(struct lvp_cmd_buffer_entry *cmd,
2328
struct rendering_state *state)
2329
{
2330
for (unsigned i = 0; i < cmd->u.execute_commands.command_buffer_count; i++) {
2331
struct lvp_cmd_buffer *secondary_buf = cmd->u.execute_commands.cmd_buffers[i];
2332
lvp_execute_cmd_buffer(secondary_buf, state);
2333
}
2334
}
2335
2336
static void handle_event_set(struct lvp_cmd_buffer_entry *cmd,
2337
struct rendering_state *state)
2338
{
2339
struct lvp_event *event = cmd->u.event_set.event;
2340
2341
if (cmd->u.event_set.flush)
2342
state->pctx->flush(state->pctx, NULL, 0);
2343
event->event_storage = (cmd->u.event_set.value == true) ? 1 : 0;
2344
}
2345
2346
static void handle_wait_events(struct lvp_cmd_buffer_entry *cmd,
2347
struct rendering_state *state)
2348
{
2349
for (unsigned i = 0; i < cmd->u.wait_events.event_count; i++) {
2350
struct lvp_event *event = cmd->u.wait_events.events[i];
2351
2352
while (event->event_storage != true);
2353
}
2354
}
2355
2356
static void handle_pipeline_barrier(struct lvp_cmd_buffer_entry *cmd,
2357
struct rendering_state *state)
2358
{
2359
/* why hello nail, I'm a hammer. - TODO */
2360
state->pctx->flush(state->pctx, NULL, 0);
2361
}
2362
2363
static void maybe_emit_state_for_begin_query(struct lvp_cmd_buffer_entry *cmd,
2364
struct rendering_state *state)
2365
{
2366
struct lvp_cmd_query_cmd *qcmd = &cmd->u.query;
2367
struct lvp_query_pool *pool = qcmd->pool;
2368
2369
if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS &&
2370
pool->pipeline_stats & VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT)
2371
emit_compute_state(state);
2372
emit_state(state);
2373
}
2374
2375
static void handle_begin_query(struct lvp_cmd_buffer_entry *cmd,
2376
struct rendering_state *state)
2377
{
2378
struct lvp_cmd_query_cmd *qcmd = &cmd->u.query;
2379
struct lvp_query_pool *pool = qcmd->pool;
2380
2381
if (!pool->queries[qcmd->query]) {
2382
enum pipe_query_type qtype = pool->base_type;
2383
if (qtype == PIPE_QUERY_OCCLUSION_COUNTER && !qcmd->precise)
2384
qtype = PIPE_QUERY_OCCLUSION_PREDICATE;
2385
pool->queries[qcmd->query] = state->pctx->create_query(state->pctx,
2386
qtype, qcmd->index);
2387
}
2388
2389
state->pctx->begin_query(state->pctx, pool->queries[qcmd->query]);
2390
}
2391
2392
static void handle_end_query(struct lvp_cmd_buffer_entry *cmd,
2393
struct rendering_state *state)
2394
{
2395
struct lvp_cmd_query_cmd *qcmd = &cmd->u.query;
2396
struct lvp_query_pool *pool = qcmd->pool;
2397
assert(pool->queries[qcmd->query]);
2398
2399
state->pctx->end_query(state->pctx, pool->queries[qcmd->query]);
2400
}
2401
2402
static void handle_reset_query_pool(struct lvp_cmd_buffer_entry *cmd,
2403
struct rendering_state *state)
2404
{
2405
struct lvp_cmd_query_cmd *qcmd = &cmd->u.query;
2406
struct lvp_query_pool *pool = qcmd->pool;
2407
for (unsigned i = qcmd->query; i < qcmd->query + qcmd->index; i++) {
2408
if (pool->queries[i]) {
2409
state->pctx->destroy_query(state->pctx, pool->queries[i]);
2410
pool->queries[i] = NULL;
2411
}
2412
}
2413
}
2414
2415
static void handle_write_timestamp(struct lvp_cmd_buffer_entry *cmd,
2416
struct rendering_state *state)
2417
{
2418
struct lvp_cmd_query_cmd *qcmd = &cmd->u.query;
2419
struct lvp_query_pool *pool = qcmd->pool;
2420
if (!pool->queries[qcmd->query]) {
2421
pool->queries[qcmd->query] = state->pctx->create_query(state->pctx,
2422
PIPE_QUERY_TIMESTAMP, 0);
2423
}
2424
2425
if (qcmd->flush)
2426
state->pctx->flush(state->pctx, NULL, 0);
2427
state->pctx->end_query(state->pctx, pool->queries[qcmd->query]);
2428
2429
}
2430
2431
static void handle_copy_query_pool_results(struct lvp_cmd_buffer_entry *cmd,
2432
struct rendering_state *state)
2433
{
2434
struct lvp_cmd_copy_query_pool_results *copycmd = &cmd->u.copy_query_pool_results;
2435
struct lvp_query_pool *pool = copycmd->pool;
2436
2437
for (unsigned i = copycmd->first_query; i < copycmd->first_query + copycmd->query_count; i++) {
2438
unsigned offset = copycmd->dst_offset + copycmd->dst->offset + (copycmd->stride * (i - copycmd->first_query));
2439
if (pool->queries[i]) {
2440
if (copycmd->flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)
2441
state->pctx->get_query_result_resource(state->pctx,
2442
pool->queries[i],
2443
copycmd->flags & VK_QUERY_RESULT_WAIT_BIT,
2444
copycmd->flags & VK_QUERY_RESULT_64_BIT ? PIPE_QUERY_TYPE_U64 : PIPE_QUERY_TYPE_U32,
2445
-1,
2446
copycmd->dst->bo,
2447
offset + (copycmd->flags & VK_QUERY_RESULT_64_BIT ? 8 : 4));
2448
if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS) {
2449
unsigned num_results = 0;
2450
unsigned result_size = copycmd->flags & VK_QUERY_RESULT_64_BIT ? 8 : 4;
2451
u_foreach_bit(bit, pool->pipeline_stats)
2452
state->pctx->get_query_result_resource(state->pctx,
2453
pool->queries[i],
2454
copycmd->flags & VK_QUERY_RESULT_WAIT_BIT,
2455
copycmd->flags & VK_QUERY_RESULT_64_BIT ? PIPE_QUERY_TYPE_U64 : PIPE_QUERY_TYPE_U32,
2456
bit,
2457
copycmd->dst->bo,
2458
offset + num_results++ * result_size);
2459
} else {
2460
state->pctx->get_query_result_resource(state->pctx,
2461
pool->queries[i],
2462
copycmd->flags & VK_QUERY_RESULT_WAIT_BIT,
2463
copycmd->flags & VK_QUERY_RESULT_64_BIT ? PIPE_QUERY_TYPE_U64 : PIPE_QUERY_TYPE_U32,
2464
0,
2465
copycmd->dst->bo,
2466
offset);
2467
}
2468
} else {
2469
/* if no queries emitted yet, just reset the buffer to 0 so avail is reported correctly */
2470
if (copycmd->flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) {
2471
struct pipe_transfer *src_t;
2472
uint32_t *map;
2473
2474
struct pipe_box box = {0};
2475
box.x = offset;
2476
box.width = copycmd->stride;
2477
box.height = 1;
2478
box.depth = 1;
2479
map = state->pctx->buffer_map(state->pctx,
2480
copycmd->dst->bo, 0, PIPE_MAP_READ, &box,
2481
&src_t);
2482
2483
memset(map, 0, box.width);
2484
state->pctx->buffer_unmap(state->pctx, src_t);
2485
}
2486
}
2487
}
2488
}
2489
2490
static void pack_clear_color(enum pipe_format pformat, VkClearColorValue *in_val, uint32_t col_val[4])
2491
{
2492
const struct util_format_description *desc = util_format_description(pformat);
2493
col_val[0] = col_val[1] = col_val[2] = col_val[3] = 0;
2494
for (unsigned c = 0; c < 4; c++) {
2495
if (desc->swizzle[c] >= 4)
2496
continue;
2497
const struct util_format_channel_description *channel = &desc->channel[desc->swizzle[c]];
2498
if (channel->size == 32) {
2499
col_val[c] = in_val->uint32[c];
2500
continue;
2501
}
2502
if (channel->pure_integer) {
2503
uint64_t v = in_val->uint32[c] & ((1u << channel->size) - 1);
2504
switch (channel->size) {
2505
case 2:
2506
case 8:
2507
case 10:
2508
col_val[0] |= (v << channel->shift);
2509
break;
2510
case 16:
2511
col_val[c / 2] |= (v << (16 * (c % 2)));
2512
break;
2513
}
2514
} else {
2515
util_pack_color(in_val->float32, pformat, (union util_color *)col_val);
2516
break;
2517
}
2518
}
2519
}
2520
2521
static void handle_clear_color_image(struct lvp_cmd_buffer_entry *cmd,
2522
struct rendering_state *state)
2523
{
2524
struct lvp_image *image = cmd->u.clear_color_image.image;
2525
uint32_t col_val[4];
2526
pack_clear_color(image->bo->format, &cmd->u.clear_color_image.clear_val, col_val);
2527
for (unsigned i = 0; i < cmd->u.clear_color_image.range_count; i++) {
2528
VkImageSubresourceRange *range = &cmd->u.clear_color_image.ranges[i];
2529
struct pipe_box box;
2530
box.x = 0;
2531
box.y = 0;
2532
box.z = 0;
2533
2534
uint32_t level_count = lvp_get_levelCount(image, range);
2535
for (unsigned j = range->baseMipLevel; j < range->baseMipLevel + level_count; j++) {
2536
box.width = u_minify(image->bo->width0, j);
2537
box.height = u_minify(image->bo->height0, j);
2538
box.depth = 1;
2539
if (image->bo->target == PIPE_TEXTURE_3D)
2540
box.depth = u_minify(image->bo->depth0, j);
2541
else if (image->bo->target == PIPE_TEXTURE_1D_ARRAY) {
2542
box.y = range->baseArrayLayer;
2543
box.height = lvp_get_layerCount(image, range);
2544
box.depth = 1;
2545
} else {
2546
box.z = range->baseArrayLayer;
2547
box.depth = lvp_get_layerCount(image, range);
2548
}
2549
2550
state->pctx->clear_texture(state->pctx, image->bo,
2551
j, &box, (void *)col_val);
2552
}
2553
}
2554
}
2555
2556
static void handle_clear_ds_image(struct lvp_cmd_buffer_entry *cmd,
2557
struct rendering_state *state)
2558
{
2559
struct lvp_image *image = cmd->u.clear_ds_image.image;
2560
for (unsigned i = 0; i < cmd->u.clear_ds_image.range_count; i++) {
2561
VkImageSubresourceRange *range = &cmd->u.clear_ds_image.ranges[i];
2562
uint32_t ds_clear_flags = 0;
2563
if (range->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)
2564
ds_clear_flags |= PIPE_CLEAR_DEPTH;
2565
if (range->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)
2566
ds_clear_flags |= PIPE_CLEAR_STENCIL;
2567
2568
uint32_t level_count = lvp_get_levelCount(image, range);
2569
for (unsigned j = 0; j < level_count; j++) {
2570
struct pipe_surface *surf;
2571
unsigned width, height;
2572
2573
width = u_minify(image->bo->width0, range->baseMipLevel + j);
2574
height = u_minify(image->bo->height0, range->baseMipLevel + j);
2575
2576
surf = create_img_surface_bo(state, range,
2577
image->bo, image->bo->format,
2578
width, height,
2579
0, lvp_get_layerCount(image, range) - 1, j);
2580
2581
state->pctx->clear_depth_stencil(state->pctx,
2582
surf,
2583
ds_clear_flags,
2584
cmd->u.clear_ds_image.clear_val.depth,
2585
cmd->u.clear_ds_image.clear_val.stencil,
2586
0, 0,
2587
width, height, true);
2588
state->pctx->surface_destroy(state->pctx, surf);
2589
}
2590
}
2591
}
2592
2593
static void handle_clear_attachments(struct lvp_cmd_buffer_entry *cmd,
2594
struct rendering_state *state)
2595
{
2596
for (uint32_t a = 0; a < cmd->u.clear_attachments.attachment_count; a++) {
2597
VkClearAttachment *att = &cmd->u.clear_attachments.attachments[a];
2598
const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
2599
struct lvp_image_view *imgv;
2600
2601
if (att->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) {
2602
struct lvp_subpass_attachment *color_att = &subpass->color_attachments[att->colorAttachment];
2603
if (!color_att || color_att->attachment == VK_ATTACHMENT_UNUSED)
2604
continue;
2605
imgv = get_attachment(state, color_att->attachment);
2606
} else {
2607
struct lvp_subpass_attachment *ds_att = subpass->depth_stencil_attachment;
2608
if (!ds_att || ds_att->attachment == VK_ATTACHMENT_UNUSED)
2609
continue;
2610
imgv = get_attachment(state, ds_att->attachment);
2611
}
2612
union pipe_color_union col_val;
2613
double dclear_val = 0;
2614
uint32_t sclear_val = 0;
2615
uint32_t ds_clear_flags = 0;
2616
if (att->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) {
2617
ds_clear_flags |= PIPE_CLEAR_DEPTH;
2618
dclear_val = att->clearValue.depthStencil.depth;
2619
}
2620
if (att->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) {
2621
ds_clear_flags |= PIPE_CLEAR_STENCIL;
2622
sclear_val = att->clearValue.depthStencil.stencil;
2623
}
2624
if (att->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
2625
for (unsigned i = 0; i < 4; i++)
2626
col_val.ui[i] = att->clearValue.color.uint32[i];
2627
}
2628
2629
for (uint32_t r = 0; r < cmd->u.clear_attachments.rect_count; r++) {
2630
2631
VkClearRect *rect = &cmd->u.clear_attachments.rects[r];
2632
if (subpass->view_mask) {
2633
u_foreach_bit(i, subpass->view_mask)
2634
clear_attachment_layers(state, imgv, &rect->rect,
2635
i, 1,
2636
ds_clear_flags, dclear_val, sclear_val,
2637
&col_val);
2638
} else
2639
clear_attachment_layers(state, imgv, &rect->rect,
2640
rect->baseArrayLayer, rect->layerCount,
2641
ds_clear_flags, dclear_val, sclear_val,
2642
&col_val);
2643
}
2644
}
2645
}
2646
2647
static void handle_resolve_image(struct lvp_cmd_buffer_entry *cmd,
2648
struct rendering_state *state)
2649
{
2650
int i;
2651
struct lvp_cmd_resolve_image *resolvecmd = &cmd->u.resolve_image;
2652
struct pipe_blit_info info;
2653
2654
memset(&info, 0, sizeof(info));
2655
2656
state->pctx->flush(state->pctx, NULL, 0);
2657
info.src.resource = resolvecmd->src->bo;
2658
info.dst.resource = resolvecmd->dst->bo;
2659
info.src.format = resolvecmd->src->bo->format;
2660
info.dst.format = resolvecmd->dst->bo->format;
2661
info.mask = util_format_is_depth_or_stencil(info.src.format) ? PIPE_MASK_ZS : PIPE_MASK_RGBA;
2662
info.filter = PIPE_TEX_FILTER_NEAREST;
2663
for (i = 0; i < resolvecmd->region_count; i++) {
2664
int srcX0, srcY0;
2665
unsigned dstX0, dstY0;
2666
2667
srcX0 = resolvecmd->regions[i].srcOffset.x;
2668
srcY0 = resolvecmd->regions[i].srcOffset.y;
2669
2670
dstX0 = resolvecmd->regions[i].dstOffset.x;
2671
dstY0 = resolvecmd->regions[i].dstOffset.y;
2672
2673
info.dst.box.x = dstX0;
2674
info.dst.box.y = dstY0;
2675
info.src.box.x = srcX0;
2676
info.src.box.y = srcY0;
2677
2678
info.dst.box.width = resolvecmd->regions[i].extent.width;
2679
info.src.box.width = resolvecmd->regions[i].extent.width;
2680
info.dst.box.height = resolvecmd->regions[i].extent.height;
2681
info.src.box.height = resolvecmd->regions[i].extent.height;
2682
2683
info.dst.box.depth = resolvecmd->regions[i].dstSubresource.layerCount;
2684
info.src.box.depth = resolvecmd->regions[i].srcSubresource.layerCount;
2685
2686
info.src.level = resolvecmd->regions[i].srcSubresource.mipLevel;
2687
info.src.box.z = resolvecmd->regions[i].srcOffset.z + resolvecmd->regions[i].srcSubresource.baseArrayLayer;
2688
2689
info.dst.level = resolvecmd->regions[i].dstSubresource.mipLevel;
2690
info.dst.box.z = resolvecmd->regions[i].dstOffset.z + resolvecmd->regions[i].dstSubresource.baseArrayLayer;
2691
2692
state->pctx->blit(state->pctx, &info);
2693
}
2694
}
2695
2696
static void handle_draw_indirect_count(struct lvp_cmd_buffer_entry *cmd,
2697
struct rendering_state *state, bool indexed)
2698
{
2699
const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
2700
struct pipe_draw_start_count_bias draw = {0};
2701
if (indexed) {
2702
state->info.index_bounds_valid = false;
2703
state->info.index_size = state->index_size;
2704
state->info.index.resource = state->index_buffer;
2705
state->info.max_index = ~0;
2706
} else
2707
state->info.index_size = 0;
2708
state->indirect_info.offset = cmd->u.draw_indirect_count.offset;
2709
state->indirect_info.stride = cmd->u.draw_indirect_count.stride;
2710
state->indirect_info.draw_count = cmd->u.draw_indirect_count.max_draw_count;
2711
state->indirect_info.buffer = cmd->u.draw_indirect_count.buffer->bo;
2712
state->indirect_info.indirect_draw_count_offset = cmd->u.draw_indirect_count.count_buffer_offset;
2713
state->indirect_info.indirect_draw_count = cmd->u.draw_indirect_count.count_buffer->bo;
2714
state->info.view_mask = subpass->view_mask;
2715
2716
state->pctx->draw_vbo(state->pctx, &state->info, 0, &state->indirect_info, &draw, 1);
2717
}
2718
2719
static void handle_compute_push_descriptor_set(struct lvp_cmd_buffer_entry *cmd,
2720
struct dyn_info *dyn_info,
2721
struct rendering_state *state)
2722
{
2723
struct lvp_cmd_push_descriptor_set *pds = &cmd->u.push_descriptor_set;
2724
struct lvp_descriptor_set_layout *layout = pds->layout->set[pds->set].layout;
2725
2726
if (!(layout->shader_stages & VK_SHADER_STAGE_COMPUTE_BIT))
2727
return;
2728
for (unsigned i = 0; i < pds->set; i++) {
2729
increment_dyn_info(dyn_info, pds->layout->set[i].layout, false);
2730
}
2731
unsigned info_idx = 0;
2732
for (unsigned i = 0; i < pds->descriptor_write_count; i++) {
2733
struct lvp_write_descriptor *desc = &pds->descriptors[i];
2734
struct lvp_descriptor_set_binding_layout *binding = &layout->binding[desc->dst_binding];
2735
2736
if (!binding->valid)
2737
continue;
2738
2739
for (unsigned j = 0; j < desc->descriptor_count; j++) {
2740
union lvp_descriptor_info *info = &pds->infos[info_idx + j];
2741
2742
handle_descriptor(state, dyn_info, binding,
2743
MESA_SHADER_COMPUTE, PIPE_SHADER_COMPUTE,
2744
j, desc->descriptor_type,
2745
info);
2746
}
2747
info_idx += desc->descriptor_count;
2748
}
2749
}
2750
2751
static void handle_push_descriptor_set(struct lvp_cmd_buffer_entry *cmd,
2752
struct rendering_state *state)
2753
{
2754
struct lvp_cmd_push_descriptor_set *pds = &cmd->u.push_descriptor_set;
2755
struct lvp_descriptor_set_layout *layout = pds->layout->set[pds->set].layout;
2756
struct dyn_info dyn_info;
2757
2758
memset(&dyn_info.stage, 0, sizeof(dyn_info.stage));
2759
dyn_info.dyn_index = 0;
2760
if (pds->bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
2761
handle_compute_push_descriptor_set(cmd, &dyn_info, state);
2762
}
2763
2764
for (unsigned i = 0; i < pds->set; i++) {
2765
increment_dyn_info(&dyn_info, pds->layout->set[i].layout, false);
2766
}
2767
2768
unsigned info_idx = 0;
2769
for (unsigned i = 0; i < pds->descriptor_write_count; i++) {
2770
struct lvp_write_descriptor *desc = &pds->descriptors[i];
2771
struct lvp_descriptor_set_binding_layout *binding = &layout->binding[desc->dst_binding];
2772
2773
if (!binding->valid)
2774
continue;
2775
2776
for (unsigned j = 0; j < desc->descriptor_count; j++) {
2777
union lvp_descriptor_info *info = &pds->infos[info_idx + j];
2778
2779
if (layout->shader_stages & VK_SHADER_STAGE_VERTEX_BIT)
2780
handle_descriptor(state, &dyn_info, binding,
2781
MESA_SHADER_VERTEX, PIPE_SHADER_VERTEX,
2782
j, desc->descriptor_type,
2783
info);
2784
if (layout->shader_stages & VK_SHADER_STAGE_FRAGMENT_BIT)
2785
handle_descriptor(state, &dyn_info, binding,
2786
MESA_SHADER_FRAGMENT, PIPE_SHADER_FRAGMENT,
2787
j, desc->descriptor_type,
2788
info);
2789
if (layout->shader_stages & VK_SHADER_STAGE_GEOMETRY_BIT)
2790
handle_descriptor(state, &dyn_info, binding,
2791
MESA_SHADER_GEOMETRY, PIPE_SHADER_GEOMETRY,
2792
j, desc->descriptor_type,
2793
info);
2794
if (layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
2795
handle_descriptor(state, &dyn_info, binding,
2796
MESA_SHADER_TESS_CTRL, PIPE_SHADER_TESS_CTRL,
2797
j, desc->descriptor_type,
2798
info);
2799
if (layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
2800
handle_descriptor(state, &dyn_info, binding,
2801
MESA_SHADER_TESS_EVAL, PIPE_SHADER_TESS_EVAL,
2802
j, desc->descriptor_type,
2803
info);
2804
}
2805
info_idx += desc->descriptor_count;
2806
}
2807
}
2808
2809
static void handle_bind_transform_feedback_buffers(struct lvp_cmd_buffer_entry *cmd,
2810
struct rendering_state *state)
2811
{
2812
struct lvp_cmd_bind_transform_feedback_buffers *btfb = &cmd->u.bind_transform_feedback_buffers;
2813
2814
for (unsigned i = 0; i < btfb->binding_count; i++) {
2815
int idx = i + btfb->first_binding;
2816
if (state->so_targets[idx])
2817
state->pctx->stream_output_target_destroy(state->pctx, state->so_targets[idx]);
2818
2819
state->so_targets[idx] = state->pctx->create_stream_output_target(state->pctx,
2820
btfb->buffers[i]->bo,
2821
btfb->offsets[i],
2822
btfb->sizes[i]);
2823
}
2824
state->num_so_targets = btfb->first_binding + btfb->binding_count;
2825
}
2826
2827
static void handle_begin_transform_feedback(struct lvp_cmd_buffer_entry *cmd,
2828
struct rendering_state *state)
2829
{
2830
struct lvp_cmd_begin_transform_feedback *btf = &cmd->u.begin_transform_feedback;
2831
uint32_t offsets[4];
2832
2833
memset(offsets, 0, sizeof(uint32_t)*4);
2834
2835
for (unsigned i = 0; i < btf->counter_buffer_count; i++) {
2836
if (!btf->counter_buffers[i])
2837
continue;
2838
2839
pipe_buffer_read(state->pctx,
2840
btf->counter_buffers[i]->bo,
2841
btf->counter_buffer_offsets[i],
2842
4,
2843
&offsets[i]);
2844
}
2845
state->pctx->set_stream_output_targets(state->pctx, state->num_so_targets,
2846
state->so_targets, offsets);
2847
}
2848
2849
static void handle_end_transform_feedback(struct lvp_cmd_buffer_entry *cmd,
2850
struct rendering_state *state)
2851
{
2852
struct lvp_cmd_end_transform_feedback *etf = &cmd->u.end_transform_feedback;
2853
2854
if (etf->counter_buffer_count) {
2855
for (unsigned i = 0; i < etf->counter_buffer_count; i++) {
2856
if (!etf->counter_buffers[i])
2857
continue;
2858
2859
uint32_t offset;
2860
offset = state->pctx->stream_output_target_offset(state->so_targets[i]);
2861
2862
pipe_buffer_write(state->pctx,
2863
etf->counter_buffers[i]->bo,
2864
etf->counter_buffer_offsets[i],
2865
4,
2866
&offset);
2867
}
2868
}
2869
state->pctx->set_stream_output_targets(state->pctx, 0, NULL, NULL);
2870
}
2871
2872
static void handle_draw_indirect_byte_count(struct lvp_cmd_buffer_entry *cmd,
2873
struct rendering_state *state)
2874
{
2875
struct lvp_cmd_draw_indirect_byte_count *dibc = &cmd->u.draw_indirect_byte_count;
2876
const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];
2877
struct pipe_draw_start_count_bias draw = {0};
2878
2879
pipe_buffer_read(state->pctx,
2880
dibc->counter_buffer->bo,
2881
dibc->counter_buffer->offset + dibc->counter_buffer_offset,
2882
4, &draw.count);
2883
2884
state->info.start_instance = cmd->u.draw_indirect_byte_count.first_instance;
2885
state->info.instance_count = cmd->u.draw_indirect_byte_count.instance_count;
2886
state->info.index_size = 0;
2887
2888
draw.count /= cmd->u.draw_indirect_byte_count.vertex_stride;
2889
state->info.view_mask = subpass->view_mask;
2890
state->pctx->draw_vbo(state->pctx, &state->info, 0, &state->indirect_info, &draw, 1);
2891
}
2892
2893
static void handle_begin_conditional_rendering(struct lvp_cmd_buffer_entry *cmd,
2894
struct rendering_state *state)
2895
{
2896
struct lvp_cmd_begin_conditional_rendering *bcr = &cmd->u.begin_conditional_rendering;
2897
state->pctx->render_condition_mem(state->pctx,
2898
bcr->buffer->bo,
2899
bcr->buffer->offset + bcr->offset,
2900
bcr->inverted);
2901
}
2902
2903
static void handle_end_conditional_rendering(struct rendering_state *state)
2904
{
2905
state->pctx->render_condition_mem(state->pctx, NULL, 0, false);
2906
}
2907
2908
static void handle_set_vertex_input(struct lvp_cmd_buffer_entry *cmd,
2909
struct rendering_state *state)
2910
{
2911
const struct lvp_cmd_set_vertex_input *vertex_input = &cmd->u.set_vertex_input;
2912
const struct VkVertexInputBindingDescription2EXT *bindings = (void*)vertex_input->data;
2913
const struct VkVertexInputAttributeDescription2EXT *attrs = (void*)(vertex_input->data +
2914
vertex_input->binding_count *
2915
sizeof(struct VkVertexInputBindingDescription2EXT));
2916
int max_location = -1;
2917
for (unsigned i = 0; i < vertex_input->attr_count; i++) {
2918
const struct VkVertexInputBindingDescription2EXT *binding = &bindings[attrs[i].binding];
2919
unsigned location = attrs[i].location;
2920
state->velem.velems[location].src_offset = attrs[i].offset;
2921
state->velem.velems[location].vertex_buffer_index = attrs[i].binding;
2922
state->velem.velems[location].src_format = lvp_vk_format_to_pipe_format(attrs[i].format);
2923
state->vb[attrs[i].binding].stride = binding->stride;
2924
2925
switch (binding->inputRate) {
2926
case VK_VERTEX_INPUT_RATE_VERTEX:
2927
state->velem.velems[location].instance_divisor = 0;
2928
break;
2929
case VK_VERTEX_INPUT_RATE_INSTANCE:
2930
state->velem.velems[location].instance_divisor = binding->divisor;
2931
break;
2932
default:
2933
assert(0);
2934
break;
2935
}
2936
2937
if ((int)location > max_location)
2938
max_location = location;
2939
}
2940
state->velem.count = max_location + 1;
2941
state->vb_dirty = true;
2942
state->ve_dirty = true;
2943
}
2944
2945
static void handle_set_cull_mode(struct lvp_cmd_buffer_entry *cmd,
2946
struct rendering_state *state)
2947
{
2948
state->rs_state.cull_face = vk_cull_to_pipe(cmd->u.set_cull_mode.cull_mode);
2949
state->rs_dirty = true;
2950
}
2951
2952
static void handle_set_front_face(struct lvp_cmd_buffer_entry *cmd,
2953
struct rendering_state *state)
2954
{
2955
state->rs_state.front_ccw = (cmd->u.set_front_face.front_face == VK_FRONT_FACE_COUNTER_CLOCKWISE);
2956
state->rs_dirty = true;
2957
}
2958
2959
static void handle_set_primitive_topology(struct lvp_cmd_buffer_entry *cmd,
2960
struct rendering_state *state)
2961
{
2962
state->info.mode = vk_conv_topology(cmd->u.set_primitive_topology.prim);
2963
state->rs_dirty = true;
2964
}
2965
2966
2967
static void handle_set_depth_test_enable(struct lvp_cmd_buffer_entry *cmd,
2968
struct rendering_state *state)
2969
{
2970
state->dsa_dirty |= state->dsa_state.depth_enabled != cmd->u.set_depth_test_enable.depth_test_enable;
2971
state->dsa_state.depth_enabled = cmd->u.set_depth_test_enable.depth_test_enable;
2972
}
2973
2974
static void handle_set_depth_write_enable(struct lvp_cmd_buffer_entry *cmd,
2975
struct rendering_state *state)
2976
{
2977
state->dsa_dirty |= state->dsa_state.depth_writemask != cmd->u.set_depth_write_enable.depth_write_enable;
2978
state->dsa_state.depth_writemask = cmd->u.set_depth_write_enable.depth_write_enable;
2979
}
2980
2981
static void handle_set_depth_compare_op(struct lvp_cmd_buffer_entry *cmd,
2982
struct rendering_state *state)
2983
{
2984
state->dsa_dirty |= state->dsa_state.depth_func != cmd->u.set_depth_compare_op.depth_op;
2985
state->dsa_state.depth_func = cmd->u.set_depth_compare_op.depth_op;
2986
}
2987
2988
static void handle_set_depth_bounds_test_enable(struct lvp_cmd_buffer_entry *cmd,
2989
struct rendering_state *state)
2990
{
2991
state->dsa_dirty |= state->dsa_state.depth_bounds_test != cmd->u.set_depth_bounds_test_enable.depth_bounds_test_enable;
2992
state->dsa_state.depth_bounds_test = cmd->u.set_depth_bounds_test_enable.depth_bounds_test_enable;
2993
}
2994
2995
static void handle_set_stencil_test_enable(struct lvp_cmd_buffer_entry *cmd,
2996
struct rendering_state *state)
2997
{
2998
state->dsa_dirty |= state->dsa_state.stencil[0].enabled != cmd->u.set_stencil_test_enable.stencil_test_enable ||
2999
state->dsa_state.stencil[1].enabled != cmd->u.set_stencil_test_enable.stencil_test_enable;
3000
state->dsa_state.stencil[0].enabled = cmd->u.set_stencil_test_enable.stencil_test_enable;
3001
state->dsa_state.stencil[1].enabled = cmd->u.set_stencil_test_enable.stencil_test_enable;
3002
}
3003
3004
static void handle_set_stencil_op(struct lvp_cmd_buffer_entry *cmd,
3005
struct rendering_state *state)
3006
{
3007
if (cmd->u.set_stencil_op.face_mask & VK_STENCIL_FACE_FRONT_BIT) {
3008
state->dsa_state.stencil[0].func = cmd->u.set_stencil_op.compare_op;
3009
state->dsa_state.stencil[0].fail_op = vk_conv_stencil_op(cmd->u.set_stencil_op.fail_op);
3010
state->dsa_state.stencil[0].zpass_op = vk_conv_stencil_op(cmd->u.set_stencil_op.pass_op);
3011
state->dsa_state.stencil[0].zfail_op = vk_conv_stencil_op(cmd->u.set_stencil_op.depth_fail_op);
3012
}
3013
3014
if (cmd->u.set_stencil_op.face_mask & VK_STENCIL_FACE_BACK_BIT) {
3015
state->dsa_state.stencil[1].func = cmd->u.set_stencil_op.compare_op;
3016
state->dsa_state.stencil[1].fail_op = vk_conv_stencil_op(cmd->u.set_stencil_op.fail_op);
3017
state->dsa_state.stencil[1].zpass_op = vk_conv_stencil_op(cmd->u.set_stencil_op.pass_op);
3018
state->dsa_state.stencil[1].zfail_op = vk_conv_stencil_op(cmd->u.set_stencil_op.depth_fail_op);
3019
}
3020
state->dsa_dirty = true;
3021
}
3022
3023
static void handle_set_line_stipple(struct lvp_cmd_buffer_entry *cmd,
3024
struct rendering_state *state)
3025
{
3026
state->rs_state.line_stipple_factor = cmd->u.set_line_stipple.line_stipple_factor - 1;
3027
state->rs_state.line_stipple_pattern = cmd->u.set_line_stipple.line_stipple_pattern;
3028
state->rs_dirty = true;
3029
}
3030
3031
static void handle_set_depth_bias_enable(struct lvp_cmd_buffer_entry *cmd,
3032
struct rendering_state *state)
3033
{
3034
state->rs_dirty |= state->depth_bias.enabled != cmd->u.set_depth_bias_enable.enable;
3035
state->depth_bias.enabled = cmd->u.set_depth_bias_enable.enable;
3036
}
3037
3038
static void handle_set_logic_op(struct lvp_cmd_buffer_entry *cmd,
3039
struct rendering_state *state)
3040
{
3041
unsigned op = vk_conv_logic_op(cmd->u.set_logic_op.op);
3042
state->rs_dirty |= state->blend_state.logicop_func != op;
3043
state->blend_state.logicop_func = op;
3044
}
3045
3046
static void handle_set_patch_control_points(struct lvp_cmd_buffer_entry *cmd,
3047
struct rendering_state *state)
3048
{
3049
state->info.vertices_per_patch = cmd->u.set_patch_control_points.vertices_per_patch;
3050
}
3051
3052
static void handle_set_primitive_restart_enable(struct lvp_cmd_buffer_entry *cmd,
3053
struct rendering_state *state)
3054
{
3055
state->info.primitive_restart = cmd->u.set_primitive_restart_enable.enable;
3056
}
3057
3058
static void handle_set_rasterizer_discard_enable(struct lvp_cmd_buffer_entry *cmd,
3059
struct rendering_state *state)
3060
{
3061
state->rs_dirty |= state->rs_state.rasterizer_discard != cmd->u.set_rasterizer_discard_enable.enable;
3062
state->rs_state.rasterizer_discard = cmd->u.set_rasterizer_discard_enable.enable;
3063
}
3064
3065
static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer,
3066
struct rendering_state *state)
3067
{
3068
struct lvp_cmd_buffer_entry *cmd;
3069
bool first = true;
3070
bool did_flush = false;
3071
3072
LIST_FOR_EACH_ENTRY(cmd, &cmd_buffer->cmds, cmd_link) {
3073
switch (cmd->cmd_type) {
3074
case LVP_CMD_BIND_PIPELINE:
3075
handle_pipeline(cmd, state);
3076
break;
3077
case LVP_CMD_SET_VIEWPORT:
3078
handle_set_viewport(cmd, state);
3079
break;
3080
case LVP_CMD_SET_SCISSOR:
3081
handle_set_scissor(cmd, state);
3082
break;
3083
case LVP_CMD_SET_LINE_WIDTH:
3084
handle_set_line_width(cmd, state);
3085
break;
3086
case LVP_CMD_SET_DEPTH_BIAS:
3087
handle_set_depth_bias(cmd, state);
3088
break;
3089
case LVP_CMD_SET_BLEND_CONSTANTS:
3090
handle_set_blend_constants(cmd, state);
3091
break;
3092
case LVP_CMD_SET_DEPTH_BOUNDS:
3093
handle_set_depth_bounds(cmd, state);
3094
break;
3095
case LVP_CMD_SET_STENCIL_COMPARE_MASK:
3096
handle_set_stencil_compare_mask(cmd, state);
3097
break;
3098
case LVP_CMD_SET_STENCIL_WRITE_MASK:
3099
handle_set_stencil_write_mask(cmd, state);
3100
break;
3101
case LVP_CMD_SET_STENCIL_REFERENCE:
3102
handle_set_stencil_reference(cmd, state);
3103
break;
3104
case LVP_CMD_BIND_DESCRIPTOR_SETS:
3105
handle_descriptor_sets(cmd, state);
3106
break;
3107
case LVP_CMD_BIND_INDEX_BUFFER:
3108
handle_index_buffer(cmd, state);
3109
break;
3110
case LVP_CMD_BIND_VERTEX_BUFFERS:
3111
handle_vertex_buffers(cmd, state);
3112
break;
3113
case LVP_CMD_DRAW:
3114
emit_state(state);
3115
handle_draw(cmd, state);
3116
break;
3117
case LVP_CMD_DRAW_INDEXED:
3118
emit_state(state);
3119
handle_draw_indexed(cmd, state);
3120
break;
3121
case LVP_CMD_DRAW_INDIRECT:
3122
emit_state(state);
3123
handle_draw_indirect(cmd, state, false);
3124
break;
3125
case LVP_CMD_DRAW_INDEXED_INDIRECT:
3126
emit_state(state);
3127
handle_draw_indirect(cmd, state, true);
3128
break;
3129
case LVP_CMD_DISPATCH:
3130
emit_compute_state(state);
3131
handle_dispatch(cmd, state);
3132
break;
3133
case LVP_CMD_DISPATCH_INDIRECT:
3134
emit_compute_state(state);
3135
handle_dispatch_indirect(cmd, state);
3136
break;
3137
case LVP_CMD_COPY_BUFFER:
3138
handle_copy_buffer(cmd, state);
3139
break;
3140
case LVP_CMD_COPY_IMAGE:
3141
handle_copy_image(cmd, state);
3142
break;
3143
case LVP_CMD_BLIT_IMAGE:
3144
handle_blit_image(cmd, state);
3145
break;
3146
case LVP_CMD_COPY_BUFFER_TO_IMAGE:
3147
handle_copy_buffer_to_image(cmd, state);
3148
break;
3149
case LVP_CMD_COPY_IMAGE_TO_BUFFER:
3150
handle_copy_image_to_buffer(cmd, state);
3151
break;
3152
case LVP_CMD_UPDATE_BUFFER:
3153
handle_update_buffer(cmd, state);
3154
break;
3155
case LVP_CMD_FILL_BUFFER:
3156
handle_fill_buffer(cmd, state);
3157
break;
3158
case LVP_CMD_CLEAR_COLOR_IMAGE:
3159
handle_clear_color_image(cmd, state);
3160
break;
3161
case LVP_CMD_CLEAR_DEPTH_STENCIL_IMAGE:
3162
handle_clear_ds_image(cmd, state);
3163
break;
3164
case LVP_CMD_CLEAR_ATTACHMENTS:
3165
handle_clear_attachments(cmd, state);
3166
break;
3167
case LVP_CMD_RESOLVE_IMAGE:
3168
handle_resolve_image(cmd, state);
3169
break;
3170
case LVP_CMD_SET_EVENT:
3171
case LVP_CMD_RESET_EVENT:
3172
handle_event_set(cmd, state);
3173
break;
3174
case LVP_CMD_WAIT_EVENTS:
3175
handle_wait_events(cmd, state);
3176
break;
3177
case LVP_CMD_PIPELINE_BARRIER:
3178
/* skip flushes since every cmdbuf does a flush
3179
after iterating its cmds and so this is redundant
3180
*/
3181
if (first || did_flush || cmd->cmd_link.next == &cmd_buffer->cmds)
3182
continue;
3183
handle_pipeline_barrier(cmd, state);
3184
did_flush = true;
3185
continue;
3186
case LVP_CMD_BEGIN_QUERY:
3187
maybe_emit_state_for_begin_query(cmd, state);
3188
handle_begin_query(cmd, state);
3189
break;
3190
case LVP_CMD_END_QUERY:
3191
handle_end_query(cmd, state);
3192
break;
3193
case LVP_CMD_RESET_QUERY_POOL:
3194
handle_reset_query_pool(cmd, state);
3195
break;
3196
case LVP_CMD_WRITE_TIMESTAMP:
3197
handle_write_timestamp(cmd, state);
3198
break;
3199
case LVP_CMD_COPY_QUERY_POOL_RESULTS:
3200
handle_copy_query_pool_results(cmd, state);
3201
break;
3202
case LVP_CMD_PUSH_CONSTANTS:
3203
handle_push_constants(cmd, state);
3204
break;
3205
case LVP_CMD_BEGIN_RENDER_PASS:
3206
handle_begin_render_pass(cmd, state);
3207
break;
3208
case LVP_CMD_NEXT_SUBPASS:
3209
handle_next_subpass(cmd, state);
3210
break;
3211
case LVP_CMD_END_RENDER_PASS:
3212
handle_end_render_pass(cmd, state);
3213
break;
3214
case LVP_CMD_EXECUTE_COMMANDS:
3215
handle_execute_commands(cmd, state);
3216
break;
3217
case LVP_CMD_DRAW_INDIRECT_COUNT:
3218
emit_state(state);
3219
handle_draw_indirect_count(cmd, state, false);
3220
break;
3221
case LVP_CMD_DRAW_INDEXED_INDIRECT_COUNT:
3222
emit_state(state);
3223
handle_draw_indirect_count(cmd, state, true);
3224
break;
3225
case LVP_CMD_PUSH_DESCRIPTOR_SET:
3226
handle_push_descriptor_set(cmd, state);
3227
break;
3228
case LVP_CMD_BIND_TRANSFORM_FEEDBACK_BUFFERS:
3229
handle_bind_transform_feedback_buffers(cmd, state);
3230
break;
3231
case LVP_CMD_BEGIN_TRANSFORM_FEEDBACK:
3232
handle_begin_transform_feedback(cmd, state);
3233
break;
3234
case LVP_CMD_END_TRANSFORM_FEEDBACK:
3235
handle_end_transform_feedback(cmd, state);
3236
break;
3237
case LVP_CMD_DRAW_INDIRECT_BYTE_COUNT:
3238
emit_state(state);
3239
handle_draw_indirect_byte_count(cmd, state);
3240
break;
3241
case LVP_CMD_BEGIN_CONDITIONAL_RENDERING:
3242
handle_begin_conditional_rendering(cmd, state);
3243
break;
3244
case LVP_CMD_END_CONDITIONAL_RENDERING:
3245
handle_end_conditional_rendering(state);
3246
break;
3247
case LVP_CMD_SET_VERTEX_INPUT:
3248
handle_set_vertex_input(cmd, state);
3249
break;
3250
case LVP_CMD_SET_CULL_MODE:
3251
handle_set_cull_mode(cmd, state);
3252
break;
3253
case LVP_CMD_SET_FRONT_FACE:
3254
handle_set_front_face(cmd, state);
3255
break;
3256
case LVP_CMD_SET_PRIMITIVE_TOPOLOGY:
3257
handle_set_primitive_topology(cmd, state);
3258
break;
3259
case LVP_CMD_SET_DEPTH_TEST_ENABLE:
3260
handle_set_depth_test_enable(cmd, state);
3261
break;
3262
case LVP_CMD_SET_DEPTH_WRITE_ENABLE:
3263
handle_set_depth_write_enable(cmd, state);
3264
break;
3265
case LVP_CMD_SET_DEPTH_COMPARE_OP:
3266
handle_set_depth_compare_op(cmd, state);
3267
break;
3268
case LVP_CMD_SET_DEPTH_BOUNDS_TEST_ENABLE:
3269
handle_set_depth_bounds_test_enable(cmd, state);
3270
break;
3271
case LVP_CMD_SET_STENCIL_TEST_ENABLE:
3272
handle_set_stencil_test_enable(cmd, state);
3273
break;
3274
case LVP_CMD_SET_STENCIL_OP:
3275
handle_set_stencil_op(cmd, state);
3276
break;
3277
case LVP_CMD_SET_LINE_STIPPLE:
3278
handle_set_line_stipple(cmd, state);
3279
break;
3280
case LVP_CMD_SET_DEPTH_BIAS_ENABLE:
3281
handle_set_depth_bias_enable(cmd, state);
3282
break;
3283
case LVP_CMD_SET_LOGIC_OP:
3284
handle_set_logic_op(cmd, state);
3285
break;
3286
case LVP_CMD_SET_PATCH_CONTROL_POINTS:
3287
handle_set_patch_control_points(cmd, state);
3288
break;
3289
case LVP_CMD_SET_PRIMITIVE_RESTART_ENABLE:
3290
handle_set_primitive_restart_enable(cmd, state);
3291
break;
3292
case LVP_CMD_SET_RASTERIZER_DISCARD_ENABLE:
3293
handle_set_rasterizer_discard_enable(cmd, state);
3294
break;
3295
}
3296
first = false;
3297
did_flush = false;
3298
}
3299
}
3300
3301
VkResult lvp_execute_cmds(struct lvp_device *device,
3302
struct lvp_queue *queue,
3303
struct lvp_cmd_buffer *cmd_buffer)
3304
{
3305
struct rendering_state state;
3306
memset(&state, 0, sizeof(state));
3307
state.pctx = queue->ctx;
3308
state.cso = queue->cso;
3309
state.blend_dirty = true;
3310
state.dsa_dirty = true;
3311
state.rs_dirty = true;
3312
state.vp_dirty = true;
3313
for (enum pipe_shader_type s = PIPE_SHADER_VERTEX; s < PIPE_SHADER_TYPES; s++) {
3314
for (unsigned i = 0; i < PIPE_MAX_SAMPLERS; i++)
3315
state.cso_ss_ptr[s][i] = &state.ss[s][i];
3316
}
3317
/* create a gallium context */
3318
lvp_execute_cmd_buffer(cmd_buffer, &state);
3319
3320
state.start_vb = -1;
3321
state.num_vb = 0;
3322
cso_unbind_context(queue->cso);
3323
for (unsigned i = 0; i < PIPE_MAX_SO_BUFFERS; i++) {
3324
if (state.so_targets[i]) {
3325
state.pctx->stream_output_target_destroy(state.pctx, state.so_targets[i]);
3326
}
3327
}
3328
3329
free(state.pending_clear_aspects);
3330
free(state.cleared_views);
3331
return VK_SUCCESS;
3332
}
3333
3334