• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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