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