radv_cmd_buffer.c 274 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*
 * Copyright © 2016 Red Hat.
 * Copyright © 2016 Bas Nieuwenhuizen
 *
 * based in part on anv driver which is:
 * Copyright © 2015 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
28
29
30
#include "radv_cs.h"
#include "radv_debug.h"
#include "radv_meta.h"
31
32
#include "radv_private.h"
#include "radv_radeon_winsys.h"
33
#include "radv_shader.h"
34
35
#include "sid.h"
#include "vk_format.h"
36
#include "vk_util.h"
37

38
39
#include "ac_debug.h"

40
enum {
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
41
42
43
44
45
46
47
48
   RADV_PREFETCH_VBO_DESCRIPTORS = (1 << 0),
   RADV_PREFETCH_VS = (1 << 1),
   RADV_PREFETCH_TCS = (1 << 2),
   RADV_PREFETCH_TES = (1 << 3),
   RADV_PREFETCH_GS = (1 << 4),
   RADV_PREFETCH_PS = (1 << 5),
   RADV_PREFETCH_SHADERS = (RADV_PREFETCH_VS | RADV_PREFETCH_TCS | RADV_PREFETCH_TES |
                            RADV_PREFETCH_GS | RADV_PREFETCH_PS)
49
50
};

51
52
53
54
55
56
enum {
   RADV_RT_STAGE_BITS = (VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR |
                         VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_MISS_BIT_KHR |
                         VK_SHADER_STAGE_INTERSECTION_BIT_KHR | VK_SHADER_STAGE_CALLABLE_BIT_KHR)
};

57
static void radv_handle_image_transition(struct radv_cmd_buffer *cmd_buffer,
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
58
59
60
61
62
                                         struct radv_image *image, VkImageLayout src_layout,
                                         bool src_render_loop, VkImageLayout dst_layout,
                                         bool dst_render_loop, uint32_t src_family,
                                         uint32_t dst_family, const VkImageSubresourceRange *range,
                                         struct radv_sample_locations_state *sample_locs);
63
64

const struct radv_dynamic_state default_dynamic_state = {
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
   .viewport =
      {
         .count = 0,
      },
   .scissor =
      {
         .count = 0,
      },
   .line_width = 1.0f,
   .depth_bias =
      {
         .bias = 0.0f,
         .clamp = 0.0f,
         .slope = 0.0f,
      },
   .blend_constants = {0.0f, 0.0f, 0.0f, 0.0f},
   .depth_bounds =
      {
         .min = 0.0f,
         .max = 1.0f,
      },
   .stencil_compare_mask =
      {
         .front = ~0u,
         .back = ~0u,
      },
   .stencil_write_mask =
      {
         .front = ~0u,
         .back = ~0u,
      },
   .stencil_reference =
      {
         .front = 0u,
         .back = 0u,
      },
   .line_stipple =
      {
         .factor = 0u,
         .pattern = 0u,
      },
   .cull_mode = 0u,
   .front_face = 0u,
   .primitive_topology = 0u,
   .fragment_shading_rate =
      {
         .size = {1u, 1u},
         .combiner_ops = {VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
                          VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR},
      },
115
   .depth_bias_enable = 0u,
116
   .primitive_restart_enable = 0u,
117
   .rasterizer_discard_enable = 0u,
118
119
};

120
static void
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
radv_bind_dynamic_state(struct radv_cmd_buffer *cmd_buffer, const struct radv_dynamic_state *src)
{
   struct radv_dynamic_state *dest = &cmd_buffer->state.dynamic;
   uint64_t copy_mask = src->mask;
   uint64_t dest_mask = 0;

   dest->discard_rectangle.count = src->discard_rectangle.count;
   dest->sample_location.count = src->sample_location.count;

   if (copy_mask & RADV_DYNAMIC_VIEWPORT) {
      if (dest->viewport.count != src->viewport.count) {
         dest->viewport.count = src->viewport.count;
         dest_mask |= RADV_DYNAMIC_VIEWPORT;
      }

      if (memcmp(&dest->viewport.viewports, &src->viewport.viewports,
                 src->viewport.count * sizeof(VkViewport))) {
         typed_memcpy(dest->viewport.viewports, src->viewport.viewports, src->viewport.count);
         dest_mask |= RADV_DYNAMIC_VIEWPORT;
      }
   }

   if (copy_mask & RADV_DYNAMIC_SCISSOR) {
      if (dest->scissor.count != src->scissor.count) {
         dest->scissor.count = src->scissor.count;
         dest_mask |= RADV_DYNAMIC_SCISSOR;
      }

      if (memcmp(&dest->scissor.scissors, &src->scissor.scissors,
                 src->scissor.count * sizeof(VkRect2D))) {
         typed_memcpy(dest->scissor.scissors, src->scissor.scissors, src->scissor.count);
         dest_mask |= RADV_DYNAMIC_SCISSOR;
      }
   }

   if (copy_mask & RADV_DYNAMIC_LINE_WIDTH) {
      if (dest->line_width != src->line_width) {
         dest->line_width = src->line_width;
         dest_mask |= RADV_DYNAMIC_LINE_WIDTH;
      }
   }

   if (copy_mask & RADV_DYNAMIC_DEPTH_BIAS) {
      if (memcmp(&dest->depth_bias, &src->depth_bias, sizeof(src->depth_bias))) {
         dest->depth_bias = src->depth_bias;
         dest_mask |= RADV_DYNAMIC_DEPTH_BIAS;
      }
   }

   if (copy_mask & RADV_DYNAMIC_BLEND_CONSTANTS) {
      if (memcmp(&dest->blend_constants, &src->blend_constants, sizeof(src->blend_constants))) {
         typed_memcpy(dest->blend_constants, src->blend_constants, 4);
         dest_mask |= RADV_DYNAMIC_BLEND_CONSTANTS;
      }
   }

   if (copy_mask & RADV_DYNAMIC_DEPTH_BOUNDS) {
      if (memcmp(&dest->depth_bounds, &src->depth_bounds, sizeof(src->depth_bounds))) {
         dest->depth_bounds = src->depth_bounds;
         dest_mask |= RADV_DYNAMIC_DEPTH_BOUNDS;
      }
   }

   if (copy_mask & RADV_DYNAMIC_STENCIL_COMPARE_MASK) {
      if (memcmp(&dest->stencil_compare_mask, &src->stencil_compare_mask,
                 sizeof(src->stencil_compare_mask))) {
         dest->stencil_compare_mask = src->stencil_compare_mask;
         dest_mask |= RADV_DYNAMIC_STENCIL_COMPARE_MASK;
      }
   }

   if (copy_mask & RADV_DYNAMIC_STENCIL_WRITE_MASK) {
      if (memcmp(&dest->stencil_write_mask, &src->stencil_write_mask,
                 sizeof(src->stencil_write_mask))) {
         dest->stencil_write_mask = src->stencil_write_mask;
         dest_mask |= RADV_DYNAMIC_STENCIL_WRITE_MASK;
      }
   }

   if (copy_mask & RADV_DYNAMIC_STENCIL_REFERENCE) {
      if (memcmp(&dest->stencil_reference, &src->stencil_reference,
                 sizeof(src->stencil_reference))) {
         dest->stencil_reference = src->stencil_reference;
         dest_mask |= RADV_DYNAMIC_STENCIL_REFERENCE;
      }
   }

   if (copy_mask & RADV_DYNAMIC_DISCARD_RECTANGLE) {
      if (memcmp(&dest->discard_rectangle.rectangles, &src->discard_rectangle.rectangles,
                 src->discard_rectangle.count * sizeof(VkRect2D))) {
         typed_memcpy(dest->discard_rectangle.rectangles, src->discard_rectangle.rectangles,
                      src->discard_rectangle.count);
         dest_mask |= RADV_DYNAMIC_DISCARD_RECTANGLE;
      }
   }

   if (copy_mask & RADV_DYNAMIC_SAMPLE_LOCATIONS) {
      if (dest->sample_location.per_pixel != src->sample_location.per_pixel ||
          dest->sample_location.grid_size.width != src->sample_location.grid_size.width ||
          dest->sample_location.grid_size.height != src->sample_location.grid_size.height ||
          memcmp(&dest->sample_location.locations, &src->sample_location.locations,
                 src->sample_location.count * sizeof(VkSampleLocationEXT))) {
         dest->sample_location.per_pixel = src->sample_location.per_pixel;
         dest->sample_location.grid_size = src->sample_location.grid_size;
         typed_memcpy(dest->sample_location.locations, src->sample_location.locations,
                      src->sample_location.count);
         dest_mask |= RADV_DYNAMIC_SAMPLE_LOCATIONS;
      }
   }

   if (copy_mask & RADV_DYNAMIC_LINE_STIPPLE) {
      if (memcmp(&dest->line_stipple, &src->line_stipple, sizeof(src->line_stipple))) {
         dest->line_stipple = src->line_stipple;
         dest_mask |= RADV_DYNAMIC_LINE_STIPPLE;
      }
   }

   if (copy_mask & RADV_DYNAMIC_CULL_MODE) {
      if (dest->cull_mode != src->cull_mode) {
         dest->cull_mode = src->cull_mode;
         dest_mask |= RADV_DYNAMIC_CULL_MODE;
      }
   }

   if (copy_mask & RADV_DYNAMIC_FRONT_FACE) {
      if (dest->front_face != src->front_face) {
         dest->front_face = src->front_face;
         dest_mask |= RADV_DYNAMIC_FRONT_FACE;
      }
   }

   if (copy_mask & RADV_DYNAMIC_PRIMITIVE_TOPOLOGY) {
      if (dest->primitive_topology != src->primitive_topology) {
         dest->primitive_topology = src->primitive_topology;
         dest_mask |= RADV_DYNAMIC_PRIMITIVE_TOPOLOGY;
      }
   }

   if (copy_mask & RADV_DYNAMIC_DEPTH_TEST_ENABLE) {
      if (dest->depth_test_enable != src->depth_test_enable) {
         dest->depth_test_enable = src->depth_test_enable;
         dest_mask |= RADV_DYNAMIC_DEPTH_TEST_ENABLE;
      }
   }

   if (copy_mask & RADV_DYNAMIC_DEPTH_WRITE_ENABLE) {
      if (dest->depth_write_enable != src->depth_write_enable) {
         dest->depth_write_enable = src->depth_write_enable;
         dest_mask |= RADV_DYNAMIC_DEPTH_WRITE_ENABLE;
      }
   }

   if (copy_mask & RADV_DYNAMIC_DEPTH_COMPARE_OP) {
      if (dest->depth_compare_op != src->depth_compare_op) {
         dest->depth_compare_op = src->depth_compare_op;
         dest_mask |= RADV_DYNAMIC_DEPTH_COMPARE_OP;
      }
   }

   if (copy_mask & RADV_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE) {
      if (dest->depth_bounds_test_enable != src->depth_bounds_test_enable) {
         dest->depth_bounds_test_enable = src->depth_bounds_test_enable;
         dest_mask |= RADV_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE;
      }
   }

   if (copy_mask & RADV_DYNAMIC_STENCIL_TEST_ENABLE) {
      if (dest->stencil_test_enable != src->stencil_test_enable) {
         dest->stencil_test_enable = src->stencil_test_enable;
         dest_mask |= RADV_DYNAMIC_STENCIL_TEST_ENABLE;
      }
   }

   if (copy_mask & RADV_DYNAMIC_STENCIL_OP) {
      if (memcmp(&dest->stencil_op, &src->stencil_op, sizeof(src->stencil_op))) {
         dest->stencil_op = src->stencil_op;
         dest_mask |= RADV_DYNAMIC_STENCIL_OP;
      }
   }

   if (copy_mask & RADV_DYNAMIC_FRAGMENT_SHADING_RATE) {
      if (memcmp(&dest->fragment_shading_rate, &src->fragment_shading_rate,
                 sizeof(src->fragment_shading_rate))) {
         dest->fragment_shading_rate = src->fragment_shading_rate;
         dest_mask |= RADV_DYNAMIC_FRAGMENT_SHADING_RATE;
      }
   }

309
310
311
312
313
314
315
   if (copy_mask & RADV_DYNAMIC_DEPTH_BIAS_ENABLE) {
      if (dest->depth_bias_enable != src->depth_bias_enable) {
         dest->depth_bias_enable = src->depth_bias_enable;
         dest_mask |= RADV_DYNAMIC_DEPTH_BIAS_ENABLE;
      }
   }

316
317
318
319
320
321
322
   if (copy_mask & RADV_DYNAMIC_PRIMITIVE_RESTART_ENABLE) {
      if (dest->primitive_restart_enable != src->primitive_restart_enable) {
         dest->primitive_restart_enable = src->primitive_restart_enable;
         dest_mask |= RADV_DYNAMIC_PRIMITIVE_RESTART_ENABLE;
      }
   }

323
324
325
326
327
328
329
   if (copy_mask & RADV_DYNAMIC_RASTERIZER_DISCARD_ENABLE) {
      if (dest->rasterizer_discard_enable != src->rasterizer_discard_enable) {
         dest->rasterizer_discard_enable = src->rasterizer_discard_enable;
         dest_mask |= RADV_DYNAMIC_RASTERIZER_DISCARD_ENABLE;
      }
   }

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
330
   cmd_buffer->state.dirty |= dest_mask;
331
332
}

333
static void
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
334
radv_bind_streamout_state(struct radv_cmd_buffer *cmd_buffer, struct radv_pipeline *pipeline)
335
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
336
337
   struct radv_streamout_state *so = &cmd_buffer->state.streamout;
   struct radv_shader_info *info;
338

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
339
340
   if (!pipeline->streamout_shader || cmd_buffer->device->physical_device->use_ngg_streamout)
      return;
341

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
342
343
344
   info = &pipeline->streamout_shader->info;
   for (int i = 0; i < MAX_SO_BUFFERS; i++)
      so->stride_in_dw[i] = info->so.strides[i];
345

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
346
   so->enabled_stream_buffers_mask = info->so.enabled_stream_buffers_mask;
347
348
}

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
349
350
bool
radv_cmd_buffer_uses_mec(struct radv_cmd_buffer *cmd_buffer)
351
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
352
353
   return cmd_buffer->queue_family_index == RADV_QUEUE_COMPUTE &&
          cmd_buffer->device->physical_device->rad_info.chip_class >= GFX7;
354
355
}

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
356
357
358
359
360
361
362
363
364
365
366
367
368
enum ring_type
radv_queue_family_to_ring(int f)
{
   switch (f) {
   case RADV_QUEUE_GENERAL:
      return RING_GFX;
   case RADV_QUEUE_COMPUTE:
      return RING_COMPUTE;
   case RADV_QUEUE_TRANSFER:
      return RING_DMA;
   default:
      unreachable("Unknown queue family");
   }
369
370
}

371
372
373
static void
radv_destroy_cmd_buffer(struct radv_cmd_buffer *cmd_buffer)
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
374
   list_del(&cmd_buffer->pool_link);
375

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
376
377
378
379
380
381
   list_for_each_entry_safe(struct radv_cmd_buffer_upload, up, &cmd_buffer->upload.list, list)
   {
      cmd_buffer->device->ws->buffer_destroy(cmd_buffer->device->ws, up->upload_bo);
      list_del(&up->list);
      free(up);
   }
382

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
383
384
   if (cmd_buffer->upload.upload_bo)
      cmd_buffer->device->ws->buffer_destroy(cmd_buffer->device->ws, cmd_buffer->upload.upload_bo);
385

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
386
387
   if (cmd_buffer->cs)
      cmd_buffer->device->ws->cs_destroy(cmd_buffer->cs);
388

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
389
390
   for (unsigned i = 0; i < MAX_BIND_POINTS; i++)
      free(cmd_buffer->descriptors[i].push_set.set.mapped_ptr);
391

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
392
393
   vk_object_base_finish(&cmd_buffer->base);
   vk_free(&cmd_buffer->pool->alloc, cmd_buffer);
394
395
}

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
396
397
398
static VkResult
radv_create_cmd_buffer(struct radv_device *device, struct radv_cmd_pool *pool,
                       VkCommandBufferLevel level, VkCommandBuffer *pCommandBuffer)
399
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
400
401
402
403
404
   struct radv_cmd_buffer *cmd_buffer;
   unsigned ring;
   cmd_buffer = vk_zalloc(&pool->alloc, sizeof(*cmd_buffer), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
   if (cmd_buffer == NULL)
      return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
405

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
406
   vk_object_base_init(&device->vk, &cmd_buffer->base, VK_OBJECT_TYPE_COMMAND_BUFFER);
407

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
408
409
410
   cmd_buffer->device = device;
   cmd_buffer->pool = pool;
   cmd_buffer->level = level;
411

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
412
413
   list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers);
   cmd_buffer->queue_family_index = pool->queue_family_index;
414

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
415
   ring = radv_queue_family_to_ring(cmd_buffer->queue_family_index);
416

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
417
418
419
420
421
   cmd_buffer->cs = device->ws->cs_create(device->ws, ring);
   if (!cmd_buffer->cs) {
      radv_destroy_cmd_buffer(cmd_buffer);
      return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
   }
422

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
423
   *pCommandBuffer = radv_cmd_buffer_to_handle(cmd_buffer);
424

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
425
   list_inithead(&cmd_buffer->upload.list);
426

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
427
   return VK_SUCCESS;
428
429
}

430
431
static VkResult
radv_reset_cmd_buffer(struct radv_cmd_buffer *cmd_buffer)
432
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
   cmd_buffer->device->ws->cs_reset(cmd_buffer->cs);

   list_for_each_entry_safe(struct radv_cmd_buffer_upload, up, &cmd_buffer->upload.list, list)
   {
      cmd_buffer->device->ws->buffer_destroy(cmd_buffer->device->ws, up->upload_bo);
      list_del(&up->list);
      free(up);
   }

   cmd_buffer->push_constant_stages = 0;
   cmd_buffer->scratch_size_per_wave_needed = 0;
   cmd_buffer->scratch_waves_wanted = 0;
   cmd_buffer->compute_scratch_size_per_wave_needed = 0;
   cmd_buffer->compute_scratch_waves_wanted = 0;
   cmd_buffer->esgs_ring_size_needed = 0;
   cmd_buffer->gsvs_ring_size_needed = 0;
   cmd_buffer->tess_rings_needed = false;
   cmd_buffer->gds_needed = false;
   cmd_buffer->gds_oa_needed = false;
   cmd_buffer->sample_positions_needed = false;

   if (cmd_buffer->upload.upload_bo)
      radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs, cmd_buffer->upload.upload_bo);
   cmd_buffer->upload.offset = 0;

   cmd_buffer->record_result = VK_SUCCESS;

   memset(cmd_buffer->vertex_bindings, 0, sizeof(cmd_buffer->vertex_bindings));

   for (unsigned i = 0; i < MAX_BIND_POINTS; i++) {
      cmd_buffer->descriptors[i].dirty = 0;
      cmd_buffer->descriptors[i].valid = 0;
      cmd_buffer->descriptors[i].push_dirty = false;
   }

   if (cmd_buffer->device->physical_device->rad_info.chip_class >= GFX9 &&
       cmd_buffer->queue_family_index == RADV_QUEUE_GENERAL) {
      unsigned num_db = cmd_buffer->device->physical_device->rad_info.max_render_backends;
      unsigned fence_offset, eop_bug_offset;
      void *fence_ptr;

      radv_cmd_buffer_upload_alloc(cmd_buffer, 8, &fence_offset, &fence_ptr);
      memset(fence_ptr, 0, 8);

      cmd_buffer->gfx9_fence_va = radv_buffer_get_va(cmd_buffer->upload.upload_bo);
      cmd_buffer->gfx9_fence_va += fence_offset;

      if (cmd_buffer->device->physical_device->rad_info.chip_class == GFX9) {
         /* Allocate a buffer for the EOP bug on GFX9. */
         radv_cmd_buffer_upload_alloc(cmd_buffer, 16 * num_db, &eop_bug_offset, &fence_ptr);
         memset(fence_ptr, 0, 16 * num_db);
         cmd_buffer->gfx9_eop_bug_va = radv_buffer_get_va(cmd_buffer->upload.upload_bo);
         cmd_buffer->gfx9_eop_bug_va += eop_bug_offset;
      }
   }

   cmd_buffer->status = RADV_CMD_BUFFER_STATUS_INITIAL;

   return cmd_buffer->record_result;
492
493
}

494
static bool
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
495
496
497
498
499
500
501
502
503
504
radv_cmd_buffer_resize_upload_buf(struct radv_cmd_buffer *cmd_buffer, uint64_t min_needed)
{
   uint64_t new_size;
   struct radeon_winsys_bo *bo;
   struct radv_cmd_buffer_upload *upload;
   struct radv_device *device = cmd_buffer->device;

   new_size = MAX2(min_needed, 16 * 1024);
   new_size = MAX2(new_size, 2 * cmd_buffer->upload.size);

505
506
507
508
   bo = device->ws->buffer_create(device->ws, new_size, 4096, device->ws->cs_domain(device->ws),
                                  RADEON_FLAG_CPU_ACCESS | RADEON_FLAG_NO_INTERPROCESS_SHARING |
                                     RADEON_FLAG_32BIT | RADEON_FLAG_GTT_WC,
                                  RADV_BO_PRIORITY_UPLOAD_BUFFER);
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539

   if (!bo) {
      cmd_buffer->record_result = VK_ERROR_OUT_OF_DEVICE_MEMORY;
      return false;
   }

   radv_cs_add_buffer(device->ws, cmd_buffer->cs, bo);
   if (cmd_buffer->upload.upload_bo) {
      upload = malloc(sizeof(*upload));

      if (!upload) {
         cmd_buffer->record_result = VK_ERROR_OUT_OF_HOST_MEMORY;
         device->ws->buffer_destroy(device->ws, bo);
         return false;
      }

      memcpy(upload, &cmd_buffer->upload, sizeof(*upload));
      list_add(&upload->list, &cmd_buffer->upload.list);
   }

   cmd_buffer->upload.upload_bo = bo;
   cmd_buffer->upload.size = new_size;
   cmd_buffer->upload.offset = 0;
   cmd_buffer->upload.map = device->ws->buffer_map(cmd_buffer->upload.upload_bo);

   if (!cmd_buffer->upload.map) {
      cmd_buffer->record_result = VK_ERROR_OUT_OF_DEVICE_MEMORY;
      return false;
   }

   return true;
540
541
542
}

bool
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
543
544
radv_cmd_buffer_upload_alloc(struct radv_cmd_buffer *cmd_buffer, unsigned size,
                             unsigned *out_offset, void **ptr)
545
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
546
   assert(size % 4 == 0);
547

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
548
   struct radeon_info *rad_info = &cmd_buffer->device->physical_device->rad_info;
549

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
550
551
552
553
554
555
556
557
   /* Align to the scalar cache line size if it results in this allocation
    * being placed in less of them.
    */
   unsigned offset = cmd_buffer->upload.offset;
   unsigned line_size = rad_info->chip_class >= GFX10 ? 64 : 32;
   unsigned gap = align(offset, line_size) - offset;
   if ((size & (line_size - 1)) > gap)
      offset = align(offset, line_size);
558

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
559
560
561
562
563
   if (offset + size > cmd_buffer->upload.size) {
      if (!radv_cmd_buffer_resize_upload_buf(cmd_buffer, size))
         return false;
      offset = 0;
   }
564

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
565
566
   *out_offset = offset;
   *ptr = cmd_buffer->upload.map + offset;
567

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
568
569
   cmd_buffer->upload.offset = offset + size;
   return true;
570
571
572
}

bool
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
573
574
radv_cmd_buffer_upload_data(struct radv_cmd_buffer *cmd_buffer, unsigned size, const void *data,
                            unsigned *out_offset)
575
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
576
   uint8_t *ptr;
577

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
578
579
   if (!radv_cmd_buffer_upload_alloc(cmd_buffer, size, out_offset, (void **)&ptr))
      return false;
580

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
581
582
   if (ptr)
      memcpy(ptr, data, size);
583

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
584
   return true;
585
586
}

587
static void
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
588
589
radv_emit_write_data_packet(struct radv_cmd_buffer *cmd_buffer, uint64_t va, unsigned count,
                            const uint32_t *data)
590
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
591
   struct radeon_cmdbuf *cs = cmd_buffer->cs;
592

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
593
   radeon_check_space(cmd_buffer->device->ws, cs, 4 + count);
594

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
595
596
597
598
599
   radeon_emit(cs, PKT3(PKT3_WRITE_DATA, 2 + count, 0));
   radeon_emit(cs, S_370_DST_SEL(V_370_MEM) | S_370_WR_CONFIRM(1) | S_370_ENGINE_SEL(V_370_ME));
   radeon_emit(cs, va);
   radeon_emit(cs, va >> 32);
   radeon_emit_array(cs, data, count);
600
601
}

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
602
603
void
radv_cmd_buffer_trace_emit(struct radv_cmd_buffer *cmd_buffer)
604
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
605
606
607
   struct radv_device *device = cmd_buffer->device;
   struct radeon_cmdbuf *cs = cmd_buffer->cs;
   uint64_t va;
608

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
609
610
611
   va = radv_buffer_get_va(device->trace_bo);
   if (cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY)
      va += 4;
612

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
613
614
   ++cmd_buffer->state.trace_id;
   radv_emit_write_data_packet(cmd_buffer, va, 1, &cmd_buffer->state.trace_id);
615

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
616
   radeon_check_space(cmd_buffer->device->ws, cs, 2);
617

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
618
619
   radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
   radeon_emit(cs, AC_ENCODE_TRACE_POINT(cmd_buffer->state.trace_id));
620
621
}

622
static void
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
623
radv_cmd_buffer_after_draw(struct radv_cmd_buffer *cmd_buffer, enum radv_cmd_flush_bits flags)
624
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
625
626
627
628
   if (unlikely(cmd_buffer->device->thread_trace.bo)) {
      radeon_emit(cmd_buffer->cs, PKT3(PKT3_EVENT_WRITE, 0, 0));
      radeon_emit(cmd_buffer->cs, EVENT_TYPE(V_028A90_THREAD_TRACE_MARKER) | EVENT_INDEX(0));
   }
629

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
630
631
632
   if (cmd_buffer->device->instance->debug_flags & RADV_DEBUG_SYNC_SHADERS) {
      enum rgp_flush_bits sqtt_flush_bits = 0;
      assert(flags & (RADV_CMD_FLAG_PS_PARTIAL_FLUSH | RADV_CMD_FLAG_CS_PARTIAL_FLUSH));
633

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
634
      radeon_check_space(cmd_buffer->device->ws, cmd_buffer->cs, 4);
635

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
636
637
638
639
640
641
642
      /* Force wait for graphics or compute engines to be idle. */
      si_cs_emit_cache_flush(cmd_buffer->cs,
                             cmd_buffer->device->physical_device->rad_info.chip_class,
                             &cmd_buffer->gfx9_fence_idx, cmd_buffer->gfx9_fence_va,
                             radv_cmd_buffer_uses_mec(cmd_buffer), flags, &sqtt_flush_bits,
                             cmd_buffer->gfx9_eop_bug_va);
   }
643

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
644
645
   if (unlikely(cmd_buffer->device->trace_bo))
      radv_cmd_buffer_trace_emit(cmd_buffer);
646
647
}

648
static void
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
649
radv_save_pipeline(struct radv_cmd_buffer *cmd_buffer, struct radv_pipeline *pipeline)
650
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
651
652
653
654
   struct radv_device *device = cmd_buffer->device;
   enum ring_type ring;
   uint32_t data[2];
   uint64_t va;
655

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
656
   va = radv_buffer_get_va(device->trace_bo);
657

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
658
   ring = radv_queue_family_to_ring(cmd_buffer->queue_family_index);
659

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
660
661
662
663
664
665
666
667
668
669
   switch (ring) {
   case RING_GFX:
      va += 8;
      break;
   case RING_COMPUTE:
      va += 16;
      break;
   default:
      assert(!"invalid ring type");
   }
670

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
671
672
673
   uint64_t pipeline_address = (uintptr_t)pipeline;
   data[0] = pipeline_address;
   data[1] = pipeline_address >> 32;
674

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
675
   radv_emit_write_data_packet(cmd_buffer, va, 2, data);
676
677
}

678
static void
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
679
radv_save_vertex_descriptors(struct radv_cmd_buffer *cmd_buffer, uint64_t vb_ptr)
680
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
681
682
683
   struct radv_device *device = cmd_buffer->device;
   uint32_t data[2];
   uint64_t va;
684

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
685
686
   va = radv_buffer_get_va(device->trace_bo);
   va += 24;
687

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
688
689
   data[0] = vb_ptr;
   data[1] = vb_ptr >> 32;
690

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
691
   radv_emit_write_data_packet(cmd_buffer, va, 2, data);
692
693
}

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
694
695
696
void
radv_set_descriptor_set(struct radv_cmd_buffer *cmd_buffer, VkPipelineBindPoint bind_point,
                        struct radv_descriptor_set *set, unsigned idx)
697
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
698
699
   struct radv_descriptor_state *descriptors_state =
      radv_get_descriptors_state(cmd_buffer, bind_point);
700

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
701
   descriptors_state->sets[idx] = set;
702

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
703
704
   descriptors_state->valid |= (1u << idx); /* active descriptors */
   descriptors_state->dirty |= (1u << idx);
705
706
}

707
static void
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
708
radv_save_descriptors(struct radv_cmd_buffer *cmd_buffer, VkPipelineBindPoint bind_point)
709
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
710
711
712
713
714
715
   struct radv_descriptor_state *descriptors_state =
      radv_get_descriptors_state(cmd_buffer, bind_point);
   struct radv_device *device = cmd_buffer->device;
   uint32_t data[MAX_SETS * 2] = {0};
   uint64_t va;
   va = radv_buffer_get_va(device->trace_bo) + 32;
716

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
717
718
719
720
721
722
   u_foreach_bit(i, descriptors_state->valid)
   {
      struct radv_descriptor_set *set = descriptors_state->sets[i];
      data[i * 2] = (uint64_t)(uintptr_t)set;
      data[i * 2 + 1] = (uint64_t)(uintptr_t)set >> 32;
   }
723

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
724
   radv_emit_write_data_packet(cmd_buffer, va, MAX_SETS * 2, data);
725
726
}

727
struct radv_userdata_info *
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
728
radv_lookup_user_sgpr(struct radv_pipeline *pipeline, gl_shader_stage stage, int idx)
729
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
730
731
   struct radv_shader_variant *shader = radv_get_shader(pipeline, stage);
   return &shader->info.user_sgprs_locs.shader_data[idx];
732
733
734
}

static void
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
735
736
radv_emit_userdata_address(struct radv_cmd_buffer *cmd_buffer, struct radv_pipeline *pipeline,
                           gl_shader_stage stage, int idx, uint64_t va)
737
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
738
739
740
741
   struct radv_userdata_info *loc = radv_lookup_user_sgpr(pipeline, stage, idx);
   uint32_t base_reg = pipeline->user_data_0[stage];
   if (loc->sgpr_idx == -1)
      return;
742

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
743
   assert(loc->num_sgprs == 1);
744

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
745
746
   radv_emit_shader_pointer(cmd_buffer->device, cmd_buffer->cs, base_reg + loc->sgpr_idx * 4, va,
                            false);
747
748
}

749
static void
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
750
751
752
radv_emit_descriptor_pointers(struct radv_cmd_buffer *cmd_buffer, struct radv_pipeline *pipeline,
                              struct radv_descriptor_state *descriptors_state,
                              gl_shader_stage stage)
753
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
754
755
756
757
758
   struct radv_device *device = cmd_buffer->device;
   struct radeon_cmdbuf *cs = cmd_buffer->cs;
   uint32_t sh_base = pipeline->user_data_0[stage];
   struct radv_userdata_locations *locs = &pipeline->shaders[stage]->info.user_sgprs_locs;
   unsigned mask = locs->descriptor_sets_enabled;
759

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
760
   mask &= descriptors_state->dirty & descriptors_state->valid;
761

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
762
763
   while (mask) {
      int start, count;
764

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
765
      u_bit_scan_consecutive_range(&mask, &start, &count);
766

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
767
768
      struct radv_userdata_info *loc = &locs->descriptor_sets[start];
      unsigned sh_offset = sh_base + loc->sgpr_idx * 4;
769

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
770
771
772
      radv_emit_shader_pointer_head(cs, sh_offset, count, true);
      for (int i = 0; i < count; i++) {
         struct radv_descriptor_set *set = descriptors_state->sets[start + i];
773

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
774
775
776
         radv_emit_shader_pointer_body(device, cs, set->header.va, true);
      }
   }
777
778
}

779
780
781
782
783
/**
 * Convert the user sample locations to hardware sample locations (the values
 * that will be emitted by PA_SC_AA_SAMPLE_LOCS_PIXEL_*).
 */
static void
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
784
785
radv_convert_user_sample_locs(struct radv_sample_locations_state *state, uint32_t x, uint32_t y,
                              VkOffset2D *sample_locs)
786
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
787
788
789
790
791
   uint32_t x_offset = x % state->grid_size.width;
   uint32_t y_offset = y % state->grid_size.height;
   uint32_t num_samples = (uint32_t)state->per_pixel;
   VkSampleLocationEXT *user_locs;
   uint32_t pixel_offset;
792

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
793
   pixel_offset = (x_offset + y_offset * state->grid_size.width) * num_samples;
794

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
795
796
   assert(pixel_offset <= MAX_SAMPLE_LOCATIONS);
   user_locs = &state->locations[pixel_offset];
797

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
798
799
800
   for (uint32_t i = 0; i < num_samples; i++) {
      float shifted_pos_x = user_locs[i].x - 0.5;
      float shifted_pos_y = user_locs[i].y - 0.5;
801

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
802
803
      int32_t scaled_pos_x = floorf(shifted_pos_x * 16);
      int32_t scaled_pos_y = floorf(shifted_pos_y * 16);
804

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
805
806
807
      sample_locs[i].x = CLAMP(scaled_pos_x, -8, 7);
      sample_locs[i].y = CLAMP(scaled_pos_y, -8, 7);
   }
808
809
810
811
812
813
814
815
}

/**
 * Compute the PA_SC_AA_SAMPLE_LOCS_PIXEL_* mask based on hardware sample
 * locations.
 */
static void
radv_compute_sample_locs_pixel(uint32_t num_samples, VkOffset2D *sample_locs,
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
816
                               uint32_t *sample_locs_pixel)
817
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
818
819
820
821
822
   for (uint32_t i = 0; i < num_samples; i++) {
      uint32_t sample_reg_idx = i / 4;
      uint32_t sample_loc_idx = i % 4;
      int32_t pos_x = sample_locs[i].x;
      int32_t pos_y = sample_locs[i].y;
823

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
824
825
      uint32_t shift_x = 8 * sample_loc_idx;
      uint32_t shift_y = shift_x + 4;
826

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
827
828
829
      sample_locs_pixel[sample_reg_idx] |= (pos_x & 0xf) << shift_x;
      sample_locs_pixel[sample_reg_idx] |= (pos_y & 0xf) << shift_y;
   }
830
831
832
833
834
835
836
}

/**
 * Compute the PA_SC_CENTROID_PRIORITY_* mask based on the top left hardware
 * sample locations.
 */
static uint64_t
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
837
838
radv_compute_centroid_priority(struct radv_cmd_buffer *cmd_buffer, VkOffset2D *sample_locs,
                               uint32_t num_samples)
839
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
840
841
842
843
   uint32_t *centroid_priorities = alloca(num_samples * sizeof(*centroid_priorities));
   uint32_t sample_mask = num_samples - 1;
   uint32_t *distances = alloca(num_samples * sizeof(*distances));
   uint64_t centroid_priority = 0;
844

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
845
846
847
848
   /* Compute the distances from center for each sample. */
   for (int i = 0; i < num_samples; i++) {
      distances[i] = (sample_locs[i].x * sample_locs[i].x) + (sample_locs[i].y * sample_locs[i].y);
   }
849

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
850
851
852
   /* Compute the centroid priorities by looking at the distances array. */
   for (int i = 0; i < num_samples; i++) {
      uint32_t min_idx = 0;
853

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
854
855
856
857
      for (int j = 1; j < num_samples; j++) {
         if (distances[j] < distances[min_idx])
            min_idx = j;
      }
858

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
859
860
861
      centroid_priorities[i] = min_idx;
      distances[min_idx] = 0xffffffff;
   }
862

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
863
864
865
866
   /* Compute the final centroid priority. */
   for (int i = 0; i < 8; i++) {
      centroid_priority |= centroid_priorities[i & sample_mask] << (i * 4);
   }
867

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
868
   return centroid_priority << 32 | centroid_priority;
869
870
871
872
873
874
875
876
}

/**
 * Emit the sample locations that are specified with VK_EXT_sample_locations.
 */
static void
radv_emit_sample_locations(struct radv_cmd_buffer *cmd_buffer)
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
   struct radv_sample_locations_state *sample_location = &cmd_buffer->state.dynamic.sample_location;
   uint32_t num_samples = (uint32_t)sample_location->per_pixel;
   struct radeon_cmdbuf *cs = cmd_buffer->cs;
   uint32_t sample_locs_pixel[4][2] = {0};
   VkOffset2D sample_locs[4][8]; /* 8 is the max. sample count supported */
   uint32_t max_sample_dist = 0;
   uint64_t centroid_priority;

   if (!cmd_buffer->state.dynamic.sample_location.count)
      return;

   /* Convert the user sample locations to hardware sample locations. */
   radv_convert_user_sample_locs(sample_location, 0, 0, sample_locs[0]);
   radv_convert_user_sample_locs(sample_location, 1, 0, sample_locs[1]);
   radv_convert_user_sample_locs(sample_location, 0, 1, sample_locs[2]);
   radv_convert_user_sample_locs(sample_location, 1, 1, sample_locs[3]);

   /* Compute the PA_SC_AA_SAMPLE_LOCS_PIXEL_* mask. */
   for (uint32_t i = 0; i < 4; i++) {
      radv_compute_sample_locs_pixel(num_samples, sample_locs[i], sample_locs_pixel[i]);
   }

   /* Compute the PA_SC_CENTROID_PRIORITY_* mask. */
   centroid_priority = radv_compute_centroid_priority(cmd_buffer, sample_locs[0], num_samples);

   /* Compute the maximum sample distance from the specified locations. */
   for (unsigned i = 0; i < 4; ++i) {
      for (uint32_t j = 0; j < num_samples; j++) {
         VkOffset2D offset = sample_locs[i][j];
         max_sample_dist = MAX2(max_sample_dist, MAX2(abs(offset.x), abs(offset.y)));
      }
   }

   /* Emit the specified user sample locations. */
   switch (num_samples) {
   case 2:
   case 4:
      radeon_set_context_reg(cs, R_028BF8_PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0,
                             sample_locs_pixel[0][0]);
      radeon_set_context_reg(cs, R_028C08_PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0,
                             sample_locs_pixel[1][0]);
      radeon_set_context_reg(cs, R_028C18_PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0,
                             sample_locs_pixel[2][0]);
      radeon_set_context_reg(cs, R_028C28_PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0,
                             sample_locs_pixel[3][0]);
      break;
   case 8:
      radeon_set_context_reg(cs, R_028BF8_PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0,
                             sample_locs_pixel[0][0]);
      radeon_set_context_reg(cs, R_028C08_PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0,
                             sample_locs_pixel[1][0]);
      radeon_set_context_reg(cs, R_028C18_PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0,
                             sample_locs_pixel[2][0]);
      radeon_set_context_reg(cs, R_028C28_PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0,
                             sample_locs_pixel[3][0]);
      radeon_set_context_reg(cs, R_028BFC_PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_1,
                             sample_locs_pixel[0][1]);
      radeon_set_context_reg(cs, R_028C0C_PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_1,
                             sample_locs_pixel[1][1]);
      radeon_set_context_reg(cs, R_028C1C_PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_1,
                             sample_locs_pixel[2][1]);
      radeon_set_context_reg(cs, R_028C2C_PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1,
                             sample_locs_pixel[3][1]);
      break;
   default:
      unreachable("invalid number of samples");
   }

   /* Emit the maximum sample distance and the centroid priority. */
   radeon_set_context_reg_rmw(cs, R_028BE0_PA_SC_AA_CONFIG,
                              S_028BE0_MAX_SAMPLE_DIST(max_sample_dist), ~C_028BE0_MAX_SAMPLE_DIST);

   radeon_set_context_reg_seq(cs, R_028BD4_PA_SC_CENTROID_PRIORITY_0, 2);
   radeon_emit(cs, centroid_priority);
   radeon_emit(cs, centroid_priority >> 32);

   cmd_buffer->state.context_roll_without_scissor_emitted = true;
954
955
}

956
static void
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
957
958
radv_emit_inline_push_consts(struct radv_cmd_buffer *cmd_buffer, struct radv_pipeline *pipeline,
                             gl_shader_stage stage, int idx, int count, uint32_t *values)
959
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
960
961
962
963
   struct radv_userdata_info *loc = radv_lookup_user_sgpr(pipeline, stage, idx);
   uint32_t base_reg = pipeline->user_data_0[stage];
   if (loc->sgpr_idx == -1)
      return;
964

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
965
   assert(loc->num_sgprs == count);
966

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
967
968
   radeon_set_sh_reg_seq(cmd_buffer->cs, base_reg + loc->sgpr_idx * 4, count);
   radeon_emit_array(cmd_buffer->cs, values, count);
969
970
}

971
static void
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
972
radv_update_multisample_state(struct radv_cmd_buffer *cmd_buffer, struct radv_pipeline *pipeline)
973
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
974
975
   int num_samples = pipeline->graphics.ms.num_samples;
   struct radv_pipeline *old_pipeline = cmd_buffer->state.emitted_pipeline;
976

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
977
978
   if (pipeline->shaders[MESA_SHADER_FRAGMENT]->info.ps.needs_sample_positions)
      cmd_buffer->sample_positions_needed = true;
979

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
980
981
   if (old_pipeline && num_samples == old_pipeline->graphics.ms.num_samples)
      return;
982

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
983
   radv_emit_default_sample_locations(cmd_buffer->cs, num_samples);
984

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
985
   cmd_buffer->state.context_roll_without_scissor_emitted = true;
986
987
}

988
static void
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
989
radv_update_binning_state(struct radv_cmd_buffer *cmd_buffer, struct radv_pipeline *pipeline)
990
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
991
   const struct radv_pipeline *old_pipeline = cmd_buffer->state.emitted_pipeline;
992

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
993
994
   if (pipeline->device->physical_device->rad_info.chip_class < GFX9)
      return;
995

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
996
997
   if (old_pipeline &&
       old_pipeline->graphics.binning.pa_sc_binner_cntl_0 ==
Samuel Pitoiset's avatar
Samuel Pitoiset committed
998
          pipeline->graphics.binning.pa_sc_binner_cntl_0)
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
999
      return;
1000

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1001
1002
1003
1004
1005
1006
1007
1008
1009
   bool binning_flush = false;
   if (cmd_buffer->device->physical_device->rad_info.family == CHIP_VEGA12 ||
       cmd_buffer->device->physical_device->rad_info.family == CHIP_VEGA20 ||
       cmd_buffer->device->physical_device->rad_info.family == CHIP_RAVEN2 ||
       cmd_buffer->device->physical_device->rad_info.chip_class >= GFX10) {
      binning_flush = !old_pipeline ||
                      G_028C44_BINNING_MODE(old_pipeline->graphics.binning.pa_sc_binner_cntl_0) !=
                         G_028C44_BINNING_MODE(pipeline->graphics.binning.pa_sc_binner_cntl_0);
   }
1010

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1011
1012
1013
   radeon_set_context_reg(cmd_buffer->cs, R_028C44_PA_SC_BINNER_CNTL_0,
                          pipeline->graphics.binning.pa_sc_binner_cntl_0 |
                             S_028C44_FLUSH_ON_BINNING_TRANSITION(!!binning_flush));
1014

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1015
   cmd_buffer->state.context_roll_without_scissor_emitted = true;
1016
1017
}

1018
static void
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1019
radv_emit_shader_prefetch(struct radv_cmd_buffer *cmd_buffer, struct radv_shader_variant *shader)
1020
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1021
   uint64_t va;
1022

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1023
1024
   if (!shader)
      return;
1025

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1026
   va = radv_buffer_get_va(shader->bo) + shader->bo_offset;
1027

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1028
   si_cp_dma_prefetch(cmd_buffer, va, shader->code_size);
1029
1030
}

1031
static void
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1032
1033
radv_emit_prefetch_L2(struct radv_cmd_buffer *cmd_buffer, struct radv_pipeline *pipeline,
                      bool vertex_stage_only)
1034
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1035
1036
   struct radv_cmd_state *state = &cmd_buffer->state;
   uint32_t mask = state->prefetch_L2_mask;
1037

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1038
1039
1040
1041
1042
   if (vertex_stage_only) {
      /* Fast prefetch path for starting draws as soon as possible.
       */
      mask = state->prefetch_L2_mask & (RADV_PREFETCH_VS | RADV_PREFETCH_VBO_DESCRIPTORS);
   }
1043

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1044
1045
   if (mask & RADV_PREFETCH_VS)
      radv_emit_shader_prefetch(cmd_buffer, pipeline->shaders[MESA_SHADER_VERTEX]);
1046

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1047
1048
   if (mask & RADV_PREFETCH_VBO_DESCRIPTORS)
      si_cp_dma_prefetch(cmd_buffer, state->vb_va, state->vb_size);
1049

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1050
1051
   if (mask & RADV_PREFETCH_TCS)
      radv_emit_shader_prefetch(cmd_buffer, pipeline->shaders[MESA_SHADER_TESS_CTRL]);
1052

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1053
1054
   if (mask & RADV_PREFETCH_TES)
      radv_emit_shader_prefetch(cmd_buffer, pipeline->shaders[MESA_SHADER_TESS_EVAL]);
1055

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1056
1057
1058
1059
1060
   if (mask & RADV_PREFETCH_GS) {
      radv_emit_shader_prefetch(cmd_buffer, pipeline->shaders[MESA_SHADER_GEOMETRY]);
      if (radv_pipeline_has_gs_copy_shader(pipeline))
         radv_emit_shader_prefetch(cmd_buffer, pipeline->gs_copy_shader);
   }
1061

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1062
1063
   if (mask & RADV_PREFETCH_PS)
      radv_emit_shader_prefetch(cmd_buffer, pipeline->shaders[MESA_SHADER_FRAGMENT]);
1064

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1065
   state->prefetch_L2_mask &= ~mask;
1066
1067
}

1068
1069
1070
static void
radv_emit_rbplus_state(struct radv_cmd_buffer *cmd_buffer)
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
   if (!cmd_buffer->device->physical_device->rad_info.rbplus_allowed)
      return;

   struct radv_pipeline *pipeline = cmd_buffer->state.pipeline;
   const struct radv_subpass *subpass = cmd_buffer->state.subpass;

   unsigned sx_ps_downconvert = 0;
   unsigned sx_blend_opt_epsilon = 0;
   unsigned sx_blend_opt_control = 0;

   if (!cmd_buffer->state.attachments || !subpass)
      return;

   for (unsigned i = 0; i < subpass->color_count; ++i) {
      if (subpass->color_attachments[i].attachment == VK_ATTACHMENT_UNUSED) {
         /* We don't set the DISABLE bits, because the HW can't have holes,
          * so the SPI color format is set to 32-bit 1-component. */
         sx_ps_downconvert |= V_028754_SX_RT_EXPORT_32_R << (i * 4);
         continue;
      }

      int idx = subpass->color_attachments[i].attachment;
      struct radv_color_buffer_info *cb = &cmd_buffer->state.attachments[idx].cb;

      unsigned format = G_028C70_FORMAT(cb->cb_color_info);
      unsigned swap = G_028C70_COMP_SWAP(cb->cb_color_info);
      uint32_t spi_format = (pipeline->graphics.col_format >> (i * 4)) & 0xf;
      uint32_t colormask = (pipeline->graphics.cb_target_mask >> (i * 4)) & 0xf;

      bool has_alpha, has_rgb;

      /* Set if RGB and A are present. */
      has_alpha = !G_028C74_FORCE_DST_ALPHA_1(cb->cb_color_attrib);

      if (format == V_028C70_COLOR_8 || format == V_028C70_COLOR_16 || format == V_028C70_COLOR_32)
         has_rgb = !has_alpha;
      else
         has_rgb = true;

      /* Check the colormask and export format. */
      if (!(colormask & 0x7))
         has_rgb = false;
      if (!(colormask & 0x8))
         has_alpha = false;

      if (spi_format == V_028714_SPI_SHADER_ZERO) {
         has_rgb = false;
         has_alpha = false;
      }

      /* The HW doesn't quite blend correctly with rgb9e5 if we disable the alpha
       * optimization, even though it has no alpha. */
      if (has_rgb && format == V_028C70_COLOR_5_9_9_9)
         has_alpha = true;

      /* Disable value checking for disabled channels. */
      if (!has_rgb)
         sx_blend_opt_control |= S_02875C_MRT0_COLOR_OPT_DISABLE(1) << (i * 4);
      if (!has_alpha)
         sx_blend_opt_control |= S_02875C_MRT0_ALPHA_OPT_DISABLE(1) << (i * 4);

      /* Enable down-conversion for 32bpp and smaller formats. */
      switch (format) {
      case V_028C70_COLOR_8:
      case V_028C70_COLOR_8_8:
      case V_028C70_COLOR_8_8_8_8:
         /* For 1 and 2-channel formats, use the superset thereof. */
         if (spi_format == V_028714_SPI_SHADER_FP16_ABGR ||
             spi_format == V_028714_SPI_SHADER_UINT16_ABGR ||
             spi_format == V_028714_SPI_SHADER_SINT16_ABGR) {
            sx_ps_downconvert |= V_028754_SX_RT_EXPORT_8_8_8_8 << (i * 4);
            sx_blend_opt_epsilon |= V_028758_8BIT_FORMAT << (i * 4);
         }
         break;

      case V_028C70_COLOR_5_6_5:
         if (spi_format == V_028714_SPI_SHADER_FP16_ABGR) {
            sx_ps_downconvert |= V_028754_SX_RT_EXPORT_5_6_5 << (i * 4);
            sx_blend_opt_epsilon |= V_028758_6BIT_FORMAT << (i * 4);
         }
         break;

      case V_028C70_COLOR_1_5_5_5:
         if (spi_format == V_028714_SPI_SHADER_FP16_ABGR) {
            sx_ps_downconvert |= V_028754_SX_RT_EXPORT_1_5_5_5 << (i * 4);
            sx_blend_opt_epsilon |= V_028758_5BIT_FORMAT << (i * 4);
         }
         break;

      case V_028C70_COLOR_4_4_4_4:
         if (spi_format == V_028714_SPI_SHADER_FP16_ABGR) {
            sx_ps_downconvert |= V_028754_SX_RT_EXPORT_4_4_4_4 << (i * 4);
            sx_blend_opt_epsilon |= V_028758_4BIT_FORMAT << (i * 4);
         }
         break;

      case V_028C70_COLOR_32:
         if (swap == V_028C70_SWAP_STD && spi_format == V_028714_SPI_SHADER_32_R)
            sx_ps_downconvert |= V_028754_SX_RT_EXPORT_32_R << (i * 4);
         else if (swap == V_028C70_SWAP_ALT_REV && spi_format == V_028714_SPI_SHADER_32_AR)
            sx_ps_downconvert |= V_028754_SX_RT_EXPORT_32_A << (i * 4);
         break;

      case V_028C70_COLOR_16:
      case V_028C70_COLOR_16_16:
         /* For 1-channel formats, use the superset thereof. */
         if (spi_format == V_028714_SPI_SHADER_UNORM16_ABGR ||
             spi_format == V_028714_SPI_SHADER_SNORM16_ABGR ||
             spi_format == V_028714_SPI_SHADER_UINT16_ABGR ||
             spi_format == V_028714_SPI_SHADER_SINT16_ABGR) {
            if (swap == V_028C70_SWAP_STD || swap == V_028C70_SWAP_STD_REV)
               sx_ps_downconvert |= V_028754_SX_RT_EXPORT_16_16_GR << (i * 4);
            else
               sx_ps_downconvert |= V_028754_SX_RT_EXPORT_16_16_AR << (i * 4);
         }
         break;

      case V_028C70_COLOR_10_11_11:
         if (spi_format == V_028714_SPI_SHADER_FP16_ABGR)
            sx_ps_downconvert |= V_028754_SX_RT_EXPORT_10_11_11 << (i * 4);
         break;

      case V_028C70_COLOR_2_10_10_10:
         if (spi_format == V_028714_SPI_SHADER_FP16_ABGR) {
            sx_ps_downconvert |= V_028754_SX_RT_EXPORT_2_10_10_10 << (i * 4);
            sx_blend_opt_epsilon |= V_028758_10BIT_FORMAT << (i * 4);
         }
         break;
      case V_028C70_COLOR_5_9_9_9:
         if (spi_format == V_028714_SPI_SHADER_FP16_ABGR)
            sx_ps_downconvert |= V_028754_SX_RT_EXPORT_9_9_9_E5 << (i * 4);
         break;
      }
   }

   /* Do not set the DISABLE bits for the unused attachments, as that
    * breaks dual source blending in SkQP and does not seem to improve
    * performance. */

   if (sx_ps_downconvert == cmd_buffer->state.last_sx_ps_downconvert &&
       sx_blend_opt_epsilon == cmd_buffer->state.last_sx_blend_opt_epsilon &&
       sx_blend_opt_control == cmd_buffer->state.last_sx_blend_opt_control)
      return;

   radeon_set_context_reg_seq(cmd_buffer->cs, R_028754_SX_PS_DOWNCONVERT, 3);
   radeon_emit(cmd_buffer->cs, sx_ps_downconvert);
   radeon_emit(cmd_buffer->cs, sx_blend_opt_epsilon);
   radeon_emit(cmd_buffer->cs, sx_blend_opt_control);

   cmd_buffer->state.context_roll_without_scissor_emitted = true;

   cmd_buffer->state.last_sx_ps_downconvert = sx_ps_downconvert;
   cmd_buffer->state.last_sx_blend_opt_epsilon = sx_blend_opt_epsilon;
   cmd_buffer->state.last_sx_blend_opt_control = sx_blend_opt_control;
1225
1226
}

1227
1228
1229
static void
radv_emit_batch_break_on_new_ps(struct radv_cmd_buffer *cmd_buffer)
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1230
1231
   if (!cmd_buffer->device->pbb_allowed)
      return;
1232

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
   struct radv_binning_settings settings =
      radv_get_binning_settings(cmd_buffer->device->physical_device);
   bool break_for_new_ps =
      (!cmd_buffer->state.emitted_pipeline ||
       cmd_buffer->state.emitted_pipeline->shaders[MESA_SHADER_FRAGMENT] !=
          cmd_buffer->state.pipeline->shaders[MESA_SHADER_FRAGMENT]) &&
      (settings.context_states_per_bin > 1 || settings.persistent_states_per_bin > 1);
   bool break_for_new_cb_target_mask =
      (!cmd_buffer->state.emitted_pipeline ||
       cmd_buffer->state.emitted_pipeline->graphics.cb_target_mask !=
          cmd_buffer->state.pipeline->graphics.cb_target_mask) &&
      settings.context_states_per_bin > 1;
1245

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1246
1247
   if (!break_for_new_ps && !break_for_new_cb_target_mask)
      return;
1248

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1249
1250
   radeon_emit(cmd_buffer->cs, PKT3(PKT3_EVENT_WRITE, 0, 0));
   radeon_emit(cmd_buffer->cs, EVENT_TYPE(V_028A90_BREAK_BATCH) | EVENT_INDEX(0));
1251
1252
}

1253
static void
1254
radv_emit_graphics_pipeline(struct radv_cmd_buffer *cmd_buffer)
1255
{
Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1256
   struct radv_pipeline *pipeline = cmd_buffer->state.pipeline;
1257

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1258
1259
   if (!pipeline || cmd_buffer->state.emitted_pipeline == pipeline)
      return;
1260

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1261
1262
   radv_update_multisample_state(cmd_buffer, pipeline);
   radv_update_binning_state(cmd_buffer, pipeline);
1263

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1264
1265
1266
   cmd_buffer->scratch_size_per_wave_needed =
      MAX2(cmd_buffer->scratch_size_per_wave_needed, pipeline->scratch_bytes_per_wave);
   cmd_buffer->scratch_waves_wanted = MAX2(cmd_buffer->scratch_waves_wanted, pipeline->max_waves);
1267

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1268
1269
1270
1271
   if (!cmd_buffer->state.emitted_pipeline ||
       cmd_buffer->state.emitted_pipeline->graphics.can_use_guardband !=
          pipeline->graphics.can_use_guardband)
      cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_SCISSOR;
1272

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1273
1274
1275
   if (!cmd_buffer->state.emitted_pipeline ||
       cmd_buffer->state.emitted_pipeline->graphics.pa_su_sc_mode_cntl !=
          pipeline->graphics.pa_su_sc_mode_cntl)
1276
1277
1278
      cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_CULL_MODE |
                                 RADV_CMD_DIRTY_DYNAMIC_FRONT_FACE |
                                 RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS;
1279

1280
1281
1282
1283
1284
   if (!cmd_buffer->state.emitted_pipeline ||
       cmd_buffer->state.emitted_pipeline->graphics.pa_cl_clip_cntl !=
          pipeline->graphics.pa_cl_clip_cntl)
      cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE;

Bas Nieuwenhuizen's avatar
Bas Nieuwenhuizen committed
1285
   if (!cmd_buffer->state.emitted_pipeline)
1286
      cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY |
1287
                                 RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS |
1288
1289
                                 RADV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS |
                                 RADV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE;