Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/intel/vulkan/anv_cmd_buffer.c
4547 views
1
/*
2
* Copyright © 2015 Intel Corporation
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
#include <assert.h>
25
#include <stdbool.h>
26
#include <string.h>
27
#include <unistd.h>
28
#include <fcntl.h>
29
30
#include "anv_private.h"
31
#include "anv_measure.h"
32
33
#include "vk_util.h"
34
35
/** \file anv_cmd_buffer.c
36
*
37
* This file contains all of the stuff for emitting commands into a command
38
* buffer. This includes implementations of most of the vkCmd*
39
* entrypoints. This file is concerned entirely with state emission and
40
* not with the command buffer data structure itself. As far as this file
41
* is concerned, most of anv_cmd_buffer is magic.
42
*/
43
44
/* TODO: These are taken from GLES. We should check the Vulkan spec */
45
const struct anv_dynamic_state default_dynamic_state = {
46
.viewport = {
47
.count = 0,
48
},
49
.scissor = {
50
.count = 0,
51
},
52
.line_width = 1.0f,
53
.depth_bias = {
54
.bias = 0.0f,
55
.clamp = 0.0f,
56
.slope = 0.0f,
57
},
58
.blend_constants = { 0.0f, 0.0f, 0.0f, 0.0f },
59
.depth_bounds = {
60
.min = 0.0f,
61
.max = 1.0f,
62
},
63
.stencil_compare_mask = {
64
.front = ~0u,
65
.back = ~0u,
66
},
67
.stencil_write_mask = {
68
.front = ~0u,
69
.back = ~0u,
70
},
71
.stencil_reference = {
72
.front = 0u,
73
.back = 0u,
74
},
75
.stencil_op = {
76
.front = {
77
.fail_op = 0,
78
.pass_op = 0,
79
.depth_fail_op = 0,
80
.compare_op = 0,
81
},
82
.back = {
83
.fail_op = 0,
84
.pass_op = 0,
85
.depth_fail_op = 0,
86
.compare_op = 0,
87
},
88
},
89
.line_stipple = {
90
.factor = 0u,
91
.pattern = 0u,
92
},
93
.cull_mode = 0,
94
.front_face = 0,
95
.primitive_topology = 0,
96
.depth_test_enable = 0,
97
.depth_write_enable = 0,
98
.depth_compare_op = 0,
99
.depth_bounds_test_enable = 0,
100
.stencil_test_enable = 0,
101
.dyn_vbo_stride = 0,
102
.dyn_vbo_size = 0,
103
.color_writes = 0xff,
104
.raster_discard = 0,
105
.depth_bias_enable = 0,
106
.primitive_restart_enable = 0,
107
.logic_op = 0,
108
};
109
110
/**
111
* Copy the dynamic state from src to dest based on the copy_mask.
112
*
113
* Avoid copying states that have not changed, except for VIEWPORT, SCISSOR and
114
* BLEND_CONSTANTS (always copy them if they are in the copy_mask).
115
*
116
* Returns a mask of the states which changed.
117
*/
118
anv_cmd_dirty_mask_t
119
anv_dynamic_state_copy(struct anv_dynamic_state *dest,
120
const struct anv_dynamic_state *src,
121
anv_cmd_dirty_mask_t copy_mask)
122
{
123
anv_cmd_dirty_mask_t changed = 0;
124
125
if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_VIEWPORT) {
126
dest->viewport.count = src->viewport.count;
127
typed_memcpy(dest->viewport.viewports, src->viewport.viewports,
128
src->viewport.count);
129
changed |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT;
130
}
131
132
if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_SCISSOR) {
133
dest->scissor.count = src->scissor.count;
134
typed_memcpy(dest->scissor.scissors, src->scissor.scissors,
135
src->scissor.count);
136
changed |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR;
137
}
138
139
if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS) {
140
typed_memcpy(dest->blend_constants, src->blend_constants, 4);
141
changed |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS;
142
}
143
144
#define ANV_CMP_COPY(field, flag) \
145
if (copy_mask & flag) { \
146
if (dest->field != src->field) { \
147
dest->field = src->field; \
148
changed |= flag; \
149
} \
150
}
151
152
ANV_CMP_COPY(line_width, ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH);
153
154
ANV_CMP_COPY(depth_bias.bias, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS);
155
ANV_CMP_COPY(depth_bias.clamp, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS);
156
ANV_CMP_COPY(depth_bias.slope, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS);
157
158
ANV_CMP_COPY(depth_bounds.min, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS);
159
ANV_CMP_COPY(depth_bounds.max, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS);
160
161
ANV_CMP_COPY(stencil_compare_mask.front, ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK);
162
ANV_CMP_COPY(stencil_compare_mask.back, ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK);
163
164
ANV_CMP_COPY(stencil_write_mask.front, ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK);
165
ANV_CMP_COPY(stencil_write_mask.back, ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK);
166
167
ANV_CMP_COPY(stencil_reference.front, ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE);
168
ANV_CMP_COPY(stencil_reference.back, ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE);
169
170
ANV_CMP_COPY(line_stipple.factor, ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE);
171
ANV_CMP_COPY(line_stipple.pattern, ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE);
172
173
ANV_CMP_COPY(cull_mode, ANV_CMD_DIRTY_DYNAMIC_CULL_MODE);
174
ANV_CMP_COPY(front_face, ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE);
175
ANV_CMP_COPY(primitive_topology, ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY);
176
ANV_CMP_COPY(depth_test_enable, ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE);
177
ANV_CMP_COPY(depth_write_enable, ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE);
178
ANV_CMP_COPY(depth_compare_op, ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP);
179
ANV_CMP_COPY(depth_bounds_test_enable, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE);
180
ANV_CMP_COPY(stencil_test_enable, ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE);
181
182
if (copy_mask & VK_DYNAMIC_STATE_STENCIL_OP_EXT) {
183
ANV_CMP_COPY(stencil_op.front.fail_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
184
ANV_CMP_COPY(stencil_op.front.pass_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
185
ANV_CMP_COPY(stencil_op.front.depth_fail_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
186
ANV_CMP_COPY(stencil_op.front.compare_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
187
ANV_CMP_COPY(stencil_op.back.fail_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
188
ANV_CMP_COPY(stencil_op.back.pass_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
189
ANV_CMP_COPY(stencil_op.back.depth_fail_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
190
ANV_CMP_COPY(stencil_op.back.compare_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
191
}
192
193
ANV_CMP_COPY(dyn_vbo_stride, ANV_CMD_DIRTY_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE);
194
ANV_CMP_COPY(dyn_vbo_size, ANV_CMD_DIRTY_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE);
195
196
ANV_CMP_COPY(raster_discard, ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE);
197
ANV_CMP_COPY(depth_bias_enable, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE);
198
ANV_CMP_COPY(primitive_restart_enable, ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE);
199
ANV_CMP_COPY(logic_op, ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP);
200
201
if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS) {
202
dest->sample_locations.samples = src->sample_locations.samples;
203
typed_memcpy(dest->sample_locations.locations,
204
src->sample_locations.locations,
205
dest->sample_locations.samples);
206
changed |= ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS;
207
}
208
209
ANV_CMP_COPY(color_writes, ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE);
210
211
ANV_CMP_COPY(fragment_shading_rate.width, ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE);
212
ANV_CMP_COPY(fragment_shading_rate.height, ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE);
213
214
#undef ANV_CMP_COPY
215
216
return changed;
217
}
218
219
static void
220
anv_cmd_state_init(struct anv_cmd_buffer *cmd_buffer)
221
{
222
struct anv_cmd_state *state = &cmd_buffer->state;
223
224
memset(state, 0, sizeof(*state));
225
226
state->current_pipeline = UINT32_MAX;
227
state->restart_index = UINT32_MAX;
228
state->gfx.dynamic = default_dynamic_state;
229
}
230
231
static void
232
anv_cmd_pipeline_state_finish(struct anv_cmd_buffer *cmd_buffer,
233
struct anv_cmd_pipeline_state *pipe_state)
234
{
235
for (uint32_t i = 0; i < ARRAY_SIZE(pipe_state->push_descriptors); i++) {
236
if (pipe_state->push_descriptors[i]) {
237
anv_descriptor_set_layout_unref(cmd_buffer->device,
238
pipe_state->push_descriptors[i]->set.layout);
239
vk_free(&cmd_buffer->pool->alloc, pipe_state->push_descriptors[i]);
240
}
241
}
242
}
243
244
static void
245
anv_cmd_state_finish(struct anv_cmd_buffer *cmd_buffer)
246
{
247
struct anv_cmd_state *state = &cmd_buffer->state;
248
249
anv_cmd_pipeline_state_finish(cmd_buffer, &state->gfx.base);
250
anv_cmd_pipeline_state_finish(cmd_buffer, &state->compute.base);
251
252
vk_free(&cmd_buffer->pool->alloc, state->attachments);
253
}
254
255
static void
256
anv_cmd_state_reset(struct anv_cmd_buffer *cmd_buffer)
257
{
258
anv_cmd_state_finish(cmd_buffer);
259
anv_cmd_state_init(cmd_buffer);
260
}
261
262
static VkResult anv_create_cmd_buffer(
263
struct anv_device * device,
264
struct anv_cmd_pool * pool,
265
VkCommandBufferLevel level,
266
VkCommandBuffer* pCommandBuffer)
267
{
268
struct anv_cmd_buffer *cmd_buffer;
269
VkResult result;
270
271
cmd_buffer = vk_object_alloc(&device->vk, &pool->alloc, sizeof(*cmd_buffer),
272
VK_OBJECT_TYPE_COMMAND_BUFFER);
273
if (cmd_buffer == NULL)
274
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
275
276
cmd_buffer->batch.status = VK_SUCCESS;
277
278
cmd_buffer->device = device;
279
cmd_buffer->pool = pool;
280
cmd_buffer->level = level;
281
282
result = anv_cmd_buffer_init_batch_bo_chain(cmd_buffer);
283
if (result != VK_SUCCESS)
284
goto fail;
285
286
anv_state_stream_init(&cmd_buffer->surface_state_stream,
287
&device->surface_state_pool, 4096);
288
anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
289
&device->dynamic_state_pool, 16384);
290
anv_state_stream_init(&cmd_buffer->general_state_stream,
291
&device->general_state_pool, 16384);
292
293
cmd_buffer->self_mod_locations = NULL;
294
295
anv_cmd_state_init(cmd_buffer);
296
297
list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers);
298
299
anv_measure_init(cmd_buffer);
300
301
*pCommandBuffer = anv_cmd_buffer_to_handle(cmd_buffer);
302
303
return VK_SUCCESS;
304
305
fail:
306
vk_free(&cmd_buffer->pool->alloc, cmd_buffer);
307
308
return result;
309
}
310
311
VkResult anv_AllocateCommandBuffers(
312
VkDevice _device,
313
const VkCommandBufferAllocateInfo* pAllocateInfo,
314
VkCommandBuffer* pCommandBuffers)
315
{
316
ANV_FROM_HANDLE(anv_device, device, _device);
317
ANV_FROM_HANDLE(anv_cmd_pool, pool, pAllocateInfo->commandPool);
318
319
VkResult result = VK_SUCCESS;
320
uint32_t i;
321
322
for (i = 0; i < pAllocateInfo->commandBufferCount; i++) {
323
result = anv_create_cmd_buffer(device, pool, pAllocateInfo->level,
324
&pCommandBuffers[i]);
325
if (result != VK_SUCCESS)
326
break;
327
}
328
329
if (result != VK_SUCCESS) {
330
anv_FreeCommandBuffers(_device, pAllocateInfo->commandPool,
331
i, pCommandBuffers);
332
for (i = 0; i < pAllocateInfo->commandBufferCount; i++)
333
pCommandBuffers[i] = VK_NULL_HANDLE;
334
}
335
336
return result;
337
}
338
339
static void
340
anv_cmd_buffer_destroy(struct anv_cmd_buffer *cmd_buffer)
341
{
342
anv_measure_destroy(cmd_buffer);
343
344
list_del(&cmd_buffer->pool_link);
345
346
anv_cmd_buffer_fini_batch_bo_chain(cmd_buffer);
347
348
anv_state_stream_finish(&cmd_buffer->surface_state_stream);
349
anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
350
anv_state_stream_finish(&cmd_buffer->general_state_stream);
351
352
anv_cmd_state_finish(cmd_buffer);
353
354
vk_free(&cmd_buffer->pool->alloc, cmd_buffer->self_mod_locations);
355
356
vk_object_free(&cmd_buffer->device->vk, &cmd_buffer->pool->alloc, cmd_buffer);
357
}
358
359
void anv_FreeCommandBuffers(
360
VkDevice device,
361
VkCommandPool commandPool,
362
uint32_t commandBufferCount,
363
const VkCommandBuffer* pCommandBuffers)
364
{
365
for (uint32_t i = 0; i < commandBufferCount; i++) {
366
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, pCommandBuffers[i]);
367
368
if (!cmd_buffer)
369
continue;
370
371
anv_cmd_buffer_destroy(cmd_buffer);
372
}
373
}
374
375
VkResult
376
anv_cmd_buffer_reset(struct anv_cmd_buffer *cmd_buffer)
377
{
378
cmd_buffer->usage_flags = 0;
379
cmd_buffer->perf_query_pool = NULL;
380
anv_cmd_buffer_reset_batch_bo_chain(cmd_buffer);
381
anv_cmd_state_reset(cmd_buffer);
382
383
anv_state_stream_finish(&cmd_buffer->surface_state_stream);
384
anv_state_stream_init(&cmd_buffer->surface_state_stream,
385
&cmd_buffer->device->surface_state_pool, 4096);
386
387
anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
388
anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
389
&cmd_buffer->device->dynamic_state_pool, 16384);
390
391
anv_state_stream_finish(&cmd_buffer->general_state_stream);
392
anv_state_stream_init(&cmd_buffer->general_state_stream,
393
&cmd_buffer->device->general_state_pool, 16384);
394
395
anv_measure_reset(cmd_buffer);
396
return VK_SUCCESS;
397
}
398
399
VkResult anv_ResetCommandBuffer(
400
VkCommandBuffer commandBuffer,
401
VkCommandBufferResetFlags flags)
402
{
403
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
404
return anv_cmd_buffer_reset(cmd_buffer);
405
}
406
407
void
408
anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer)
409
{
410
const struct intel_device_info *devinfo = &cmd_buffer->device->info;
411
anv_genX(devinfo, cmd_buffer_emit_state_base_address)(cmd_buffer);
412
}
413
414
void
415
anv_cmd_buffer_mark_image_written(struct anv_cmd_buffer *cmd_buffer,
416
const struct anv_image *image,
417
VkImageAspectFlagBits aspect,
418
enum isl_aux_usage aux_usage,
419
uint32_t level,
420
uint32_t base_layer,
421
uint32_t layer_count)
422
{
423
const struct intel_device_info *devinfo = &cmd_buffer->device->info;
424
anv_genX(devinfo, cmd_buffer_mark_image_written)(cmd_buffer, image,
425
aspect, aux_usage,
426
level, base_layer,
427
layer_count);
428
}
429
430
void
431
anv_cmd_emit_conditional_render_predicate(struct anv_cmd_buffer *cmd_buffer)
432
{
433
const struct intel_device_info *devinfo = &cmd_buffer->device->info;
434
anv_genX(devinfo, cmd_emit_conditional_render_predicate)(cmd_buffer);
435
}
436
437
static bool
438
mem_update(void *dst, const void *src, size_t size)
439
{
440
if (memcmp(dst, src, size) == 0)
441
return false;
442
443
memcpy(dst, src, size);
444
return true;
445
}
446
447
static void
448
set_dirty_for_bind_map(struct anv_cmd_buffer *cmd_buffer,
449
gl_shader_stage stage,
450
const struct anv_pipeline_bind_map *map)
451
{
452
assert(stage < ARRAY_SIZE(cmd_buffer->state.surface_sha1s));
453
if (mem_update(cmd_buffer->state.surface_sha1s[stage],
454
map->surface_sha1, sizeof(map->surface_sha1)))
455
cmd_buffer->state.descriptors_dirty |= mesa_to_vk_shader_stage(stage);
456
457
assert(stage < ARRAY_SIZE(cmd_buffer->state.sampler_sha1s));
458
if (mem_update(cmd_buffer->state.sampler_sha1s[stage],
459
map->sampler_sha1, sizeof(map->sampler_sha1)))
460
cmd_buffer->state.descriptors_dirty |= mesa_to_vk_shader_stage(stage);
461
462
assert(stage < ARRAY_SIZE(cmd_buffer->state.push_sha1s));
463
if (mem_update(cmd_buffer->state.push_sha1s[stage],
464
map->push_sha1, sizeof(map->push_sha1)))
465
cmd_buffer->state.push_constants_dirty |= mesa_to_vk_shader_stage(stage);
466
}
467
468
void anv_CmdBindPipeline(
469
VkCommandBuffer commandBuffer,
470
VkPipelineBindPoint pipelineBindPoint,
471
VkPipeline _pipeline)
472
{
473
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
474
ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline);
475
476
switch (pipelineBindPoint) {
477
case VK_PIPELINE_BIND_POINT_COMPUTE: {
478
struct anv_compute_pipeline *compute_pipeline =
479
anv_pipeline_to_compute(pipeline);
480
if (cmd_buffer->state.compute.pipeline == compute_pipeline)
481
return;
482
483
cmd_buffer->state.compute.pipeline = compute_pipeline;
484
cmd_buffer->state.compute.pipeline_dirty = true;
485
set_dirty_for_bind_map(cmd_buffer, MESA_SHADER_COMPUTE,
486
&compute_pipeline->cs->bind_map);
487
break;
488
}
489
490
case VK_PIPELINE_BIND_POINT_GRAPHICS: {
491
struct anv_graphics_pipeline *gfx_pipeline =
492
anv_pipeline_to_graphics(pipeline);
493
if (cmd_buffer->state.gfx.pipeline == gfx_pipeline)
494
return;
495
496
cmd_buffer->state.gfx.pipeline = gfx_pipeline;
497
cmd_buffer->state.gfx.vb_dirty |= gfx_pipeline->vb_used;
498
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_PIPELINE;
499
500
anv_foreach_stage(stage, gfx_pipeline->active_stages) {
501
set_dirty_for_bind_map(cmd_buffer, stage,
502
&gfx_pipeline->shaders[stage]->bind_map);
503
}
504
505
/* Apply the dynamic state from the pipeline */
506
cmd_buffer->state.gfx.dirty |=
507
anv_dynamic_state_copy(&cmd_buffer->state.gfx.dynamic,
508
&gfx_pipeline->dynamic_state,
509
gfx_pipeline->dynamic_state_mask);
510
break;
511
}
512
513
case VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR: {
514
struct anv_ray_tracing_pipeline *rt_pipeline =
515
anv_pipeline_to_ray_tracing(pipeline);
516
if (cmd_buffer->state.rt.pipeline == rt_pipeline)
517
return;
518
519
cmd_buffer->state.rt.pipeline = rt_pipeline;
520
cmd_buffer->state.rt.pipeline_dirty = true;
521
522
if (rt_pipeline->stack_size > 0) {
523
anv_CmdSetRayTracingPipelineStackSizeKHR(commandBuffer,
524
rt_pipeline->stack_size);
525
}
526
break;
527
}
528
529
default:
530
assert(!"invalid bind point");
531
break;
532
}
533
}
534
535
void anv_CmdSetRasterizerDiscardEnableEXT(
536
VkCommandBuffer commandBuffer,
537
VkBool32 rasterizerDiscardEnable)
538
{
539
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
540
541
cmd_buffer->state.gfx.dynamic.raster_discard = rasterizerDiscardEnable;
542
543
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE;
544
}
545
546
void anv_CmdSetDepthBiasEnableEXT(
547
VkCommandBuffer commandBuffer,
548
VkBool32 depthBiasEnable)
549
{
550
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
551
552
cmd_buffer->state.gfx.dynamic.depth_bias_enable = depthBiasEnable;
553
554
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE;
555
}
556
557
void anv_CmdSetPrimitiveRestartEnableEXT(
558
VkCommandBuffer commandBuffer,
559
VkBool32 primitiveRestartEnable)
560
{
561
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
562
563
cmd_buffer->state.gfx.dynamic.primitive_restart_enable = primitiveRestartEnable;
564
565
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE;
566
}
567
568
void anv_CmdSetLogicOpEXT(
569
VkCommandBuffer commandBuffer,
570
VkLogicOp logicOp)
571
{
572
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
573
574
cmd_buffer->state.gfx.dynamic.logic_op = logicOp;
575
576
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP;
577
}
578
579
void anv_CmdSetPatchControlPointsEXT(
580
VkCommandBuffer commandBuffer,
581
uint32_t patchControlPoints)
582
{
583
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
584
anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_FEATURE_NOT_PRESENT);
585
}
586
587
void anv_CmdSetViewport(
588
VkCommandBuffer commandBuffer,
589
uint32_t firstViewport,
590
uint32_t viewportCount,
591
const VkViewport* pViewports)
592
{
593
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
594
595
const uint32_t total_count = firstViewport + viewportCount;
596
if (cmd_buffer->state.gfx.dynamic.viewport.count < total_count)
597
cmd_buffer->state.gfx.dynamic.viewport.count = total_count;
598
599
memcpy(cmd_buffer->state.gfx.dynamic.viewport.viewports + firstViewport,
600
pViewports, viewportCount * sizeof(*pViewports));
601
602
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT;
603
}
604
605
void anv_CmdSetViewportWithCountEXT(
606
VkCommandBuffer commandBuffer,
607
uint32_t viewportCount,
608
const VkViewport* pViewports)
609
{
610
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
611
612
cmd_buffer->state.gfx.dynamic.viewport.count = viewportCount;
613
614
memcpy(cmd_buffer->state.gfx.dynamic.viewport.viewports,
615
pViewports, viewportCount * sizeof(*pViewports));
616
617
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT;
618
}
619
620
void anv_CmdSetScissor(
621
VkCommandBuffer commandBuffer,
622
uint32_t firstScissor,
623
uint32_t scissorCount,
624
const VkRect2D* pScissors)
625
{
626
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
627
628
const uint32_t total_count = firstScissor + scissorCount;
629
if (cmd_buffer->state.gfx.dynamic.scissor.count < total_count)
630
cmd_buffer->state.gfx.dynamic.scissor.count = total_count;
631
632
memcpy(cmd_buffer->state.gfx.dynamic.scissor.scissors + firstScissor,
633
pScissors, scissorCount * sizeof(*pScissors));
634
635
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR;
636
}
637
638
void anv_CmdSetScissorWithCountEXT(
639
VkCommandBuffer commandBuffer,
640
uint32_t scissorCount,
641
const VkRect2D* pScissors)
642
{
643
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
644
645
cmd_buffer->state.gfx.dynamic.scissor.count = scissorCount;
646
647
memcpy(cmd_buffer->state.gfx.dynamic.scissor.scissors,
648
pScissors, scissorCount * sizeof(*pScissors));
649
650
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR;
651
}
652
653
void anv_CmdSetPrimitiveTopologyEXT(
654
VkCommandBuffer commandBuffer,
655
VkPrimitiveTopology primitiveTopology)
656
{
657
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
658
659
cmd_buffer->state.gfx.dynamic.primitive_topology = primitiveTopology;
660
661
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY;
662
}
663
664
void anv_CmdSetLineWidth(
665
VkCommandBuffer commandBuffer,
666
float lineWidth)
667
{
668
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
669
670
cmd_buffer->state.gfx.dynamic.line_width = lineWidth;
671
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH;
672
}
673
674
void anv_CmdSetDepthBias(
675
VkCommandBuffer commandBuffer,
676
float depthBiasConstantFactor,
677
float depthBiasClamp,
678
float depthBiasSlopeFactor)
679
{
680
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
681
682
cmd_buffer->state.gfx.dynamic.depth_bias.bias = depthBiasConstantFactor;
683
cmd_buffer->state.gfx.dynamic.depth_bias.clamp = depthBiasClamp;
684
cmd_buffer->state.gfx.dynamic.depth_bias.slope = depthBiasSlopeFactor;
685
686
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS;
687
}
688
689
void anv_CmdSetBlendConstants(
690
VkCommandBuffer commandBuffer,
691
const float blendConstants[4])
692
{
693
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
694
695
memcpy(cmd_buffer->state.gfx.dynamic.blend_constants,
696
blendConstants, sizeof(float) * 4);
697
698
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS;
699
}
700
701
void anv_CmdSetDepthBounds(
702
VkCommandBuffer commandBuffer,
703
float minDepthBounds,
704
float maxDepthBounds)
705
{
706
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
707
708
cmd_buffer->state.gfx.dynamic.depth_bounds.min = minDepthBounds;
709
cmd_buffer->state.gfx.dynamic.depth_bounds.max = maxDepthBounds;
710
711
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS;
712
}
713
714
void anv_CmdSetStencilCompareMask(
715
VkCommandBuffer commandBuffer,
716
VkStencilFaceFlags faceMask,
717
uint32_t compareMask)
718
{
719
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
720
721
if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
722
cmd_buffer->state.gfx.dynamic.stencil_compare_mask.front = compareMask;
723
if (faceMask & VK_STENCIL_FACE_BACK_BIT)
724
cmd_buffer->state.gfx.dynamic.stencil_compare_mask.back = compareMask;
725
726
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK;
727
}
728
729
void anv_CmdSetStencilWriteMask(
730
VkCommandBuffer commandBuffer,
731
VkStencilFaceFlags faceMask,
732
uint32_t writeMask)
733
{
734
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
735
736
if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
737
cmd_buffer->state.gfx.dynamic.stencil_write_mask.front = writeMask;
738
if (faceMask & VK_STENCIL_FACE_BACK_BIT)
739
cmd_buffer->state.gfx.dynamic.stencil_write_mask.back = writeMask;
740
741
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK;
742
}
743
744
void anv_CmdSetStencilReference(
745
VkCommandBuffer commandBuffer,
746
VkStencilFaceFlags faceMask,
747
uint32_t reference)
748
{
749
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
750
751
if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
752
cmd_buffer->state.gfx.dynamic.stencil_reference.front = reference;
753
if (faceMask & VK_STENCIL_FACE_BACK_BIT)
754
cmd_buffer->state.gfx.dynamic.stencil_reference.back = reference;
755
756
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE;
757
}
758
759
void anv_CmdSetSampleLocationsEXT(
760
VkCommandBuffer commandBuffer,
761
const VkSampleLocationsInfoEXT* pSampleLocationsInfo)
762
{
763
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
764
765
struct anv_dynamic_state *dyn_state = &cmd_buffer->state.gfx.dynamic;
766
uint32_t samples = pSampleLocationsInfo->sampleLocationsPerPixel;
767
768
dyn_state->sample_locations.samples = samples;
769
typed_memcpy(dyn_state->sample_locations.locations,
770
pSampleLocationsInfo->pSampleLocations, samples);
771
772
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS;
773
}
774
775
void anv_CmdSetLineStippleEXT(
776
VkCommandBuffer commandBuffer,
777
uint32_t lineStippleFactor,
778
uint16_t lineStipplePattern)
779
{
780
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
781
782
cmd_buffer->state.gfx.dynamic.line_stipple.factor = lineStippleFactor;
783
cmd_buffer->state.gfx.dynamic.line_stipple.pattern = lineStipplePattern;
784
785
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE;
786
}
787
788
void anv_CmdSetCullModeEXT(
789
VkCommandBuffer commandBuffer,
790
VkCullModeFlags cullMode)
791
{
792
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
793
794
cmd_buffer->state.gfx.dynamic.cull_mode = cullMode;
795
796
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_CULL_MODE;
797
}
798
799
void anv_CmdSetFrontFaceEXT(
800
VkCommandBuffer commandBuffer,
801
VkFrontFace frontFace)
802
{
803
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
804
805
cmd_buffer->state.gfx.dynamic.front_face = frontFace;
806
807
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE;
808
}
809
810
void anv_CmdSetDepthTestEnableEXT(
811
VkCommandBuffer commandBuffer,
812
VkBool32 depthTestEnable)
813
814
{
815
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
816
817
cmd_buffer->state.gfx.dynamic.depth_test_enable = depthTestEnable;
818
819
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE;
820
}
821
822
void anv_CmdSetDepthWriteEnableEXT(
823
VkCommandBuffer commandBuffer,
824
VkBool32 depthWriteEnable)
825
{
826
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
827
828
cmd_buffer->state.gfx.dynamic.depth_write_enable = depthWriteEnable;
829
830
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE;
831
}
832
833
void anv_CmdSetDepthCompareOpEXT(
834
VkCommandBuffer commandBuffer,
835
VkCompareOp depthCompareOp)
836
{
837
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
838
839
cmd_buffer->state.gfx.dynamic.depth_compare_op = depthCompareOp;
840
841
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP;
842
}
843
844
void anv_CmdSetDepthBoundsTestEnableEXT(
845
VkCommandBuffer commandBuffer,
846
VkBool32 depthBoundsTestEnable)
847
{
848
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
849
850
cmd_buffer->state.gfx.dynamic.depth_bounds_test_enable = depthBoundsTestEnable;
851
852
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE;
853
}
854
855
void anv_CmdSetStencilTestEnableEXT(
856
VkCommandBuffer commandBuffer,
857
VkBool32 stencilTestEnable)
858
{
859
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
860
861
cmd_buffer->state.gfx.dynamic.stencil_test_enable = stencilTestEnable;
862
863
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE;
864
}
865
866
void anv_CmdSetStencilOpEXT(
867
VkCommandBuffer commandBuffer,
868
VkStencilFaceFlags faceMask,
869
VkStencilOp failOp,
870
VkStencilOp passOp,
871
VkStencilOp depthFailOp,
872
VkCompareOp compareOp)
873
{
874
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
875
876
if (faceMask & VK_STENCIL_FACE_FRONT_BIT) {
877
cmd_buffer->state.gfx.dynamic.stencil_op.front.fail_op = failOp;
878
cmd_buffer->state.gfx.dynamic.stencil_op.front.pass_op = passOp;
879
cmd_buffer->state.gfx.dynamic.stencil_op.front.depth_fail_op = depthFailOp;
880
cmd_buffer->state.gfx.dynamic.stencil_op.front.compare_op = compareOp;
881
}
882
883
if (faceMask & VK_STENCIL_FACE_BACK_BIT) {
884
cmd_buffer->state.gfx.dynamic.stencil_op.back.fail_op = failOp;
885
cmd_buffer->state.gfx.dynamic.stencil_op.back.pass_op = passOp;
886
cmd_buffer->state.gfx.dynamic.stencil_op.back.depth_fail_op = depthFailOp;
887
cmd_buffer->state.gfx.dynamic.stencil_op.back.compare_op = compareOp;
888
}
889
890
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP;
891
}
892
893
static void
894
anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
895
VkPipelineBindPoint bind_point,
896
struct anv_pipeline_layout *layout,
897
uint32_t set_index,
898
struct anv_descriptor_set *set,
899
uint32_t *dynamic_offset_count,
900
const uint32_t **dynamic_offsets)
901
{
902
struct anv_descriptor_set_layout *set_layout =
903
layout->set[set_index].layout;
904
905
VkShaderStageFlags stages = set_layout->shader_stages;
906
struct anv_cmd_pipeline_state *pipe_state;
907
908
switch (bind_point) {
909
case VK_PIPELINE_BIND_POINT_GRAPHICS:
910
stages &= VK_SHADER_STAGE_ALL_GRAPHICS;
911
pipe_state = &cmd_buffer->state.gfx.base;
912
break;
913
914
case VK_PIPELINE_BIND_POINT_COMPUTE:
915
stages &= VK_SHADER_STAGE_COMPUTE_BIT;
916
pipe_state = &cmd_buffer->state.compute.base;
917
break;
918
919
case VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR:
920
stages &= VK_SHADER_STAGE_RAYGEN_BIT_KHR |
921
VK_SHADER_STAGE_ANY_HIT_BIT_KHR |
922
VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR |
923
VK_SHADER_STAGE_MISS_BIT_KHR |
924
VK_SHADER_STAGE_INTERSECTION_BIT_KHR |
925
VK_SHADER_STAGE_CALLABLE_BIT_KHR;
926
pipe_state = &cmd_buffer->state.rt.base;
927
break;
928
929
default:
930
unreachable("invalid bind point");
931
}
932
933
VkShaderStageFlags dirty_stages = 0;
934
/* If it's a push descriptor set, we have to flag things as dirty
935
* regardless of whether or not the CPU-side data structure changed as we
936
* may have edited in-place.
937
*/
938
if (pipe_state->descriptors[set_index] != set ||
939
anv_descriptor_set_is_push(set)) {
940
pipe_state->descriptors[set_index] = set;
941
942
/* Ray-tracing shaders are entirely bindless and so they don't have
943
* access to HW binding tables. This means that we have to upload the
944
* descriptor set as an 64-bit address in the push constants.
945
*/
946
if (bind_point == VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR) {
947
struct anv_push_constants *push = &pipe_state->push_constants;
948
949
struct anv_address addr = anv_descriptor_set_address(set);
950
push->desc_sets[set_index] = anv_address_physical(addr);
951
952
if (addr.bo) {
953
anv_reloc_list_add_bo(cmd_buffer->batch.relocs,
954
cmd_buffer->batch.alloc,
955
addr.bo);
956
}
957
}
958
959
dirty_stages |= stages;
960
}
961
962
if (dynamic_offsets) {
963
if (set_layout->dynamic_offset_count > 0) {
964
struct anv_push_constants *push = &pipe_state->push_constants;
965
uint32_t dynamic_offset_start =
966
layout->set[set_index].dynamic_offset_start;
967
uint32_t *push_offsets =
968
&push->dynamic_offsets[dynamic_offset_start];
969
970
/* Assert that everything is in range */
971
assert(set_layout->dynamic_offset_count <= *dynamic_offset_count);
972
assert(dynamic_offset_start + set_layout->dynamic_offset_count <=
973
ARRAY_SIZE(push->dynamic_offsets));
974
975
for (uint32_t i = 0; i < set_layout->dynamic_offset_count; i++) {
976
if (push_offsets[i] != (*dynamic_offsets)[i]) {
977
push_offsets[i] = (*dynamic_offsets)[i];
978
/* dynamic_offset_stages[] elements could contain blanket
979
* values like VK_SHADER_STAGE_ALL, so limit this to the
980
* binding point's bits.
981
*/
982
dirty_stages |= set_layout->dynamic_offset_stages[i] & stages;
983
}
984
}
985
986
*dynamic_offsets += set_layout->dynamic_offset_count;
987
*dynamic_offset_count -= set_layout->dynamic_offset_count;
988
}
989
}
990
991
cmd_buffer->state.descriptors_dirty |= dirty_stages;
992
cmd_buffer->state.push_constants_dirty |= dirty_stages;
993
}
994
995
void anv_CmdBindDescriptorSets(
996
VkCommandBuffer commandBuffer,
997
VkPipelineBindPoint pipelineBindPoint,
998
VkPipelineLayout _layout,
999
uint32_t firstSet,
1000
uint32_t descriptorSetCount,
1001
const VkDescriptorSet* pDescriptorSets,
1002
uint32_t dynamicOffsetCount,
1003
const uint32_t* pDynamicOffsets)
1004
{
1005
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1006
ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
1007
1008
assert(firstSet + descriptorSetCount <= MAX_SETS);
1009
1010
for (uint32_t i = 0; i < descriptorSetCount; i++) {
1011
ANV_FROM_HANDLE(anv_descriptor_set, set, pDescriptorSets[i]);
1012
anv_cmd_buffer_bind_descriptor_set(cmd_buffer, pipelineBindPoint,
1013
layout, firstSet + i, set,
1014
&dynamicOffsetCount,
1015
&pDynamicOffsets);
1016
}
1017
}
1018
1019
void anv_CmdBindVertexBuffers2EXT(
1020
VkCommandBuffer commandBuffer,
1021
uint32_t firstBinding,
1022
uint32_t bindingCount,
1023
const VkBuffer* pBuffers,
1024
const VkDeviceSize* pOffsets,
1025
const VkDeviceSize* pSizes,
1026
const VkDeviceSize* pStrides)
1027
{
1028
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1029
struct anv_vertex_binding *vb = cmd_buffer->state.vertex_bindings;
1030
1031
/* We have to defer setting up vertex buffer since we need the buffer
1032
* stride from the pipeline. */
1033
1034
if (pSizes)
1035
cmd_buffer->state.gfx.dynamic.dyn_vbo_size = true;
1036
if (pStrides)
1037
cmd_buffer->state.gfx.dynamic.dyn_vbo_stride = true;
1038
1039
assert(firstBinding + bindingCount <= MAX_VBS);
1040
for (uint32_t i = 0; i < bindingCount; i++) {
1041
vb[firstBinding + i].buffer = anv_buffer_from_handle(pBuffers[i]);
1042
vb[firstBinding + i].offset = pOffsets[i];
1043
vb[firstBinding + i].size = pSizes ? pSizes[i] : 0;
1044
vb[firstBinding + i].stride = pStrides ? pStrides[i] : 0;
1045
cmd_buffer->state.gfx.vb_dirty |= 1 << (firstBinding + i);
1046
}
1047
}
1048
1049
void anv_CmdBindVertexBuffers(
1050
VkCommandBuffer commandBuffer,
1051
uint32_t firstBinding,
1052
uint32_t bindingCount,
1053
const VkBuffer* pBuffers,
1054
const VkDeviceSize* pOffsets)
1055
{
1056
return anv_CmdBindVertexBuffers2EXT(commandBuffer, firstBinding,
1057
bindingCount, pBuffers, pOffsets,
1058
NULL, NULL);
1059
}
1060
1061
void anv_CmdBindTransformFeedbackBuffersEXT(
1062
VkCommandBuffer commandBuffer,
1063
uint32_t firstBinding,
1064
uint32_t bindingCount,
1065
const VkBuffer* pBuffers,
1066
const VkDeviceSize* pOffsets,
1067
const VkDeviceSize* pSizes)
1068
{
1069
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1070
struct anv_xfb_binding *xfb = cmd_buffer->state.xfb_bindings;
1071
1072
/* We have to defer setting up vertex buffer since we need the buffer
1073
* stride from the pipeline. */
1074
1075
assert(firstBinding + bindingCount <= MAX_XFB_BUFFERS);
1076
for (uint32_t i = 0; i < bindingCount; i++) {
1077
if (pBuffers[i] == VK_NULL_HANDLE) {
1078
xfb[firstBinding + i].buffer = NULL;
1079
} else {
1080
ANV_FROM_HANDLE(anv_buffer, buffer, pBuffers[i]);
1081
xfb[firstBinding + i].buffer = buffer;
1082
xfb[firstBinding + i].offset = pOffsets[i];
1083
xfb[firstBinding + i].size =
1084
anv_buffer_get_range(buffer, pOffsets[i],
1085
pSizes ? pSizes[i] : VK_WHOLE_SIZE);
1086
}
1087
}
1088
}
1089
1090
enum isl_format
1091
anv_isl_format_for_descriptor_type(const struct anv_device *device,
1092
VkDescriptorType type)
1093
{
1094
switch (type) {
1095
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1096
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1097
return device->physical->compiler->indirect_ubos_use_sampler ?
1098
ISL_FORMAT_R32G32B32A32_FLOAT : ISL_FORMAT_RAW;
1099
1100
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1101
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1102
return ISL_FORMAT_RAW;
1103
1104
default:
1105
unreachable("Invalid descriptor type");
1106
}
1107
}
1108
1109
struct anv_state
1110
anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer,
1111
const void *data, uint32_t size, uint32_t alignment)
1112
{
1113
struct anv_state state;
1114
1115
state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, size, alignment);
1116
memcpy(state.map, data, size);
1117
1118
VG(VALGRIND_CHECK_MEM_IS_DEFINED(state.map, size));
1119
1120
return state;
1121
}
1122
1123
struct anv_state
1124
anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer,
1125
uint32_t *a, uint32_t *b,
1126
uint32_t dwords, uint32_t alignment)
1127
{
1128
struct anv_state state;
1129
uint32_t *p;
1130
1131
state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
1132
dwords * 4, alignment);
1133
p = state.map;
1134
for (uint32_t i = 0; i < dwords; i++)
1135
p[i] = a[i] | b[i];
1136
1137
VG(VALGRIND_CHECK_MEM_IS_DEFINED(p, dwords * 4));
1138
1139
return state;
1140
}
1141
1142
struct anv_state
1143
anv_cmd_buffer_gfx_push_constants(struct anv_cmd_buffer *cmd_buffer)
1144
{
1145
struct anv_push_constants *data =
1146
&cmd_buffer->state.gfx.base.push_constants;
1147
1148
struct anv_state state =
1149
anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
1150
sizeof(struct anv_push_constants),
1151
32 /* bottom 5 bits MBZ */);
1152
memcpy(state.map, data, sizeof(struct anv_push_constants));
1153
1154
return state;
1155
}
1156
1157
struct anv_state
1158
anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer)
1159
{
1160
const struct intel_device_info *devinfo = &cmd_buffer->device->info;
1161
struct anv_push_constants *data =
1162
&cmd_buffer->state.compute.base.push_constants;
1163
struct anv_compute_pipeline *pipeline = cmd_buffer->state.compute.pipeline;
1164
const struct brw_cs_prog_data *cs_prog_data = get_cs_prog_data(pipeline);
1165
const struct anv_push_range *range = &pipeline->cs->bind_map.push_ranges[0];
1166
1167
const struct brw_cs_dispatch_info dispatch =
1168
brw_cs_get_dispatch_info(devinfo, cs_prog_data, NULL);
1169
const unsigned total_push_constants_size =
1170
brw_cs_push_const_total_size(cs_prog_data, dispatch.threads);
1171
if (total_push_constants_size == 0)
1172
return (struct anv_state) { .offset = 0 };
1173
1174
const unsigned push_constant_alignment =
1175
cmd_buffer->device->info.ver < 8 ? 32 : 64;
1176
const unsigned aligned_total_push_constants_size =
1177
ALIGN(total_push_constants_size, push_constant_alignment);
1178
struct anv_state state;
1179
if (devinfo->verx10 >= 125) {
1180
state = anv_state_stream_alloc(&cmd_buffer->general_state_stream,
1181
aligned_total_push_constants_size,
1182
push_constant_alignment);
1183
} else {
1184
state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
1185
aligned_total_push_constants_size,
1186
push_constant_alignment);
1187
}
1188
1189
void *dst = state.map;
1190
const void *src = (char *)data + (range->start * 32);
1191
1192
if (cs_prog_data->push.cross_thread.size > 0) {
1193
memcpy(dst, src, cs_prog_data->push.cross_thread.size);
1194
dst += cs_prog_data->push.cross_thread.size;
1195
src += cs_prog_data->push.cross_thread.size;
1196
}
1197
1198
if (cs_prog_data->push.per_thread.size > 0) {
1199
for (unsigned t = 0; t < dispatch.threads; t++) {
1200
memcpy(dst, src, cs_prog_data->push.per_thread.size);
1201
1202
uint32_t *subgroup_id = dst +
1203
offsetof(struct anv_push_constants, cs.subgroup_id) -
1204
(range->start * 32 + cs_prog_data->push.cross_thread.size);
1205
*subgroup_id = t;
1206
1207
dst += cs_prog_data->push.per_thread.size;
1208
}
1209
}
1210
1211
return state;
1212
}
1213
1214
void anv_CmdPushConstants(
1215
VkCommandBuffer commandBuffer,
1216
VkPipelineLayout layout,
1217
VkShaderStageFlags stageFlags,
1218
uint32_t offset,
1219
uint32_t size,
1220
const void* pValues)
1221
{
1222
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1223
1224
if (stageFlags & VK_SHADER_STAGE_ALL_GRAPHICS) {
1225
struct anv_cmd_pipeline_state *pipe_state =
1226
&cmd_buffer->state.gfx.base;
1227
1228
memcpy(pipe_state->push_constants.client_data + offset, pValues, size);
1229
}
1230
if (stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) {
1231
struct anv_cmd_pipeline_state *pipe_state =
1232
&cmd_buffer->state.compute.base;
1233
1234
memcpy(pipe_state->push_constants.client_data + offset, pValues, size);
1235
}
1236
if (stageFlags & (VK_SHADER_STAGE_RAYGEN_BIT_KHR |
1237
VK_SHADER_STAGE_ANY_HIT_BIT_KHR |
1238
VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR |
1239
VK_SHADER_STAGE_MISS_BIT_KHR |
1240
VK_SHADER_STAGE_INTERSECTION_BIT_KHR |
1241
VK_SHADER_STAGE_CALLABLE_BIT_KHR)) {
1242
struct anv_cmd_pipeline_state *pipe_state =
1243
&cmd_buffer->state.rt.base;
1244
1245
memcpy(pipe_state->push_constants.client_data + offset, pValues, size);
1246
}
1247
1248
cmd_buffer->state.push_constants_dirty |= stageFlags;
1249
}
1250
1251
VkResult anv_CreateCommandPool(
1252
VkDevice _device,
1253
const VkCommandPoolCreateInfo* pCreateInfo,
1254
const VkAllocationCallbacks* pAllocator,
1255
VkCommandPool* pCmdPool)
1256
{
1257
ANV_FROM_HANDLE(anv_device, device, _device);
1258
struct anv_cmd_pool *pool;
1259
1260
pool = vk_object_alloc(&device->vk, pAllocator, sizeof(*pool),
1261
VK_OBJECT_TYPE_COMMAND_POOL);
1262
if (pool == NULL)
1263
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1264
1265
if (pAllocator)
1266
pool->alloc = *pAllocator;
1267
else
1268
pool->alloc = device->vk.alloc;
1269
1270
list_inithead(&pool->cmd_buffers);
1271
1272
pool->flags = pCreateInfo->flags;
1273
1274
*pCmdPool = anv_cmd_pool_to_handle(pool);
1275
1276
return VK_SUCCESS;
1277
}
1278
1279
void anv_DestroyCommandPool(
1280
VkDevice _device,
1281
VkCommandPool commandPool,
1282
const VkAllocationCallbacks* pAllocator)
1283
{
1284
ANV_FROM_HANDLE(anv_device, device, _device);
1285
ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool);
1286
1287
if (!pool)
1288
return;
1289
1290
list_for_each_entry_safe(struct anv_cmd_buffer, cmd_buffer,
1291
&pool->cmd_buffers, pool_link) {
1292
anv_cmd_buffer_destroy(cmd_buffer);
1293
}
1294
1295
vk_object_free(&device->vk, pAllocator, pool);
1296
}
1297
1298
VkResult anv_ResetCommandPool(
1299
VkDevice device,
1300
VkCommandPool commandPool,
1301
VkCommandPoolResetFlags flags)
1302
{
1303
ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool);
1304
1305
list_for_each_entry(struct anv_cmd_buffer, cmd_buffer,
1306
&pool->cmd_buffers, pool_link) {
1307
anv_cmd_buffer_reset(cmd_buffer);
1308
}
1309
1310
return VK_SUCCESS;
1311
}
1312
1313
void anv_TrimCommandPool(
1314
VkDevice device,
1315
VkCommandPool commandPool,
1316
VkCommandPoolTrimFlags flags)
1317
{
1318
/* Nothing for us to do here. Our pools stay pretty tidy. */
1319
}
1320
1321
/**
1322
* Return NULL if the current subpass has no depthstencil attachment.
1323
*/
1324
const struct anv_image_view *
1325
anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer *cmd_buffer)
1326
{
1327
const struct anv_subpass *subpass = cmd_buffer->state.subpass;
1328
1329
if (subpass->depth_stencil_attachment == NULL)
1330
return NULL;
1331
1332
const struct anv_image_view *iview =
1333
cmd_buffer->state.attachments[subpass->depth_stencil_attachment->attachment].image_view;
1334
1335
assert(iview->aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT |
1336
VK_IMAGE_ASPECT_STENCIL_BIT));
1337
1338
return iview;
1339
}
1340
1341
static struct anv_descriptor_set *
1342
anv_cmd_buffer_push_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
1343
VkPipelineBindPoint bind_point,
1344
struct anv_descriptor_set_layout *layout,
1345
uint32_t _set)
1346
{
1347
struct anv_cmd_pipeline_state *pipe_state;
1348
1349
switch (bind_point) {
1350
case VK_PIPELINE_BIND_POINT_GRAPHICS:
1351
pipe_state = &cmd_buffer->state.gfx.base;
1352
break;
1353
1354
case VK_PIPELINE_BIND_POINT_COMPUTE:
1355
pipe_state = &cmd_buffer->state.compute.base;
1356
break;
1357
1358
case VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR:
1359
pipe_state = &cmd_buffer->state.rt.base;
1360
break;
1361
1362
default:
1363
unreachable("invalid bind point");
1364
}
1365
1366
struct anv_push_descriptor_set **push_set =
1367
&pipe_state->push_descriptors[_set];
1368
1369
if (*push_set == NULL) {
1370
*push_set = vk_zalloc(&cmd_buffer->pool->alloc,
1371
sizeof(struct anv_push_descriptor_set), 8,
1372
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1373
if (*push_set == NULL) {
1374
anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_OUT_OF_HOST_MEMORY);
1375
return NULL;
1376
}
1377
}
1378
1379
struct anv_descriptor_set *set = &(*push_set)->set;
1380
1381
if (set->layout != layout) {
1382
if (set->layout)
1383
anv_descriptor_set_layout_unref(cmd_buffer->device, set->layout);
1384
anv_descriptor_set_layout_ref(layout);
1385
set->layout = layout;
1386
}
1387
set->size = anv_descriptor_set_layout_size(layout, 0);
1388
set->buffer_view_count = layout->buffer_view_count;
1389
set->descriptor_count = layout->descriptor_count;
1390
set->buffer_views = (*push_set)->buffer_views;
1391
1392
if (layout->descriptor_buffer_size &&
1393
((*push_set)->set_used_on_gpu ||
1394
set->desc_mem.alloc_size < layout->descriptor_buffer_size)) {
1395
/* The previous buffer is either actively used by some GPU command (so
1396
* we can't modify it) or is too small. Allocate a new one.
1397
*/
1398
struct anv_state desc_mem =
1399
anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream,
1400
anv_descriptor_set_layout_descriptor_buffer_size(layout, 0),
1401
ANV_UBO_ALIGNMENT);
1402
if (set->desc_mem.alloc_size) {
1403
/* TODO: Do we really need to copy all the time? */
1404
memcpy(desc_mem.map, set->desc_mem.map,
1405
MIN2(desc_mem.alloc_size, set->desc_mem.alloc_size));
1406
}
1407
set->desc_mem = desc_mem;
1408
1409
set->desc_addr = (struct anv_address) {
1410
.bo = cmd_buffer->dynamic_state_stream.state_pool->block_pool.bo,
1411
.offset = set->desc_mem.offset,
1412
};
1413
1414
enum isl_format format =
1415
anv_isl_format_for_descriptor_type(cmd_buffer->device,
1416
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
1417
1418
const struct isl_device *isl_dev = &cmd_buffer->device->isl_dev;
1419
set->desc_surface_state =
1420
anv_state_stream_alloc(&cmd_buffer->surface_state_stream,
1421
isl_dev->ss.size, isl_dev->ss.align);
1422
anv_fill_buffer_surface_state(cmd_buffer->device,
1423
set->desc_surface_state, format,
1424
ISL_SURF_USAGE_CONSTANT_BUFFER_BIT,
1425
set->desc_addr,
1426
layout->descriptor_buffer_size, 1);
1427
}
1428
1429
return set;
1430
}
1431
1432
void anv_CmdPushDescriptorSetKHR(
1433
VkCommandBuffer commandBuffer,
1434
VkPipelineBindPoint pipelineBindPoint,
1435
VkPipelineLayout _layout,
1436
uint32_t _set,
1437
uint32_t descriptorWriteCount,
1438
const VkWriteDescriptorSet* pDescriptorWrites)
1439
{
1440
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1441
ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
1442
1443
assert(_set < MAX_SETS);
1444
1445
struct anv_descriptor_set_layout *set_layout = layout->set[_set].layout;
1446
1447
struct anv_descriptor_set *set =
1448
anv_cmd_buffer_push_descriptor_set(cmd_buffer, pipelineBindPoint,
1449
set_layout, _set);
1450
if (!set)
1451
return;
1452
1453
/* Go through the user supplied descriptors. */
1454
for (uint32_t i = 0; i < descriptorWriteCount; i++) {
1455
const VkWriteDescriptorSet *write = &pDescriptorWrites[i];
1456
1457
switch (write->descriptorType) {
1458
case VK_DESCRIPTOR_TYPE_SAMPLER:
1459
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1460
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1461
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1462
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1463
for (uint32_t j = 0; j < write->descriptorCount; j++) {
1464
anv_descriptor_set_write_image_view(cmd_buffer->device, set,
1465
write->pImageInfo + j,
1466
write->descriptorType,
1467
write->dstBinding,
1468
write->dstArrayElement + j);
1469
}
1470
break;
1471
1472
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1473
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1474
for (uint32_t j = 0; j < write->descriptorCount; j++) {
1475
ANV_FROM_HANDLE(anv_buffer_view, bview,
1476
write->pTexelBufferView[j]);
1477
1478
anv_descriptor_set_write_buffer_view(cmd_buffer->device, set,
1479
write->descriptorType,
1480
bview,
1481
write->dstBinding,
1482
write->dstArrayElement + j);
1483
}
1484
break;
1485
1486
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1487
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1488
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1489
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1490
for (uint32_t j = 0; j < write->descriptorCount; j++) {
1491
ANV_FROM_HANDLE(anv_buffer, buffer, write->pBufferInfo[j].buffer);
1492
1493
anv_descriptor_set_write_buffer(cmd_buffer->device, set,
1494
&cmd_buffer->surface_state_stream,
1495
write->descriptorType,
1496
buffer,
1497
write->dstBinding,
1498
write->dstArrayElement + j,
1499
write->pBufferInfo[j].offset,
1500
write->pBufferInfo[j].range);
1501
}
1502
break;
1503
1504
case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: {
1505
const VkWriteDescriptorSetAccelerationStructureKHR *accel_write =
1506
vk_find_struct_const(write, WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR);
1507
assert(accel_write->accelerationStructureCount ==
1508
write->descriptorCount);
1509
for (uint32_t j = 0; j < write->descriptorCount; j++) {
1510
ANV_FROM_HANDLE(anv_acceleration_structure, accel,
1511
accel_write->pAccelerationStructures[j]);
1512
anv_descriptor_set_write_acceleration_structure(cmd_buffer->device,
1513
set, accel,
1514
write->dstBinding,
1515
write->dstArrayElement + j);
1516
}
1517
break;
1518
}
1519
1520
default:
1521
break;
1522
}
1523
}
1524
1525
anv_cmd_buffer_bind_descriptor_set(cmd_buffer, pipelineBindPoint,
1526
layout, _set, set, NULL, NULL);
1527
}
1528
1529
void anv_CmdPushDescriptorSetWithTemplateKHR(
1530
VkCommandBuffer commandBuffer,
1531
VkDescriptorUpdateTemplate descriptorUpdateTemplate,
1532
VkPipelineLayout _layout,
1533
uint32_t _set,
1534
const void* pData)
1535
{
1536
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1537
ANV_FROM_HANDLE(anv_descriptor_update_template, template,
1538
descriptorUpdateTemplate);
1539
ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
1540
1541
assert(_set < MAX_PUSH_DESCRIPTORS);
1542
1543
struct anv_descriptor_set_layout *set_layout = layout->set[_set].layout;
1544
1545
struct anv_descriptor_set *set =
1546
anv_cmd_buffer_push_descriptor_set(cmd_buffer, template->bind_point,
1547
set_layout, _set);
1548
if (!set)
1549
return;
1550
1551
anv_descriptor_set_write_template(cmd_buffer->device, set,
1552
&cmd_buffer->surface_state_stream,
1553
template,
1554
pData);
1555
1556
anv_cmd_buffer_bind_descriptor_set(cmd_buffer, template->bind_point,
1557
layout, _set, set, NULL, NULL);
1558
}
1559
1560
void anv_CmdSetDeviceMask(
1561
VkCommandBuffer commandBuffer,
1562
uint32_t deviceMask)
1563
{
1564
/* No-op */
1565
}
1566
1567
void anv_CmdSetColorWriteEnableEXT(
1568
VkCommandBuffer commandBuffer,
1569
uint32_t attachmentCount,
1570
const VkBool32* pColorWriteEnables)
1571
{
1572
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1573
1574
assert(attachmentCount < MAX_RTS);
1575
1576
uint8_t color_writes = 0;
1577
for (uint32_t i = 0; i < attachmentCount; i++)
1578
color_writes |= pColorWriteEnables[i] ? (1 << i) : 0;
1579
1580
if (cmd_buffer->state.gfx.dynamic.color_writes != color_writes) {
1581
cmd_buffer->state.gfx.dynamic.color_writes = color_writes;
1582
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE;
1583
}
1584
}
1585
1586
void anv_CmdSetFragmentShadingRateKHR(
1587
VkCommandBuffer commandBuffer,
1588
const VkExtent2D* pFragmentSize,
1589
const VkFragmentShadingRateCombinerOpKHR combinerOps[2])
1590
{
1591
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1592
1593
cmd_buffer->state.gfx.dynamic.fragment_shading_rate = *pFragmentSize;
1594
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE;
1595
}
1596
1597
static inline uint32_t
1598
ilog2_round_up(uint32_t value)
1599
{
1600
assert(value != 0);
1601
return 32 - __builtin_clz(value - 1);
1602
}
1603
1604
void anv_CmdSetRayTracingPipelineStackSizeKHR(
1605
VkCommandBuffer commandBuffer,
1606
uint32_t pipelineStackSize)
1607
{
1608
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1609
struct anv_cmd_ray_tracing_state *rt = &cmd_buffer->state.rt;
1610
struct anv_device *device = cmd_buffer->device;
1611
1612
if (anv_batch_has_error(&cmd_buffer->batch))
1613
return;
1614
1615
uint32_t stack_ids_per_dss = 2048; /* TODO */
1616
1617
unsigned stack_size_log2 = ilog2_round_up(pipelineStackSize);
1618
if (stack_size_log2 < 10)
1619
stack_size_log2 = 10;
1620
1621
if (rt->scratch.layout.total_size == 1 << stack_size_log2)
1622
return;
1623
1624
brw_rt_compute_scratch_layout(&rt->scratch.layout, &device->info,
1625
stack_ids_per_dss, 1 << stack_size_log2);
1626
1627
unsigned bucket = stack_size_log2 - 10;
1628
assert(bucket < ARRAY_SIZE(device->rt_scratch_bos));
1629
1630
struct anv_bo *bo = p_atomic_read(&device->rt_scratch_bos[bucket]);
1631
if (bo == NULL) {
1632
struct anv_bo *new_bo;
1633
VkResult result = anv_device_alloc_bo(device, "RT scratch",
1634
rt->scratch.layout.total_size,
1635
0, /* alloc_flags */
1636
0, /* explicit_address */
1637
&new_bo);
1638
if (result != VK_SUCCESS) {
1639
rt->scratch.layout.total_size = 0;
1640
anv_batch_set_error(&cmd_buffer->batch, result);
1641
return;
1642
}
1643
1644
bo = p_atomic_cmpxchg(&device->rt_scratch_bos[bucket], NULL, new_bo);
1645
if (bo != NULL) {
1646
anv_device_release_bo(device, bo);
1647
} else {
1648
bo = new_bo;
1649
}
1650
}
1651
1652
rt->scratch.bo = bo;
1653
}
1654
1655