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 static void
anv_cmd_state_init(struct anv_cmd_buffer * cmd_buffer)45 anv_cmd_state_init(struct anv_cmd_buffer *cmd_buffer)
46 {
47 struct anv_cmd_state *state = &cmd_buffer->state;
48
49 memset(state, 0, sizeof(*state));
50
51 state->current_pipeline = UINT32_MAX;
52 state->gfx.restart_index = UINT32_MAX;
53 state->gfx.dirty = 0;
54 }
55
56 static void
anv_cmd_pipeline_state_finish(struct anv_cmd_buffer * cmd_buffer,struct anv_cmd_pipeline_state * pipe_state)57 anv_cmd_pipeline_state_finish(struct anv_cmd_buffer *cmd_buffer,
58 struct anv_cmd_pipeline_state *pipe_state)
59 {
60 for (uint32_t i = 0; i < ARRAY_SIZE(pipe_state->push_descriptors); i++) {
61 if (pipe_state->push_descriptors[i]) {
62 anv_descriptor_set_layout_unref(cmd_buffer->device,
63 pipe_state->push_descriptors[i]->set.layout);
64 vk_free(&cmd_buffer->vk.pool->alloc, pipe_state->push_descriptors[i]);
65 }
66 }
67 }
68
69 static void
anv_cmd_state_finish(struct anv_cmd_buffer * cmd_buffer)70 anv_cmd_state_finish(struct anv_cmd_buffer *cmd_buffer)
71 {
72 struct anv_cmd_state *state = &cmd_buffer->state;
73
74 anv_cmd_pipeline_state_finish(cmd_buffer, &state->gfx.base);
75 anv_cmd_pipeline_state_finish(cmd_buffer, &state->compute.base);
76 }
77
78 static void
anv_cmd_state_reset(struct anv_cmd_buffer * cmd_buffer)79 anv_cmd_state_reset(struct anv_cmd_buffer *cmd_buffer)
80 {
81 anv_cmd_state_finish(cmd_buffer);
82 anv_cmd_state_init(cmd_buffer);
83 }
84
85 static void anv_cmd_buffer_destroy(struct vk_command_buffer *vk_cmd_buffer);
86
anv_create_cmd_buffer(struct anv_device * device,struct vk_command_pool * pool,VkCommandBufferLevel level,VkCommandBuffer * pCommandBuffer)87 static VkResult anv_create_cmd_buffer(
88 struct anv_device * device,
89 struct vk_command_pool * pool,
90 VkCommandBufferLevel level,
91 VkCommandBuffer* pCommandBuffer)
92 {
93 struct anv_cmd_buffer *cmd_buffer;
94 VkResult result;
95
96 cmd_buffer = vk_alloc(&pool->alloc, sizeof(*cmd_buffer), 8,
97 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
98 if (cmd_buffer == NULL)
99 return vk_error(pool, VK_ERROR_OUT_OF_HOST_MEMORY);
100
101 result = vk_command_buffer_init(&cmd_buffer->vk, pool, level);
102 if (result != VK_SUCCESS)
103 goto fail_alloc;
104
105 cmd_buffer->vk.destroy = anv_cmd_buffer_destroy;
106 cmd_buffer->vk.dynamic_graphics_state.ms.sample_locations =
107 &cmd_buffer->state.gfx.sample_locations;
108
109 cmd_buffer->batch.status = VK_SUCCESS;
110
111 cmd_buffer->device = device;
112
113 assert(pool->queue_family_index < device->physical->queue.family_count);
114 cmd_buffer->queue_family =
115 &device->physical->queue.families[pool->queue_family_index];
116
117 result = anv_cmd_buffer_init_batch_bo_chain(cmd_buffer);
118 if (result != VK_SUCCESS)
119 goto fail_vk;
120
121 anv_state_stream_init(&cmd_buffer->surface_state_stream,
122 &device->surface_state_pool, 4096);
123 anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
124 &device->dynamic_state_pool, 16384);
125 anv_state_stream_init(&cmd_buffer->general_state_stream,
126 &device->general_state_pool, 16384);
127
128 cmd_buffer->self_mod_locations = NULL;
129
130 anv_cmd_state_init(cmd_buffer);
131
132 anv_measure_init(cmd_buffer);
133
134 u_trace_init(&cmd_buffer->trace, &device->ds.trace_context);
135
136 *pCommandBuffer = anv_cmd_buffer_to_handle(cmd_buffer);
137
138 return VK_SUCCESS;
139
140 fail_vk:
141 vk_command_buffer_finish(&cmd_buffer->vk);
142 fail_alloc:
143 vk_free2(&device->vk.alloc, &pool->alloc, cmd_buffer);
144
145 return result;
146 }
147
anv_AllocateCommandBuffers(VkDevice _device,const VkCommandBufferAllocateInfo * pAllocateInfo,VkCommandBuffer * pCommandBuffers)148 VkResult anv_AllocateCommandBuffers(
149 VkDevice _device,
150 const VkCommandBufferAllocateInfo* pAllocateInfo,
151 VkCommandBuffer* pCommandBuffers)
152 {
153 ANV_FROM_HANDLE(anv_device, device, _device);
154 VK_FROM_HANDLE(vk_command_pool, pool, pAllocateInfo->commandPool);
155
156 VkResult result = VK_SUCCESS;
157 uint32_t i;
158
159 for (i = 0; i < pAllocateInfo->commandBufferCount; i++) {
160 result = anv_create_cmd_buffer(device, pool, pAllocateInfo->level,
161 &pCommandBuffers[i]);
162 if (result != VK_SUCCESS)
163 break;
164 }
165
166 if (result != VK_SUCCESS) {
167 while (i--) {
168 VK_FROM_HANDLE(vk_command_buffer, cmd_buffer, pCommandBuffers[i]);
169 anv_cmd_buffer_destroy(cmd_buffer);
170 }
171 for (i = 0; i < pAllocateInfo->commandBufferCount; i++)
172 pCommandBuffers[i] = VK_NULL_HANDLE;
173 }
174
175 return result;
176 }
177
178 static void
anv_cmd_buffer_destroy(struct vk_command_buffer * vk_cmd_buffer)179 anv_cmd_buffer_destroy(struct vk_command_buffer *vk_cmd_buffer)
180 {
181 struct anv_cmd_buffer *cmd_buffer =
182 container_of(vk_cmd_buffer, struct anv_cmd_buffer, vk);
183
184 u_trace_fini(&cmd_buffer->trace);
185
186 anv_measure_destroy(cmd_buffer);
187
188 anv_cmd_buffer_fini_batch_bo_chain(cmd_buffer);
189
190 anv_state_stream_finish(&cmd_buffer->surface_state_stream);
191 anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
192 anv_state_stream_finish(&cmd_buffer->general_state_stream);
193
194 anv_cmd_state_finish(cmd_buffer);
195
196 vk_free(&cmd_buffer->vk.pool->alloc, cmd_buffer->self_mod_locations);
197
198 vk_command_buffer_finish(&cmd_buffer->vk);
199 vk_free(&cmd_buffer->vk.pool->alloc, cmd_buffer);
200 }
201
202 VkResult
anv_cmd_buffer_reset(struct anv_cmd_buffer * cmd_buffer)203 anv_cmd_buffer_reset(struct anv_cmd_buffer *cmd_buffer)
204 {
205 vk_command_buffer_reset(&cmd_buffer->vk);
206
207 cmd_buffer->usage_flags = 0;
208 cmd_buffer->perf_query_pool = NULL;
209 anv_cmd_buffer_reset_batch_bo_chain(cmd_buffer);
210 anv_cmd_state_reset(cmd_buffer);
211
212 anv_state_stream_finish(&cmd_buffer->surface_state_stream);
213 anv_state_stream_init(&cmd_buffer->surface_state_stream,
214 &cmd_buffer->device->surface_state_pool, 4096);
215
216 anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
217 anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
218 &cmd_buffer->device->dynamic_state_pool, 16384);
219
220 anv_state_stream_finish(&cmd_buffer->general_state_stream);
221 anv_state_stream_init(&cmd_buffer->general_state_stream,
222 &cmd_buffer->device->general_state_pool, 16384);
223
224 anv_measure_reset(cmd_buffer);
225
226 u_trace_fini(&cmd_buffer->trace);
227 u_trace_init(&cmd_buffer->trace, &cmd_buffer->device->ds.trace_context);
228
229 return VK_SUCCESS;
230 }
231
anv_ResetCommandBuffer(VkCommandBuffer commandBuffer,VkCommandBufferResetFlags flags)232 VkResult anv_ResetCommandBuffer(
233 VkCommandBuffer commandBuffer,
234 VkCommandBufferResetFlags flags)
235 {
236 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
237 return anv_cmd_buffer_reset(cmd_buffer);
238 }
239
240 void
anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer * cmd_buffer)241 anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer)
242 {
243 const struct intel_device_info *devinfo = &cmd_buffer->device->info;
244 anv_genX(devinfo, cmd_buffer_emit_state_base_address)(cmd_buffer);
245 }
246
247 void
anv_cmd_buffer_mark_image_written(struct anv_cmd_buffer * cmd_buffer,const struct anv_image * image,VkImageAspectFlagBits aspect,enum isl_aux_usage aux_usage,uint32_t level,uint32_t base_layer,uint32_t layer_count)248 anv_cmd_buffer_mark_image_written(struct anv_cmd_buffer *cmd_buffer,
249 const struct anv_image *image,
250 VkImageAspectFlagBits aspect,
251 enum isl_aux_usage aux_usage,
252 uint32_t level,
253 uint32_t base_layer,
254 uint32_t layer_count)
255 {
256 const struct intel_device_info *devinfo = &cmd_buffer->device->info;
257 anv_genX(devinfo, cmd_buffer_mark_image_written)(cmd_buffer, image,
258 aspect, aux_usage,
259 level, base_layer,
260 layer_count);
261 }
262
263 void
anv_cmd_emit_conditional_render_predicate(struct anv_cmd_buffer * cmd_buffer)264 anv_cmd_emit_conditional_render_predicate(struct anv_cmd_buffer *cmd_buffer)
265 {
266 const struct intel_device_info *devinfo = &cmd_buffer->device->info;
267 anv_genX(devinfo, cmd_emit_conditional_render_predicate)(cmd_buffer);
268 }
269
270 static bool
mem_update(void * dst,const void * src,size_t size)271 mem_update(void *dst, const void *src, size_t size)
272 {
273 if (memcmp(dst, src, size) == 0)
274 return false;
275
276 memcpy(dst, src, size);
277 return true;
278 }
279
280 static void
set_dirty_for_bind_map(struct anv_cmd_buffer * cmd_buffer,gl_shader_stage stage,const struct anv_pipeline_bind_map * map)281 set_dirty_for_bind_map(struct anv_cmd_buffer *cmd_buffer,
282 gl_shader_stage stage,
283 const struct anv_pipeline_bind_map *map)
284 {
285 assert(stage < ARRAY_SIZE(cmd_buffer->state.surface_sha1s));
286 if (mem_update(cmd_buffer->state.surface_sha1s[stage],
287 map->surface_sha1, sizeof(map->surface_sha1)))
288 cmd_buffer->state.descriptors_dirty |= mesa_to_vk_shader_stage(stage);
289
290 assert(stage < ARRAY_SIZE(cmd_buffer->state.sampler_sha1s));
291 if (mem_update(cmd_buffer->state.sampler_sha1s[stage],
292 map->sampler_sha1, sizeof(map->sampler_sha1)))
293 cmd_buffer->state.descriptors_dirty |= mesa_to_vk_shader_stage(stage);
294
295 assert(stage < ARRAY_SIZE(cmd_buffer->state.push_sha1s));
296 if (mem_update(cmd_buffer->state.push_sha1s[stage],
297 map->push_sha1, sizeof(map->push_sha1)))
298 cmd_buffer->state.push_constants_dirty |= mesa_to_vk_shader_stage(stage);
299 }
300
301 static inline uint32_t
ilog2_round_up(uint32_t value)302 ilog2_round_up(uint32_t value)
303 {
304 assert(value != 0);
305 return 32 - __builtin_clz(value - 1);
306 }
307
308 static void
anv_cmd_buffer_set_ray_query_buffer(struct anv_cmd_buffer * cmd_buffer,struct anv_cmd_pipeline_state * pipeline_state,struct anv_pipeline * pipeline,VkShaderStageFlags stages)309 anv_cmd_buffer_set_ray_query_buffer(struct anv_cmd_buffer *cmd_buffer,
310 struct anv_cmd_pipeline_state *pipeline_state,
311 struct anv_pipeline *pipeline,
312 VkShaderStageFlags stages)
313 {
314 struct anv_device *device = cmd_buffer->device;
315
316 uint64_t ray_shadow_size =
317 align_u64(brw_rt_ray_queries_shadow_stacks_size(&device->info,
318 pipeline->ray_queries),
319 4096);
320 if (ray_shadow_size > 0 &&
321 (!cmd_buffer->state.ray_query_shadow_bo ||
322 cmd_buffer->state.ray_query_shadow_bo->size < ray_shadow_size)) {
323 unsigned shadow_size_log2 = MAX2(ilog2_round_up(ray_shadow_size), 16);
324 unsigned bucket = shadow_size_log2 - 16;
325 assert(bucket < ARRAY_SIZE(device->ray_query_shadow_bos));
326
327 struct anv_bo *bo = p_atomic_read(&device->ray_query_shadow_bos[bucket]);
328 if (bo == NULL) {
329 struct anv_bo *new_bo;
330 VkResult result = anv_device_alloc_bo(device, "RT queries shadow",
331 ray_shadow_size,
332 ANV_BO_ALLOC_LOCAL_MEM, /* alloc_flags */
333 0, /* explicit_address */
334 &new_bo);
335 if (result != VK_SUCCESS) {
336 anv_batch_set_error(&cmd_buffer->batch, result);
337 return;
338 }
339
340 bo = p_atomic_cmpxchg(&device->ray_query_shadow_bos[bucket], NULL, new_bo);
341 if (bo != NULL) {
342 anv_device_release_bo(device, bo);
343 } else {
344 bo = new_bo;
345 }
346 }
347 cmd_buffer->state.ray_query_shadow_bo = bo;
348
349 /* Add the ray query buffers to the batch list. */
350 anv_reloc_list_add_bo(cmd_buffer->batch.relocs,
351 cmd_buffer->batch.alloc,
352 cmd_buffer->state.ray_query_shadow_bo);
353 }
354
355 /* Add the HW buffer to the list of BO used. */
356 anv_reloc_list_add_bo(cmd_buffer->batch.relocs,
357 cmd_buffer->batch.alloc,
358 device->ray_query_bo);
359
360 /* Fill the push constants & mark them dirty. */
361 struct anv_state ray_query_global_state =
362 anv_genX(&device->info, cmd_buffer_ray_query_globals)(cmd_buffer);
363
364 struct anv_address ray_query_globals_addr = (struct anv_address) {
365 .bo = device->dynamic_state_pool.block_pool.bo,
366 .offset = ray_query_global_state.offset,
367 };
368 pipeline_state->push_constants.ray_query_globals =
369 anv_address_physical(ray_query_globals_addr);
370 cmd_buffer->state.push_constants_dirty |= stages;
371 }
372
anv_CmdBindPipeline(VkCommandBuffer commandBuffer,VkPipelineBindPoint pipelineBindPoint,VkPipeline _pipeline)373 void anv_CmdBindPipeline(
374 VkCommandBuffer commandBuffer,
375 VkPipelineBindPoint pipelineBindPoint,
376 VkPipeline _pipeline)
377 {
378 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
379 ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline);
380 struct anv_cmd_pipeline_state *state;
381 VkShaderStageFlags stages = 0;
382
383 switch (pipelineBindPoint) {
384 case VK_PIPELINE_BIND_POINT_COMPUTE: {
385 struct anv_compute_pipeline *compute_pipeline =
386 anv_pipeline_to_compute(pipeline);
387 if (cmd_buffer->state.compute.pipeline == compute_pipeline)
388 return;
389
390 cmd_buffer->state.compute.pipeline = compute_pipeline;
391 cmd_buffer->state.compute.pipeline_dirty = true;
392 set_dirty_for_bind_map(cmd_buffer, MESA_SHADER_COMPUTE,
393 &compute_pipeline->cs->bind_map);
394
395 state = &cmd_buffer->state.compute.base;
396 stages = VK_SHADER_STAGE_COMPUTE_BIT;
397 break;
398 }
399
400 case VK_PIPELINE_BIND_POINT_GRAPHICS: {
401 struct anv_graphics_pipeline *gfx_pipeline =
402 anv_pipeline_to_graphics(pipeline);
403 if (cmd_buffer->state.gfx.pipeline == gfx_pipeline)
404 return;
405
406 cmd_buffer->state.gfx.pipeline = gfx_pipeline;
407 cmd_buffer->state.gfx.vb_dirty |= gfx_pipeline->vb_used;
408 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_PIPELINE;
409
410 anv_foreach_stage(stage, gfx_pipeline->active_stages) {
411 set_dirty_for_bind_map(cmd_buffer, stage,
412 &gfx_pipeline->shaders[stage]->bind_map);
413 }
414
415 /* Apply the non dynamic state from the pipeline */
416 vk_cmd_set_dynamic_graphics_state(&cmd_buffer->vk,
417 &gfx_pipeline->dynamic_state);
418
419 state = &cmd_buffer->state.gfx.base;
420 stages = gfx_pipeline->active_stages;
421 break;
422 }
423
424 case VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR: {
425 struct anv_ray_tracing_pipeline *rt_pipeline =
426 anv_pipeline_to_ray_tracing(pipeline);
427 if (cmd_buffer->state.rt.pipeline == rt_pipeline)
428 return;
429
430 cmd_buffer->state.rt.pipeline = rt_pipeline;
431 cmd_buffer->state.rt.pipeline_dirty = true;
432
433 if (rt_pipeline->stack_size > 0) {
434 anv_CmdSetRayTracingPipelineStackSizeKHR(commandBuffer,
435 rt_pipeline->stack_size);
436 }
437
438 state = &cmd_buffer->state.rt.base;
439 break;
440 }
441
442 default:
443 unreachable("invalid bind point");
444 break;
445 }
446
447 if (pipeline->ray_queries > 0)
448 anv_cmd_buffer_set_ray_query_buffer(cmd_buffer, state, pipeline, stages);
449 }
450
451 static void
anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer * cmd_buffer,VkPipelineBindPoint bind_point,struct anv_pipeline_layout * layout,uint32_t set_index,struct anv_descriptor_set * set,uint32_t * dynamic_offset_count,const uint32_t ** dynamic_offsets)452 anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
453 VkPipelineBindPoint bind_point,
454 struct anv_pipeline_layout *layout,
455 uint32_t set_index,
456 struct anv_descriptor_set *set,
457 uint32_t *dynamic_offset_count,
458 const uint32_t **dynamic_offsets)
459 {
460 /* Either we have no pool because it's a push descriptor or the pool is not
461 * host only :
462 *
463 * VUID-vkCmdBindDescriptorSets-pDescriptorSets-04616:
464 *
465 * "Each element of pDescriptorSets must not have been allocated from a
466 * VkDescriptorPool with the
467 * VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_VALVE flag set"
468 */
469 assert(!set->pool || !set->pool->host_only);
470
471 struct anv_descriptor_set_layout *set_layout =
472 layout->set[set_index].layout;
473
474 VkShaderStageFlags stages = set_layout->shader_stages;
475 struct anv_cmd_pipeline_state *pipe_state;
476
477 switch (bind_point) {
478 case VK_PIPELINE_BIND_POINT_GRAPHICS:
479 stages &= VK_SHADER_STAGE_ALL_GRAPHICS |
480 (cmd_buffer->device->vk.enabled_extensions.NV_mesh_shader ?
481 (VK_SHADER_STAGE_TASK_BIT_NV |
482 VK_SHADER_STAGE_MESH_BIT_NV) : 0);
483 pipe_state = &cmd_buffer->state.gfx.base;
484 break;
485
486 case VK_PIPELINE_BIND_POINT_COMPUTE:
487 stages &= VK_SHADER_STAGE_COMPUTE_BIT;
488 pipe_state = &cmd_buffer->state.compute.base;
489 break;
490
491 case VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR:
492 stages &= VK_SHADER_STAGE_RAYGEN_BIT_KHR |
493 VK_SHADER_STAGE_ANY_HIT_BIT_KHR |
494 VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR |
495 VK_SHADER_STAGE_MISS_BIT_KHR |
496 VK_SHADER_STAGE_INTERSECTION_BIT_KHR |
497 VK_SHADER_STAGE_CALLABLE_BIT_KHR;
498 pipe_state = &cmd_buffer->state.rt.base;
499 break;
500
501 default:
502 unreachable("invalid bind point");
503 }
504
505 VkShaderStageFlags dirty_stages = 0;
506 /* If it's a push descriptor set, we have to flag things as dirty
507 * regardless of whether or not the CPU-side data structure changed as we
508 * may have edited in-place.
509 */
510 if (pipe_state->descriptors[set_index] != set ||
511 anv_descriptor_set_is_push(set)) {
512 pipe_state->descriptors[set_index] = set;
513
514 /* Those stages don't have access to HW binding tables.
515 * This means that we have to upload the descriptor set
516 * as an 64-bit address in the push constants.
517 */
518 bool update_desc_sets = stages & (VK_SHADER_STAGE_TASK_BIT_NV |
519 VK_SHADER_STAGE_MESH_BIT_NV |
520 VK_SHADER_STAGE_RAYGEN_BIT_KHR |
521 VK_SHADER_STAGE_ANY_HIT_BIT_KHR |
522 VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR |
523 VK_SHADER_STAGE_MISS_BIT_KHR |
524 VK_SHADER_STAGE_INTERSECTION_BIT_KHR |
525 VK_SHADER_STAGE_CALLABLE_BIT_KHR);
526
527 if (update_desc_sets) {
528 struct anv_push_constants *push = &pipe_state->push_constants;
529
530 struct anv_address addr = anv_descriptor_set_address(set);
531 push->desc_sets[set_index] = anv_address_physical(addr);
532
533 if (addr.bo) {
534 anv_reloc_list_add_bo(cmd_buffer->batch.relocs,
535 cmd_buffer->batch.alloc,
536 addr.bo);
537 }
538 }
539
540 dirty_stages |= stages;
541 }
542
543 if (dynamic_offsets) {
544 if (set_layout->dynamic_offset_count > 0) {
545 struct anv_push_constants *push = &pipe_state->push_constants;
546 uint32_t dynamic_offset_start =
547 layout->set[set_index].dynamic_offset_start;
548 uint32_t *push_offsets =
549 &push->dynamic_offsets[dynamic_offset_start];
550
551 /* Assert that everything is in range */
552 assert(set_layout->dynamic_offset_count <= *dynamic_offset_count);
553 assert(dynamic_offset_start + set_layout->dynamic_offset_count <=
554 ARRAY_SIZE(push->dynamic_offsets));
555
556 for (uint32_t i = 0; i < set_layout->dynamic_offset_count; i++) {
557 if (push_offsets[i] != (*dynamic_offsets)[i]) {
558 push_offsets[i] = (*dynamic_offsets)[i];
559 /* dynamic_offset_stages[] elements could contain blanket
560 * values like VK_SHADER_STAGE_ALL, so limit this to the
561 * binding point's bits.
562 */
563 dirty_stages |= set_layout->dynamic_offset_stages[i] & stages;
564 }
565 }
566
567 *dynamic_offsets += set_layout->dynamic_offset_count;
568 *dynamic_offset_count -= set_layout->dynamic_offset_count;
569 }
570 }
571
572 cmd_buffer->state.descriptors_dirty |= dirty_stages;
573 cmd_buffer->state.push_constants_dirty |= dirty_stages;
574 }
575
anv_CmdBindDescriptorSets(VkCommandBuffer commandBuffer,VkPipelineBindPoint pipelineBindPoint,VkPipelineLayout _layout,uint32_t firstSet,uint32_t descriptorSetCount,const VkDescriptorSet * pDescriptorSets,uint32_t dynamicOffsetCount,const uint32_t * pDynamicOffsets)576 void anv_CmdBindDescriptorSets(
577 VkCommandBuffer commandBuffer,
578 VkPipelineBindPoint pipelineBindPoint,
579 VkPipelineLayout _layout,
580 uint32_t firstSet,
581 uint32_t descriptorSetCount,
582 const VkDescriptorSet* pDescriptorSets,
583 uint32_t dynamicOffsetCount,
584 const uint32_t* pDynamicOffsets)
585 {
586 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
587 ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
588
589 assert(firstSet + descriptorSetCount <= MAX_SETS);
590
591 for (uint32_t i = 0; i < descriptorSetCount; i++) {
592 ANV_FROM_HANDLE(anv_descriptor_set, set, pDescriptorSets[i]);
593 anv_cmd_buffer_bind_descriptor_set(cmd_buffer, pipelineBindPoint,
594 layout, firstSet + i, set,
595 &dynamicOffsetCount,
596 &pDynamicOffsets);
597 }
598 }
599
anv_CmdBindVertexBuffers2(VkCommandBuffer commandBuffer,uint32_t firstBinding,uint32_t bindingCount,const VkBuffer * pBuffers,const VkDeviceSize * pOffsets,const VkDeviceSize * pSizes,const VkDeviceSize * pStrides)600 void anv_CmdBindVertexBuffers2(
601 VkCommandBuffer commandBuffer,
602 uint32_t firstBinding,
603 uint32_t bindingCount,
604 const VkBuffer* pBuffers,
605 const VkDeviceSize* pOffsets,
606 const VkDeviceSize* pSizes,
607 const VkDeviceSize* pStrides)
608 {
609 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
610 struct anv_vertex_binding *vb = cmd_buffer->state.vertex_bindings;
611
612 /* We have to defer setting up vertex buffer since we need the buffer
613 * stride from the pipeline. */
614
615 assert(firstBinding + bindingCount <= MAX_VBS);
616 for (uint32_t i = 0; i < bindingCount; i++) {
617 ANV_FROM_HANDLE(anv_buffer, buffer, pBuffers[i]);
618
619 if (buffer == NULL) {
620 vb[firstBinding + i] = (struct anv_vertex_binding) {
621 .buffer = NULL,
622 };
623 } else {
624 vb[firstBinding + i] = (struct anv_vertex_binding) {
625 .buffer = buffer,
626 .offset = pOffsets[i],
627 .size = vk_buffer_range(&buffer->vk, pOffsets[i],
628 pSizes ? pSizes[i] : VK_WHOLE_SIZE),
629 };
630 }
631 cmd_buffer->state.gfx.vb_dirty |= 1 << (firstBinding + i);
632 }
633
634 if (pStrides != NULL) {
635 vk_cmd_set_vertex_binding_strides(&cmd_buffer->vk, firstBinding,
636 bindingCount, pStrides);
637 }
638 }
639
anv_CmdBindTransformFeedbackBuffersEXT(VkCommandBuffer commandBuffer,uint32_t firstBinding,uint32_t bindingCount,const VkBuffer * pBuffers,const VkDeviceSize * pOffsets,const VkDeviceSize * pSizes)640 void anv_CmdBindTransformFeedbackBuffersEXT(
641 VkCommandBuffer commandBuffer,
642 uint32_t firstBinding,
643 uint32_t bindingCount,
644 const VkBuffer* pBuffers,
645 const VkDeviceSize* pOffsets,
646 const VkDeviceSize* pSizes)
647 {
648 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
649 struct anv_xfb_binding *xfb = cmd_buffer->state.xfb_bindings;
650
651 /* We have to defer setting up vertex buffer since we need the buffer
652 * stride from the pipeline. */
653
654 assert(firstBinding + bindingCount <= MAX_XFB_BUFFERS);
655 for (uint32_t i = 0; i < bindingCount; i++) {
656 if (pBuffers[i] == VK_NULL_HANDLE) {
657 xfb[firstBinding + i].buffer = NULL;
658 } else {
659 ANV_FROM_HANDLE(anv_buffer, buffer, pBuffers[i]);
660 xfb[firstBinding + i].buffer = buffer;
661 xfb[firstBinding + i].offset = pOffsets[i];
662 xfb[firstBinding + i].size =
663 vk_buffer_range(&buffer->vk, pOffsets[i],
664 pSizes ? pSizes[i] : VK_WHOLE_SIZE);
665 }
666 }
667 }
668
669 enum isl_format
anv_isl_format_for_descriptor_type(const struct anv_device * device,VkDescriptorType type)670 anv_isl_format_for_descriptor_type(const struct anv_device *device,
671 VkDescriptorType type)
672 {
673 switch (type) {
674 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
675 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
676 return device->physical->compiler->indirect_ubos_use_sampler ?
677 ISL_FORMAT_R32G32B32A32_FLOAT : ISL_FORMAT_RAW;
678
679 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
680 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
681 return ISL_FORMAT_RAW;
682
683 default:
684 unreachable("Invalid descriptor type");
685 }
686 }
687
688 struct anv_state
anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer * cmd_buffer,const void * data,uint32_t size,uint32_t alignment)689 anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer,
690 const void *data, uint32_t size, uint32_t alignment)
691 {
692 struct anv_state state;
693
694 state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, size, alignment);
695 memcpy(state.map, data, size);
696
697 VG(VALGRIND_CHECK_MEM_IS_DEFINED(state.map, size));
698
699 return state;
700 }
701
702 struct anv_state
anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer * cmd_buffer,uint32_t * a,uint32_t * b,uint32_t dwords,uint32_t alignment)703 anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer,
704 uint32_t *a, uint32_t *b,
705 uint32_t dwords, uint32_t alignment)
706 {
707 struct anv_state state;
708 uint32_t *p;
709
710 state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
711 dwords * 4, alignment);
712 p = state.map;
713 for (uint32_t i = 0; i < dwords; i++)
714 p[i] = a[i] | b[i];
715
716 VG(VALGRIND_CHECK_MEM_IS_DEFINED(p, dwords * 4));
717
718 return state;
719 }
720
721 struct anv_state
anv_cmd_buffer_gfx_push_constants(struct anv_cmd_buffer * cmd_buffer)722 anv_cmd_buffer_gfx_push_constants(struct anv_cmd_buffer *cmd_buffer)
723 {
724 struct anv_push_constants *data =
725 &cmd_buffer->state.gfx.base.push_constants;
726
727 struct anv_state state =
728 anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
729 sizeof(struct anv_push_constants),
730 32 /* bottom 5 bits MBZ */);
731 memcpy(state.map, data, sizeof(struct anv_push_constants));
732
733 return state;
734 }
735
736 struct anv_state
anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer * cmd_buffer)737 anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer)
738 {
739 const struct intel_device_info *devinfo = &cmd_buffer->device->info;
740 struct anv_push_constants *data =
741 &cmd_buffer->state.compute.base.push_constants;
742 struct anv_compute_pipeline *pipeline = cmd_buffer->state.compute.pipeline;
743 const struct brw_cs_prog_data *cs_prog_data = get_cs_prog_data(pipeline);
744 const struct anv_push_range *range = &pipeline->cs->bind_map.push_ranges[0];
745
746 const struct brw_cs_dispatch_info dispatch =
747 brw_cs_get_dispatch_info(devinfo, cs_prog_data, NULL);
748 const unsigned total_push_constants_size =
749 brw_cs_push_const_total_size(cs_prog_data, dispatch.threads);
750 if (total_push_constants_size == 0)
751 return (struct anv_state) { .offset = 0 };
752
753 const unsigned push_constant_alignment =
754 cmd_buffer->device->info.ver < 8 ? 32 : 64;
755 const unsigned aligned_total_push_constants_size =
756 ALIGN(total_push_constants_size, push_constant_alignment);
757 struct anv_state state;
758 if (devinfo->verx10 >= 125) {
759 state = anv_state_stream_alloc(&cmd_buffer->general_state_stream,
760 aligned_total_push_constants_size,
761 push_constant_alignment);
762 } else {
763 state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
764 aligned_total_push_constants_size,
765 push_constant_alignment);
766 }
767
768 void *dst = state.map;
769 const void *src = (char *)data + (range->start * 32);
770
771 if (cs_prog_data->push.cross_thread.size > 0) {
772 memcpy(dst, src, cs_prog_data->push.cross_thread.size);
773 dst += cs_prog_data->push.cross_thread.size;
774 src += cs_prog_data->push.cross_thread.size;
775 }
776
777 if (cs_prog_data->push.per_thread.size > 0) {
778 for (unsigned t = 0; t < dispatch.threads; t++) {
779 memcpy(dst, src, cs_prog_data->push.per_thread.size);
780
781 uint32_t *subgroup_id = dst +
782 offsetof(struct anv_push_constants, cs.subgroup_id) -
783 (range->start * 32 + cs_prog_data->push.cross_thread.size);
784 *subgroup_id = t;
785
786 dst += cs_prog_data->push.per_thread.size;
787 }
788 }
789
790 return state;
791 }
792
anv_CmdPushConstants(VkCommandBuffer commandBuffer,VkPipelineLayout layout,VkShaderStageFlags stageFlags,uint32_t offset,uint32_t size,const void * pValues)793 void anv_CmdPushConstants(
794 VkCommandBuffer commandBuffer,
795 VkPipelineLayout layout,
796 VkShaderStageFlags stageFlags,
797 uint32_t offset,
798 uint32_t size,
799 const void* pValues)
800 {
801 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
802
803 if (stageFlags & (VK_SHADER_STAGE_ALL_GRAPHICS |
804 VK_SHADER_STAGE_TASK_BIT_NV |
805 VK_SHADER_STAGE_MESH_BIT_NV)) {
806 struct anv_cmd_pipeline_state *pipe_state =
807 &cmd_buffer->state.gfx.base;
808
809 memcpy(pipe_state->push_constants.client_data + offset, pValues, size);
810 }
811 if (stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) {
812 struct anv_cmd_pipeline_state *pipe_state =
813 &cmd_buffer->state.compute.base;
814
815 memcpy(pipe_state->push_constants.client_data + offset, pValues, size);
816 }
817 if (stageFlags & (VK_SHADER_STAGE_RAYGEN_BIT_KHR |
818 VK_SHADER_STAGE_ANY_HIT_BIT_KHR |
819 VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR |
820 VK_SHADER_STAGE_MISS_BIT_KHR |
821 VK_SHADER_STAGE_INTERSECTION_BIT_KHR |
822 VK_SHADER_STAGE_CALLABLE_BIT_KHR)) {
823 struct anv_cmd_pipeline_state *pipe_state =
824 &cmd_buffer->state.rt.base;
825
826 memcpy(pipe_state->push_constants.client_data + offset, pValues, size);
827 }
828
829 cmd_buffer->state.push_constants_dirty |= stageFlags;
830 }
831
832 static struct anv_descriptor_set *
anv_cmd_buffer_push_descriptor_set(struct anv_cmd_buffer * cmd_buffer,VkPipelineBindPoint bind_point,struct anv_descriptor_set_layout * layout,uint32_t _set)833 anv_cmd_buffer_push_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
834 VkPipelineBindPoint bind_point,
835 struct anv_descriptor_set_layout *layout,
836 uint32_t _set)
837 {
838 struct anv_cmd_pipeline_state *pipe_state;
839
840 switch (bind_point) {
841 case VK_PIPELINE_BIND_POINT_GRAPHICS:
842 pipe_state = &cmd_buffer->state.gfx.base;
843 break;
844
845 case VK_PIPELINE_BIND_POINT_COMPUTE:
846 pipe_state = &cmd_buffer->state.compute.base;
847 break;
848
849 case VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR:
850 pipe_state = &cmd_buffer->state.rt.base;
851 break;
852
853 default:
854 unreachable("invalid bind point");
855 }
856
857 struct anv_push_descriptor_set **push_set =
858 &pipe_state->push_descriptors[_set];
859
860 if (*push_set == NULL) {
861 *push_set = vk_zalloc(&cmd_buffer->vk.pool->alloc,
862 sizeof(struct anv_push_descriptor_set), 8,
863 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
864 if (*push_set == NULL) {
865 anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_OUT_OF_HOST_MEMORY);
866 return NULL;
867 }
868 }
869
870 struct anv_descriptor_set *set = &(*push_set)->set;
871
872 if (set->layout != layout) {
873 if (set->layout)
874 anv_descriptor_set_layout_unref(cmd_buffer->device, set->layout);
875 anv_descriptor_set_layout_ref(layout);
876 set->layout = layout;
877 }
878 set->size = anv_descriptor_set_layout_size(layout, 0);
879 set->buffer_view_count = layout->buffer_view_count;
880 set->descriptor_count = layout->descriptor_count;
881 set->buffer_views = (*push_set)->buffer_views;
882
883 if (layout->descriptor_buffer_size &&
884 ((*push_set)->set_used_on_gpu ||
885 set->desc_mem.alloc_size < layout->descriptor_buffer_size)) {
886 /* The previous buffer is either actively used by some GPU command (so
887 * we can't modify it) or is too small. Allocate a new one.
888 */
889 struct anv_state desc_mem =
890 anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream,
891 anv_descriptor_set_layout_descriptor_buffer_size(layout, 0),
892 ANV_UBO_ALIGNMENT);
893 if (set->desc_mem.alloc_size) {
894 /* TODO: Do we really need to copy all the time? */
895 memcpy(desc_mem.map, set->desc_mem.map,
896 MIN2(desc_mem.alloc_size, set->desc_mem.alloc_size));
897 }
898 set->desc_mem = desc_mem;
899
900 set->desc_addr = (struct anv_address) {
901 .bo = cmd_buffer->dynamic_state_stream.state_pool->block_pool.bo,
902 .offset = set->desc_mem.offset,
903 };
904
905 enum isl_format format =
906 anv_isl_format_for_descriptor_type(cmd_buffer->device,
907 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
908
909 const struct isl_device *isl_dev = &cmd_buffer->device->isl_dev;
910 set->desc_surface_state =
911 anv_state_stream_alloc(&cmd_buffer->surface_state_stream,
912 isl_dev->ss.size, isl_dev->ss.align);
913 anv_fill_buffer_surface_state(cmd_buffer->device,
914 set->desc_surface_state,
915 format, ISL_SWIZZLE_IDENTITY,
916 ISL_SURF_USAGE_CONSTANT_BUFFER_BIT,
917 set->desc_addr,
918 layout->descriptor_buffer_size, 1);
919 }
920
921 return set;
922 }
923
anv_CmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer,VkPipelineBindPoint pipelineBindPoint,VkPipelineLayout _layout,uint32_t _set,uint32_t descriptorWriteCount,const VkWriteDescriptorSet * pDescriptorWrites)924 void anv_CmdPushDescriptorSetKHR(
925 VkCommandBuffer commandBuffer,
926 VkPipelineBindPoint pipelineBindPoint,
927 VkPipelineLayout _layout,
928 uint32_t _set,
929 uint32_t descriptorWriteCount,
930 const VkWriteDescriptorSet* pDescriptorWrites)
931 {
932 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
933 ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
934
935 assert(_set < MAX_SETS);
936
937 struct anv_descriptor_set_layout *set_layout = layout->set[_set].layout;
938
939 struct anv_descriptor_set *set =
940 anv_cmd_buffer_push_descriptor_set(cmd_buffer, pipelineBindPoint,
941 set_layout, _set);
942 if (!set)
943 return;
944
945 /* Go through the user supplied descriptors. */
946 for (uint32_t i = 0; i < descriptorWriteCount; i++) {
947 const VkWriteDescriptorSet *write = &pDescriptorWrites[i];
948
949 switch (write->descriptorType) {
950 case VK_DESCRIPTOR_TYPE_SAMPLER:
951 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
952 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
953 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
954 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
955 for (uint32_t j = 0; j < write->descriptorCount; j++) {
956 anv_descriptor_set_write_image_view(cmd_buffer->device, set,
957 write->pImageInfo + j,
958 write->descriptorType,
959 write->dstBinding,
960 write->dstArrayElement + j);
961 }
962 break;
963
964 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
965 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
966 for (uint32_t j = 0; j < write->descriptorCount; j++) {
967 ANV_FROM_HANDLE(anv_buffer_view, bview,
968 write->pTexelBufferView[j]);
969
970 anv_descriptor_set_write_buffer_view(cmd_buffer->device, set,
971 write->descriptorType,
972 bview,
973 write->dstBinding,
974 write->dstArrayElement + j);
975 }
976 break;
977
978 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
979 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
980 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
981 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
982 for (uint32_t j = 0; j < write->descriptorCount; j++) {
983 ANV_FROM_HANDLE(anv_buffer, buffer, write->pBufferInfo[j].buffer);
984
985 anv_descriptor_set_write_buffer(cmd_buffer->device, set,
986 &cmd_buffer->surface_state_stream,
987 write->descriptorType,
988 buffer,
989 write->dstBinding,
990 write->dstArrayElement + j,
991 write->pBufferInfo[j].offset,
992 write->pBufferInfo[j].range);
993 }
994 break;
995
996 case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: {
997 const VkWriteDescriptorSetAccelerationStructureKHR *accel_write =
998 vk_find_struct_const(write, WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR);
999 assert(accel_write->accelerationStructureCount ==
1000 write->descriptorCount);
1001 for (uint32_t j = 0; j < write->descriptorCount; j++) {
1002 ANV_FROM_HANDLE(anv_acceleration_structure, accel,
1003 accel_write->pAccelerationStructures[j]);
1004 anv_descriptor_set_write_acceleration_structure(cmd_buffer->device,
1005 set, accel,
1006 write->dstBinding,
1007 write->dstArrayElement + j);
1008 }
1009 break;
1010 }
1011
1012 default:
1013 break;
1014 }
1015 }
1016
1017 anv_cmd_buffer_bind_descriptor_set(cmd_buffer, pipelineBindPoint,
1018 layout, _set, set, NULL, NULL);
1019 }
1020
anv_CmdPushDescriptorSetWithTemplateKHR(VkCommandBuffer commandBuffer,VkDescriptorUpdateTemplate descriptorUpdateTemplate,VkPipelineLayout _layout,uint32_t _set,const void * pData)1021 void anv_CmdPushDescriptorSetWithTemplateKHR(
1022 VkCommandBuffer commandBuffer,
1023 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
1024 VkPipelineLayout _layout,
1025 uint32_t _set,
1026 const void* pData)
1027 {
1028 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1029 ANV_FROM_HANDLE(anv_descriptor_update_template, template,
1030 descriptorUpdateTemplate);
1031 ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
1032
1033 assert(_set < MAX_PUSH_DESCRIPTORS);
1034
1035 struct anv_descriptor_set_layout *set_layout = layout->set[_set].layout;
1036
1037 struct anv_descriptor_set *set =
1038 anv_cmd_buffer_push_descriptor_set(cmd_buffer, template->bind_point,
1039 set_layout, _set);
1040 if (!set)
1041 return;
1042
1043 anv_descriptor_set_write_template(cmd_buffer->device, set,
1044 &cmd_buffer->surface_state_stream,
1045 template,
1046 pData);
1047
1048 anv_cmd_buffer_bind_descriptor_set(cmd_buffer, template->bind_point,
1049 layout, _set, set, NULL, NULL);
1050 }
1051
anv_CmdSetDeviceMask(VkCommandBuffer commandBuffer,uint32_t deviceMask)1052 void anv_CmdSetDeviceMask(
1053 VkCommandBuffer commandBuffer,
1054 uint32_t deviceMask)
1055 {
1056 /* No-op */
1057 }
1058
anv_CmdSetRayTracingPipelineStackSizeKHR(VkCommandBuffer commandBuffer,uint32_t pipelineStackSize)1059 void anv_CmdSetRayTracingPipelineStackSizeKHR(
1060 VkCommandBuffer commandBuffer,
1061 uint32_t pipelineStackSize)
1062 {
1063 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1064 struct anv_cmd_ray_tracing_state *rt = &cmd_buffer->state.rt;
1065 struct anv_device *device = cmd_buffer->device;
1066
1067 if (anv_batch_has_error(&cmd_buffer->batch))
1068 return;
1069
1070 uint32_t stack_ids_per_dss = 2048; /* TODO */
1071
1072 unsigned stack_size_log2 = ilog2_round_up(pipelineStackSize);
1073 if (stack_size_log2 < 10)
1074 stack_size_log2 = 10;
1075
1076 if (rt->scratch.layout.total_size == 1 << stack_size_log2)
1077 return;
1078
1079 brw_rt_compute_scratch_layout(&rt->scratch.layout, &device->info,
1080 stack_ids_per_dss, 1 << stack_size_log2);
1081
1082 unsigned bucket = stack_size_log2 - 10;
1083 assert(bucket < ARRAY_SIZE(device->rt_scratch_bos));
1084
1085 struct anv_bo *bo = p_atomic_read(&device->rt_scratch_bos[bucket]);
1086 if (bo == NULL) {
1087 struct anv_bo *new_bo;
1088 VkResult result = anv_device_alloc_bo(device, "RT scratch",
1089 rt->scratch.layout.total_size,
1090 ANV_BO_ALLOC_LOCAL_MEM,
1091 0, /* explicit_address */
1092 &new_bo);
1093 if (result != VK_SUCCESS) {
1094 rt->scratch.layout.total_size = 0;
1095 anv_batch_set_error(&cmd_buffer->batch, result);
1096 return;
1097 }
1098
1099 bo = p_atomic_cmpxchg(&device->rt_scratch_bos[bucket], NULL, new_bo);
1100 if (bo != NULL) {
1101 anv_device_release_bo(device, bo);
1102 } else {
1103 bo = new_bo;
1104 }
1105 }
1106
1107 rt->scratch.bo = bo;
1108 }
1109