• 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 
32 #include "vk_format_info.h"
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 };
104 
105 /**
106  * Copy the dynamic state from src to dest based on the copy_mask.
107  *
108  * Avoid copying states that have not changed, except for VIEWPORT, SCISSOR and
109  * BLEND_CONSTANTS (always copy them if they are in the copy_mask).
110  *
111  * Returns a mask of the states which changed.
112  */
113 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)114 anv_dynamic_state_copy(struct anv_dynamic_state *dest,
115                        const struct anv_dynamic_state *src,
116                        anv_cmd_dirty_mask_t copy_mask)
117 {
118    anv_cmd_dirty_mask_t changed = 0;
119 
120    if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_VIEWPORT) {
121       dest->viewport.count = src->viewport.count;
122       typed_memcpy(dest->viewport.viewports, src->viewport.viewports,
123                    src->viewport.count);
124       changed |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT;
125    }
126 
127    if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_SCISSOR) {
128       dest->scissor.count = src->scissor.count;
129       typed_memcpy(dest->scissor.scissors, src->scissor.scissors,
130                    src->scissor.count);
131       changed |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR;
132    }
133 
134    if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS) {
135       typed_memcpy(dest->blend_constants, src->blend_constants, 4);
136       changed |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS;
137    }
138 
139 #define ANV_CMP_COPY(field, flag)                                 \
140    if (copy_mask & flag) {                                        \
141       if (dest->field != src->field) {                            \
142          dest->field = src->field;                                \
143          changed |= flag;                                         \
144       }                                                           \
145    }
146 
147    ANV_CMP_COPY(line_width, ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH);
148 
149    ANV_CMP_COPY(depth_bias.bias, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS);
150    ANV_CMP_COPY(depth_bias.clamp, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS);
151    ANV_CMP_COPY(depth_bias.slope, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS);
152 
153    ANV_CMP_COPY(depth_bounds.min, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS);
154    ANV_CMP_COPY(depth_bounds.max, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS);
155 
156    ANV_CMP_COPY(stencil_compare_mask.front, ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK);
157    ANV_CMP_COPY(stencil_compare_mask.back, ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK);
158 
159    ANV_CMP_COPY(stencil_write_mask.front, ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK);
160    ANV_CMP_COPY(stencil_write_mask.back, ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK);
161 
162    ANV_CMP_COPY(stencil_reference.front, ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE);
163    ANV_CMP_COPY(stencil_reference.back, ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE);
164 
165    ANV_CMP_COPY(line_stipple.factor, ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE);
166    ANV_CMP_COPY(line_stipple.pattern, ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE);
167 
168    ANV_CMP_COPY(cull_mode, ANV_CMD_DIRTY_DYNAMIC_CULL_MODE);
169    ANV_CMP_COPY(front_face, ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE);
170    ANV_CMP_COPY(primitive_topology, ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY);
171    ANV_CMP_COPY(depth_test_enable, ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE);
172    ANV_CMP_COPY(depth_write_enable, ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE);
173    ANV_CMP_COPY(depth_compare_op, ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP);
174    ANV_CMP_COPY(depth_bounds_test_enable, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE);
175    ANV_CMP_COPY(stencil_test_enable, ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE);
176 
177    if (copy_mask & VK_DYNAMIC_STATE_STENCIL_OP_EXT) {
178       ANV_CMP_COPY(stencil_op.front.fail_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
179       ANV_CMP_COPY(stencil_op.front.pass_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
180       ANV_CMP_COPY(stencil_op.front.depth_fail_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
181       ANV_CMP_COPY(stencil_op.front.compare_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
182       ANV_CMP_COPY(stencil_op.back.fail_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
183       ANV_CMP_COPY(stencil_op.back.pass_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
184       ANV_CMP_COPY(stencil_op.back.depth_fail_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
185       ANV_CMP_COPY(stencil_op.back.compare_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
186    }
187 
188    ANV_CMP_COPY(dyn_vbo_stride, ANV_CMD_DIRTY_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE);
189    ANV_CMP_COPY(dyn_vbo_size, ANV_CMD_DIRTY_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE);
190 
191 #undef ANV_CMP_COPY
192 
193    return changed;
194 }
195 
196 static void
anv_cmd_state_init(struct anv_cmd_buffer * cmd_buffer)197 anv_cmd_state_init(struct anv_cmd_buffer *cmd_buffer)
198 {
199    struct anv_cmd_state *state = &cmd_buffer->state;
200 
201    memset(state, 0, sizeof(*state));
202 
203    state->current_pipeline = UINT32_MAX;
204    state->restart_index = UINT32_MAX;
205    state->gfx.dynamic = default_dynamic_state;
206 }
207 
208 static void
anv_cmd_pipeline_state_finish(struct anv_cmd_buffer * cmd_buffer,struct anv_cmd_pipeline_state * pipe_state)209 anv_cmd_pipeline_state_finish(struct anv_cmd_buffer *cmd_buffer,
210                               struct anv_cmd_pipeline_state *pipe_state)
211 {
212    for (uint32_t i = 0; i < ARRAY_SIZE(pipe_state->push_descriptors); i++) {
213       if (pipe_state->push_descriptors[i]) {
214          anv_descriptor_set_layout_unref(cmd_buffer->device,
215              pipe_state->push_descriptors[i]->set.layout);
216          vk_free(&cmd_buffer->pool->alloc, pipe_state->push_descriptors[i]);
217       }
218    }
219 }
220 
221 static void
anv_cmd_state_finish(struct anv_cmd_buffer * cmd_buffer)222 anv_cmd_state_finish(struct anv_cmd_buffer *cmd_buffer)
223 {
224    struct anv_cmd_state *state = &cmd_buffer->state;
225 
226    anv_cmd_pipeline_state_finish(cmd_buffer, &state->gfx.base);
227    anv_cmd_pipeline_state_finish(cmd_buffer, &state->compute.base);
228 
229    vk_free(&cmd_buffer->pool->alloc, state->attachments);
230 }
231 
232 static void
anv_cmd_state_reset(struct anv_cmd_buffer * cmd_buffer)233 anv_cmd_state_reset(struct anv_cmd_buffer *cmd_buffer)
234 {
235    anv_cmd_state_finish(cmd_buffer);
236    anv_cmd_state_init(cmd_buffer);
237 }
238 
anv_create_cmd_buffer(struct anv_device * device,struct anv_cmd_pool * pool,VkCommandBufferLevel level,VkCommandBuffer * pCommandBuffer)239 static VkResult anv_create_cmd_buffer(
240     struct anv_device *                         device,
241     struct anv_cmd_pool *                       pool,
242     VkCommandBufferLevel                        level,
243     VkCommandBuffer*                            pCommandBuffer)
244 {
245    struct anv_cmd_buffer *cmd_buffer;
246    VkResult result;
247 
248    cmd_buffer = vk_alloc(&pool->alloc, sizeof(*cmd_buffer), 8,
249                           VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
250    if (cmd_buffer == NULL)
251       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
252 
253    vk_object_base_init(&device->vk, &cmd_buffer->base,
254                        VK_OBJECT_TYPE_COMMAND_BUFFER);
255 
256    cmd_buffer->batch.status = VK_SUCCESS;
257 
258    cmd_buffer->device = device;
259    cmd_buffer->pool = pool;
260    cmd_buffer->level = level;
261 
262    result = anv_cmd_buffer_init_batch_bo_chain(cmd_buffer);
263    if (result != VK_SUCCESS)
264       goto fail;
265 
266    anv_state_stream_init(&cmd_buffer->surface_state_stream,
267                          &device->surface_state_pool, 4096);
268    anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
269                          &device->dynamic_state_pool, 16384);
270 
271    anv_cmd_state_init(cmd_buffer);
272 
273    list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers);
274 
275    *pCommandBuffer = anv_cmd_buffer_to_handle(cmd_buffer);
276 
277    return VK_SUCCESS;
278 
279  fail:
280    vk_free(&cmd_buffer->pool->alloc, cmd_buffer);
281 
282    return result;
283 }
284 
anv_AllocateCommandBuffers(VkDevice _device,const VkCommandBufferAllocateInfo * pAllocateInfo,VkCommandBuffer * pCommandBuffers)285 VkResult anv_AllocateCommandBuffers(
286     VkDevice                                    _device,
287     const VkCommandBufferAllocateInfo*          pAllocateInfo,
288     VkCommandBuffer*                            pCommandBuffers)
289 {
290    ANV_FROM_HANDLE(anv_device, device, _device);
291    ANV_FROM_HANDLE(anv_cmd_pool, pool, pAllocateInfo->commandPool);
292 
293    VkResult result = VK_SUCCESS;
294    uint32_t i;
295 
296    for (i = 0; i < pAllocateInfo->commandBufferCount; i++) {
297       result = anv_create_cmd_buffer(device, pool, pAllocateInfo->level,
298                                      &pCommandBuffers[i]);
299       if (result != VK_SUCCESS)
300          break;
301    }
302 
303    if (result != VK_SUCCESS) {
304       anv_FreeCommandBuffers(_device, pAllocateInfo->commandPool,
305                              i, pCommandBuffers);
306       for (i = 0; i < pAllocateInfo->commandBufferCount; i++)
307          pCommandBuffers[i] = VK_NULL_HANDLE;
308    }
309 
310    return result;
311 }
312 
313 static void
anv_cmd_buffer_destroy(struct anv_cmd_buffer * cmd_buffer)314 anv_cmd_buffer_destroy(struct anv_cmd_buffer *cmd_buffer)
315 {
316    list_del(&cmd_buffer->pool_link);
317 
318    anv_cmd_buffer_fini_batch_bo_chain(cmd_buffer);
319 
320    anv_state_stream_finish(&cmd_buffer->surface_state_stream);
321    anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
322 
323    anv_cmd_state_finish(cmd_buffer);
324 
325    vk_object_base_finish(&cmd_buffer->base);
326    vk_free(&cmd_buffer->pool->alloc, cmd_buffer);
327 }
328 
anv_FreeCommandBuffers(VkDevice device,VkCommandPool commandPool,uint32_t commandBufferCount,const VkCommandBuffer * pCommandBuffers)329 void anv_FreeCommandBuffers(
330     VkDevice                                    device,
331     VkCommandPool                               commandPool,
332     uint32_t                                    commandBufferCount,
333     const VkCommandBuffer*                      pCommandBuffers)
334 {
335    for (uint32_t i = 0; i < commandBufferCount; i++) {
336       ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, pCommandBuffers[i]);
337 
338       if (!cmd_buffer)
339          continue;
340 
341       anv_cmd_buffer_destroy(cmd_buffer);
342    }
343 }
344 
345 VkResult
anv_cmd_buffer_reset(struct anv_cmd_buffer * cmd_buffer)346 anv_cmd_buffer_reset(struct anv_cmd_buffer *cmd_buffer)
347 {
348    cmd_buffer->usage_flags = 0;
349    cmd_buffer->perf_query_pool = NULL;
350    anv_cmd_buffer_reset_batch_bo_chain(cmd_buffer);
351    anv_cmd_state_reset(cmd_buffer);
352 
353    anv_state_stream_finish(&cmd_buffer->surface_state_stream);
354    anv_state_stream_init(&cmd_buffer->surface_state_stream,
355                          &cmd_buffer->device->surface_state_pool, 4096);
356 
357    anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
358    anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
359                          &cmd_buffer->device->dynamic_state_pool, 16384);
360    return VK_SUCCESS;
361 }
362 
anv_ResetCommandBuffer(VkCommandBuffer commandBuffer,VkCommandBufferResetFlags flags)363 VkResult anv_ResetCommandBuffer(
364     VkCommandBuffer                             commandBuffer,
365     VkCommandBufferResetFlags                   flags)
366 {
367    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
368    return anv_cmd_buffer_reset(cmd_buffer);
369 }
370 
371 #define anv_genX_call(devinfo, func, ...)          \
372    switch ((devinfo)->gen) {                       \
373    case 7:                                         \
374       if ((devinfo)->is_haswell) {                 \
375          gen75_##func(__VA_ARGS__);                \
376       } else {                                     \
377          gen7_##func(__VA_ARGS__);                 \
378       }                                            \
379       break;                                       \
380    case 8:                                         \
381       gen8_##func(__VA_ARGS__);                    \
382       break;                                       \
383    case 9:                                         \
384       gen9_##func(__VA_ARGS__);                    \
385       break;                                       \
386    case 11:                                        \
387       gen11_##func(__VA_ARGS__);                   \
388       break;                                       \
389    case 12:                                        \
390       gen12_##func(__VA_ARGS__);                   \
391       break;                                       \
392    default:                                        \
393       assert(!"Unknown hardware generation");      \
394    }
395 
396 void
anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer * cmd_buffer)397 anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer)
398 {
399    anv_genX_call(&cmd_buffer->device->info,
400                  cmd_buffer_emit_state_base_address,
401                  cmd_buffer);
402 }
403 
404 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)405 anv_cmd_buffer_mark_image_written(struct anv_cmd_buffer *cmd_buffer,
406                                   const struct anv_image *image,
407                                   VkImageAspectFlagBits aspect,
408                                   enum isl_aux_usage aux_usage,
409                                   uint32_t level,
410                                   uint32_t base_layer,
411                                   uint32_t layer_count)
412 {
413    anv_genX_call(&cmd_buffer->device->info,
414                  cmd_buffer_mark_image_written,
415                  cmd_buffer, image, aspect, aux_usage,
416                  level, base_layer, layer_count);
417 }
418 
419 void
anv_cmd_emit_conditional_render_predicate(struct anv_cmd_buffer * cmd_buffer)420 anv_cmd_emit_conditional_render_predicate(struct anv_cmd_buffer *cmd_buffer)
421 {
422    anv_genX_call(&cmd_buffer->device->info,
423                  cmd_emit_conditional_render_predicate,
424                  cmd_buffer);
425 }
426 
427 static bool
mem_update(void * dst,const void * src,size_t size)428 mem_update(void *dst, const void *src, size_t size)
429 {
430    if (memcmp(dst, src, size) == 0)
431       return false;
432 
433    memcpy(dst, src, size);
434    return true;
435 }
436 
437 static void
set_dirty_for_bind_map(struct anv_cmd_buffer * cmd_buffer,gl_shader_stage stage,const struct anv_pipeline_bind_map * map)438 set_dirty_for_bind_map(struct anv_cmd_buffer *cmd_buffer,
439                        gl_shader_stage stage,
440                        const struct anv_pipeline_bind_map *map)
441 {
442    if (mem_update(cmd_buffer->state.surface_sha1s[stage],
443                   map->surface_sha1, sizeof(map->surface_sha1)))
444       cmd_buffer->state.descriptors_dirty |= mesa_to_vk_shader_stage(stage);
445 
446    if (mem_update(cmd_buffer->state.sampler_sha1s[stage],
447                   map->sampler_sha1, sizeof(map->sampler_sha1)))
448       cmd_buffer->state.descriptors_dirty |= mesa_to_vk_shader_stage(stage);
449 
450    if (mem_update(cmd_buffer->state.push_sha1s[stage],
451                   map->push_sha1, sizeof(map->push_sha1)))
452       cmd_buffer->state.push_constants_dirty |= mesa_to_vk_shader_stage(stage);
453 }
454 
anv_CmdBindPipeline(VkCommandBuffer commandBuffer,VkPipelineBindPoint pipelineBindPoint,VkPipeline _pipeline)455 void anv_CmdBindPipeline(
456     VkCommandBuffer                             commandBuffer,
457     VkPipelineBindPoint                         pipelineBindPoint,
458     VkPipeline                                  _pipeline)
459 {
460    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
461    ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline);
462 
463    switch (pipelineBindPoint) {
464    case VK_PIPELINE_BIND_POINT_COMPUTE: {
465       struct anv_compute_pipeline *compute_pipeline =
466          anv_pipeline_to_compute(pipeline);
467       if (cmd_buffer->state.compute.pipeline == compute_pipeline)
468          return;
469 
470       cmd_buffer->state.compute.pipeline = compute_pipeline;
471       cmd_buffer->state.compute.pipeline_dirty = true;
472       set_dirty_for_bind_map(cmd_buffer, MESA_SHADER_COMPUTE,
473                              &compute_pipeline->cs->bind_map);
474       break;
475    }
476 
477    case VK_PIPELINE_BIND_POINT_GRAPHICS: {
478       struct anv_graphics_pipeline *gfx_pipeline =
479          anv_pipeline_to_graphics(pipeline);
480       if (cmd_buffer->state.gfx.pipeline == gfx_pipeline)
481          return;
482 
483       cmd_buffer->state.gfx.pipeline = gfx_pipeline;
484       cmd_buffer->state.gfx.vb_dirty |= gfx_pipeline->vb_used;
485       cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_PIPELINE;
486 
487       anv_foreach_stage(stage, gfx_pipeline->active_stages) {
488          set_dirty_for_bind_map(cmd_buffer, stage,
489                                 &gfx_pipeline->shaders[stage]->bind_map);
490       }
491 
492       /* Apply the dynamic state from the pipeline */
493       cmd_buffer->state.gfx.dirty |=
494          anv_dynamic_state_copy(&cmd_buffer->state.gfx.dynamic,
495                                 &gfx_pipeline->dynamic_state,
496                                 gfx_pipeline->dynamic_state_mask);
497       break;
498    }
499 
500    default:
501       assert(!"invalid bind point");
502       break;
503    }
504 }
505 
anv_CmdSetViewport(VkCommandBuffer commandBuffer,uint32_t firstViewport,uint32_t viewportCount,const VkViewport * pViewports)506 void anv_CmdSetViewport(
507     VkCommandBuffer                             commandBuffer,
508     uint32_t                                    firstViewport,
509     uint32_t                                    viewportCount,
510     const VkViewport*                           pViewports)
511 {
512    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
513 
514    const uint32_t total_count = firstViewport + viewportCount;
515    if (cmd_buffer->state.gfx.dynamic.viewport.count < total_count)
516       cmd_buffer->state.gfx.dynamic.viewport.count = total_count;
517 
518    memcpy(cmd_buffer->state.gfx.dynamic.viewport.viewports + firstViewport,
519           pViewports, viewportCount * sizeof(*pViewports));
520 
521    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT;
522 }
523 
anv_CmdSetViewportWithCountEXT(VkCommandBuffer commandBuffer,uint32_t viewportCount,const VkViewport * pViewports)524 void anv_CmdSetViewportWithCountEXT(
525    VkCommandBuffer                              commandBuffer,
526    uint32_t                                     viewportCount,
527    const VkViewport*                            pViewports)
528 {
529    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
530 
531    cmd_buffer->state.gfx.dynamic.viewport.count = viewportCount;
532 
533    memcpy(cmd_buffer->state.gfx.dynamic.viewport.viewports,
534           pViewports, viewportCount * sizeof(*pViewports));
535 
536    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT;
537 }
538 
anv_CmdSetScissor(VkCommandBuffer commandBuffer,uint32_t firstScissor,uint32_t scissorCount,const VkRect2D * pScissors)539 void anv_CmdSetScissor(
540     VkCommandBuffer                             commandBuffer,
541     uint32_t                                    firstScissor,
542     uint32_t                                    scissorCount,
543     const VkRect2D*                             pScissors)
544 {
545    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
546 
547    const uint32_t total_count = firstScissor + scissorCount;
548    if (cmd_buffer->state.gfx.dynamic.scissor.count < total_count)
549       cmd_buffer->state.gfx.dynamic.scissor.count = total_count;
550 
551    memcpy(cmd_buffer->state.gfx.dynamic.scissor.scissors + firstScissor,
552           pScissors, scissorCount * sizeof(*pScissors));
553 
554    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR;
555 }
556 
anv_CmdSetScissorWithCountEXT(VkCommandBuffer commandBuffer,uint32_t scissorCount,const VkRect2D * pScissors)557 void anv_CmdSetScissorWithCountEXT(
558    VkCommandBuffer                              commandBuffer,
559    uint32_t                                     scissorCount,
560    const VkRect2D*                              pScissors)
561 {
562    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
563 
564    cmd_buffer->state.gfx.dynamic.scissor.count = scissorCount;
565 
566    memcpy(cmd_buffer->state.gfx.dynamic.scissor.scissors,
567           pScissors, scissorCount * sizeof(*pScissors));
568 
569    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR;
570 }
571 
anv_CmdSetPrimitiveTopologyEXT(VkCommandBuffer commandBuffer,VkPrimitiveTopology primitiveTopology)572 void anv_CmdSetPrimitiveTopologyEXT(
573    VkCommandBuffer                              commandBuffer,
574    VkPrimitiveTopology                          primitiveTopology)
575 {
576    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
577 
578    cmd_buffer->state.gfx.dynamic.primitive_topology = primitiveTopology;
579 
580    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY;
581 }
582 
anv_CmdSetLineWidth(VkCommandBuffer commandBuffer,float lineWidth)583 void anv_CmdSetLineWidth(
584     VkCommandBuffer                             commandBuffer,
585     float                                       lineWidth)
586 {
587    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
588 
589    cmd_buffer->state.gfx.dynamic.line_width = lineWidth;
590    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH;
591 }
592 
anv_CmdSetDepthBias(VkCommandBuffer commandBuffer,float depthBiasConstantFactor,float depthBiasClamp,float depthBiasSlopeFactor)593 void anv_CmdSetDepthBias(
594     VkCommandBuffer                             commandBuffer,
595     float                                       depthBiasConstantFactor,
596     float                                       depthBiasClamp,
597     float                                       depthBiasSlopeFactor)
598 {
599    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
600 
601    cmd_buffer->state.gfx.dynamic.depth_bias.bias = depthBiasConstantFactor;
602    cmd_buffer->state.gfx.dynamic.depth_bias.clamp = depthBiasClamp;
603    cmd_buffer->state.gfx.dynamic.depth_bias.slope = depthBiasSlopeFactor;
604 
605    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS;
606 }
607 
anv_CmdSetBlendConstants(VkCommandBuffer commandBuffer,const float blendConstants[4])608 void anv_CmdSetBlendConstants(
609     VkCommandBuffer                             commandBuffer,
610     const float                                 blendConstants[4])
611 {
612    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
613 
614    memcpy(cmd_buffer->state.gfx.dynamic.blend_constants,
615           blendConstants, sizeof(float) * 4);
616 
617    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS;
618 }
619 
anv_CmdSetDepthBounds(VkCommandBuffer commandBuffer,float minDepthBounds,float maxDepthBounds)620 void anv_CmdSetDepthBounds(
621     VkCommandBuffer                             commandBuffer,
622     float                                       minDepthBounds,
623     float                                       maxDepthBounds)
624 {
625    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
626 
627    cmd_buffer->state.gfx.dynamic.depth_bounds.min = minDepthBounds;
628    cmd_buffer->state.gfx.dynamic.depth_bounds.max = maxDepthBounds;
629 
630    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS;
631 }
632 
anv_CmdSetStencilCompareMask(VkCommandBuffer commandBuffer,VkStencilFaceFlags faceMask,uint32_t compareMask)633 void anv_CmdSetStencilCompareMask(
634     VkCommandBuffer                             commandBuffer,
635     VkStencilFaceFlags                          faceMask,
636     uint32_t                                    compareMask)
637 {
638    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
639 
640    if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
641       cmd_buffer->state.gfx.dynamic.stencil_compare_mask.front = compareMask;
642    if (faceMask & VK_STENCIL_FACE_BACK_BIT)
643       cmd_buffer->state.gfx.dynamic.stencil_compare_mask.back = compareMask;
644 
645    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK;
646 }
647 
anv_CmdSetStencilWriteMask(VkCommandBuffer commandBuffer,VkStencilFaceFlags faceMask,uint32_t writeMask)648 void anv_CmdSetStencilWriteMask(
649     VkCommandBuffer                             commandBuffer,
650     VkStencilFaceFlags                          faceMask,
651     uint32_t                                    writeMask)
652 {
653    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
654 
655    if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
656       cmd_buffer->state.gfx.dynamic.stencil_write_mask.front = writeMask;
657    if (faceMask & VK_STENCIL_FACE_BACK_BIT)
658       cmd_buffer->state.gfx.dynamic.stencil_write_mask.back = writeMask;
659 
660    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK;
661 }
662 
anv_CmdSetStencilReference(VkCommandBuffer commandBuffer,VkStencilFaceFlags faceMask,uint32_t reference)663 void anv_CmdSetStencilReference(
664     VkCommandBuffer                             commandBuffer,
665     VkStencilFaceFlags                          faceMask,
666     uint32_t                                    reference)
667 {
668    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
669 
670    if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
671       cmd_buffer->state.gfx.dynamic.stencil_reference.front = reference;
672    if (faceMask & VK_STENCIL_FACE_BACK_BIT)
673       cmd_buffer->state.gfx.dynamic.stencil_reference.back = reference;
674 
675    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE;
676 }
677 
anv_CmdSetLineStippleEXT(VkCommandBuffer commandBuffer,uint32_t lineStippleFactor,uint16_t lineStipplePattern)678 void anv_CmdSetLineStippleEXT(
679     VkCommandBuffer                             commandBuffer,
680     uint32_t                                    lineStippleFactor,
681     uint16_t                                    lineStipplePattern)
682 {
683    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
684 
685    cmd_buffer->state.gfx.dynamic.line_stipple.factor = lineStippleFactor;
686    cmd_buffer->state.gfx.dynamic.line_stipple.pattern = lineStipplePattern;
687 
688    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE;
689 }
690 
anv_CmdSetCullModeEXT(VkCommandBuffer commandBuffer,VkCullModeFlags cullMode)691 void anv_CmdSetCullModeEXT(
692    VkCommandBuffer                              commandBuffer,
693    VkCullModeFlags                              cullMode)
694 {
695    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
696 
697    cmd_buffer->state.gfx.dynamic.cull_mode = cullMode;
698 
699    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_CULL_MODE;
700 }
701 
anv_CmdSetFrontFaceEXT(VkCommandBuffer commandBuffer,VkFrontFace frontFace)702 void anv_CmdSetFrontFaceEXT(
703    VkCommandBuffer                              commandBuffer,
704    VkFrontFace                                  frontFace)
705 {
706    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
707 
708    cmd_buffer->state.gfx.dynamic.front_face = frontFace;
709 
710    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE;
711 }
712 
anv_CmdSetDepthTestEnableEXT(VkCommandBuffer commandBuffer,VkBool32 depthTestEnable)713 void anv_CmdSetDepthTestEnableEXT(
714    VkCommandBuffer                              commandBuffer,
715    VkBool32                                     depthTestEnable)
716 
717 {
718    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
719 
720    cmd_buffer->state.gfx.dynamic.depth_test_enable = depthTestEnable;
721 
722    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE;
723 }
724 
anv_CmdSetDepthWriteEnableEXT(VkCommandBuffer commandBuffer,VkBool32 depthWriteEnable)725 void anv_CmdSetDepthWriteEnableEXT(
726    VkCommandBuffer                              commandBuffer,
727    VkBool32                                     depthWriteEnable)
728 {
729    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
730 
731    cmd_buffer->state.gfx.dynamic.depth_write_enable = depthWriteEnable;
732 
733    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE;
734 }
735 
anv_CmdSetDepthCompareOpEXT(VkCommandBuffer commandBuffer,VkCompareOp depthCompareOp)736 void anv_CmdSetDepthCompareOpEXT(
737    VkCommandBuffer                              commandBuffer,
738    VkCompareOp                                  depthCompareOp)
739 {
740    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
741 
742    cmd_buffer->state.gfx.dynamic.depth_compare_op = depthCompareOp;
743 
744    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP;
745 }
746 
anv_CmdSetDepthBoundsTestEnableEXT(VkCommandBuffer commandBuffer,VkBool32 depthBoundsTestEnable)747 void anv_CmdSetDepthBoundsTestEnableEXT(
748    VkCommandBuffer                              commandBuffer,
749    VkBool32                                     depthBoundsTestEnable)
750 {
751    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
752 
753    cmd_buffer->state.gfx.dynamic.depth_bounds_test_enable = depthBoundsTestEnable;
754 
755    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE;
756 }
757 
anv_CmdSetStencilTestEnableEXT(VkCommandBuffer commandBuffer,VkBool32 stencilTestEnable)758 void anv_CmdSetStencilTestEnableEXT(
759    VkCommandBuffer                              commandBuffer,
760    VkBool32                                     stencilTestEnable)
761 {
762    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
763 
764    cmd_buffer->state.gfx.dynamic.stencil_test_enable = stencilTestEnable;
765 
766    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE;
767 }
768 
anv_CmdSetStencilOpEXT(VkCommandBuffer commandBuffer,VkStencilFaceFlags faceMask,VkStencilOp failOp,VkStencilOp passOp,VkStencilOp depthFailOp,VkCompareOp compareOp)769 void anv_CmdSetStencilOpEXT(
770    VkCommandBuffer                              commandBuffer,
771    VkStencilFaceFlags                           faceMask,
772    VkStencilOp                                  failOp,
773    VkStencilOp                                  passOp,
774    VkStencilOp                                  depthFailOp,
775    VkCompareOp                                  compareOp)
776 {
777    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
778 
779    if (faceMask & VK_STENCIL_FACE_FRONT_BIT) {
780       cmd_buffer->state.gfx.dynamic.stencil_op.front.fail_op = failOp;
781       cmd_buffer->state.gfx.dynamic.stencil_op.front.pass_op = passOp;
782       cmd_buffer->state.gfx.dynamic.stencil_op.front.depth_fail_op = depthFailOp;
783       cmd_buffer->state.gfx.dynamic.stencil_op.front.compare_op = compareOp;
784     }
785 
786    if (faceMask & VK_STENCIL_FACE_BACK_BIT) {
787       cmd_buffer->state.gfx.dynamic.stencil_op.back.fail_op = failOp;
788       cmd_buffer->state.gfx.dynamic.stencil_op.back.pass_op = passOp;
789       cmd_buffer->state.gfx.dynamic.stencil_op.back.depth_fail_op = depthFailOp;
790       cmd_buffer->state.gfx.dynamic.stencil_op.back.compare_op = compareOp;
791    }
792 
793    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP;
794 }
795 
796 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)797 anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
798                                    VkPipelineBindPoint bind_point,
799                                    struct anv_pipeline_layout *layout,
800                                    uint32_t set_index,
801                                    struct anv_descriptor_set *set,
802                                    uint32_t *dynamic_offset_count,
803                                    const uint32_t **dynamic_offsets)
804 {
805    struct anv_descriptor_set_layout *set_layout =
806       layout->set[set_index].layout;
807 
808    VkShaderStageFlags stages = set_layout->shader_stages;
809    struct anv_cmd_pipeline_state *pipe_state;
810 
811    switch (bind_point) {
812    case VK_PIPELINE_BIND_POINT_GRAPHICS:
813       stages &= VK_SHADER_STAGE_ALL_GRAPHICS;
814       pipe_state = &cmd_buffer->state.gfx.base;
815       break;
816 
817    case VK_PIPELINE_BIND_POINT_COMPUTE:
818       stages &= VK_SHADER_STAGE_COMPUTE_BIT;
819       pipe_state = &cmd_buffer->state.compute.base;
820       break;
821 
822    default:
823       unreachable("invalid bind point");
824    }
825 
826    VkShaderStageFlags dirty_stages = 0;
827    if (pipe_state->descriptors[set_index] != set) {
828       pipe_state->descriptors[set_index] = set;
829       dirty_stages |= stages;
830    }
831 
832    /* If it's a push descriptor set, we have to flag things as dirty
833     * regardless of whether or not the CPU-side data structure changed as we
834     * may have edited in-place.
835     */
836    if (set->pool == NULL)
837       dirty_stages |= stages;
838 
839    if (dynamic_offsets) {
840       if (set_layout->dynamic_offset_count > 0) {
841          struct anv_push_constants *push = &pipe_state->push_constants;
842          uint32_t dynamic_offset_start =
843             layout->set[set_index].dynamic_offset_start;
844          uint32_t *push_offsets =
845             &push->dynamic_offsets[dynamic_offset_start];
846 
847          /* Assert that everything is in range */
848          assert(set_layout->dynamic_offset_count <= *dynamic_offset_count);
849          assert(dynamic_offset_start + set_layout->dynamic_offset_count <=
850                 ARRAY_SIZE(push->dynamic_offsets));
851 
852          for (uint32_t i = 0; i < set_layout->dynamic_offset_count; i++) {
853             if (push_offsets[i] != (*dynamic_offsets)[i]) {
854                push_offsets[i] = (*dynamic_offsets)[i];
855                /* dynamic_offset_stages[] elements could contain blanket
856                 * values like VK_SHADER_STAGE_ALL, so limit this to the
857                 * binding point's bits.
858                 */
859                dirty_stages |= set_layout->dynamic_offset_stages[i] & stages;
860             }
861          }
862 
863          *dynamic_offsets += set_layout->dynamic_offset_count;
864          *dynamic_offset_count -= set_layout->dynamic_offset_count;
865       }
866    }
867 
868    cmd_buffer->state.descriptors_dirty |= dirty_stages;
869    cmd_buffer->state.push_constants_dirty |= dirty_stages;
870 }
871 
anv_CmdBindDescriptorSets(VkCommandBuffer commandBuffer,VkPipelineBindPoint pipelineBindPoint,VkPipelineLayout _layout,uint32_t firstSet,uint32_t descriptorSetCount,const VkDescriptorSet * pDescriptorSets,uint32_t dynamicOffsetCount,const uint32_t * pDynamicOffsets)872 void anv_CmdBindDescriptorSets(
873     VkCommandBuffer                             commandBuffer,
874     VkPipelineBindPoint                         pipelineBindPoint,
875     VkPipelineLayout                            _layout,
876     uint32_t                                    firstSet,
877     uint32_t                                    descriptorSetCount,
878     const VkDescriptorSet*                      pDescriptorSets,
879     uint32_t                                    dynamicOffsetCount,
880     const uint32_t*                             pDynamicOffsets)
881 {
882    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
883    ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
884 
885    assert(firstSet + descriptorSetCount <= MAX_SETS);
886 
887    for (uint32_t i = 0; i < descriptorSetCount; i++) {
888       ANV_FROM_HANDLE(anv_descriptor_set, set, pDescriptorSets[i]);
889       anv_cmd_buffer_bind_descriptor_set(cmd_buffer, pipelineBindPoint,
890                                          layout, firstSet + i, set,
891                                          &dynamicOffsetCount,
892                                          &pDynamicOffsets);
893    }
894 }
895 
anv_CmdBindVertexBuffers2EXT(VkCommandBuffer commandBuffer,uint32_t firstBinding,uint32_t bindingCount,const VkBuffer * pBuffers,const VkDeviceSize * pOffsets,const VkDeviceSize * pSizes,const VkDeviceSize * pStrides)896 void anv_CmdBindVertexBuffers2EXT(
897    VkCommandBuffer                              commandBuffer,
898    uint32_t                                     firstBinding,
899    uint32_t                                     bindingCount,
900    const VkBuffer*                              pBuffers,
901    const VkDeviceSize*                          pOffsets,
902    const VkDeviceSize*                          pSizes,
903    const VkDeviceSize*                          pStrides)
904 {
905    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
906    struct anv_vertex_binding *vb = cmd_buffer->state.vertex_bindings;
907 
908    /* We have to defer setting up vertex buffer since we need the buffer
909     * stride from the pipeline. */
910 
911    if (pSizes)
912       cmd_buffer->state.gfx.dynamic.dyn_vbo_size = true;
913    if (pStrides)
914       cmd_buffer->state.gfx.dynamic.dyn_vbo_stride = true;
915 
916    assert(firstBinding + bindingCount <= MAX_VBS);
917    for (uint32_t i = 0; i < bindingCount; i++) {
918       vb[firstBinding + i].buffer = anv_buffer_from_handle(pBuffers[i]);
919       vb[firstBinding + i].offset = pOffsets[i];
920       vb[firstBinding + i].size = pSizes ? pSizes[i] : 0;
921       vb[firstBinding + i].stride = pStrides ? pStrides[i] : 0;
922       cmd_buffer->state.gfx.vb_dirty |= 1 << (firstBinding + i);
923    }
924 }
925 
anv_CmdBindVertexBuffers(VkCommandBuffer commandBuffer,uint32_t firstBinding,uint32_t bindingCount,const VkBuffer * pBuffers,const VkDeviceSize * pOffsets)926 void anv_CmdBindVertexBuffers(
927     VkCommandBuffer                             commandBuffer,
928     uint32_t                                    firstBinding,
929     uint32_t                                    bindingCount,
930     const VkBuffer*                             pBuffers,
931     const VkDeviceSize*                         pOffsets)
932 {
933    return anv_CmdBindVertexBuffers2EXT(commandBuffer, firstBinding,
934                                        bindingCount, pBuffers, pOffsets,
935                                        NULL, NULL);
936 }
937 
anv_CmdBindTransformFeedbackBuffersEXT(VkCommandBuffer commandBuffer,uint32_t firstBinding,uint32_t bindingCount,const VkBuffer * pBuffers,const VkDeviceSize * pOffsets,const VkDeviceSize * pSizes)938 void anv_CmdBindTransformFeedbackBuffersEXT(
939     VkCommandBuffer                             commandBuffer,
940     uint32_t                                    firstBinding,
941     uint32_t                                    bindingCount,
942     const VkBuffer*                             pBuffers,
943     const VkDeviceSize*                         pOffsets,
944     const VkDeviceSize*                         pSizes)
945 {
946    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
947    struct anv_xfb_binding *xfb = cmd_buffer->state.xfb_bindings;
948 
949    /* We have to defer setting up vertex buffer since we need the buffer
950     * stride from the pipeline. */
951 
952    assert(firstBinding + bindingCount <= MAX_XFB_BUFFERS);
953    for (uint32_t i = 0; i < bindingCount; i++) {
954       if (pBuffers[i] == VK_NULL_HANDLE) {
955          xfb[firstBinding + i].buffer = NULL;
956       } else {
957          ANV_FROM_HANDLE(anv_buffer, buffer, pBuffers[i]);
958          xfb[firstBinding + i].buffer = buffer;
959          xfb[firstBinding + i].offset = pOffsets[i];
960          xfb[firstBinding + i].size =
961             anv_buffer_get_range(buffer, pOffsets[i],
962                                  pSizes ? pSizes[i] : VK_WHOLE_SIZE);
963       }
964    }
965 }
966 
967 enum isl_format
anv_isl_format_for_descriptor_type(const struct anv_device * device,VkDescriptorType type)968 anv_isl_format_for_descriptor_type(const struct anv_device *device,
969                                    VkDescriptorType type)
970 {
971    switch (type) {
972    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
973    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
974       return device->physical->compiler->indirect_ubos_use_sampler ?
975              ISL_FORMAT_R32G32B32A32_FLOAT : ISL_FORMAT_RAW;
976 
977    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
978    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
979       return ISL_FORMAT_RAW;
980 
981    default:
982       unreachable("Invalid descriptor type");
983    }
984 }
985 
986 struct anv_state
anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer * cmd_buffer,const void * data,uint32_t size,uint32_t alignment)987 anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer,
988                             const void *data, uint32_t size, uint32_t alignment)
989 {
990    struct anv_state state;
991 
992    state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, size, alignment);
993    memcpy(state.map, data, size);
994 
995    VG(VALGRIND_CHECK_MEM_IS_DEFINED(state.map, size));
996 
997    return state;
998 }
999 
1000 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)1001 anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer,
1002                              uint32_t *a, uint32_t *b,
1003                              uint32_t dwords, uint32_t alignment)
1004 {
1005    struct anv_state state;
1006    uint32_t *p;
1007 
1008    state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
1009                                               dwords * 4, alignment);
1010    p = state.map;
1011    for (uint32_t i = 0; i < dwords; i++)
1012       p[i] = a[i] | b[i];
1013 
1014    VG(VALGRIND_CHECK_MEM_IS_DEFINED(p, dwords * 4));
1015 
1016    return state;
1017 }
1018 
1019 struct anv_state
anv_cmd_buffer_gfx_push_constants(struct anv_cmd_buffer * cmd_buffer)1020 anv_cmd_buffer_gfx_push_constants(struct anv_cmd_buffer *cmd_buffer)
1021 {
1022    struct anv_push_constants *data =
1023       &cmd_buffer->state.gfx.base.push_constants;
1024 
1025    struct anv_state state =
1026       anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
1027                                          sizeof(struct anv_push_constants),
1028                                          32 /* bottom 5 bits MBZ */);
1029    memcpy(state.map, data, sizeof(struct anv_push_constants));
1030 
1031    return state;
1032 }
1033 
1034 struct anv_state
anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer * cmd_buffer)1035 anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer)
1036 {
1037    struct anv_push_constants *data =
1038       &cmd_buffer->state.compute.base.push_constants;
1039    struct anv_compute_pipeline *pipeline = cmd_buffer->state.compute.pipeline;
1040    const struct brw_cs_prog_data *cs_prog_data = get_cs_prog_data(pipeline);
1041    const struct anv_push_range *range = &pipeline->cs->bind_map.push_ranges[0];
1042 
1043    const struct anv_cs_parameters cs_params = anv_cs_parameters(pipeline);
1044    const unsigned total_push_constants_size =
1045       brw_cs_push_const_total_size(cs_prog_data, cs_params.threads);
1046    if (total_push_constants_size == 0)
1047       return (struct anv_state) { .offset = 0 };
1048 
1049    const unsigned push_constant_alignment =
1050       cmd_buffer->device->info.gen < 8 ? 32 : 64;
1051    const unsigned aligned_total_push_constants_size =
1052       ALIGN(total_push_constants_size, push_constant_alignment);
1053    struct anv_state state =
1054       anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
1055                                          aligned_total_push_constants_size,
1056                                          push_constant_alignment);
1057 
1058    void *dst = state.map;
1059    const void *src = (char *)data + (range->start * 32);
1060 
1061    if (cs_prog_data->push.cross_thread.size > 0) {
1062       memcpy(dst, src, cs_prog_data->push.cross_thread.size);
1063       dst += cs_prog_data->push.cross_thread.size;
1064       src += cs_prog_data->push.cross_thread.size;
1065    }
1066 
1067    if (cs_prog_data->push.per_thread.size > 0) {
1068       for (unsigned t = 0; t < cs_params.threads; t++) {
1069          memcpy(dst, src, cs_prog_data->push.per_thread.size);
1070 
1071          uint32_t *subgroup_id = dst +
1072             offsetof(struct anv_push_constants, cs.subgroup_id) -
1073             (range->start * 32 + cs_prog_data->push.cross_thread.size);
1074          *subgroup_id = t;
1075 
1076          dst += cs_prog_data->push.per_thread.size;
1077       }
1078    }
1079 
1080    return state;
1081 }
1082 
anv_CmdPushConstants(VkCommandBuffer commandBuffer,VkPipelineLayout layout,VkShaderStageFlags stageFlags,uint32_t offset,uint32_t size,const void * pValues)1083 void anv_CmdPushConstants(
1084     VkCommandBuffer                             commandBuffer,
1085     VkPipelineLayout                            layout,
1086     VkShaderStageFlags                          stageFlags,
1087     uint32_t                                    offset,
1088     uint32_t                                    size,
1089     const void*                                 pValues)
1090 {
1091    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1092 
1093    if (stageFlags & VK_SHADER_STAGE_ALL_GRAPHICS) {
1094       struct anv_cmd_pipeline_state *pipe_state =
1095          &cmd_buffer->state.gfx.base;
1096 
1097       memcpy(pipe_state->push_constants.client_data + offset, pValues, size);
1098    }
1099    if (stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) {
1100       struct anv_cmd_pipeline_state *pipe_state =
1101          &cmd_buffer->state.compute.base;
1102 
1103       memcpy(pipe_state->push_constants.client_data + offset, pValues, size);
1104    }
1105 
1106    cmd_buffer->state.push_constants_dirty |= stageFlags;
1107 }
1108 
anv_CreateCommandPool(VkDevice _device,const VkCommandPoolCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkCommandPool * pCmdPool)1109 VkResult anv_CreateCommandPool(
1110     VkDevice                                    _device,
1111     const VkCommandPoolCreateInfo*              pCreateInfo,
1112     const VkAllocationCallbacks*                pAllocator,
1113     VkCommandPool*                              pCmdPool)
1114 {
1115    ANV_FROM_HANDLE(anv_device, device, _device);
1116    struct anv_cmd_pool *pool;
1117 
1118    pool = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*pool), 8,
1119                      VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1120    if (pool == NULL)
1121       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1122 
1123    vk_object_base_init(&device->vk, &pool->base, VK_OBJECT_TYPE_COMMAND_POOL);
1124 
1125    if (pAllocator)
1126       pool->alloc = *pAllocator;
1127    else
1128       pool->alloc = device->vk.alloc;
1129 
1130    list_inithead(&pool->cmd_buffers);
1131 
1132    *pCmdPool = anv_cmd_pool_to_handle(pool);
1133 
1134    return VK_SUCCESS;
1135 }
1136 
anv_DestroyCommandPool(VkDevice _device,VkCommandPool commandPool,const VkAllocationCallbacks * pAllocator)1137 void anv_DestroyCommandPool(
1138     VkDevice                                    _device,
1139     VkCommandPool                               commandPool,
1140     const VkAllocationCallbacks*                pAllocator)
1141 {
1142    ANV_FROM_HANDLE(anv_device, device, _device);
1143    ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool);
1144 
1145    if (!pool)
1146       return;
1147 
1148    list_for_each_entry_safe(struct anv_cmd_buffer, cmd_buffer,
1149                             &pool->cmd_buffers, pool_link) {
1150       anv_cmd_buffer_destroy(cmd_buffer);
1151    }
1152 
1153    vk_object_base_finish(&pool->base);
1154    vk_free2(&device->vk.alloc, pAllocator, pool);
1155 }
1156 
anv_ResetCommandPool(VkDevice device,VkCommandPool commandPool,VkCommandPoolResetFlags flags)1157 VkResult anv_ResetCommandPool(
1158     VkDevice                                    device,
1159     VkCommandPool                               commandPool,
1160     VkCommandPoolResetFlags                     flags)
1161 {
1162    ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool);
1163 
1164    list_for_each_entry(struct anv_cmd_buffer, cmd_buffer,
1165                        &pool->cmd_buffers, pool_link) {
1166       anv_cmd_buffer_reset(cmd_buffer);
1167    }
1168 
1169    return VK_SUCCESS;
1170 }
1171 
anv_TrimCommandPool(VkDevice device,VkCommandPool commandPool,VkCommandPoolTrimFlags flags)1172 void anv_TrimCommandPool(
1173     VkDevice                                    device,
1174     VkCommandPool                               commandPool,
1175     VkCommandPoolTrimFlags                      flags)
1176 {
1177    /* Nothing for us to do here.  Our pools stay pretty tidy. */
1178 }
1179 
1180 /**
1181  * Return NULL if the current subpass has no depthstencil attachment.
1182  */
1183 const struct anv_image_view *
anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer * cmd_buffer)1184 anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer *cmd_buffer)
1185 {
1186    const struct anv_subpass *subpass = cmd_buffer->state.subpass;
1187 
1188    if (subpass->depth_stencil_attachment == NULL)
1189       return NULL;
1190 
1191    const struct anv_image_view *iview =
1192       cmd_buffer->state.attachments[subpass->depth_stencil_attachment->attachment].image_view;
1193 
1194    assert(iview->aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT |
1195                                 VK_IMAGE_ASPECT_STENCIL_BIT));
1196 
1197    return iview;
1198 }
1199 
1200 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)1201 anv_cmd_buffer_push_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
1202                                    VkPipelineBindPoint bind_point,
1203                                    struct anv_descriptor_set_layout *layout,
1204                                    uint32_t _set)
1205 {
1206    struct anv_cmd_pipeline_state *pipe_state;
1207    if (bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
1208       pipe_state = &cmd_buffer->state.compute.base;
1209    } else {
1210       assert(bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS);
1211       pipe_state = &cmd_buffer->state.gfx.base;
1212    }
1213 
1214    struct anv_push_descriptor_set **push_set =
1215       &pipe_state->push_descriptors[_set];
1216 
1217    if (*push_set == NULL) {
1218       *push_set = vk_zalloc(&cmd_buffer->pool->alloc,
1219                             sizeof(struct anv_push_descriptor_set), 8,
1220                             VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1221       if (*push_set == NULL) {
1222          anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_OUT_OF_HOST_MEMORY);
1223          return NULL;
1224       }
1225    }
1226 
1227    struct anv_descriptor_set *set = &(*push_set)->set;
1228 
1229    if (set->layout != layout) {
1230       if (set->layout)
1231          anv_descriptor_set_layout_unref(cmd_buffer->device, set->layout);
1232       anv_descriptor_set_layout_ref(layout);
1233       set->layout = layout;
1234    }
1235    set->size = anv_descriptor_set_layout_size(layout, 0);
1236    set->buffer_view_count = layout->buffer_view_count;
1237    set->descriptor_count = layout->descriptor_count;
1238    set->buffer_views = (*push_set)->buffer_views;
1239 
1240    if (layout->descriptor_buffer_size &&
1241        ((*push_set)->set_used_on_gpu ||
1242         set->desc_mem.alloc_size < layout->descriptor_buffer_size)) {
1243       /* The previous buffer is either actively used by some GPU command (so
1244        * we can't modify it) or is too small.  Allocate a new one.
1245        */
1246       struct anv_state desc_mem =
1247          anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream,
1248                                 layout->descriptor_buffer_size, 32);
1249       if (set->desc_mem.alloc_size) {
1250          /* TODO: Do we really need to copy all the time? */
1251          memcpy(desc_mem.map, set->desc_mem.map,
1252                 MIN2(desc_mem.alloc_size, set->desc_mem.alloc_size));
1253       }
1254       set->desc_mem = desc_mem;
1255 
1256       struct anv_address addr = {
1257          .bo = cmd_buffer->dynamic_state_stream.state_pool->block_pool.bo,
1258          .offset = set->desc_mem.offset,
1259       };
1260 
1261       enum isl_format format =
1262          anv_isl_format_for_descriptor_type(cmd_buffer->device,
1263                                             VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
1264 
1265       const struct isl_device *isl_dev = &cmd_buffer->device->isl_dev;
1266       set->desc_surface_state =
1267          anv_state_stream_alloc(&cmd_buffer->surface_state_stream,
1268                                 isl_dev->ss.size, isl_dev->ss.align);
1269       anv_fill_buffer_surface_state(cmd_buffer->device,
1270                                     set->desc_surface_state, format,
1271                                     ISL_SURF_USAGE_CONSTANT_BUFFER_BIT,
1272                                     addr, layout->descriptor_buffer_size, 1);
1273    }
1274 
1275    return set;
1276 }
1277 
anv_CmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer,VkPipelineBindPoint pipelineBindPoint,VkPipelineLayout _layout,uint32_t _set,uint32_t descriptorWriteCount,const VkWriteDescriptorSet * pDescriptorWrites)1278 void anv_CmdPushDescriptorSetKHR(
1279     VkCommandBuffer commandBuffer,
1280     VkPipelineBindPoint pipelineBindPoint,
1281     VkPipelineLayout _layout,
1282     uint32_t _set,
1283     uint32_t descriptorWriteCount,
1284     const VkWriteDescriptorSet* pDescriptorWrites)
1285 {
1286    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1287    ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
1288 
1289    assert(_set < MAX_SETS);
1290 
1291    struct anv_descriptor_set_layout *set_layout = layout->set[_set].layout;
1292 
1293    struct anv_descriptor_set *set =
1294       anv_cmd_buffer_push_descriptor_set(cmd_buffer, pipelineBindPoint,
1295                                          set_layout, _set);
1296    if (!set)
1297       return;
1298 
1299    /* Go through the user supplied descriptors. */
1300    for (uint32_t i = 0; i < descriptorWriteCount; i++) {
1301       const VkWriteDescriptorSet *write = &pDescriptorWrites[i];
1302 
1303       switch (write->descriptorType) {
1304       case VK_DESCRIPTOR_TYPE_SAMPLER:
1305       case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1306       case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1307       case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1308       case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1309          for (uint32_t j = 0; j < write->descriptorCount; j++) {
1310             anv_descriptor_set_write_image_view(cmd_buffer->device, set,
1311                                                 write->pImageInfo + j,
1312                                                 write->descriptorType,
1313                                                 write->dstBinding,
1314                                                 write->dstArrayElement + j);
1315          }
1316          break;
1317 
1318       case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1319       case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1320          for (uint32_t j = 0; j < write->descriptorCount; j++) {
1321             ANV_FROM_HANDLE(anv_buffer_view, bview,
1322                             write->pTexelBufferView[j]);
1323 
1324             anv_descriptor_set_write_buffer_view(cmd_buffer->device, set,
1325                                                  write->descriptorType,
1326                                                  bview,
1327                                                  write->dstBinding,
1328                                                  write->dstArrayElement + j);
1329          }
1330          break;
1331 
1332       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1333       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1334       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1335       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1336          for (uint32_t j = 0; j < write->descriptorCount; j++) {
1337             ANV_FROM_HANDLE(anv_buffer, buffer, write->pBufferInfo[j].buffer);
1338 
1339             anv_descriptor_set_write_buffer(cmd_buffer->device, set,
1340                                             &cmd_buffer->surface_state_stream,
1341                                             write->descriptorType,
1342                                             buffer,
1343                                             write->dstBinding,
1344                                             write->dstArrayElement + j,
1345                                             write->pBufferInfo[j].offset,
1346                                             write->pBufferInfo[j].range);
1347          }
1348          break;
1349 
1350       default:
1351          break;
1352       }
1353    }
1354 
1355    anv_cmd_buffer_bind_descriptor_set(cmd_buffer, pipelineBindPoint,
1356                                       layout, _set, set, NULL, NULL);
1357 }
1358 
anv_CmdPushDescriptorSetWithTemplateKHR(VkCommandBuffer commandBuffer,VkDescriptorUpdateTemplate descriptorUpdateTemplate,VkPipelineLayout _layout,uint32_t _set,const void * pData)1359 void anv_CmdPushDescriptorSetWithTemplateKHR(
1360     VkCommandBuffer                             commandBuffer,
1361     VkDescriptorUpdateTemplate                  descriptorUpdateTemplate,
1362     VkPipelineLayout                            _layout,
1363     uint32_t                                    _set,
1364     const void*                                 pData)
1365 {
1366    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1367    ANV_FROM_HANDLE(anv_descriptor_update_template, template,
1368                    descriptorUpdateTemplate);
1369    ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
1370 
1371    assert(_set < MAX_PUSH_DESCRIPTORS);
1372 
1373    struct anv_descriptor_set_layout *set_layout = layout->set[_set].layout;
1374 
1375    struct anv_descriptor_set *set =
1376       anv_cmd_buffer_push_descriptor_set(cmd_buffer, template->bind_point,
1377                                          set_layout, _set);
1378    if (!set)
1379       return;
1380 
1381    anv_descriptor_set_write_template(cmd_buffer->device, set,
1382                                      &cmd_buffer->surface_state_stream,
1383                                      template,
1384                                      pData);
1385 
1386    anv_cmd_buffer_bind_descriptor_set(cmd_buffer, template->bind_point,
1387                                       layout, _set, set, NULL, NULL);
1388 }
1389 
anv_CmdSetDeviceMask(VkCommandBuffer commandBuffer,uint32_t deviceMask)1390 void anv_CmdSetDeviceMask(
1391     VkCommandBuffer                             commandBuffer,
1392     uint32_t                                    deviceMask)
1393 {
1394    /* No-op */
1395 }
1396